
AWS CDK: The IaC Upgrade I Wish I Made Earlier
CloudFormation helped me understand Infrastructure as Code. But AWS CDK changed how I engineer on AWS. In this article, I'll share the key limitations that pushed me away from raw templates, how CDK simplifies complex infrastructure patterns, and why building cloud infrastructure now feels closer to real software development.
Introduction
For years, AWS CloudFormation was my default approach for deploying infrastructure on AWS. Like many cloud engineers, I started my Infrastructure as Code journey by writing YAML templates, creating stacks manually, troubleshooting deployment failures, and trying to organize increasingly large templates as projects became more complex. At the beginning, this felt completely normal because CloudFormation was the standard and the foundation behind most AWS deployments.
But over time, something started to change.
As I worked on larger projects involving multiple environments, CI/CD pipelines, Lambda functions, S3 integrations, and event-driven architectures, I realized I was spending more time dealing with infrastructure syntax than actually building cloud solutions. Simple changes often required navigating hundreds of lines of YAML, debugging obscure dependency errors, or managing repetitive configurations across environments.
Then I started using AWS CDK.
The shift was immediate. Infrastructure suddenly became easier to organize, easier to scale, and far more enjoyable to work with. Instead of thinking in terms of templates, I started thinking in terms of reusable components and actual engineering patterns. AWS CDK completely changed the way I approach cloud development, and after using it extensively, going back to raw CloudFormation honestly feels difficult.
Here are the biggest reasons why I switched to AWS CDK, and why I probably won’t return to manually writing large CloudFormation templates.
Rason #1: Infrastructure Finally Feels Like Real Engineering
CloudFormation works very well for simple infrastructure. But when deployments start changing depending on the environment, the templates can quickly become difficult to maintain.
For example, imagine:
- dev only deploys one Lambda function,
- and prod deploys extra alarms, EventBridge rules, and backup configurations.
In CloudFormation, this usually means adding multiple conditions, duplicating resources, and managing large YAML templates with complex logic.
With CDK, this becomes much easier because you can use normal programming logic to decide what gets deployed depending on the environment.
1
2
3
if environment == "prod":
create_backup_bucket()
create_cloudwatch_alarms()Instead of creating complicated YAML conditions everywhere, the infrastructure logic stays simple and readable.
Reason #2: S3 Bucket Deletion Is No Longer Painful
One of the most frustrating experiences with CloudFormation is deleting stacks that contain S3 buckets. Almost every AWS engineer has encountered the classic deployment failure where CloudFormation refuses to delete a stack because the S3 bucket is not empty.
At that point, the cleanup process begins manually:
- deleting objects,
- removing versions,
- clearing delete markers,
- retrying the stack deletion again.
This becomes especially frustrating during development and testing, where infrastructure is frequently created and destroyed.
With CDK, this process becomes dramatically simpler.
1
2
removal_policy=RemovalPolicy.DESTROY,
auto_delete_objects=TrueCDK automatically handles bucket cleanup during stack deletion, removing a huge amount of operational friction during development cycles.
Reason #3: CloudFormation Limitations Become Much Easier to Handle
Another area where CDK completely improves the experience is configuring S3 event notifications. In raw CloudFormation, setting up S3 notifications with Lambda functions can quickly become complicated due to permissions management, notification configurations, and circular dependency issues.
What should conceptually be a simple integration often requires multiple resources and careful dependency ordering. In some cases, CloudFormation limitations make the configuration far more complex than expected.
With CDK, this process becomes incredibly clean and intuitive.
1
2
3
4
bucket.add_event_notification(
s3.EventType.OBJECT_CREATED,
s3n.LambdaDestination(my_lambda)
)Behind the scenes, CDK automatically manages many of the dependencies and permissions required for the integration to work correctly. Instead of focusing on resource wiring and troubleshooting deployment dependencies, I can focus directly on the application architecture itself.
This is one of the biggest reasons why CDK feels more modern and developer-friendly.
Reason #4: The Developer Experience Is Significantly Better
Using AWS CDK feels much closer to modern software engineering than traditional infrastructure management. Since infrastructure is written in a real programming language, I benefit from IDE support, autocomplete, type checking, reusable libraries, and cleaner project organization.
With CloudFormation, many mistakes are only discovered during deployment. A missing reference or incorrect property often means waiting for the stack deployment to fail before identifying the issue. With CDK, many of these problems are caught immediately during development thanks to type validation and IDE tooling.
This dramatically improves productivity and confidence, especially when working on larger projects involving multiple AWS services.
Reason #5: Reusable Infrastructure Actually Becomes Reusable
One thing I struggled with in CloudFormation was creating truly reusable infrastructure patterns. Reusability often meant relying on nested stacks, exports/imports, or duplicating templates across repositories.
CDK changes this completely through constructs.
Instead of copying infrastructure definitions repeatedly, I can create reusable components that encapsulate best practices. For example, I can build standardized constructs for secure S3 buckets, Lambda deployments, VPC architectures, or CI/CD pipelines, then reuse them across projects.
This approach not only improves consistency but also reduces the amount of repeated engineering effort across teams and environments.
Reason #6: Large Projects Stay Easier to Maintain
As infrastructure grows, CloudFormation templates can become increasingly difficult to navigate. Large YAML files with deeply nested intrinsic functions eventually become hard to debug and maintain, especially when multiple engineers are collaborating on the same infrastructure.
CDK allows infrastructure to be organized into logical stacks, constructs, and helper modules. This modular approach makes large environments much easier to understand and evolve over time.
Instead of managing one massive template, infrastructure becomes structured similarly to a well-organized software application. That separation of concerns becomes extremely valuable as cloud platforms scale.
Reason #7: Multi-Environment Deployments Become Cleaner
Managing multiple environments such as development, QA, staging, and production in CloudFormation often introduces additional complexity through parameter files, mappings, and duplicated configurations.
With CDK, environment management feels significantly cleaner. Context variables and reusable configurations make deployments much more scalable and maintainable.
For example:
1
environment = self.node.try_get_context("env")Then deployment becomes as simple as:
1
cdk deploy -c env=prodThis creates a much smoother deployment workflow and simplifies environment-specific customization.
Reason #8: cdk diff Adds a Huge Layer of Safety
One of the most underrated CDK features is the cdk diff command. Before deploying infrastructure changes, CDK can show exactly what resources will be created, modified, or deleted.
1
cdk diffThis visibility is incredibly valuable because it helps detect accidental changes before deployment. Whether it is an unexpected resource replacement, IAM permission modification, or security-related change, reviewing the infrastructure diff adds a huge layer of confidence during deployments.
In production environments, this becomes extremely important
Conclusion
CloudFormation remains an extremely powerful and foundational AWS service. In fact, AWS CDK still relies on CloudFormation underneath, which means all the benefits of managed stack deployments, rollback capabilities, and AWS-native provisioning still exist.
But from a developer experience perspective, CDK represents a major evolution in how infrastructure can be built and maintained.
It removes a large amount of operational friction, simplifies complex integrations, improves maintainability, and allows cloud infrastructure to follow modern engineering practices instead of static template management.
Most importantly, CDK allows engineers to spend less time fighting YAML and more time designing scalable architectures and building actual solutions.
And once infrastructure starts feeling like software engineering instead of template engineering, it becomes very hard to go back.
References
- What is the AWS CDK?
https://docs.aws.amazon.com/cdk/v2/guide/home.html - Perform programmatic actions using the CDK Toolkit Library
https://docs.aws.amazon.com/cdk/v2/guide/toolkit-library.html - Use other tools with the AWS CDK
https://docs.aws.amazon.com/cdk/v2/guide/tools.html - What is CloudFormation?
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html - Managing AWS resources as a single unit with CloudFormation stacks
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacks.html
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article