簡體   English   中英

CDK 創建的兄弟堆棧中的競爭條件導致“找不到名為 X 的導出”

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM