CloudFormation Static Code Analysis

CloudFormation Static Code Analysis

Firstly, I'll explain the scenario, A few friends of mine are building a startup and want to enforce strong security measures on their infrastructure from the initial phase to avoid future headaches of rework things after golive, They’ve asked for suggestions on how to enhance security in their Infrastructure as Code (CloudFormation). Specifically, they need a workflow in their CI/CD pipeline to ensure that all infrastructure changes adhere to AWS security best practices before trigger the deployments.

Let’s. reconfirm the requirements first:
"Static code analyser on CloudFormation" and it should integrate with CI/CD Pipeline for seamless Infrastructure deployment flow also pipeline should fail its execution if there is any anti-patterns or security issue in code before deploy it in production.

  1. It should come with all minimum required rules to enforce security, I don't want to write the rules from the scratch.

  2. There should be an option to add exceptions in the rules.

  3. there should be some easy way to validate like rule-checker validate in code editor before committing so we can catch those missing items before committing.

  4. light weight cli option is better as we have to run this during the build, lets avoid complex setups.

  5. It's ideal to have the option to add custom rules without the need to write complex modules.

  6. We prefer not to make any changes to the CloudFormation template or transform it into another language for validation purposes.

Exploring solutions for a problem is always fascinating thing as there is lots of reading / comparison/ testing and tradeoff between the available solution with our requirements with other factors eg:- Operations efforts , cost , ease of integrations etc-

Phase-1: Search & Shortlist solutions

Search as much as possible and note down the possible solution for this usecase, there were lots of options but I just shortlisted below tools.

  1. cfn-nag: cfn-nag is a popular tool developed by Stelligent for scanning CloudFormation templates for security issues based on predefined rules. It is written in Ruby and provides a simple way to identify common security concerns

  2. cfripper:
    cfripper is an open-source tool developed by GoDaddy to analyze CloudFormation templates for security vulnerabilities and compliance issues. It is written in Python and supports custom rules, allowing you to extend its capabilities as needed.

  3. cfn-guard
    AWS CloudFormation Guard is an open-source general-purpose policy-as-code evaluation tool. It provides developers with a simple-to-use, yet powerful and expressive domain-specific language (DSL) to define policies and enables developers to validate JSON- or YAML- formatted structured data with those policies.

Phase-2: Deep dive to features and compare with our requirements

let's read bit more and note down interesting features and information about each.

Just overview:

  1. cfripper: Designed by GoDaddy, cfripper focuses on analyzing CloudFormation templates for security vulnerabilities and compliance issues. It aims to identify potential risks in the templates to ensure a secure and compliant infrastructure.

  2. cfn-nag is a tool maintained by stelligent that scans CloudFormation templates for security risks and compliance issues based on predefined rules. It aims to help users identify issues related to security best practices.

  3. cfn-guard: cfn-guard enables you to define custom policy rules using its domain-specific language. It allows you to enforce specific organizational requirements, naming conventions, and more in addition to security checks.

2. Customization:

  • cfripper: Supports custom rules, allowing users to extend its capabilities and define their own rules to suit their specific security and compliance requirements.

  • cfn-nag: Offers predefined rules for security and best practices checks. While you can choose which rules to include or exclude, it doesn’t provide the same level of flexibility as cfripper or cfn-guard.

  • cfn-guard: Allows users to define custom policy rules using a custom language, providing a high level of customization and control over policy enforcement.

3. Ease of Use:

  • cfripper: The ease of use may depend on your familiarity with Python and the tool’s syntax. Customizing rules may require a certain level of scripting knowledge.

  • cfn-nag: Relatively straightforward to use, especially if you don’t require extensive customization.

  • cfn-guard: Custom rule definition might require a learning curve due to the custom language.

4. Integration:

  • All three tools can be integrated into CI/CD pipelines to automate template analysis before deployment with CLI options.

5. Community and Documentation:

  • cfripper: Developed by GoDaddy, its community and documentation may be growing.

  • cfn-nag: Has an established user base and documentation.

  • cfn-guard: Well-documented and maintained, with flexibility for custom rule creation.

Given the information provided, “cfripper” appears to share similarities with both “cfn-nag” and “cfn-guard” in terms of its focus on CloudFormation template security analysis. The choice between these tools may depend on factors such as customization needs, ease of use, and the level of control you require over rule creation and enforcement.

