From 37c79b94e3093b0cecc21c77e8bc79579ea002e5 Mon Sep 17 00:00:00 2001 From: Michael Sambol Date: Wed, 10 Jan 2024 11:06:18 -0600 Subject: [PATCH 1/3] feat(cli): option to ignore no stacks (#28387) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I'm new to development on this package—any feedback regarding testing is appreciated. Closes #28371. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../cli-integ/resources/cdk-apps/app/app.js | 3 ++ .../tests/cli-integ-tests/cli.integtest.ts | 19 +++++++++ packages/aws-cdk/README.md | 14 +++++++ .../aws-cdk/lib/api/cxapp/cloud-assembly.ts | 12 +++++- packages/aws-cdk/lib/api/deployments.ts | 7 ++++ packages/aws-cdk/lib/cdk-toolkit.ts | 17 ++++++-- packages/aws-cdk/lib/cli.ts | 4 +- packages/aws-cdk/lib/settings.ts | 1 + .../aws-cdk/test/api/cloud-assembly.test.ts | 40 +++++++++++++++++++ 9 files changed, 112 insertions(+), 5 deletions(-) diff --git a/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js b/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js index 048e6fabd5165..eeb1ad83673e2 100755 --- a/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js +++ b/packages/@aws-cdk-testing/cli-integ/resources/cdk-apps/app/app.js @@ -492,6 +492,9 @@ switch (stackSet) { stage.synth({ validateOnSynthesis: true }); break; + case 'stage-with-no-stacks': + break; + default: throw new Error(`Unrecognized INTEG_STACK_SET: '${stackSet}'`); } diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/cli.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/cli.integtest.ts index ccdf07b166f33..b64a3c085bd34 100644 --- a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/cli.integtest.ts +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/cli.integtest.ts @@ -780,6 +780,25 @@ integTest('deploy stack without resource', withDefaultFixture(async (fixture) => .rejects.toThrow('conditional-resource does not exist'); })); +integTest('deploy no stacks with --ignore-no-stacks', withDefaultFixture(async (fixture) => { + // empty array for stack names + await fixture.cdkDeploy([], { + options: ['--ignore-no-stacks'], + modEnv: { + INTEG_STACK_SET: 'stage-with-no-stacks', + }, + }); +})); + +integTest('deploy no stacks error', withDefaultFixture(async (fixture) => { + // empty array for stack names + await expect(fixture.cdkDeploy([], { + modEnv: { + INTEG_STACK_SET: 'stage-with-no-stacks', + }, + })).rejects.toThrow('exited with error'); +})); + integTest('IAM diff', withDefaultFixture(async (fixture) => { const output = await fixture.cdk(['diff', fixture.fullStackName('iam-test')]); diff --git a/packages/aws-cdk/README.md b/packages/aws-cdk/README.md index 7642508136e9d..c16acb3f690ab 100644 --- a/packages/aws-cdk/README.md +++ b/packages/aws-cdk/README.md @@ -386,6 +386,20 @@ $ cdk deploy --method=prepare-change-set --change-set-name MyChangeSetName For more control over when stack changes are deployed, the CDK can generate a CloudFormation change set but not execute it. +#### Ignore No Stacks + +You may have an app with multiple environments, e.g., dev and prod. When starting +development, your prod app may not have any resources or the resources are commented +out. In this scenario, you will receive an error message stating that the app has no +stacks. + +To bypass this error messages, you can pass the `--ignore-no-stacks` flag to the +`deploy` command: + +```console +$ cdk deploy --ignore-no-stacks +``` + #### Hotswap deployments for faster development You can pass the `--hotswap` flag to the `deploy` command: diff --git a/packages/aws-cdk/lib/api/cxapp/cloud-assembly.ts b/packages/aws-cdk/lib/api/cxapp/cloud-assembly.ts index 84cfa775e0cf7..c797e3a3492c4 100644 --- a/packages/aws-cdk/lib/api/cxapp/cloud-assembly.ts +++ b/packages/aws-cdk/lib/api/cxapp/cloud-assembly.ts @@ -38,9 +38,16 @@ export interface SelectStacksOptions { extend?: ExtendedStackSelection; /** - * The behavior if if no selectors are privided. + * The behavior if if no selectors are provided. */ defaultBehavior: DefaultSelection; + + /** + * Whether to deploy if the app contains no stacks. + * + * @default false + */ + ignoreNoStacks?: boolean; } /** @@ -100,6 +107,9 @@ export class CloudAssembly { const patterns = sanitizePatterns(selector.patterns); if (stacks.length === 0) { + if (options.ignoreNoStacks) { + return new StackCollection(this, []); + } throw new Error('This app contains no stacks'); } diff --git a/packages/aws-cdk/lib/api/deployments.ts b/packages/aws-cdk/lib/api/deployments.ts index 4da0d27837c92..09264f393fc3c 100644 --- a/packages/aws-cdk/lib/api/deployments.ts +++ b/packages/aws-cdk/lib/api/deployments.ts @@ -199,6 +199,13 @@ export interface DeployStackOptions { * @default true To remain backward compatible. */ readonly assetParallelism?: boolean; + + /** + * Whether to deploy if the app contains no stacks. + * + * @default false + */ + ignoreNoStacks?: boolean; } interface AssetOptions { diff --git a/packages/aws-cdk/lib/cdk-toolkit.ts b/packages/aws-cdk/lib/cdk-toolkit.ts index 43a2638154a3a..4a8a40949ab4d 100644 --- a/packages/aws-cdk/lib/cdk-toolkit.ts +++ b/packages/aws-cdk/lib/cdk-toolkit.ts @@ -200,7 +200,8 @@ export class CdkToolkit { } const startSynthTime = new Date().getTime(); - const stackCollection = await this.selectStacksForDeploy(options.selector, options.exclusively, options.cacheCloudAssembly); + const stackCollection = await this.selectStacksForDeploy(options.selector, options.exclusively, + options.cacheCloudAssembly, options.ignoreNoStacks); const elapsedSynthTime = new Date().getTime() - startSynthTime; print('\n✨ Synthesis time: %ss\n', formatTime(elapsedSynthTime)); @@ -317,6 +318,7 @@ export class CdkToolkit { hotswap: options.hotswap, extraUserAgent: options.extraUserAgent, assetParallelism: options.assetParallelism, + ignoreNoStacks: options.ignoreNoStacks, }); const message = result.noOp @@ -491,7 +493,7 @@ export class CdkToolkit { } public async import(options: ImportOptions) { - const stacks = await this.selectStacksForDeploy(options.selector, true, true); + const stacks = await this.selectStacksForDeploy(options.selector, true, true, false); if (stacks.stackCount > 1) { throw new Error(`Stack selection is ambiguous, please choose a specific stack for import [${stacks.stackArtifacts.map(x => x.id).join(', ')}]`); @@ -741,11 +743,13 @@ export class CdkToolkit { return stacks; } - private async selectStacksForDeploy(selector: StackSelector, exclusively?: boolean, cacheCloudAssembly?: boolean): Promise { + private async selectStacksForDeploy(selector: StackSelector, exclusively?: boolean, + cacheCloudAssembly?: boolean, ignoreNoStacks?: boolean): Promise { const assembly = await this.assembly(cacheCloudAssembly); const stacks = await assembly.selectStacks(selector, { extend: exclusively ? ExtendedStackSelection.None : ExtendedStackSelection.Upstream, defaultBehavior: DefaultSelection.OnlySingle, + ignoreNoStacks, }); this.validateStacksSelected(stacks, selector.patterns); @@ -1159,6 +1163,13 @@ export interface DeployOptions extends CfnDeployOptions, WatchOptions { * @default AssetBuildTime.ALL_BEFORE_DEPLOY */ readonly assetBuildTime?: AssetBuildTime; + + /** + * Whether to deploy if the app contains no stacks. + * + * @default false + */ + readonly ignoreNoStacks?: boolean; } export interface ImportOptions extends CfnDeployOptions { diff --git a/packages/aws-cdk/lib/cli.ts b/packages/aws-cdk/lib/cli.ts index df2f3c24fa569..5574f487a496c 100644 --- a/packages/aws-cdk/lib/cli.ts +++ b/packages/aws-cdk/lib/cli.ts @@ -172,7 +172,8 @@ async function parseCommandLineArguments(args: string[]) { }) .option('concurrency', { type: 'number', desc: 'Maximum number of simultaneous deployments (dependency permitting) to execute.', default: 1, requiresArg: true }) .option('asset-parallelism', { type: 'boolean', desc: 'Whether to build/publish assets in parallel' }) - .option('asset-prebuild', { type: 'boolean', desc: 'Whether to build all assets before deploying the first stack (useful for failing Docker builds)', default: true }), + .option('asset-prebuild', { type: 'boolean', desc: 'Whether to build all assets before deploying the first stack (useful for failing Docker builds)', default: true }) + .option('ignore-no-stacks', { type: 'boolean', desc: 'Whether to deploy if the app contains no stacks', default: false }), ) .command('import [STACK]', 'Import existing resource(s) into the given STACK', (yargs: Argv) => yargs .option('execute', { type: 'boolean', desc: 'Whether to execute ChangeSet (--no-execute will NOT execute the ChangeSet)', default: true }) @@ -585,6 +586,7 @@ export async function exec(args: string[], synthesizer?: Synthesizer): Promise { expect(x.stackCount).toBe(2); }); +test('select behavior with no stacks and ignore stacks option', async() => { + // GIVEN + const cxasm = await testCloudAssemblyNoStacks(); + + // WHEN + const x = await cxasm.selectStacks({ patterns: [] }, { + defaultBehavior: DefaultSelection.AllStacks, + ignoreNoStacks: true, + }); + + // THEN + expect(x.stackCount).toBe(0); +}); + +test('select behavior with no stacks and no ignore stacks option', async() => { + // GIVEN + const cxasm = await testCloudAssemblyNoStacks(); + + // WHEN & THEN + await expect(cxasm.selectStacks({ patterns: [] }, { defaultBehavior: DefaultSelection.AllStacks, ignoreNoStacks: false })) + .rejects.toThrow('This app contains no stacks'); +}); + +test('select behavior with no stacks and default ignore stacks options (false)', async() => { + // GIVEN + const cxasm = await testCloudAssemblyNoStacks(); + + // WHEN & THEN + await expect(cxasm.selectStacks({ patterns: [] }, { defaultBehavior: DefaultSelection.AllStacks })) + .rejects.toThrow('This app contains no stacks'); +}); + async function testCloudAssembly({ env }: { env?: string, versionReporting?: boolean } = {}) { const cloudExec = new MockCloudExecutable({ stacks: [{ @@ -182,6 +214,14 @@ async function testCloudAssembly({ env }: { env?: string, versionReporting?: boo return cloudExec.synthesize(); } +async function testCloudAssemblyNoStacks() { + const cloudExec = new MockCloudExecutable({ + stacks: [], + }); + + return cloudExec.synthesize(); +} + async function testNestedCloudAssembly({ env }: { env?: string, versionReporting?: boolean } = {}) { const cloudExec = new MockCloudExecutable({ stacks: [{ From a04fe7a13405f7f58941c752f874fb67fcf163b0 Mon Sep 17 00:00:00 2001 From: philipws Date: Wed, 10 Jan 2024 17:33:33 +0000 Subject: [PATCH 2/3] docs: spelling grammar and brands for contributing doc (#28649) When reading through the CONTRIBUTING.md there was a few issues which confused me. These changes correct those so the next new contributor can read it more easily. Also, makes brand names consistent in the file and with the brands public name (E.g. "cloudformation" to "CloudFormation"). ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- CONTRIBUTING.md | 58 ++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 564695c76a0ec..7644c072eb899 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ The CDK is released under the [Apache license](http://aws.amazon.com/apache2.0/) Any code you submit will be released under that license. This document describes how to set up a development environment and submit your changes. Please -let us know if it's not up-to-date (even better, submit a PR with your corrections ;-)). +let us know if it's not up-to-date (even better, submit a PR with your corrections ;-)). - [Where To Contribute](#where-to-contribute) - [Demonstrating Value](#demonstrating-value) @@ -33,7 +33,7 @@ let us know if it's not up-to-date (even better, submit a PR with your correcti - [Tools](#tools-advanced) - [Linters](#linters) - [scripts/foreach.sh](#scriptsforeachsh) - - [Jetbrains support (WebStorm/IntelliJ)](#jetbrains-support-webstormintellij) + - [JetBrains support (WebStorm/IntelliJ)](#jetbrains-support-webstormintellij) - [Linking against this repository](#linking-against-this-repository) - [Running integration tests in parallel](#running-integration-tests-in-parallel) - [Visualizing dependencies in a CloudFormation Template](#visualizing-dependencies-in-a-cloudformation-template) @@ -100,11 +100,11 @@ Contributions are accepted through a number of channels, including direct pull r Here are some things we look at when evaluating a contribution: -1. Signal - Is there a github issue, or possibly multiple related ones, that the contribution addresses. Do the issues have a lot of engagement, such as comments, +1 reactions, etc that indicate that many users are affected by it? +1. Signal - Is there a GitHub issue, or possibly multiple related ones, that the contribution addresses. Do the issues have a lot of engagement, such as comments, +1 reactions, etc that indicate that many users are affected by it? 1. Size - Is the contribution limited to a relatively self-contained surface area? Is it broken up into the smallest possible unit of functionality that makes sense? 1. Priority - Does the contribution address an issue in, or add a new feature of, a service that has a high priority for coverage? These are generally core services most commonly used on AWS such as IAM, EC2, Lambda, and ECS. -1. Quality - Does the contribution take into account all of the guidance provided in our documentation regarding [design patterns](./docs/DESIGN_GUIDELINES.md), test coverage, and best practices as it relates to code within the aws-cdk repository? Does it also make an effort to follow patterns commonly used within the aws-cdk repository and not deviate unecessarily from these conventions? -1. Breaking Changes - Does the contribution introduce any risk for breaking existing users applications? Specifically, does it require any code changes or can it trigger any resource replacement in cloudformation that would result in downtime? +1. Quality - Does the contribution take into account all of the guidance provided in our documentation regarding [design patterns](./docs/DESIGN_GUIDELINES.md), test coverage, and best practices as it relates to code within the aws-cdk repository? Does it also make an effort to follow patterns commonly used within the aws-cdk repository and not deviate unnecessarily from these conventions? +1. Breaking Changes - Does the contribution introduce any risk for breaking existing users applications? Specifically, does it require any code changes or can it trigger any resource replacement in CloudFormation that would result in downtime? ### Demonstrating Value @@ -120,7 +120,7 @@ All of this information will help make it clear to reviewers why your contributi ### Publishing Your Own Package -This is by far the strongest signal you can give to the CDK team that a feature should be included within the core aws-cdk packages. A package published on npm, pypi, maven central, nuget, and github (for go) that has good documentation, a clear purpose, and an active group of users is a good indication that the functionality it provides is useful and should be examined for inclusion in the core aws-cdk packages. This may not be the goal of any given package, and some constructs and features do not provide functionality that should ever be vended as part of the core framework. However, if a package you own does include functionality that you and other users believe should be vended as part of the core CDK, we encourage making a pull request, or RFC if appropriate, proposing it's inclusion. +This is by far the strongest signal you can give to the CDK team that a feature should be included within the core aws-cdk packages. A package published on npm, PyPI, Maven Central, NuGet, and GitHub (for Go) that has good documentation, a clear purpose, and an active group of users is a good indication that the functionality it provides is useful and should be examined for inclusion in the core aws-cdk packages. This may not be the goal of any given package, and some constructs and features do not provide functionality that should ever be vended as part of the core framework. However, if a package you own does include functionality that you and other users believe should be vended as part of the core CDK, we encourage making a pull request, or RFC if appropriate, proposing its inclusion. #### Trust and Third Party Packages @@ -163,8 +163,8 @@ $ yarn install ``` We recommend that you use [Visual Studio Code](https://code.visualstudio.com/) to work on the CDK. -We use `eslint` to keep our code consistent in terms of style and reducing defects. We recommend installing -the [eslint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) as well. +We use `ESLint` to keep our code consistent in terms of style and reducing defects. We recommend installing +the [ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) as well. Windows, as a development environment, has known performance and compatibility issues. To help in this case, consider using [Gitpod](#gitpod) or [Amazon CodeCatalyst DevEnv](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/codecatalyst-service.html) instead. @@ -185,9 +185,9 @@ specific to the CDK. ### Building aws-cdk-lib -The full build of all of the packages within the repository can take a few minutes, about 20 when all tests are run. +The full build of all of the packages within the repository can take a few minutes, about 20 when all tests are run. Most contributions only require working on a single package, usually `aws-cdk-lib`. To build this package for the first -time, you can execute the following to build it and it's dependencies. +time, you can execute the following to build it and its dependencies. ```console $ npx lerna run build --scope=aws-cdk-lib @@ -299,7 +299,7 @@ eval $(gp env -e) ### Amazon CodeCatalyst Dev Environments Dev Environments are cloud-based development environments. -[Amazon CodeCatalyst](https://aws.amazon.com/codecatalyst/) allows you to checkout your linked Github +[Amazon CodeCatalyst](https://aws.amazon.com/codecatalyst/) allows you to checkout your linked GitHub repositories in your Dev Environments with your favorite local IDEs such as VSCode or JetBrains. Build up `aws-cdk-lib` as well as `framework-integ` when you enter your Dev Env: @@ -368,13 +368,13 @@ much more likely to give a PR for those issues prompt attention. In some cases, it is useful to seek feedback by iterating on a design document. This is useful when you plan a big change or feature, or you want advice on what would be the best path forward. -In many cases, the comments section of the relevant Github issue is sufficent for such discussion, and can be a good place to socialize and get feedback on what you plan to do. If the changes are significant in scope, require a longer form medium to communicate, or you just want to ensure that the core team agrees with your planned implementation before you submit it for review to avoid wasted work, there are a few different strategies you can pursue. +In many cases, the comments section of the relevant GitHub issue is sufficient for such discussion, and can be a good place to socialize and get feedback on what you plan to do. If the changes are significant in scope, require a longer form medium to communicate, or you just want to ensure that the core team agrees with your planned implementation before you submit it for review to avoid wasted work, there are a few different strategies you can pursue. 1. README driven development - This is the core team's preferred method for reviewing new APIs. Submit a draft PR with updates to the README for the package that you intend to change that clearly describes how the functionality will be used. For new L2s, include usage examples that cover common use cases and showcase the features of the API you're designing. The most important thing to consider for any feature is the public API and this will help to give a clear picture of what changes users can expect. -1. Write an [RFC](aws/aws-cdk-rfcs) - This is a process for discussing new functionality that is large in scope, may incur breaking changes, or may otherwise warrant discussion from multiple stakeholders on the core team or within the community. Spefically, it is a good place to discuss new features in the core CDK framework or the CLI that are unable to be decoupled from the core cdk codebase. -1. Publish a package - A separate package is the best place to demonstrate the value of new functionality that you believe should be included within the CDK core libraries. It not only illustrates a complete solution with it's entire API surface area available to review, it also proves that your design works! When publishing a package with the goal for eventual inclusion within aws-cdk-lib, make sure to follow our [design guidelines](./docs/DESIGN_GUIDELINES.md) wherever relevant. +1. Write an [RFC](aws/aws-cdk-rfcs) - This is a process for discussing new functionality that is large in scope, may incur breaking changes, or may otherwise warrant discussion from multiple stakeholders on the core team or within the community. Specifically, it is a good place to discuss new features in the core CDK framework or the CLI that are unable to be decoupled from the core cdk codebase. +1. Publish a package - A separate package is the best place to demonstrate the value of new functionality that you believe should be included within the CDK core libraries. It not only illustrates a complete solution with its entire API surface area available to review, it also proves that your design works! When publishing a package with the goal for eventual inclusion within aws-cdk-lib, make sure to follow our [design guidelines](./docs/DESIGN_GUIDELINES.md) wherever relevant. -Performing any of the above processes helps us to ensure that expectations are clearly set before a contribution is made. We want to ensure that everyone is able to contribute to the CDK ecosystem effectively. If you make a contribution that is ultimately not merged by into aws-cdk-lib, but you believe it should be, we encourage you to keep pursuing it. The scope of the core framework is intentionally limited to ensure that we can effectively maintain it's surface area and ensure code quality and reliablity over the long term. However, new patterns may emerge in the ecosystem that clearly provide better solutions than those currently in aws-cdk-lib. If your solutions gains popularity within the community, and you want us to re-evaluate it's inclusion, reach out to us on cdk.dev or create a github issue with a feature request and references to your package. See [demonstrating value](#demonstrating-value) for more information. +Performing any of the above processes helps us to ensure that expectations are clearly set before a contribution is made. We want to ensure that everyone is able to contribute to the CDK ecosystem effectively. If you make a contribution that is ultimately not merged by into aws-cdk-lib, but you believe it should be, we encourage you to keep pursuing it. The scope of the core framework is intentionally limited to ensure that we can effectively maintain its surface area and ensure code quality and reliability over the long term. However, new patterns may emerge in the ecosystem that clearly provide better solutions than those currently in aws-cdk-lib. If your solutions gains popularity within the community, and you want us to re-evaluate its inclusion, reach out to us on cdk.dev or create a GitHub issue with a feature request and references to your package. See [demonstrating value](#demonstrating-value) for more information. ### Step 3: Work your Magic @@ -428,7 +428,7 @@ new features and all fixes unless there is a good reason why one is not needed. All integration tests going forward should use the [IntegTest](https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/integ-tests-alpha/lib/test-case.ts#L148) construct. Over time we will be updating all of our existing tests to use this construct. It -allows for more control over configuring each tests as well as the ability to perform +allows for more control over configuring each test as well as the ability to perform assertions against the deployed infrastructure. ```ts @@ -586,14 +586,14 @@ CDK integration tests. > CDK core members can push to a branch on the AWS CDK repo (naming convention: `/`). * Create a [pull request on - Github](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork). + GitHub](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork). * Pull request title and message (and PR title and description) must adhere to [conventionalcommits](https://www.conventionalcommits.org). * The title must begin with `feat(module): title`, `fix(module): title`, `refactor(module): title` or `chore(module): title`. * `feat`: indicates a feature added (requires tests and README updates in principle, but can be suppressed) - * `fix`: indicates a bug fixes (requires tests in principle, but can be suppressed) + * `fix`: indicates a bug fix (requires tests in principle, but can be suppressed) * `docs`: indicates updated documentation (docstrings or Markdown files) * `refactor`: indicates a feature-preserving refactoring * `chore`: something without directly visible user benefit (does not end up in the CHANGELOG). Typically used for build scripts, config, or changes so minor they don't warrant showing up the CHANGELOG. @@ -869,7 +869,7 @@ preview version. For example, assume we add the method ```ts /** - * This methods grants awesome powers + * This method grants awesome powers */ grantAwesomePowerBeta1(); ``` @@ -881,20 +881,20 @@ change, we will add `grantAwesomePowerBeta2()` and deprecate ```ts /** -* This methods grants awesome powers to the given principal +* This method grants awesome powers to the given principal * * @param grantee The principal to grant powers to */ grantAwesomePowerBeta2(grantee: iam.IGrantable) /** -* This methods grants awesome powers +* This method grants awesome powers * @deprecated use grantAwesomePowerBeta2 */ grantAwesomePowerBeta1() ``` -When we decide its time to graduate the API, the latest preview version will +When we decide it's time to graduate the API, the latest preview version will be deprecated and the final version - `grantAwesomePower` will be added. ## Documentation @@ -905,7 +905,7 @@ the README for the `aws-ec2` module - https://docs.aws.amazon.com/cdk/api/latest ### Rosetta The README file contains code snippets written as typescript code. Code snippets typed in fenced code blocks -(such as `` ```ts ``) will be automatically extracted, compiled and translated to other languages when the +(such as `` ```ts ``) will be automatically extracted, compiled and translated to other languages during the [pack](#pack) step. We call this feature 'rosetta'. You can run rosetta on the aws-cdk-lib module (or any other module) by running: @@ -1045,16 +1045,16 @@ yarn lint The following linters are used: -- [eslint](#eslint) +- [ESLint](#eslint) - [pkglint](#pkglint) - [awslint](#awslint) -#### eslint +#### ESLint All packages in the repo use a standard base configuration found at [eslintrc.js](tools/@aws-cdk/cdk-build-tools/config/eslintrc.js). This can be customized for any package by modifying the `.eslintrc` file found at its root. -If you're using the VS Code and would like to see eslint violations on it, install the [eslint +If you're using the VS Code and would like to see ESLint violations on it, install the [ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint). #### pkglint @@ -1097,7 +1097,7 @@ Here are a few useful commands: evaluate only the rule specified [awslint README](./packages/awslint/README.md) for details on include/exclude rule patterns. -### Jetbrains support (WebStorm/IntelliJ) +### JetBrains support (WebStorm/IntelliJ) This project uses lerna and utilizes symlinks inside nested `node_modules` directories. You may encounter an issue during indexing where the IDE attempts to index these directories and keeps following links until the process runs out of @@ -1151,7 +1151,7 @@ Experimental packages are used to develop new constructs and experiment with the them as stable and including them within `aws-cdk-lib`. Once they are included in `aws-cdk-lib`, no more breaking api changes can be made. -When you want to build an alpha package (for example, `some-package-alpha`), you can execute the following in the root of the repository to build it and it's dependencies. +When you want to build an alpha package (for example, `some-package-alpha`), you can execute the following in the root of the repository to build it and its dependencies. ``` $ npx lerna run build --scope=@aws-cdk/some-package-alpha @@ -1288,7 +1288,7 @@ $ scripts/build-typescript.sh -w This does not do code generation and it does not do JSII checks and JSII assembly generation. Instead of doing a package-by-package ordered build, it compiles all `.ts` files in the repository all at once. This takes about the same time as it does to compile the biggest package all by itself, and on my machine is the difference between a 15 -CPU-minute build and a 20 CPU-second build. If you use this methods of recompiling and you want to run the test, you +CPU-minute build and a 20 CPU-second build. If you use this method of recompiling and you want to run the test, you have to disable the built-in rebuild functionality of `lerna run test`: ```shell From 0cada616bc5574ae7f3f7eba37e98ef4bc926bb3 Mon Sep 17 00:00:00 2001 From: Troy B <81539149+miiiak@users.noreply.github.com> Date: Wed, 10 Jan 2024 11:03:50 -0700 Subject: [PATCH 3/3] docs(route53): crossaccountrole scope-down guidance (#28624) Reference [issue 28596](https://github.com/aws/aws-cdk/issues/28596) The motivation is to help CDK builders understand how to take advantage of IAM scope-down capabilities to ensure least-privilege cross-account role access related to cross account zone delegation. The Cross Account Zone Delegation guidance currently includes reference to creating a crossAccountRole, but provides no suggestion on how to safely scope down the role for least-privilege access. We can and should provide this guidance. E.g. ``` const crossAccountRole = new iam.Role(this, 'CrossAccountRole', { // The role name must be predictable roleName: 'MyDelegationRole', // The other account assumedBy: new iam.AccountPrincipal('12345678901'), }); ``` should be more like: ``` const crossAccountRole = new iam.Role(this, 'CrossAccountRole', { // The role name must be predictable roleName: 'MyDelegationRole', // The other account assumedBy: new iam.AccountPrincipal('12345678901'), // You can scope down this role policy to be least privileged. // If you want the other account to be able to manage specific records, // you can scope down by resource and/or normalized record names inlinePolicies: { "crossAccountPolicy": new iam.PolicyDocument({ statements: [ new iam.PolicyStatement({ sid: "ListHostedZonesByName", effect: iam.Effect.ALLOW, actions: ["route53:ListHostedZonesByName"], resources: ["*"] }), new iam.PolicyStatement({ sid: "GetHostedZoneAndChangeResourceRecordSet", effect: iam.Effect.ALLOW, actions: ["route53:GetHostedZone", "route53:ChangeResourceRecordSet"], // This example assumes the RecordSet subdomain.somexample.com // is contained in the HostedZone resources: ["arn:aws:route53:::hostedzone/HZID00000000000000000"], conditions: { "ForAllValues:StringLike": { "route53:ChangeResourceRecordSetsNormalizedRecordNames": [ "subdomain.someexample.com" ] } } }) }); ``` Closes #28596. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk-lib/aws-route53/README.md | 32 +++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-route53/README.md b/packages/aws-cdk-lib/aws-route53/README.md index 91dc7baeee353..ce92008765691 100644 --- a/packages/aws-cdk-lib/aws-route53/README.md +++ b/packages/aws-cdk-lib/aws-route53/README.md @@ -182,7 +182,7 @@ new route53.ARecord(this, 'ARecord', { ### Cross Account Zone Delegation If you want to have your root domain hosted zone in one account and your subdomain hosted -zone in a diferent one, you can use `CrossAccountZoneDelegationRecord` to set up delegation +zone in a different one, you can use `CrossAccountZoneDelegationRecord` to set up delegation between them. In the account containing the parent hosted zone: @@ -196,6 +196,36 @@ const crossAccountRole = new iam.Role(this, 'CrossAccountRole', { roleName: 'MyDelegationRole', // The other account assumedBy: new iam.AccountPrincipal('12345678901'), + // You can scope down this role policy to be least privileged. + // If you want the other account to be able to manage specific records, + // you can scope down by resource and/or normalized record names + inlinePolicies: { + crossAccountPolicy: new iam.PolicyDocument({ + statements: [ + new iam.PolicyStatement({ + sid: 'ListHostedZonesByName', + effect: iam.Effect.ALLOW, + actions: ['route53:ListHostedZonesByName'], + resources: ['*'], + }), + new iam.PolicyStatement({ + sid: 'GetHostedZoneAndChangeResourceRecordSet', + effect: iam.Effect.ALLOW, + actions: ['route53:GetHostedZone', 'route53:ChangeResourceRecordSet'], + // This example assumes the RecordSet subdomain.somexample.com + // is contained in the HostedZone + resources: ['arn:aws:route53:::hostedzone/HZID00000000000000000'], + conditions: { + 'ForAllValues:StringLike': { + 'route53:ChangeResourceRecordSetsNormalizedRecordNames': [ + 'subdomain.someexample.com', + ], + }, + }, + }), + ], + }), + }, }); parentZone.grantDelegation(crossAccountRole); ```