Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws-cdk: be able to change default settings for what resources to retain and destroy #28183

Open
2 tasks
girotomas opened this issue Nov 29, 2023 · 6 comments
Open
2 tasks
Assignees
Labels
@aws-cdk/core Related to core CDK functionality effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p2

Comments

@girotomas
Copy link

girotomas commented Nov 29, 2023

Describe the feature

Basically in cdk.json we add a new setting:

"destroyResources": ["DynamoDBTables", "IAMRoles", "CloudwatchDashboards"]

to change the default behavior of these resources.

Use Case

This allow us not to have to hardcode everywhere:

    role.applyRemovalPolicy(RemovalPolicy.DESTROY)

The main motivation is for Region Build Automation.

Disclosure: I work at AWS Redshift and we use extensively the aws-cdk. I've noticed that destroying failed stacks that got half created is a huge pain and consumption of time. There should be a easy way to set some setting that allows all resources to be deleted easily if the stack is not a production stack.

For example for new regions that don't yet serve production traffic you don't want to have a huge pain of deleting resources. You want to be able to delete those stacks easily and not to have to fight through all the "termination protection errors" and "this resource has to be deleted manually". This is really a productivity killer.

Proposed Solution

No response

Other Information

No response

Acknowledgements

  • I may be able to implement this feature request
  • This feature might incur a breaking change

CDK version used

v2

Environment details (OS name and version, etc.)

typescript amazon-linux

@girotomas girotomas added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Nov 29, 2023
@github-actions github-actions bot added @aws-cdk/aws-redshift Related to Amazon Redshift @aws-cdk/aws-iam Related to AWS Identity and Access Management labels Nov 29, 2023
@msambol
Copy link
Contributor

msambol commented Nov 29, 2023

I can take this, assuming the core team wants to support it.

@khushail khushail added needs-review p2 and removed needs-triage This issue or PR still needs to be triaged. labels Nov 29, 2023
@pahud
Copy link
Contributor

pahud commented Nov 29, 2023

Love this idea! Before we have this feature, an alternative solution is to build a helper method like this and you should be able to control the removal policy of all or specific resources behind an array of constructs and you can control your own strategy in your code.

Not fully tested but it works for me.

export class DemoStack extends Stack {
	constructor(scope: Construct, id: string, props: StackProps) {
		super(scope, id, props);
	}
	protected addRemovalPolicy(removalPolicy: RemovalPolicy, children?: IConstruct[], ) {
		(children ?? this.node.children).forEach((child) => {
			if(CfnResource.isCfnResource(child)) {
				child.applyRemovalPolicy(removalPolicy);
			} else if (Construct.isConstruct(child)) {
				this.addRemovalPolicy(removalPolicy, child.node.children)
			}
		});
	};
	protected addDestroyRemovalPolicy(children?: IConstruct[]) {
		this.addRemovalPolicy(RemovalPolicy.DESTROY, children ?? this.node.children)
	}
	protected addRetainExceptOnCreateRemovalPolicy(children?: IConstruct[]) {
		(children ?? this.node.children).forEach((child) => {
			if(CfnResource.isCfnResource(child)) {
				child.addOverride('DeletionPolicy', 'RetainExceptOnCreate')				
			} else if (Construct.isConstruct(child)) {
				this.addRetainExceptOnCreateRemovalPolicy(child.node.children)
			}
		});
	}
	protected setRetainExceptOnCreateIfRetain(children?: IConstruct[]) {
		(children ?? this.node.children).forEach((child) => {
			if(CfnResource.isCfnResource(child)) {
				if(child.cfnOptions.deletionPolicy == CfnDeletionPolicy.RETAIN) {
					child.addOverride('DeletionPolicy', 'RetainExceptOnCreate')
				}		
			} else if (Construct.isConstruct(child)) {
				this.setRetainExceptOnCreateIfRetain(child.node.children)
			}
		});
	}
}

@khushail khushail added effort/medium Medium work item – several days of effort and removed needs-review labels Nov 29, 2023
@scanlonp scanlonp self-assigned this Nov 29, 2023
@scanlonp
Copy link
Contributor

@msambol, this is something that I have thought about, and would like to support! However, I think the scope could be fairly large. I envision setting up rules that could edit defaults and/or simply set values that cannot later be changed.

This seems like it needs some more serious design work, and would likely be implemented by our core team.

If you would like to take a run at it, I would ask for some design ideas as well as some consideration of edge cases. If it is simply implementing the work around @pahud suggested, then it may be better to leave it up to the OP.

But please share your thoughts!

@msambol
Copy link
Contributor

msambol commented Nov 29, 2023

@scanlonp Feel free to drive this! I am starting a new gig soon so I'll have less time. But I'd like to follow the work because this will be interesting. 😄

@scanlonp
Copy link
Contributor

@msambol this is not something I plan on doing in the near future, but can keep you looped in!

@scanlonp scanlonp added @aws-cdk/core Related to core CDK functionality and removed @aws-cdk/aws-iam Related to AWS Identity and Access Management @aws-cdk/aws-redshift Related to Amazon Redshift labels Nov 29, 2023
@longtv2222
Copy link
Contributor

longtv2222 commented Jan 15, 2024

Running into the same problem as well, however, I got it resolved by using CDK aspect

import { CfnResource, IAspect, RemovalPolicy, App, Aspects, Stack } from "aws-cdk-lib";
import { IConstruct } from "constructs";

// This aspect set renmoval policy of all resources in a node to DESTROY
export class RemovalPolicyDestroyAspect implements IAspect {
    visit(node: IConstruct): void {
        if (CfnResource.isCfnResource(node)) {
            // Can also check if resource is a DynamoDB Table or not as well
            node.applyRemovalPolicy(RemovalPolicy.DESTROY);
        }
    }
}

const app = new App();
new Stack(app, "stack");
Aspects.of(app).add(new RemovalPolicyDestroyAspect());

The above code set retention policy of all resources in stack to DESTROY

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/core Related to core CDK functionality effort/medium Medium work item – several days of effort feature-request A feature should be added or improved. p2
Projects
None yet
Development

No branches or pull requests

7 participants