%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 [![npm version](https://badge.fury.io/js/cdk-remote-stack.svg)](https://badge.fury.io/js/cdk-remote-stack) [![PyPI version](https://badge.fury.io/py/cdk-remote-stack.svg)](https://badge.fury.io/py/cdk-remote-stack) [![release](https://github.com/pahud/cdk-remote-stack/actions/workflows/release.yml/badge.svg)](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. ![](images/remote-param-1.svg) ```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. ![](images/remote-param-2.svg) ```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. ![](images/remote-param-3.svg) 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 [![npm version](https://badge.fury.io/js/cdk-remote-stack.svg)](https://badge.fury.io/js/cdk-remote-stack) [![PyPI version](https://badge.fury.io/py/cdk-remote-stack.svg)](https://badge.fury.io/py/cdk-remote-stack) [![release](https://github.com/pahud/cdk-remote-stack/actions/workflows/release.yml/badge.svg)](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. ![](images/remote-param-1.svg) ```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. ![](images/remote-param-2.svg) ```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. ![](images/remote-param-3.svg) 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 [![npm version](https://badge.fury.io/js/cdk-remote-stack.svg)](https://badge.fury.io/js/cdk-remote-stack) [![PyPI version](https://badge.fury.io/py/cdk-remote-stack.svg)](https://badge.fury.io/py/cdk-remote-stack) [![release](https://github.com/pahud/cdk-remote-stack/actions/workflows/release.yml/badge.svg)](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. ![](images/remote-param-1.svg) ```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. ![](images/remote-param-2.svg) ```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. ![](images/remote-param-3.svg) 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 - 2.0.10-1 - Package Spec generated