AWS DevOps & Developer Productivity Blog
Accelerate infrastructure development with CloudFormation pre-deployment validation and simplified troubleshooting
AWS CloudFormation makes it easy to model and provision your cloud application infrastructure as code. CloudFormation templates can be written directly in JSON or YAML, or they can be generated by tools like the AWS Cloud Development Kit (CDK). Resources are created and managed by CloudFormation as units called Stacks. Additionally, change set enable you to preview the stack changes before deployment.
CloudFormation now offers powerful new features that transform how you develop and troubleshoot infrastructure as code, pre-deployment validation that catches errors in seconds, enhanced operation tracking, and simplified failure debugging. These capabilities shift-left infrastructure code validation, helping you prevent infrastructure deployment failures that impacts development velocity.
In this blog post, we’ll explore how these new features accelerate development cycles by catching common errors during change set creation and providing precise troubleshooting through operation tracking and failure filtering. Whether you’re a platform engineer managing complex multi-service deployments or a developer iterating on infrastructure templates, we’ll show you how to:
- Validate resource properties and detect naming conflicts before deployment
- Prevent deployment failures by checking S3 bucket emptiness before deletion operations
- Track operations with unique IDs for focused troubleshooting
- Quickly identify root causes using the new describe-events API
This comprehensive guide will walk through real-world scenarios demonstrating how these capabilities can reduce infrastructure deployment failures from hours of debugging to seconds of validation, helping you deliver cloud infrastructure faster and more reliably.
Key Capabilities
- Pre-deployment Validation: Catch template errors instantly instead of discovering them after resource provisioning attempts. These include pre-deployment validation for resource property syntax errors, resource naming conflicts for existing resources in your account, and S3 bucket emptiness constraint violations on delete operations.
- Operation Tracking: Say goodbye to long debugging sessions. Each stack action now comes with a unique Operation ID, transforming the “needle in haystack” troubleshooting experience into precise, targeted problem-solving.
- Streamlined Events API for simplified Debugging: Use the new describe-events API and FailedEvents=true filter to instantly pinpoint issues. One command tells you exactly what went wrong, eliminating the need to scroll through endless logs.
- Immediate Feedback: Transform your CI/CD pipeline from a potential bottleneck into a rapid iteration engine. Get immediate feedback on common deployment issues, allowing your team to fix and deploy faster than ever before.
How It works
Pre-deployment Validation
The following scenarios show how you can leverage CloudFormation pre-deployment validation to detect property syntax errors, resource naming conflicts, and constraint violations during change set creation.
Understanding Validation Modes
CloudFormation pre-deployment validation operates in two modes that determine how validation failures are handled.
- FAIL mode prevents change set execution when validation detects errors, ensuring problematic templates cannot proceed to deployment. This applies to property syntax errors and resource naming conflicts.
- WARN mode allows change set creation to succeed despite validation failures, providing warnings that developers can review and address before execution. This applies to constraint violations like S3 bucket emptiness that may be resolvable through manual intervention.
Understanding these modes helps you anticipate whether validation issues will block your deployment workflow or simply require attention before execution.
Let’s walk you through practical scenarios:
Scenario 1: Validate Resource Property Syntax
CloudFormation evaluates each resource property definition or value before provisioning begins. The following example illustrates several common resource property errors:
- The “AWS::Lambda::Function”
Roleproperty requires an ARN pattern. - The “AWS::Lambda::Function”
Timeoutproperty expects an integer instead of a string. - The “AWS::Lambda::Function”
TracingConfig.Modenested property ENUM value is invalid. - The “AWS::Lambda::Alias”
Nameproperty is required but not defined. - The “AWS::Lambda::Alias” the extra property
Descriptionin a nested pathRoutingConfig.AdditionalVersionWeights.0is not supported.
Prior to this launch, these resource configuration errors would be detected at the resource provisioning time only. However, with the pre-deployment validations feature, these errors can be identified ahead of the deployment phase, streamlining the development-test lifecycle efficiency and minimizing rollbacks during deployments.
Template
AWSTemplateFormatVersion: "2010-09-09"
Description: This template demonstrates how pre-deployment validation and enhanced troubleshooting work
Resources:
MyLambdaFunction:
Type: "AWS::Lambda::Function"
Properties:
FunctionName: "dev-test"
Role: 'MyRole' #1. Non-matching pattern
Runtime: "python3.11"
Handler: "index.lambda_handler"
Code:
ZipFile: |
import json
def lambda_handler(event, context):
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
Timeout: "30s" #2. Type mismatch
MemorySize: 128
TracingConfig:
Mode: "DISABLED" #3. Invalid ENUM
MyCandidateReleaseVersion:
Type: "AWS::Lambda::Version"
Properties:
FunctionName: !Ref "MyLambdaFunction"
Description: "v2"
MyLambdaAlias:
Type: AWS::Lambda::Alias
Properties:
#4. Missing required property "Name"
FunctionName: !Ref "MyLambdaFunction"
FunctionVersion: "$LATEST"
RoutingConfig:
AdditionalVersionWeights:
- FunctionVersion: !GetAtt "MyCandidateReleaseVersion.Version"
FunctionWeight: 0.1
Description: "10% traffic to the new version" #5. Unsupported property
Step 1: Create Change Set
Console
Create a new stack using the change set creation flow, provide the template and all required parameters.

