diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | python-cdk-remote-stack.spec | 824 | ||||
| -rw-r--r-- | sources | 1 |
3 files changed, 826 insertions, 0 deletions
@@ -0,0 +1 @@ +/cdk-remote-stack-2.0.10.tar.gz diff --git a/python-cdk-remote-stack.spec b/python-cdk-remote-stack.spec new file mode 100644 index 0000000..6ccd1d7 --- /dev/null +++ b/python-cdk-remote-stack.spec @@ -0,0 +1,824 @@ +%global _empty_manifest_terminate_build 0 +Name: python-cdk-remote-stack +Version: 2.0.10 +Release: 1 +Summary: Get outputs and AWS SSM parameters from cross-region AWS CloudFormation stacks +License: Apache-2.0 +URL: https://github.com/pahud/cdk-remote-stack.git +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/87/36/1971120375705d0f47ab75d3db35070436420fa26e06ec57b2b372cdd9cf/cdk-remote-stack-2.0.10.tar.gz +BuildArch: noarch + +Requires: python3-aws-cdk-lib +Requires: python3-constructs +Requires: python3-jsii +Requires: python3-publication +Requires: python3-typeguard + +%description +[](https://badge.fury.io/js/cdk-remote-stack) +[](https://badge.fury.io/py/cdk-remote-stack) +[](https://github.com/pahud/cdk-remote-stack/actions/workflows/release.yml) + +# cdk-remote-stack + +Get outputs and AWS SSM parameters from cross-region AWS CloudFormation stacks + +# Install + +Use the npm dist tag to opt in CDKv1 or CDKv2: + +```sh +// for CDKv2 +npm install cdk-remote-stack +or +npm install cdk-remote-stack@latest + +// for CDKv1 +npm install cdk-remote-stack@cdkv1 +``` + +# Why + +Setting up cross-regional cross-stack references requires using multiple constructs from the AWS CDK construct library and is not straightforward. + +`cdk-remote-stack` aims to simplify the cross-regional cross-stack references to help you easily build cross-regional multi-stack AWS CDK applications. + +This construct library provides two main constructs: + +* **RemoteOutputs** - cross regional stack outputs reference. +* **RemoteParameters** - cross regional/account SSM parameters reference. + +# RemoteOutputs + +`RemoteOutputs` is ideal for one stack referencing the outputs from another across different AWS regions. + +Let's say we have two cross-regional stacks in the same AWS CDK application: + +1. **stackJP** - stack in Japan (`JP`) to create a SNS topic +2. **stackUS** - stack in United States (`US`) to get the outputs from `stackJP` and print out the SNS `TopicName` from `stackJP` outputs. + +```python +import { RemoteOutputs } from 'cdk-remote-stack'; +import * as cdk from 'aws-cdk-lib'; + +const app = new cdk.App(); + +const envJP = { + region: 'ap-northeast-1', + account: process.env.CDK_DEFAULT_ACCOUNT, +}; + +const envUS = { + region: 'us-west-2', + account: process.env.CDK_DEFAULT_ACCOUNT, +}; + +// first stack in JP +const stackJP = new cdk.Stack(app, 'demo-stack-jp', { env: envJP }) + +new cdk.CfnOutput(stackJP, 'TopicName', { value: 'foo' }) + +// second stack in US +const stackUS = new cdk.Stack(app, 'demo-stack-us', { env: envUS }) + +// ensure the dependency +stackUS.addDependency(stackJP) + +// get the stackJP stack outputs from stackUS +const outputs = new RemoteOutputs(stackUS, 'Outputs', { stack: stackJP }) + +const remoteOutputValue = outputs.get('TopicName') + +// the value should be exactly the same with the output value of `TopicName` +new cdk.CfnOutput(stackUS, 'RemoteTopicName', { value: remoteOutputValue }) +``` + +At this moment, `RemoteOutputs` only supports cross-regional reference in a single AWS account. + +## Always get the latest stack output + +By default, the `RemoteOutputs` construct will always try to get the latest output from the source stack. You may opt out by setting `alwaysUpdate` to `false` to turn this feature off. + +For example: + +```python +const outputs = new RemoteOutputs(stackUS, 'Outputs', { + stack: stackJP, + alwaysUpdate: false, +}) +``` + +# RemoteParameters + +[AWS Systems Manager (AWS SSM) Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html) is great to store and persist parameters and allow stacks from other regons/accounts to reference. Let's dive into the two major scenarios below: + +## Stacks from single account and different regions + +In this sample, we create two stacks from JP (`ap-northeast-1`) and US (`us-west-2`). The JP stack will produce and update parameters in its parameter store, while the US stack will consume the parameters across differnt regions with the `RemoteParameters` construct. + + + +```python + const envJP = { region: 'ap-northeast-1', account: '111111111111' }; + const envUS = { region: 'us-west-2', account: '111111111111' }; + + // first stack in JP + const producerStackName = 'demo-stack-jp'; + const stackJP = new cdk.Stack(app, producerStackName, { env: envJP }); + const parameterPath = `/${envJP.account}/${envJP.region}/${producerStackName}` + + new ssm.StringParameter(stackJP, 'foo1', { + parameterName: `${parameterPath}/foo1`, + stringValue: 'bar1', + }); + new ssm.StringParameter(stackJP, 'foo2', { + parameterName: `${parameterPath}/foo2`, + stringValue: 'bar2', + }); + new ssm.StringParameter(stackJP, 'foo3', { + parameterName: `${parameterPath}/foo3`, + stringValue: 'bar3', + }); + + // second stack in US + const stackUS = new cdk.Stack(app, 'demo-stack-us', { env: envUS }); + + // ensure the dependency + stackUS.addDependency(stackJP); + + // get remote parameters by path from AWS SSM parameter store + const parameters = new RemoteParameters(stackUS, 'Parameters', { + path: parameterPath, + region: stackJP.region, + }) + + const foo1 = parameters.get(`${parameterPath}/foo1`); + const foo2 = parameters.get(`${parameterPath}/foo2`); + const foo3 = parameters.get(`${parameterPath}/foo3`); + + new cdk.CfnOutput(stackUS, 'foo1Output', { value: foo1 }); + new cdk.CfnOutput(stackUS, 'foo2Output', { value: foo2 }); + new cdk.CfnOutput(stackUS, 'foo3Output', { value: foo3 }); +``` + +## Stacks from differnt accounts and different regions + +Similar to the use case above, but now we deploy stacks in separate accounts and regions. We will need to pass an AWS Identity and Access Management (AWS IAM) `role` to the `RemoteParameters` construct to get all the parameters from the remote environment. + + + +```python + + const envJP = { region: 'ap-northeast-1', account: '111111111111' }; + const envUS = { region: 'us-west-2', account: '222222222222' }; + + // first stack in JP + const producerStackName = 'demo-stack-jp'; + const stackJP = new cdk.Stack(app, producerStackName, { env: envJP }); + const parameterPath = `/${envJP.account}/${envJP.region}/${producerStackName}` + + new ssm.StringParameter(stackJP, 'foo1', { + parameterName: `${parameterPath}/foo1`, + stringValue: 'bar1', + }); + new ssm.StringParameter(stackJP, 'foo2', { + parameterName: `${parameterPath}/foo2`, + stringValue: 'bar2', + }); + new ssm.StringParameter(stackJP, 'foo3', { + parameterName: `${parameterPath}/foo3`, + stringValue: 'bar3', + }); + + // allow US account to assume this read only role to get parameters + const cdkReadOnlyRole = new iam.Role(stackJP, 'readOnlyRole', { + assumedBy: new iam.AccountPrincipal(envUS.account), + roleName: PhysicalName.GENERATE_IF_NEEDED, + managedPolicies: [ iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMReadOnlyAccess')], + }) + + // second stack in US + const stackUS = new cdk.Stack(app, 'demo-stack-us', { env: envUS }); + + // ensure the dependency + stackUS.addDependency(stackJP); + + // get remote parameters by path from AWS SSM parameter store + const parameters = new RemoteParameters(stackUS, 'Parameters', { + path: parameterPath, + region: stackJP.region, + // assume this role for cross-account parameters + role: iam.Role.fromRoleArn(stackUS, 'readOnlyRole', cdkReadOnlyRole.roleArn), + }) + + const foo1 = parameters.get(`${parameterPath}/foo1`); + const foo2 = parameters.get(`${parameterPath}/foo2`); + const foo3 = parameters.get(`${parameterPath}/foo3`); + + new cdk.CfnOutput(stackUS, 'foo1Output', { value: foo1 }); + new cdk.CfnOutput(stackUS, 'foo2Output', { value: foo2 }); + new cdk.CfnOutput(stackUS, 'foo3Output', { value: foo3 }); +``` + +## Dedicated account for a centralized parameter store + +The parameters are stored in a centralized account/region and previously provisioned as a source-of-truth configuration store. All other stacks from different accounts/regions are consuming the parameters from the central configuration store. + +This scenario is pretty much like #2. The difference is that there's a dedicated account for centralized configuration store being shared with all other accounts. + + + +You will need create `RemoteParameters` for all the consuming stacks like: + +```python +// for StackUS +new RemoteParameters(stackUS, 'Parameters', { + path: parameterPath, + region: 'eu-central-1' + // assume this role for cross-account parameters + role: iam.Role.fromRoleArn(stackUS, 'readOnlyRole', sharedReadOnlyRoleArn), +}) + +// for StackJP +new RemoteParameters(stackJP, 'Parameters', { + path: parameterPath, + region: 'eu-central-1' + // assume this role for cross-account parameters + role: iam.Role.fromRoleArn(stackJP, 'readOnlyRole', sharedReadOnlyRoleArn), +}) +``` + +## Tools for multi-account deployment + +You will need to install and bootstrap your target accounts with AWS CDK 1.108.0 or later, so you can deploy stacks from different accounts. It [adds support](https://github.com/aws/aws-cdk/pull/14874) for cross-account lookups. Alternatively, install [cdk-assume-role-credential-plugin](https://github.com/aws-samples/cdk-assume-role-credential-plugin). Read this [blog post](https://aws.amazon.com/tw/blogs/devops/cdk-credential-plugin/) to setup this plugin. + +## Limitations + +1. At this moment, the `RemoteParameters` construct only supports the `String` data type from parameter store. +2. Maximum number of parameters is `100`. Will make it configurable in the future if required. + +# Contributing + +See [CONTRIBUTING](CONTRIBUTING.md) for more information. + +# License + +This code is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file. + + +%package -n python3-cdk-remote-stack +Summary: Get outputs and AWS SSM parameters from cross-region AWS CloudFormation stacks +Provides: python-cdk-remote-stack +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-cdk-remote-stack +[](https://badge.fury.io/js/cdk-remote-stack) +[](https://badge.fury.io/py/cdk-remote-stack) +[](https://github.com/pahud/cdk-remote-stack/actions/workflows/release.yml) + +# cdk-remote-stack + +Get outputs and AWS SSM parameters from cross-region AWS CloudFormation stacks + +# Install + +Use the npm dist tag to opt in CDKv1 or CDKv2: + +```sh +// for CDKv2 +npm install cdk-remote-stack +or +npm install cdk-remote-stack@latest + +// for CDKv1 +npm install cdk-remote-stack@cdkv1 +``` + +# Why + +Setting up cross-regional cross-stack references requires using multiple constructs from the AWS CDK construct library and is not straightforward. + +`cdk-remote-stack` aims to simplify the cross-regional cross-stack references to help you easily build cross-regional multi-stack AWS CDK applications. + +This construct library provides two main constructs: + +* **RemoteOutputs** - cross regional stack outputs reference. +* **RemoteParameters** - cross regional/account SSM parameters reference. + +# RemoteOutputs + +`RemoteOutputs` is ideal for one stack referencing the outputs from another across different AWS regions. + +Let's say we have two cross-regional stacks in the same AWS CDK application: + +1. **stackJP** - stack in Japan (`JP`) to create a SNS topic +2. **stackUS** - stack in United States (`US`) to get the outputs from `stackJP` and print out the SNS `TopicName` from `stackJP` outputs. + +```python +import { RemoteOutputs } from 'cdk-remote-stack'; +import * as cdk from 'aws-cdk-lib'; + +const app = new cdk.App(); + +const envJP = { + region: 'ap-northeast-1', + account: process.env.CDK_DEFAULT_ACCOUNT, +}; + +const envUS = { + region: 'us-west-2', + account: process.env.CDK_DEFAULT_ACCOUNT, +}; + +// first stack in JP +const stackJP = new cdk.Stack(app, 'demo-stack-jp', { env: envJP }) + +new cdk.CfnOutput(stackJP, 'TopicName', { value: 'foo' }) + +// second stack in US +const stackUS = new cdk.Stack(app, 'demo-stack-us', { env: envUS }) + +// ensure the dependency +stackUS.addDependency(stackJP) + +// get the stackJP stack outputs from stackUS +const outputs = new RemoteOutputs(stackUS, 'Outputs', { stack: stackJP }) + +const remoteOutputValue = outputs.get('TopicName') + +// the value should be exactly the same with the output value of `TopicName` +new cdk.CfnOutput(stackUS, 'RemoteTopicName', { value: remoteOutputValue }) +``` + +At this moment, `RemoteOutputs` only supports cross-regional reference in a single AWS account. + +## Always get the latest stack output + +By default, the `RemoteOutputs` construct will always try to get the latest output from the source stack. You may opt out by setting `alwaysUpdate` to `false` to turn this feature off. + +For example: + +```python +const outputs = new RemoteOutputs(stackUS, 'Outputs', { + stack: stackJP, + alwaysUpdate: false, +}) +``` + +# RemoteParameters + +[AWS Systems Manager (AWS SSM) Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html) is great to store and persist parameters and allow stacks from other regons/accounts to reference. Let's dive into the two major scenarios below: + +## Stacks from single account and different regions + +In this sample, we create two stacks from JP (`ap-northeast-1`) and US (`us-west-2`). The JP stack will produce and update parameters in its parameter store, while the US stack will consume the parameters across differnt regions with the `RemoteParameters` construct. + + + +```python + const envJP = { region: 'ap-northeast-1', account: '111111111111' }; + const envUS = { region: 'us-west-2', account: '111111111111' }; + + // first stack in JP + const producerStackName = 'demo-stack-jp'; + const stackJP = new cdk.Stack(app, producerStackName, { env: envJP }); + const parameterPath = `/${envJP.account}/${envJP.region}/${producerStackName}` + + new ssm.StringParameter(stackJP, 'foo1', { + parameterName: `${parameterPath}/foo1`, + stringValue: 'bar1', + }); + new ssm.StringParameter(stackJP, 'foo2', { + parameterName: `${parameterPath}/foo2`, + stringValue: 'bar2', + }); + new ssm.StringParameter(stackJP, 'foo3', { + parameterName: `${parameterPath}/foo3`, + stringValue: 'bar3', + }); + + // second stack in US + const stackUS = new cdk.Stack(app, 'demo-stack-us', { env: envUS }); + + // ensure the dependency + stackUS.addDependency(stackJP); + + // get remote parameters by path from AWS SSM parameter store + const parameters = new RemoteParameters(stackUS, 'Parameters', { + path: parameterPath, + region: stackJP.region, + }) + + const foo1 = parameters.get(`${parameterPath}/foo1`); + const foo2 = parameters.get(`${parameterPath}/foo2`); + const foo3 = parameters.get(`${parameterPath}/foo3`); + + new cdk.CfnOutput(stackUS, 'foo1Output', { value: foo1 }); + new cdk.CfnOutput(stackUS, 'foo2Output', { value: foo2 }); + new cdk.CfnOutput(stackUS, 'foo3Output', { value: foo3 }); +``` + +## Stacks from differnt accounts and different regions + +Similar to the use case above, but now we deploy stacks in separate accounts and regions. We will need to pass an AWS Identity and Access Management (AWS IAM) `role` to the `RemoteParameters` construct to get all the parameters from the remote environment. + + + +```python + + const envJP = { region: 'ap-northeast-1', account: '111111111111' }; + const envUS = { region: 'us-west-2', account: '222222222222' }; + + // first stack in JP + const producerStackName = 'demo-stack-jp'; + const stackJP = new cdk.Stack(app, producerStackName, { env: envJP }); + const parameterPath = `/${envJP.account}/${envJP.region}/${producerStackName}` + + new ssm.StringParameter(stackJP, 'foo1', { + parameterName: `${parameterPath}/foo1`, + stringValue: 'bar1', + }); + new ssm.StringParameter(stackJP, 'foo2', { + parameterName: `${parameterPath}/foo2`, + stringValue: 'bar2', + }); + new ssm.StringParameter(stackJP, 'foo3', { + parameterName: `${parameterPath}/foo3`, + stringValue: 'bar3', + }); + + // allow US account to assume this read only role to get parameters + const cdkReadOnlyRole = new iam.Role(stackJP, 'readOnlyRole', { + assumedBy: new iam.AccountPrincipal(envUS.account), + roleName: PhysicalName.GENERATE_IF_NEEDED, + managedPolicies: [ iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMReadOnlyAccess')], + }) + + // second stack in US + const stackUS = new cdk.Stack(app, 'demo-stack-us', { env: envUS }); + + // ensure the dependency + stackUS.addDependency(stackJP); + + // get remote parameters by path from AWS SSM parameter store + const parameters = new RemoteParameters(stackUS, 'Parameters', { + path: parameterPath, + region: stackJP.region, + // assume this role for cross-account parameters + role: iam.Role.fromRoleArn(stackUS, 'readOnlyRole', cdkReadOnlyRole.roleArn), + }) + + const foo1 = parameters.get(`${parameterPath}/foo1`); + const foo2 = parameters.get(`${parameterPath}/foo2`); + const foo3 = parameters.get(`${parameterPath}/foo3`); + + new cdk.CfnOutput(stackUS, 'foo1Output', { value: foo1 }); + new cdk.CfnOutput(stackUS, 'foo2Output', { value: foo2 }); + new cdk.CfnOutput(stackUS, 'foo3Output', { value: foo3 }); +``` + +## Dedicated account for a centralized parameter store + +The parameters are stored in a centralized account/region and previously provisioned as a source-of-truth configuration store. All other stacks from different accounts/regions are consuming the parameters from the central configuration store. + +This scenario is pretty much like #2. The difference is that there's a dedicated account for centralized configuration store being shared with all other accounts. + + + +You will need create `RemoteParameters` for all the consuming stacks like: + +```python +// for StackUS +new RemoteParameters(stackUS, 'Parameters', { + path: parameterPath, + region: 'eu-central-1' + // assume this role for cross-account parameters + role: iam.Role.fromRoleArn(stackUS, 'readOnlyRole', sharedReadOnlyRoleArn), +}) + +// for StackJP +new RemoteParameters(stackJP, 'Parameters', { + path: parameterPath, + region: 'eu-central-1' + // assume this role for cross-account parameters + role: iam.Role.fromRoleArn(stackJP, 'readOnlyRole', sharedReadOnlyRoleArn), +}) +``` + +## Tools for multi-account deployment + +You will need to install and bootstrap your target accounts with AWS CDK 1.108.0 or later, so you can deploy stacks from different accounts. It [adds support](https://github.com/aws/aws-cdk/pull/14874) for cross-account lookups. Alternatively, install [cdk-assume-role-credential-plugin](https://github.com/aws-samples/cdk-assume-role-credential-plugin). Read this [blog post](https://aws.amazon.com/tw/blogs/devops/cdk-credential-plugin/) to setup this plugin. + +## Limitations + +1. At this moment, the `RemoteParameters` construct only supports the `String` data type from parameter store. +2. Maximum number of parameters is `100`. Will make it configurable in the future if required. + +# Contributing + +See [CONTRIBUTING](CONTRIBUTING.md) for more information. + +# License + +This code is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file. + + +%package help +Summary: Development documents and examples for cdk-remote-stack +Provides: python3-cdk-remote-stack-doc +%description help +[](https://badge.fury.io/js/cdk-remote-stack) +[](https://badge.fury.io/py/cdk-remote-stack) +[](https://github.com/pahud/cdk-remote-stack/actions/workflows/release.yml) + +# cdk-remote-stack + +Get outputs and AWS SSM parameters from cross-region AWS CloudFormation stacks + +# Install + +Use the npm dist tag to opt in CDKv1 or CDKv2: + +```sh +// for CDKv2 +npm install cdk-remote-stack +or +npm install cdk-remote-stack@latest + +// for CDKv1 +npm install cdk-remote-stack@cdkv1 +``` + +# Why + +Setting up cross-regional cross-stack references requires using multiple constructs from the AWS CDK construct library and is not straightforward. + +`cdk-remote-stack` aims to simplify the cross-regional cross-stack references to help you easily build cross-regional multi-stack AWS CDK applications. + +This construct library provides two main constructs: + +* **RemoteOutputs** - cross regional stack outputs reference. +* **RemoteParameters** - cross regional/account SSM parameters reference. + +# RemoteOutputs + +`RemoteOutputs` is ideal for one stack referencing the outputs from another across different AWS regions. + +Let's say we have two cross-regional stacks in the same AWS CDK application: + +1. **stackJP** - stack in Japan (`JP`) to create a SNS topic +2. **stackUS** - stack in United States (`US`) to get the outputs from `stackJP` and print out the SNS `TopicName` from `stackJP` outputs. + +```python +import { RemoteOutputs } from 'cdk-remote-stack'; +import * as cdk from 'aws-cdk-lib'; + +const app = new cdk.App(); + +const envJP = { + region: 'ap-northeast-1', + account: process.env.CDK_DEFAULT_ACCOUNT, +}; + +const envUS = { + region: 'us-west-2', + account: process.env.CDK_DEFAULT_ACCOUNT, +}; + +// first stack in JP +const stackJP = new cdk.Stack(app, 'demo-stack-jp', { env: envJP }) + +new cdk.CfnOutput(stackJP, 'TopicName', { value: 'foo' }) + +// second stack in US +const stackUS = new cdk.Stack(app, 'demo-stack-us', { env: envUS }) + +// ensure the dependency +stackUS.addDependency(stackJP) + +// get the stackJP stack outputs from stackUS +const outputs = new RemoteOutputs(stackUS, 'Outputs', { stack: stackJP }) + +const remoteOutputValue = outputs.get('TopicName') + +// the value should be exactly the same with the output value of `TopicName` +new cdk.CfnOutput(stackUS, 'RemoteTopicName', { value: remoteOutputValue }) +``` + +At this moment, `RemoteOutputs` only supports cross-regional reference in a single AWS account. + +## Always get the latest stack output + +By default, the `RemoteOutputs` construct will always try to get the latest output from the source stack. You may opt out by setting `alwaysUpdate` to `false` to turn this feature off. + +For example: + +```python +const outputs = new RemoteOutputs(stackUS, 'Outputs', { + stack: stackJP, + alwaysUpdate: false, +}) +``` + +# RemoteParameters + +[AWS Systems Manager (AWS SSM) Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html) is great to store and persist parameters and allow stacks from other regons/accounts to reference. Let's dive into the two major scenarios below: + +## Stacks from single account and different regions + +In this sample, we create two stacks from JP (`ap-northeast-1`) and US (`us-west-2`). The JP stack will produce and update parameters in its parameter store, while the US stack will consume the parameters across differnt regions with the `RemoteParameters` construct. + + + +```python + const envJP = { region: 'ap-northeast-1', account: '111111111111' }; + const envUS = { region: 'us-west-2', account: '111111111111' }; + + // first stack in JP + const producerStackName = 'demo-stack-jp'; + const stackJP = new cdk.Stack(app, producerStackName, { env: envJP }); + const parameterPath = `/${envJP.account}/${envJP.region}/${producerStackName}` + + new ssm.StringParameter(stackJP, 'foo1', { + parameterName: `${parameterPath}/foo1`, + stringValue: 'bar1', + }); + new ssm.StringParameter(stackJP, 'foo2', { + parameterName: `${parameterPath}/foo2`, + stringValue: 'bar2', + }); + new ssm.StringParameter(stackJP, 'foo3', { + parameterName: `${parameterPath}/foo3`, + stringValue: 'bar3', + }); + + // second stack in US + const stackUS = new cdk.Stack(app, 'demo-stack-us', { env: envUS }); + + // ensure the dependency + stackUS.addDependency(stackJP); + + // get remote parameters by path from AWS SSM parameter store + const parameters = new RemoteParameters(stackUS, 'Parameters', { + path: parameterPath, + region: stackJP.region, + }) + + const foo1 = parameters.get(`${parameterPath}/foo1`); + const foo2 = parameters.get(`${parameterPath}/foo2`); + const foo3 = parameters.get(`${parameterPath}/foo3`); + + new cdk.CfnOutput(stackUS, 'foo1Output', { value: foo1 }); + new cdk.CfnOutput(stackUS, 'foo2Output', { value: foo2 }); + new cdk.CfnOutput(stackUS, 'foo3Output', { value: foo3 }); +``` + +## Stacks from differnt accounts and different regions + +Similar to the use case above, but now we deploy stacks in separate accounts and regions. We will need to pass an AWS Identity and Access Management (AWS IAM) `role` to the `RemoteParameters` construct to get all the parameters from the remote environment. + + + +```python + + const envJP = { region: 'ap-northeast-1', account: '111111111111' }; + const envUS = { region: 'us-west-2', account: '222222222222' }; + + // first stack in JP + const producerStackName = 'demo-stack-jp'; + const stackJP = new cdk.Stack(app, producerStackName, { env: envJP }); + const parameterPath = `/${envJP.account}/${envJP.region}/${producerStackName}` + + new ssm.StringParameter(stackJP, 'foo1', { + parameterName: `${parameterPath}/foo1`, + stringValue: 'bar1', + }); + new ssm.StringParameter(stackJP, 'foo2', { + parameterName: `${parameterPath}/foo2`, + stringValue: 'bar2', + }); + new ssm.StringParameter(stackJP, 'foo3', { + parameterName: `${parameterPath}/foo3`, + stringValue: 'bar3', + }); + + // allow US account to assume this read only role to get parameters + const cdkReadOnlyRole = new iam.Role(stackJP, 'readOnlyRole', { + assumedBy: new iam.AccountPrincipal(envUS.account), + roleName: PhysicalName.GENERATE_IF_NEEDED, + managedPolicies: [ iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMReadOnlyAccess')], + }) + + // second stack in US + const stackUS = new cdk.Stack(app, 'demo-stack-us', { env: envUS }); + + // ensure the dependency + stackUS.addDependency(stackJP); + + // get remote parameters by path from AWS SSM parameter store + const parameters = new RemoteParameters(stackUS, 'Parameters', { + path: parameterPath, + region: stackJP.region, + // assume this role for cross-account parameters + role: iam.Role.fromRoleArn(stackUS, 'readOnlyRole', cdkReadOnlyRole.roleArn), + }) + + const foo1 = parameters.get(`${parameterPath}/foo1`); + const foo2 = parameters.get(`${parameterPath}/foo2`); + const foo3 = parameters.get(`${parameterPath}/foo3`); + + new cdk.CfnOutput(stackUS, 'foo1Output', { value: foo1 }); + new cdk.CfnOutput(stackUS, 'foo2Output', { value: foo2 }); + new cdk.CfnOutput(stackUS, 'foo3Output', { value: foo3 }); +``` + +## Dedicated account for a centralized parameter store + +The parameters are stored in a centralized account/region and previously provisioned as a source-of-truth configuration store. All other stacks from different accounts/regions are consuming the parameters from the central configuration store. + +This scenario is pretty much like #2. The difference is that there's a dedicated account for centralized configuration store being shared with all other accounts. + + + +You will need create `RemoteParameters` for all the consuming stacks like: + +```python +// for StackUS +new RemoteParameters(stackUS, 'Parameters', { + path: parameterPath, + region: 'eu-central-1' + // assume this role for cross-account parameters + role: iam.Role.fromRoleArn(stackUS, 'readOnlyRole', sharedReadOnlyRoleArn), +}) + +// for StackJP +new RemoteParameters(stackJP, 'Parameters', { + path: parameterPath, + region: 'eu-central-1' + // assume this role for cross-account parameters + role: iam.Role.fromRoleArn(stackJP, 'readOnlyRole', sharedReadOnlyRoleArn), +}) +``` + +## Tools for multi-account deployment + +You will need to install and bootstrap your target accounts with AWS CDK 1.108.0 or later, so you can deploy stacks from different accounts. It [adds support](https://github.com/aws/aws-cdk/pull/14874) for cross-account lookups. Alternatively, install [cdk-assume-role-credential-plugin](https://github.com/aws-samples/cdk-assume-role-credential-plugin). Read this [blog post](https://aws.amazon.com/tw/blogs/devops/cdk-credential-plugin/) to setup this plugin. + +## Limitations + +1. At this moment, the `RemoteParameters` construct only supports the `String` data type from parameter store. +2. Maximum number of parameters is `100`. Will make it configurable in the future if required. + +# Contributing + +See [CONTRIBUTING](CONTRIBUTING.md) for more information. + +# License + +This code is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file. + + +%prep +%autosetup -n cdk-remote-stack-2.0.10 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-cdk-remote-stack -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Tue Apr 11 2023 Python_Bot <Python_Bot@openeuler.org> - 2.0.10-1 +- Package Spec generated @@ -0,0 +1 @@ +71c5192ceaf84d1dd05e6ef5dc4d9d89 cdk-remote-stack-2.0.10.tar.gz |
