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.

CodebuildSettings
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:

CodebuildLogInfo
eg. Information of latest git commit before starting the validation

CodebuildSuccess
eg. Output of successful validation

Example of a failed build job:

CodebuildFailure
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.

buildspec.yml

version: 0.2
phases:
  install:
    runtime-versions:
        ruby: 2.6    
    commands:
    - 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
  build:
    commands:
    - scriptToExecute=`find $(pwd)/ \( -name "CfnTemplateValidation.sh" \) `
    - chmod +x "$scriptToExecute"
    - bash "$scriptToExecute" --full_scan no --codecommit-repository_name NAME-OF-YOUR-CODECOMMIT-REPO --codebuild_project_name NAME-OF-CODEBUILD-PROJECT
artifacts:
  files: '**/*'

Download the template validation script here: CfnTemplateValidation.sh

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




DevOps on AWS like a Rockstar

DevOps Automation on AWS

Jun 6th 2019

Alan Kiš

Custom Resource with CloudFormation

How to invoke Custom Resources each time when your CloudFormation Stack is being updated.

Jun 1st 2019

David Krohn