In this tutorial, you'll learn how to integrate cfn-lint into an AWS CI/CD workflow using Amazon Web Services CodePipeline and CodeBuild. By the end, you'll have a governance stage in your pipeline that automatically validates CloudFormation templates before deployment.
We’ll cover:
- Creating a compliant CloudFormation template
- Validating templates locally with cfn-lint
- Verifying the governance stage inside CodePipeline
Why Use cfn-lint?
cfn-lint is an open-source tool that validates AWS CloudFormation templates against AWS resource specifications and best practices.
It helps detect:
- Syntax issues
- Invalid resource properties
- Misconfigured IAM permissions
- Incorrect parameter usage
- Security-related template mistakes
Clone the repository used in this lab:
cd && git clone https://github.com/pluralsight-cloud/Path-Proactive-Security-in-Your-AWS-CI-CD-Pipeline.git
Navigate to the lab directory:
cd Path-Proactive-Security-in-Your-AWS-CI-CD-Pipeline/4-lab-using-static-analysis-to-detect-cloudformation-misconfigurations
Objective 1: Introduce a Compliant Template
First, verify the pre-existing AWS resources.
Verify the S3 Bucket
Open Amazon S3 and locate the bucket that starts with:
governance-lab-artifacts-
You should notice:
- The bucket is empty
- Versioning is enabled
Save the bucket name for later.
Verify the Pipeline
Open AWS CodePipeline and locate:
governance-pipeline
The pipeline should currently be in a failed state.
Verify the stages exist in this order:
- Source
- GovernanceLint
- Deploy
Update the CloudFormation Template
Open the template file:
vim infra/template.yml
Uncomment the IAM role section:
:46,$s/# //g
Alternatively, paste the following IAM role resource:
NewRole:
Type: AWS::IAM::Role
Properties:
RoleName: governance-lab-test-role
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: compliant-s3-limited-access
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- s3:GetObject
- s3:ListBucket
- s3:PutObject
Resource:
- !Sub "arn:aws:s3:::governance-lab-artifacts-${AWS::AccountId}-${AWS::Region}-an/*"
- !Sub "arn:aws:s3:::governance-lab-artifacts-${AWS::AccountId}-${AWS::Region}-an"
Save and exit:
:wq!
This IAM role allows EC2 instances to assume the role and access specific S3 bucket actions with limited permissions.
Objective 2: Validate Templates Locally
Before integrating linting into the pipeline, validate the template locally.
Install cfn-lint
Run:
pip install cfn-lint pyyaml boto3
Verify installation:
cfn-lint --version
Example output:
Lint the Template
Run:
cfn-lint -f pretty infra/template.yml
If the template is valid, you'll see output indicating:
0 errors
Objective 3: Update the CodeBuild Configuration
Next, integrate cfn-lint into the pipeline’s governance stage.
Open the buildspec file:
vim configuration/buildspec.yml
Delete the existing content:
:1,20d
Uncomment the remaining lines:
:1,$s/# //g
What This BuildSpec Does
The updated buildspec introduces two phases:
Install Phase
Installs:
- cfn-lint
- PyYAML
- boto3
Build Phase
Runs lint validation against every YAML template inside the infra directory.
If linting fails, the pipeline stops immediately before deployment.
This creates an automated governance gate inside the CI/CD process.
Objective 4: Verify the Governance Stage
Now upload the updated artifacts to trigger the pipeline.
Zip the Project Files
cd ~/Path-Proactive-Security-in-Your-AWS-CI-CD-Pipeline/4-lab-using-static-analysis-to-detect-cloudformation-misconfigurations
zip -r artifacts.zip infra configuration
Upload to Amazon S3
aws s3 cp artifacts.zip s3://<YOUR_BUCKET_NAME_GOES_HERE>/
Verify Pipeline Execution
Navigate back to AWS CodePipeline and monitor:
governance-pipeline
You should observe:
- GovernanceLint stage executes successfully
- Deploy stage completes successfully
- CloudFormation stack deployment succeeds
Inside the GovernanceLint logs, you'll see:
cfn-lint --version
cfn-lint -f pretty infra/**/*.yml
with no validation errors.
Verify CloudFormation Resources
Open the deployed CloudFormation stack:
governance-lab-deploy
Under the Resources tab, you should see:
- AppSecurityGroup
- NewRole
This confirms the compliant template passed validation and deployed successfully.
Testing a Failure Scenario (Optional)
To test the governance controls, intentionally introduce a template error.
Update:
FromPort: 443
to:
FromPort: HTTPS
Rebuild and upload the artifacts again:
zip -r artifacts.zip infra configuration
aws s3 cp artifacts.zip s3://<YOUR_BUCKET_NAME_GOES_HERE>/
This time, the GovernanceLint stage should fail, and CodeBuild logs will display the cfn-lint validation error.
This proves the governance stage is actively blocking malformed infrastructure templates from deployment.
Benefits of Adding cfn-lint to AWS CodePipeline
Integrating cfn-lint into your CI/CD pipeline provides several advantages:
- Early detection of template errors
- Improved infrastructure security
- Faster deployment troubleshooting
- Consistent infrastructure governance
- Reduced production deployment failures
Most importantly, it shifts validation left — catching issues before they ever reach AWS CloudFormation deployment stages.









Top comments (0)