Figure 1: Create a change set view
CLI Command
aws cloudformation create-change-set \
--stack-name "dev-lambda-stack" \
--change-set-name "updateAlias" \
--change-set-type "CREATE" \
--template-body file://lambda-with-alias-template.yaml
Step 2: Check Change Set Status
To review the status of your change set
Console

Figure 2: Describe change set status
CLI command
aws cloudformation describe-change-set \
--change-set-name "arn:aws:cloudformation:us-west-2:123456789012:changeSet/updateAlias/94498df5-1afb-43b1-9869-9f82b2d877ac"
{
"ChangeSetName": "updateAlias",
"ChangeSetId": "arn:aws:cloudformation:us-west-2:123456789012:changeSet/updateAlias/94498df5-1afb-43b1-9869-9f82b2d877ac",
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/dev-lambda-stack/2d2c3240-bb59-11f0-b080-0613dc96740d",
"StackName": "dev-lambda-stack",
"CreationTime": "2025-11-06T21:40:13.333000+00:00",
<strong> "ExecutionStatus": "UNAVAILABLE",
"Status": "FAILED",
"StatusReason": "The following hook(s)/validation failed: [AWS::EarlyValidation::PropertyValidation]. To troubleshoot Early Validation errors, use the DescribeEvents API for detailed failure information.",
"NotificationARNs": [],</strong>
"RollbackConfiguration": {},
"Capabilities": [],
"Changes": [
{
"Type": "Resource",
"ResourceChange": {
"Action": "Add",
"LogicalResourceId": "MyCandidateReleaseVersion",
"ResourceType": "AWS::Lambda::Version",
"Scope": [],
"Details": []
}
},
{
"Type": "Resource",
"ResourceChange": {
"Action": "Add",
"LogicalResourceId": "MyLambdaAlias",
"ResourceType": "AWS::Lambda::Alias",
"Scope": [],
"Details": []
}
},
{
"Type": "Resource",
"ResourceChange": {
"Action": "Add",
"LogicalResourceId": "MyLambdaFunction",
"ResourceType": "AWS::Lambda::Function",
"Scope": [],
"Details": []
}
}
],
"IncludeNestedStacks": false
}
You can see the status of the change set is failed with a detailed status reason. You can now proceed to review the change set validation results.
Step 3: Review validation results
Console
With the console, you can review multiple validation errors in a single interface. When you click on a validation, CloudFormation pinpoints the location of the invalid property error in your template.

Figure 3: Pre-deployment validations view
Use Case: Invalid ENUM value for nested property
Catching invalid configuration values before deployment. This demonstrates validation of nested properties like TracingConfig.Mode. The tool helpfully shows the supported values “Active” & “Pass through” as well as the provided invalid value “DISABLED”.

Figure 4: Validation of Invalid ENUM value for nested property
Use Case: Lambda Function Timeout property type mismatch
Preventing type-related deployment failures. Shows how validation catches string values (“30s”) where integers are required, saving developers from runtime errors.

Figure 5: Validation of Lambda Function Timeout property type mismatch
Use Case: Lambda Function Role property pattern mismatch
Validating ARN format requirements. Demonstrates pattern validation ensuring Role properties match required ARN format.

Figure 6: Lambda Function Role property pattern mismatch
Use Case: Undefined required Lambda Alias Name property
Catching missing required properties. Shows validation detecting absent mandatory fields, preventing incomplete resource definitions from reaching deployment.

