Skip to main content

Get outputs and parameters from remote CDK stacks

Project description

awscdk-jsii-template NPM version PyPI version Build

cdk-remote-stack

Get outputs from cross-regional AWS CDK stacks

Why

AWS CDK cross-regional cross-stack reference is not easy with the native AWS CDK construct library.

cdk-remote-stack aims to simplify the cross-regional cross-stack reference to help you easily build cross-regional multi-stack AWS CDK apps.

This construct library provides two major 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 CDK stacks in the same cdk app:

  1. stackJP - cdk stack in JP to create a SNS topic
  2. stackUS - cdk stack in US to get the Outputs from stackJP and print out the SNS TopicName from stackJP Outputs.
# Example automatically generated from non-compiling source. May contain errors.
from cdk_remote_stack import RemoteOutputs
import aws_cdk.core as cdk

app = cdk.App()

env_jP = {
    "region": "ap-northeast-1",
    "account": process.env.CDK_DEFAULT_ACCOUNT
}

env_uS = {
    "region": "us-west-2",
    "account": process.env.CDK_DEFAULT_ACCOUNT
}

# first stack in JP
stack_jP = cdk.Stack(app, "demo-stack-jp", env=env_jP)

cdk.CfnOutput(stack_jP, "TopicName", value="foo")

# second stack in US
stack_uS = cdk.Stack(app, "demo-stack-us", env=env_uS)

# ensure the dependency
stack_uS.add_dependency(stack_jP)

# get the stackJP stack outputs from stackUS
outputs = RemoteOutputs(stack_uS, "Outputs", stack=stack_jP)

remote_output_value = outputs.get("TopicName")

# the value should be exactly the same with the output value of `TopicName`
cdk.CfnOutput(stack_uS, "RemoteTopicName", value=remote_output_value)

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:

# Example automatically generated from non-compiling source. May contain errors.
outputs = RemoteOutputs(stack_uS, "Outputs",
    stack=stack_jP,
    always_update=False
)

RemoteParameters

AWS SSM Parameter Store 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:

#1 - 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.

# Example automatically generated from non-compiling source. May contain errors.
env_jP = {"region": "ap-northeast-1", "account": "111111111111"}
env_uS = {"region": "us-west-2", "account": "111111111111"}

# first stack in JP
producer_stack_name = "demo-stack-jp"
stack_jP = cdk.Stack(app, producer_stack_name, env=env_jP)
parameter_path = f"/{envJP.account}/{envJP.region}/{producerStackName}"

ssm.StringParameter(stack_jP, "foo1",
    parameter_name=f"{parameterPath}/foo1",
    string_value="bar1"
)
ssm.StringParameter(stack_jP, "foo2",
    parameter_name=f"{parameterPath}/foo2",
    string_value="bar2"
)
ssm.StringParameter(stack_jP, "foo3",
    parameter_name=f"{parameterPath}/foo3",
    string_value="bar3"
)

# second stack in US
stack_uS = cdk.Stack(app, "demo-stack-us", env=env_uS)

# ensure the dependency
stack_uS.add_dependency(stack_jP)

# get remote parameters by path from SSM parameter store
parameters = RemoteParameters(stack_uS, "Parameters",
    path=parameter_path,
    region=stack_jP.region
)

foo1 = parameters.get(f"{parameterPath}/foo1")
foo2 = parameters.get(f"{parameterPath}/foo2")
foo3 = parameters.get(f"{parameterPath}/foo3")

cdk.CfnOutput(stack_uS, "foo1Output", value=foo1)
cdk.CfnOutput(stack_uS, "foo2Output", value=foo2)
cdk.CfnOutput(stack_uS, "foo3Output", value=foo3)

#2 - Stacks from differnt accounts and different regions

Similar to the case above, now we are running seperate stacks in seperate account/region. We will need to pass a role to the RemoteParameters construct to get all the parameters from remote.

# Example automatically generated from non-compiling source. May contain errors.
env_jP = {"region": "ap-northeast-1", "account": "111111111111"}
env_uS = {"region": "us-west-2", "account": "222222222222"}

# first stack in JP
producer_stack_name = "demo-stack-jp"
stack_jP = cdk.Stack(app, producer_stack_name, env=env_jP)
parameter_path = f"/{envJP.account}/{envJP.region}/{producerStackName}"

ssm.StringParameter(stack_jP, "foo1",
    parameter_name=f"{parameterPath}/foo1",
    string_value="bar1"
)
ssm.StringParameter(stack_jP, "foo2",
    parameter_name=f"{parameterPath}/foo2",
    string_value="bar2"
)
ssm.StringParameter(stack_jP, "foo3",
    parameter_name=f"{parameterPath}/foo3",
    string_value="bar3"
)

