Exploring CDK and Policy as Code with CDK-Nag and Python

Infrastructure as Code (IaC) has become a standard in cloud development, allowing for quick environment setups and compliance through versioning. Tools like Terraform and the Cloud Development Kit (CDK) simplify the process compared to traditional Clou…


This content originally appeared on DEV Community and was authored by Dr. Malte Polley

Infrastructure as Code (IaC) has become a standard in cloud development, allowing for quick environment setups and compliance through versioning. Tools like Terraform and the Cloud Development Kit (CDK) simplify the process compared to traditional CloudFormation.

In a previous blog post, I discussed using a custom solution for pull request reporting with cfn-lint and cfn_nag. While cfn-lint is still valuable for creating your own compliance rules, keeping up with CDK and AWS recommendations can be challenging. Fortunately, cdk-nag can serve as a substitute for cfn-lint.

CDK-Nag: Making Infrastructure Decisions Visible

Most tools I've used have a common issue: they can check your infrastructure but often fall short on providing actionable insights. cdk-nag enhances visibility into the compliant aspects of your IaC deployment. It comes with prebuilt rule packs for various standards:

  1. AWS Solutions
  2. HIPAA Security
  3. NIST 800-53 Rev 4
  4. NIST 800-53 Rev 5
  5. PCI DSS 3.2.1

These rules are mapped to specific controls, making compliance evaluations straightforward, even for non-AWS exployees.

Sample Implementation of CDK-Nag in Python

For demonstration, we'll use a sample CDK application created with the command cdk init app --language python. If you're new to CDK, check out the official tutorial.

Here's a minimal example of creating an S3 bucket in your CDK stack:

from aws_cdk import Stack, aws_s3 as s3
from constructs import Construct
from src.load_env.config import CDKConfig

class CdkSampleRepoStack(Stack):
    """Create the actual deployment in each AWS account."""

    def __init__(self, scope: Construct, construct_id: str, stage: str, config: CDKConfig, **kwargs) -> None:
        """Initialize CDK stack class."""
        super().__init__(scope, construct_id, **kwargs)

        # Create the S3 bucket
        bucket = s3.Bucket(self, id="MyBucket")

After running cdk synth, you'll generate a CloudFormation template in the cdk.out folder. However, this bucket configuration may have implicit or missing settings, such as encryption or TLS policies.

To leverage AWS best practices, add cdk-nag to your app.py:

#!/usr/bin/env python3
import os
import cdk_nag
import aws_cdk as cdk
from hello_cdk.hello_cdk_stack import CdkSampleRepoStack

app = cdk.App()
CdkSampleRepoStack(app, "HelloCdkStack", env=cdk.Environment(account='123456789012', region='us-east-1'))
cdk_nag.Aspects.of(app).add(cdk_nag.AwsSolutionsChecks(verbose=True))
app.synth()

Running cdk synth now will display error messages in your terminal, such as:

[Error at /CdkSampleRepoStack/MyBucket/Resource] AwsSolutions-S1: The S3 Bucket has server access logs disabled.

[Error at /CdkSampleRepoStack/MyBucket/Resource] AwsSolutions-S10: The S3 Bucket or bucket policy does not require requests to use SSL.

Handling Best Practice Violations

Sometimes, you may need to explicitly violate a best practice, like disabling access logging for a non-critical bucket. You can suppress specific rules as follows:

# hello_cdk.hello_cdk_stack.py
bucket = s3.Bucket(
    self,
    id="MyBucket",
    block_public_access=s3.BlockPublicAccess(
        block_public_acls=True,
        block_public_policy=True,
        ignore_public_acls=True,
        restrict_public_buckets=True,
    ),
    versioned=True,
    enforce_ssl=True,
    encryption=s3.BucketEncryption.KMS_MANAGED,
)

nag_suppression.add_resource_suppressions(
    construct=bucket,
    suppressions=[
        {
            "id": "AwsSolutions-S1",
            "reason": "This bucket does not hold customer data",
        }
    ],
)

