A guide for removing an existing CloudFormation stack - but retaining all managed resources.
First step - we need to get the CloudFormation stack into a state of DELETE_FAILED
. This can be achieved by attempting stack delete with an IAM role that only has IAM action rights to cloudformation:DeleteStack
and cloudformation:DescribeStackResources
.
Create a new temporary IAM role with only the following allowed policy actions - for the rest of this guide that will be IAM role TEMP_CLOUDFORMATION_ROLE
:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"cloudformation:DeleteStack",
"cloudformation:DescribeStackResources",
"iam:PassRole"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
...and the following trust relationship/assume role policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "cloudformation.amazonaws.com"
}
}
]
}
Next, configure your AWS CLI via ~/.aws/config
to include this new IAM role.
Important
Confirm you can successfully assume the temporary IAM role before attempting the failed delete operation - otherwise, you may successfully delete resources.
$ aws sts get-caller-identity --profile TEMP_CLOUDFORMATION_ROLE
{
"UserId": "AIDXXXXXXXXXXXXXXXXXX",
"Account": "1234567890",
"Arn": "arn:aws:sts::1234567890:assumed-role/TEMP_CLOUDFORMATION_ROLE"
}
Now, proceed with the CloudFormation stack delete which will intentionally fail based on the IAM permissions set for the TEMP_CLOUDFORMATION_ROLE
IAM role:
$ aws cloudformation delete-stack \
--profile TEMP_CLOUDFORMATION_ROLE \
--role-arn arn:aws:iam::1234567890:role/TEMP_CLOUDFORMATION_ROLE \
--stack-name DELETE_THIS_STACK
The CloudFormation stack will now enter a DELETE_FAILED
state.
Next, obtain a list of the logical resource IDs managed by the stack:
$ aws cloudformation describe-stack-resources \
--profile TEMP_CLOUDFORMATION_ROLE \
--stack-name DELETE_THIS_STACK \
--output text \
--query "join(' ',StackResources[].LogicalResourceId)"
Now delete the stack using the --retain-resources
argument to aws cloudformation delete-stack
- providing a space delimited list of logical resource IDs obtained above to retain:
$ aws cloudformation delete-stack \
--profile TEMP_CLOUDFORMATION_ROLE \
--retain-resources LOGICAL_RESOURCE_ID1 LOGICAL_RESOURCE_ID2 LOGICAL_RESOURCE_IDX \
--role-arn arn:aws:iam::1234567890:role/TEMP_CLOUDFORMATION_ROLE \
--stack-name DELETE_THIS_STACK
Finally, remove your temporary IAM role TEMP_CLOUDFORMATION_ROLE
. Done!
Yeah, sure.

As you can see, the policy
Then, I tried to run, with the
--profile
set to the temp user,ec2 describe-instances
, acloudformation list-stacks
and then thests get-caller-identity
to be sure about the selected user. Describe instances was not possible, so, I thought that this user could not delete ec2 resources also.Then I tried to retain resources, but, as you mention, it couldn't be done before the DELETE_FAILED state
(names changed for privacy reasons)
So, I removed the last line
--retain-resources
and re-ran. It doesn't show any output. The ec2 instances was not deleted because of a "deletion protection" that I've set to them before. I'm not 100% sure that I've set the same to the RDS database, but I remember to do it and set the "apply immediately" option. But this is another issue.Well, the RDS and some other resources were deleted. :/