[英]Race condition in siblings stacks created by CDK leading to "No export named X found"
我有一個帶有 CDK TS 代碼的應用程序,可以為盡可能多的堆棧生成多個 CloudFormation 模板。 (請注意,我沒有編寫 CloudFormation 模板的經驗。)
這些堆棧之一,StorageStack,除其他外導出 DynamoDB 表。 另一個 CommonStack 使用它。 在同一個構建中部署它們時,我最終在 CommonStack 上出現“未找到名為 X 的導出”錯誤,盡管它是在 StorageStack 之后運行的,並且表 ARN 在輸出中。
我查看了 CDK 構建工件,果然,StorageStack 中有 Output:
"Outputs": {
"ExportsOutputFnGetAttbnpversionstable5A7FA84BArnCF389FA7": {
"Value": {
"Fn::GetAtt": [
"bnpversionstable5A7FA84B",
"Arn"
]
},
"Export": {
"Name": "StorageStack:ExportsOutputFnGetAttbnpversionstable5A7FA84BArnCF389FA7"
}
},
"ExportsOutputRefbnpversionstable5A7FA84B846085C0": {
"Value": {
"Ref": "bnpversionstable5A7FA84B"
},
"Export": {
"Name": "StorageStack:ExportsOutputRefbnpversionstable5A7FA84B846085C0"
}
},
現在是 CommonStack:
"ApiversionsDataSourceServiceRole5C6396DC": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "appsync.amazonaws.com"
}
}
],
"Version": "2012-10-17"
}
},
"Metadata": {
"aws:cdk:path": "CommonStack/Api/versionsDataSource/ServiceRole/Resource"
}
},
"ApiversionsDataSourceServiceRoleDefaultPolicy3ECB516A": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"dynamodb:BatchGetItem",
"dynamodb:GetRecords",
"dynamodb:GetShardIterator",
"dynamodb:Query",
"dynamodb:GetItem",
"dynamodb:Scan",
"dynamodb:ConditionCheckItem",
"dynamodb:BatchWriteItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"dynamodb:DescribeTable"
],
"Effect": "Allow",
"Resource": [
{
"Fn::ImportValue": "StorageStack:ExportsOutputFnGetAttbnpversionstable5A7FA84BArnCF389FA7"
},
{
"Ref": "AWS::NoValue"
}
]
}
],
"Version": "2012-10-17"
},
"PolicyName": "ApiversionsDataSourceServiceRoleDefaultPolicy3ECB516A",
"Roles": [
{
"Ref": "ApiversionsDataSourceServiceRole5C6396DC"
}
]
},
"Metadata": {
"aws:cdk:path": "CommonStack/Api/versionsDataSource/ServiceRole/DefaultPolicy/Resource"
}
},
"ApiversionsDataSource2186200D": {
"Type": "AWS::AppSync::DataSource",
"Properties": {
"ApiId": {
"Fn::GetAtt": [
"ApiF70053CD",
"ApiId"
]
},
"Name": "versionsDataSource",
"Type": "AMAZON_DYNAMODB",
"DynamoDBConfig": {
"AwsRegion": "eu-west-1",
"TableName": {
"Fn::ImportValue": "StorageStack:ExportsOutputRefbnpversionstable5A7FA84B846085C0"
}
},
"ServiceRoleArn": {
"Fn::GetAtt": [
"ApiversionsDataSourceServiceRole5C6396DC",
"Arn"
]
}
},
"Metadata": {
"aws:cdk:path": "CommonStack/Api/versionsDataSource/Resource"
}
},
這些模板按預期工作,如果我在一段時間后重新運行第二個模板,它就會工作。 所以這是一種競爭條件。
這是編排堆棧並傳遞的 CDK 代碼
它們之間的 dynamodb.ITable`:
const storage = new StorageStack(app, 'StorageStack', stack_props)
(...)
stack_props.storage.tables.versions = storage.versions_table
const common_stack = new CommonStack(app, 'CommonStack', stack_props)
可以做些什么來防止競爭條件?
所以經過一番調查,這似乎是由於我的部署方法。
我正在使用 CodePipeline,並將 CloudFormation 操作作為部署。 這意味着每個堆棧一個動作,將它們放在同一管道階段並不能保證執行順序。
因此,如果您的堆棧之間存在依賴關系並且正在使用 CodePipeline,請將它們分隔在不同的階段,而不是同一階段的不同操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.