UNPKG

@alma-cdk/cross-region-parameter

Version:

Store AWS SSM Parameter Store Parameters into another AWS Region with AWS CDK

116 lines 15.2 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.CrossRegionParameter = exports.OnEvent = void 0; const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti"); const aws_cdk_lib_1 = require("aws-cdk-lib"); const iam = require("aws-cdk-lib/aws-iam"); const ssm = require("aws-cdk-lib/aws-ssm"); const cr = require("aws-cdk-lib/custom-resources"); const change_case_1 = require("change-case"); const constructs_1 = require("constructs"); const add_1 = require("./errors/add"); var OnEvent; (function (OnEvent) { OnEvent["ON_CREATE"] = "onCreate"; OnEvent["ON_UPDATE"] = "onUpdate"; OnEvent["ON_DELETE"] = "onDelete"; })(OnEvent = exports.OnEvent || (exports.OnEvent = {})); /** Cross-Region SSM Parameter. */ class CrossRegionParameter extends constructs_1.Construct { /** * Define a new Cross-Region SSM Parameter. * * @example * new CrossRegionParameter(this, 'SayHiToSweden', { * region: 'eu-north-1', * name: '/parameter/path/message', * description: 'Some message for the Swedes', * value: 'Hej då!', * }); */ constructor(scope, name, props) { super(scope, name); this.validateRegion(props.region); const st = this.definePolicy(props); const policy = new iam.Policy(this, `${change_case_1.pascalCase(name)}CrPolicy`, { statements: [st] }); const role = new iam.Role(this, 'ParameterCrRole', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), }); role.attachInlinePolicy(policy); const customResource = new cr.AwsCustomResource(this, 'AwsCustomResource', { onCreate: this.defineCreateUpdateSdkCall(OnEvent.ON_CREATE, props), onUpdate: this.defineCreateUpdateSdkCall(OnEvent.ON_UPDATE, props), onDelete: this.defineDeleteSdkCall(props), policy: cr.AwsCustomResourcePolicy.fromStatements([st]), role, }); customResource.node.addDependency(role); } definePhysicalResourceId(props) { const { region, name } = props; return cr.PhysicalResourceId.of(`CrossRegionParameter${change_case_1.pascalCase(region)}${change_case_1.pascalCase(name)}`); } defineCreateUpdateSdkCall(eventType, props) { const { region, name, description, value, allowedPattern, keyId, parameterTier: tier = ssm.ParameterTier.STANDARD, parameterType: type = ssm.ParameterType.STRING, tags, policies, } = props; const parameters = { Name: name, Value: value, AllowedPattern: allowedPattern, Description: description, KeyId: keyId, Overwrite: eventType !== OnEvent.ON_CREATE, Policies: policies, Tags: this.tagPropsToTagParams(tags), Tier: tier, Type: type, }; return { physicalResourceId: this.definePhysicalResourceId(props), region, service: 'SSM', action: 'putParameter', parameters, }; } /** Ensure Parameter target region is not the same as the current "source" region. */ validateRegion(region) { const currentRegion = aws_cdk_lib_1.Stack.of(this).region; if (currentRegion === region) { add_1.addError(this, `Parameter target region ${region} can not be the same as source region ${currentRegion}`); } } /** Convert CDK/JSII compatible TagPropList to SDK compatible TagList. */ tagPropsToTagParams(tags) { return tags?.map(t => ({ Key: t.key, Value: t.value, })); } defineDeleteSdkCall(props) { const { region, name } = props; return { physicalResourceId: this.definePhysicalResourceId(props), region, service: 'SSM', action: 'deleteParameter', parameters: { Name: name, }, }; } definePolicy(props) { const { region, name } = props; // Depending if path paramater or simple parameter we may or may not need to set a slash separator to resource ARN const separator = name.indexOf('/') === 0 ? '' : '/'; return new iam.PolicyStatement({ actions: ['ssm:PutParameter', 'ssm:DeleteParameter'], resources: [`arn:aws:ssm:${region}:${aws_cdk_lib_1.Stack.of(this).account}:parameter${separator}${name}`], effect: iam.Effect.ALLOW, }); } } exports.CrossRegionParameter = CrossRegionParameter; _a = JSII_RTTI_SYMBOL_1; CrossRegionParameter[_a] = { fqn: "@alma-cdk/cross-region-parameter.CrossRegionParameter", version: "0.0.15" }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyYW1ldGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3BhcmFtZXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDZDQUFvQztBQUNwQywyQ0FBMkM7QUFDM0MsMkNBQTJDO0FBQzNDLG1EQUFtRDtBQUVuRCw2Q0FBeUM7QUFDekMsMkNBQXVDO0FBQ3ZDLHNDQUF3QztBQUd4QyxJQUFZLE9BSVg7QUFKRCxXQUFZLE9BQU87SUFDakIsaUNBQW9CLENBQUE7SUFDcEIsaUNBQW9CLENBQUE7SUFDcEIsaUNBQW9CLENBQUE7QUFDdEIsQ0FBQyxFQUpXLE9BQU8sR0FBUCxlQUFPLEtBQVAsZUFBTyxRQUlsQjtBQUVELGtDQUFrQztBQUNsQyxNQUFhLG9CQUFxQixTQUFRLHNCQUFTO0lBRWpEOzs7Ozs7Ozs7O09BVUc7SUFDSCxZQUFZLEtBQWdCLEVBQUUsSUFBWSxFQUFFLEtBQWdDO1FBQzFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFbkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFbEMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUVwQyxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLEdBQUcsd0JBQVUsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRXpGLE1BQU0sSUFBSSxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsaUJBQWlCLEVBQUU7WUFDakQsU0FBUyxFQUFFLElBQUksR0FBRyxDQUFDLGdCQUFnQixDQUFDLHNCQUFzQixDQUFDO1NBQzVELENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztR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LENBQUM7WUFDeEQsTUFBTTtZQUNOLE9BQU8sRUFBRSxLQUFLO1lBQ2QsTUFBTSxFQUFFLGlCQUFpQjtZQUN6QixVQUFVLEVBQUU7Z0JBQ1YsSUFBSSxFQUFFLElBQUk7YUFDWDtTQUNGLENBQUM7SUFDSixDQUFDO0lBRU8sWUFBWSxDQUFDLEtBQWdDO1FBQ25ELE1BQU0sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsS0FBSyxDQUFDO1FBRS9CLGtIQUFrSDtRQUNsSCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFFckQsT0FBTyxJQUFJLEdBQUcsQ0FBQyxlQUFlLENBQUM7WUFDN0IsT0FBTyxFQUFFLENBQUMsa0JBQWtCLEVBQUUscUJBQXFCLENBQUM7WUFDcEQsU0FBUyxFQUFFLENBQUMsZUFBZSxNQUFNLElBQUksbUJBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxhQUFhLFNBQVMsR0FBRyxJQUFJLEVBQUUsQ0FBQztZQUMzRixNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLO1NBQ3pCLENBQUMsQ0FBQztJQUNMLENBQUM7O0FBMUhILG9EQTJIQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0ICogYXMgc3NtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1zc20nO1xuaW1wb3J0ICogYXMgY3IgZnJvbSAnYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlcyc7XG5pbXBvcnQgeyBQdXRQYXJhbWV0ZXJSZXF1ZXN0LCBUYWdMaXN0IH0gZnJvbSAnYXdzLXNkay9jbGllbnRzL3NzbSc7XG5pbXBvcnQgeyBwYXNjYWxDYXNlIH0gZnJvbSAnY2hhbmdlLWNhc2UnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBhZGRFcnJvciB9IGZyb20gJy4vZXJyb3JzL2FkZCc7XG5pbXBvcnQgeyBDcm9zc1JlZ2lvblBhcmFtZXRlclByb3BzLCBUYWdQcm9wTGlzdCB9IGZyb20gJy4vcHJvcHMnO1xuXG5leHBvcnQgZW51bSBPbkV2ZW50IHtcbiAgT05fQ1JFQVRFPSdvbkNyZWF0ZScsXG4gIE9OX1VQREFURT0nb25VcGRhdGUnLFxuICBPTl9ERUxFVEU9J29uRGVsZXRlJyxcbn1cblxuLyoqIENyb3NzLVJlZ2lvbiBTU00gUGFyYW1ldGVyLiAqL1xuZXhwb3J0IGNsYXNzIENyb3NzUmVnaW9uUGFyYW1ldGVyIGV4dGVuZHMgQ29uc3RydWN0IHtcblxuICAvKipcbiAgICogRGVmaW5lIGEgbmV3IENyb3NzLVJlZ2lvbiBTU00gUGFyYW1ldGVyLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBuZXcgQ3Jvc3NSZWdpb25QYXJhbWV0ZXIodGhpcywgJ1NheUhpVG9Td2VkZW4nLCB7XG4gICAqICAgcmVnaW9uOiAnZXUtbm9ydGgtMScsXG4gICAqICAgbmFtZTogJy9wYXJhbWV0ZXIvcGF0aC9tZXNzYWdlJyxcbiAgICogICBkZXNjcmlwdGlvbjogJ1NvbWUgbWVzc2FnZSBmb3IgdGhlIFN3ZWRlcycsXG4gICAqICAgdmFsdWU6ICdIZWogZMOlIScsXG4gICAqIH0pO1xuICAgKi9cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgbmFtZTogc3RyaW5nLCBwcm9wczogQ3Jvc3NSZWdpb25QYXJhbWV0ZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBuYW1lKTtcblxuICAgIHRoaXMudmFsaWRhdGVSZWdpb24ocHJvcHMucmVnaW9uKTtcblxuICAgIGNvbnN0IHN0ID0gdGhpcy5kZWZpbmVQb2xpY3kocHJvcHMpO1xuXG4gICAgY29uc3QgcG9saWN5ID0gbmV3IGlhbS5Qb2xpY3kodGhpcywgYCR7cGFzY2FsQ2FzZShuYW1lKX1DclBvbGljeWAsIHsgc3RhdGVtZW50czogW3N0XSB9KTtcblxuICAgIGNvbnN0IHJvbGUgPSBuZXcgaWFtLlJvbGUodGhpcywgJ1BhcmFtZXRlckNyUm9sZScsIHtcbiAgICAgIGFzc3VtZWRCeTogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKCdsYW1iZGEuYW1hem9uYXdzLmNvbScpLFxuICAgIH0pO1xuXG4gICAgcm9sZS5hdHRhY2hJbmxpbmVQb2xpY3kocG9saWN5KTtcblxuICAgIGNvbnN0IGN1c3RvbVJlc291cmNlID0gbmV3IGNyLkF3c0N1c3RvbVJlc291cmNlKHRoaXMsICdBd3NDdXN0b21SZXNvdXJjZScsIHtcbiAgICAgIG9uQ3JlYXRlOiB0aGlzLmRlZmluZUNyZWF0ZVVwZGF0ZVNka0NhbGwoT25FdmVudC5PTl9DUkVBVEUsIHByb3BzKSxcbiAgICAgIG9uVXBkYXRlOiB0aGlzLmRlZmluZUNyZWF0ZVVwZGF0ZVNka0NhbGwoT25FdmVudC5PTl9VUERBVEUsIHByb3BzKSxcbiAgICAgIG9uRGVsZXRlOiB0aGlzLmRlZmluZURlbGV0ZVNka0NhbGwocHJvcHMpLFxuICAgICAgcG9saWN5OiBjci5Bd3NDdXN0b21SZXNvdXJjZVBvbGljeS5mcm9tU3RhdGVtZW50cyhbc3RdKSxcbiAgICAgIHJvbGUsXG4gICAgfSk7XG5cbiAgICBjdXN0b21SZXNvdXJjZS5ub2RlLmFkZERlcGVuZGVuY3kocm9sZSk7XG4gIH1cblxuICBwcml2YXRlIGRlZmluZVBoeXNpY2FsUmVzb3VyY2VJZChwcm9wczogQ3Jvc3NSZWdpb25QYXJhbWV0ZXJQcm9wcyk6IGNyLlBoeXNpY2FsUmVzb3VyY2VJZCB7XG4gICAgY29uc3QgeyByZWdpb24sIG5hbWUgfSA9IHByb3BzO1xuICAgIHJldHVybiBjci5QaHlzaWNhbFJlc291cmNlSWQub2YoYENyb3NzUmVnaW9uUGFyYW1ldGVyJHtwYXNjYWxDYXNlKHJlZ2lvbil9JHtwYXNjYWxDYXNlKG5hbWUpfWApO1xuICB9XG5cbiAgcHJpdmF0ZSBkZWZpbmVDcmVhdGVVcGRhdGVTZGtDYWxsKGV2ZW50VHlwZTogT25FdmVudCwgcHJvcHM6IENyb3NzUmVnaW9uUGFyYW1ldGVyUHJvcHMpOiBjci5Bd3NTZGtDYWxsIHtcbiAgICBjb25zdCB7XG4gICAgICByZWdpb24sXG4gICAgICBuYW1lLFxuICAgICAgZGVzY3JpcHRpb24sXG4gICAgICB2YWx1ZSxcbiAgICAgIGFsbG93ZWRQYXR0ZXJuLFxuICAgICAga2V5SWQsXG4gICAgICBwYXJhbWV0ZXJUaWVyOiB0aWVyID0gc3NtLlBhcmFtZXRlclRpZXIuU1RBTkRBUkQsXG4gICAgICBwYXJhbWV0ZXJUeXBlOiB0eXBlID0gc3NtLlBhcmFtZXRlclR5cGUuU1RSSU5HLFxuICAgICAgdGFncyxcbiAgICAgIHBvbGljaWVzLFxuICAgIH0gPSBwcm9wcztcblxuICAgIGNvbnN0IHBhcmFtZXRlcnM6IFB1dFBhcmFtZXRlclJlcXVlc3QgPSB7XG4gICAgICBOYW1lOiBuYW1lLCAvKiByZXF1aXJlZCAqL1xuICAgICAgVmFsdWU6IHZhbHVlLCAvKiByZXF1aXJlZCAqL1xuICAgICAgQWxsb3dlZFBhdHRlcm46IGFsbG93ZWRQYXR0ZXJuLFxuICAgICAgRGVzY3JpcHRpb246IGRlc2NyaXB0aW9uLFxuICAgICAgS2V5SWQ6IGtleUlkLFxuICAgICAgT3ZlcndyaXRlOiBldmVudFR5cGUgIT09IE9uRXZlbnQuT05fQ1JFQVRFLFxuICAgICAgUG9saWNpZXM6IHBvbGljaWVzLFxuICAgICAgVGFnczogdGhpcy50YWdQcm9wc1RvVGFnUGFyYW1zKHRhZ3MpLFxuICAgICAgVGllcjogdGllcixcbiAgICAgIFR5cGU6IHR5cGUsXG4gICAgfTtcblxuICAgIHJldHVybiB7XG4gICAgICBwaHlzaWNhbFJlc291cmNlSWQ6IHRoaXMuZGVmaW5lUGh5c2ljYWxSZXNvdXJjZUlkKHByb3BzKSxcbiAgICAgIHJlZ2lvbixcbiAgICAgIHNlcnZpY2U6ICdTU00nLFxuICAgICAgYWN0aW9uOiAncHV0UGFyYW1ldGVyJyxcbiAgICAgIHBhcmFtZXRlcnMsXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBFbnN1cmUgUGFyYW1ldGVyIHRhcmdldCByZWdpb24gaXMgbm90IHRoZSBzYW1lIGFzIHRoZSBjdXJyZW50IFwic291cmNlXCIgcmVnaW9uLiAqL1xuICBwcml2YXRlIHZhbGlkYXRlUmVnaW9uKHJlZ2lvbjogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudFJlZ2lvbiA9IFN0YWNrLm9mKHRoaXMpLnJlZ2lvbjtcbiAgICBpZiAoY3VycmVudFJlZ2lvbiA9PT0gcmVnaW9uKSB7XG4gICAgICBhZGRFcnJvcih0aGlzLCBgUGFyYW1ldGVyIHRhcmdldCByZWdpb24gJHtyZWdpb259IGNhbiBub3QgYmUgdGhlIHNhbWUgYXMgc291cmNlIHJlZ2lvbiAke2N1cnJlbnRSZWdpb259YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIENvbnZlcnQgQ0RLL0pTSUkgY29tcGF0aWJsZSBUYWdQcm9wTGlzdCB0byBTREsgY29tcGF0aWJsZSBUYWdMaXN0LiAqL1xuICBwcml2YXRlIHRhZ1Byb3BzVG9UYWdQYXJhbXModGFncz86IFRhZ1Byb3BMaXN0KTogVGFnTGlzdCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRhZ3M/Lm1hcCh0ID0+ICh7XG4gICAgICBLZXk6IHQua2V5LFxuICAgICAgVmFsdWU6IHQudmFsdWUsXG4gICAgfSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBkZWZpbmVEZWxldGVTZGtDYWxsKHByb3BzOiBDcm9zc1JlZ2lvblBhcmFtZXRlclByb3BzKTogY3IuQXdzU2RrQ2FsbCB7XG5cbiAgICBjb25zdCB7IHJlZ2lvbiwgbmFtZSB9ID0gcHJvcHM7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcGh5c2ljYWxSZXNvdXJjZUlkOiB0aGlzLmRlZmluZVBoeXNpY2FsUmVzb3VyY2VJZChwcm9wcyksXG4gICAgICByZWdpb24sXG4gICAgICBzZXJ2aWNlOiAnU1NNJyxcbiAgICAgIGFjdGlvbjogJ2RlbGV0ZVBhcmFtZXRlcicsXG4gICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgIE5hbWU6IG5hbWUsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGRlZmluZVBvbGljeShwcm9wczogQ3Jvc3NSZWdpb25QYXJhbWV0ZXJQcm9wcyk6IGlhbS5Qb2xpY3lTdGF0ZW1lbnQge1xuICAgIGNvbnN0IHsgcmVnaW9uLCBuYW1lIH0gPSBwcm9wcztcblxuICAgIC8vIERlcGVuZGluZyBpZiBwYXRoIHBhcmFtYXRlciBvciBzaW1wbGUgcGFyYW1ldGVyIHdlIG1heSBvciBtYXkgbm90IG5lZWQgdG8gc2V0IGEgc2xhc2ggc2VwYXJhdG9yIHRvIHJlc291cmNlIEFSTlxuICAgIGNvbnN0IHNlcGFyYXRvciA9IG5hbWUuaW5kZXhPZignLycpID09PSAwID8gJycgOiAnLyc7XG5cbiAgICByZXR1cm4gbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgYWN0aW9uczogWydzc206UHV0UGFyYW1ldGVyJywgJ3NzbTpEZWxldGVQYXJhbWV0ZXInXSxcbiAgICAgIHJlc291cmNlczogW2Bhcm46YXdzOnNzbToke3JlZ2lvbn06JHtTdGFjay5vZih0aGlzKS5hY2NvdW50fTpwYXJhbWV0ZXIke3NlcGFyYXRvcn0ke25hbWV9YF0sXG4gICAgICBlZmZlY3Q6IGlhbS5FZmZlY3QuQUxMT1csXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==