AWS Infrastructure as Code options
AWS offers several ways to describe infrastructure as code. They are not really competitors: every one of them ultimately produces or deploys a CloudFormation stack, so the choice is about the authoring experience and the governance model rather than about capability.
SAM and CloudFormation
Section titled “SAM and CloudFormation”CloudFormation is the general-purpose service. It can manage any AWS resource type, in declarative JSON or YAML, with no language runtime involved.
SAM is a specialisation for serverless applications, implemented as a CloudFormation transform. A SAM template is a CloudFormation template; the transform expands its high-level types into ordinary resources before the stack is created.
The same Lambda function, both ways:
# CloudFormationResources: MyFunction: Type: AWS::Lambda::Function Properties: Handler: index.handler Runtime: nodejs24.x Role: !GetAtt MyFunctionRole.Arn Code: ZipFile: | exports.handler = async () => ({ statusCode: 200, body: 'Hello' }); # ...plus MyFunctionRole, plus a log group, plus API Gateway resources# SAMTransform: AWS::Serverless-2016-10-31Resources: MyFunction: Type: AWS::Serverless::Function Properties: Handler: index.handler Runtime: nodejs24.x InlineCode: | exports.handler = async () => ({ statusCode: 200, body: 'Hello' }); Events: Api: Type: HttpApi Properties: Path: /hello Method: getThe differences that matter:
- Abstraction. SAM generates the execution role, the log group and the API Gateway wiring; CloudFormation requires each to be declared.
- Coverage. SAM’s high-level types cover functions, APIs, simple tables, state machines and layers. Everything else is written as ordinary CloudFormation in the same file.
- Local testing. The SAM CLI runs functions and APIs locally against a container that matches the Lambda execution environment. CloudFormation has no equivalent.
- Deployment ergonomics.
sam buildandsam deploywrap packaging, change-set creation and execution.
Use SAM for serverless-dominated workloads and CloudFormation for everything else — and note that “mixing” them is not a compromise, it is the normal case.
AWS CDK
Section titled “AWS CDK”The CDK defines infrastructure in TypeScript, Python, Java, C# or Go and synthesises a CloudFormation template from it.
import * as cdk from 'aws-cdk-lib';import * as s3 from 'aws-cdk-lib/aws-s3';
export class MyCdkStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { super(scope, id, props);
new s3.Bucket(this, 'MyBucket', { versioned: true, encryption: s3.BucketEncryption.S3_MANAGED, blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, removalPolicy: cdk.RemovalPolicy.RETAIN, }); }}What it buys: loops, conditionals and abstractions in a real language; high-level constructs that apply sensible defaults; reusable components published as packages; type checking and IDE completion; and unit tests over the synthesised template.
What it costs: a build step, a language runtime in the pipeline, and a layer of indirection between what is written and what is deployed. A construct that silently creates nine resources is convenient until something in it needs to be different. Local Lambda testing under the CDK is done through the SAM CLI, not by the CDK itself.
AWS Service Catalog
Section titled “AWS Service Catalog”Service Catalog is a governance layer rather than an authoring tool. A platform team publishes approved CloudFormation templates as products, groups them into portfolios, and shares those portfolios with accounts or with the whole organisation. A team then provisions a product without holding permissions on the underlying services, because the provisioning is done by a launch role held by Service Catalog.
It answers a different question from the other three: not “how do I describe this infrastructure” but “how do I let fifty teams provision infrastructure without giving fifty teams administrator access”. See cross-account infrastructure deployment.
Comparison
Section titled “Comparison”| CloudFormation | SAM | CDK | Service Catalog | |
|---|---|---|---|---|
| Primary use | General infrastructure as code | Serverless applications | Programmatic IaC | Governed self-service provisioning |
| Authored in | YAML or JSON | YAML | TypeScript, Python, Java, C#, Go | CloudFormation templates |
| Learning curve | Moderate | Low | Moderate to high | Low for consumers |
| Flexibility | High | Medium | Very high | Medium |
| Local testing | No | Yes, via the SAM CLI | Via the SAM CLI | No |
| Output | A stack | A stack | A stack | A provisioned product, backed by a stack |
Choosing
Section titled “Choosing”CloudFormation when the workload is not serverless, when declarative templates are preferred, or when a template has to be readable by people who do not run the build.
SAM when the workload is mostly Lambda, API Gateway, DynamoDB and Step Functions, and local invocation matters.
CDK when the infrastructure is complex enough that loops, conditionals and shared abstractions earn their keep, and when the team is comfortable owning a build step in the deployment path.
Service Catalog when the problem is who may provision what, rather than how it is described.
They coexist. A common arrangement is CDK or CloudFormation for platform infrastructure, SAM for individual serverless services, and Service Catalog publishing the approved patterns to application teams.
AWS Proton
Section titled “AWS Proton”Older material lists AWS Proton as a fifth option for templated microservice and container deployments. It should not be adopted: AWS closed it to new sign-ups on 7 October 2025, and support ends on 7 October 2026, after which the console and Proton resources become inaccessible. Infrastructure already deployed by Proton remains intact.
The governance role Proton played — a platform team publishing standard stacks that application teams instantiate — is covered by Service Catalog together with a CDK or CloudFormation library of shared constructs.
What they have in common
Section titled “What they have in common”- All of them produce CloudFormation stacks, so stack limits, change sets, drift detection and rollback behaviour apply to all of them equally.
- All of them can be used in the same organisation, and frequently in the same account.
- The deciding factors are team skills, the shape of the workload, how many teams have to consume the result, and how much governance the estate needs.