For years, the industry standard for Infrastructure as Code (IaC) has been HCL (HashiCorp Configuration Language). While HCL is powerful, as a Python developer, I’ve always felt a certain friction when switching between the imperative logic of my application code and the declarative nature of my infrastructure files. That’s why I shifted to the Cloud Development Kit for Terraform (CDKTF).
In this cdktf tutorial for python developers, I’m going to show you how to stop treating your infrastructure as a set of static configuration files and start treating it like actual software. By using CDKTF, you get the full power of the Python ecosystem—loops, conditionals, and object-oriented patterns—while still benefiting from the massive provider ecosystem of Terraform.
Why CDKTF over Standard Terraform?
I’ve spent a lot of time comparing different IaC tools. If you’re coming from a Python background, the benefits are immediate. Instead of creating complex modules in HCL to simulate loops, you just use a for loop. Instead of duplicating blocks of code, you create a Python class.
If you are debating between different high-level abstractions, you might find my Terraform vs AWS CDK for Lambda comparison helpful, as it clarifies when to stay within a cloud-native framework versus using the provider-agnostic CDKTF.
Prerequisites
- Python 3.9+ installed on your machine.
- Node.js (required for the CDKTF CLI).
- Terraform CLI installed and configured.
- Cloud credentials (AWS, GCP, or Azure) configured in your environment variables.
Step-by-Step Implementation
Step 1: Install the CDKTF CLI
First, we need the command-line tool that handles the synthesis of your Python code into Terraform JSON files. Run the following in your terminal:
npm install --global cdktf-cli
Step 2: Initialize Your Project
Now, create a new directory for your project and initialize it specifically for Python:
mkdir my-python-infra && cd my-python-infra
cdktf init --template=python --local
This command sets up a virtual environment, installs the necessary Python dependencies, and creates a basic project structure. As shown in the image below, you’ll notice a main.py file where all the magic happens.
Step 3: Define Your Infrastructure
Let’s build a simple example: an AWS S3 bucket and a Lambda function. Open main.py and replace the boilerplate with this implementation:
from constructs import Construct
from cdktf import App, TerraformStack
from cdktf_cdktf_provider_aws.provider import AwsProvider
from cdktf_cdktf_provider_aws.s3_bucket import S3Bucket
from cdktf_cdktf_provider_aws.lambda_function import LambdaFunction
class MyInfrastructureStack(TerraformStack):
def __init__(self, scope: Construct, id: str):
super().__init__(scope, id)
# Initialize the AWS Provider
AwsProvider(self, "AWS", region="us-east-1")
# Create an S3 Bucket using a simple variable
bucket_name = "ajmani-dev-cdktf-demo-2026"
S3Bucket(self, "MyBucket",
bucket=bucket_name,
tags={"Environment": "Dev", "ManagedBy": "CDKTF"}
)
# Example of Pythonic logic: Creating multiple resources
for i in range(3):
LambdaFunction(self, f"MyLambda-{i}",
function_name=f"processor-node-{i}",
role="arn:aws:iam::123456789012:role/lambda-role",
handler="index.handler",
runtime="python3.9",
s3_bucket="my-code-bucket",
s3_key=f"code-{i}.zip"
)
app = App()
MyInfrastructureStack(app, "python-infra")
app.synth()
Step 4: Deploy Your Infrastructure
To deploy, you don’t run terraform apply directly. Instead, you use the CDKTF wrapper which synthesizes the Python code into a JSON configuration that Terraform understands:
cdktf deploy
The CLI will show you a plan of the resources to be created. Confirm with ‘yes’ to execute the deployment.
Pro Tips for Python Developers
- Use Type Hinting: CDKTF provides excellent type definitions. Always use them in your classes to get full IDE autocomplete in VS Code or PyCharm.
- Abstract Your Patterns: If you find yourself deploying the same set of resources (e.g., an S3 bucket + CloudFront distribution) repeatedly, create a custom Python class that inherits from
Construct. - Environment Management: Use
python-dotenvto manage different secrets and environment variables instead of hardcoding values in your stack.
Troubleshooting Common Issues
In my experience, the most common hurdle is the cdktf synth step failing due to missing provider versions. If you see a provider error, try running cdktf get to refresh your provider bindings.
Additionally, ensure your virtual environment is active. If you’re seeing ImportError for the AWS provider, it’s usually because the provider package (e.g., cdktf-cdktf-provider-aws) wasn’t installed in the current venv during init.
What’s Next?
Now that you’ve mastered the basics of this cdktf tutorial for python developers, you can start exploring more complex patterns. If you’re looking for an alternative to Terraform entirely, you might want to read my Pulumi review 2026 to see how it compares in terms of state management and developer experience.
For those managing serverless workloads, I highly recommend looking into how different abstractions handle event triggers. I’ve broken this down in my guide on Terraform vs AWS CDK for Lambda.