Figure 7: Validation of undefined required Lambda Alias Name property
Notice how the validation Path field (e.g., “/Resources/MyLambdaFunction/Properties/TracingConfig/Mode”) pinpoints the exact template location of each error. This eliminates manual searching through hundreds of lines of infrastructure code – a common time sink that can take minutes in complex templates.
Use case: Unsupported property
Shows how CloudFormation validation catches unsupported properties. In this example, the AWS::Lambda::Alias resource had an unsupported extra property Description in a nested path RoutingConfig.AdditionalVersionWeights.0.

Figure 8: CloudFormation validation of unsupported resource property
CLI command
You can also use the new describe-events API to review the validation responses.
aws cloudformation describe-events \
--change-set-id "arn:aws:cloudformation:us-west-2:123456789012:changeSet/updateAlias/94498df5-1afb-43b1-9869-9f82b2d877ac"
{
"OperationEvents": [
{
"EventId": "d3221796-d6a4-40c3-a987-93b103e7fcc1",
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/dev-lambda-stack/2d2c3240-bb59-11f0-b080-0613dc96740d",
"OperationId": "94498df5-1afb-43b1-9869-9f82b2d877ac",
"OperationType": "CREATE_CHANGESET",
"OperationStatus": "FAILED",
"EventType": "STACK_EVENT",
"Timestamp": "2025-11-06T21:40:18.428000+00:00",
"StartTime": "2025-11-06T21:40:13.399000+00:00",
"EndTime": "2025-11-06T21:40:18.428000+00:00"
},
{
"EventId": "87b628b4-fbcb-42b0-bf07-779007bf0d85",
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/dev-lambda-stack/2d2c3240-bb59-11f0-b080-0613dc96740d",
"OperationId": "94498df5-1afb-43b1-9869-9f82b2d877ac",
"OperationType": "CREATE_CHANGESET",
"EventType": "VALIDATION_ERROR",
"LogicalResourceId": "MyLambdaFunction",
"PhysicalResourceId": "",
"ResourceType": "AWS::Lambda::Function",
"Timestamp": "2025-11-06T21:40:18.163000+00:00",
"ValidationFailureMode": "FAIL", "ValidationName": "PROPERTY_VALIDATION", "ValidationStatus": "FAILED", "ValidationStatusReason": "DISABLED is not a valid enum value. Supported values: [Active, PassThrough]", "ValidationPath": "/Resources/MyLambdaFunction/Properties/TracingConfig/Mode" },
{
"EventId": "2f89cf64-e810-4285-8936-b77f7b72228c",
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/dev-lambda-stack/2d2c3240-bb59-11f0-b080-0613dc96740d",
"OperationId": "94498df5-1afb-43b1-9869-9f82b2d877ac",
"OperationType": "CREATE_CHANGESET",
"EventType": "VALIDATION_ERROR",
"LogicalResourceId": "MyLambdaFunction",
"PhysicalResourceId": "",
"ResourceType": "AWS::Lambda::Function",
"Timestamp": "2025-11-06T21:40:18.163000+00:00",
"ValidationFailureMode": "FAIL", "ValidationName": "PROPERTY_VALIDATION", "ValidationStatus": "FAILED", "ValidationStatusReason": "Property [Timeout] expected type: Integer, found: String", "ValidationPath": "/Resources/MyLambdaFunction/Properties/Timeout" },
{
"EventId": "b2448484-4e41-4c53-b19e-6355dafeac6b",
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/dev-lambda-stack/2d2c3240-bb59-11f0-b080-0613dc96740d",
"OperationId": "94498df5-1afb-43b1-9869-9f82b2d877ac",
"OperationType": "CREATE_CHANGESET",
"EventType": "VALIDATION_ERROR",
"LogicalResourceId": "MyLambdaAlias",
"PhysicalResourceId": "",
"ResourceType": "AWS::Lambda::Alias",
"Timestamp": "2025-11-06T21:40:18.134000+00:00",
"ValidationFailureMode": "FAIL", "ValidationName": "PROPERTY_VALIDATION", "ValidationStatus": "FAILED", "ValidationStatusReason": "Required property [Name] not found", "ValidationPath": "/Resources/MyLambdaAlias/Properties" },
{
"EventId": "694e94f0-a2f1-49fd-8045-545a9cb41ca9",
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/dev-lambda-stack/2d2c3240-bb59-11f0-b080-0613dc96740d",
"OperationId": "94498df5-1afb-43b1-9869-9f82b2d877ac",
"OperationType": "CREATE_CHANGESET",
"EventType": "VALIDATION_ERROR",
"LogicalResourceId": "MyLambdaAlias",
"PhysicalResourceId": "",
"ResourceType": "AWS::Lambda::Alias",
"Timestamp": "2025-11-06T21:40:18.132000+00:00",
"ValidationFailureMode": "FAIL",
"ValidationName": "PROPERTY_VALIDATION",
"ValidationStatus": "FAILED",
"ValidationStatusReason": "Unsupported property [Description]",
"ValidationPath": "/Resources/MyLambdaAlias/Properties/RoutingConfig/AdditionalVersionWeights/0"
},
{
"EventId": "935cbd72-a637-4ad5-908d-e2ce241022ad",
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/dev-lambda-stack/2d2c3240-bb59-11f0-b080-0613dc96740d",
"OperationId": "94498df5-1afb-43b1-9869-9f82b2d877ac",
"OperationType": "CREATE_CHANGESET",
"EventType": "VALIDATION_ERROR",
"LogicalResourceId": "MyLambdaFunction",
"PhysicalResourceId": "",
"ResourceType": "AWS::Lambda::Function",
"Timestamp": "2025-11-06T21:40:18.126000+00:00",
"ValidationFailureMode": "FAIL", "ValidationName": "PROPERTY_VALIDATION", "ValidationStatus": "FAILED", "ValidationStatusReason": "Property value [MyRole] does not match pattern: ^arn:(aws[a-zA-Z-]*)?:iam::\\d{12}:role/?[a-zA-Z_0-9+=,.@\\-_/]+$", "ValidationPath": "/Resources/MyLambdaFunction/Properties/Role" },
{
"EventId": "c4d25b22-9e8f-42f9-bd2e-3391b9bdacbd",
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/dev-lambda-stack/2d2c3240-bb59-11f0-b080-0613dc96740d",
"OperationId": "94498df5-1afb-43b1-9869-9f82b2d877ac",
"OperationType": "CREATE_CHANGESET",
"OperationStatus": "IN_PROGRESS",
"EventType": "STACK_EVENT",
"Timestamp": "2025-11-06T21:40:13.399000+00:00",
"StartTime": "2025-11-06T21:40:13.399000+00:00"
}
]
}
Scenario 2: Resource Name Conflict Validation
Resource name conflict validation makes sure that new resources added to a template are not already present in your AWS account or globally (e.g: Amazon S3, Amazon Route 53 DNS), preventing deployment errors caused due to resource name conflicts
After reviewing the property validation exceptions, let’s assume that you resolved all the issues and successfully deployed the stack. Next, the you have decided to include a S3 bucket resource in the template. You name the bucket “dev-thumbnails” but didn’t verify if the bucket with this name already exists. If a bucket with this name already exists, the CreateChangeSet operation will fail, reporting to the developer that the bucket already exists.
...
MyDevThumbnailsBucket:
Type: "AWS::S3::Bucket"
Properties:
BucketName: "dev-thumbnails"
Step 1: Create Change Set
aws cloudformation create-change-set \
--stack-name "dev-lambda-stack" \
--change-set-name "addBucket" \
--template-body file://lambda-with-alias-template.yaml | jq .
Step 2: Review Deployment Validations
Use CloudFormation change set console to review validations response or use the new DescribeEvents API in the CLi.

