Home > Back-end >  Why do I get a "No Export Named" error when using nested stacks in CloudFormation?
Why do I get a "No Export Named" error when using nested stacks in CloudFormation?

Time:10-15

I'm defining an export in a CloudFormation template to be used in another.

I can see the export is being created in the AWS console however, the second stack fails to find it.

The error:

UPDATE_ROLLBACK_IN_PROGRESS with reason: No export named sandbox06-ODM-KinesisStreamArn found

template.yml

Resources:
  KinesisStream:
    Type: AWS::Kinesis::Stream
    Properties:
      ShardCount: 1
      RetentionPeriodHours: 24
      Name: !Sub ${Environment}-${Application}
Outputs:
  Topic:
    Value: !Ref Topic
  KinesisStreamArn:
    Value: !GetAtt KinesisStream.Arn
    Export:
      Name: !Sub ${Environment}-${Domain}-KinesisStreamArn

firehose.yml

KinesisFirehoseRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service: firehose.amazonaws.com
            Action: sts:AssumeRole
      Path: /
      Policies:
        - PolicyName: KinesisFirehosePolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - kinesis:*
                  - s3:*
                  - s3-object-lambda:*
                Resource:
                  - !Sub "${Bucket.Arn}/*"
                  - Fn::ImportValue: !Sub "${Environment}-${Domain}-KinesisStreamArn"

nested_template.yml

  OperationalData:
    Type: AWS::Serverless::Application
    Properties:
      Parameters:
        Environment: !Ref Environment
        Domain: OperationalData
        Application: odm
        BucketPrefix: pie
        WhiteListCidr: !Ref WhiteListCidr
        VpcId:
          Fn::ImportValue: !Sub vpc-${Environment}-VPCID
        VpcCidr:
          Fn::ImportValue: !Sub vpc-${Environment}-VPCCIDR
        Subnets:
          Fn::ImportValue: !Sub vpc-${Environment}-PrivateSubnets
      Location: ./data/odm/template.yml
      Tags:
        Environment: !Ref Environment
        Domain: odm
        Application: !Ref Application
        Developer: !Ref Developer
        DevOpsAdmin: !Ref DevOpsAdmin
        Repository: !Ref Repository
        Team: !Ref Team

  DataEngineeringData:
    Type: AWS::Serverless::Application
    Properties:
      Parameters:
        Environment: !Ref Environment
        Domain: DataEngineeringData
        Application: data-engineering
      Location: ./data/data-engineering/template.yml
      Tags:
        Environment: !Ref Environment
        Domain: DataEngineeringData
        Application: data-engineering
        Developer: !Ref Developer
        DevOpsAdmin: !Ref DevOpsAdmin
        Repository: !Ref Repository
        Team: !Ref Team

What is the issue?

CodePudding user response:

the second stack fails to find it

This is because nested CloudFormation stacks are created in parallel by default.

This means that if one of your child stacks - e.g. the stack which contains KinesisFirehoseRole - is importing the output from another child stack - e.g. the stack which contains KinesisStream - then the stack creation will fail.

This is because as they're created in parallel, how does CloudFormation ensure that the export value has been exported by the time another child stack created is importing it?

To fix this, use the DependsOn attribute on the stack which contains KinesisFirehoseRole.

This should point to the stack which contains KinesisStream as KinesisFirehoseRole has a dependency on it.

DependsOn makes this dependency explicit and will ensure correct stack creation order.

Something like this should work:

Stack-Containing-Kinesis-Firehose-Role:
   Type: AWS::CloudFormation::Stack
   DependsOn: Stack-Containing-Kinesis-Stream-Resource-Which-Outputs-KinesisStreamArn
   ...
  • Related