Infrastructure as Code
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. See the section bibliography for the reference material consulted while preparing these pages. |
Examples on this page target AWS CLI 2.37 (2.37.7 was current when checked), the AWS CDK CLI 2.1143 together with
aws-cdk-lib 2.272, AWS SAM CLI 1.166 and the Terraform hashicorp/aws provider 6.67, all checked on 2026-10-01.
The CDK CLI and the construct library are versioned separately, so their numbers no longer match. Re-verify version
numbers with aws --version, cdk --version and sam --version before relying on exact behaviour. The Bookshelf
scenario used here (a static front end, catalog-api, orders-api and the notifier worker) is described in
the section introduction; the region us-east-1 and the account ID 111122223333 are
placeholders.
Declarative vs. imperative management
AWS resources can be managed imperatively, by running a sequence of commands such as aws ec2 create-vpc …, or
declaratively, by submitting a template that describes the desired end state and letting a service work out which
resources to create, update or delete. An imperative script only performs the action it was written for: rerunning it
against an environment that has changed either fails or does the wrong thing. A declarative definition can be applied
again and again, and the engine compares it with the current state, which is what makes previews (change sets), rollback
and drift detection possible.
AWS offers its own declarative engine, AWS CloudFormation, and three authoring layers on top of or beside it:
| Tool | What you write | What runs |
|---|---|---|
CloudFormation |
YAML or JSON templates |
CloudFormation itself, as stacks |
AWS CDK v2 |
Java, TypeScript, Python, .NET or Go code |
|
AWS SAM |
A CloudFormation template with a short |
SAM expands it to plain CloudFormation, then deploys it as a stack |
Terraform |
HCL, with the |
Terraform, which calls the AWS APIs directly and keeps its own state |
Older guides and tutorials sometimes present the AWS CDK v2 as a developer preview, the AWS Copilot CLI as the easiest way to deploy containers, or AWS Application Composer as the visual editor. The CDK v2 has been generally available since December 2021, the Copilot CLI is out of support (see AWS Copilot CLI end of support), and Application Composer has been renamed AWS Infrastructure Composer.
CloudFormation
Template anatomy
A template is a YAML or JSON document. Only Resources is required; the other top-level sections are optional:
| Section | Purpose |
|---|---|
|
Inputs supplied at deploy time, with types, defaults, allowed values and constraints |
|
Static lookup tables, for example per-region values |
|
Boolean expressions that switch resources or properties on and off |
|
The AWS resources to create (required) |
|
Values to show after deployment or to export to other stacks |
|
Macros such as |
Intrinsic functions connect the pieces: !Ref returns a parameter value or a resource identifier, !GetAtt returns an
attribute such as an ARN, !Sub substitutes variables into a string, and !Select with !GetAZs picks Availability
Zones. Pseudo parameters such as ${AWS::Region}, ${AWS::AccountId} and ${AWS::StackName} are resolved by
CloudFormation, so a template never needs to hard-code an account ID or a region.
Stacks
A stack is the unit CloudFormation creates, updates and deletes: every resource in the template belongs to exactly one
stack, and deleting the stack deletes the resources it created, in dependency order. If a create or update fails,
CloudFormation rolls the stack back to its last known good state. Resources are identified inside the stack by their
logical ID (for example CatalogApiRepository); the physical name AWS assigns is generated unless the template sets it.
Fixing a physical name, as the Bookshelf template does for ECR repositories and log groups, makes names predictable but
means a replacement cannot be created before the old resource is deleted.
Change sets
A change set is a preview: CloudFormation compares the submitted template and parameters with the running stack and lists every resource it would add, modify or remove, and whether a modification needs a replacement. Nothing changes until the change set is executed, so it is the equivalent of a plan in other tools and the safest way to update a shared stack. Newer drift-aware change sets can also compare the template with the real, drifted state of the resources and, when requested, revert the differences; check the current CloudFormation documentation for the exact mode names.
Drift detection
Drift is any difference between what the template says and what exists, usually caused by someone editing a resource in
the console or with the CLI. Drift detection compares the actual configuration of the supported resources with the
stack definition and reports each resource as IN_SYNC or MODIFIED, listing the differing properties. Drift detection
reports; it does not repair. Fix drift either by editing the resource back, by updating the template to accept the new
state, or by running a drift-aware change set.
Other CloudFormation features
-
Stack refactoring moves resources between stacks, or renames logical IDs, without recreating them.
-
The IaC generator scans resources that already exist in an account and produces a template for them, which is the usual way to bring hand-built infrastructure under management.
-
Pre-deployment validation checks a template or change set for errors that would otherwise only appear while a stack is being created, such as resource name conflicts.
-
StackSets deploy one template to many accounts and Regions, typically across an organization, see Accounts and Organizations.
-
Rollback triggers tie a stack update to CloudWatch alarms so a failing deployment rolls back automatically.
In the AWS Management Console
-
Open the CloudFormation console and use the Region selector (top right) to choose the Region the stack will live in.
-
Choose Stacks, then Create stack and With new resources (standard).
-
Under Prerequisite - Prepare template choose Choose an existing template, then upload the template file and choose Next.
-
Enter a stack name and fill in the parameters, then choose Next twice and review the summary. Acknowledge any IAM capability prompt, which appears only when the template creates IAM resources.
-
Choose Submit and watch the Events tab until the stack reaches
CREATE_COMPLETE. -
To update, open the stack, choose Update stack, then Make a direct update or Create change set. Choosing a change set shows the Changes tab, where Execute change set applies it.
-
To check drift, choose Stack actions, then Detect drift, and afterwards View drift results.
-
To pick a different tool, Infrastructure Composer in the same console lets you assemble a template visually, and IaC generator in the left navigation scans existing resources into a template.
With the AWS CLI
aws cloudformation deploy is the one-command route: it creates a change set, waits for it and executes it, creating the
stack when it does not exist yet.
STACK="bookshelf-baseline"
aws cloudformation validate-template \
--template-body file://bookshelf-baseline.yaml
aws cloudformation deploy \
--stack-name "$STACK" \
--template-file bookshelf-baseline.yaml \
--parameter-overrides EnvironmentName=bookshelf \
--tags project=bookshelf
See the aws cloudformation deploy and validate-template command references.
To review before applying, create, inspect and execute a change set explicitly. Use --change-set-type CREATE for a
stack that does not exist yet and UPDATE afterwards:
STACK="bookshelf-baseline"
CHANGE_SET="add-private-subnets"
aws cloudformation create-change-set \
--stack-name "$STACK" \
--change-set-name "$CHANGE_SET" \
--change-set-type UPDATE \
--template-body file://bookshelf-baseline.yaml
aws cloudformation wait change-set-create-complete \
--stack-name "$STACK" --change-set-name "$CHANGE_SET"
aws cloudformation describe-change-set \
--stack-name "$STACK" --change-set-name "$CHANGE_SET" \
--query 'Changes[].ResourceChange.[Action,LogicalResourceId,Replacement]' \
--output table
aws cloudformation execute-change-set \
--stack-name "$STACK" --change-set-name "$CHANGE_SET"
See create-change-set and the change sets user guide page.
Follow a deployment and detect drift:
STACK="bookshelf-baseline"
aws cloudformation describe-stack-events \
--stack-name "$STACK" \
--query 'StackEvents[0:10].[Timestamp,LogicalResourceId,ResourceStatus,ResourceStatusReason]' \
--output table
DRIFT_ID=$(aws cloudformation detect-stack-drift \
--stack-name "$STACK" --query StackDriftDetectionId --output text)
aws cloudformation describe-stack-drift-detection-status \
--stack-drift-detection-id "$DRIFT_ID"
aws cloudformation describe-stack-resource-drifts \
--stack-name "$STACK" \
--stack-resource-drift-status-filters MODIFIED DELETED
See detect-stack-drift and the drift detection user guide page.
AWS CDK v2
The AWS Cloud Development Kit (CDK) lets you define infrastructure in a general-purpose language and generates CloudFormation from it, so loops, functions, types and unit tests are available. A CDK app contains one or more stacks, and each stack contains constructs, in three levels:
-
L1 constructs (
CfnVpc,CfnRepository) map one to one to CloudFormation resources. -
L2 constructs (
Vpc,Repository,Cluster) wrap a resource with sensible defaults and helper methods, for examplerepository.grantPull(role). -
L3 constructs (patterns) combine several resources, such as an ECS service behind a load balancer.
The CLI is installed separately from the library (npm install -g aws-cdk), and since the CLI and aws-cdk-lib
are versioned independently, a newer CLI can deploy apps built with an older library. The commands are:
| Command | Purpose |
|---|---|
|
One-time, per account and Region: creates the |
|
Generates the CloudFormation template(s) into |
|
Compares the synthesized template with the deployed stack, like a change set |
|
Synthesizes and deploys through CloudFormation |
|
Deletes the stack |
The following Java app defines the same Bookshelf baseline as the CloudFormation template later on this page (network, registries and cluster):
package com.example.bookshelf;
import java.util.List;
import software.amazon.awscdk.App;
import software.amazon.awscdk.RemovalPolicy;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.ec2.SubnetConfiguration;
import software.amazon.awscdk.services.ec2.SubnetType;
import software.amazon.awscdk.services.ec2.Vpc;
import software.amazon.awscdk.services.ecr.Repository;
import software.amazon.awscdk.services.ecr.TagMutability;
import software.amazon.awscdk.services.ecs.Cluster;
import software.constructs.Construct;
public class BaselineStack extends Stack {
public BaselineStack(final Construct scope, final String id, final StackProps props) {
super(scope, id, props);
Vpc vpc = Vpc.Builder.create(this, "Vpc")
.maxAzs(2)
.natGateways(0)
.subnetConfiguration(List.of(
SubnetConfiguration.builder().name("public")
.subnetType(SubnetType.PUBLIC).cidrMask(24).build(),
SubnetConfiguration.builder().name("private")
.subnetType(SubnetType.PRIVATE_ISOLATED).cidrMask(24).build()))
.build();
for (String name : List.of("catalog-api", "orders-api", "notifier")) {
Repository.Builder.create(this, "Repo-" + name)
.repositoryName("bookshelf/" + name)
.imageTagMutability(TagMutability.IMMUTABLE)
.removalPolicy(RemovalPolicy.DESTROY)
.emptyOnDelete(true)
.build();
}
Cluster.Builder.create(this, "Cluster")
.clusterName("bookshelf")
.vpc(vpc)
.build();
}
public static void main(final String[] args) {
App app = new App();
new BaselineStack(app, "BookshelfBaseline", StackProps.builder().build());
app.synth();
}
}
See the AWS CDK v2 Developer Guide and the
CDK Java API reference. Leaving env unset makes the stack
environment-agnostic, so the account and Region come from the CLI profile at deploy time.
In the AWS Management Console
The CDK has no console workflow of its own, but everything it deploys is a normal CloudFormation stack. Open the
CloudFormation console, find the stack (BookshelfBaseline, plus the CDKToolkit stack created by bootstrapping), and
use the Template tab to see the generated template and the Resources tab to see what was created.
AWS SAM
The AWS Serverless Application Model (SAM) is a CloudFormation extension for serverless applications. A template that
declares Transform: AWS::Serverless-2016-10-31 can use short resource types such as AWS::Serverless::Function,
AWS::Serverless::Api, AWS::Serverless::HttpApi and AWS::Serverless::SimpleTable, which SAM expands into the
Lambda functions, IAM roles, event source mappings and API resources they imply. The SAM CLI adds local development
commands on top. The Bookshelf notifier (an SQS-triggered function) looks like this:
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: Bookshelf notifier worker (SQS-triggered Lambda)
Resources:
NotifierQueue:
Type: AWS::SQS::Queue
Properties:
QueueName: bookshelf-notifier
VisibilityTimeout: 60
Notifier:
Type: AWS::Serverless::Function
Properties:
FunctionName: notifier
CodeUri: notifier/
Handler: com.example.bookshelf.NotifierHandler::handleRequest
Runtime: java25
Architectures: [arm64]
MemorySize: 512
Timeout: 30
SnapStart:
ApplyOn: PublishedVersions
AutoPublishAlias: live
Events:
Orders:
Type: SQS
Properties:
Queue: !GetAtt NotifierQueue.Arn
BatchSize: 10
See the AWS::Serverless::Function reference. The function itself is covered in AWS Lambda and the event wiring in Lambda: Event-Driven and Serverless Apps.
In the AWS Management Console
-
Open the Lambda console, choose Create function, and use Use a blueprint or Author from scratch; the console can also export a function to Infrastructure Composer, which generates a SAM template.
-
Open Infrastructure Composer in the console to drag resources onto a canvas and download or sync the generated SAM or CloudFormation template.
-
A deployed SAM application is an ordinary CloudFormation stack: find it under CloudFormation Stacks, and use View in Application Composer (or Infrastructure Composer) on its Template tab to see it as a diagram.
With the SAM CLI
sam init # pick a quick-start template and runtime
sam build # compile and stage artifacts in .aws-sam/build
sam local invoke Notifier --event events/order.json
sam deploy --guided # first deployment, saves samconfig.toml
sam sync --stack-name bookshelf-notifier --watch # fast dev loop, not for production
sam delete --stack-name bookshelf-notifier
See the SAM
CLI command reference. sam local invoke and sam local start-api need Docker running.
Terraform
Terraform is a third-party tool from HashiCorp that calls the AWS APIs through the hashicorp/aws provider. Unlike
CloudFormation, there is no AWS-managed state: Terraform stores its own state file, usually in an S3 bucket with
locking. The example below provisions two of the Bookshelf baseline resources, an ECR repository and a log group,
with provider version 6:
terraform {
required_version = ">= 1.10"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.0"
}
}
}
provider "aws" {
region = "us-east-1" # placeholder Region
}
resource "aws_ecr_repository" "catalog_api" {
name = "bookshelf/catalog-api"
image_tag_mutability = "IMMUTABLE"
force_delete = true # allow destroy even when images exist
encryption_configuration {
encryption_type = "AES256"
}
}
resource "aws_cloudwatch_log_group" "catalog_api" {
name = "/bookshelf/catalog-api"
retention_in_days = 30
}
See the hashicorp/aws provider documentation and
the version 6 upgrade guide.
In-depth Terraform coverage, including remote state, modules and pipelines, is tracked separately in GitHub issue
#171 of this documentation repository and is not repeated here. The usual cycle is terraform init,
terraform plan, terraform apply and terraform destroy; credentials come from the same CLI profile or
environment variables as every other AWS tool, see Getting Started with AWS.
AWS Copilot CLI end of support
The AWS Copilot CLI, a command-line tool that generated CloudFormation to deploy containerized applications on ECS and
Fargate (copilot init, copilot deploy), reached end of support on 2026-06-12. It no longer receives fixes or new
features. The CloudFormation stacks it created are ordinary stacks and continue to run, but they should be managed
another way going forward. The current options are:
-
ECS Express Mode for a fast path from a container image to a load-balanced Fargate service, see ECS and Fargate.
-
A CloudFormation template or CDK app for full control, as in the Bookshelf baseline below.
-
The AWS CDK ECS patterns for the same load-balanced-service shape Copilot produced.
Tutorials that still start with copilot init should be treated as outdated. See
the end-of-support
announcement and its migration guidance.
Bookshelf baseline: a runnable CloudFormation template
The template below creates the shared Bookshelf baseline that later pages build on: a VPC with two public and two
isolated private subnets across two Availability Zones, an internet gateway and public route table, three ECR
repositories (bookshelf/catalog-api, bookshelf/orders-api, bookshelf/notifier), an ECS cluster named bookshelf
with the Fargate and Fargate Spot capacity providers, and one CloudWatch log group per service. It creates no IAM
resources and no NAT gateway, so deploying it needs no capability acknowledgement and no hourly network charge, though
the VPC itself, the repositories and the log groups cost nothing until used. Save it as bookshelf-baseline.yaml.
AWSTemplateFormatVersion: "2010-09-09"
Description: Bookshelf baseline - VPC, ECR repositories, ECS cluster and log groups
Parameters:
EnvironmentName:
Type: String
Default: bookshelf
AllowedPattern: "[a-z][a-z0-9-]{1,30}"
Description: Prefix used in resource names and tags.
VpcCidr:
Type: String
Default: 10.0.0.0/16
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(1[6-9]|2[0-4])"
Description: CIDR block of the VPC (a /16 to /24 range).
LogRetentionDays:
Type: Number
Default: 30
AllowedValues: [7, 14, 30, 60, 90, 180, 365]
Description: Retention for the service log groups.
Resources:
Vpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCidr
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Sub "${EnvironmentName}-vpc"
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Sub "${EnvironmentName}-igw"
InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref Vpc
InternetGatewayId: !Ref InternetGateway
PublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
AvailabilityZone: !Select [0, !GetAZs ""]
CidrBlock: !Select [0, !Cidr [!Ref VpcCidr, 4, 8]]
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: !Sub "${EnvironmentName}-public-a"
PublicSubnetB:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
AvailabilityZone: !Select [1, !GetAZs ""]
CidrBlock: !Select [1, !Cidr [!Ref VpcCidr, 4, 8]]
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: !Sub "${EnvironmentName}-public-b"
PrivateSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
AvailabilityZone: !Select [0, !GetAZs ""]
CidrBlock: !Select [2, !Cidr [!Ref VpcCidr, 4, 8]]
Tags:
- Key: Name
Value: !Sub "${EnvironmentName}-private-a"
PrivateSubnetB:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref Vpc
AvailabilityZone: !Select [1, !GetAZs ""]
CidrBlock: !Select [3, !Cidr [!Ref VpcCidr, 4, 8]]
Tags:
- Key: Name
Value: !Sub "${EnvironmentName}-private-b"
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref Vpc
Tags:
- Key: Name
Value: !Sub "${EnvironmentName}-public-rt"
PublicDefaultRoute:
Type: AWS::EC2::Route
DependsOn: InternetGatewayAttachment
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnetARouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetA
RouteTableId: !Ref PublicRouteTable
PublicSubnetBRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnetB
RouteTableId: !Ref PublicRouteTable
CatalogApiRepository:
Type: AWS::ECR::Repository
Properties:
RepositoryName: bookshelf/catalog-api
ImageTagMutability: IMMUTABLE
EmptyOnDelete: true
EncryptionConfiguration:
EncryptionType: AES256
OrdersApiRepository:
Type: AWS::ECR::Repository
Properties:
RepositoryName: bookshelf/orders-api
ImageTagMutability: IMMUTABLE
EmptyOnDelete: true
EncryptionConfiguration:
EncryptionType: AES256
NotifierRepository:
Type: AWS::ECR::Repository
Properties:
RepositoryName: bookshelf/notifier
ImageTagMutability: IMMUTABLE
EmptyOnDelete: true
EncryptionConfiguration:
EncryptionType: AES256
Cluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Ref EnvironmentName
ClusterCapacityProviders:
Type: AWS::ECS::ClusterCapacityProviderAssociations
Properties:
Cluster: !Ref Cluster
CapacityProviders: [FARGATE, FARGATE_SPOT]
DefaultCapacityProviderStrategy:
- CapacityProvider: FARGATE
Weight: 1
CatalogApiLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub "/${EnvironmentName}/catalog-api"
RetentionInDays: !Ref LogRetentionDays
OrdersApiLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub "/${EnvironmentName}/orders-api"
RetentionInDays: !Ref LogRetentionDays
NotifierLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub "/${EnvironmentName}/notifier"
RetentionInDays: !Ref LogRetentionDays
Outputs:
VpcId:
Value: !Ref Vpc
Export:
Name: !Sub "${AWS::StackName}-VpcId"
PublicSubnetIds:
Value: !Join [",", [!Ref PublicSubnetA, !Ref PublicSubnetB]]
Export:
Name: !Sub "${AWS::StackName}-PublicSubnetIds"
PrivateSubnetIds:
Value: !Join [",", [!Ref PrivateSubnetA, !Ref PrivateSubnetB]]
Export:
Name: !Sub "${AWS::StackName}-PrivateSubnetIds"
ClusterName:
Value: !Ref Cluster
Export:
Name: !Sub "${AWS::StackName}-ClusterName"
CatalogApiRepositoryUri:
Value: !GetAtt CatalogApiRepository.RepositoryUri
See the AWS::EC2::VPC,
AWS::ECR::Repository,
AWS::ECS::Cluster
and
AWS::Logs::LogGroup
template references. Note how the template uses ${AWS::StackName} in export names so that two stacks created from it
never collide, and Fn::Cidr to carve four /24 subnets out of the VPC range instead of hard-coding them. The subnets are
explained in VPC Networking, the repositories in Container Registry, and the
cluster in ECS and Fargate.
In the AWS Management Console
-
Select the Region in the console Region selector (the template is Region-neutral;
us-east-1is a placeholder) and open CloudFormation. -
Choose Create stack, With new resources (standard), Upload a template file, and select
bookshelf-baseline.yaml. -
Name the stack
bookshelf-baseline, keep the default parameters, and choose Next until Submit. -
Wait for
CREATE_COMPLETE, then open the Outputs tab for the VPC ID, subnet IDs, cluster name and repository URI. -
Verify in the VPC, ECR, ECS and CloudWatch consoles that the resources exist.
With the AWS CLI
AWS_REGION="us-east-1"
STACK="bookshelf-baseline"
aws cloudformation validate-template \
--region "$AWS_REGION" \
--template-body file://bookshelf-baseline.yaml
aws cloudformation deploy \
--region "$AWS_REGION" \
--stack-name "$STACK" \
--template-file bookshelf-baseline.yaml \
--parameter-overrides EnvironmentName=bookshelf LogRetentionDays=30
aws cloudformation describe-stacks \
--region "$AWS_REGION" \
--stack-name "$STACK" \
--query 'Stacks[0].Outputs[].[OutputKey,OutputValue]' \
--output table
See deploy and describe-stacks. If a repository or log group with the same fixed name already exists in the Region (for example from a manual experiment), the stack creation fails and rolls back; delete the conflicting resource or change the name and retry.
Pricing and limits
CloudFormation itself has no charge for managing AWS resources with the built-in resource types; third-party and registry extensions are billed per handler operation, and the resources a template creates are billed at their own rates. Consult the CloudFormation pricing page for the current model. The CDK and SAM CLIs are free; the CDK bootstrap stack creates a small staging bucket and repository whose storage is billed like any other. Terraform’s cost depends on the edition and backend chosen. Account limits that affect larger templates include the maximum number of resources per stack, the template body size and the number of stacks per Region; see CloudFormation quotas for current values, and split large systems into several stacks or nested stacks.
Clean up
Deleting the stack removes everything created by the Bookshelf baseline. The ECR repositories use EmptyOnDelete, so
they are deleted even when images were pushed to them, and the log groups are deleted with their data:
AWS_REGION="us-east-1"
STACK="bookshelf-baseline"
aws cloudformation delete-stack --region "$AWS_REGION" --stack-name "$STACK"
aws cloudformation wait stack-delete-complete --region "$AWS_REGION" --stack-name "$STACK"
See delete-stack. For the other
tools shown here, use cdk destroy for the CDK app, sam delete --stack-name bookshelf-notifier for the SAM
application (this also removes the artifacts bucket objects it uploaded), and terraform destroy for the Terraform
example. If other stacks import this stack’s exports, delete those first, otherwise the deletion is refused. To remove
the CDK bootstrap resources as well, delete the CDKToolkit stack once it is empty; the bootstrap staging bucket
retains objects and must be emptied first. In the console, select the stack in CloudFormation and choose Delete.
Related pages
-
Getting Started with AWS for installing the AWS CLI and configuring credentials and profiles.
-
Identity and Access for the roles CloudFormation, CDK and SAM assume during deployment.
-
Developer Tools and DevOps for running these tools from CI pipelines.
-
Infrastructure as Code for the Azure counterpart (ARM, Bicep and Deployment Stacks).