Creating a Dockerfile with all AWS CloudFormation test tools

About Advent Calendar

This is the 22nd day article of the Advent Calendar "Japan APN Ambassador Advent Calendar 2020" by APN Ambassador. For more information on APN Ambassador, please see the following articles.

-What is APN Ambassador? -APN Ambassador Program is a world standard!

Please note that the content of the post is my personal opinion and does not represent the company to which I belong.

Introduction

When writing AWS CloudFormation in YAML or JSON, it is difficult to visually review the contents of the template, such as grammar and parameter types. Therefore, there are various tools to make it easier to test CloudFormation. In this article, we will introduce these tools and aim to define the introduction of the introduced tools in Dockerfile and reuse them.

Tool introduction

Tools range from those that come with the AWS CLI to those that are open source. I will introduce them one by one.

① aws cloudformation validate-template

image.png

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cloudformation/validate-template.html

Execution example

bash-4.2# aws cloudformation validate-template --template-body file://./vpcsample-template.yaml 

An error occurred (ValidationError) when calling the ValidateTemplate operation: Template format error: YAML not well-formed. (line 26, column 17)

② cfn-lint

image.png

https://github.com/aws-cloudformation/cfn-python-lint

Execution example

bash-4.2# cfn-lint vpcsample-template.yaml
W3010 Don't hardcode ap-northeast-1a for AvailabilityZones
vpcsample-template.yaml:18:13

③ taskcat

https://github.com/aws-quickstart/taskcat

.taskcat.yml sample

project:
   name: taskcat-example
   regions:
      - ap-northeast-1
      - us-east-1
   tests:
      vpcsample:
         template: ./vpcsample-template.yaml

Execution example

bash-4.2# taskcat test run 

version 0.9.20
[INFO   ] : Linting passed for file: /workspaces/awsdev/work/vpcsample-template.yaml
[S3: -> ] s3://tcat-taskcat-example-XXXXXXXXXXXXXX/taskcat-example/vpcsample-template.yaml
[INFO   ] : ┏ stack Ⓜ tCaT-taskcat-example-vpcsample-2a58141fb6114aed895774ebfcac9ed2                                        
[INFO   ] : ┣ region: ap-northeast-1                                                                                         
[INFO   ] : ┗ status: CREATE_COMPLETE                                                                                        
[INFO   ] : ┏ stack Ⓜ tCaT-taskcat-example-vpcsample-2a58141fb6114aed895774ebfcac9ed2                                        
[INFO   ] : ┣ region: us-east-1                                                                                              
[INFO   ] : ┗ status: CREATE_COMPLETE                                                                                        
[INFO   ] : Reporting on arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/tCaT-taskcat-example-vpcsample-2a58141fb6114aed895774ebfcac9ed2/7e9705c0-2747-11eb-861d-0aff14bc0982
[INFO   ] : Reporting on arn:aws:cloudformation:us-east-1:XXXXXXXXXXXX:stack/tCaT-taskcat-example-vpcsample-2a58141fb6114aed895774ebfcac9ed2/7fc94430-2747-11eb-bfb5-1246411399d1
[INFO   ] : Deleting stack: arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/tCaT-taskcat-example-vpcsample-2a58141fb6114aed895774ebfcac9ed2/7e9705c0-2747-11eb-861d-0aff14bc0982
[INFO   ] : Deleting stack: arn:aws:cloudformation:us-east-1:XXXXXXXXXXXX:stack/tCaT-taskcat-example-vpcsample-2a58141fb6114aed895774ebfcac9ed2/7fc94430-2747-11eb-bfb5-1246411399d1
[INFO   ] : ┏ stack Ⓜ tCaT-taskcat-example-vpcsample-2a58141fb6114aed895774ebfcac9ed2                                        
[INFO   ] : ┣ region: ap-northeast-1                                                                                         
[INFO   ] : ┗ status: DELETE_COMPLETE                                                                                        
[INFO   ] : ┏ stack Ⓜ tCaT-taskcat-example-vpcsample-2a58141fb6114aed895774ebfcac9ed2                                        
[INFO   ] : ┣ region: us-east-1                                                                                              
[INFO   ] : ┗ status: DELETE_COMPLETE

Report sample (text)