Figure 9: Resource name conflict validation
CLI Command
aws cloudformation describe-events \
--change-set-name "arn:aws:cloudformation:us-west-2:123456789012:changeSet/addBucket/eafcdb2b-e018-4e0f-9e87-86b251f4eac5"
{
"OperationEvents": [
{
"EventId": "e6049394-30e4-466d-9fb4-b5f525144058",
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/dev-lambda-stack/2d2c3240-bb59-11f0-b080-0613dc96740d",
"OperationId": "eafcdb2b-e018-4e0f-9e87-86b251f4eac5",
"OperationType": "CREATE_CHANGESET",
"OperationStatus": "FAILED",
"EventType": "STACK_EVENT",
"Timestamp": "2025-11-06T21:58:49.872000+00:00",
"StartTime": "2025-11-06T21:58:44.252000+00:00",
"EndTime": "2025-11-06T21:58:49.872000+00:00"
},
{
"EventId": "bca310c3-61e6-4478-9b0a-3a89f816aec0",
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/dev-lambda-stack/2d2c3240-bb59-11f0-b080-0613dc96740d",
"OperationId": "eafcdb2b-e018-4e0f-9e87-86b251f4eac5",
"OperationType": "CREATE_CHANGESET",
"EventType": "VALIDATION_ERROR",
"LogicalResourceId": "MyDevThumbnailsBucket",
"PhysicalResourceId": "",
"ResourceType": "AWS::S3::Bucket",
"Timestamp": "2025-11-06T21:58:49.606000+00:00",
"ValidationFailureMode": "FAIL", "ValidationName": "NAME_CONFLICT_VALIDATION", "ValidationStatus": "FAILED", "ValidationStatusReason": "Resource of type 'AWS::S3::Bucket' with identifier 'dev-thumbnails' already exists.", "ValidationPath": "/Resources/MyDevThumbnailsBucket" },
{
"EventId": "8158f79f-ee58-4c3b-b3eb-3beace064139",
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/dev-lambda-stack/2d2c3240-bb59-11f0-b080-0613dc96740d",
"OperationId": "eafcdb2b-e018-4e0f-9e87-86b251f4eac5",
"OperationType": "CREATE_CHANGESET",
"OperationStatus": "IN_PROGRESS",
"EventType": "STACK_EVENT",
"Timestamp": "2025-11-06T21:58:44.252000+00:00",
"StartTime": "2025-11-06T21:58:44.252000+00:00"
}
]
}
Scenario 3: S3 bucket not empty
Since AWS S3 service does not allow customers to delete S3 Buckets when there are objects in them, the new pre-deployment validations will warn you if you try to delete a bucket that is not empty.
Resuming our journey, let’s assume that you fix the name conflict issue by renaming the bucket to “dev-test-tumbnails”, and then updates the stack. After testing the lambda function’s integration with S3, the dev-cycle generated a few thumbnail objects in the S3 bucket.
Later, you decide to fix the bucket name because you notice a typo: “dev-test-tumbnails” should be “dev-test-thumbnails” (missing “h”). When you update the template to use the corrected name, CloudFormation will need to create the new bucket then delete the old one during the clean-up phase.
Step 1: Create Change Set
aws cloudformation create-change-set \
--stack-name "dev-lambda-stack" \
--change-set-name "renameBucket" \
--template-body file://lambda-with-alias-template.yaml | jq .
Step 2: Review Validation
Use CloudFormation change set console to review validations response or use the new DescribeEvents API in the CLI.