For the most accurate and up-to-date comparison, I recommend reviewing the documentation for each tool and potentially testing them in your environment to assess how well they meet your specific requirements for CloudFormation template security analysis.

Phase-3 : Lets play with these tools :-)


Follow below official GitHub page and follow the installation procedure in

How to use it , just use cfn_nag_scan command like below, it will show WARN & ERROR incase its found any missing best practice for antipatterns in code, its such a simple tool.

❯ cfn_nag_scan -i ./CloudFormation/nestedstacks/backend-stack.cfn.yml
| WARN W79
| Resource: ["ECRBackendRepository"]
| Line Numbers: [87]
| ECR Repository should have ScanOnPush enabled

Note: removed other security warning.


❯ cfripper ./CloudFormation/nestedstacks/backend-stack.cfn.yml --format txt
Issues found:
        - EC2SecurityGroupOpenToWorldRule: Port(s) 443 open to public IPs: ( in security group 'BackendLoadbalancerSecurityGroup'
        - FullWildcardPrincipalRule: BackendPublicObjectS3BucketPolicy should not allow full wildcard `*`, or wildcard in account ID like `arn:aws:iam::*:12345` at `*`
        - GenericResourceFullWildcardPrincipalRule: ECRBackendRepository should not allow full wildcard `*`, or wildcard in account ID like `arn:aws:iam::*:12345` at `*`
        - GenericResourceFullWildcardPrincipalRule: BackendPublicObjectS3BucketPolicy should not allow full wildcard `*`, or wildcard in account ID like `arn:aws:iam::*:12345` at `*`
        - S3LifecycleConfigurationRule: S3 Bucket AlbLogsBucket is required to contain a LifecycleConfiguration property
        - S3LifecycleConfigurationRule: S3 Bucket BackendPrivateObjectBucket is required to contain a LifecycleConfiguration property
        - S3LifecycleConfigurationRule: S3 Bucket BackendPublicObjectBucket is required to contain a LifecycleConfiguration property
        - S3ObjectVersioningRule: S3 Bucket AlbLogsBucket is required to have object versioning enabled
        - S3ObjectVersioningRule: S3 Bucket BackendPrivateObjectBucket is required to have object versioning enabled


❯ cfn-guard validate --data ./CloudFormation/nestedstacks/backend-stack.cfn.yml --rules ./rules/rules.guard
/Users/midhun.k/repo/demo/iris-coreinfra/CloudFormation/nestedstacks/backend-stack.cfn.yml Status = FAIL
FAILED rules
rules.guard/BucketEncryption    FAIL
Evaluating data /Users/midhun.k/repo/demo/static-demo/CloudFormation/nestedstacks/backend-stack.cfn.yml against rules rules.guard
Number of non-compliant resources 3
Resource = AlbLogsBucket {
  Type      = AWS::S3::Bucket
  Rule = BucketEncryption {
    ALL {
      Check = GuardBlockAccessClause #Location[file:rules.guard, line:5, column:5] {
        RequiredPropertyError {
          PropertyPath       = /Resources/AlbLogsBucket/Properties
          MissingProperty    = BucketEncryption.ServerSideEncryptionConfiguration[*]
          Error               = Check was not compliant as property [BucketEncryption.ServerSideEncryptionConfiguration[*]] is missing. Value traversed to [Path=/Resources/AlbLogsBucket/Properties[L:173,C:6] Value={"BucketName":{"Fn::Sub":"demobucket-accesslogs-${Environment}"}}]
              171.  AlbLogsBucket:
              172.    Type: AWS::S3::Bucket
              173.    Properties:
              174.      BucketName: !Sub 'demobucket-accesslogs-${Environment}' 
              176.  AlbLogsBucketPolicy:

In conclusion, My decision was based on my specific requirements. As outlined in second step, each tool has its unique features and benefits. In my case,I chose cfn-nag primarily for its simplicity, along with a few other specified requirements, so always understand your requirements completely before jump into the conclusions there is no tool is full proof solution for our issues we'll have to select most matching solution for our requirements, understanding our exact requirement is the key here, anyway no more boring talk just winding this up

Thanks for reading:
Diagrams | Images | Gif's are not created by me - All credit for that goes to the creators.

📚 "Stay in the know! Subscribe to the blog for the latest insights on tech trends, DevOps and Cloud strategies, and more. 📚#StayTuned
- Site

Did you find this article valuable?

Support Midhun K by becoming a sponsor. Any amount is appreciated!