Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(toolkit): support multiple toolkit stacks in the same environment #1427

Merged
merged 2 commits into from
Dec 27, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions docs/src/tools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,29 @@ Here are the actions you can take on your CDK app
If one of cdk.json or ~/.cdk.json exists, options specified there will be used
as defaults. Settings in cdk.json take precedence.

.. _config-files:

Configuration
=============

The CDK toolkit resolves its configuration by reading files in the following order:

1. ``~/.cdk.json``: user-level configuration file
2. ``cdk.json``: project configuration file
3. Command line arguments

The following options are supported in **cdk.json**:

* ``app`` (string): the command-line to use in order to invoke your CDK app.
* ``browser`` (string): the command to use to open the browser, using %u as a placeholder for the path of the file to open
* ``context`` (hash): key-value pairs of context values which can later be read by ``Construct.getContext(key)``
* ``language`` (string): programming langauge to use for **cdk-init**
* ``pathMetadata`` (boolean): Include "aws:cdk:path" CloudFormation metadata for each resource (enabled by default)
* ``plugin`` (array): Name or path of a node package that extend the CDK features
* ``requireApproval`` (string): what security-sensitive changes need manual approval (choices: "never", "any-change", "broadening")
* ``toolkitStackName`` (string): the name of the CDK toolkit stack
* ``versionReporting`` (boolean): Include the "AWS::CDK::Metadata" resource in synthesized templates

.. _security-changes:

