Skip to content

Instantly share code, notes, and snippets.

@magnetikonline
Last active February 16, 2025 22:44
Show Gist options
  • Save magnetikonline/51bbb3de48dc4a10e11f38f9d911ac08 to your computer and use it in GitHub Desktop.
Save magnetikonline/51bbb3de48dc4a10e11f38f9d911ac08 to your computer and use it in GitHub Desktop.
Remove existing AWS CloudFormation stack, but retain all managed resources.

Delete CloudFormation stack - retaining resources

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!

Reference

@albertodiazdorado
Copy link

Would this work with resources that do not define a DeletionPolicy attribute, such as AWS::AutoScaling::AutoScalingGroup?

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-autoscalinggroup.html

@magnetikonline
Copy link
Author

magnetikonline commented Jan 8, 2024

Thanks again @martinhelfert - have updated the instructions to use an IAM role (not user) - and make use of --role-arn with all aws cloudformation delete-stack commands for additional safety. I think that's great advice 👍.

Also noted the IAM role needs a assume role policy of:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudformation.amazonaws.com"
      }
    }
  ]
}

otherwise the use of --role-arn won't work.

@SamuelNeves
Copy link

It would be really usefull if AWS just give us an option like --not-delete-resources

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment