About Experience Skills Contact Blog Tools
← Back to articles

CloudFormation's Quiet Renaissance

· 6 min read

Every year or two, someone writes the “CloudFormation is dead” post. Terraform has won. CDK has made raw templates obsolete. YAML is a crime against humanity. And every year, I open the AWS console on a client project and find CloudFormation stacks running the infrastructure that actually matters — the production databases, the IAM boundaries, the networking layers that nobody wants to touch.

CloudFormation isn’t dead. It’s been quietly getting better in ways that don’t generate conference talks but genuinely change the day-to-day experience of managing AWS infrastructure. After using it across multiple production environments over the past fifteen years — alongside Terraform, SAM, and CDK — I think the current state of CloudFormation tooling is the strongest it’s ever been.

The Pain Was Real

I’m not going to pretend CloudFormation didn’t deserve the criticism. For years, the authoring experience was genuinely painful. You’d write hundreds of lines of YAML, deploy, wait three minutes, get a cryptic error about an invalid property name, fix it, redeploy, wait again. The feedback loop was brutal compared to terraform plan, which would catch most errors in seconds without touching AWS at all.

Drift was the other chronic problem. Someone would tweak a security group during an incident, the template would fall out of sync, and the next deployment would silently overwrite the manual change — or worse, fail in a way that left the stack in a partially updated state. Drift detection existed, but it was manual, slow, and didn’t integrate into deployment workflows.

These were legitimate reasons to choose Terraform instead. I did, for several projects, and I don’t regret it. But the calculus has shifted.

The Language Server Changes Everything

The single biggest improvement to CloudFormation in recent memory is the Language Server, available through the AWS Toolkit for VS Code and other LSP-compatible editors. This isn’t just syntax highlighting — it’s real-time validation, auto-completion for resource properties, documentation on hover, and diagnostics that catch errors before you ever run a deployment.

The impact on the authoring experience is hard to overstate. I used to keep the CloudFormation resource reference open in a browser tab at all times, constantly switching between my editor and the docs to look up property names, required fields, and allowed values. Now the editor tells me immediately when I’ve misspelled InstanceType or forgotten a required SubnetId. That tight feedback loop that Terraform had with terraform validate — CloudFormation finally has an equivalent, and it runs continuously as you type.

The Language Server also includes deployment features directly in the IDE: creating and executing change sets, viewing stack events, browsing deployed resources, and comparing your template against the live state. That last capability feeds directly into drift management, which I’ll come back to.

AI-Assisted Infrastructure with the IaC MCP Server

AWS released an Infrastructure-as-Code MCP Server that connects AI assistants — Claude Code, Cursor, Kiro — to CloudFormation and CDK documentation, template validation, and deployment troubleshooting. I’ve been using it with Claude Code, and it fills a gap that I didn’t realize was costing me as much time as it was.

The server provides tools split into two categories. The remote tools search AWS documentation and CDK construct libraries, returning current information about resource types, properties, and implementation patterns. The local tools run entirely on your machine: cfn-lint validation with specific fix suggestions and line numbers, CloudFormation Guard compliance checks, and deployment failure analysis that pulls in CloudTrail events to explain why a stack update failed.

The deployment troubleshooting is where this really earns its keep. Before this tool, debugging a failed stack update meant opening the CloudFormation console, scrolling through events, finding the failed resource, then separately opening CloudTrail to understand what API call failed and why. The MCP server does this investigation automatically, pattern-matching against known failure cases and providing resolution guidance. For the kinds of IAM permission errors and resource dependency issues that account for most deployment failures, this cuts debugging time from minutes to seconds.

{
  "mcpServers": {
    "awslabs.aws-iac-mcp-server": {
      "command": "uvx",
      "args": ["awslabs.aws-iac-mcp-server@latest"]
    }
  }
}

One line in your MCP configuration. The return on that setup cost is immediate.

Drift-Aware Change Sets: Solving the Real Problem

Drift management has always been CloudFormation’s weakest point compared to Terraform, where terraform plan naturally shows you the delta between your desired state and reality. CloudFormation’s drift detection was a separate, manual operation that you had to remember to run, and it didn’t integrate into the deployment workflow.

