简体   繁体   中英

Race condition in siblings stacks created by CDK leading to "No export named X found"

I have an app with CDK TS code that generates multiple CloudFormation templates for as many stacks. (Please note that I have no experience writing CloudFormation templates.)

One of these stacks, StorageStack, exports a DynamoDB table, among other things. Another one, CommonStack, uses it. When deploying them in the same build, I end up with a "No export named X found" error on the CommonStack, despite it being run after StorageStack, and the table ARN being in the outputs.

在此处输入图像描述

在此处输入图像描述

I had a look at the CDK build artifacts, and sure enough, the Output is there in the StorageStack:

"Outputs": {
    "ExportsOutputFnGetAttbnpversionstable5A7FA84BArnCF389FA7": {
      "Value": {
        "Fn::GetAtt": [
          "bnpversionstable5A7FA84B",
          "Arn"
        ]
      },
      "Export": {
        "Name": "StorageStack:ExportsOutputFnGetAttbnpversionstable5A7FA84BArnCF389FA7"
      }
    },
    "ExportsOutputRefbnpversionstable5A7FA84B846085C0": {
      "Value": {
        "Ref": "bnpversionstable5A7FA84B"
      },
      "Export": {
        "Name": "StorageStack:ExportsOutputRefbnpversionstable5A7FA84B846085C0"
      }
    },

Now the 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"
      }
    },

These templates work as expected, and IF I re-run the second one after a time, it work. So this is a kind of race condition.

Here is the CDK code orchestrating the stacks and passing the dynamodb.ITable` between them:

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)

What can be done to prevent the race condition?

So after some investigating, it seems this is due to my deployment method.

I'm using CodePipeline, with CloudFormation actions as deployment. This means one action per stack, and putting them in the same pipeline stage does NOT guarantee order of execution.

So if you have dependencies between your stacks and are using CodePipeline, separate them in different stages, not different actions in the same stage.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM