paint-brush
How To Use AWS CloudFormation To Reduce Redundancyby@surbhi-khandelwal
155 reads

How To Use AWS CloudFormation To Reduce Redundancy

by Surbhi KhandelwalSeptember 19th, 2020
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

AWS CloudFormation is a service that allows developers and businesses to create a collection of their AWS and third party resources in an easy way and provision them. It helps in automating and simplifying repeated tasks like creating groups of all the related resources that are used in your applications. It can be written in a file called a template. A template file consists of the individual configuration of all AWS services, within a single file. We will keep it brief for the scope of this article, but it offers a GUI to create templates.

Coin Mentioned

Mention Thumbnail
featured image - How To Use AWS CloudFormation To Reduce Redundancy
Surbhi Khandelwal HackerNoon profile picture

Mr. X has been working on a very interesting, and meticulously written web application involving some heavy computation and a complete test suite. He architects the system well and chooses to host his application over AWS.

He uses AWS RDS for his database, AWS EC2 to serve his application and AWS Lambda to do the heavy calculations. He also Dockerized his entire application in order to seamlessly build and deploy his work at his will. 

Everything was set, the app was working amazingly, so he scheduled a demo with a potential client. He was making some last-minute changes and everything was still working well. So, right before the demo, it was time for deployment. 

Mr. X deployed the Lambda application quickly and proceeded to rebuild his Docker images. He pulled the code on his EC2 machine but forgot to rebuild his Docker images. Instead, on the spur of the moment, he simply restarted his containers and proceeded for the demo. It takes no guesswork to learn that the demo didn’t go well.

Every other developer has a similar story to share at some point in time. But could this be avoided? The answer is yes! Could deployment be automated across all your AWS services at once so that your whole application gets deployed in one go? Again, yes!

AWS CloudFormation makes it possible.

Understanding CloudFormation: Stacks and Templates

AWS CloudFormation is a service that allows developers and businesses to create a collection of their AWS and third party resources in an easy way and provision them. AWS CloudFormation helps in automating and simplifying repeated tasks like creating groups of all the related resources that are used in your applications. 

Basically, AWS CloudFormation makes creating and interconnecting all the resources that are needed by your application as simple as creating a single EC2 or RDS instance.

So clearly, CloudFormation can help us in automated deployment across all your AWS services at once so your whole application can get deployed in one go. Now let’s understand what exactly it does and how. We will keep it brief for the scope of this article.

CloudFormation essentially “stacks” up your entire application based on the AWS services you’re using. A stack is a collection of your AWS services. In the case of Mr. X from our case study, his stack would comprise of EC2, Lambda, and RDS.

CloudFormation manages a deployment configuration against each service you are using. This configuration is written in a file called a template. It can be written in either YAML or JSON. A template file consists of the individual configuration of all the AWS services, within a single file.

Deploying a Stack

Before we start writing the template, we need to see what we should achieve after creating them. In order to do that, login to your AWS console and search for CloudFormation under “Find services”.

Select CloudFormation and click on “Create stack” as shown below.

On the next screen, let’s go with “Template is ready” for now. The “Create template in Designer” option is out of scope for this article, but it offers a GUI to create templates.

Also let’s select “Upload a template file” under Specify template.

As you can see, templates can be hosted on S3 as well.

Let’s first see what happens when a template file is uploaded.

As shown in the image above, you need to set a stack name, and then enter parameters for each resource that you are going to use/create. In this example, a MySQL database is being created.

Let’s click “Next”. Now a Stack options page will be shown which is used to set advanced options for a stack. We can discuss them in subsequent articles. Let’s click “Next” again.

This is the final screen to review the stack before it is actually created, built, and deployed. This page has a “Create stack” button, let’s hit it to create the stack.

Finally, the stack creation and deployment is in progress. Once you refresh the stack, you’ll be able to pull in the latest state of the stack. If all goes well, the status should change to green CREATE_COMPLETE text with a green checkmark. Now let’s see how to make a template in order to configure a stack.

Writing a Template