# allow US account to assume this readonly role to get parameters
cdk_read_only_role = iam.Role(stack_jP, "readOnlyRole",
    assumed_by=iam.AccountPrincipal(env_uS.account),
    role_name=PhysicalName.GENERATE_IF_NEEDED,
    managed_policies=[iam.ManagedPolicy.from_aws_managed_policy_name("AmazonSSMReadOnlyAccess")]
)

# second stack in US
stack_uS = cdk.Stack(app, "demo-stack-us", env=env_uS)

# ensure the dependency
stack_uS.add_dependency(stack_jP)

# get remote parameters by path from SSM parameter store
parameters = RemoteParameters(stack_uS, "Parameters",
    path=parameter_path,
    region=stack_jP.region,
    # assume this role for cross-account parameters
    role=iam.Role.from_role_arn(stack_uS, "readOnlyRole", cdk_read_only_role.role_arn)
)

foo1 = parameters.get(f"{parameterPath}/foo1")
foo2 = parameters.get(f"{parameterPath}/foo2")
foo3 = parameters.get(f"{parameterPath}/foo3")

cdk.CfnOutput(stack_uS, "foo1Output", value=foo1)
cdk.CfnOutput(stack_uS, "foo2Output", value=foo2)
cdk.CfnOutput(stack_uS, "foo3Output", value=foo3)

#3 - dedicated account for a centralized parameter store

The parameters are stored in a centralized account/region and previously provisioned as a state-of-truth configuration store. All other stacks from different account/region are consuming the parameters from remote.

This scenario is pretty much like #2. The difference is that there's a dedicated account for centralized parameter store being shared across all other accounts.

You will need create RemoteParameters for all the consuming stacks like:

# Example automatically generated from non-compiling source. May contain errors.
# for StackUS
RemoteParameters(stack_uS, "Parameters",
    path=parameter_path,
    region="eu-central-1",
    # assume this role for cross-account parameters
    role=iam.Role.from_role_arn(stack_uS, "readOnlyRole", shared_read_only_role_arn)
)

# for StackJP
RemoteParameters(stack_jP, "Parameters",
    path=parameter_path,
    region="eu-central-1",
    # assume this role for cross-account parameters
    role=iam.Role.from_role_arn(stack_jP, "readOnlyRole", shared_read_only_role_arn)
)

Tools for multi-account deployment

You will need to install cdk-assume-role-credential-plugin so you can deploy stacks from different accounts. Read this blog post to setup this plugin.

Limitation

  1. At this moment, the RemoteParameters construct only support the String data type from parameter store.
  2. Max number of parameters is 100. Will make it configurable in the future PR when required.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cdk-remote-stack-0.1.208.tar.gz (52.8 kB view details)

Uploaded Source

Built Distribution

cdk_remote_stack-0.1.208-py3-none-any.whl (51.1 kB view details)

Uploaded Python 3

File details

Details for the file cdk-remote-stack-0.1.208.tar.gz.

File metadata

  • Download URL: cdk-remote-stack-0.1.208.tar.gz
  • Upload date:
  • Size: 52.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.6.0 importlib_metadata/4.8.2 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.7.3

File hashes

Hashes for cdk-remote-stack-0.1.208.tar.gz
Algorithm Hash digest
SHA256 ec0c5660a0e4cc6cd96ac348152ff08fb34aa91e39e62608541235da922f2d68
MD5 4c9cc4dcd51d5b9bd944a3e9e98521f8
BLAKE2b-256 9fc9d84d8b29f0aa7112a38bb450344340a0bfcb71c6612e0478abc8909b3fb9

See more details on using hashes here.

File details

Details for the file cdk_remote_stack-0.1.208-py3-none-any.whl.

File metadata

  • Download URL: cdk_remote_stack-0.1.208-py3-none-any.whl
  • Upload date:
  • Size: 51.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.6.0 importlib_metadata/4.8.2 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.7.3

File hashes

Hashes for cdk_remote_stack-0.1.208-py3-none-any.whl
Algorithm Hash digest
SHA256 c24c61c549c4af122772de75f0ebf5b56f8fc3c3e80e03e657645171ae3dce8a
MD5 df60c709536a05a340b9c008c9b7132a
BLAKE2b-256 608c7db100a8b2c87ba1a90bccd921e0f176b16a0c066399697c07d6580e0056

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page