Figure 10: S3 bucket emptiness on delete operation validation
CLI Command
aws cloudformation describe-events \
--change-set-name "arn:aws:cloudformation:us-west-2:123456789012:changeSet/addBucket/eafcdb2b-e018-4e0f-9e87-86b251f4eac5"
{
"OperationEvents": [
{
"EventId": "24920e0f-1941-45a5-9177-786bc805b724",
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/dev-lambda-stack/2d2c3240-bb59-11f0-b080-0613dc96740d",
"OperationId": "8fef2b60-b411-4d0e-920e-7ec7c7aa39f2",
"OperationType": "CREATE_CHANGESET",
"OperationStatus": "SUCCEEDED",
"EventType": "STACK_EVENT",
"Timestamp": "2025-11-06T22:52:26.355000+00:00",
"StartTime": "2025-11-06T22:52:21.071000+00:00",
"EndTime": "2025-11-06T22:52:26.355000+00:00"
},
{
"EventId": "c117e02d-a652-4755-9586-6d4ccb0f6504",
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/dev-lambda-stack/2d2c3240-bb59-11f0-b080-0613dc96740d",
"OperationId": "8fef2b60-b411-4d0e-920e-7ec7c7aa39f2",
"OperationType": "CREATE_CHANGESET",
"EventType": "VALIDATION_ERROR",
"LogicalResourceId": "MyDevThumbnailsBucket",
"PhysicalResourceId": "",
"ResourceType": "AWS::S3::Bucket",
"Timestamp": "2025-11-06T22:52:25.960000+00:00",
"ValidationFailureMode": "WARN", "ValidationName": "BUCKET_EMPTINESS_VALIDATION", "ValidationStatus": "FAILED", "ValidationStatusReason": "The bucket 'dev-tumbnails' is not empty. You must either delete all objects and versions or use the deletion policy to retain it, otherwise the delete operation will fail.", "ValidationPath": "/Resources/MyDevThumbnailsBucket"
},
{
"EventId": "6c66ff53-6751-4b4c-96b8-d1a33fc43b4f",
"StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/dev-lambda-stack/2d2c3240-bb59-11f0-b080-0613dc96740d",
"OperationId": "8fef2b60-b411-4d0e-920e-7ec7c7aa39f2",
"OperationType": "CREATE_CHANGESET",
"OperationStatus": "IN_PROGRESS",
"EventType": "STACK_EVENT",
"Timestamp": "2025-11-06T22:52:21.071000+00:00",
"StartTime": "2025-11-06T22:52:21.071000+00:00"
}
]
}
Bucket emptiness validation uses WARN mode, which allows change set creation to succeed even when the validation check fails. This gives you time to review and empty the bucket before execution. However, if you execute the change set without emptying the bucket, the delete operation will fail.
Notice in the output above:
ValidationStatus: "FAILED"– The emptiness check detected objects in the bucketValidationFailureMode: "WARN"– This is a warning, not a blocking errorOperationStatus: "SUCCEEDED"– Change set creation completed successfully despite the warning
This design allows you to review the warning, take corrective action (such as emptying the bucket), and then proceed with execution.
Beyond catching errors early, these capabilities also transform how you troubleshoot failed deployments with enhanced operation tracking and filtering.
New DescribeEvents API with Operation IDs and root cause filtering
The new DescribeEvents API retrieves CloudFormation events based on flexible query criteria. It groups stack operations by operation ID, enabling you to focus specifically on individual stack operations involved during your stack deployment.
Operation: An operation is any action performed on a stack, including stack lifecycle actions (Create, Update, Delete, Rollback), change set creation, nested stack creation, and automatic rollbacks triggered by failures. Each operation has a unique identifier and represents a discrete change attempt on the stack.