Security-related changes
Expand Down
11 changes: 7 additions & 4 deletions packages/aws-cdk/bin/cdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,15 @@ async function parseCommandLineArguments() {
.option('version-reporting', { type: 'boolean', desc: 'Include the "AWS::CDK::Metadata" resource in synthesized templates (enabled by default)', default: undefined })
.option('path-metadata', { type: 'boolean', desc: 'Include "aws:cdk:path" CloudFormation metadata for each resource (enabled by default)', default: true })
.option('role-arn', { type: 'string', alias: 'r', desc: 'ARN of Role to use when invoking CloudFormation', default: undefined })
.option('toolkit-stack-name', { type: 'string', desc: 'The name of the CDK toolkit stack' })
.command([ 'list', 'ls' ], 'Lists all stacks in the app', yargs => yargs
.option('long', { type: 'boolean', default: false, alias: 'l', desc: 'display environment information for each stack' }))
.command([ 'synthesize [STACKS..]', 'synth [STACKS..]' ], 'Synthesizes and prints the CloudFormation template for this stack', yargs => yargs
.option('interactive', { type: 'boolean', alias: 'i', desc: 'interactively watch and show template updates' })
.option('output', { type: 'string', alias: 'o', desc: 'write CloudFormation template for requested stacks to the given directory' }))
.command('bootstrap [ENVIRONMENTS..]', 'Deploys the CDK toolkit stack into an AWS environment', yargs => yargs
.option('toolkit-stack-name', { type: 'string', desc: 'the name of the CDK toolkit stack' }))
.command('bootstrap [ENVIRONMENTS..]', 'Deploys the CDK toolkit stack into an AWS environment')
.command('deploy [STACKS..]', 'Deploys the stack(s) named STACKS into your AWS account', yargs => yargs
.option('require-approval', { type: 'string', choices: [RequireApproval.Never, RequireApproval.AnyChange, RequireApproval.Broadening], desc: 'what security-sensitive changes need manual approval' })
.option('toolkit-stack-name', { type: 'string', desc: 'the name of the CDK toolkit stack' }))
.option('require-approval', { type: 'string', choices: [RequireApproval.Never, RequireApproval.AnyChange, RequireApproval.Broadening], desc: 'what security-sensitive changes need manual approval' }))
.command('destroy [STACKS..]', 'Destroy the stack(s) named STACKS', yargs => yargs
.option('force', { type: 'boolean', alias: 'f', desc: 'Do not ask for confirmation before destroying the stacks' }))
.command('diff [STACK]', 'Compares the specified stack with the deployed stack or a local template file', yargs => yargs
Expand Down Expand Up @@ -144,6 +143,10 @@ async function initCommandLine() {
async function main(command: string, args: any): Promise<number | string | {} | void> {
const toolkitStackName: string = configuration.combined.get(['toolkitStackName']) || DEFAULT_TOOLKIT_STACK_NAME;

if (toolkitStackName !== DEFAULT_TOOLKIT_STACK_NAME) {
print(`Toolkit stack: ${colors.bold(toolkitStackName)}`);
}

args.STACKS = args.STACKS || [];
args.ENVIRONMENTS = args.ENVIRONMENTS || [];

Expand Down
24 changes: 24 additions & 0 deletions packages/aws-cdk/integ-tests/test-cdk-multiple-toolkit-stacks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash
set -euo pipefail
scriptdir=$(cd $(dirname $0) && pwd)
source ${scriptdir}/common.bash
# ----------------------------------------------------------

setup

toolkit_stack_name_1="toolkit-stack-${RANDOM}"
toolkit_stack_name_2="toolkit-stack-${RANDOM}"
eladb marked this conversation as resolved.
Show resolved Hide resolved

# deploy two toolkit stacks into the same environment (see #1416)
cdk bootstrap --toolkit-stack-name ${toolkit_stack_name_1}
cdk bootstrap --toolkit-stack-name ${toolkit_stack_name_2}

# just check that the new stack exists
aws cloudformation describe-stack-resources --stack-name ${toolkit_stack_name_1}
aws cloudformation describe-stack-resources --stack-name ${toolkit_stack_name_2}

# clean up
aws cloudformation delete-stack --stack-name ${toolkit_stack_name_1}
aws cloudformation delete-stack --stack-name ${toolkit_stack_name_2}

echo "✅ success"
22 changes: 10 additions & 12 deletions packages/aws-cdk/lib/api/bootstrap-environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,26 @@ export const BUCKET_DOMAIN_NAME_OUTPUT = 'BucketDomainName';
export async function bootstrapEnvironment(environment: Environment, aws: SDK, toolkitStackName: string, roleArn: string | undefined): Promise<DeployStackResult> {
const synthesizedStack: SynthesizedStack = {
environment,
metadata: { },
metadata: {},
template: {
Description: "The CDK Toolkit Stack. It cas created by `cdk bootstrap` and manages resources necessary for managing your Cloud Applications with AWS CDK.",
Resources: {
StagingBucket: {
Type: "AWS::S3::Bucket",
Properties: {
AccessControl: "Private",
BucketEncryption: { ServerSideEncryptionConfiguration: [ { ServerSideEncryptionByDefault: { SSEAlgorithm: "aws:kms" } } ] }
}
Type: "AWS::S3::Bucket",
Properties: {
AccessControl: "Private",
BucketEncryption: { ServerSideEncryptionConfiguration: [{ ServerSideEncryptionByDefault: { SSEAlgorithm: "aws:kms" } }] }
}
}
},
Outputs: {
[BUCKET_NAME_OUTPUT]: {
Description: "The name of the S3 bucket owned by the CDK toolkit stack",
Value: { Ref: "StagingBucket" },
Export: { Name: "CDKToolkit:BucketName" }
Description: "The name of the S3 bucket owned by the CDK toolkit stack",
Value: { Ref: "StagingBucket" }
},
[BUCKET_DOMAIN_NAME_OUTPUT]: {
Description: "The domain name of the S3 bucket owned by the CDK toolkit stack",
Value: { "Fn::GetAtt": [ "StagingBucket", "DomainName" ] },
Export: { Name: "CDKToolkit:BucketDomainName" }
Description: "The domain name of the S3 bucket owned by the CDK toolkit stack",
Value: { "Fn::GetAtt": ["StagingBucket", "DomainName"] }
}
}
},
Expand Down