Search code examples
amazon-web-servicesmappingaws-cloudformationnested-stack

How to use Mappings in AWS CloudFormation templates in nested stacks


Let's consider the following Mappings and FindInMap are used in the same AWS CloudFormation template. They will work.

Now, consider the VpcIds under Mappings are in the master.yaml template, and I am trying to create the EgressOnlyInternetGateway resource from the nested.yaml template using those Mappings located in the master.yaml template.

How can I accomplish this?

# master.yaml
Mappings:
  VpcIds:
    us-east-1: 
      "123456789012": "vpc-00011122233344455"
      "234567890123": "vpc-11122233344455566"
    us-west-1: 
      "123456789012": "vpc-22233344455566677"
      "234567890123": "vpc-33344455566677788"


# nested.yaml
Resources:
  EgressOnlyInternetGateway:
    Type: AWS::EC2::EgressOnlyInternetGateway
    Properties:
      VpcId: !FindInMap [VpcIds, !Ref "AWS::Region", !Ref "AWS::AccountId"]

Update: I am trying to create a resource MyTestNestedSg in MyTestNestedStack (MyTestNestedStack.yaml) using the a mapped parameter defined in MyTestMasterStack as showing below. I am getting error: Parameter values specified for a template which does not require them, against MyTestNestedStack.

How can I resolve this?

Please note that the resource MyTestMasterSg under MyTestMasterStack is just for the completeness.

# MyTestMasterStack.yaml
Mappings:
  VpcIds:
    us-east-1: 
      "123456789012": "vpc-00011122233344455" 
      "234567890123": "vpc-11122233344455566" 

Resources:
  MyTestNestedStack:
    Type: AWS::CloudFormation::Stack
    Properties: 
      Parameters: 
        VpcId: !FindInMap [VpcIds, !Ref "AWS::Region", !Ref "AWS::AccountId"]
      TemplateURL: "https://s3.amazonaws.com/my_template_bucket_name/MyTestNestedStack.yaml"
      TimeoutInMinutes: 60

  MyTestMasterSg:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: "vpc-017a12485ad93e94a"
      GroupDescription: Testing resource creation wtih Mappings from the parent Stack
      GroupName: MyTestMasterSg
      SecurityGroupIngress:
        - CidrIp: 10.1.0.0/16
          FromPort: 80
          IpProtocol: tcp
          ToPort: 80

# MyTestNestedStack.yaml
Resources:
  MyTestNestedSg:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId: !Ref VpcId
      GroupDescription: Testing resource creation wtih Mappings from the parent Stack
      GroupName: MyTestNestedSg
      SecurityGroupIngress:
        - CidrIp: 10.1.0.0/16
          FromPort: 8080
          IpProtocol: tcp
          ToPort: 8080

Solution

  • You can't do this. You have to past resolved mapping values through Parameters to your AWS::CloudFormation::Stack resource.

    Nested stacks should be self sufficient and they don't have access to the parent stack's parameters, mappings or resources. They can only work with data that you explicitly pass through Parameters of AWS::CloudFormation::Stack resource.

    So in parent stack you would have to do:

    MyNestedStack:
      Type: AWS::CloudFormation::Stack
      Properties: 
        Parameters: 
          VpcId : !FindInMap [VpcIds, !Ref "AWS::Region", !Ref "AWS::AccountId"]
      TemplateURL: String
    

    Update

    Your MyTestNestedStack.yaml is missing Paramters:

    Parameters:
      
      VpcId:
        Type: AWS::EC2::VPC::Id