-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
feat(cli): --concurrency
option
#19378
Conversation
@@ -153,11 +154,17 @@ export class CdkToolkit { | |||
warning('⚠️ It should only be used for development - never use it for your production Stacks!'); | |||
} | |||
|
|||
const stacks = stackCollection.stackArtifacts; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This all works because stackArtifacts
is pre-sorted based on stack dependencies
@rix0rrr sorry for the direct tag but this PR didn't get auto-assigned and it looks like you've been on most of the PRs in these files. Any chance you'd be able to review or point me to the best person to get feedback? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking initiative on this! I really appreciate it. However, things are rarely as simple as they seem:
- I see why you made the exception for
--require-approval
... but this doesn't seem like the best way to go about things. A solution that allows for keeping the approval might toposort into levels, and do group approvals on each level before deploying them all in parallel.
That is not the biggest concern I have though, because it's something that allows for future extension. The bigger one is:
- The stack monitor. We'll have multiple stack monitor outputs all trampling over each other. The stack monitor will need to be made multi-stack aware, and have output limitations placed on them, in order to have properly formatted output.
Also, the "total time" reporting seems to have disappeared.
Thanks for the reply @rix0rrr!
I agree this is where we ultimately want to get to but what are your thoughts on leaving it as is for now and following up with a separate approval refactor?
I'll need to do some more digging around the monitors. Any suggestions around how to test the latest changes from the CLI level?
Added back in the latest version. Although the calculation is a little odd as its total synth time + individual stack deploy time but that is pre-existing |
@@ -142,7 +150,17 @@ integTest('deploy', withDefaultFixture(async (fixture) => { | |||
integTest('deploy all', withDefaultFixture(async (fixture) => { | |||
const arns = await fixture.cdkDeploy('test-*', { captureStderr: false }); | |||
|
|||
// verify that we only deployed a single stack (there's a single ARN in the output) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pre-existing incorrect comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
@rix0rrr as far as I can tell the Stack monitors work just fine concurrently but the monitor output can be confusing. I updated the logic to require |
@rix0rrr how do you want to proceed here? Happy to make a separate PR to address the security approvals |
d10905e
to
443e24a
Compare
In the meantime: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All looks pretty good, after some minor changes I'm happy to merge this. I want everyone to know not concerned about this pull request itself: the code looks good and the feature makes sense.
I'm concerned about the inevitable follow-up requests this will bring:
- Please make it work with confirmations (likelihood: high)
- Now that more requests are executing in parallel, I'm getting more throttles and my deployments are failing as a result (likelihood: high)
- Please make it work with the other progress reporter (likelihood: low-medium)
@relm923 will you be around to do follow-ups if issues come up?
One more thing that popped into my head: what happens if failures occur while a parallel deployment is happening? As best I can imagine, some red line will appear with an error, then a whole heap of SUCCESS will be printed as another stack that's deploying at the same time completes successfully, then we will print "Stack XYZ successfully deployed", and subsequently we'll exit with an error.
Can you tell me how confusing it will look when this happens?
packages/aws-cdk/lib/cdk-toolkit.ts
Outdated
.every((id) => !stacksAwaitingDeploy[id]); | ||
|
||
const enqueueStackDeploys = async () => { | ||
while (stacks[0] && isStackUnblocked(stacks[0])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're leaving some concurrency on the table here by only considering the first element from the list.
If we had dependencies:
C -> A
D -> B
And the list happened to toposort as [A, B, C, D]
, then with this implementation even if B
finishes we still can't start D
because we are forced to wait for C
to start first.
This can be changed to a for
loop -- on every iteration, consider all stacks.
It should probably be a forEach
, otherwise we might run afoul of the "closing over a loop variable" gotcha.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch! Updated to a forEach
loop
})); | ||
|
||
integTest('deploy all concurrently', withDefaultFixture(async (fixture) => { | ||
const arns = await fixture.cdkDeploy('test-*', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this is safe, many stacks in the integ app were designed to be deployed in a "just-so" way. Please pick a well-defined subset of like 5 stacks or so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was mainly basing this off the pre-existing deploy-all
test case -
integTest('deploy all', withDefaultFixture(async (fixture) => { |
Happy to pick a different set if you'd prefer
@@ -142,7 +150,17 @@ integTest('deploy', withDefaultFixture(async (fixture) => { | |||
integTest('deploy all', withDefaultFixture(async (fixture) => { | |||
const arns = await fixture.cdkDeploy('test-*', { captureStderr: false }); | |||
|
|||
// verify that we only deployed a single stack (there's a single ARN in the output) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
In my custom tool that does parallel deployments, I had this same problem (especially when I was doing 50 in parallel). What I ended up doing was on error:
This makes it really easy to find what failed in a wall of text.
This can be a problem. I think the primary thing that causes throttling is the API call to check on the status of the CFN deployment. Think before this PR it was every 3 seconds which is too low for parallel deployments. Think for parallel deployments, we can just default to higher and then you can also use AWS SDK settings for controlling retries (EG: increase the number and the wait between retries). |
Happy to help with follow ups as they arise
Example with failure (colors stripped)yarn run v1.22.18 ✨ Synthesis time: 16.18s
Failed resources: ❌ relm-broken-1 failed: Error: The stack named relm-broken-1 failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE /Users/relm/Development/aws-cdk/packages/aws-cdk/lib/api/util/cloudformation.ts:307 The failures are still reported here. In flight stacks will continue while remaining stacks are not updated |
@relm923 Just curious, do your changes support specifying |
Only via CLI currently. Happy to (or have someone else) add settings/ |
--concurrency
option
Thanks @relm923, that's what I needed to hear 😋. It's going in. |
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Reverts #19378 It breaks 4 integ tests: ``` ● security related changes without a CLI are expected to fail ... (node:7140) UnhandledPromiseRejectionWarning: Error: \"--require-approval\" is enabled and stack includes security-sensitive updates, but terminal (TTY) is not attached so we are unable to get a confirmation from the user ● update to stack in ROLLBACK_COMPLETE state will delete stack and create a new one expect(received).rejects.toThrow() Received promise resolved instead of rejected Resolved to value: "" at expect (../node_modules/expect/build/index.js:128:15) at expect (cli.integtest.ts:267:9) at block (../helpers/cdk.ts:131:13) at runMicrotasks (<anonymous>) at ResourcePool.using (../helpers/resource-pool.ts:44:14) at ../helpers/test-helpers.ts:36:14 ● stack in UPDATE_ROLLBACK_COMPLETE state can be updated expect(received).rejects.toThrow() Received promise resolved instead of rejected Resolved to value: "" at expect (../node_modules/expect/build/index.js:128:15) at expect (cli.integtest.ts:320:9) at runMicrotasks (<anonymous>) at ../helpers/cdk.ts:131:7 at ResourcePool.using (../helpers/resource-pool.ts:44:14) at ../helpers/test-helpers.ts:36:14 ● failed deploy does not hang ... (node:8336) UnhandledPromiseRejectionWarning: Error: The stack named cdktest-0m9jeq4rpbp-failed failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE: Property PolicyDocument cannot be empty. ``` Something around the handling of errors in the new async deployment.
Unfortunately the term “integ test” is overloaded. We have:
the second set is not run automatically in PRs since that has security implications: one needs to run them by hand |
@rix0rrr unless I'm doing something wrong (likely) yarn jest --testMatch '**/integ/cli/cli.integtest.js' I've tried running with and without piping to |
Closes aws#1973 Add `--concurrency` parameter to `cdk deploy` command to enable concurrent deployments while respecting stack dependencies. Concurrency mode will only work with `--progress events` due to the poor interaction of concurrent deployments and the progress bar rendering. ### Open Questions - [x] How best to write automated tests around this? Added unit and integration tests - [x] Should other commands (ex: `destroy`) support concurrency? Only supporting deploy command in this PR - [x] Any other concerns with this approach as it changes a key component of `cdk` - [x] How should this work with the `--exclusively` flag? Only check dependencies between requested stacks Example output: ```sh $ yarn cdk deploy --all --require-approval "never" --concurrency 3 --progress bar yarn run v1.22.17 warning package.json: No license field $ cdk deploy --all --require-approval never --concurrency 3 --progress bar ✨ Synthesis time: 16.04s⚠️ The --concurrency flag only supports --progress "events". Switching to "events". relm-test-1 relm-test-1: deploying... relm-test-2: deploying... relm-test-2: creating CloudFormation changeset... relm-test-1: creating CloudFormation changeset... relm-test-1 | 0/3 | 4:57:19 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-1 User Initiated relm-test-1 | 0/3 | 4:57:24 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-1 User Initiated relm-test-1 | 0/3 | 4:57:30 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) relm-test-2 | 0/3 | 4:57:19 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-2 User Initiated relm-test-2 | 0/3 | 4:57:24 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-2 User Initiated relm-test-2 | 0/3 | 4:57:29 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) relm-test-2 | 0/3 | 4:57:29 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-1 | 0/3 | 4:57:30 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-1 | 0/3 | 4:57:30 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) Resource creation Initiated relm-test-1 | 0/3 | 4:57:32 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated relm-test-1 | 1/3 | 4:57:33 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-2 | 0/3 | 4:57:30 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) Resource creation Initiated relm-test-2 | 0/3 | 4:57:31 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated relm-test-2 | 1/3 | 4:57:32 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-2 | 2/3 | 4:57:41 PM | CREATE_COMPLETE | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) relm-test-2 | 3/3 | 4:57:43 PM | CREATE_COMPLETE | AWS::CloudFormation::Stack | relm-test-2 relm-test-1 | 2/3 | 4:57:41 PM | CREATE_COMPLETE | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) relm-test-1 | 3/3 | 4:57:43 PM | CREATE_COMPLETE | AWS::CloudFormation::Stack | relm-test-1 ✅ relm-test-1 ✨ Deployment time: 28.39s Stack ARN: arn:aws:cloudformation:us-east-1:XXXXXXXXXXXX:stack/relm-test-1/ffcdb210-a6fd-11ec-b05c-0a02909bf4fb ✨ Total time: 44.43s ✅ relm-test-2 ✨ Deployment time: 28.45s Outputs: relm-test-2.ExportsOutputRefTempTopic9C0CBD7CC97C6BE5 = arn:aws:sns:us-east-1:XXXXXXXXXXXX:relm-test-2-TempTopic9C0CBD7C-2ETJWELY3MFD Stack ARN: arn:aws:cloudformation:us-east-1:XXXXXXXXXXXX:stack/relm-test-2/ffbc7400-a6fd-11ec-ac95-0ea201c9d581 ✨ Total time: 44.49s relm-test-2B relm-test-2B: deploying... relm-test-2B: creating CloudFormation changeset... relm-test-2B | 0/4 | 4:57:47 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-2B User Initiated relm-test-2B | 0/4 | 4:57:58 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-2B User Initiated relm-test-2B | 0/4 | 4:58:04 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | TopicRole (TopicRole3526982D) relm-test-2B | 0/4 | 4:58:04 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-2B | 0/4 | 4:58:05 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | TopicRole (TopicRole3526982D) Resource creation Initiated relm-test-2B | 0/4 | 4:58:06 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated relm-test-2B | 1/4 | 4:58:07 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-2B | 2/4 | 4:58:19 PM | CREATE_COMPLETE | AWS::IAM::Role | TopicRole (TopicRole3526982D) relm-test-2B | 2/4 | 4:58:22 PM | CREATE_IN_PROGRESS | AWS::IAM::Policy | TopicRole/DefaultPolicy (TopicRoleDefaultPolicy489E2B68) relm-test-2B | 2/4 | 4:58:23 PM | CREATE_IN_PROGRESS | AWS::IAM::Policy | TopicRole/DefaultPolicy (TopicRoleDefaultPolicy489E2B68) Resource creation Initiated relm-test-2B | 3/4 | 4:58:36 PM | CREATE_COMPLETE | AWS::IAM::Policy | TopicRole/DefaultPolicy (TopicRoleDefaultPolicy489E2B68) relm-test-2B | 4/4 | 4:58:37 PM | CREATE_COMPLETE | AWS::CloudFormation::Stack | relm-test-2B ✅ relm-test-2B ✨ Deployment time: 54.71s Stack ARN: arn:aws:cloudformation:us-east-1:XXXXXXXXXXXX:stack/relm-test-2B/10b341d0-a6fe-11ec-a535-12d49b16bf9b ✨ Total time: 70.75s ✨ Done in 99.79s. ``` ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Reverts aws#19378 It breaks 4 integ tests: ``` ● security related changes without a CLI are expected to fail ... (node:7140) UnhandledPromiseRejectionWarning: Error: \"--require-approval\" is enabled and stack includes security-sensitive updates, but terminal (TTY) is not attached so we are unable to get a confirmation from the user ● update to stack in ROLLBACK_COMPLETE state will delete stack and create a new one expect(received).rejects.toThrow() Received promise resolved instead of rejected Resolved to value: "" at expect (../node_modules/expect/build/index.js:128:15) at expect (cli.integtest.ts:267:9) at block (../helpers/cdk.ts:131:13) at runMicrotasks (<anonymous>) at ResourcePool.using (../helpers/resource-pool.ts:44:14) at ../helpers/test-helpers.ts:36:14 ● stack in UPDATE_ROLLBACK_COMPLETE state can be updated expect(received).rejects.toThrow() Received promise resolved instead of rejected Resolved to value: "" at expect (../node_modules/expect/build/index.js:128:15) at expect (cli.integtest.ts:320:9) at runMicrotasks (<anonymous>) at ../helpers/cdk.ts:131:7 at ResourcePool.using (../helpers/resource-pool.ts:44:14) at ../helpers/test-helpers.ts:36:14 ● failed deploy does not hang ... (node:8336) UnhandledPromiseRejectionWarning: Error: The stack named cdktest-0m9jeq4rpbp-failed failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE: Property PolicyDocument cannot be empty. ``` Something around the handling of errors in the new async deployment.
Isn't it the other way around? The manual runs have security implications. This is a good feature, yet delayed by some obscure run by hand requirements. Do you have a process to improve this? |
Closes #1973 (reattempting #19378) Add `--concurrency` parameter to `cdk deploy` command to enable concurrent deployments while respecting stack dependencies. Concurrency mode will only work with `--progress events` due to the poor interaction of concurrent deployments and the progress bar rendering. ### Open Questions - [x] How best to write automated tests around this? Added unit and integration tests - [x] Should other commands (ex: `destroy`) support concurrency? Only supporting deploy command in this PR - [x] Any other concerns with this approach as it changes a key component of `cdk` - [x] How should this work with the `--exclusively` flag? Only check dependencies between requested stacks <details> <summary>Example Output (Success):</summary> <pre> $ yarn cdk deploy --all --require-approval "never" --concurrency 3 --progress bar yarn run v1.22.17 warning package.json: No license field $ cdk deploy --all --require-approval never --concurrency 3 --progress bar ✨ Synthesis time: 16.04s⚠️ The --concurrency flag only supports --progress "events". Switching to "events". relm-test-1 relm-test-1: deploying... relm-test-2: deploying... relm-test-2: creating CloudFormation changeset... relm-test-1: creating CloudFormation changeset... relm-test-1 | 0/3 | 4:57:19 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-1 User Initiated relm-test-1 | 0/3 | 4:57:24 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-1 User Initiated relm-test-1 | 0/3 | 4:57:30 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) relm-test-2 | 0/3 | 4:57:19 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-2 User Initiated relm-test-2 | 0/3 | 4:57:24 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-2 User Initiated relm-test-2 | 0/3 | 4:57:29 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) relm-test-2 | 0/3 | 4:57:29 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-1 | 0/3 | 4:57:30 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-1 | 0/3 | 4:57:30 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) Resource creation Initiated relm-test-1 | 0/3 | 4:57:32 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated relm-test-1 | 1/3 | 4:57:33 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-2 | 0/3 | 4:57:30 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) Resource creation Initiated relm-test-2 | 0/3 | 4:57:31 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated relm-test-2 | 1/3 | 4:57:32 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-2 | 2/3 | 4:57:41 PM | CREATE_COMPLETE | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) relm-test-2 | 3/3 | 4:57:43 PM | CREATE_COMPLETE | AWS::CloudFormation::Stack | relm-test-2 relm-test-1 | 2/3 | 4:57:41 PM | CREATE_COMPLETE | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) relm-test-1 | 3/3 | 4:57:43 PM | CREATE_COMPLETE | AWS::CloudFormation::Stack | relm-test-1 ✅ relm-test-1 ✨ Deployment time: 28.39s Stack ARN: arn:aws:cloudformation:us-east-1:XXXXXXXXXXXX:stack/relm-test-1/ffcdb210-a6fd-11ec-b05c-0a02909bf4fb ✨ Total time: 44.43s ✅ relm-test-2 ✨ Deployment time: 28.45s Outputs: relm-test-2.ExportsOutputRefTempTopic9C0CBD7CC97C6BE5 = arn:aws:sns:us-east-1:XXXXXXXXXXXX:relm-test-2-TempTopic9C0CBD7C-2ETJWELY3MFD Stack ARN: arn:aws:cloudformation:us-east-1:XXXXXXXXXXXX:stack/relm-test-2/ffbc7400-a6fd-11ec-ac95-0ea201c9d581 ✨ Total time: 44.49s relm-test-2B relm-test-2B: deploying... relm-test-2B: creating CloudFormation changeset... relm-test-2B | 0/4 | 4:57:47 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-2B User Initiated relm-test-2B | 0/4 | 4:57:58 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-2B User Initiated relm-test-2B | 0/4 | 4:58:04 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | TopicRole (TopicRole3526982D) relm-test-2B | 0/4 | 4:58:04 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-2B | 0/4 | 4:58:05 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | TopicRole (TopicRole3526982D) Resource creation Initiated relm-test-2B | 0/4 | 4:58:06 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated relm-test-2B | 1/4 | 4:58:07 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-2B | 2/4 | 4:58:19 PM | CREATE_COMPLETE | AWS::IAM::Role | TopicRole (TopicRole3526982D) relm-test-2B | 2/4 | 4:58:22 PM | CREATE_IN_PROGRESS | AWS::IAM::Policy | TopicRole/DefaultPolicy (TopicRoleDefaultPolicy489E2B68) relm-test-2B | 2/4 | 4:58:23 PM | CREATE_IN_PROGRESS | AWS::IAM::Policy | TopicRole/DefaultPolicy (TopicRoleDefaultPolicy489E2B68) Resource creation Initiated relm-test-2B | 3/4 | 4:58:36 PM | CREATE_COMPLETE | AWS::IAM::Policy | TopicRole/DefaultPolicy (TopicRoleDefaultPolicy489E2B68) relm-test-2B | 4/4 | 4:58:37 PM | CREATE_COMPLETE | AWS::CloudFormation::Stack | relm-test-2B ✅ relm-test-2B ✨ Deployment time: 54.71s Stack ARN: arn:aws:cloudformation:us-east-1:XXXXXXXXXXXX:stack/relm-test-2B/10b341d0-a6fe-11ec-a535-12d49b16bf9b ✨ Total time: 70.75s ✨ Done in 99.79s. </pre> </details> <details> <summary>Example Output (Failure):</summary> <pre> yarn run v1.22.18 warning package.json: No license field $ cdk deploy --all --require-approval never --concurrency 3 --progress bar ✨ Synthesis time: 16.18s⚠️ The --concurrency flag only supports --progress "events". Switching to "events". relm-broken-1 relm-broken-1: deploying... relm-broken-2 relm-broken-2: deploying... relm-test-1: deploying... relm-test-1: creating CloudFormation changeset... relm-broken-1: creating CloudFormation changeset... relm-broken-2: creating CloudFormation changeset... relm-broken-2 | 0/3 | 9:12:48 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-broken-2 User Initiated relm-broken-2 | 0/3 | 9:12:53 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-broken-2 User Initiated relm-broken-1 | 0/3 | 9:12:48 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-broken-1 User Initiated relm-broken-1 | 0/3 | 9:12:53 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-broken-1 User Initiated relm-test-1 | 0/3 | 9:12:48 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-1 User Initiated relm-test-1 | 0/3 | 9:12:54 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-1 User Initiated relm-test-1 | 0/3 | 9:12:59 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TestTopic (TestTopic339EC197) relm-test-1 | 0/3 | 9:12:59 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-1 | 0/3 | 9:13:00 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TestTopic (TestTopic339EC197) Resource creation Initiated relm-test-1 | 0/3 | 9:13:01 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated relm-test-1 | 1/3 | 9:13:02 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-broken-2 | 0/3 | 9:12:59 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TestTopic (TestTopic339EC197) relm-broken-2 | 0/3 | 9:12:59 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-broken-2 | 0/3 | 9:13:00 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TestTopic (TestTopic339EC197) Resource creation Initiated relm-broken-2 | 0/3 | 9:13:02 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated relm-broken-2 | 1/3 | 9:13:02 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-broken-1 | 0/3 | 9:13:04 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-broken-1 | 0/3 | 9:13:04 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TestTopic (TestTopic339EC197) relm-broken-1 | 0/3 | 9:13:04 PM | CREATE_FAILED | AWS::SNS::Topic | TestTopic (TestTopic339EC197) TestTopic already exists in stack arn:aws:cloudformation:us-east-1:__ACCOUNT_ID__:stack/relm-broken-2/79fc1770-cc10-11ec-8279-0a02b75d1237 new Topic (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/aws-sns/lib/topic.ts:102:22) \_ new BrokenStack (/Users/relm/Development/aws-cdk-test-stack/lib/broken-stack.ts:11:18) \_ Object.<anonymous> (/Users/relm/Development/aws-cdk-test-stack/bin/aws-cdk-test-stack.ts:12:1) \_ Module._compile (node:internal/modules/cjs/loader:1103:14) \_ Module.m._compile (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/index.ts:1455:23) \_ Module._extensions..js (node:internal/modules/cjs/loader:1157:10) \_ Object.require.extensions.<computed> [as .ts] (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/index.ts:1458:12) \_ Module.load (node:internal/modules/cjs/loader:981:32) \_ Function.Module._load (node:internal/modules/cjs/loader:822:12) \_ Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) \_ phase4 (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:567:12) \_ bootstrap (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:85:10) \_ main (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:54:10) \_ Object.<anonymous> (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:717:3) \_ Module._compile (node:internal/modules/cjs/loader:1103:14) \_ Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10) \_ Module.load (node:internal/modules/cjs/loader:981:32) \_ Function.Module._load (node:internal/modules/cjs/loader:822:12) \_ Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) \_ node:internal/main/run_main_module:17:47 relm-broken-1 | 0/3 | 9:13:05 PM | CREATE_FAILED | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation cancelled new MetadataResource (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/private/metadata-resource.ts:22:24) \_ /Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/private/synthesis.ts:166:5 \_ visit (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/private/synthesis.ts:231:5) \_ visit (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/private/synthesis.ts:227:5) \_ injectMetadataResources (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/private/synthesis.ts:157:3) \_ Object.synthesize (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/private/synthesis.ts:18:3) \_ App.synth (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/stage.ts:180:23) \_ process.<anonymous> (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/app.ts:131:45) \_ Object.onceWrapper (node:events:646:26) \_ process.emit (node:events:526:28) \_ process.emit (node:domain:475:12) \_ process.emit.sharedData.processEmitHook.installedValue [as emit] (/Users/relm/Development/aws-cdk-test-stack/node_modules/@cspotcode/source-map-support/source-map-support.js:613:40) relm-broken-1 | 0/3 | 9:13:06 PM | ROLLBACK_IN_PROGRESS | AWS::CloudFormation::Stack | relm-broken-1 The following resource(s) failed to create: [TestTopic339EC197, CDKMetadata]. Rollback requested by user. relm-broken-1 | 1/3 | 9:13:10 PM | DELETE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-broken-1 | 2/3 | 9:13:10 PM | DELETE_COMPLETE | AWS::SNS::Topic | TestTopic (TestTopic339EC197) relm-broken-1 | 3/3 | 9:13:11 PM | ROLLBACK_COMPLETE | AWS::CloudFormation::Stack | relm-broken-1 relm-broken-2 | 2/3 | 9:13:11 PM | CREATE_COMPLETE | AWS::SNS::Topic | TestTopic (TestTopic339EC197) relm-broken-2 | 3/3 | 9:13:12 PM | CREATE_COMPLETE | AWS::CloudFormation::Stack | relm-broken-2 relm-test-1 | 2/3 | 9:13:10 PM | CREATE_COMPLETE | AWS::SNS::Topic | TestTopic (TestTopic339EC197) Failed resources: relm-broken-1 | 9:13:04 PM | CREATE_FAILED | AWS::SNS::Topic | TestTopic (TestTopic339EC197) TestTopic already exists in stack arn:aws:cloudformation:us-east-1:__ACCOUNT_ID__:stack/relm-broken-2/79fc1770-cc10-11ec-8279-0a02b75d1237 new Topic (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/aws-sns/lib/topic.ts:102:22) \_ new BrokenStack (/Users/relm/Development/aws-cdk-test-stack/lib/broken-stack.ts:11:18) \_ Object.<anonymous> (/Users/relm/Development/aws-cdk-test-stack/bin/aws-cdk-test-stack.ts:12:1) \_ Module._compile (node:internal/modules/cjs/loader:1103:14) \_ Module.m._compile (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/index.ts:1455:23) \_ Module._extensions..js (node:internal/modules/cjs/loader:1157:10) \_ Object.require.extensions.<computed> [as .ts] (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/index.ts:1458:12) \_ Module.load (node:internal/modules/cjs/loader:981:32) \_ Function.Module._load (node:internal/modules/cjs/loader:822:12) \_ Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) \_ phase4 (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:567:12) \_ bootstrap (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:85:10) \_ main (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:54:10) \_ Object.<anonymous> (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:717:3) \_ Module._compile (node:internal/modules/cjs/loader:1103:14) \_ Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10) \_ Module.load (node:internal/modules/cjs/loader:981:32) \_ Function.Module._load (node:internal/modules/cjs/loader:822:12) \_ Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) \_ node:internal/main/run_main_module:17:47 ❌ relm-broken-1 failed: Error: The stack named relm-broken-1 failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE at Object.waitForStackDeploy (/Users/relm/Development/aws-cdk/packages/aws-cdk/lib/api/util/cloudformation.ts:307:11) at processTicksAndRejections (node:internal/process/task_queues:96:5) at prepareAndExecuteChangeSet (/Users/relm/Development/aws-cdk/packages/aws-cdk/lib/api/deploy-stack.ts:355:26) at deployStack (/Users/relm/Development/aws-cdk/packages/aws-cdk/lib/cdk-toolkit.ts:229:24) at /Users/relm/Development/aws-cdk/packages/aws-cdk/lib/cdk-toolkit.ts:306:13 at run (/Users/relm/Development/aws-cdk/node_modules/p-queue/dist/index.js:163:29) /Users/relm/Development/aws-cdk/packages/aws-cdk/lib/api/util/cloudformation.ts:307 throw new Error(`The stack named ${stackName} failed creation, it may need to be manually deleted from the AWS console: ${status}`); ^ Error: The stack named relm-broken-1 failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE at Object.waitForStackDeploy (/Users/relm/Development/aws-cdk/packages/aws-cdk/lib/api/util/cloudformation.ts:307:11) at processTicksAndRejections (node:internal/process/task_queues:96:5) at prepareAndExecuteChangeSet (/Users/relm/Development/aws-cdk/packages/aws-cdk/lib/api/deploy-stack.ts:355:26) at deployStack (/Users/relm/Development/aws-cdk/packages/aws-cdk/lib/cdk-toolkit.ts:229:24) at /Users/relm/Development/aws-cdk/packages/aws-cdk/lib/cdk-toolkit.ts:306:13 at run (/Users/relm/Development/aws-cdk/node_modules/p-queue/dist/index.js:163:29) error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. </pre> </details> ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Closes aws#1973 (reattempting aws#19378) Add `--concurrency` parameter to `cdk deploy` command to enable concurrent deployments while respecting stack dependencies. Concurrency mode will only work with `--progress events` due to the poor interaction of concurrent deployments and the progress bar rendering. ### Open Questions - [x] How best to write automated tests around this? Added unit and integration tests - [x] Should other commands (ex: `destroy`) support concurrency? Only supporting deploy command in this PR - [x] Any other concerns with this approach as it changes a key component of `cdk` - [x] How should this work with the `--exclusively` flag? Only check dependencies between requested stacks <details> <summary>Example Output (Success):</summary> <pre> $ yarn cdk deploy --all --require-approval "never" --concurrency 3 --progress bar yarn run v1.22.17 warning package.json: No license field $ cdk deploy --all --require-approval never --concurrency 3 --progress bar ✨ Synthesis time: 16.04s⚠️ The --concurrency flag only supports --progress "events". Switching to "events". relm-test-1 relm-test-1: deploying... relm-test-2: deploying... relm-test-2: creating CloudFormation changeset... relm-test-1: creating CloudFormation changeset... relm-test-1 | 0/3 | 4:57:19 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-1 User Initiated relm-test-1 | 0/3 | 4:57:24 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-1 User Initiated relm-test-1 | 0/3 | 4:57:30 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) relm-test-2 | 0/3 | 4:57:19 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-2 User Initiated relm-test-2 | 0/3 | 4:57:24 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-2 User Initiated relm-test-2 | 0/3 | 4:57:29 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) relm-test-2 | 0/3 | 4:57:29 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-1 | 0/3 | 4:57:30 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-1 | 0/3 | 4:57:30 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) Resource creation Initiated relm-test-1 | 0/3 | 4:57:32 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated relm-test-1 | 1/3 | 4:57:33 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-2 | 0/3 | 4:57:30 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) Resource creation Initiated relm-test-2 | 0/3 | 4:57:31 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated relm-test-2 | 1/3 | 4:57:32 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-2 | 2/3 | 4:57:41 PM | CREATE_COMPLETE | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) relm-test-2 | 3/3 | 4:57:43 PM | CREATE_COMPLETE | AWS::CloudFormation::Stack | relm-test-2 relm-test-1 | 2/3 | 4:57:41 PM | CREATE_COMPLETE | AWS::SNS::Topic | TempTopic (TempTopic9C0CBD7C) relm-test-1 | 3/3 | 4:57:43 PM | CREATE_COMPLETE | AWS::CloudFormation::Stack | relm-test-1 ✅ relm-test-1 ✨ Deployment time: 28.39s Stack ARN: arn:aws:cloudformation:us-east-1:XXXXXXXXXXXX:stack/relm-test-1/ffcdb210-a6fd-11ec-b05c-0a02909bf4fb ✨ Total time: 44.43s ✅ relm-test-2 ✨ Deployment time: 28.45s Outputs: relm-test-2.ExportsOutputRefTempTopic9C0CBD7CC97C6BE5 = arn:aws:sns:us-east-1:XXXXXXXXXXXX:relm-test-2-TempTopic9C0CBD7C-2ETJWELY3MFD Stack ARN: arn:aws:cloudformation:us-east-1:XXXXXXXXXXXX:stack/relm-test-2/ffbc7400-a6fd-11ec-ac95-0ea201c9d581 ✨ Total time: 44.49s relm-test-2B relm-test-2B: deploying... relm-test-2B: creating CloudFormation changeset... relm-test-2B | 0/4 | 4:57:47 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-2B User Initiated relm-test-2B | 0/4 | 4:57:58 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-2B User Initiated relm-test-2B | 0/4 | 4:58:04 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | TopicRole (TopicRole3526982D) relm-test-2B | 0/4 | 4:58:04 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-2B | 0/4 | 4:58:05 PM | CREATE_IN_PROGRESS | AWS::IAM::Role | TopicRole (TopicRole3526982D) Resource creation Initiated relm-test-2B | 0/4 | 4:58:06 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated relm-test-2B | 1/4 | 4:58:07 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-2B | 2/4 | 4:58:19 PM | CREATE_COMPLETE | AWS::IAM::Role | TopicRole (TopicRole3526982D) relm-test-2B | 2/4 | 4:58:22 PM | CREATE_IN_PROGRESS | AWS::IAM::Policy | TopicRole/DefaultPolicy (TopicRoleDefaultPolicy489E2B68) relm-test-2B | 2/4 | 4:58:23 PM | CREATE_IN_PROGRESS | AWS::IAM::Policy | TopicRole/DefaultPolicy (TopicRoleDefaultPolicy489E2B68) Resource creation Initiated relm-test-2B | 3/4 | 4:58:36 PM | CREATE_COMPLETE | AWS::IAM::Policy | TopicRole/DefaultPolicy (TopicRoleDefaultPolicy489E2B68) relm-test-2B | 4/4 | 4:58:37 PM | CREATE_COMPLETE | AWS::CloudFormation::Stack | relm-test-2B ✅ relm-test-2B ✨ Deployment time: 54.71s Stack ARN: arn:aws:cloudformation:us-east-1:XXXXXXXXXXXX:stack/relm-test-2B/10b341d0-a6fe-11ec-a535-12d49b16bf9b ✨ Total time: 70.75s ✨ Done in 99.79s. </pre> </details> <details> <summary>Example Output (Failure):</summary> <pre> yarn run v1.22.18 warning package.json: No license field $ cdk deploy --all --require-approval never --concurrency 3 --progress bar ✨ Synthesis time: 16.18s⚠️ The --concurrency flag only supports --progress "events". Switching to "events". relm-broken-1 relm-broken-1: deploying... relm-broken-2 relm-broken-2: deploying... relm-test-1: deploying... relm-test-1: creating CloudFormation changeset... relm-broken-1: creating CloudFormation changeset... relm-broken-2: creating CloudFormation changeset... relm-broken-2 | 0/3 | 9:12:48 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-broken-2 User Initiated relm-broken-2 | 0/3 | 9:12:53 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-broken-2 User Initiated relm-broken-1 | 0/3 | 9:12:48 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-broken-1 User Initiated relm-broken-1 | 0/3 | 9:12:53 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-broken-1 User Initiated relm-test-1 | 0/3 | 9:12:48 PM | REVIEW_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-1 User Initiated relm-test-1 | 0/3 | 9:12:54 PM | CREATE_IN_PROGRESS | AWS::CloudFormation::Stack | relm-test-1 User Initiated relm-test-1 | 0/3 | 9:12:59 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TestTopic (TestTopic339EC197) relm-test-1 | 0/3 | 9:12:59 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-test-1 | 0/3 | 9:13:00 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TestTopic (TestTopic339EC197) Resource creation Initiated relm-test-1 | 0/3 | 9:13:01 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated relm-test-1 | 1/3 | 9:13:02 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-broken-2 | 0/3 | 9:12:59 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TestTopic (TestTopic339EC197) relm-broken-2 | 0/3 | 9:12:59 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-broken-2 | 0/3 | 9:13:00 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TestTopic (TestTopic339EC197) Resource creation Initiated relm-broken-2 | 0/3 | 9:13:02 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation Initiated relm-broken-2 | 1/3 | 9:13:02 PM | CREATE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-broken-1 | 0/3 | 9:13:04 PM | CREATE_IN_PROGRESS | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-broken-1 | 0/3 | 9:13:04 PM | CREATE_IN_PROGRESS | AWS::SNS::Topic | TestTopic (TestTopic339EC197) relm-broken-1 | 0/3 | 9:13:04 PM | CREATE_FAILED | AWS::SNS::Topic | TestTopic (TestTopic339EC197) TestTopic already exists in stack arn:aws:cloudformation:us-east-1:__ACCOUNT_ID__:stack/relm-broken-2/79fc1770-cc10-11ec-8279-0a02b75d1237 new Topic (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/aws-sns/lib/topic.ts:102:22) \_ new BrokenStack (/Users/relm/Development/aws-cdk-test-stack/lib/broken-stack.ts:11:18) \_ Object.<anonymous> (/Users/relm/Development/aws-cdk-test-stack/bin/aws-cdk-test-stack.ts:12:1) \_ Module._compile (node:internal/modules/cjs/loader:1103:14) \_ Module.m._compile (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/index.ts:1455:23) \_ Module._extensions..js (node:internal/modules/cjs/loader:1157:10) \_ Object.require.extensions.<computed> [as .ts] (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/index.ts:1458:12) \_ Module.load (node:internal/modules/cjs/loader:981:32) \_ Function.Module._load (node:internal/modules/cjs/loader:822:12) \_ Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) \_ phase4 (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:567:12) \_ bootstrap (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:85:10) \_ main (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:54:10) \_ Object.<anonymous> (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:717:3) \_ Module._compile (node:internal/modules/cjs/loader:1103:14) \_ Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10) \_ Module.load (node:internal/modules/cjs/loader:981:32) \_ Function.Module._load (node:internal/modules/cjs/loader:822:12) \_ Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) \_ node:internal/main/run_main_module:17:47 relm-broken-1 | 0/3 | 9:13:05 PM | CREATE_FAILED | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) Resource creation cancelled new MetadataResource (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/private/metadata-resource.ts:22:24) \_ /Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/private/synthesis.ts:166:5 \_ visit (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/private/synthesis.ts:231:5) \_ visit (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/private/synthesis.ts:227:5) \_ injectMetadataResources (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/private/synthesis.ts:157:3) \_ Object.synthesize (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/private/synthesis.ts:18:3) \_ App.synth (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/stage.ts:180:23) \_ process.<anonymous> (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/core/lib/app.ts:131:45) \_ Object.onceWrapper (node:events:646:26) \_ process.emit (node:events:526:28) \_ process.emit (node:domain:475:12) \_ process.emit.sharedData.processEmitHook.installedValue [as emit] (/Users/relm/Development/aws-cdk-test-stack/node_modules/@cspotcode/source-map-support/source-map-support.js:613:40) relm-broken-1 | 0/3 | 9:13:06 PM | ROLLBACK_IN_PROGRESS | AWS::CloudFormation::Stack | relm-broken-1 The following resource(s) failed to create: [TestTopic339EC197, CDKMetadata]. Rollback requested by user. relm-broken-1 | 1/3 | 9:13:10 PM | DELETE_COMPLETE | AWS::CDK::Metadata | CDKMetadata/Default (CDKMetadata) relm-broken-1 | 2/3 | 9:13:10 PM | DELETE_COMPLETE | AWS::SNS::Topic | TestTopic (TestTopic339EC197) relm-broken-1 | 3/3 | 9:13:11 PM | ROLLBACK_COMPLETE | AWS::CloudFormation::Stack | relm-broken-1 relm-broken-2 | 2/3 | 9:13:11 PM | CREATE_COMPLETE | AWS::SNS::Topic | TestTopic (TestTopic339EC197) relm-broken-2 | 3/3 | 9:13:12 PM | CREATE_COMPLETE | AWS::CloudFormation::Stack | relm-broken-2 relm-test-1 | 2/3 | 9:13:10 PM | CREATE_COMPLETE | AWS::SNS::Topic | TestTopic (TestTopic339EC197) Failed resources: relm-broken-1 | 9:13:04 PM | CREATE_FAILED | AWS::SNS::Topic | TestTopic (TestTopic339EC197) TestTopic already exists in stack arn:aws:cloudformation:us-east-1:__ACCOUNT_ID__:stack/relm-broken-2/79fc1770-cc10-11ec-8279-0a02b75d1237 new Topic (/Users/relm/Development/aws-cdk/packages/aws-cdk-lib/aws-sns/lib/topic.ts:102:22) \_ new BrokenStack (/Users/relm/Development/aws-cdk-test-stack/lib/broken-stack.ts:11:18) \_ Object.<anonymous> (/Users/relm/Development/aws-cdk-test-stack/bin/aws-cdk-test-stack.ts:12:1) \_ Module._compile (node:internal/modules/cjs/loader:1103:14) \_ Module.m._compile (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/index.ts:1455:23) \_ Module._extensions..js (node:internal/modules/cjs/loader:1157:10) \_ Object.require.extensions.<computed> [as .ts] (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/index.ts:1458:12) \_ Module.load (node:internal/modules/cjs/loader:981:32) \_ Function.Module._load (node:internal/modules/cjs/loader:822:12) \_ Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) \_ phase4 (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:567:12) \_ bootstrap (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:85:10) \_ main (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:54:10) \_ Object.<anonymous> (/Users/relm/Development/aws-cdk-test-stack/node_modules/ts-node/src/bin.ts:717:3) \_ Module._compile (node:internal/modules/cjs/loader:1103:14) \_ Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10) \_ Module.load (node:internal/modules/cjs/loader:981:32) \_ Function.Module._load (node:internal/modules/cjs/loader:822:12) \_ Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) \_ node:internal/main/run_main_module:17:47 ❌ relm-broken-1 failed: Error: The stack named relm-broken-1 failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE at Object.waitForStackDeploy (/Users/relm/Development/aws-cdk/packages/aws-cdk/lib/api/util/cloudformation.ts:307:11) at processTicksAndRejections (node:internal/process/task_queues:96:5) at prepareAndExecuteChangeSet (/Users/relm/Development/aws-cdk/packages/aws-cdk/lib/api/deploy-stack.ts:355:26) at deployStack (/Users/relm/Development/aws-cdk/packages/aws-cdk/lib/cdk-toolkit.ts:229:24) at /Users/relm/Development/aws-cdk/packages/aws-cdk/lib/cdk-toolkit.ts:306:13 at run (/Users/relm/Development/aws-cdk/node_modules/p-queue/dist/index.js:163:29) /Users/relm/Development/aws-cdk/packages/aws-cdk/lib/api/util/cloudformation.ts:307 throw new Error(`The stack named ${stackName} failed creation, it may need to be manually deleted from the AWS console: ${status}`); ^ Error: The stack named relm-broken-1 failed creation, it may need to be manually deleted from the AWS console: ROLLBACK_COMPLETE at Object.waitForStackDeploy (/Users/relm/Development/aws-cdk/packages/aws-cdk/lib/api/util/cloudformation.ts:307:11) at processTicksAndRejections (node:internal/process/task_queues:96:5) at prepareAndExecuteChangeSet (/Users/relm/Development/aws-cdk/packages/aws-cdk/lib/api/deploy-stack.ts:355:26) at deployStack (/Users/relm/Development/aws-cdk/packages/aws-cdk/lib/cdk-toolkit.ts:229:24) at /Users/relm/Development/aws-cdk/packages/aws-cdk/lib/cdk-toolkit.ts:306:13 at run (/Users/relm/Development/aws-cdk/node_modules/p-queue/dist/index.js:163:29) error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. </pre> </details> ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@relm923 Out of interest does concurrency work down to the nested stack level or only the top level stack? |
Closes #1973
Add
--concurrency
parameter tocdk deploy
command to enable concurrent deployments while respecting stack dependencies. Concurrency mode will only work with--progress events
due to the poor interaction of concurrent deployments and the progress bar rendering.Open Questions
Added unit and integration tests
destroy
) support concurrency?Only supporting deploy command in this PR
cdk
--exclusively
flag?Only check dependencies between requested stacks
Example output:
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license