DEV Community

Cover image for Getting started with Python based IaC using AWS CDK

Getting started with Python based IaC using AWS CDK

AWS CDK Getting Started

Table of Contents

Introduction

Programming language based IaC tools becoming famous in recent times. We will see one such tool AWS CDK In this article.

We will required steps on how to get started with creating infrastructure in AWS CDK for AWS. I'll be using Python language to create infrastructure in AWS using AWS CDK

AWS started supporting Programming language based Infrastructure as code (IaC in short) and named it as AWS Cloud Development Kit. Other similar tools are CDKTF and Pulumi.


What is AWS CDK

The AWS CDK lets you build reliable, scalable, cost-effective applications in the cloud with the considerable expressive power of a programming language

You can read more about it in AWS CDK docs

Concepts and Key Components

  • Constructs are the basic building blocks of AWS CDK apps. A construct represents a "cloud component" and encapsulates everything AWS CloudFormation needs to create the component.
  • App is a construct, It is used to provision infrastructure resources.
  • Stack is the unit of deployment in the AWS CDK . All AWS resources defined within the scope of a stack, either directly or indirectly, are provisioned as a single unit. All constructs that represent AWS resources must be defined, directly or indirectly, within the scope of a Stack construct.
  • Go through AWS CDK documentation to know further about the Concepts and Components of AWS CDK

Steps to getting into AWS CDK

  • We need to install NodeJS
  • Python and PIP for developing Python language based infrastructure definition
  • Also we need to configure AWS credentials for setting up infra in AWS

Step 1 Setting up Pre Requisites

Install node package manager

sudo npm install -g npm@latest
Enter fullscreen mode Exit fullscreen mode

Install Python and Pip

Configure AWS Cloud Credentials

  • AWS by default reads the auth config details as per the precedence mentioned here
  • So we will be using aws configure to set the authentication details and it is getting added into ~/.aws/credentials and ~/.aws/config
  • Install AWS CLI from docs
  • Configure AWS CLI

Step 2 Install AWS CDK

sudo python3 -m pip install aws-cdk-lib
sudo npm install -g aws-cdk
Enter fullscreen mode Exit fullscreen mode
  • Check cdk command
cdk version
Enter fullscreen mode Exit fullscreen mode

Step 3 Create CDK project

  • Create directory and initialize AWS CDK
mkdir awscdk
cd awscdk/
Enter fullscreen mode Exit fullscreen mode

cdk init

  • Since we are creating python based code, init app to have Python modules support
cdk init app --language python
Enter fullscreen mode Exit fullscreen mode
  • This command will initialize the empty directory and creates the necessary files required to getting started with AWS CDK development
  • It also shows the possible next steps to proceed with AWS CDK as README content in console output
Applying project template app for python

# Welcome to your CDK Python project!

This is a blank project for CDK development with Python.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

This project is set up like a standard Python project.  The initialization
process also creates a virtualenv within this project, stored under the `.venv`
directory.  To create the virtualenv it assumes that there is a `python3`
(or `python` for Windows) executable in your path with access to the `venv`
package. If for any reason the automatic creation of the virtualenv fails,
you can create the virtualenv manually.

To manually create a virtualenv on MacOS and Linux:

``
$ python3 -m venv .venv
``

After the init process completes and the virtualenv is created, you can use the following
step to activate your virtualenv.

``
$ source .venv/bin/activate
``

If you are a Windows platform, you would activate the virtualenv like this:

``
% .venv\Scripts\activate.bat
``

Once the virtualenv is activated, you can install the required dependencies.

``
$ pip install -r requirements.txt
``

At this point you can now synthesize the CloudFormation template for this code.

``
$ cdk synth
``

To add additional dependencies, for example other CDK libraries, just add
them to your `setup.py` file and rerun the `pip install -r requirements.txt`
command.

## Useful commands

 * `cdk ls`          list all stacks in the app
 * `cdk synth`       emits the synthesized CloudFormation template
 * `cdk deploy`      deploy this stack to your default AWS account/region
 * `cdk diff`        compare deployed stack with current state
 * `cdk docs`        open CDK documentation

Enjoy!

Initializing a new git repository...
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint:   git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint:   git branch -m <name>
Please run 'python3 -m venv .venv'!
Executing Creating virtualenv...
✅ All done!
Enter fullscreen mode Exit fullscreen mode
  • Contents of the directory created by init command
$ ls -a
.  ..  app.py  awscdk  cdk.json  .git  .gitignore  README.md  requirements-dev.txt  requirements.txt  source.bat  tests  .venv
Enter fullscreen mode Exit fullscreen mode

