Introduction to AWS Cloudformation

This is an outline of my approach towards building cloudformation templates. Each step within this outline is further assisted with AWS cloudformation documentation to make it simple to obtain additional information. My approach starts like so : I first hash out the structure of what I'm planning to build, then I define the resources in a JSON file, and finally I define the properties within those resources. The resulting end is a cloudformation template. To illustrate this approach, lets build an Elastic beanstalk cloudformation template from the ground up.

Define the Structure

Lets define the structure of what we are building. To define what we need, look through the AWS template resource types and note the resources we are going to be using to build an Elastic Beanstalk.

There are 3 parts to an Elastic Beanstalk :

  • Application (AWS::ElasticBeanstalk::Application)
  • Application Version (AWS::ElasticBeanstalk::ApplicationVersion)
  • Environment (AWS::ElasticBeanstalk::Environment)

The application is the foundation of the elastic beanstalk. An application needs at least 1 application version. Each application needs to have an environment and every environment needs a configuration.

Define the Resources

Create a JSON file and add the defined structure into the file.
Our Elastic Beanstalk structure should have all the resources defined like so.

{
    "Resources": {
        "nodeApplication": {
            "Type": "AWS::ElasticBeanstalk::Application",
            "Properties": {}
        },
        "nodeApplicationVersion": {
            "type": "AWS::ElasticBeanstalk::ApplicationVersion",
            "Properties": {}
        },
        "nodeEnvironment": {
            "Type": "AWS::ElasticBeanstalk::Environment",
            "Properties": {}
        }
    }
}

nodeApplication

This is the foundation of the Elastic Beanstalk. There are 2 properties that need to be defined for this resource.

  • Name
  • Description
        "nodeApplication": {
            "Type": "AWS::ElasticBeanstalk::Application",
            "Properties": {
                "Name": "Super Application",
                "Description": "This is a super cool Node.js Application"
            }
        }

nodeApplicationVersion

Elastic Beanstalk creates a new application version each time an application is launched.
Since we only care about launching a beanstalk at this point, we just need the applicationVersion to reference an AWS sample application.

Lets define the following parameters :

  • ApplicationName
  • Description
  • SourceBundle
        "nodeApplicationVersion": {
            "Type": "AWS::ElasticBeanstalk::ApplicationVersion",
            "Properties": {
                "ApplicationName": {
                    "Ref": "nodeApplication"
                },
                "Description": "This is a test node app",
                "SourceBundle": {
                    "S3Bucket": {
                        "Fn::Join": ["-", ["elasticbeanstalk-samples", {
                            "Ref": "AWS::Region"
                        }]]
                    },
                    "S3Key": "nodejs-sample.zip"
                }
            }
        }

The applicationName property is referencing the nodeApplication resource using the Reference (Ref) parameter.

The description set and finally the S3Bucket is defined in the sourceBundle property.

There is a lot going on in the S3Bucket property. Basically, what is happening is we are using an AWS intrinsic function (Fn::Join) to join 2 strings. We are joining "elasticbeanstalk-samples" with a pseudo region reference (AWS::region) the elastic beanstalk is created in. The function will output a string similar to "elasticbeanstalk-samples-us-west-2".

nodeEnvironment

The application environment relative to the application version. Lets define the following properties :

  • ApplicationName
  • SolutionStackName
  • OptionSettings
  • VersionLabel

ApplicationName

Application name should be the same as what is defined in the previous step.

SolutionStackName

Solution Stack specifies the environments operating system, architecture and application server. You can view a list of solution stacks running the following command in the terminal : aws elasticbeanstalk list-available-solution-stacks

To learn more about solution stacks you can visit this page here.

OptionSettings

The configurations for the environment can be set in 2 ways. You can add a configuration resource and reference the resource in the templateName property like this templateName:{"Ref":"NodeConfig"} or you can define the environment configurations in the OptionsSettings property array.

Lets set the environment configurations in the OptionSettings property.

The optionSettings property is an object array that contains configuration properties from different resources.

VersionLabel

VersionLabel will point to the applicationVersion that we have defined in the previous step.

        "nodeEnvironment": {
            "Type": "AWS::ElasticBeanstalk::Environment",
            "Properties": {
                "ApplicationName": {
                    "Ref": "nodeApplication"
                },
                "SolutionStackName": "64bit Amazon Linux 2017.03 v4.1.0 running Node.js",
                "OptionSettings": [{
                        "Namespace": "aws:autoscaling:launchconfiguration",
                        "OptionName": "InstanceType",
                        "Value": "t1.micro"
                    }],
                    "VersionLabel": {
                        "Ref": "nodeApplicationVersion"
                    }
                }
            }

Final Cloudformation Template

Your final cloudformation template should be similar to the following :

{
    "Resources": {
        "nodeApplication": {
            "Type": "AWS::ElasticBeanstalk::Application",
            "Properties": {
                "Name": "Node Cloudformation",
                "Description": "Cloudformation"
            }
        },
        "nodeApplicationVersion": {
            "Type": "AWS::ElasticBeanstalk::ApplicationVersion",
            "Properties": {
                "ApplicationName": {
                    "Ref": "nodeApplication"
                },
                "Description": "Initial Version",
                "SourceBundle": {
                    "S3Bucket": {
                        "Fn::Join": ["-", ["elasticbeanstalk-samples", {
                            "Ref": "AWS::Region"
                        }]]
                    },
                    "S3Key": "nodejs-sample.zip"
                }


            }
        },
        "nodeEnvironment": {
            "Type": "AWS::ElasticBeanstalk::Environment",
            "Properties": {
                "ApplicationName": {
                    "Ref": "nodeApplication"
                },
                "SolutionStackName": "64bit Amazon Linux 2017.03 v4.1.0 running Node.js",
                "OptionSettings": [{
                        "Namespace": "aws:autoscaling:launchconfiguration",
                        "OptionName": "InstanceType",
                        "Value": "t1.micro"
                    }],
                    "VersionLabel": {
                        "Ref": "nodeApplicationVersion"
                    }
                }
            }
        }
}

-->