With this suppression, the CSV report will now indicate that the rule has been suppressed. But, cdk-nag not supports suppressions on constructs but also on resource paths and many more

Integrating Pull Request Reporting with cdk-nag

Integrating cdk-nag into your CI/CD pipeline can enhance your deployment process. For instance, in Azure DevOps, you can automate pull request comments based on the cdk synth results.

Here's a brief overview of how to set this up:

  1. Create a message class to handle comments.
  2. Use pandas to read the generated CSV files.
  3. Translate the CSV table to Markdown.
  4. Post comments to your pull requests.
import pull_request_comment
import logging
import pandas as pd
import os

logging.basicConfig(
    level=logging.INFO, format="[%(levelname)s] - %(message)s", force=True
)

def main():
    """Create a Pull Request comment within azure-pipelines-pr.yml"."""
    for filename in os.listdir("./synth/templates/"):
        if filename.endswith(".csv"):
            try:
                df = pd.read_csv(f"./cdk.out/templates/{filename}")
            except FileNotFoundError as e:
                logging.exception(e)
                raise
            if df.empty is False:
                logging.info("Adding CDK Validation report")
                result = msg.add(comment=df.to_markdown())

if __name__ == "__main__":
    main()

In your Azure DevOps pipeline, add a task to run cdk synth and then execute the script to post comments:

- task: AWSShellScript@1
  inputs:
    awsCredentials: ${{ parameters.ServiceConnection }}
    regionName: ${{ parameters.AwsRegion }}
    scriptType: 'inline'
    inlineScript: |
      cdk synth
      python3 src/pull_requests/comment.py

Results of cdk-nag reports within a Pull Request pipeline

Final Thoughts

Implementing cdk-nag in your workflow may require some effort, but it provides an easier way to ensure compliance before deploying to AWS. Shifting left in your development process is always a good idea, especially for beginners looking to ensure correct deployments.

Happy and save coding! :-)


This content originally appeared on DEV Community and was authored by Dr. Malte Polley


Print Share Comment Cite Upload Translate Updates
APA

Dr. Malte Polley | Sciencx (2024-09-11T12:20:52+00:00) Exploring CDK and Policy as Code with CDK-Nag and Python. Retrieved from https://www.scien.cx/2024/09/11/exploring-cdk-and-policy-as-code-with-cdk-nag-and-python/

MLA
" » Exploring CDK and Policy as Code with CDK-Nag and Python." Dr. Malte Polley | Sciencx - Wednesday September 11, 2024, https://www.scien.cx/2024/09/11/exploring-cdk-and-policy-as-code-with-cdk-nag-and-python/
HARVARD
Dr. Malte Polley | Sciencx Wednesday September 11, 2024 » Exploring CDK and Policy as Code with CDK-Nag and Python., viewed ,<https://www.scien.cx/2024/09/11/exploring-cdk-and-policy-as-code-with-cdk-nag-and-python/>
VANCOUVER
Dr. Malte Polley | Sciencx - » Exploring CDK and Policy as Code with CDK-Nag and Python. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/09/11/exploring-cdk-and-policy-as-code-with-cdk-nag-and-python/
CHICAGO
" » Exploring CDK and Policy as Code with CDK-Nag and Python." Dr. Malte Polley | Sciencx - Accessed . https://www.scien.cx/2024/09/11/exploring-cdk-and-policy-as-code-with-cdk-nag-and-python/
IEEE
" » Exploring CDK and Policy as Code with CDK-Nag and Python." Dr. Malte Polley | Sciencx [Online]. Available: https://www.scien.cx/2024/09/11/exploring-cdk-and-policy-as-code-with-cdk-nag-and-python/. [Accessed: ]
rf:citation
» Exploring CDK and Policy as Code with CDK-Nag and Python | Dr. Malte Polley | Sciencx | https://www.scien.cx/2024/09/11/exploring-cdk-and-policy-as-code-with-cdk-nag-and-python/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.