DEV Community

Cao Duy Khanh
Cao Duy Khanh

Posted on

Static Analysis for CloudFormation

To satisfy CloudFormation is well, we should apply static analysis tool for it.
Today, I would like 2 static analysis tools:

  • cfn-lint: Verify that the template is correct.
  • cfn-nag: Verify that there is no code that poses a security risk.

Sections

Setup

  • cfn-lint
pip install cfn-lint
Enter fullscreen mode Exit fullscreen mode
  • cfn_nag
gem install cfn-nag
Enter fullscreen mode Exit fullscreen mode
  • setup cloudformation template with name s3.yml
AWSTemplateFormatVersion: '2010-09-09'

Description: S3 Cloudformation Template

Parameters:

  EnvironmentStage: 
    AllowedValues:
      - "Dev"
      - "Stg"
      - "Prod"
    Default: "Dev"
    Description: "Environment Dev, Staging, Production"
    Type: String

Resources:

  WebCmsOAI:
    Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
    Properties:
      CloudFrontOriginAccessIdentityConfig:
        Comment: Origin Access Identity for Web Cms S3 Bucket

  WebCmsBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub '${AWS::StackName}-web-cms'
      CorsConfiguration:
        CorsRules:
        - AllowedHeaders:
          - '*'
          AllowedMethods:
          - GET
          - PUT
          AllowedOrigins:
          - '*'
          MaxAge: 3000
      VersioningConfiguration:
        Status: Enabled
      WebsiteConfiguration:
        ErrorDocument: index.html
        IndexDocument: index.html

  WebCmsBucketPolicy:
    Type: AWS::S3::BucketPolicy
    DependsOn: WebCmsBucket
    Properties:
      Bucket: !Ref WebCmsBucket
      PolicyDocument:
        Statement:
          - Action:
              - 's3:GetObject'
            Effect: Allow
            Resource: !Sub 'arn:aws:s3:::${AWS::StackName}-web-cms/*'
            Principal: 
              CanonicalUser: !GetAtt WebCmsOAI.S3CanonicalUserId

Outputs:
  WebCmsBucket:
    Value: !Ref WebCmsBucket
    Export:
      Name: !Sub '${AWS::StackName}-WebCmsBucket'

  WebCmsBucketEndpoint:
    Value: !Join
      - ''
      - - !GetAtt
           - WebCmsBucket
           - RegionalDomainName
    Export:
      Name: !Sub '${AWS::StackName}-WebCmsBucketEndpoint'

  WebCmsOAI:
    Value: !Ref WebCmsOAI
    Export:
      Name: !Sub ${AWS::StackName}-WebCmsOAI

Enter fullscreen mode Exit fullscreen mode

cfn-lint Usage

> cfn-lint s3.yml
W2001 Parameter EnvironmentStage not used.
s3.yml:7:3

W3005 Obsolete DependsOn on resource (WebCmsBucket), dependency already enforced by a "Ref" at Resources/PublicCMSWebsitePolicy/Properties/Bucket/Ref
s3.yml:46:5
Enter fullscreen mode Exit fullscreen mode

As you can see, cfn-lint output covers all 2 issues that we previously highlighted in the form of warnings and errors. Errors indicate issues that will prevent your CloudFormation stack from deploying, and warnings indicate potential issues in your stack that you might want to think about.

cfn-lint also comes with extensive configuration support which allows you to customise your linting rules.

WebCmsBucketPolicy:
    Type: AWS::S3::BucketPolicy
    DependsOn: WebCmsBucket
    Properties:
      Bucket: !Ref WebCmsBucket
      PolicyDocument:
        Statement:
          - Action:
              - 's3:GetObject'
            Effect: Allow
            Resource: !Sub 'arn:aws:s3:::${AWS::StackName}-web-cms/*'
            Principal: 
              CanonicalUser: !GetAtt WebCmsOAI.S3CanonicalUserId
    Metadata:
      cfn-lint:
        config:
          ignore_checks:
            - W3005
Enter fullscreen mode Exit fullscreen mode

cfn_nag Usage

> cfn_nag_scan -i s3.yml
------------------------------------------------------------
s3.yml
------------------------------------------------------------------------------------------------------------------------
| WARN W35
|
| Resource: ["WebCmsBucket"]
| Line Numbers: [25]
|
| S3 Bucket should have access logging configured
------------------------------------------------------------
| WARN W41
|
| Resource: ["WebCmsBucket"]
| Line Numbers: [25]
|
| S3 Bucket should have encryption option set

Failures count: 0
Warnings count: 2
Enter fullscreen mode Exit fullscreen mode

As you can see, cfn_nag output covers all 2 issues that we previously highlighted in the form of warnings and failures. These issues that will prevent your CloudFormation stack from security risks

cfn_nag also comes with extensive configuration support which allows you to customise your rules.

WebCmsBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub '${AWS::StackName}-web-cms'
      CorsConfiguration:
        CorsRules:
        - AllowedHeaders:
          - '*'
          AllowedMethods:
          - GET
          - PUT
          AllowedOrigins:
          - '*'
          MaxAge: 3000
      VersioningConfiguration:
        Status: Enabled
      WebsiteConfiguration:
        ErrorDocument: index.html
        IndexDocument: index.html
    Metadata:
      cfn_nag:
        rules_to_suppress:
          - id: W35
            reason: "Test ignore rule S3 Bucket should have access logging configured"
          - id: W41
            reason: "Test ignore rule S3 Bucket should have encryption option set"
Enter fullscreen mode Exit fullscreen mode

Top comments (0)