@aws-community/ephemeral
Version:
Ephemeral Stacks! A CDK Stack and Construct that will self-destruct after a specified time period.
93 lines • 13.2 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SelfDestructConstruct = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const aws_stepfunctions_tasks_1 = require("aws-cdk-lib/aws-stepfunctions-tasks");
const aws_stepfunctions_1 = require("aws-cdk-lib/aws-stepfunctions");
const constructs_1 = require("constructs");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const custom_resources_1 = require("aws-cdk-lib/custom-resources");
const self_destruct_aspect_1 = require("./self-destruct-aspect");
class SelfDestructConstruct extends constructs_1.Construct {
constructor(scope, id, props = {}) {
super(scope, id);
const { duration } = props;
const listExecutions = new aws_stepfunctions_tasks_1.CallAwsService(this, 'ListExecutions', {
action: 'listExecutions',
iamAction: 'states:ListExecutions',
iamResources: ['*'],
parameters: {
'StateMachineArn.$': '$$.StateMachine.Id',
StatusFilter: 'RUNNING',
},
service: 'sfn',
});
const executionsMap = new aws_stepfunctions_1.Map(this, 'ExecutionsMap', {
inputPath: '$.Executions',
});
const stopExecution = new aws_stepfunctions_tasks_1.CallAwsService(this, 'StopExecution', {
action: 'stopExecution',
iamAction: 'states:StopExecution',
iamResources: ['*'],
parameters: {
Cause: 'Superceded',
'ExecutionArn.$': '$.ExecutionArn',
},
service: 'sfn',
});
executionsMap.iterator(new aws_stepfunctions_1.Choice(this, 'NotSelf?')
.when(aws_stepfunctions_1.Condition.not(aws_stepfunctions_1.Condition.stringEqualsJsonPath('$.ExecutionArn', '$$.Execution.Id')), stopExecution)
.otherwise(new aws_stepfunctions_1.Pass(this, 'self')));
const wait = new aws_stepfunctions_1.Wait(this, 'Wait', {
time: aws_stepfunctions_1.WaitTime.duration(duration),
});
const wasDelete = new aws_stepfunctions_1.Choice(this, 'WasDelete?')
.when(aws_stepfunctions_1.Condition.stringEquals('$$.Execution.Input.Action', 'Delete'), new aws_stepfunctions_1.Succeed(this, 'DeleteSuccess'))
.otherwise(wait);
const deleteStack = new aws_stepfunctions_tasks_1.CallAwsService(this, 'DeleteStack', {
action: 'deleteStack',
iamAction: 'cloudformation:DeleteStack',
iamResources: ['*'],
parameters: {
'StackName.$': '$$.Execution.Input.StackName',
},
service: 'cloudformation',
});
const finished = new aws_stepfunctions_1.Succeed(this, 'Finished');
listExecutions.next(executionsMap);
executionsMap.next(wasDelete);
wait.next(deleteStack);
deleteStack.next(finished);
const sm = new aws_stepfunctions_1.StateMachine(this, 'SelfDestructMachine', {
definitionBody: aws_stepfunctions_1.DefinitionBody.fromChainable(listExecutions),
});
const sdkCall = (Action) => ({
action: 'startExecution',
parameters: {
input: JSON.stringify({
Action,
StackArn: aws_cdk_lib_1.Stack.of(this).stackId,
StackName: aws_cdk_lib_1.Stack.of(this).stackName,
Version: `${Date.now()}`,
}),
stateMachineArn: sm.stateMachineArn,
},
physicalResourceId: custom_resources_1.PhysicalResourceId.of('SelfDestructCR'),
service: 'StepFunctions',
});
new custom_resources_1.AwsCustomResource(this, 'SelfDestructCR', {
onCreate: sdkCall('Create'),
onDelete: sdkCall('Delete'),
onUpdate: sdkCall('Update'),
policy: custom_resources_1.AwsCustomResourcePolicy.fromSdkCalls({
resources: [sm.stateMachineArn],
}),
});
aws_cdk_lib_1.Aspects.of(aws_cdk_lib_1.Stack.of(this)).add(new self_destruct_aspect_1.SelfDestructAspect());
}
}
_a = JSII_RTTI_SYMBOL_1;
SelfDestructConstruct[_a] = { fqn: "@aws-community/ephemeral.SelfDestructConstruct", version: "2.1.0" };
exports.SelfDestructConstruct = SelfDestructConstruct;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZi1kZXN0cnVjdC1jb25zdHJ1Y3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc2VsZi1kZXN0cnVjdC1jb25zdHJ1Y3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxpRkFBcUU7QUFDckUscUVBUWtEO0FBQ2xELDJDQUF1QztBQUN2Qyw2Q0FBdUQ7QUFDdkQsbUVBRzJEO0FBQzNELGlFQUE0RDtBQU01RCxNQUFhLHFCQUFzQixTQUFRLHNCQUFTO0lBQ2xELFlBQWEsS0FBZ0IsRUFBRSxFQUFVLEVBQUUsUUFBb0MsRUFDaEQ7UUFDN0IsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsS0FBSyxDQUFDO1FBRTNCLE1BQU0sY0FBYyxHQUFHLElBQUksd0NBQWMsQ0FBQyxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7WUFDaEUsTUFBTSxFQUFFLGdCQUFnQjtZQUN4QixTQUFTLEVBQUUsdUJBQXVCO1lBQ2xDLFlBQVksRUFBRSxDQUFDLEdBQUcsQ0FBQztZQUNuQixVQUFVLEVBQUU7Z0JBQ1YsbUJBQW1CLEVBQUUsb0JBQW9CO2dCQUN6QyxZQUFZLEVBQUUsU0FBUzthQUN4QjtZQUNELE9BQU8sRUFBRSxLQUFLO1NBQ2YsQ0FBQyxDQUFDO1FBRUgsTUFBTSxhQUFhLEdBQUcsSUFBSSx1QkFBRyxDQUFDLElBQUksRUFBRSxlQUFlLEVBQUU7WUFDbkQsU0FBUyxFQUFFLGNBQWM7U0FDMUIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxhQUFhLEdBQUcsSUFBSSx3Q0FBYyxDQUFDLElBQUksRUFBRSxlQUFlLEVBQUU7WUFDOUQsTUFBTSxFQUFFLGVBQWU7WUFDdkIsU0FBUyxFQUFFLHNCQUFzQjtZQUNqQyxZQUFZLEVBQUUsQ0FBQyxHQUFHLENBQUM7WUFDbkIsVUFBVSxFQUFFO2dCQUNWLEtBQUssRUFBRSxZQUFZO2dCQUNuQixnQkFBZ0IsRUFBRSxnQkFBZ0I7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RSxDQUFDLGVBQWUsQ0FBQzthQUNoQyxDQUFDO1NBQ0gsQ0FBQyxDQUFDO1FBRUgscUJBQU8sQ0FBQyxFQUFFLENBQUMsbUJBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSx5Q0FBa0IsRUFBRSxDQUFDLENBQUM7SUFDM0QsQ0FBQzs7OztBQXBHVSxzREFBcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDYWxsQXdzU2VydmljZSB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zdGVwZnVuY3Rpb25zLXRhc2tzJztcbmltcG9ydCB7IENob2ljZSxcbiAgQ29uZGl0aW9uLFxuICBEZWZpbml0aW9uQm9keSxcbiAgTWFwLFxuICBQYXNzLFxuICBTdGF0ZU1hY2hpbmUsXG4gIFN1Y2NlZWQsXG4gIFdhaXQsXG4gIFdhaXRUaW1lIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXN0ZXBmdW5jdGlvbnMnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBBc3BlY3RzLCBEdXJhdGlvbiwgU3RhY2sgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBBd3NDdXN0b21SZXNvdXJjZSxcbiAgQXdzQ3VzdG9tUmVzb3VyY2VQb2xpY3ksXG4gIEF3c1Nka0NhbGwsXG4gIFBoeXNpY2FsUmVzb3VyY2VJZCB9IGZyb20gJ2F3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXMnO1xuaW1wb3J0IHsgU2VsZkRlc3RydWN0QXNwZWN0IH0gZnJvbSAnLi9zZWxmLWRlc3RydWN0LWFzcGVjdCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VsZkRlc3RydWN0Q29uc3RydWN0UHJvcHMge1xuICByZWFkb25seSBkdXJhdGlvbjogRHVyYXRpb25cbn1cblxuZXhwb3J0IGNsYXNzIFNlbGZEZXN0cnVjdENvbnN0cnVjdCBleHRlbmRzIENvbnN0cnVjdCB7XG4gIGNvbnN0cnVjdG9yIChzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogU2VsZkRlc3RydWN0Q29uc3RydWN0UHJvcHMgPSB7XG4gIH0gYXMgU2VsZkRlc3RydWN0Q29uc3RydWN0UHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgY29uc3QgeyBkdXJhdGlvbiB9ID0gcHJvcHM7XG5cbiAgICBjb25zdCBsaXN0RXhlY3V0aW9ucyA9IG5ldyBDYWxsQXdzU2VydmljZSh0aGlzLCAnTGlzdEV4ZWN1dGlvbnMnLCB7XG4gICAgICBhY3Rpb246ICdsaXN0RXhlY3V0aW9ucycsXG4gICAgICBpYW1BY3Rpb246ICdzdGF0ZXM6TGlzdEV4ZWN1dGlvbnMnLFxuICAgICAgaWFtUmVzb3VyY2VzOiBbJyonXSxcbiAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgJ1N0YXRlTWFjaGluZUFybi4kJzogJyQkLlN0YXRlTWFjaGluZS5JZCcsXG4gICAgICAgIFN0YXR1c0ZpbHRlcjogJ1JVTk5JTkcnLFxuICAgICAgfSxcbiAgICAgIHNlcnZpY2U6ICdzZm4nLFxuICAgIH0pO1xuXG4gICAgY29uc3QgZXhlY3V0aW9uc01hcCA9IG5ldyBNYXAodGhpcywgJ0V4ZWN1dGlvbnNNYXAnLCB7XG4gICAgICBpbnB1dFBhdGg6ICckLkV4ZWN1dGlvbnMnLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgc3RvcEV4ZWN1dGlvbiA9IG5ldyBDYWxsQXdzU2VydmljZSh0aGlzLCAnU3RvcEV4ZWN1dGlvbicsIHtcbiAgICAgIGFjdGlvbjogJ3N0b3BFeGVjdXRpb24nLFxuICAgICAgaWFtQWN0aW9uOiAnc3RhdGVzOlN0b3BFeGVjdXRpb24nLFxuICAgICAgaWFtUmVzb3VyY2VzOiBbJyonXSxcbiAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgQ2F1c2U6ICdTdXBlcmNlZGVkJyxcbiAgICAgICAgJ0V4ZWN1dGlvbkFybi4kJzogJyQuRXhlY3V0aW9uQXJuJyxcbiAgICAgIH0sXG4gICAgICBzZXJ2aWNlOiAnc2ZuJyxcbiAgICB9KTtcblxuICAgIGV4ZWN1dGlvbnNNYXAuaXRlcmF0b3IoXG4gICAgICBuZXcgQ2hvaWNlKHRoaXMsICdOb3RTZWxmPycpXG4gICAgICAgIC53aGVuKFxuICAgICAgICAgIENvbmRpdGlvbi5ub3QoXG4gICAgICAgICAgICBDb25kaXRpb24uc3RyaW5nRXF1YWxzSnNvblBhdGgoJyQuRXhlY3V0aW9uQXJuJywgJyQkLkV4ZWN1dGlvbi5JZCcpLFxuICAgICAgICAgICksXG4gICAgICAgICAgc3RvcEV4ZWN1dGlvbixcbiAgICAgICAgKVxuICAgICAgICAub3RoZXJ3aXNlKG5ldyBQYXNzKHRoaXMsICdzZWxmJykpLFxuICAgICk7XG5cbiAgICBjb25zdCB3YWl0ID0gbmV3IFdhaXQodGhpcywgJ1dhaXQnLCB7XG4gICAgICB0aW1lOiBXYWl0VGltZS5kdXJhdGlvbihkdXJhdGlvbiksXG4gICAgfSk7XG4gICAgY29uc3Qgd2FzRGVsZXRlID0gbmV3IENob2ljZSh0aGlzLCAnV2FzRGVsZXRlPycpXG4gICAgICAud2hlbihcbiAgICAgICAgQ29uZGl0aW9uLnN0cmluZ0VxdWFscygnJCQuRXhlY3V0aW9uLklucHV0LkFjdGlvbicsICdEZWxldGUnKSxcbiAgICAgICAgbmV3IFN1Y2NlZWQodGhpcywgJ0RlbGV0ZVN1Y2Nlc3MnKSxcbiAgICAgIClcbiAgICAgIC5vdGhlcndpc2Uod2FpdCk7XG5cbiAgICBjb25zdCBkZWxldGVTdGFjayA9IG5ldyBDYWxsQXdzU2VydmljZSh0aGlzLCAnRGVsZXRlU3RhY2snLCB7XG4gICAgICBhY3Rpb246ICdkZWxldGVTdGFjaycsXG4gICAgICBpYW1BY3Rpb246ICdjbG91ZGZvcm1hdGlvbjpEZWxldGVTdGFjaycsXG4gICAgICBpYW1SZXNvdXJjZXM6IFsnKiddLFxuICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAnU3RhY2tOYW1lLiQnOiAnJCQuRXhlY3V0aW9uLklucHV0LlN0YWNrTmFtZScsXG4gICAgICB9LFxuICAgICAgc2VydmljZTogJ2Nsb3VkZm9ybWF0aW9uJyxcbiAgICB9KTtcblxuICAgIGNvbnN0IGZpbmlzaGVkID0gbmV3IFN1Y2NlZWQodGhpcywgJ0ZpbmlzaGVkJyk7XG5cbiAgICBsaXN0RXhlY3V0aW9ucy5uZXh0KGV4ZWN1dGlvbnNNYXApO1xuICAgIGV4ZWN1dGlvbnNNYXAubmV4dCh3YXNEZWxldGUpO1xuICAgIHdhaXQubmV4dChkZWxldGVTdGFjayk7XG4gICAgZGVsZXRlU3RhY2submV4dChmaW5pc2hlZCk7XG5cbiAgICBjb25zdCBzbSA9IG5ldyBTdGF0ZU1hY2hpbmUodGhpcywgJ1NlbGZEZXN0cnVjdE1hY2hpbmUnLCB7XG4gICAgICBkZWZpbml0aW9uQm9keTogRGVmaW5pdGlvbkJvZHkuZnJvbUNoYWluYWJsZShsaXN0RXhlY3V0aW9ucyksXG4gICAgfSk7XG5cbiAgICBjb25zdCBzZGtDYWxsID0gKEFjdGlvbjogc3RyaW5nKTogQXdzU2RrQ2FsbCA9PiAoe1xuICAgICAgYWN0aW9uOiAnc3RhcnRFeGVjdXRpb24nLFxuICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICBpbnB1dDogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgIEFjdGlvbixcbiAgICAgICAgICBTdGFja0FybjogU3RhY2sub2YodGhpcykuc3RhY2tJZCxcbiAgICAgICAgICBTdGFja05hbWU6IFN0YWNrLm9mKHRoaXMpLnN0YWNrTmFtZSxcbiAgICAgICAgICBWZXJzaW9uOiBgJHtEYXRlLm5vdygpfWAsXG4gICAgICAgIH0pLFxuICAgICAgICBzdGF0ZU1hY2hpbmVBcm46IHNtLnN0YXRlTWFjaGluZUFybixcbiAgICAgIH0sXG4gICAgICBwaHlzaWNhbFJlc291cmNlSWQ6IFBoeXNpY2FsUmVzb3VyY2VJZC5vZignU2VsZkRlc3RydWN0Q1InKSxcbiAgICAgIHNlcnZpY2U6ICdTdGVwRnVuY3Rpb25zJyxcbiAgICB9KTtcblxuICAgIG5ldyBBd3NDdXN0b21SZXNvdXJjZSh0aGlzLCAnU2VsZkRlc3RydWN0Q1InLCB7XG4gICAgICBvbkNyZWF0ZTogc2RrQ2FsbCgnQ3JlYXRlJyksXG4gICAgICBvbkRlbGV0ZTogc2RrQ2FsbCgnRGVsZXRlJyksXG4gICAgICBvblVwZGF0ZTogc2RrQ2FsbCgnVXBkYXRlJyksXG4gICAgICBwb2xpY3k6IEF3c0N1c3RvbVJlc291cmNlUG9saWN5LmZyb21TZGtDYWxscyh7XG4gICAgICAgIHJlc291cmNlczogW3NtLnN0YXRlTWFjaGluZUFybl0sXG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIEFzcGVjdHMub2YoU3RhY2sub2YodGhpcykpLmFkZChuZXcgU2VsZkRlc3RydWN0QXNwZWN0KCkpO1xuICB9XG59XG4iXX0=