Step 4 Setup Python Virtual Environment

  • To work with the new cdk project, activate its python virtual environment. This allows the project's dependencies to be installed locally in the project folder, instead of globally.
  • In ubuntu systems, Python venv can be installed using,
# in ubuntu this is needed
sudo apt install python3.9-venv
Enter fullscreen mode Exit fullscreen mode
  • Then run,
python3 -m venv .venv
Enter fullscreen mode Exit fullscreen mode

or

source .venv/bin/activate
Enter fullscreen mode Exit fullscreen mode

Step 5 Install Dependencies

  • After we installed the python venv, we can install the project dependencies using the command,
python3 -m pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

Step 6 Verifying the project

cdk ls

  • Just before adding the code to setup our infrastructure, we can verify the CDK code setup by running the command below,
$ cdk ls

AwscdkStack
Enter fullscreen mode Exit fullscreen mode
  • It displays the AWS CDK stack, defined in the directory ./awscdk/awscdk_stack.py

Step 7 Defining AWS Infrastructure using Python

  • Now open the project directory in vscode or your preferred code editor to add the infrastructure code.
  • I use the command code . from current working directory to open the project in vscode editor
  • Add the Python code to create s3 bucket in the AWS account
  • Open file ./awscdk/awscdk_stack.py
import aws_cdk as cdk
import aws_cdk.aws_s3 as s3

class HelloCdkStack(cdk.Stack):

    def __init__(self, scope: cdk.App, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        bucket = s3.Bucket(self, "MyFirstBucket", versioned=True)
Enter fullscreen mode Exit fullscreen mode
  • Let us dissect the code blocks that are defined in the above code. This is the example code defined in the docs

Bucket is the first construct we've seen, so let's take a closer look. Like all constructs, the Bucket class takes three parameters.

scope: Tells the bucket that the stack is its parent: it is defined within the scope of the stack. You can define constructs inside of constructs, creating a hierarchy (tree). Here, and in most cases, the scope is this (self in Python), meaning the construct that contains the bucket: the stack.

Id: The logical ID of the Bucket within your AWS CDK app.

props: A bundle of values that define properties of the bucket.

  • Now proceed to next steps to begin deploying the CDK Stack

Step 8 Spinning up Infra

  • After adding the code, let us now try to synthesize the proposed infrastructure

cdk synth

  • Run the command below to synthesize,
$ cdk synth

Resources:
  MyFirstBucketB8884501:
    Type: AWS::S3::Bucket
    Properties:
      VersioningConfiguration:
        Status: Enabled
    UpdateReplacePolicy: Retain
    DeletionPolicy: Retain
    Metadata:
      aws:cdk:path: AwscdkStack/MyFirstBucket/Resource
  CDKMetadata:
    Type: AWS::CDK::Metadata
    Properties:
      Analytics: v2:deflate64:H4sIAAAAAAAA/yXI0QpAMBSA4Wdxvx0iyS0vIB5AzOQYZ7WdJcm7I1f/159CWkASDYeXajJywxGujgdlxLt6n8FVBWU0i3qmX/fHVnsbnNKfa0sTMlq6RXPyYinOoIQ8Wj2idIEYdw3t3wdyVYK2bwAAAA==
    Metadata:
      aws:cdk:path: AwscdkStack/CDKMetadata/Default
    Condition: CDKMetadataAvailable
Conditions:
  CDKMetadataAvailable:
    Fn::Or:
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - af-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-northeast-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-northeast-2
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-southeast-1
          - Fn::Equals:
              - Ref: AWS::Region
              - ap-southeast-2
          - Fn::Equals:
              - Ref: AWS::Region
              - ca-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - cn-north-1
          - Fn::Equals:
              - Ref: AWS::Region
              - cn-northwest-1
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-central-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-north-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-1
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-2
          - Fn::Equals:
              - Ref: AWS::Region
              - eu-west-3
          - Fn::Equals:
              - Ref: AWS::Region
              - me-south-1
          - Fn::Equals:
              - Ref: AWS::Region
              - sa-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-east-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-east-2
      - Fn::Or:
          - Fn::Equals:
              - Ref: AWS::Region
              - us-west-1
          - Fn::Equals:
              - Ref: AWS::Region
              - us-west-2
Parameters:
  BootstrapVersion:
    Type: AWS::SSM::Parameter::Value<String>
    Default: /cdk-bootstrap/hnb659fds/version
    Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]
Rules:
  CheckBootstrapVersion:
    Assertions:
      - Assert:
          Fn::Not:
            - Fn::Contains:
                - - "1"
                  - "2"
                  - "3"
                  - "4"
                  - "5"
                - Ref: BootstrapVersion
        AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.
Enter fullscreen mode Exit fullscreen mode

