Beginning with AWS CloudFormation – Part 3

Welcome (or welcome back) folks.  In this post we are going to look at chaining resources together.  Previously we deployed a VPC, but now we want to put stuff in it.  We’ll be using the subnet resource today, and here is the CloudFormation doc link to it:

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-subnet.html

Rather than re-hash what we’ve already done in the other posts, let’s just take a quick run through creating a CloudFormation template to deploy a subnet resource.  Looking at the documentation you can see the required pieces for a subnet are the CIDR block and the VPC ID.  The VPC ID essentially serves as your resource target.

If you were to deploy a single CloudFormation template that created both the VPC and the subnet, you might guess by now that you would simply define the VPC resource, and then define the subnet resource using “Ref”: “vpcResourceName” as the VPC ID. Using the skills we already covered you should be able to accomplish this.  You can chain together multiple resources in a single template this way without too much fuss.  However, this isn’t always the recommended thing to do, especially with reusable parts.  In other words, I don’t really want to have the same resource created in every single template I use, especially if I’ve gone to a lot of trouble with parameter inputs and customization.  Then I’ve got to remember where I’ve used it when I make a change.

We are going to do something a little different in this post.  First, I’m going to create a VPC manually, because you won’t always want to create a new VPC with each deployment.  In fact, you will likely rarely be creating VPCs in your stacks.  So let’s just create one with the console:

1create_vpc

Pretty basic.  This is a new VPC with the name CFTest and a CIDR block of 172.10.0.0/16.  If I check this out in the console, I can see the VPC ID value as well.  I’ll note this ID down.

2vpc_info

Now I’m creating a new template, either with the designer or as a text file.  This template will take some input, create a new subnet, and then output the subnet ID.  If you are using the designer you can simply click the Template tab at the bottom and paste this whole thing in there.  Note: if you are following along you will want to replace the Default: value with your VPC ID.

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Parameters": {
        "myVPCName": {
            "Default": "vpc-e456f39f",
            "Description": "VPC target for subnet",
            "Type": "String"
        },
        "myCidrBlock": {
            "Description": "CIDR Block for Subnet",
            "Type": "String"
        }
    },
    "Resources": {
        "mySubnet": {
            "Type": "AWS::EC2::Subnet",
            "Properties": {
                "CidrBlock": {"Ref": "myCidrBlock"},
                "VpcId": {"Ref": "myVPCName"}
            }
        }
    },
    "Outputs": {
        "mySubnetId": { "Value": { "Ref": "mySubnet" }  
    } 
}

If using the designer, once you have this entered, save the template but save it in an S3 bucket.  It will create a new S3 bucket for you to use and show you URL location of it.  Copy this URL!

5templatesaveS3

If you aren’t using the designer simply upload your text file into an S3 bucket location.  Let’s run this stack to make sure it works.  Here are my Parameter inputs.  Note that if you used a default value for the VPC ID it should be pre-populated, although you can still enter your own custom VPC ID if you want.

3stackdeploy

And once it finishes you should see your subnet in the console.  Perfect.

4subnetcreated

Back in CloudFormation choose this stack and then delete it.  It will delete the subnet it created.

What we are going for here is a reusable component, right?  At this moment, we have a template that will create a subnet resource for us.  The thing we are wanting to do is called nesting, or having a stack that calls another stack. We do that by using the CloudFormation stack resource.  In CloudFormation, stacks are resources just like VPCs, subnets, etc.

Here is some doc on nesting:

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-nested-stacks.html

And here is the documentation for stack resources:

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-stack.html

You can chain stacks together multiple times, but we are going to keep it simple and just have a simple top level stack that calls the subnet stack.

Again back in the designer or in a text file, you will want to create something that looks like this, obviously replacing the S3 TemplateURL with your own.  This should be a completely separate template from the subnet template earlier!

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Resources": {
        "mySubnetStack": {
            "Type": "AWS::CloudFormation::Stack",
            "Properties": {
                "TemplateURL": "https://s3-external-1.amazonaws.com/cf-templates-dbp227s8qkrv-us-east-1/2018061ur6-subnet.templatehziulmqnqe5",
                "Parameters": {
                    "myCidrBlock": "172.10.20.0/24",
                    "myVPCName": "vpc-e456f39f"
                }
            }
        }
    },
    "Outputs": {
        "mySubnetId": { "Value": {"Fn::GetAtt": [ "mySubnetStack", "Outputs.mySubnetId"]}} 
    }
}

Again if you’ve followed along this should be more of the same.  We are creating a stack resource, referencing the location of the template file in S3.  We are also passing in the parameters needed to create the subnet – not in the Parameters section of the template but as a property of the subnet stack.  The only real oddity is the output which is referencing the stack output as an attribute.  So we use the Fn::GetAtt intrinsic function to reference and output this attribute.  You need to think of the subnet stack in this case as a resource and not as a template.

When we execute this stack, notice that our output is a little more interesting.  See how we actually have two stacks showing?  The outer parent and the child stack which is marked Nested.

6nestedstackinprogress

But other than that, the result is more or less the same.  There is an output in both the child and parent stacks that shows the subnet ID:

7subnetIdout

And we can view this subnet in the VPC:

8subnetinfo

With this ability to reuse CloudFormation templates, you can do some surprisingly powerful things.  Play around and see where it can help you out when deploying to AWS.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s