Skip to main content

CDK Cross-Account Resource Example

A practical example demonstrating how to manage AWS resources across multiple accounts using CDK and orbits. This project showcases an hello-world example: it deploys an AWS Systems Manager parameter in Account A and read it from a Lambda function in Account B.

Problem statement

Using AWS CDK and CloudFormation, consuming cross-account resources is difficult because stacks cannot directly reference resources from other AWS accounts, requiring manual coordination and hardcoded values.

Common problematic scenarios include:

  • Accessing Docker images built in account A from account B;
  • Using secrets from account A in account B applications;
  • Establishing VPC peering between accounts;
  • Granting cross-account S3 bucket access;
  • Sharing Lambda layers across accounts;
  • Writing values into the DNS zone of account A from account B.

This limitation is shown in this example:

const app = new cdk.App()

const paramA = new ParamStack(app, 'stack-A', {
...,
env: {
account: "account-A"
}
})

const lambdaB = new LambdaStack(app, 'stack-A', {
...,
parameterArn : paramA.parameter.arn, // ❌ you can not reference a resource from a stack from another account
env: {
account: "account-B"
}
})

With orbits, cross-account resource sharing works seamlessly:

const paramOutput = await this.do('updateParam', new ParamResource());

await this.do(
'updateLambda',
new LambdaResource().setArgument({
stackProps: {
parameterArn: paramOutput.parameterArn, // ✅ you can reference any stack
env: {
account: this.argument.accountA.id,
},
},
})
);

Architecture Overview

Prerequisites

Clone this repository

cd samples/cross-account-aws-cdk
  • Install node.js dependencies : npm i

Setup AWS environment

You'll need access to two AWS accounts with the following permissions:

  • Account A: CloudFormation deployment rights
  • Account B: CloudFormation deployment rights

Configure environment values

  • Copy the environment template:
    cp .base.env .env
  • Edit .env file with your account details.

Deployment

  • Load environment variables:
    export $(cat .env | xargs)
  • Define your mongo_url:
    export ORBITS_DB__MONGO__URL=your-mongo-url
  • Deploy Cross-Account Infrastructure:
    npx tsx src/orbits/orbi.ts
    This command will:
    • Deploy the SSM parameter in Account A;
    • Create the Lambda function in Account B with appropriate cross-account permissions;
    • Set up the necessary IAM roles and policies for cross-account access.

Verify the result of the Lambda Function

  • Navigate to the AWS Console for Account B

  • Go to Lambda service

  • Find the deployed function (typically named with a stack prefix)

  • Click Test to create a test event

  • Execute the test

  • Expected Output

    The Lambda function should successfully retrieve the parameter from Account A and should display the value of parameter A in its logs.

    console.log('Param:', param.Parameter.Value);

    The default value of parameter is "hello-world".

Cleanup

To remove all deployed resources from both accounts:

export HELLO_COMMAND=uninstall
npx tsx src/orbits/orbi.ts
warning

This will permanently delete all resources created by this example. Make sure you want to remove everything before running this command.

Project Structure

├── src/
│ ├── orbits/
│ │ └── orbi.ts # Main orchestration script
│ │ ├── lambda-resource.ts # lambda resource definition
│ │ ├── param-resource.ts # Param resource definition
│ │ ├── hello-resource.ts # Hello resource definition : the resource that make the junction between param and lambda
│ └── cdk/ # CDK stack definitions
│ ├── lambda.ts # lambda CDK stack
│ └── param.ts # Param CDK stack
├── .base.env # Environment template
├── .env # Your environment variables (git-ignored)
├── package.json
└── README.md

Step-by-step explanation

For a detailed walkthrough of the different files and how they work together, check out this blog post.

Security Considerations

The cross-account access follows the principle of least privilege. Parameters are accessed using IAM roles, not hardcoded credentials. CloudFormation stacks can be easily audited for security compliance