cdk bootstrap

  • Then run the bootstrap command
  • Use the cdk bootstrap command to bootstrap one or more AWS environments. In its basic form, this command bootstraps one or more specified AWS environments.
$ cdk bootstrap

 ⏳  Bootstrapping environment aws://account-id/us-west-2...
Trusted accounts for deployment: (none)
Trusted accounts for lookup: (none)
Using default execution policy of 'arn:aws:iam::aws:policy/AdministratorAccess'. Pass '--cloudformation-execution-policies' to customize.
CDKToolkit: creating CloudFormation changeset...
 ✅  Environment aws://account-id/us-west-2 bootstrapped.
Enter fullscreen mode Exit fullscreen mode

cdk deploy

  • After bootstrapping the CDK environment, run cdk deploy command to add the infrastructure
$ cdk deploy

✨  Synthesis time: 3.83s

This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening).
Please confirm you intend to make the following modifications:

IAM Statement Changes
┌───┬───────────────────────────────────────────────────────────────┬────────┬───────────────────────────────────────┬───────────────────────────────────────────────────────────────────┬───────────┐
│   │ Resource                                                      │ Effect │ Action                                │ Principal                                                         │ Condition │
├───┼───────────────────────────────────────────────────────────────┼────────┼───────────────────────────────────────┼───────────────────────────────────────────────────────────────────┼───────────┤
│ + │ ${Custom::S3AutoDeleteObjectsCustomResourceProvider/Role.Arn} │ Allow  │ sts:AssumeRole                        │ Service:lambda.amazonaws.com                                      │           │
├───┼───────────────────────────────────────────────────────────────┼────────┼───────────────────────────────────────┼───────────────────────────────────────────────────────────────────┼───────────┤
│ + │ ${MyFirstBucket.Arn}                                          │ Allow  │ s3:DeleteObject*                      │ AWS:${Custom::S3AutoDeleteObjectsCustomResourceProvider/Role.Arn} │           │
│   │ ${MyFirstBucket.Arn}/*                                        │        │ s3:GetBucket*                         │                                                                   │           │
│   │                                                               │        │ s3:List*                              │                                                                   │           │
└───┴───────────────────────────────────────────────────────────────┴────────┴───────────────────────────────────────┴───────────────────────────────────────────────────────────────────┴───────────┘
IAM Policy Changes
┌───┬───────────────────────────────────────────────────────────┬──────────────────────────────────────────────────────────────────────────────────────────────┐
│   │ Resource                                                  │ Managed Policy ARN                                                                           │
├───┼───────────────────────────────────────────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────┤
│ + │ ${Custom::S3AutoDeleteObjectsCustomResourceProvider/Role} │ {"Fn::Sub":"arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"} │
└───┴───────────────────────────────────────────────────────────┴──────────────────────────────────────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299)

Do you wish to deploy these changes (y/n)? y
AwscdkStack: deploying...
[0%] start: Publishing 075615afa517203dd67c21:current_account-current_region
[0%] start: Publishing b3e30b6400895ee28d0614:current_account-current_region
[50%] success: Published 880615afa517203dd67c21:current_account-current_region
[100%] success: Published b3e30b6400895ee28d0614:current_account-current_region
AwscdkStack: creating CloudFormation changeset...

 ✅  AwscdkStack

✨  Deployment time: 77.86s

Stack ARN:
arn:aws:cloudformation:us-west-2:account-id:stack/AwscdkStack/398ef750-e70b-11ec-b89d-021a55f488dd

✨  Total time: 81.69s
Enter fullscreen mode Exit fullscreen mode

Cleaning up the Demo Stack

  • Since we are creating the demo deployment, let's tear down the AWS resources
  • Use the command cdk destroy to delete the resources

cdk destroy

$ cdk destroy

Are you sure you want to delete: AwscdkStack (y/n)? y
AwscdkStack: destroying...

 ✅  AwscdkStack: destroyed
Enter fullscreen mode Exit fullscreen mode

Important commands

Command Function
cdk init Creates a new CDK project in the current directory from a specified template
cdk list or ls Lists the stacks in the app
cdk synthesize or synth Synthesizes and prints the CloudFormation template for the specified stack(s)
cdk bootstrap Deploys the CDK Toolkit staging stack
cdk deploy Deploys the specified stack(s)
cdk destroy Destroys the specified stack(s)
cdk diff Compares the specified stack with the deployed stack or a local CloudFormation template

Conclusion

  • We discussed how to get started with AWS CDK in this blog and created a sample s3 bucket as part of demo
  • We can learn more about AWS CDK from the documentation and it has more examples to get practiced
  • I've experimented with Python based IaC creation with both CDKTF and AWS CDK. Planning to write a comparison blog as the next step.

References

Community and Social Footprints

Discussion (0)