简体   繁体   中英

Cloudformation stack with nested resources fails to create

I'm trying to define some common resources (specifically, a couple of IAM roles) that will be shared between two environments, via a nested stack. The first environment to use the nested stack's resources creates ok, but the second one fails when trying to run the nested stack. Am I not understanding something about how nested stacks work, or am I just doing something wrong?

My nested stack is defined as:

AWSTemplateFormatVersion: '2010-09-09'
Description: Defines common resources shared between environments.

Parameters:
    ParentStage:
    Type: String
    Description: The Stage or environment name.
    Default: ""
    ParentVpcId:
    Type: "AWS::EC2::VPC::Id"
    Description: VpcId of your existing Virtual Private Cloud (VPC)
    Default: ""

Resources:

    LambdaFunctionSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
        GroupDescription: Identifies Lamdba functions to VPC resources
        GroupName: BBA-KTDO-SG-LambdaFunction
        VpcId: !Ref ParentVpcId

    RdsAccessSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
        GroupDescription: Allows Lambda functions access to RDS instances
        GroupName: BBA-KTDO-SG-RDS
        SecurityGroupIngress:
        - IpProtocol: tcp
            FromPort: 3306
            ToPort: 3306
            SourceSecurityGroupId: !Ref LambdaFunctionSG
        VpcId: !Ref ParentVpcId

I've uploaded that YAML file to an S3 bucket, and I'm then trying to use it in two separate stack files (ie app_dev.yaml and app_prod.yaml ) as:

Resources:

    CommonResources:
    Type: 'AWS::CloudFormation::Stack'
    Properties:
        TemplateURL: "https://my-buildbucket.s3-eu-west-1.amazonaws.com/common/common.yaml"
        Parameters:
        ParentStage: !Ref Stage
        ParentVpcId: !Ref VpcId

And referring to its outputs as (eg):

VpcConfig:
    SecurityGroupIds:
        - !GetAtt [ CommonResources, Outputs.LambdaFunctionSGId ]

The first environment creates fine, including the nested resources. When I try to run the second environment, it fails with error:

Embedded stack arn:aws:cloudformation:eu-west-1:238165151424:stack/my-prod-stack-CommonResources-L94ZCIP0UD9W/f9d06dd0-994d-11eb-9802-02554f144c21 was not successfully created: The following resource(s) failed to create: [LambdaExecuteRole, LambdaFunctionSG].

Is it not possible to share a single resource definition between two separate stacks like this, or have I just missed something in the implementation?

As @jasonwadsworth mentioned that's correct names of the stacks are always amended with a random string at the end AWS::CloudFormation::Stack check the return values. Use GetAtt to get the name of the stack and construct the output. How do I pass values between nested stacks within the same parent stack in AWS CloudFormation?

Plus use aws cloudformation package command for packaging the nested stacks, no need to manually upload them to s3 bucket.

someting like

aws cloudformation package \
--template-file /path_to_template/template.json \
--s3-bucket bucket-name \
--output-template-file packaged-template.json

Take a look on the cloudformation output exports as well in case you are curious Difference between an Output & an Export

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