# CloudFormation

Source: /aws/services/cloudformation/

## Introduction

:::note
With LocalStack version 4.8.0 (and above) we've introduced a **new CloudFormation engine** with Change Sets at its core, which would allow proper update and rollback support in the near future.

This includes internal changes that may affect existing stacks or deployment behavior. Most users will benefit from the new behavior automatically, but there are a few important notes to be aware of:

- **Persistence is not backwards-compatible:** If you use persistent state, your stacks may not load correctly between the new and old engines.
- **Default behavior has changed:** If your deployment logic depends on specific legacy quirks or unsupported update behavior, you may encounter issues.
- **New features and improvements:** are now available under the new engine.

If you encounter problems or regressions you can **revert to the legacy engine** by setting:

```bash
PROVIDER_OVERRIDE_CLOUDFORMATION=engine-legacy
```
:::

:::note

## Upcoming Change in Handling Unsupported Resource Types

In a future LocalStack release, the behavior of the CloudFormation engine will change when stacks contain **unsupported AWS resource types**.

**Currently**, unsupported resources are silently ignored or mocked so that the rest of the stack can proceed.

**With the upcoming change**, CloudFormation will instead **fail the deployment** if the template includes unsupported resource types.

To keep the current behavior and prepare for this breaking change ahead, you can enable it manually: 

```bash
CFN_IGNORE_UNSUPPORTED_RESOURCE_TYPES=1
```

:::

CloudFormation is a service provided by Amazon Web Services (AWS) that allows you to define and provision infrastructure as code.
It enables you to create, update, and manage resources in a repeatable and automated manner using declarative templates.
With CloudFormation, you can use JSON or YAML templates to define your desired infrastructure state.
You can specify resources, their configurations, dependencies, and relationships in these templates.