Drift-aware change sets fix this properly. When you create a change set, CloudFormation now compares your template not just against the previous template, but against the actual deployed state. If someone modified a resource outside of CloudFormation — a security group rule added during an incident, a Lambda memory increase applied through the console — the change set shows you exactly what drifted and lets you decide how to handle it before deploying.

This matters because drift is inevitable in production environments. I’ve managed stacks across organizations with strict IaC policies and excellent engineering discipline, and drift still happens. An on-call engineer bumps a Lambda’s memory allocation from 128 MB to 512 MB at 3 AM to stop an outage. A network engineer adds a temporary ingress rule to debug a connectivity issue. These are reasonable actions taken under pressure, and punishing them with process isn’t the answer.

The answer is making drift visible at the point where it matters — the next deployment. Drift-aware change sets do exactly this. They surface the conflict and let you make an informed decision: keep the manual change and update the template to match, or overwrite it with the template’s value. That’s a meaningful improvement over the old workflow of deploying blind and hoping nothing breaks.

Hooks and Guard for Compliance at Scale

CloudFormation Hooks let you run validation logic before resources are provisioned, updated, or deleted. Combined with CloudFormation Guard, which lets you write compliance rules as declarative policies, you get a system where infrastructure changes are validated against organizational standards before they reach AWS.

I use this pattern for the kinds of guardrails that are tedious to enforce through code review: ensuring all S3 buckets have encryption enabled, all RDS instances are deployed in private subnets, all Lambda functions have a maximum memory allocation below a certain threshold, all resources carry the required cost-allocation tags.

# guard-rules/s3-encryption.guard
rule s3_bucket_encryption {
  Resources.*[ Type == 'AWS::S3::Bucket' ] {
    Properties.BucketEncryption.ServerSideEncryptionConfiguration[*] {
      ServerSideEncryptionByDefault.SSEAlgorithm == "aws:kms"
    }
  }
}

These rules run in the deployment pipeline, not in a PR review comment that someone might ignore. If a template violates a rule, the deployment fails with a clear message explaining what’s wrong and why. This shifts compliance from “someone needs to remember to check” to “the system enforces it automatically.”

For multi-account environments, StackSets extend this model across accounts and regions. I’ve used this to enforce tagging policies and security baselines across dozens of accounts, where the alternative would have been either a custom tool or an honor system.

When CloudFormation Is the Right Choice

The IaC landscape in 2026 has three serious options for AWS infrastructure, and the right choice depends on your constraints more than the tools’ capabilities.

CloudFormation wins when you’re AWS-native and value operational simplicity. There’s no state file to manage, no backend to configure, no additional infrastructure to run. CloudFormation tracks state server-side as part of the AWS control plane. You get automatic rollback on failure, native integration with IAM, CloudTrail, AWS Config, and Service Catalog, and same-day support for new AWS services. For teams that don’t want to operate Terraform state infrastructure — S3 buckets, lock configuration, state file access policies — this is a genuine advantage.

Terraform wins when you need multi-cloud or extensive third-party integrations. If you’re managing resources across AWS, Azure, and a SaaS provider like Datadog or PagerDuty in the same workflow, Terraform’s provider ecosystem is unmatched.

CDK wins when your team prefers defining infrastructure in a programming language and you want higher-level abstractions than raw resource definitions. But CDK generates CloudFormation templates under the hood, so you’re still running on the same deployment engine — with an additional layer of abstraction that can make debugging harder when deployments fail.

I reach for CloudFormation when the infrastructure is AWS-only, the team is small enough that operational overhead matters, and the compliance requirements favor tight AWS integration. That describes more projects than the IaC discourse would have you believe.

The Honest Take

CloudFormation’s renaissance isn’t dramatic. There’s no single feature that makes you rethink everything. It’s a steady accumulation of improvements that collectively address the tool’s historical weaknesses: faster feedback through the Language Server, AI-assisted authoring and debugging through the MCP Server, proper drift management through drift-aware change sets, and automated compliance through Hooks and Guard.

The result is a tool that’s significantly more pleasant to use than it was two years ago, integrated into the IDE workflow rather than forcing you into the console, and still carrying its core advantage of zero operational overhead for state management. If you dismissed CloudFormation years ago because the authoring experience was painful and drift management was primitive, it’s worth a second look. The YAML hasn’t changed, but everything around it has.