11 AWS Cloudformation Expert Tricks


I've collected a lot of useful tips in my work with Cloudfromation, which I would like to share.

1. Using an IDE with Autocomplete

For the Jetbrains IDEs like PHPStorm, Webstorm or IntelliJ there is a very good AWS Cloudfromation plugin called AWS Cloudfromation by Leonid Shalupov:

AWS Cloudfromation Plugin by Leonid Shalupov

This offers Autocomplete for the IDE and an automatic format check, whether attributes are set, which are not allowed there. On this way you can find many errors even before validating and saves a lot of time.

AWS Cloudfromation Autocomple

2. Using AWS CLI Commands

In order to test and deploy the templates in Cloudfromation, it is best to AWS CLI use to save a lot of time.

The most important commands for cloud formation are:

### stack anlegen:
#https://docs.aws.amazon.com/cli/latest/reference/cloudformation/create-stack.html
aws cloudformation create-stack  --template-body file://infrastructure/cloudformation.yml --stack-name myteststack

#### template validieren:
aws cloudformation validate-template --template-body file://infrastructure/cloudformation.yml

### status des stacks abrufen:
aws cloudformation describe-stacks --stack-name myteststack

### update stack
aws cloudformation update-stack --template-body file://infrastructure/cloudformation.yml --stack-name myteststack

### delete stack
aws cloudformation delete-stack --stack-name myteststack

## output ändern:
# json, table, text möglich
aws cloudformation describe-stacks --stack-name myteststack --output=text

3. Write multi-line text readable

files:
  /var/www/html/public/index.php:
    content: >-
      <html>
        <body>
          <h1>Welcome to the AWS CloudFormation PHP Sample</h1>
          <p/>
          <?php
            // Print out the current data and time
            print "The Current Date and Time is: <br/>";
            print date("g:i A l, F j Y.");
          ?>
          <?php  phpinfo(); ?>
        </body>
      </html>
    mode: '000600'
    owner: apache
    group: apache

4. Using variables in strings

/etc/httpd/conf.d/http-vhost.conf:
  content: !Sub
    - >-
      <Directory "/var/www/html/public">
         Options Indexes FollowSymLinks
         AllowOverride All
         Require all granted
      </Directory>

      <VirtualHost *:80>
         DocumentRoot "/var/www/html/public"
         ServerName "${Domain}"
      </VirtualHost>
    - { Domain: !Ref Domain }

5. Use two stacks for testing

To save time, I always use 2 Stacks to develop, these are created and deleted alternately, otherwise, you will have to wait for the stack to be deleted when developing.

CLI commands:

aws cloudformation create-stack  --template-body file://infrastructure/cloudformation.yml --stack-name myteststack

aws cloudformation delete-stack --stack-name myteststack
aws cloudformation create-stack  --template-body file://infrastructure/cloudformation.yml --stack-name myteststack2

aws cloudformation delete-stack --stack-name myteststack2
aws cloudformation create-stack  --template-body file://infrastructure/cloudformation.yml --stack-name myteststack

....

6. Building a Cloudfromation Template

The most important page of the cloud formation documentation is the Building a Cloud Formation Template.

"Resources": {
  "MyInstance": {
    "Type": "AWS::EC2::Instance",
    "Metadata" : {
      "AWS::CloudFormation::Init" : {
        "config" : {
          "packages" : {
            :
          },
          "groups" : {
            :
          },
          "users" : {
            :
          },
          "sources" : {
            :
          },
          "files" : {
            :
          },
          "commands" : {
            :
          },
          "services" : {
            :
          }
        }
      }
    },
    "Properties": {
      :
    }
  }
}

Here, among other things,. described, in which order the configuration sections are processed:

  1. packages
  2. groups
  3. users
  4. Sources
  5. Files
  6. Commands
  7. Services

In this order, the configuration sections should also be defined in the template.

7. Create Cronjob in Amazon Linux 2

Here are 2 Examples, how to work for different users (root and ec2-user) Crontabs creates:

InstallCrontab:
 files:
 /var/spool/cron/root:
 content: !Sub |
 # m h dom mon dow command
 39 1,13 * * * certbot renew --no-self-upgrade > /dev/null 2>&1

 mode: '000600'
 owner: root
 group: root

 /var/spool/cron/ec2-user:
 content: !Sub |
 # m h dom mon dow command
 */5 * * * * /usr/local/bin/aws-scripts-mon/mon-put-instance-data.pl --mem-avail --swap-used --disk-space-avail --disk-path=/ --from-cron > /dev/null 2>&1

 mode: '000600'
 owner: ec2-user
 group: ec2-user