LocalStack supports CloudFormation, allowing you to use the CloudFormation APIs in your local environment to declaratively define your architecture on the AWS, including resources such as S3 Buckets, Lambda Functions, and much more.
The [API Coverage section](#api-coverage) and [feature coverage](#feature-coverage) provides information on the extent of CloudFormation's integration with LocalStack.

## Getting started

This guide is designed for users new to CloudFormation and assumes basic knowledge of the AWS CLI and our [`lstk aws`](/aws/developer-tools/running-localstack/lstk/cloud-and-iac-commands/#aws) command.

Start your LocalStack container using your preferred method.
We will demonstrate how to deploy a simple CloudFormation stack consisting of a single S3 Bucket with the AWS CLI.

### Create a CloudFormation Stack

CloudFormation stack is a collection of AWS resources that you can create, update, or delete as a single unit.
Stacks are defined using JSON or YAML templates.
Use the following code snippet and save the content in either `cfn-quickstart-stack.yaml` or `cfn-quickstart-stack.json`, depending on your preferred format.

<Tabs>
<TabItem label="YAML">
```yaml showshowLineNumbers
Resources:
  LocalBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: cfn-quickstart-bucket
```
</TabItem>
<TabItem label="JSON">
```json showshowLineNumbers
{
  "Resources": {
    "LocalBucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "BucketName": "cfn-quickstart-bucket"
      }
    }
  }
}
```
</TabItem>
</Tabs>

### Deploy the CloudFormation Stack

You can deploy the CloudFormation stack using the AWS CLI with the [`deploy`](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/deploy/index.html) command.
The `deploy` command creates and updates CloudFormation stacks.
Run the following command to deploy the stack:

```bash
lstk aws cloudformation deploy \
    --stack-name cfn-quickstart-stack \
    --template-file "./cfn-quickstart-stack.yaml"
```

You can verify that the stack was created successfully by listing the S3 buckets in your LocalStack container using the [`ListBucket` API](https://docs.aws.amazon.com/cli/latest/reference/s3api/list-buckets.html).
Run the following command to list the buckets:

```bash
lstk aws s3api list-buckets
```

### Delete the CloudFormation Stack

You can delete the CloudFormation stack using the [`delete-stack`](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/delete-stack.html) command.
Run the following command to delete the stack along with all the resources created by the stack:

```bash
lstk aws cloudformation delete-stack \
    --stack-name cfn-quickstart-stack
```

## Registry Extensions

LocalStack supports the execution of private CloudFormation registry extensions — custom resource types packaged with the [CloudFormation CLI](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/what-is-cloudformation-cli.html) and registered in your account's CloudFormation registry.

Registry extensions work similarly to [custom resources](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html), with one key difference: the Lambda function that handles their lifecycle is not directly managed by the user.
When a private extension is activated, LocalStack deploys and invokes the embedded handler Lambda internally, giving you full local emulation of the extension's Create, Read, Update, Delete, and List (CRUDL) lifecycle.

### Registering and using a private extension

Build and package your extension using the CloudFormation CLI, then upload the package to S3 and register the type:

```bash
lstk aws cloudformation register-type \
    --type RESOURCE \
    --type-name MyOrg::MyService::MyResource \
    --schema-handler-package s3://my-bucket/my-extension.zip
```

You can then reference the registered type in a template like any built-in resource type:

```yaml
Resources:
  MyCustomResource:
    Type: MyOrg::MyService::MyResource
    Properties:
      SomeProperty: value
```

When the stack is deployed, LocalStack routes each lifecycle operation to the handler Lambda that was deployed from the extension package.

### Supported package formats

LocalStack currently resolves the handler artifact from the following formats inside the extension ZIP package:

| Format | Description |
|:-------|:------------|
| `ResourceProvider.zip` | Python or Node.js handler produced by the CloudFormation CLI |
| Single JAR file | Java-based resource provider handler |

Support for additional payload formats will be added in future releases.

:::note
Extension packages must target a currently supported Lambda runtime.
Python 3.9 is no longer supported; use Python 3.12 or another supported runtime when building your extension.
:::

## Resource Browser

The LocalStack Web Application provides a Resource Browser for managing CloudFormation stacks to manage your AWS resources locally.
You can access the Resource Browser by opening the LocalStack Web Application in your browser, navigating to the **Resources** section, and then clicking on **CloudFormation** under the **Management/Governance** section.

![CloudFormation Resource Browser](/images/aws/cloudformation-resource-browser.png)

The Resource Browser allows you to perform the following actions:

- **Create Stack**: Create a new CloudFormation stack by clicking on **Create Stack** and provide a template file or URL, including the stack name and parameters.
- **Edit Stack**: Edit an existing CloudFormation stack by clicking on **Edit Stack** and editing the stack name and parameters and clicking on **Submit**.
- **View Stack**: View an existing CloudFormation stack by clicking on the Stack Name and viewing the stack details, including the stack name, status, and resources.
- **Delete Stack**: Delete an existing CloudFormation stack by clicking on the Stack Name and clicking on **Actions** and then **Remove Selected**.

## Examples

The following code snippets and sample applications provide practical examples of how to use CloudFormation in LocalStack for various use cases:

- [Serverless Container-based APIs with Amazon ECS & API Gateway](https://github.com/localstack/serverless-api-ecs-apigateway-sample)
- [Deploying containers on ECS clusters using ECR and Fargate](/aws/tutorials/ecs-ecr-container-app/)
- [Messaging Processing application with SQS, DynamoDB, and Fargate](https://github.com/localstack/sqs-fargate-ddb-cdk-go)
- [CloudFormation Registry Extension demo](https://github.com/localstack-samples/cloudformation-registry-demo)

## Best practices

CloudFormation templates that target both real AWS and LocalStack should avoid hardcoded values that differ between the two environments.
Using [pseudo parameters](#pseudo-parameters) and [intrinsic functions](#intrinsic-functions) keeps a single template portable without conditional logic or environment-specific parameter overrides.

### Use `AWS::URLSuffix` for service domain names

Hardcoding `amazonaws.com` (or conversely `localhost.localstack.cloud`) when building service URLs is one of the most common causes of templates that deploy on AWS but fail on LocalStack, or vice versa.
This typically shows up in API Gateway invoke URLs, Step Functions API integration targets, and other places where a template constructs a fully qualified endpoint.

The `AWS::URLSuffix` pseudo parameter resolves to `amazonaws.com` on AWS (or `amazonaws.com.cn` in China Regions) and to the configured [`LOCALSTACK_HOST`](/aws/customization/configuration-options/) on LocalStack, which defaults to `localhost.localstack.cloud`.
Referencing it lets the same template produce a valid URL in either environment.

The following snippet shows the anti-pattern to avoid, where `amazonaws.com` is hardcoded into the output URL.
A template written this way deploys on AWS but produces a non-resolvable URL on LocalStack:

```yaml
Outputs:
  ApiUrl:
    Value: !Sub "https://${MyApi}.execute-api.${AWS::Region}.amazonaws.com/${StageName}"
```

Reference `AWS::URLSuffix` instead so the same template resolves to `amazonaws.com` on AWS and to the LocalStack host locally:

```yaml
Outputs:
  ApiUrl:
    Value: !Sub "https://${MyApi}.execute-api.${AWS::Region}.${AWS::URLSuffix}/${StageName}"
```

The same pattern applies when wiring an API Gateway stage into a Step Functions task, when building a WebSocket invoke URL, or any other integration `Uri` that embeds a service domain.
The LocalStack team contributed this practice upstream to the [AWS SAM application templates](https://github.com/aws/aws-sam-cli-app-templates/pull/525) and to the [AWS serverless patterns collection](https://github.com/aws-samples/serverless-patterns) that backs [serverlessland.com/patterns](https://serverlessland.com/patterns) and the VS Code Application Builder.

:::caution
`AWS::URLSuffix` is the right tool for endpoints your template constructs, such as API Gateway URLs or service domain joins.
Avoid substituting it into URIs that AWS resolves to fixed production hostnames, for example:

- ECR image URIs such as `<account>.dkr.ecr.<region>.amazonaws.com/<image>`
- SageMaker built-in image URIs
- AppSync `HttpConfig` endpoints for Bedrock or Step Functions data sources

In those cases, the `amazonaws.com` suffix is part of a registry or service endpoint that is not served by LocalStack, so rewriting it can break the template on AWS without making it work on LocalStack.
:::

### Use `AWS::Partition` when building ARNs

Prefer composing ARNs with `AWS::Partition`, `AWS::Region`, and `AWS::AccountId` rather than embedding a literal `arn:aws:...` prefix.
The resulting template also works on AWS GovCloud and AWS China without changes:

```yaml
ManagedPolicyArns:
  - !Sub "arn:${AWS::Partition}:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs"
```

### Reference resources with `!Ref` and `Fn::GetAtt`

When one resource needs the address of another, read it from the resource itself with `!Ref` or `!GetAtt` rather than constructing the URL from service domains.
For example, use `!GetAtt MyQueue.QueueUrl` or `!GetAtt MyBucket.DomainName` so LocalStack returns the local endpoint while AWS returns the real one.

## Feature coverage

:::tip
We are continually enhancing our CloudFormation feature coverage by consistently introducing new resource types.
Your feature requests assist us in determining the priority of resource additions.
Feel free to contribute by [creating a new GitHub Discussion](https://github.com/orgs/localstack/discussions/new/choose).
:::

### Features

| Feature             | Support                                         |
|:--------------------|:------------------------------------------------|
| Parameters          | Partial                                         |
| Dynamic References  | **Full**                                        |
| Rules               | -                                               |
| Mappings            | **Full**                                        |
| Conditions          | **Full**                                        |
| Transform           | **Full**                                        |
| Outputs             | **Full**                                        |
| Custom resources    | Partial                                         |
| Drift detection     | -                                               |
| Importing Resources | -                                               |
| Change sets         | **Full**                                        |
| Nested stacks       | Partial                                         |
| StackSets           | Partial                                         |
| Intrinsic Functions | Partial                                         |
| Registry extension execution | Partial                                |

:::note
Currently, support for `UPDATE` operations on resources is limited.
Prefer stack re-creation over stack update at this time.
:::

:::note
Currently, support for `NoEcho` parameters is limited.
Parameters will be masked only in the `Parameters` section of responses to `DescribeStacks` and `DescribeChangeSets` requests.
This might expose sensitive information.
Please exercise caution when using parameters with `NoEcho`.
:::

### Intrinsic Functions

| Intrinsic Function | Supported | Explanation                                                  |
| ------------------ | --------- | ------------------------------------------------------------ |
| `Fn::And`          | Yes       | Performs a logical AND operation on two or more expressions. |
| `Fn::Or`           | Yes       | Performs a logical OR operation on two or more expressions.  |
| `Fn::Base64`       | Yes       | Converts a binary string to a Base64-encoded string.         |
| `Fn::Sub`          | Yes       | Performs a string substitution operation.                    |
| `Fn::Split`        | Yes       | Splits a string into an array of strings.                    |
| `Fn::Length`       | Yes       | Returns the length of a string.                              |
| `Fn::Join`         | Yes       | Joins an array of strings into a single string.              |
| `Fn::FindInMap`    | Yes       | Finds a value in a map.                                      |
| `Fn::Ref`          | Yes       | References a resource in the template.                       |
| `Fn::GetAtt`       | Yes       | Gets an attribute from a resource.                           |
| `Fn::If`           | Yes       | Performs a conditional evaluation.                           |
| `Fn::Import`       | Yes       | Imports a value from another template.                       |
| `Fn::ToJsonString` | No        | Converts an object or map into a json string.                |
| `Fn::Cidr`         | No        | Generates a CIDR block from the inputs.                      |
| `Fn::GetAZs`       | No        | Returns a list of the Availability Zones of a region.        |

### Pseudo Parameters

[Pseudo parameters](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html) are built-in variables that CloudFormation resolves at deployment time.
You can reference them with the `Ref` intrinsic function (for example, `!Ref AWS::Region`) or with `Fn::Sub` (for example, `!Sub "${AWS::Region}"`).
LocalStack resolves each pseudo parameter to the equivalent value for the local environment, which lets the same template deploy against both AWS and LocalStack.

| Pseudo Parameter        | Supported | Value in LocalStack                                                                         | Value in AWS                                                                      |
| ----------------------- | --------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `AWS::AccountId`        | Yes       | The account ID used by the stack (default: `000000000000`)                                  | The AWS account ID of the account deploying the stack                             |
| `AWS::NotificationARNs` | Partial   | Empty list                                                                                  | The list of SNS topic ARNs passed to the stack via `--notification-arns`          |
| `AWS::NoValue`          | Yes       | Removes the corresponding property when used as a return value in `Fn::If`                  | Same                                                                              |
| `AWS::Partition`        | Yes       | `aws`                                                                                       | `aws`, `aws-cn`, or `aws-us-gov` depending on the Region                          |
| `AWS::Region`           | Yes       | The Region of the encompassing resource                                                     | Same                                                                              |
| `AWS::StackId`          | Yes       | The ARN of the stack                                                                        | Same                                                                              |
| `AWS::StackName`        | Yes       | The name of the stack                                                                       | Same                                                                              |
| `AWS::URLSuffix`        | Yes       | The configured [`LOCALSTACK_HOST`](/aws/customization/configuration-options/) (default: `localhost.localstack.cloud`) | `amazonaws.com`, or `amazonaws.com.cn` in China Regions |

:::tip
Reach for `AWS::URLSuffix` and `AWS::Partition` instead of hardcoding `amazonaws.com` or `arn:aws:...` in templates.
See [Best practices](#best-practices) for details.
:::

### Resources

<CloudFormationCoverage client:load />

## API Coverage


### CloudFormation API coverage

Source service: `cloudformation`. 37 of 90 tracked operations are implemented.

Service documentation: /aws/services/cloudformation/
License availability: available starting with the Hobby plan. See /aws/licensing/ for current plan details.

| Operation | Status |
| --- | --- |
| ActivateOrganizationsAccess | Not implemented |
| ActivateType | Not implemented |
| BatchDescribeTypeConfigurations | Not implemented |
| CancelUpdateStack | Not implemented |
| ContinueUpdateRollback | Not implemented |
| CreateChangeSet | Implemented |
| CreateGeneratedTemplate | Not implemented |
| CreateStack | Implemented |
| CreateStackInstances | Implemented |
| CreateStackRefactor | Not implemented |
| CreateStackSet | Implemented |
| DeactivateOrganizationsAccess | Not implemented |
| DeactivateType | Not implemented |
| DeleteChangeSet | Implemented |
| DeleteGeneratedTemplate | Not implemented |
| DeleteStack | Implemented |
| DeleteStackInstances | Implemented |
| DeleteStackSet | Implemented |
| DeregisterType | Implemented |
| DescribeAccountLimits | Not implemented |
| DescribeChangeSet | Implemented |
| DescribeChangeSetHooks | Not implemented |
| DescribeEvents | Not implemented |
| DescribeGeneratedTemplate | Not implemented |
| DescribeOrganizationsAccess | Not implemented |
| DescribePublisher | Not implemented |
| DescribeResourceScan | Not implemented |
| DescribeStackDriftDetectionStatus | Not implemented |
| DescribeStackEvents | Implemented |
| DescribeStackInstance | Not implemented |
| DescribeStackRefactor | Not implemented |
| DescribeStackResource | Implemented |
| DescribeStackResourceDrifts | Not implemented |
| DescribeStackResources | Implemented |
| DescribeStackSet | Implemented |
| DescribeStackSetOperation | Implemented |
| DescribeStacks | Implemented |
| DescribeType | Implemented |
| DescribeTypeRegistration | Implemented |
| DetectStackDrift | Not implemented |
| DetectStackResourceDrift | Not implemented |
| DetectStackSetDrift | Not implemented |
| EstimateTemplateCost | Not implemented |
| ExecuteChangeSet | Implemented |
| ExecuteStackRefactor | Not implemented |
| GetGeneratedTemplate | Not implemented |
| GetHookResult | Not implemented |
| GetStackPolicy | Not implemented |
| GetTemplate | Implemented |
| GetTemplateSummary | Implemented |
| ImportStacksToStackSet | Not implemented |
| ListChangeSets | Implemented |
| ListExports | Implemented |
| ListGeneratedTemplates | Not implemented |
| ListHookResults | Not implemented |
| ListImports | Implemented |
| ListResourceScanRelatedResources | Not implemented |
| ListResourceScanResources | Not implemented |
| ListResourceScans | Not implemented |
| ListStackInstanceResourceDrifts | Not implemented |
| ListStackInstances | Implemented |
| ListStackRefactorActions | Not implemented |
| ListStackRefactors | Not implemented |
| ListStackResources | Implemented |
| ListStackSetAutoDeploymentTargets | Not implemented |
| ListStackSetOperationResults | Not implemented |
| ListStackSetOperations | Not implemented |
| ListStackSets | Implemented |
| ListStacks | Implemented |
| ListTypeRegistrations | Implemented |
| ListTypeVersions | Implemented |
| ListTypes | Implemented |
| PublishType | Not implemented |
| RecordHandlerProgress | Not implemented |
| RegisterPublisher | Not implemented |
| RegisterType | Implemented |
| RollbackStack | Not implemented |
| SetStackPolicy | Not implemented |
| SetTypeConfiguration | Not implemented |
| SetTypeDefaultVersion | Implemented |
| SignalResource | Not implemented |
| StartResourceScan | Not implemented |
| StopStackSetOperation | Not implemented |
| TestType | Not implemented |
| UpdateGeneratedTemplate | Not implemented |
| UpdateStack | Implemented |
| UpdateStackInstances | Not implemented |
| UpdateStackSet | Implemented |
| UpdateTerminationProtection | Implemented |
| ValidateTemplate | Implemented |
