├── .gitignore ├── .npmignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── api ├── create.py └── read.py ├── cdk.json ├── cdk ├── bin │ └── pipeline.ts └── lib │ ├── api-stack.ts │ ├── cdk-pipeline-stack.ts │ └── ddb-stack.ts ├── images ├── 1_click.png ├── architecture.png ├── attach_console_role.png ├── attach_role.png ├── attach_trusted_role_policy.png ├── create_policy.png ├── create_trusted_role.png ├── edit_env.png ├── env_setting.png ├── github_repo.png ├── github_token.png ├── multi_region_app.png ├── pipeline_policy.png ├── prefix.png ├── release_change.png ├── review_policy.png ├── switch_role.png ├── switch_role_dropdown.png └── trusted_account_summary.png ├── jest.config.js ├── package-lock.json ├── package.json └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | !jest.config.js 3 | *.d.ts 4 | node_modules 5 | 6 | # CDK asset staging directory 7 | .cdk.staging 8 | cdk.out 9 | build/ 10 | .env 11 | api/node_modules 12 | 13 | 14 | cdk.context.json 15 | .DS_Store 16 | __* -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.ts 2 | !*.d.ts 3 | 4 | # CDK asset staging directory 5 | .cdk.staging 6 | cdk.out 7 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Build CI/CD Pipelines with CDK - Multi Account/Region Deployments 2 | 3 | In this sample we introduce a way to build CI/CD pipelines using the CDK to realize multi account/region deployments. An example use case for this is deployment of software and infrastructure to multiple environments such as Development, QA, Staging, and Production. 4 | 5 |   6 | 7 | ## Stack Architecture 8 | 9 |   10 | 11 | The following diagram shows the pipeline and target accounts’ regional architecture. The entire architecture spans four accounts. One account is for the deployment pipeline, and the other three accounts are the accounts that the application is deployed to: 12 | 13 | ![CI/CD Pipeline with CDK - Multi Account/Region Deployments Architecture](./images/architecture.png) 14 | 15 |   16 | 17 | ## Cross Account Console Setup - Console (Optional but recommended) 18 | During the deployment, we will need to switch between four AWS accounts to check resources. To avoid the time spent to log in and out of accounts, we will leverage roles to get access to different accounts in the console. This step will facilitate switching accounts in the console with 1-click. The alternative to this approach would be to continuously log in and out of the accounts used by the pipeline, and the accounts the pipeline deploys to. 19 | 20 | 1. In each of target accounts (prd, stg, dev), using the IAM (Identity and Access Management) service, create a role `OrganizationAccountAccessRole` and configure it to trust the pipeline account, attach policy, add tags, and confirm creation: 21 | 22 | * Create role that trusts another AWS account and specify pipeline account ID: 23 | ![create_trusted_role](./images/create_trusted_role.png) 24 | 25 | * Specify policy to attach to trusted role (`AdministratorAccess` used as the pipeline needs to create resources and IAM entities): 26 | ![attach_trusted_role_policy](./images/attach_trusted_role_policy.png) 27 | 28 | * Review and create the role: 29 | ![trusted_account_summary](./images/trusted_account_summary.png) 30 | 31 | 2. In the pipeline account, create a policy as below for each of the target accounts and attach to a role your account can access. 32 | 33 | * Policy template: 34 | ``` 35 | { 36 | "Version": "2012-10-17", 37 | "Statement": [ 38 | { 39 | "Sid": "VisualEditor0", 40 | "Effect": "Allow", 41 | "Action": "sts:AssumeRole", 42 | "Resource": "arn:aws:iam:::role/OrganizationAccountAccessRole" 43 | }, 44 | { 45 | "Sid": "VisualEditor1", 46 | "Effect": "Allow", 47 | "Action": "sts:AssumeRole", 48 | "Resource": "arn:aws:iam:::role/OrganizationAccountAccessRole" 49 | }, 50 | { 51 | "Sid": "VisualEditor2", 52 | "Effect": "Allow", 53 | "Action": "sts:AssumeRole", 54 | "Resource": "arn:aws:iam:::role/OrganizationAccountAccessRole" 55 | } 56 | ] 57 | } 58 | ``` 59 | * Create IAM policy: 60 | ![create_policy](./images/create_policy.png) 61 | 62 | * Review and name IAM policy: 63 | ![review_policy](./images/review_policy.png) 64 | 65 | * Attach policy to role your user has access to: 66 | ![attach_console_role](./images/attach_console_role.png) 67 | 68 | 3. Use drop-down menu at top-right of the console to switch between accounts. 69 | * Click the `Switch role` button: 70 | ![switch_role_dropdown](./images/switch_role_dropdown.png) 71 | 72 | * Enter the information of the role you want to assume: 73 | ![switch_role](./images/switch_role.png) 74 | 75 | * Notice that roles you switch into are remembered, allowing 1-click role switching in the future: 76 | ![1_click](./images/1_click.png) 77 |   78 | 79 | ## Fork and update the code 80 | 81 | The easiest way to start trying out the capabilities of CDK Pipelines with this sample is to fork this repository and make changes in your own fork. After you have created your own fork, clone the repository to your development environment and open the stack file `cdk/lib/cdk-pipeline-stack.ts`. This file contains the pipeline stack definitions, including a set of constants that are needed to provision the full environment. Review and update the constants for GitHub organization, repository, branch, the three deployment AWS accounts, and regions. 82 | 83 | ## Regional CDK Bootstrapping 84 | 85 | Each account region combo that is deployed to must be bootstrapped. Since it is a cross-account deployment, a trust must be established during this process. 86 | 87 | Deploying AWS CDK apps into an AWS environment may require that you provision resources the AWS CDK needs to perform the deployment. These resources include an Amazon S3 bucket for storing files and IAM roles that grant permissions needed to perform deployments. The process of provisioning these initial resources is called bootstrapping. 88 | 89 | 1. For each target account/region run the following CLI command. The command must run with appropriate privileges in the target account: 90 | ``` 91 | cdk bootstrap --trust --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess aws:/// 92 | ``` 93 | **Note:** You will also need to run this in the secondary region in the pipeline account 94 | 95 | 2. Given we are deploying to 2 regions in 3 different accounts, we must run this command 6 times 96 | 97 |   98 | 99 | ## Initial Deployment of Pipeline 100 | 101 |   102 | 103 | ### Pipeline Overview 104 | 105 | `./cdk/bin/pipeline.ts`: Creation of CDK App for Pipeline 106 | 107 | `./cdk/lib/cdk-pipeline-stack.ts`: Definition of stacks to deploy, as well as environments to deploy to. 108 | 109 |   110 | 111 | ### Github Access 112 | 1. Create a GitHub token [here](https://github.com/settings/tokens/) using an account with access to the forked repo. Set the permission as below 113 | 114 | ![github_repo](./images/github_repo.png) 115 | 116 | 2. In the pipeline account/region, create a secret in [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) to store access token for GitHub repo. The token must stored as a plaintext secret with a name of `github-token`: 117 | 118 | ![github_token](./images/github_token.png) 119 | 120 |   121 | 122 | ### Deploy Pipeline 123 | 124 | 1. Clone the repo and run command. When prompted to create security groups/deploy, accept. 125 | ``` 126 | cdk deploy CdkPipelineStack 127 | ``` 128 | 129 | 2. Navigate to CodePipeline in Console and cancel the initial build. 130 | 3. Set Env Vars in the Build step of the pipeline as below. 131 | 132 | ![edit_env](./images/edit_env.png) 133 | 134 | ![env_setting](./images/env_setting.png) 135 | 136 |   137 | 138 | ### Configure Pipeline Role 139 | 140 | In pipeline account, create a Policy for each target account to allow Pipeline role to assume Roles created during bootstrap process 141 | 142 | 1. Get CDK prefix from a target account 143 | 144 | ![prefix](./images/prefix.png) 145 | 146 | 2. Create policy for all 3 accounts 147 | 148 | ![pipeline_policy](./images/pipeline_policy.png) 149 | 150 | 3. Attach all 3 policies to the Pipeline Build role (Very similar to what we did for cross account access in console) 151 | 152 | ![attach_role](./images/attach_role.png) 153 | 154 |   155 | 156 | ### Run Pipeline 157 | Navigate to Pipeline and Release Changes, app resources will be deployed in three accounts and two regions in each account. 158 | 159 | Waves can be used to deploy multiple stages in parallel. In this example: 160 | - DEV and QA 161 | - PRD and STG Primary 162 | - PRD and STG Secondary 163 | 164 | 165 | ![release_change](./images/release_change.png) 166 | 167 |   168 | 169 | ## App Architecture 170 | 171 | App structure contains three stacks: 172 | 173 | - VPC: Core networking 174 | - RDS: RDS Postgres Instance (or read replica in multi-region deployment) 175 | - API: Lambda w/ VPC attachment and API gateway 176 | 177 | ![multi_region_app](./images/multi_region_app.png) 178 | 179 |   180 | 181 | ## Cleanup 182 | Each Stack (VPC, RDS, API) is deployed independently to each account/region 183 | This allows each to be updated separately. 184 | 185 | You will need to go CloudFormation in each account/region and delete the stacks when you want to clean up the resources. 186 | 187 | Explore nested stacks if this behavior is not acceptable 188 | 189 | ## Troubleshooting 190 | Message `Policy contains a statement with one or more invalid principals`: Ensure environment variables are set. _Note:_ You must set them in the CodeBuild project after each deployment of the pipeline (You shouldn't deploy it often, it self-mutates :)). 191 | 192 | 193 | ## Security 194 | 195 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 196 | 197 | ## License 198 | 199 | This library is licensed under the MIT-0 License. See the LICENSE file. 200 | -------------------------------------------------------------------------------- /api/create.py: -------------------------------------------------------------------------------- 1 | import json 2 | import boto3 3 | import os 4 | 5 | def handler(event, context=None): 6 | print('request: {}'.format(json.dumps(event))) 7 | client = boto3.client('dynamodb') 8 | table = os.getenv('DDB_TABLE_NAME', 'undefined') 9 | key = event['key'] 10 | value = event['value'] 11 | response = response = client.put_item( 12 | Item={ 13 | 'Key': { 14 | 'S': key, 15 | }, 16 | 'Value': { 17 | 'S': value, 18 | }, 19 | }, 20 | TableName=table, 21 | ) 22 | return json.dumps(response) -------------------------------------------------------------------------------- /api/read.py: -------------------------------------------------------------------------------- 1 | import json 2 | import boto3 3 | import os 4 | 5 | def handler(event, context=None): 6 | print('request: {}'.format(json.dumps(event))) 7 | client = boto3.client('dynamodb') 8 | table = os.getenv('DDB_TABLE_NAME', 'undefined') 9 | key = event['key'] 10 | response = client.get_item( 11 | Key={ 12 | 'Key': { 13 | 'S': key, 14 | }, 15 | }, 16 | TableName=table, 17 | ) 18 | return json.dumps(response) -------------------------------------------------------------------------------- /cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node --prefer-ts-exts cdk/bin/pipeline.ts", 3 | "context": { 4 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false, 5 | "@aws-cdk/aws-ecs-patterns:removeDefaultDesiredCount": false, 6 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": false, 7 | "@aws-cdk/aws-lambda:recognizeVersionProps": false 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /cdk/bin/pipeline.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { App } from 'aws-cdk-lib'; 3 | import { CdkPipelineStack } from '../lib/cdk-pipeline-stack'; 4 | import { AwsSolutionsChecks } from 'cdk-nag'; 5 | import { Aspects } from 'aws-cdk-lib'; 6 | 7 | const app = new App(); 8 | // Add the cdk-nag AwsSolutions Pack with extra verbose logging enabled. 9 | Aspects.of(app).add(new AwsSolutionsChecks({ verbose: true })) 10 | 11 | new CdkPipelineStack(app, 'CdkPipelineStack', { 12 | env: { 13 | account: process.env.CDK_DEFAULT_ACCOUNT, 14 | region: process.env.CDK_DEFAULT_REGION 15 | }, 16 | }); 17 | 18 | app.synth(); -------------------------------------------------------------------------------- /cdk/lib/api-stack.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from "constructs"; 2 | import { Stack, StackProps } from "aws-cdk-lib"; 3 | import { Function, Runtime, Code } from "aws-cdk-lib/aws-lambda"; 4 | import { TableV2 } from "aws-cdk-lib/aws-dynamodb"; 5 | import { Role, ServicePrincipal } from "aws-cdk-lib/aws-iam"; 6 | 7 | export interface ApiStackProperties extends StackProps { 8 | dynamoTable: TableV2 9 | } 10 | 11 | export class ApiStack extends Stack { 12 | constructor(scope: Construct, id: string, props: ApiStackProperties) { 13 | super(scope, id, props); 14 | 15 | const readLambda = new Function(this, "read-lambda", { 16 | runtime: Runtime.PYTHON_3_12, 17 | code: Code.fromAsset("api"), 18 | handler: "read.handler", 19 | environment: { 20 | DDB_TABLE_NAME: props.dynamoTable.tableName 21 | }, 22 | }); 23 | 24 | const createLambda = new Function(this, "create-lambda", { 25 | runtime: Runtime.PYTHON_3_12, 26 | code: Code.fromAsset("api"), 27 | handler: "create.handler", 28 | environment: { 29 | DDB_TABLE_NAME: props.dynamoTable.tableName 30 | }, 31 | }); 32 | 33 | props.dynamoTable.grantReadData(readLambda); 34 | props.dynamoTable.grantReadWriteData(createLambda); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /cdk/lib/cdk-pipeline-stack.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from "constructs"; 2 | import { Stage, StageProps, Stack, StackProps, Aws } from "aws-cdk-lib"; 3 | import { CodePipeline, CodePipelineSource, ManualApprovalStep, ShellStep, Wave } from "aws-cdk-lib/pipelines"; 4 | import { ApiStack } from "./api-stack"; 5 | import { DDBStack } from "./ddb-stack"; 6 | import { NagSuppressions } from "cdk-nag"; 7 | 8 | class AppStage extends Stage { 9 | public readonly apiStack: ApiStack; 10 | public readonly rdsStack: DDBStack; 11 | 12 | constructor(scope: Construct, id: string, props?: StageProps) { 13 | super(scope, id, props); 14 | 15 | var ddbStack = new DDBStack(this, "ddb-stack", props) 16 | new ApiStack(this, 'api-stack', { 17 | dynamoTable: ddbStack.table 18 | }) 19 | } 20 | } 21 | 22 | export class CdkPipelineStack extends Stack { 23 | constructor(scope: Construct, id: string, props?: StackProps) { 24 | super(scope, id, props); 25 | 26 | // Suppressing cdk-nag errors 27 | NagSuppressions.addStackSuppressions(this, [ 28 | { 29 | id: 'AwsSolutions-IAM5', 30 | reason: 'Suppressing errors originating in external packages.' 31 | }, 32 | { 33 | id: 'AwsSolutions-KMS5', 34 | reason: 'Suppressing errors originating in external packages.' 35 | }, 36 | { 37 | id: 'AwsSolutions-S1', 38 | reason: 'Suppressing errors originating in external packages.' 39 | } 40 | ]) 41 | 42 | const githubOrg = process.env.GITHUB_ORG || "kevasync"; 43 | const githubRepo = process.env.GITHUB_REPO || "multiple-account-cdk-cicd-pipeline"; 44 | const githubBranch = process.env.GITHUB_BRANCH || "main"; 45 | const devAccountId = process.env.DEV_ACCOUNT_ID || "undefined"; 46 | const stgAccountId = process.env.STG_ACCOUNT_ID || "undefined"; 47 | const prdAccountId = process.env.PRD_ACCOUNT_ID || "undefined"; 48 | const primaryRegion = process.env.PRIMARY_REGION || "us-west-2"; 49 | const secondaryRegion = process.env.SECONDARY_REGION || "us-east-1"; 50 | 51 | const pipeline = new CodePipeline(this, "CDKPipeline", { 52 | crossAccountKeys: true, 53 | pipelineName: "CDKPipeline", 54 | synth: new ShellStep("deploy", { 55 | input: CodePipelineSource.gitHub(`${githubOrg}/${githubRepo}`, githubBranch), 56 | commands: [ 57 | "npm ci", 58 | "npx cdk synth" 59 | ] 60 | }), 61 | }); 62 | 63 | const devQaWave = pipeline.addWave("DEV-and-QA-Deployments"); 64 | const dev = new AppStage(this, "dev", { 65 | env: { account: devAccountId, region: primaryRegion } 66 | }); 67 | 68 | const qa = new AppStage(this, "qa", { 69 | env: { account: devAccountId, region: secondaryRegion } 70 | }); 71 | 72 | const stg = new AppStage(this, "stg", { 73 | env: { account: stgAccountId, region: primaryRegion } 74 | }); 75 | 76 | devQaWave.addStage(dev); 77 | devQaWave.addStage(qa); 78 | devQaWave.addStage(stg); 79 | 80 | const primaryRdsRegionWave = pipeline.addWave("PROD-Deployment", { 81 | pre: [new ManualApprovalStep("ProdManualApproval")] 82 | }); 83 | const prdPrimary = new AppStage(this, "prd-primary", { 84 | env: { account: prdAccountId, region: primaryRegion } 85 | }); 86 | primaryRdsRegionWave.addStage(prdPrimary); 87 | } 88 | } -------------------------------------------------------------------------------- /cdk/lib/ddb-stack.ts: -------------------------------------------------------------------------------- 1 | import { Construct } from "constructs"; 2 | import { Stack, StackProps } from "aws-cdk-lib"; 3 | 4 | import { AttributeType, TableV2 } from "aws-cdk-lib/aws-dynamodb"; 5 | 6 | export class DDBStack extends Stack { 7 | public readonly table: TableV2; 8 | 9 | constructor(scope: Construct, id: string, props?: StackProps) { 10 | super(scope, id, props); 11 | 12 | const table = new TableV2(this, 'Table', { 13 | partitionKey: { name: 'Key', type: AttributeType.STRING }, 14 | }); 15 | 16 | this.table = table; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /images/1_click.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/1_click.png -------------------------------------------------------------------------------- /images/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/architecture.png -------------------------------------------------------------------------------- /images/attach_console_role.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/attach_console_role.png -------------------------------------------------------------------------------- /images/attach_role.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/attach_role.png -------------------------------------------------------------------------------- /images/attach_trusted_role_policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/attach_trusted_role_policy.png -------------------------------------------------------------------------------- /images/create_policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/create_policy.png -------------------------------------------------------------------------------- /images/create_trusted_role.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/create_trusted_role.png -------------------------------------------------------------------------------- /images/edit_env.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/edit_env.png -------------------------------------------------------------------------------- /images/env_setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/env_setting.png -------------------------------------------------------------------------------- /images/github_repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/github_repo.png -------------------------------------------------------------------------------- /images/github_token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/github_token.png -------------------------------------------------------------------------------- /images/multi_region_app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/multi_region_app.png -------------------------------------------------------------------------------- /images/pipeline_policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/pipeline_policy.png -------------------------------------------------------------------------------- /images/prefix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/prefix.png -------------------------------------------------------------------------------- /images/release_change.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/release_change.png -------------------------------------------------------------------------------- /images/review_policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/review_policy.png -------------------------------------------------------------------------------- /images/switch_role.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/switch_role.png -------------------------------------------------------------------------------- /images/switch_role_dropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/switch_role_dropdown.png -------------------------------------------------------------------------------- /images/trusted_account_summary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/multiple-account-cdk-cicd-pipeline/8cc082ec4f071946def0836d0d9e7c886771804c/images/trusted_account_summary.png -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | testEnvironment: "node", 3 | roots: ["/cdk/test"], 4 | testMatch: ["**/*.test.ts"], 5 | transform: { 6 | "^.+\\.tsx?$": "ts-jest", 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "api", 3 | "version": "2.0.0", 4 | "scripts": { 5 | "build": "tsc", 6 | "watch": "tsc -w", 7 | "test": "jest", 8 | "cdk": "cdk" 9 | }, 10 | "peerDependencies": { 11 | "aws-cdk-lib": "^2.103.0", 12 | "constructs": "^10.3.0" 13 | }, 14 | "devDependencies": { 15 | "@types/jest": "^26.0.24", 16 | "@types/node": "10.17.27", 17 | "aws-cdk-lib": "^2.110.1", 18 | "jest": "^29.7.0", 19 | "ts-jest": "^29.1.1", 20 | "ts-node": "^10.9.1", 21 | "typescript": "^5.3.2" 22 | }, 23 | "dependencies": { 24 | "cdk-nag": "^2.27.198", 25 | "source-map-support": "^0.5.21" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "module": "commonjs", 5 | "lib": [ 6 | "es2018" 7 | ], 8 | "declaration": true, 9 | "strict": true, 10 | "noImplicitAny": true, 11 | "strictNullChecks": true, 12 | "noImplicitThis": true, 13 | "alwaysStrict": true, 14 | "noUnusedLocals": false, 15 | "noUnusedParameters": false, 16 | "noImplicitReturns": true, 17 | "noFallthroughCasesInSwitch": false, 18 | "inlineSourceMap": true, 19 | "inlineSources": true, 20 | "experimentalDecorators": true, 21 | "strictPropertyInitialization": false, 22 | "typeRoots": [ 23 | "./node_modules/@types" 24 | ], 25 | "esModuleInterop": true 26 | }, 27 | "exclude": [ 28 | "node_modules", 29 | "cdk.out" 30 | ] 31 | } 32 | 33 | 34 | --------------------------------------------------------------------------------