bash-4.2# cat tCaT-taskcat-example-vpcsample-2a58141fb6114aed895774ebfcac9ed2-ap-northeast-1-cfnlogs.txt
-----------------------------------------------------------------------------
Region: ap-northeast-1
StackName: tCaT-taskcat-example-vpcsample-2a58141fb6114aed895774ebfcac9ed2
*****************************************************************************
ResourceStatusReason:  
Stack launch was successful
*****************************************************************************
*****************************************************************************
Events:  
TimeStamp                         ResourceStatus      ResourceType                LogicalResourceId                                                ResourceStatusReason
--------------------------------  ------------------  --------------------------  ---------------------------------------------------------------  ---------------------------
2020-11-15 13:36:54.256000+00:00  CREATE_COMPLETE     AWS::CloudFormation::Stack  tCaT-taskcat-example-vpcsample-2a58141fb6114aed895774ebfcac9ed2
2020-11-15 13:36:52.656000+00:00  CREATE_COMPLETE     AWS::EC2::Subnet            TestSubnet01
2020-11-15 13:36:40.587000+00:00  CREATE_COMPLETE     AWS::EC2::Subnet            TestSubnet03
2020-11-15 13:36:40.280000+00:00  CREATE_COMPLETE     AWS::EC2::Subnet            TestSubnet02
2020-11-15 13:36:36.368000+00:00  CREATE_IN_PROGRESS  AWS::EC2::Subnet            TestSubnet01                                                     Resource creation Initiated
2020-11-15 13:36:35.712000+00:00  CREATE_IN_PROGRESS  AWS::EC2::Subnet            TestSubnet01
2020-11-15 13:36:24.163000+00:00  CREATE_IN_PROGRESS  AWS::EC2::Subnet            TestSubnet03                                                     Resource creation Initiated
2020-11-15 13:36:24.147000+00:00  CREATE_IN_PROGRESS  AWS::EC2::Subnet            TestSubnet02                                                     Resource creation Initiated
2020-11-15 13:36:23.594000+00:00  CREATE_IN_PROGRESS  AWS::EC2::Subnet            TestSubnet03
2020-11-15 13:36:23.442000+00:00  CREATE_IN_PROGRESS  AWS::EC2::Subnet            TestSubnet02
2020-11-15 13:36:21.092000+00:00  CREATE_COMPLETE     AWS::EC2::VPC               TestVPC
2020-11-15 13:36:04.224000+00:00  CREATE_IN_PROGRESS  AWS::EC2::VPC               TestVPC                                                          Resource creation Initiated
2020-11-15 13:36:03.612000+00:00  CREATE_IN_PROGRESS  AWS::EC2::VPC               TestVPC
2020-11-15 13:35:59.310000+00:00  CREATE_IN_PROGRESS  AWS::CloudFormation::Stack  tCaT-taskcat-example-vpcsample-2a58141fb6114aed895774ebfcac9ed2  User Initiated
*****************************************************************************
-----------------------------------------------------------------------------
Tested on: Sunday, 15. November 2020 01:37PM

Report sample (HTML)

image.png

④ cfn_nag

image.png

https://github.com/stelligent/cfn_nag

Execution example

bash-4.2# cfn_nag_scan --input-path vpcsample-template.yaml 
------------------------------------------------------------
vpcsample-template.yaml
------------------------------------------------------------------------------------------------------------------------
| WARN W60
|
| Resources: ["TestVPC"]
| Line Numbers: [5]
|
| VPC should have a flow log attached

Failures count: 0
Warnings count: 1

⑤ CloudFormation Guard

image.png

https://github.com/aws-cloudformation/cloudformation-guard

Execution example

bash-4.2# cfn-guard check -t Examples/ebs_volume_template.json -r Examples/ebs_volume_template.ruleset

[NewVolume2] failed because [Encrypted] is [false] and the permitted value is [true]
[NewVolume] failed because [Encrypted] is [false] and the permitted value is [true]
[NewVolume] failed because [Size] is [500] and the permitted value is [<= 100]
Number of failures: 3

Pack test tools into Dockerfile

It can also be run with VSCode Remote Containers.

Also, since privilege is required to execute taskcat, let's move it by referring to the link below. This article is titled VSCode Remote Containers, but if you don't use VSCode Remote Containers, you can follow the steps up to the point of attachment. How to develop in a container with --privileged and/sbin/init passed in VSCode Remote Containers

# AWS CLI v2 (Official)
FROM amazon/aws-cli:latest

# To install Visual Studio Code Server
# and modules
RUN yum -y update && \
    yum -y install tar gzip git

# To install pip
RUN curl -kL https://bootstrap.pypa.io/get-pip.py | python

# To install cfn-lint
RUN pip install cfn-lint

# To install taskcat
RUN yum -y install python3 && \
    pip3 install taskcat

# To install docker (for taskcat)
RUN amazon-linux-extras install -y docker

# To install cfn-nag & CloudFormation Guard
RUN yum -y install bzip2 gcc make openssl-devel && \
    git clone https://github.com/sstephenson/rbenv.git ~/.rbenv && \
    echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile && \
    echo 'eval "$(rbenv init -)"' >> ~/.bash_profile && \
    source ~/.bash_profile && \
    git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build && \
    ~/.rbenv/plugins/ruby-build/install.sh && \
    rbenv install 2.7.2 && \
    rbenv global 2.7.2 && \
    gem install cfn-nag && \
    yum -y install wget && \
    wget https://github.com/aws-cloudformation/cloudformation-guard/releases/download/1.0.0/cfn-guard-linux-1.0.0.tar.gz && \
    tar -xvf cfn-guard-linux-1.0.0.tar.gz -C ~/

# To clean up
RUN yum clean all

Points that made a decision when creating a Dockerfile

I think the point is which container image to put in FROM, but this time I chose amazon/aws-cli: latest. This image is the official AWS CLI v2 Docker image. Reference: Using Official AWS CLI Version 2 Docker Image

I chose this image because I thought it would be better to use the official image to get support related to the AWS CLI.

However, instead, installing and running cfn-nag requires a rather tedious procedure to install Ruby. That said, if you use the image of ruby, installing the AWS CLI will be a little troublesome this time, so even if you consider the advantages and disadvantages, it was difficult to make a decision.

Summary and for the future

References

Recommended Posts

Creating a Dockerfile with all AWS CloudFormation test tools
Creating a test case
[Rails] Creating a new project with rails new
Creating a timer app with a muddy
Creating a browser automation tool with Ruby + Selenium
I built a Code Pipeline with AWS CDK.
Make System.out a Mock with Spock Test Framework
Creating a common repository with Spring Data JPA