Before we start writing templates, let’s look at the elements of an AWS CloudFormation template:

Elements of an AWS CloudFormation template

AWS CloudFormation templates are text files that can be written in JSON or YAML. These files generally comprise of five types of elements:

  1. list of template parameters (input values supplied at stack creation time - optional)
  2. list of output values (e.g. the complete URL to a web application - optional)
  3. list of data tables used to lookup static configuration values (e.g., AMI names - optional)
  4. list of all AWS resources that your application is using and their configuration values

A template file format version number

Let’s first select the services that we need to configure. Let’s assume we need to set up two EC2 instances (one with the application, and the other with the database). 

Let’s assume that we have a Python application communicating with MySQL database. Template configuration for an EC2 instance can
look like this:

And the template configuration for RDS can as as follows:

Resources:
  Ec2Instance:
    Type: ‘AWS::EC2::Instance’
    Properties:
      SecurityGroups:
        – !Ref InstanceSecurityGroup
        – MyExistingSecurityGroup
      KeyName: mykey
      ImageId: ami-7a11e213
  InstanceSecurityGroup:
    Type: ‘AWS::EC2::SecurityGroup’
    Properties:
      GroupDescription: Enable SSH access via port 22
      SecurityGroupIngress:
        – IpProtocol: tcp
          FromPort: ’22’
          ToPort: ’22’
          CidrIp: 0.0.0.0/0

And the template configuration for RDS can as as follows:

Parameters:
  DBInstanceID:
    Default: mydbinstance
    Description: My database instance
    Type: String
    MinLength: ‘1’
    MaxLength: ’63’
    AllowedPattern: ‘[a-zA-Z][a-zA-Z0-9]*’
    ConstraintDescription: >-
      ( You have to begin with a letter and it should not end with a hyphen or double hyphen)

  DBName:
    Default: mydb
    Description: My database
    Type: String
    MinLength: ‘1’
    MaxLength: ’64’
    AllowedPattern: ‘[a-zA-Z][a-zA-Z0-9]*’
    ConstraintDescription: ( You must begin with a letter and the rest should be alphanumeric characters.)
  DBInstanceClass:
    Default: db.m5.large
    Description: DB instance class
    Type: String
    ConstraintDescription: Must select a valid DB instance type.
  DBAllocatedStorage:
    Default: ’50’
    Description: The size of the database (GiB)
    Type: Number
    MinValue: ‘5’
    MaxValue: ‘1024’
    ConstraintDescription: must be between 20 and 65536 GiB.
  DBUsername:
    NoEcho: ‘trueDescription: Username for MySQL database access
    Type: String
    MinLength: ‘1’
    MaxLength: ’16’
    AllowedPattern: ‘[a-zA-Z][a-zA-Z0-9]*’
    ConstraintDescription: ( You must begin with a letter and the rest should be alphanumeric characters.)
  DBPassword:
    NoEcho: ‘trueDescription: Password MySQL database access
    Type: String
    MinLength: ‘8’
    MaxLength: ’41’
    AllowedPattern: ‘[a-zA-Z0-9]*’
    ConstraintDescription: (You can only use alphanumeric characters.)
Resources:
  MyDB:
    Type: ‘AWS::RDS::DBInstanceProperties:
      DBInstanceIdentifier: !Ref DBInstanceID
      DBName: !Ref DBName
      DBInstanceClass: !Ref DBInstanceClass
      AllocatedStorage: !Ref DBAllocatedStorage
      Engine: MySQL
      EngineVersion: 8.0.16
      MasterUsername: !Ref DBUsername
      MasterUserPassword: !Ref DBPassword
      MonitoringInterval: ’60’
      MonitoringRoleArn: ‘arn:aws:iam::123456789012:role/rds-monitoring-role

Hope That Helps

And that’s about it! To sum up, we create a template file, we specify our resources and parameters according to our requirements that enable the resources, then we use this template to create a CloudFormation stack, which in turn auto-provisions these resources to us. The next time you make a deployment and you’re still not using CloudFormation, do take a moment to think about Mr.X.