简体   繁体   中英

Writing reusable CloudFormation snippets with AWS::Include and Nested Stacks

I have been using nested stacks in CloudFormation for several months and they are very useful. So I thought I should spend sometime to make each nested stack reusable to other teams in the org.

I saw the use case of AWS::Include in several places like here and here and it makes good sense to me.

One approach I have in mind is one snippet for each resource, like an AWS::EC2::Subnet or AWS::EC2::InternetGateway which can be included zero or more times into a vpc.json template, which itself can be used as a nested stack in a larger application.

The snippet does not take any parameters, but can reference a parameter that exists in the parent template.

At first glance this doesn't seem enough to me. Consider this example:

"PublicSubnet": {
  "Type": "AWS::EC2::Subnet",
  "Properties": {
    "VpcId": {"Ref": "VPC"},
    "AvailabilityZone": {
       "Fn::Select" : [ "0", { "Fn::GetAZs" : {"Ref": "AWS::Region"} }]
    },
    "CidrBlock": {
      "Fn::FindInMap": ["AZSubnetMap", {
         "Fn::Select" : [ "0", { "Fn::GetAZs" : {"Ref": "AWS::Region"} }]},
         "PublicSubnet"]},
    "MapPublicIpOnLaunch": "true",
    "Tags": [..]
  }
}

How can I avoid hard coding that "0" for the AZ in a Subnet snippet for example?

Unfortunately, AWS doesn't provide a way to dynamically update the template as per the requirement.

I have solved a similar problem using Mustache Templates using Java Library Handle Bars . Using this library you can generate template on the fly based on the requirements.

Hope this helps.

You will have to use two AWS::Include files located in:

  • s3://yourname/PublicSubnetA.yaml
  • s3://yourname/PublicSubnetB.yaml

And call them from your MAIN Template:

Fn::Transform:        
    Name: AWS::Include
    Parameters:
      Location : "s3://yourname/PublicSubnetA.yaml"   


 Fn::Transform:        
    Name: AWS::Include
    Parameters:
      Location : "s3://yourname/PublicSubnetB.yaml"   

I 'am trying to find way to send additional parameters or override parameter to AWS::include, as you see it has Parameters: Location:

Why ti's not understanding more parameters and not just Location, I would be glad to have something like this:

 Fn::Transform:        
    Name: AWS::Include
    Parameters:
      MySubnetIndex: 0
      Location : "s3://yourname/PublicSubnetB.yaml"   

I tried this way to send additional parameters:

Fn::Transform:        
    Name: AWS::Include
    Parameters:
       Location : "s3://my.test/create-ec2.yaml"   
       EC2Size :
         Type:  String
         Default: "t2.micro"

And got interesting error:

The value of parameter EC2Size under transform Include must resolve to a string, number, boolean or a list of any of these

Looks like it understand what this is additional parameters, probably it need to be configured little bit different. I was not able to find way to fix this error yet.

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