8. yaml or json

Cloud formation offers 2 Formats to, which are indeed very different, json and yaml. I chose yaml, because there is less to write and the syntax easier to read. However, I noticed during the univing, that almost all questions on Stackoverflow are in json, which has shown a disadvantage.

Even better, however, is:

9. Use a framework

Unfortunately, you always end up with a huge file in yaml or json without a way to split the content or include other files.

That's why I would have a framework such as lono to recommend, to keep the code simpler and clear.

The ability to split a porject to multiple files also makes it easier to work with a VCS like GIT.

10. Debugging EC2 Instance Errors

Unfortunately, you often get the little telling error message:

 "Failed to receive 1 resource signal(s) within the specified duration"

Error message in the Cloudwatch interface

Here you should then call the EC2 System Log and search for the correct error message for the location “Cloud-init”:

11. Create Cloudwatch Alarm with CloudWatchMonitoringScripts

To secure its infrastructure, you can create Cloudwatch alarms, which, for example,. by email (Sns) benachrichten, if the CPU load is too high or there is too little free RAM or the hard drive is running full.

To get the data for the hard drive and the RAM, there are CloudWatchMonitoringScripts install and set up a cronjob.

This can be done with Cloudfromation as follows:

InstallAwsCloudwatchAgent:
  commands:
    downloadCloudWatchMonitoringScripts:
      command: "sudo curl -o /tmp/CloudWatchMonitoringScripts-1.2.2.zip  https://aws-cloudwatch.s3.amazonaws.com/downloads/CloudWatchMonitoringScripts-1.2.2.zip"

    unzipCloudWatchMonitoringScripts:
      command: "sudo unzip /tmp/CloudWatchMonitoringScripts-1.2.2.zip -d /usr/local/bin"

  packages:
    yum:
      perl-Switch: []
      perl-DateTime: []
      perl-Sys-Syslog: []
      perl-LWP-Protocol-https: []
      perl-Digest-SHA.x86_64: []
  files:
    /var/spool/cron/root:
      content: !Sub |
        # m h dom mon dow      command
        */5 * * * *   /usr/local/bin/aws-scripts-mon/mon-put-instance-data.pl --mem-avail --swap-used  --disk-space-avail --disk-path=/ --from-cron > /dev/null 2>&1

      mode: '000644'
      owner: root
      group: root

And you can then create an alarm:

CPUAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    AlarmName: MyCPUAlarm
    AlarmDescription: CPU alarm for ec2 instance
    AlarmActions:
      - arn:aws:sns:xxx
    MetricName: CPUUtilization
    Namespace: AWS/EC2
    Statistic: Average
    Period: '300'
    EvaluationPeriods: '3'
    Threshold: '50'
    ComparisonOperator: GreaterThanThreshold
    TreatMissingData:  missing
    Dimensions:
      - Name: InstanceId
        Value:
          Ref: WebServerInstance

MemoryAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    AlarmName: MyMemoryAlarm
    AlarmDescription: Memory alarm for ec2 instance
    AlarmActions:
      - arn:aws:sns:xxx
    MetricName: MemoryAvailable
    Namespace: System/Linux
    Statistic: Average
    Period: '300'
    EvaluationPeriods: '3'
    Threshold: '200'
    ComparisonOperator: LessThanOrEqualToThreshold
    TreatMissingData:  missing
    Dimensions:
      - Name: InstanceId
        Value:
          Ref: WebServerInstance

DiskSpaceAlarm:
  Type: AWS::CloudWatch::Alarm
  Properties:
    AlarmName: MyDiskSpaceAlarm
    AlarmDescription: Free Disk Space alarm for ec2 instance
    AlarmActions:
      - arn:aws:sns:xxxx
    MetricName: DiskSpaceAvailable
    Namespace: System/Linux
    Statistic: Average
    Period: '300'
    EvaluationPeriods: '3'
    Threshold: '5'
    ComparisonOperator: LessThanOrEqualToThreshold
    TreatMissingData:  missing
    Dimensions:
      - Name: InstanceId
        Value:
          Ref: WebServerInstance
      - Name: Filesystem
        Value: /dev/xvda1
      - Name: MountPath
        Value: /

 

 

Comments are closed.