CloudFormation security validation


Here at globaldatanet we especially enjoy building as much as automation possible for us and our clients' deployments. 

Today we are going to quickly cover an important security validation topic that you're probably aware of by now, to make sure all CloudFormation code follows the best practices and it's secure when deploying new or existing infrastructure.

The problem:

We use the cfn-nag tool to verify all the CloudFormation templates that we ship to production, this means that as part of our Codepipeline we have a build step in-place (could be an AWS Lambda or a Codebuild) which will run the security validation.

We like some efficiency 😎

  • The Build execution should be fast as possible, so the idea is to only run the files from the last commit pushed instead of going through the complete repo structure every time (which can become an issue when dealing with hundreds of CloudFormation templates). 
  • We should also skip files that are not either .YAML or .YML (we never use JSON for our CF templates).
  • We should be able to run a complete scan whenever we need.
  • An error in one of the templates should fail the Codepipeline execution.

The solution:

Taking into consideration all the requirements we decided to use a Codebuild for it, giving us more flexibility, easiness to implement and visualization if something happens. 

Note: As an alternative, the cfn-nag is also available from the AWS Lambda public serverless app repository, you can integrate easily the cfn-nag-pipeline function into your Codepipeline.

Our use case:

We use Codecommit as our Codepipeline source, but our Bash script also supports any git-like repo, as long as you choose to pass the .git files to Codebuild. By getting the list of the CF files from the last commit we can then run cfn-nag agaist thiose files only.

eg. Codebuild settings

In a nutshell:

  • The cfn-nag runs in a Codebuild (right after the Codepipeline source stage).
  • It validates all the CloudFormation files (from the last commit pushed, but also supports a "full scan" bypassing the argument to the Codebuild buildspec file or when you run the Codebuild from the 1st time).
  • Does also an optional cfn-lint Syntax validation.
  • If a CloudFormation template contains too permissive IAM policies, Security Group rules, NACLs, etc the Codebuild process will fail and consequently, the Codepipeline interrupts the normal deployment.

Example of successful/validated build:

eg. Information of latest git commit before starting the validation

eg. Output of successful validation

Example of a failed build job:

eg. Output of failed validation

We are globaldatanet are big fans of opensource and code sharing, so here it goes, the bash script, the buildspec file for the Codebuild and some examples for a simple Codepipeline.


version: 0.2
        ruby: 2.6    
    - pip3 install awscli --upgrade --quiet
    - pip3 install cfn-lint --quiet
    - aws --version              
    - yum install jq git -y -q
    - gem install cfn-nag
    - cfn_nag_rules # Show all cfn_nag_rules that will be used in the scan
    - scriptToExecute=`find $(pwd)/ \( -name "" \) `
    - chmod +x "$scriptToExecute"
    - bash "$scriptToExecute" --full_scan no --codecommit-repository_name NAME-OF-YOUR-CODECOMMIT-REPO --codebuild_project_name NAME-OF-CODEBUILD-PROJECT
  files: '**/*'

Download the template validation script here:

Keep in touch! We would love to hear from you and/or help you build the next amazing automation on AWS 😎


DevOps tools you should have on your belt

A collection of tools that will help you to improve your daily work.


Nov 10th 2020


David Krohn

CloudFormation Best Practices

Recommendations that can help you to use CloudFormation more effectively and securely throughout its entire workflow.


Oct 20th 2020


David Krohn

Share your ACM Private CA cross-account

How to automate AWS RAM to share your ACM Private CA cross-account


Sep 3rd 2020


David Krohn