Figure 11: Stack Events grouped by Operation Id
Scenario
When an update operation on an existing stack fails and results in a rollback, and you want to understand the reason behind the update stack failure. Using the operation ID obtained from the update stack response or from the describe stacks response, you can call describe events to get details on the failure.
Step 1: Update Stack
aws cloudformation update-stack \
--stack-name test-1106 \
--template-body file://test-1106-update.yaml
Output:
{
"StackId": "arn:aws:cloudformation:us-west-2:012345678901:stack/test-1106/07580010-bb79-11f0-8f6c-0289bb5c804f",
"OperationId": "1c211b5a-4538-4dc9-bfed-e07734371e57"
}
Step 2: Review stack status with describe stacks
The stack description available via describe-stacks API now includes LastOperations information showing recent operation IDs and their types. This enables you to quickly identify which operations occurred and their current status without parsing through event logs.

Figure 11: CloudFormation Stack Info page showing new operation IDs
CLI Command
aws cloudformation describe-stacks \
--stack-name test-1106
{
"Stacks": [
{
"StackId": "arn:aws:cloudformation:us-west-2:012345678901:stack/test-1106/07580010-bb79-11f0-8f6c-0289bb5c804f",
"StackName": "test-1106",
"Description": "A simple CloudFormation template to create an S3 bucket.",
"CreationTime": "2025-11-07T01:28:13.778000+00:00",
"LastUpdatedTime": "2025-11-07T01:43:39.838000+00:00",
"RollbackConfiguration": {},
"StackStatus": "UPDATE_ROLLBACK_COMPLETE",
"DisableRollback": false,
"NotificationARNs": [],
"Tags": [],
"EnableTerminationProtection": false,
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
},
"LastOperations": [ { "OperationType": "ROLLBACK", "OperationId": "d0f12313-7bdb-414d-a879-828a99b36f29" }, { "OperationType": "UPDATE_STACK", "OperationId": "1c211b5a-4538-4dc9-bfed-e07734371e57" }
]
}
]
}
Step 3: Review operation status with describe events API and operation id
Using the operation ID from the previous step, you can now query specific operation events to understand exactly what happened during that operation. This targeted approach eliminates the need to search through all stack events to find relevant information.
Figure 12: New CloudFormation stack operation page
CLI Command
aws cloudformation describe-stacks \
--stack-name test-1106
{
"OperationEvents": [
{
"EventId": "76358afe-01ff-45e1-bf4d-8b89109aca57",
"StackId": "arn:aws:cloudformation:us-west-2:012345678901:stack/test-1106/07580010-bb79-11f0-8f6c-0289bb5c804f",
"OperationId": "1c211b5a-4538-4dc9-bfed-e07734371e57", "OperationType": "UPDATE_STACK",
"OperationStatus": "FAILED",
"EventType": "STACK_EVENT",
"Timestamp": "2025-11-07T01:43:44.322000+00:00",
"StartTime": "2025-11-07T01:43:39.820000+00:00",
"EndTime": "2025-11-07T01:43:44.322000+00:00"
},
{
"EventId": "01fcd898-38f3-477d-891d-e950d964d594",
"StackId": "arn:aws:cloudformation:us-west-2:012345678901:stack/test-1106/07580010-bb79-11f0-8f6c-0289bb5c804f",
"OperationId": "1c211b5a-4538-4dc9-bfed-e07734371e57", "EventType": "PROVISIONING_ERROR",
"LogicalResourceId": "MyS3Bucket",
"PhysicalResourceId": "test-1106-bucket",
"ResourceType": "AWS::S3::Bucket",
"Timestamp": "2025-11-07T01:43:43.561000+00:00",
"ResourceStatus": "UPDATE_FAILED",
"ResourceStatusReason": "The target bucket for logging does not exist (Service: Amazon S3; Status Code: 400; Error Code: InvalidTargetBucketForLogging; Request ID: ZQAPTT7646A9GQ0H; S3 Extended Request ID: 5Cl/xSAfQgs8UJ7rdq4EvsJT8pxnYLZlc3FzTgpQCxZlukoIiWYXkuds6xDzkmpurH+6epy2s9g7Ro7XN4ZFoQ==; Proxy: null)",
"ResourceProperties": "{\"BucketName\":\"test-1106-bucket\",\"LoggingConfiguration\":{\"LogFilePrefix\":\"access-logs/\",\"DestinationBucketName\":\"logs-1106-bucket\"},\"LifecycleConfiguration\":{\"Rules\":[{\"Status\":\"Enabled\",\"ExpirationInDays\":\"90\",\"Id\":\"DeleteOldVersions\"}]},\"Tags\":[{\"Value\":\"Development\",\"Key\":\"Environment\"},{\"Value\":\"CloudFormationDemo\",\"Key\":\"Project\"}]}"
},
{
"EventId": "2976d65e-44cc-4674-b771-a22d86a7d3f8",
"StackId": "arn:aws:cloudformation:us-west-2:012345678901:stack/test-1106/07580010-bb79-11f0-8f6c-0289bb5c804f",
"OperationId": "1c211b5a-4538-4dc9-bfed-e07734371e57", "EventType": "PROGRESS",
"LogicalResourceId": "MyS3Bucket",
"PhysicalResourceId": "test-1106-bucket",
"ResourceType": "AWS::S3::Bucket",
"Timestamp": "2025-11-07T01:43:43.034000+00:00",
"ResourceStatus": "UPDATE_IN_PROGRESS",
"ResourceProperties": "{\"BucketName\":\"test-1106-bucket\",\"LoggingConfiguration\":{\"LogFilePrefix\":\"access-logs/\",\"DestinationBucketName\":\"logs-bucket\"},\"LifecycleConfiguration\":{\"Rules\":[{\"Status\":\"Enabled\",\"ExpirationInDays\":\"90\",\"Id\":\"DeleteOldVersions\"}]},\"Tags\":[{\"Value\":\"Development\",\"Key\":\"Environment\"},{\"Value\":\"CloudFormationDemo\",\"Key\":\"Project\"}]}"
},
{
"EventId": "daf7e299-df02-4eab-b3e9-11a4659f789f",
"StackId": "arn:aws:cloudformation:us-west-2:012345678901:stack/test-1106/07580010-bb79-11f0-8f6c-0289bb5c804f",
"OperationId": "1c211b5a-4538-4dc9-bfed-e07734371e57", "EventType": "PROGRESS",
"LogicalResourceId": "test-1106",
"PhysicalResourceId": "arn:aws:cloudformation:us-west-2:012345678901:stack/test-1106/07580010-bb79-11f0-8f6c-0289bb5c804f",
"ResourceType": "AWS::CloudFormation::Stack",
"Timestamp": "2025-11-07T01:43:39.838000+00:00",
"ResourceStatus": "UPDATE_IN_PROGRESS",
"ResourceStatusReason": "User Initiated"
},
{
"EventId": "0b1ebf05-4496-4a8c-978e-7c081def3e4d",
"StackId": "arn:aws:cloudformation:us-west-2:012345678901:stack/test-1106/07580010-bb79-11f0-8f6c-0289bb5c804f",
"OperationId": "1c211b5a-4538-4dc9-bfed-e07734371e57", "OperationType": "UPDATE_STACK",
"OperationStatus": "IN_PROGRESS",
"EventType": "STACK_EVENT",
"Timestamp": "2025-11-07T01:43:39.820000+00:00",
"StartTime": "2025-11-07T01:43:39.820000+00:00"
}
]
}
Step 4: Identify failure root cause(s) with FailedEvents filter
The new failure root cause filter instantly surfaces only the events that caused the operation to fail. This eliminates the need to manually scan through progress events to identify the root cause of deployment failures.

Figure 13: Filter operation failure root causes
CLI Command
aws cloudformation describe-events \
--operation-id 1c211b5a-4538-4dc9-bfed-e07734371e57 \
--filter FailedEvents=true
{
"OperationEvents": [
{
"EventId": "01fcd898-38f3-477d-891d-e950d964d594",
"StackId": "arn:aws:cloudformation:us-west-2:012345678901:stack/test-1106/07580010-bb79-11f0-8f6c-0289bb5c804f",
"OperationId": "1c211b5a-4538-4dc9-bfed-e07734371e57",
"EventType": "PROVISIONING_ERROR",
"LogicalResourceId": "MyS3Bucket",
"PhysicalResourceId": "test-1106-bucket",
"ResourceType": "AWS::S3::Bucket",
"Timestamp": "2025-11-07T01:43:43.561000+00:00",
"ResourceStatus": "UPDATE_FAILED",
"ResourceStatusReason": "The target bucket for logging does not exist (Service: Amazon S3; Status Code: 400; Error Code: InvalidTargetBucketForLogging; Request ID: ZQAPTT7646A9GQ0H; S3 Extended Request ID: 5Cl/xSAfQgs8UJ7rdq4EvsJT8pxnYLZlc3FzTgpQCxZlukoIiWYXkuds6xDzkmpurH+6epy2s9g7Ro7XN4ZFoQ==; Proxy: null)",
"ResourceProperties": "{\"BucketName\":\"test-1106-bucket\",\"LoggingConfiguration\":{\"LogFilePrefix\":\"access-logs/\",\"DestinationBucketName\":\"logs-bucket\"},\"LifecycleConfiguration\":{\"Rules\":[{\"Status\":\"Enabled\",\"ExpirationInDays\":\"90\",\"Id\":\"DeleteOldVersions\"}]},\"Tags\":[{\"Value\":\"Development\",\"Key\":\"Environment\"},{\"Value\":\"CloudFormationDemo\",\"Key\":\"Project\"}]}"
}
]
}
The FailedEvents=true filter transforms troubleshooting from parsing dozens of progress events to instantly seeing only what matters. This can make diagnosis of issues during an incident much easier..
Real-World Impact
These features improve your Infrastructure development experience with CloudFormation:
- Template syntax errors: Previously discovered after minutes of provisioning, now caught in seconds
- Resource conflicts: No more failed deployments due to existing resources
- Debugging complexity: Transform troubleshooting sessions into faster targeted fixes
- CI/CD reliability: Reduce pipeline failures and improve deployment confidence
Getting Started
These capabilities are available today in all AWS Regions where CloudFormation is supported. Pre-deployment validation is automatically enabled for all change set operations, no configuration required.
Try it now:
- Create any change set from the CloudFormation console or via SDK or CLI with aws cloudformation create-change-set
- Use `aws cloudformation describe-events –change-set-name <your-changeset-arn>` to see validation results
- Filter failure root causes instantly: via console or CLI with aws cloudformation describe-events –operation-id <id> –filter FailedEvents=true
Best Practices
- Always use change sets: Even for simple updates, change sets now provide validation feedback
- Leverage Operation IDs: Use the unique identifiers for focused troubleshooting
- Filter events strategically: Use –filters FailedEvents=true to focus on problems
- Automate validation: Integrate the describe-events API into your CI/CD pipelines
- Use Console: CloudFormation console provides a visual experience with error source mapping to the specific line on your template.
Conclusion
Start using these features today in your development workflow. Whether you’re building new infrastructure or maintaining existing stacks, early validation and enhanced troubleshooting will accelerate your deployment cycles and make it easier to manage infrastructure.
Ready to experience faster CloudFormation development? Create your first change set and see validation in action.