diff --git a/.github/workflows/cr-checklist.yml b/.github/workflows/cr-checklist.yml index cdca37051a4d5..5badcb02eb2ac 100644 --- a/.github/workflows/cr-checklist.yml +++ b/.github/workflows/cr-checklist.yml @@ -9,7 +9,7 @@ jobs: name: Creates a checklist for PRs that contain changes to custom resources steps: - name: Checkout repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Dynamic checklist action uses: vishalsinha21/dynamic-checklist@v1 with: diff --git a/.github/workflows/pr-linter.yml b/.github/workflows/pr-linter.yml index 8231b94fa2319..73cc7b595e00d 100644 --- a/.github/workflows/pr-linter.yml +++ b/.github/workflows/pr-linter.yml @@ -21,7 +21,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Install & Build prlint run: yarn install --frozen-lockfile && cd tools/@aws-cdk/prlint && yarn build+test diff --git a/.github/workflows/v2-pull-request.yml b/.github/workflows/v2-pull-request.yml index 351ee2c8c427f..8e7e00acdbc25 100644 --- a/.github/workflows/v2-pull-request.yml +++ b/.github/workflows/v2-pull-request.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: branch: ${{ github.event.pull_request.head.ref }} token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/yarn-upgrade.yml b/.github/workflows/yarn-upgrade.yml index e694f383740ab..c9c6edb8d82b5 100644 --- a/.github/workflows/yarn-upgrade.yml +++ b/.github/workflows/yarn-upgrade.yml @@ -15,7 +15,7 @@ jobs: steps: - name: Check Out - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Node uses: actions/setup-node@v3 @@ -87,7 +87,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check Out - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Download patch uses: actions/download-artifact@v2 diff --git a/packages/@aws-cdk/aws-apigateway/lib/integrations/stepfunctions.ts b/packages/@aws-cdk/aws-apigateway/lib/integrations/stepfunctions.ts index 1430cc0d9a1dd..f9461eb0b44e8 100644 --- a/packages/@aws-cdk/aws-apigateway/lib/integrations/stepfunctions.ts +++ b/packages/@aws-cdk/aws-apigateway/lib/integrations/stepfunctions.ts @@ -203,7 +203,7 @@ function integrationResponse() { '#if($input.path(\'$.status\').toString().equals("FAILED"))', '#set($context.responseOverride.status = 500)', '{', - '"error": "$input.path(\'$.error\')"', + '"error": "$input.path(\'$.error\')",', '"cause": "$input.path(\'$.cause\')"', '}', '#else', diff --git a/packages/@aws-cdk/aws-apigateway/test/integ.stepfunctions-api.expected.json b/packages/@aws-cdk/aws-apigateway/test/integ.stepfunctions-api.expected.json index 575a390605c94..afbccd88a73ae 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integ.stepfunctions-api.expected.json +++ b/packages/@aws-cdk/aws-apigateway/test/integ.stepfunctions-api.expected.json @@ -160,7 +160,7 @@ "IntegrationResponses": [ { "ResponseTemplates": { - "application/json": "#set($inputRoot = $input.path('$'))\n#if($input.path('$.status').toString().equals(\"FAILED\"))\n#set($context.responseOverride.status = 500)\n{\n\"error\": \"$input.path('$.error')\"\n\"cause\": \"$input.path('$.cause')\"\n}\n#else\n$input.path('$.output')\n#end" + "application/json": "#set($inputRoot = $input.path('$'))\n#if($input.path('$.status').toString().equals(\"FAILED\"))\n#set($context.responseOverride.status = 500)\n{\n\"error\": \"$input.path('$.error')\",\n\"cause\": \"$input.path('$.cause')\"\n}\n#else\n$input.path('$.output')\n#end" }, "StatusCode": "200" }, diff --git a/packages/@aws-cdk/aws-apigateway/test/integrations/stepfunctions.test.ts b/packages/@aws-cdk/aws-apigateway/test/integrations/stepfunctions.test.ts index 5140cf1f6bdbb..32fd13c5741c0 100644 --- a/packages/@aws-cdk/aws-apigateway/test/integrations/stepfunctions.test.ts +++ b/packages/@aws-cdk/aws-apigateway/test/integrations/stepfunctions.test.ts @@ -418,7 +418,7 @@ function getIntegrationResponse() { '#if($input.path(\'$.status\').toString().equals("FAILED"))', '#set($context.responseOverride.status = 500)', '{', - '"error": "$input.path(\'$.error\')"', + '"error": "$input.path(\'$.error\')",', '"cause": "$input.path(\'$.cause\')"', '}', '#else', diff --git a/packages/@aws-cdk/aws-apigateway/test/stepfunctions-api.test.ts b/packages/@aws-cdk/aws-apigateway/test/stepfunctions-api.test.ts index d43ed0dff9f59..5922d61025965 100644 --- a/packages/@aws-cdk/aws-apigateway/test/stepfunctions-api.test.ts +++ b/packages/@aws-cdk/aws-apigateway/test/stepfunctions-api.test.ts @@ -181,7 +181,7 @@ function getIntegrationResponse() { '#if($input.path(\'$.status\').toString().equals("FAILED"))', '#set($context.responseOverride.status = 500)', '{', - '"error": "$input.path(\'$.error\')"', + '"error": "$input.path(\'$.error\')",', '"cause": "$input.path(\'$.cause\')"', '}', '#else', diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/lambda.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/lambda.ts index 2417fffe1610d..69019e0c2866a 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/lambda.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/lib/http/lambda.ts @@ -50,7 +50,7 @@ export class HttpLambdaIntegration extends HttpRouteIntegration { this._id = id; } - public bind(options: HttpRouteIntegrationBindOptions): HttpRouteIntegrationConfig { + protected completeBind(options: HttpRouteIntegrationBindOptions) { const route = options.route; this.handler.addPermission(`${this._id}-Permission`, { scope: options.scope, @@ -61,7 +61,9 @@ export class HttpLambdaIntegration extends HttpRouteIntegration { resourceName: `*/*${route.path ?? ''}`, // empty string in the case of the catch-all route $default }), }); + } + public bind(_: HttpRouteIntegrationBindOptions): HttpRouteIntegrationConfig { return { type: HttpIntegrationType.AWS_PROXY, uri: this.handler.functionArn, diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/lambda.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/lambda.test.ts index 5c318e1629842..f832921ad995b 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/lambda.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/lambda.test.ts @@ -1,4 +1,4 @@ -import { Template } from '@aws-cdk/assertions'; +import { Match, Template } from '@aws-cdk/assertions'; import { HttpApi, HttpRoute, HttpRouteKey, MappingValue, ParameterMapping, PayloadFormatVersion } from '@aws-cdk/aws-apigatewayv2'; import { Code, Function, Runtime } from '@aws-cdk/aws-lambda'; import { App, Stack } from '@aws-cdk/core'; @@ -71,6 +71,41 @@ describe('LambdaProxyIntegration', () => { expect(() => app.synth()).not.toThrow(); }); + + test('multiple routes for the same lambda integration', () => { + const app = new App(); + const lambdaStack = new Stack(app, 'lambdaStack'); + const fooFn = fooFunction(lambdaStack, 'Fn'); + + const stack = new Stack(app, 'apigwStack'); + const api = new HttpApi(stack, 'httpApi'); + const integration = new HttpLambdaIntegration('Integration', fooFn); + + api.addRoutes({ + path: '/foo', + integration, + }); + + api.addRoutes({ + path: '/bar', + integration, + }); + + // Make sure we have two permissions -- one for each method -- but a single integration + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { + SourceArn: { + 'Fn::Join': ['', Match.arrayWith([':execute-api:', '/*/*/foo'])], + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { + SourceArn: { + 'Fn::Join': ['', Match.arrayWith([':execute-api:', '/*/*/bar'])], + }, + }); + + Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::Integration', 1); + }); }); function fooFunction(stack: Stack, id: string) { diff --git a/packages/@aws-cdk/aws-apigatewayv2/lib/http/integration.ts b/packages/@aws-cdk/aws-apigatewayv2/lib/http/integration.ts index 58e9c9a60879a..9667f072d9036 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/lib/http/integration.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/lib/http/integration.ts @@ -332,9 +332,22 @@ export abstract class HttpRouteIntegration { credentials: config.credentials, }); } + this.completeBind(options); return { integrationId: this.integration.integrationId }; } + /** + * Complete the binding of the integration to the route. In some cases, there is + * some additional work to do, such as adding permissions for the API to access + * the target. This work is necessary whether the integration has just been + * created for this route or it is an existing one, previously created for other + * routes. In most cases, however, concrete implementations do not need to + * override this method. + */ + protected completeBind(_options: HttpRouteIntegrationBindOptions): void { + // no-op by default + } + /** * Bind this integration to the route. */ diff --git a/packages/@aws-cdk/aws-codebuild/README.md b/packages/@aws-cdk/aws-codebuild/README.md index 4bccbbc68cfa1..3be027de2404c 100644 --- a/packages/@aws-cdk/aws-codebuild/README.md +++ b/packages/@aws-cdk/aws-codebuild/README.md @@ -280,11 +280,12 @@ can use the `environment` property to customize the build environment: ## Images The CodeBuild library supports both Linux and Windows images via the -`LinuxBuildImage` and `WindowsBuildImage` classes, respectively. +`LinuxBuildImage` (or `LinuxArmBuildImage`), and `WindowsBuildImage` classes, respectively. You can specify one of the predefined Windows/Linux images by using one of the constants such as `WindowsBuildImage.WIN_SERVER_CORE_2019_BASE`, -`WindowsBuildImage.WINDOWS_BASE_2_0` or `LinuxBuildImage.STANDARD_2_0`. +`WindowsBuildImage.WINDOWS_BASE_2_0`, `LinuxBuildImage.STANDARD_2_0`, or +`LinuxArmBuildImage.AMAZON_LINUX_2_ARM`. Alternatively, you can specify a custom image using one of the static methods on `LinuxBuildImage`: @@ -302,6 +303,10 @@ or one of the corresponding methods on `WindowsBuildImage`: * `WindowsBuildImage.fromEcrRepository(repo[, tag, imageType])` * `WindowsBuildImage.fromAsset(parent, id, props, [, imageType])` +or one of the corresponding methods on `LinuxArmBuildImage`: + +* `LinuxArmBuildImage.fromEcrRepository(repo[, tag])` + Note that the `WindowsBuildImage` version of the static methods accepts an optional parameter of type `WindowsImageType`, which can be either `WindowsImageType.STANDARD`, the default, or `WindowsImageType.SERVER_2019`: diff --git a/packages/@aws-cdk/aws-codebuild/lib/index.ts b/packages/@aws-cdk/aws-codebuild/lib/index.ts index 5c2de5f3119c2..e2abd2da98db8 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/index.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/index.ts @@ -11,6 +11,7 @@ export * from './build-spec'; export * from './file-location'; export * from './linux-gpu-build-image'; export * from './untrusted-code-boundary-policy'; +export * from './linux-arm-build-image'; // AWS::CodeBuild CloudFormation Resources: export * from './codebuild.generated'; diff --git a/packages/@aws-cdk/aws-codebuild/lib/linux-arm-build-image.ts b/packages/@aws-cdk/aws-codebuild/lib/linux-arm-build-image.ts new file mode 100644 index 0000000000000..12a7d2e54daf6 --- /dev/null +++ b/packages/@aws-cdk/aws-codebuild/lib/linux-arm-build-image.ts @@ -0,0 +1,105 @@ +import * as ecr from '@aws-cdk/aws-ecr'; +import * as secretsmanager from '@aws-cdk/aws-secretsmanager'; +import { BuildSpec } from './build-spec'; +import { runScriptLinuxBuildSpec } from './private/run-script-linux-build-spec'; +import { BuildEnvironment, ComputeType, IBuildImage, ImagePullPrincipalType } from './project'; + +/** + * Construction properties of {@link LinuxArmBuildImage}. + * Module-private, as the constructor of {@link LinuxArmBuildImage} is private. + */ +interface LinuxArmBuildImageProps { + readonly imageId: string; + readonly imagePullPrincipalType?: ImagePullPrincipalType; + readonly secretsManagerCredentials?: secretsmanager.ISecret; + readonly repository?: ecr.IRepository; +} + +/** + * A CodeBuild image running aarch64 Linux. + * + * This class has a bunch of public constants that represent the CodeBuild ARM images. + * + * You can also specify a custom image using the static method: + * + * - LinuxBuildImage.fromEcrRepository(repo[, tag]) + * + * + * @see https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-available.html + */ +export class LinuxArmBuildImage implements IBuildImage { + /** Image "aws/codebuild/amazonlinux2-aarch64-standard:1.0". */ + public static readonly AMAZON_LINUX_2_STANDARD_1_0 = LinuxArmBuildImage.fromCodeBuildImageId('aws/codebuild/amazonlinux2-aarch64-standard:1.0'); + /** Image "aws/codebuild/amazonlinux2-aarch64-standard:2.0". */ + public static readonly AMAZON_LINUX_2_STANDARD_2_0 = LinuxArmBuildImage.fromCodeBuildImageId('aws/codebuild/amazonlinux2-aarch64-standard:2.0'); + + /** + * Returns an ARM image running Linux from an ECR repository. + * + * NOTE: if the repository is external (i.e. imported), then we won't be able to add + * a resource policy statement for it so CodeBuild can pull the image. + * + * @see https://docs.aws.amazon.com/codebuild/latest/userguide/sample-ecr.html + * + * @param repository The ECR repository + * @param tag Image tag (default "latest") + * @returns An aarch64 Linux build image from an ECR repository. + */ + public static fromEcrRepository(repository: ecr.IRepository, tag: string = 'latest'): IBuildImage { + return new LinuxArmBuildImage({ + imageId: repository.repositoryUriForTag(tag), + imagePullPrincipalType: ImagePullPrincipalType.SERVICE_ROLE, + repository, + }); + } + + /** + * Uses a Docker image provided by CodeBuild. + * + * @see https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-available.html + * + * @param id The image identifier + * @example 'aws/codebuild/amazonlinux2-aarch64-standard:1.0' + * @returns A Docker image provided by CodeBuild. + */ + public static fromCodeBuildImageId(id: string): IBuildImage { + return new LinuxArmBuildImage({ + imageId: id, + imagePullPrincipalType: ImagePullPrincipalType.CODEBUILD, + }); + } + + public readonly type = 'ARM_CONTAINER'; + public readonly defaultComputeType = ComputeType.LARGE; + public readonly imageId: string; + public readonly imagePullPrincipalType?: ImagePullPrincipalType; + public readonly secretsManagerCredentials?: secretsmanager.ISecret; + public readonly repository?: ecr.IRepository; + + private constructor(props: LinuxArmBuildImageProps) { + this.imageId = props.imageId; + this.imagePullPrincipalType = props.imagePullPrincipalType; + this.secretsManagerCredentials = props.secretsManagerCredentials; + this.repository = props.repository; + } + + /** + * Validates by checking the BuildEnvironment computeType as aarch64 images only support ComputeType.SMALL and + * ComputeType.LARGE + * @param buildEnvironment BuildEnvironment + */ + public validate(buildEnvironment: BuildEnvironment): string[] { + const ret = []; + if (buildEnvironment.computeType && + buildEnvironment.computeType !== ComputeType.SMALL && + buildEnvironment.computeType !== ComputeType.LARGE) { + ret.push(`ARM images only support ComputeTypes '${ComputeType.SMALL}' and '${ComputeType.LARGE}' - ` + + `'${buildEnvironment.computeType}' was given`); + } + return ret; + } + + public runScriptBuildspec(entrypoint: string): BuildSpec { + return runScriptLinuxBuildSpec(entrypoint); + } +} diff --git a/packages/@aws-cdk/aws-codebuild/lib/project.ts b/packages/@aws-cdk/aws-codebuild/lib/project.ts index c6a816e3aedd2..e3ea5ac394f4c 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/project.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/project.ts @@ -1642,32 +1642,6 @@ export interface IBindableBuildImage extends IBuildImage { bind(scope: CoreConstruct, project: IProject, options: BuildImageBindOptions): BuildImageConfig; } -class ArmBuildImage implements IBuildImage { - public readonly type = 'ARM_CONTAINER'; - public readonly defaultComputeType = ComputeType.LARGE; - public readonly imagePullPrincipalType = ImagePullPrincipalType.CODEBUILD; - public readonly imageId: string; - - constructor(imageId: string) { - this.imageId = imageId; - } - - public validate(buildEnvironment: BuildEnvironment): string[] { - const ret = []; - if (buildEnvironment.computeType && - buildEnvironment.computeType !== ComputeType.SMALL && - buildEnvironment.computeType !== ComputeType.LARGE) { - ret.push(`ARM images only support ComputeTypes '${ComputeType.SMALL}' and '${ComputeType.LARGE}' - ` + - `'${buildEnvironment.computeType}' was given`); - } - return ret; - } - - public runScriptBuildspec(entrypoint: string): BuildSpec { - return runScriptLinuxBuildSpec(entrypoint); - } -} - /** * The options when creating a CodeBuild Docker build image * using {@link LinuxBuildImage.fromDockerRegistry} @@ -1695,8 +1669,12 @@ interface LinuxBuildImageProps { readonly repository?: ecr.IRepository; } +// Keep around to resolve a circular dependency until removing deprecated ARM image constants from LinuxBuildImage +// eslint-disable-next-line no-duplicate-imports, import/order +import { LinuxArmBuildImage } from './linux-arm-build-image'; + /** - * A CodeBuild image running Linux. + * A CodeBuild image running x86-64 Linux. * * This class has a bunch of public constants that represent the most popular images. * @@ -1723,9 +1701,13 @@ export class LinuxBuildImage implements IBuildImage { /** The Amazon Linux 2 x86_64 standard image, version `3.0`. */ public static readonly AMAZON_LINUX_2_3 = LinuxBuildImage.codeBuildImage('aws/codebuild/amazonlinux2-x86_64-standard:3.0'); - public static readonly AMAZON_LINUX_2_ARM: IBuildImage = new ArmBuildImage('aws/codebuild/amazonlinux2-aarch64-standard:1.0'); - /** Image "aws/codebuild/amazonlinux2-aarch64-standard:2.0". */ - public static readonly AMAZON_LINUX_2_ARM_2: IBuildImage = new ArmBuildImage('aws/codebuild/amazonlinux2-aarch64-standard:2.0'); + /** @deprecated Use LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_1_0 instead. */ + public static readonly AMAZON_LINUX_2_ARM = LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_1_0; + /** + * Image "aws/codebuild/amazonlinux2-aarch64-standard:2.0". + * @deprecated Use LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_2_0 instead. + * */ + public static readonly AMAZON_LINUX_2_ARM_2 = LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_2_0; /** @deprecated Use {@link STANDARD_2_0} and specify runtime in buildspec runtime-versions section */ public static readonly UBUNTU_14_04_BASE = LinuxBuildImage.codeBuildImage('aws/codebuild/ubuntu-base:14.04'); @@ -1789,7 +1771,7 @@ export class LinuxBuildImage implements IBuildImage { public static readonly UBUNTU_14_04_DOTNET_CORE_2_1 = LinuxBuildImage.codeBuildImage('aws/codebuild/dot-net:core-2.1'); /** - * @returns a Linux build image from a Docker Hub image. + * @returns a x86-64 Linux build image from a Docker Hub image. */ public static fromDockerRegistry(name: string, options: DockerImageOptions = {}): IBuildImage { return new LinuxBuildImage({ @@ -1800,7 +1782,7 @@ export class LinuxBuildImage implements IBuildImage { } /** - * @returns A Linux build image from an ECR repository. + * @returns A x86-64 Linux build image from an ECR repository. * * NOTE: if the repository is external (i.e. imported), then we won't be able to add * a resource policy statement for it so CodeBuild can pull the image. @@ -1819,7 +1801,7 @@ export class LinuxBuildImage implements IBuildImage { } /** - * Uses an Docker image asset as a Linux build image. + * Uses an Docker image asset as a x86-64 Linux build image. */ public static fromAsset(scope: Construct, id: string, props: DockerImageAssetProps): IBuildImage { const asset = new DockerImageAsset(scope, id, props); @@ -1961,7 +1943,7 @@ export class WindowsBuildImage implements IBuildImage { } /** - * @returns A Linux build image from an ECR repository. + * @returns A Windows build image from an ECR repository. * * NOTE: if the repository is external (i.e. imported), then we won't be able to add * a resource policy statement for it so CodeBuild can pull the image. @@ -2125,4 +2107,4 @@ export enum ProjectNotificationEvents { function isBindableBuildImage(x: unknown): x is IBindableBuildImage { return typeof x === 'object' && !!x && !!(x as any).bind; -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-codebuild/test/linux-arm-build-image.test.ts b/packages/@aws-cdk/aws-codebuild/test/linux-arm-build-image.test.ts new file mode 100644 index 0000000000000..389fbc0529b22 --- /dev/null +++ b/packages/@aws-cdk/aws-codebuild/test/linux-arm-build-image.test.ts @@ -0,0 +1,328 @@ +import { Match, Template } from '@aws-cdk/assertions'; +import * as ecr from '@aws-cdk/aws-ecr'; +import * as cdk from '@aws-cdk/core'; +import * as codebuild from '../lib'; + +describe('Linux ARM build image', () => { + describe('AMAZON_LINUX_2_STANDARD_1_0', () => { + test('has type ARM_CONTAINER and default ComputeType LARGE', () => { + const stack = new cdk.Stack(); + new codebuild.PipelineProject(stack, 'Project', { + environment: { + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_1_0, + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CodeBuild::Project', { + Environment: { + Type: 'ARM_CONTAINER', + ComputeType: 'BUILD_GENERAL1_LARGE', + }, + }); + }); + + test('can be used with ComputeType SMALL', () => { + const stack = new cdk.Stack(); + new codebuild.PipelineProject(stack, 'Project', { + environment: { + computeType: codebuild.ComputeType.SMALL, + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_1_0, + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CodeBuild::Project', { + Environment: { + Type: 'ARM_CONTAINER', + ComputeType: 'BUILD_GENERAL1_SMALL', + }, + }); + }); + + test('cannot be used in conjunction with ComputeType MEDIUM', () => { + const stack = new cdk.Stack(); + + expect(() => { + new codebuild.PipelineProject(stack, 'Project', { + environment: { + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_1_0, + computeType: codebuild.ComputeType.MEDIUM, + }, + }); + }).toThrow(/ARM images only support ComputeTypes 'BUILD_GENERAL1_SMALL' and 'BUILD_GENERAL1_LARGE' - 'BUILD_GENERAL1_MEDIUM' was given/); + }); + + test('can be used with ComputeType LARGE', () => { + const stack = new cdk.Stack(); + new codebuild.PipelineProject(stack, 'Project', { + environment: { + computeType: codebuild.ComputeType.LARGE, + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_1_0, + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CodeBuild::Project', { + Environment: { + Type: 'ARM_CONTAINER', + ComputeType: 'BUILD_GENERAL1_LARGE', + }, + }); + }); + + test('cannot be used in conjunction with ComputeType X2_LARGE', () => { + const stack = new cdk.Stack(); + + expect(() => { + new codebuild.PipelineProject(stack, 'Project', { + environment: { + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_1_0, + computeType: codebuild.ComputeType.X2_LARGE, + }, + }); + }).toThrow(/ARM images only support ComputeTypes 'BUILD_GENERAL1_SMALL' and 'BUILD_GENERAL1_LARGE' - 'BUILD_GENERAL1_2XLARGE' was given/); + }); + }); + + describe('AMAZON_LINUX_2_STANDARD_2_0', () => { + test('has type ARM_CONTAINER and default ComputeType LARGE', () => { + const stack = new cdk.Stack(); + new codebuild.PipelineProject(stack, 'Project', { + environment: { + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_2_0, + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CodeBuild::Project', { + Environment: { + Type: 'ARM_CONTAINER', + ComputeType: 'BUILD_GENERAL1_LARGE', + }, + }); + }); + + test('can be used with ComputeType SMALL', () => { + const stack = new cdk.Stack(); + new codebuild.PipelineProject(stack, 'Project', { + environment: { + computeType: codebuild.ComputeType.SMALL, + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_2_0, + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CodeBuild::Project', { + Environment: { + Type: 'ARM_CONTAINER', + ComputeType: 'BUILD_GENERAL1_SMALL', + }, + }); + }); + + test('cannot be used in conjunction with ComputeType MEDIUM', () => { + const stack = new cdk.Stack(); + + expect(() => { + new codebuild.PipelineProject(stack, 'Project', { + environment: { + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_2_0, + computeType: codebuild.ComputeType.MEDIUM, + }, + }); + }).toThrow(/ARM images only support ComputeTypes 'BUILD_GENERAL1_SMALL' and 'BUILD_GENERAL1_LARGE' - 'BUILD_GENERAL1_MEDIUM' was given/); + }); + + test('can be used with ComputeType LARGE', () => { + const stack = new cdk.Stack(); + new codebuild.PipelineProject(stack, 'Project', { + environment: { + computeType: codebuild.ComputeType.LARGE, + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_2_0, + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CodeBuild::Project', { + Environment: { + Type: 'ARM_CONTAINER', + ComputeType: 'BUILD_GENERAL1_LARGE', + }, + }); + }); + + test('cannot be used in conjunction with ComputeType X2_LARGE', () => { + const stack = new cdk.Stack(); + + expect(() => { + new codebuild.PipelineProject(stack, 'Project', { + environment: { + buildImage: codebuild.LinuxArmBuildImage.AMAZON_LINUX_2_STANDARD_2_0, + computeType: codebuild.ComputeType.X2_LARGE, + }, + }); + }).toThrow(/ARM images only support ComputeTypes 'BUILD_GENERAL1_SMALL' and 'BUILD_GENERAL1_LARGE' - 'BUILD_GENERAL1_2XLARGE' was given/); + }); + }); + + describe('ECR Repository', () => { + test('allows creating a build image from a new ECR repository', () => { + const stack = new cdk.Stack(); + + const repository = new ecr.Repository(stack, 'my-repo'); + + new codebuild.Project(stack, 'Project', { + buildSpec: codebuild.BuildSpec.fromObject({ + version: '0.2', + phases: { + build: { commands: ['ls'] }, + }, + }), + environment: { + buildImage: codebuild.LinuxArmBuildImage.fromEcrRepository(repository, 'v1'), + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CodeBuild::Project', { + Environment: { + ComputeType: 'BUILD_GENERAL1_LARGE', + Image: { + 'Fn::Join': ['', [ + { + 'Fn::Select': [4, { + 'Fn::Split': [':', { + 'Fn::GetAtt': ['myrepo5DFA62E5', 'Arn'], + }], + }], + }, + '.dkr.ecr.', + { + 'Fn::Select': [3, { + 'Fn::Split': [':', { + 'Fn::GetAtt': ['myrepo5DFA62E5', 'Arn'], + }], + }], + }, + '.', + { Ref: 'AWS::URLSuffix' }, + '/', + { Ref: 'myrepo5DFA62E5' }, + ':v1', + ]], + }, + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: Match.arrayWith([Match.objectLike({ + Action: [ + 'ecr:BatchCheckLayerAvailability', + 'ecr:GetDownloadUrlForLayer', + 'ecr:BatchGetImage', + ], + Resource: { + 'Fn::GetAtt': ['myrepo5DFA62E5', 'Arn'], + }, + })]), + }, + }); + }); + + test('allows creating a build image from an existing ECR repository', () => { + const stack = new cdk.Stack(); + + const repository = ecr.Repository.fromRepositoryName(stack, 'my-imported-repo', 'test-repo'); + + new codebuild.Project(stack, 'Project', { + buildSpec: codebuild.BuildSpec.fromObject({ + version: '0.2', + phases: { + build: { commands: ['ls'] }, + }, + }), + environment: { + buildImage: codebuild.LinuxArmBuildImage.fromEcrRepository(repository), + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CodeBuild::Project', { + Environment: { + ComputeType: 'BUILD_GENERAL1_LARGE', + Image: { + 'Fn::Join': ['', [ + { Ref: 'AWS::AccountId' }, + '.dkr.ecr.', + { Ref: 'AWS::Region' }, + '.', + { Ref: 'AWS::URLSuffix' }, + '/test-repo:latest', + ]], + }, + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: Match.arrayWith([Match.objectLike({ + Action: [ + 'ecr:BatchCheckLayerAvailability', + 'ecr:GetDownloadUrlForLayer', + 'ecr:BatchGetImage', + ], + Resource: { + 'Fn::Join': ['', [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':ecr:', + { Ref: 'AWS::Region' }, + ':', + { Ref: 'AWS::AccountId' }, + ':repository/test-repo', + ]], + }, + })]), + }, + }); + }); + + test('allows creating a build image from an existing cross-account ECR repository', () => { + const stack = new cdk.Stack(); + + const repository = ecr.Repository.fromRepositoryArn(stack, 'my-cross-acount-repo', 'arn:aws:ecr:us-east-1:585695036304:repository/foo/bar/foo/fooo'); + + new codebuild.Project(stack, 'Project', { + buildSpec: codebuild.BuildSpec.fromObject({ + version: '0.2', + phases: { + build: { commands: ['ls'] }, + }, + }), + environment: { + buildImage: codebuild.LinuxArmBuildImage.fromEcrRepository(repository), + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CodeBuild::Project', { + Environment: { + ComputeType: 'BUILD_GENERAL1_LARGE', + Image: { + 'Fn::Join': ['', [ + '585695036304.dkr.ecr.us-east-1.', + { Ref: 'AWS::URLSuffix' }, + '/foo/bar/foo/fooo:latest', + ]], + }, + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: Match.arrayWith([Match.objectLike({ + Action: [ + 'ecr:BatchCheckLayerAvailability', + 'ecr:GetDownloadUrlForLayer', + 'ecr:BatchGetImage', + ], + Resource: 'arn:aws:ecr:us-east-1:585695036304:repository/foo/bar/foo/fooo', + })]), + }, + }); + }); + }); +}); diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc.ts b/packages/@aws-cdk/aws-ec2/lib/vpc.ts index 8c8d6795fa23c..741a6ceba4f07 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc.ts @@ -2222,6 +2222,24 @@ const DUMMY_VPC_PROPS: cxapi.VpcContextResponse = { }, ], }, + { + name: 'Isolated', + type: cxapi.VpcSubnetGroupType.ISOLATED, + subnets: [ + { + availabilityZone: 'dummy1a', + subnetId: 'p-12345', + routeTableId: 'rtb-12345p', + cidr: '1.2.3.4/5', + }, + { + availabilityZone: 'dummy1b', + subnetId: 'p-67890', + routeTableId: 'rtb-57890p', + cidr: '1.2.3.4/5', + }, + ], + }, ], vpcId: 'vpc-12345', }; diff --git a/packages/@aws-cdk/aws-eks/lib/service-account.ts b/packages/@aws-cdk/aws-eks/lib/service-account.ts index c49e2a944a765..a330aa41e0df5 100644 --- a/packages/@aws-cdk/aws-eks/lib/service-account.ts +++ b/packages/@aws-cdk/aws-eks/lib/service-account.ts @@ -14,12 +14,18 @@ import { Construct as CoreConstruct } from '@aws-cdk/core'; export interface ServiceAccountOptions { /** * The name of the service account. + * + * The name of a ServiceAccount object must be a valid DNS subdomain name. + * https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ * @default - If no name is given, it will use the id of the resource. */ readonly name?: string; /** * The namespace of the service account. + * + * All namespace names must be valid RFC 1123 DNS labels. + * https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/#namespaces-and-dns * @default "default" */ readonly namespace?: string; @@ -65,6 +71,16 @@ export class ServiceAccount extends CoreConstruct implements IPrincipal { this.serviceAccountName = props.name ?? Names.uniqueId(this).toLowerCase(); this.serviceAccountNamespace = props.namespace ?? 'default'; + // From K8s docs: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + if (!this.isValidDnsSubdomainName(this.serviceAccountName)) { + throw RangeError('The name of a ServiceAccount object must be a valid DNS subdomain name.'); + } + + // From K8s docs: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/#namespaces-and-dns + if (!this.isValidDnsLabelName(this.serviceAccountNamespace)) { + throw RangeError('All namespace names must be valid RFC 1123 DNS labels.'); + } + /* Add conditions to the role to improve security. This prevents other pods in the same namespace to assume the role. * See documentation: https://docs.aws.amazon.com/eks/latest/userguide/create-service-account-iam-policy-and-role.html */ @@ -117,4 +133,22 @@ export class ServiceAccount extends CoreConstruct implements IPrincipal { public addToPrincipalPolicy(statement: PolicyStatement): AddToPrincipalPolicyResult { return this.role.addToPrincipalPolicy(statement); } + + /** + * If the value is a DNS subdomain name as defined in RFC 1123, from K8s docs. + * + * https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names + */ + private isValidDnsSubdomainName(value: string): boolean { + return value.length <= 253 && /^[a-z0-9]+[a-z0-9-.]*[a-z0-9]+$/.test(value); + } + + /** + * If the value follows DNS label standard as defined in RFC 1123, from K8s docs. + * + * https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-label-names + */ + private isValidDnsLabelName(value: string): boolean { + return value.length <= 63 && /^[a-z0-9]+[a-z0-9-]*[a-z0-9]+$/.test(value); + } } diff --git a/packages/@aws-cdk/aws-eks/test/service-account.test.ts b/packages/@aws-cdk/aws-eks/test/service-account.test.ts index e4db2f6680a97..7ece468d200d0 100644 --- a/packages/@aws-cdk/aws-eks/test/service-account.test.ts +++ b/packages/@aws-cdk/aws-eks/test/service-account.test.ts @@ -174,4 +174,101 @@ describe('service account', () => { }); }); + + describe('Service Account name must follow Kubernetes spec', () => { + test('throw error on capital letters', () => { + // GIVEN + const { cluster } = testFixtureCluster(); + + // WHEN + expect(() => cluster.addServiceAccount('InvalidServiceAccount', { + name: 'XXX', + })) + // THEN + .toThrowError(RangeError); + }); + test('throw error if ends with dot', () => { + // GIVEN + const { cluster } = testFixtureCluster(); + + // WHEN + expect(() => cluster.addServiceAccount('InvalidServiceAccount', { + name: 'test.', + })) + // THEN + .toThrowError(RangeError); + }); + test('dot in the name is allowed', () => { + // GIVEN + const { cluster } = testFixtureCluster(); + const valueWithDot = 'test.name'; + + // WHEN + const sa = cluster.addServiceAccount('InvalidServiceAccount', { + name: valueWithDot, + }); + + // THEN + expect(sa.serviceAccountName).toEqual(valueWithDot); + }); + test('throw error if name is too long', () => { + // GIVEN + const { cluster } = testFixtureCluster(); + + // WHEN + expect(() => cluster.addServiceAccount('InvalidServiceAccount', { + name: 'x'.repeat(255), + })) + // THEN + .toThrowError(RangeError); + }); + }); + + describe('Service Account namespace must follow Kubernetes spec', () => { + test('throw error on capital letters', () => { + // GIVEN + const { cluster } = testFixtureCluster(); + + // WHEN + expect(() => cluster.addServiceAccount('InvalidServiceAccount', { + namespace: 'XXX', + })) + // THEN + .toThrowError(RangeError); + }); + test('throw error if ends with dot', () => { + // GIVEN + const { cluster } = testFixtureCluster(); + + // WHEN + expect(() => cluster.addServiceAccount('InvalidServiceAccount', { + namespace: 'test.', + })) + // THEN + .toThrowError(RangeError); + }); + test('throw error if dot is in the name', () => { + // GIVEN + const { cluster } = testFixtureCluster(); + const valueWithDot = 'test.name'; + + // WHEN + expect(() => cluster.addServiceAccount('InvalidServiceAccount', { + namespace: valueWithDot, + })) + // THEN + .toThrowError(RangeError); + }); + test('throw error if name is too long', () => { + // GIVEN + const { cluster } = testFixtureCluster(); + + // WHEN + expect(() => cluster.addServiceAccount('InvalidServiceAccount', { + namespace: 'x'.repeat(65), + })) + // THEN + .toThrowError(RangeError); + }); + }); }); diff --git a/packages/@aws-cdk/aws-events-targets/README.md b/packages/@aws-cdk/aws-events-targets/README.md index d98b08d652086..34157fef412b5 100644 --- a/packages/@aws-cdk/aws-events-targets/README.md +++ b/packages/@aws-cdk/aws-events-targets/README.md @@ -167,13 +167,13 @@ const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('events.amazonaws.com'), }); const stateMachine = new sfn.StateMachine(this, 'SM', { - definition: new sfn.Wait(this, 'Hello', { time: sfn.WaitTime.duration(cdk.Duration.seconds(10)) }), - role, + definition: new sfn.Wait(this, 'Hello', { time: sfn.WaitTime.duration(cdk.Duration.seconds(10)) }) }); rule.addTarget(new targets.SfnStateMachine(stateMachine, { input: events.RuleTargetInput.fromObject({ SomeParam: 'SomeValue' }), deadLetterQueue: dlq, + role: role })); ``` diff --git a/packages/@aws-cdk/aws-events-targets/test/stepfunctions/statemachine.test.ts b/packages/@aws-cdk/aws-events-targets/test/stepfunctions/statemachine.test.ts index 158b19f34fa0a..6327213b7a744 100644 --- a/packages/@aws-cdk/aws-events-targets/test/stepfunctions/statemachine.test.ts +++ b/packages/@aws-cdk/aws-events-targets/test/stepfunctions/statemachine.test.ts @@ -68,12 +68,12 @@ test('Existing role can be used for State machine Rule target', () => { }); const stateMachine = new sfn.StateMachine(stack, 'SM', { definition: new sfn.Wait(stack, 'Hello', { time: sfn.WaitTime.duration(cdk.Duration.seconds(10)) }), - role, }); // WHEN rule.addTarget(new targets.SfnStateMachine(stateMachine, { input: events.RuleTargetInput.fromObject({ SomeParam: 'SomeValue' }), + role: role, })); // THEN @@ -125,13 +125,13 @@ test('specifying retry policy', () => { }); const stateMachine = new sfn.StateMachine(stack, 'SM', { definition: new sfn.Wait(stack, 'Hello', { time: sfn.WaitTime.duration(cdk.Duration.seconds(10)) }), - role, }); rule.addTarget(new targets.SfnStateMachine(stateMachine, { input: events.RuleTargetInput.fromObject({ SomeParam: 'SomeValue' }), maxEventAge: cdk.Duration.hours(2), retryAttempts: 2, + role: role, })); // THEN @@ -151,7 +151,7 @@ test('specifying retry policy', () => { }, RoleArn: { 'Fn::GetAtt': [ - 'SMEventsRoleB320A902', + 'Role1ABCC5F0', 'Arn', ], }, @@ -176,13 +176,13 @@ test('use a Dead Letter Queue for the rule target', () => { }); const stateMachine = new sfn.StateMachine(stack, 'SM', { definition: new sfn.Wait(stack, 'Hello', { time: sfn.WaitTime.duration(cdk.Duration.seconds(10)) }), - role, }); // WHEN rule.addTarget(new targets.SfnStateMachine(stateMachine, { input: events.RuleTargetInput.fromObject({ SomeParam: 'SomeValue' }), deadLetterQueue: dlq, + role: role, })); // the Permission resource should be in the event stack @@ -206,7 +206,7 @@ test('use a Dead Letter Queue for the rule target', () => { Input: '{"SomeParam":"SomeValue"}', RoleArn: { 'Fn::GetAtt': [ - 'SMEventsRoleB320A902', + 'Role1ABCC5F0', 'Arn', ], }, diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts index 4a23e2726add3..ee6b395c5d262 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts @@ -89,7 +89,7 @@ export class Bundling implements cdk.BundlingOptions { this.packageManager = PackageManager.fromLockFile(props.depsLockFilePath, props.logLevel); Bundling.esbuildInstallation = Bundling.esbuildInstallation ?? PackageInstallation.detect('esbuild'); - Bundling.tscInstallation = Bundling.tscInstallation ?? PackageInstallation.detect('tsc'); + Bundling.tscInstallation = Bundling.tscInstallation ?? PackageInstallation.detect('typescript'); this.projectRoot = props.projectRoot; this.relativeEntryPath = path.relative(this.projectRoot, path.resolve(props.entry)); diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts index b22230947b0d5..37e7fa0c94b6b 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts @@ -16,6 +16,7 @@ beforeEach(() => { jest.resetAllMocks(); jest.restoreAllMocks(); Bundling.clearEsbuildInstallationCache(); + Bundling.clearTscInstallationCache(); jest.spyOn(Code, 'fromAsset'); @@ -602,6 +603,8 @@ test('esbuild bundling with pre compilations', () => { ], }), }); + + expect(detectPackageInstallationMock).toHaveBeenCalledWith('typescript'); }); test('throws with pre compilation and not found tsconfig', () => { diff --git a/packages/@aws-cdk/aws-lambda-python/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-python/lib/bundling.ts index 14af585f75509..27c8d24f83558 100644 --- a/packages/@aws-cdk/aws-lambda-python/lib/bundling.ts +++ b/packages/@aws-cdk/aws-lambda-python/lib/bundling.ts @@ -69,7 +69,7 @@ export class Bundling implements CdkBundlingOptions { image, } = props; - const outputPath = path.join(AssetStaging.BUNDLING_OUTPUT_DIR, outputPathSuffix); + const outputPath = path.posix.join(AssetStaging.BUNDLING_OUTPUT_DIR, outputPathSuffix); const bundlingCommands = this.createBundlingCommand({ entry, diff --git a/packages/@aws-cdk/aws-rds/lib/cluster.ts b/packages/@aws-cdk/aws-rds/lib/cluster.ts index 76fe7d597b70b..5ac2ce91e652a 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster.ts @@ -11,7 +11,7 @@ import { IClusterEngine } from './cluster-engine'; import { DatabaseClusterAttributes, IDatabaseCluster } from './cluster-ref'; import { Endpoint } from './endpoint'; import { IParameterGroup, ParameterGroup } from './parameter-group'; -import { DEFAULT_PASSWORD_EXCLUDE_CHARS, defaultDeletionProtection, renderCredentials, setupS3ImportExport, helperRemovalPolicy, renderUnless } from './private/util'; +import { applyDefaultRotationOptions, defaultDeletionProtection, renderCredentials, setupS3ImportExport, helperRemovalPolicy, renderUnless } from './private/util'; import { BackupProps, Credentials, InstanceProps, PerformanceInsightRetention, RotationSingleUserOptions, RotationMultiUserOptions } from './props'; import { DatabaseProxy, DatabaseProxyOptions, ProxyTarget } from './proxy'; import { CfnDBCluster, CfnDBClusterProps, CfnDBInstance } from './rds.generated'; @@ -595,13 +595,11 @@ export class DatabaseCluster extends DatabaseClusterNew { } return new secretsmanager.SecretRotation(this, id, { + ...applyDefaultRotationOptions(options, this.vpcSubnets), secret: this.secret, application: this.singleUserRotationApplication, vpc: this.vpc, - vpcSubnets: this.vpcSubnets, target: this, - ...options, - excludeCharacters: options.excludeCharacters ?? DEFAULT_PASSWORD_EXCLUDE_CHARS, }); } @@ -612,13 +610,13 @@ export class DatabaseCluster extends DatabaseClusterNew { if (!this.secret) { throw new Error('Cannot add multi user rotation for a cluster without secret.'); } + return new secretsmanager.SecretRotation(this, id, { - ...options, - excludeCharacters: options.excludeCharacters ?? DEFAULT_PASSWORD_EXCLUDE_CHARS, + ...applyDefaultRotationOptions(options, this.vpcSubnets), + secret: options.secret, masterSecret: this.secret, application: this.multiUserRotationApplication, vpc: this.vpc, - vpcSubnets: this.vpcSubnets, target: this, }); } diff --git a/packages/@aws-cdk/aws-rds/lib/instance.ts b/packages/@aws-cdk/aws-rds/lib/instance.ts index f1aa82dd20b3b..ec19adaddf554 100644 --- a/packages/@aws-cdk/aws-rds/lib/instance.ts +++ b/packages/@aws-cdk/aws-rds/lib/instance.ts @@ -13,7 +13,7 @@ import { Endpoint } from './endpoint'; import { IInstanceEngine } from './instance-engine'; import { IOptionGroup } from './option-group'; import { IParameterGroup, ParameterGroup } from './parameter-group'; -import { DEFAULT_PASSWORD_EXCLUDE_CHARS, defaultDeletionProtection, engineDescription, renderCredentials, setupS3ImportExport, helperRemovalPolicy, renderUnless } from './private/util'; +import { applyDefaultRotationOptions, defaultDeletionProtection, engineDescription, renderCredentials, setupS3ImportExport, helperRemovalPolicy, renderUnless } from './private/util'; import { Credentials, PerformanceInsightRetention, RotationMultiUserOptions, RotationSingleUserOptions, SnapshotCredentials } from './props'; import { DatabaseProxy, DatabaseProxyOptions, ProxyTarget } from './proxy'; import { CfnDBInstance, CfnDBInstanceProps } from './rds.generated'; @@ -931,13 +931,11 @@ abstract class DatabaseInstanceSource extends DatabaseInstanceNew implements IDa } return new secretsmanager.SecretRotation(this, id, { + ...applyDefaultRotationOptions(options, this.vpcPlacement), secret: this.secret, application: this.singleUserRotationApplication, vpc: this.vpc, - vpcSubnets: this.vpcPlacement, target: this, - ...options, - excludeCharacters: options.excludeCharacters ?? DEFAULT_PASSWORD_EXCLUDE_CHARS, }); } @@ -948,13 +946,13 @@ abstract class DatabaseInstanceSource extends DatabaseInstanceNew implements IDa if (!this.secret) { throw new Error('Cannot add multi user rotation for an instance without secret.'); } + return new secretsmanager.SecretRotation(this, id, { - ...options, - excludeCharacters: options.excludeCharacters ?? DEFAULT_PASSWORD_EXCLUDE_CHARS, + ...applyDefaultRotationOptions(options, this.vpcPlacement), + secret: options.secret, masterSecret: this.secret, application: this.multiUserRotationApplication, vpc: this.vpc, - vpcSubnets: this.vpcPlacement, target: this, }); } diff --git a/packages/@aws-cdk/aws-rds/lib/private/util.ts b/packages/@aws-cdk/aws-rds/lib/private/util.ts index 1664647c92bd8..729744a911eaf 100644 --- a/packages/@aws-cdk/aws-rds/lib/private/util.ts +++ b/packages/@aws-cdk/aws-rds/lib/private/util.ts @@ -1,9 +1,10 @@ +import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as s3 from '@aws-cdk/aws-s3'; import { RemovalPolicy } from '@aws-cdk/core'; import { DatabaseSecret } from '../database-secret'; import { IEngine } from '../engine'; -import { Credentials } from '../props'; +import { CommonRotationUserOptions, Credentials } from '../props'; // keep this import separate from other imports to reduce chance for merge conflicts with v2-main // eslint-disable-next-line no-duplicate-imports, import/order @@ -134,3 +135,14 @@ export function helperRemovalPolicy(basePolicy?: RemovalPolicy): RemovalPolicy { export function renderUnless(value: A, suppressValue: A): A | undefined { return value === suppressValue ? undefined : value; } + +/** + * Applies defaults for rotation options + */ +export function applyDefaultRotationOptions(options: CommonRotationUserOptions, defaultvpcSubnets?: ec2.SubnetSelection): CommonRotationUserOptions { + return { + excludeCharacters: DEFAULT_PASSWORD_EXCLUDE_CHARS, + vpcSubnets: defaultvpcSubnets, + ...options, + }; +} diff --git a/packages/@aws-cdk/aws-rds/lib/props.ts b/packages/@aws-cdk/aws-rds/lib/props.ts index 663719431d640..6338fa0368849 100644 --- a/packages/@aws-cdk/aws-rds/lib/props.ts +++ b/packages/@aws-cdk/aws-rds/lib/props.ts @@ -456,7 +456,7 @@ export abstract class SnapshotCredentials { /** * Properties common to single-user and multi-user rotation options. */ -interface CommonRotationUserOptions { +export interface CommonRotationUserOptions { /** * Specifies the number of days after the previous rotation * before Secrets Manager triggers the next automatic rotation. diff --git a/packages/@aws-cdk/aws-rds/lib/serverless-cluster.ts b/packages/@aws-cdk/aws-rds/lib/serverless-cluster.ts index 955b92ac58e5f..4e8aa6d46597d 100644 --- a/packages/@aws-cdk/aws-rds/lib/serverless-cluster.ts +++ b/packages/@aws-cdk/aws-rds/lib/serverless-cluster.ts @@ -10,7 +10,7 @@ import { DatabaseSecret } from './database-secret'; import { Endpoint } from './endpoint'; import { IParameterGroup } from './parameter-group'; import { DATA_API_ACTIONS } from './perms'; -import { defaultDeletionProtection, DEFAULT_PASSWORD_EXCLUDE_CHARS, renderCredentials } from './private/util'; +import { applyDefaultRotationOptions, defaultDeletionProtection, renderCredentials } from './private/util'; import { Credentials, RotationMultiUserOptions, RotationSingleUserOptions, SnapshotCredentials } from './props'; import { CfnDBCluster, CfnDBClusterProps } from './rds.generated'; import { ISubnetGroup, SubnetGroup } from './subnet-group'; @@ -558,13 +558,11 @@ export class ServerlessCluster extends ServerlessClusterNew { } return new secretsmanager.SecretRotation(this, id, { + ...applyDefaultRotationOptions(options, this.vpcSubnets), secret: this.secret, application: this.singleUserRotationApplication, vpc: this.vpc, - vpcSubnets: this.vpcSubnets, target: this, - ...options, - excludeCharacters: options.excludeCharacters ?? DEFAULT_PASSWORD_EXCLUDE_CHARS, }); } @@ -581,12 +579,11 @@ export class ServerlessCluster extends ServerlessClusterNew { } return new secretsmanager.SecretRotation(this, id, { - ...options, - excludeCharacters: options.excludeCharacters ?? DEFAULT_PASSWORD_EXCLUDE_CHARS, + ...applyDefaultRotationOptions(options, this.vpcSubnets), + secret: options.secret, masterSecret: this.secret, application: this.multiUserRotationApplication, vpc: this.vpc, - vpcSubnets: this.vpcSubnets, target: this, }); } diff --git a/packages/@aws-cdk/aws-rds/test/cluster.test.ts b/packages/@aws-cdk/aws-rds/test/cluster.test.ts index ea6123026cca5..a7c749e04a399 100644 --- a/packages/@aws-cdk/aws-rds/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-rds/test/cluster.test.ts @@ -889,15 +889,18 @@ describe('cluster', () => { }); }); - test('addRotationSingleUser() with options', () => { + test('addRotationSingleUser() with custom automaticallyAfter, excludeCharacters and vpcSubnets', () => { // GIVEN const stack = new cdk.Stack(); - const vpcWithIsolated = new ec2.Vpc(stack, 'Vpc', { - subnetConfiguration: [ - { name: 'public', subnetType: ec2.SubnetType.PUBLIC }, - { name: 'private', subnetType: ec2.SubnetType.PRIVATE_WITH_NAT }, - { name: 'isolated', subnetType: ec2.SubnetType.PRIVATE_ISOLATED }, - ], + const vpcWithIsolated = ec2.Vpc.fromVpcAttributes(stack, 'Vpc', { + vpcId: 'vpc-id', + availabilityZones: ['az1'], + publicSubnetIds: ['public-subnet-id-1', 'public-subnet-id-2'], + publicSubnetNames: ['public-subnet-name-1', 'public-subnet-name-2'], + privateSubnetIds: ['private-subnet-id-1', 'private-subnet-id-2'], + privateSubnetNames: ['private-subnet-name-1', 'private-subnet-name-2'], + isolatedSubnetIds: ['isolated-subnet-id-1', 'isolated-subnet-id-2'], + isolatedSubnetNames: ['isolated-subnet-name-1', 'isolated-subnet-name-2'], }); // WHEN @@ -935,20 +938,64 @@ describe('cluster', () => { { Ref: 'AWS::URLSuffix' }, ]], }, - functionName: 'DatabaseRotationSingleUser458A45BE', - vpcSubnetIds: { + vpcSubnetIds: 'private-subnet-id-1,private-subnet-id-2', + excludeCharacters: '°_@', + }, + }); + }); + + test('addRotationMultiUser() with custom automaticallyAfter, excludeCharacters and vpcSubnets', () => { + // GIVEN + const stack = new cdk.Stack(); + const vpcWithIsolated = ec2.Vpc.fromVpcAttributes(stack, 'Vpc', { + vpcId: 'vpc-id', + availabilityZones: ['az1'], + publicSubnetIds: ['public-subnet-id-1', 'public-subnet-id-2'], + publicSubnetNames: ['public-subnet-name-1', 'public-subnet-name-2'], + privateSubnetIds: ['private-subnet-id-1', 'private-subnet-id-2'], + privateSubnetNames: ['private-subnet-name-1', 'private-subnet-name-2'], + isolatedSubnetIds: ['isolated-subnet-id-1', 'isolated-subnet-id-2'], + isolatedSubnetNames: ['isolated-subnet-name-1', 'isolated-subnet-name-2'], + }); + const userSecret = new DatabaseSecret(stack, 'UserSecret', { username: 'user' }); + + // WHEN + // DB in isolated subnet (no internet connectivity) + const cluster = new DatabaseCluster(stack, 'Database', { + engine: DatabaseClusterEngine.AURORA_MYSQL, + instanceProps: { + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + vpc: vpcWithIsolated, + vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED }, + }, + }); + + // Rotation in private subnet (internet via NAT) + cluster.addRotationMultiUser('user', { + secret: userSecret.attach(cluster), + automaticallyAfter: cdk.Duration.days(15), + excludeCharacters: '°_@', + vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_NAT }, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::RotationSchedule', { + RotationRules: { + AutomaticallyAfterDays: 15, + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::Serverless::Application', { + Parameters: { + endpoint: { 'Fn::Join': ['', [ - { Ref: 'VpcprivateSubnet1SubnetCEAD3716' }, - ',', - { Ref: 'VpcprivateSubnet2Subnet2DE7549C' }, + 'https://secretsmanager.', + { Ref: 'AWS::Region' }, + '.', + { Ref: 'AWS::URLSuffix' }, ]], }, - vpcSecurityGroupIds: { - 'Fn::GetAtt': [ - 'DatabaseRotationSingleUserSecurityGroupAC6E0E73', - 'GroupId', - ], - }, + vpcSubnetIds: 'private-subnet-id-1,private-subnet-id-2', excludeCharacters: '°_@', }, }); diff --git a/packages/@aws-cdk/aws-rds/test/instance.test.ts b/packages/@aws-cdk/aws-rds/test/instance.test.ts index 2cb7e5ebb95fc..05881f57129e0 100644 --- a/packages/@aws-cdk/aws-rds/test/instance.test.ts +++ b/packages/@aws-cdk/aws-rds/test/instance.test.ts @@ -797,14 +797,17 @@ describe('instance', () => { }); }); - test('addRotationSingleUser() with options', () => { + test('addRotationSingleUser() with custom automaticallyAfter, excludeCharacters and vpcSubnets', () => { // GIVEN - const vpcWithIsolated = new ec2.Vpc(stack, 'Vpc', { - subnetConfiguration: [ - { name: 'public', subnetType: ec2.SubnetType.PUBLIC }, - { name: 'private', subnetType: ec2.SubnetType.PRIVATE_WITH_NAT }, - { name: 'isolated', subnetType: ec2.SubnetType.PRIVATE_ISOLATED }, - ], + const vpcWithIsolated = ec2.Vpc.fromVpcAttributes(stack, 'Vpc', { + vpcId: 'vpc-id', + availabilityZones: ['az1'], + publicSubnetIds: ['public-subnet-id-1', 'public-subnet-id-2'], + publicSubnetNames: ['public-subnet-name-1', 'public-subnet-name-2'], + privateSubnetIds: ['private-subnet-id-1', 'private-subnet-id-2'], + privateSubnetNames: ['private-subnet-name-1', 'private-subnet-name-2'], + isolatedSubnetIds: ['isolated-subnet-id-1', 'isolated-subnet-id-2'], + isolatedSubnetNames: ['isolated-subnet-name-1', 'isolated-subnet-name-2'], }); // WHEN @@ -839,26 +842,69 @@ describe('instance', () => { { Ref: 'AWS::URLSuffix' }, ]], }, - functionName: 'DatabaseRotationSingleUser458A45BE', - vpcSubnetIds: { + vpcSubnetIds: 'private-subnet-id-1,private-subnet-id-2', + excludeCharacters: '°_@', + }, + }); + }); + + test('addRotationMultiUser() with custom automaticallyAfter, excludeCharacters and vpcSubnets', () => { + // GIVEN + const vpcWithIsolated = ec2.Vpc.fromVpcAttributes(stack, 'Vpc', { + vpcId: 'vpc-id', + availabilityZones: ['az1'], + publicSubnetIds: ['public-subnet-id-1', 'public-subnet-id-2'], + publicSubnetNames: ['public-subnet-name-1', 'public-subnet-name-2'], + privateSubnetIds: ['private-subnet-id-1', 'private-subnet-id-2'], + privateSubnetNames: ['private-subnet-name-1', 'private-subnet-name-2'], + isolatedSubnetIds: ['isolated-subnet-id-1', 'isolated-subnet-id-2'], + isolatedSubnetNames: ['isolated-subnet-name-1', 'isolated-subnet-name-2'], + }); + const userSecret = new rds.DatabaseSecret(stack, 'UserSecret', { username: 'user' }); + + // WHEN + // DB in isolated subnet (no internet connectivity) + const instance = new rds.DatabaseInstance(stack, 'Database', { + engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_10 }), + vpc: vpcWithIsolated, + vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED }, + }); + + // Rotation in private subnet (internet via NAT) + instance.addRotationMultiUser('user', { + secret: userSecret.attach(instance), + automaticallyAfter: cdk.Duration.days(15), + excludeCharacters: '°_@', + vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_NAT }, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::RotationSchedule', { + RotationRules: { + AutomaticallyAfterDays: 15, + }, + }); + + vpcWithIsolated.selectSubnets({ + subnetType: ec2.SubnetType.PRIVATE_WITH_NAT, + }).subnetIds; + + Template.fromStack(stack).hasResourceProperties('AWS::Serverless::Application', { + Parameters: { + endpoint: { 'Fn::Join': ['', [ - { Ref: 'VpcprivateSubnet1SubnetCEAD3716' }, - ',', - { Ref: 'VpcprivateSubnet2Subnet2DE7549C' }, + 'https://secretsmanager.', + { Ref: 'AWS::Region' }, + '.', + { Ref: 'AWS::URLSuffix' }, ]], }, - vpcSecurityGroupIds: { - 'Fn::GetAtt': [ - 'DatabaseRotationSingleUserSecurityGroupAC6E0E73', - 'GroupId', - ], - }, + vpcSubnetIds: 'private-subnet-id-1,private-subnet-id-2', excludeCharacters: '°_@', }, }); }); - test('addRotationSingleUser() with VPC interface endpoint', () => { // GIVEN const vpcIsolatedOnly = new ec2.Vpc(stack, 'Vpc', { natGateways: 0 }); diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index 42d6a84bdc18b..321f65603c14c 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -2297,6 +2297,16 @@ export enum EventType { */ OBJECT_RESTORE_COMPLETED = 's3:ObjectRestore:Completed', + /** + * Using restore object event types you can receive notifications for + * initiation and completion when restoring objects from the S3 Glacier + * storage class. + * + * You use s3:ObjectRestore:Delete to request notification of + * restoration completion. + */ + OBJECT_RESTORE_DELETE = 's3:ObjectRestore:Delete', + /** * You can use this event type to request Amazon S3 to send a notification * message when Amazon S3 detects that an object of the RRS storage class is diff --git a/packages/@aws-cdk/cfnspec/spec-source/cfn-docs/cfn-docs.json b/packages/@aws-cdk/cfnspec/spec-source/cfn-docs/cfn-docs.json index 6add4bc83193c..ac2b4d0caddc7 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/cfn-docs/cfn-docs.json +++ b/packages/@aws-cdk/cfnspec/spec-source/cfn-docs/cfn-docs.json @@ -653,6 +653,7 @@ "Name": "The name of the component.", "Overrides": "Describes the component's properties that can be overriden in a customized instance of the component. You can't specify `tags` as a valid property for `overrides` .", "Properties": "Describes the component's properties. You can't specify `tags` as a valid property for `properties` .", + "SchemaVersion": "The schema version of the component when it was imported.", "SourceId": "The unique ID of the component in its original source system, such as Figma.", "Tags": "One or more key-value pairs to use when tagging the component.", "Variants": "A list of the component's variants. A variant is a unique style configuration of a main component." @@ -925,6 +926,7 @@ "properties": { "BasePath": "The base path name that callers of the API must provide in the URL after the domain name.", "DomainName": "The `DomainName` of an [AWS::ApiGateway::DomainName](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-domainname.html) resource.", + "Id": "", "RestApiId": "The ID of the API.", "Stage": "The name of the API's stage." } @@ -5134,7 +5136,7 @@ "MixedInstancesPolicy": "An embedded object that specifies a mixed instances policy.\n\nThe policy includes properties that not only define the distribution of On-Demand Instances and Spot Instances, the maximum price to pay for Spot Instances (optional), and how the Auto Scaling group allocates instance types to fulfill On-Demand and Spot capacities, but also the properties that specify the instance configuration information\u2014the launch template and instance types. The policy can also include a weight for each instance type and different launch templates for individual instance types.\n\nFor more information, see [Auto Scaling groups with multiple instance types and purchase options](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-mixed-instances-groups.html) in the *Amazon EC2 Auto Scaling User Guide* .\n\nIf you specify `LaunchTemplate` , `InstanceId` , or `LaunchConfigurationName` , don't specify `MixedInstancesPolicy` .", "NewInstancesProtectedFromScaleIn": "Indicates whether newly launched instances are protected from termination by Amazon EC2 Auto Scaling when scaling in. For more information about preventing instances from terminating on scale in, see [Instance Protection](https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-instance-termination.html#instance-protection) in the *Amazon EC2 Auto Scaling User Guide* .", "NotificationConfigurations": "Configures an Auto Scaling group to send notifications when specified events take place.", - "PlacementGroup": "The name of the placement group into which you want to launch your instances. A placement group is a logical grouping of instances within a single Availability Zone. For more information, see [Placement Groups](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html) in the *Amazon EC2 User Guide for Linux Instances* .", + "PlacementGroup": "The name of the placement group into which you want to launch your instances. For more information, see [Placement groups](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/placement-groups.html) in the *Amazon EC2 User Guide for Linux Instances* .\n\n> A *cluster* placement group is a logical grouping of instances within a single Availability Zone. You cannot specify multiple Availability Zones and a cluster placement group.", "ServiceLinkedRoleARN": "The Amazon Resource Name (ARN) of the service-linked role that the Auto Scaling group uses to call other AWS services on your behalf. By default, Amazon EC2 Auto Scaling uses a service-linked role named `AWSServiceRoleForAutoScaling` , which it creates if it does not exist. For more information, see [Service-linked roles for Amazon EC2 Auto Scaling](https://docs.aws.amazon.com/autoscaling/ec2/userguide/autoscaling-service-linked-role.html) in the *Amazon EC2 Auto Scaling User Guide* .", "Tags": "One or more tags. You can tag your Auto Scaling group and propagate the tags to the Amazon EC2 instances it launches. For more information, see [Tagging Auto Scaling groups and instances](https://docs.aws.amazon.com/autoscaling/ec2/userguide/autoscaling-tagging.html) in the *Amazon EC2 Auto Scaling User Guide* .", "TargetGroupARNs": "One or more Amazon Resource Names (ARN) of load balancer target groups to associate with the Auto Scaling group. Instances are registered as targets in a target group, and traffic is routed to the target group. For more information, see [Elastic Load Balancing and Amazon EC2 Auto Scaling](https://docs.aws.amazon.com/autoscaling/ec2/userguide/autoscaling-load-balancer.html) in the *Amazon EC2 Auto Scaling User Guide* .", @@ -13880,7 +13882,7 @@ "InstanceWarmupPeriod": "The period of time, in seconds, after a newly launched Amazon EC2 instance can contribute to CloudWatch metrics for Auto Scaling group. If this parameter is omitted, the default value of `300` seconds is used.", "MaximumScalingStepSize": "The maximum number of container instances that Amazon ECS scales in or scales out at one time. If this parameter is omitted, the default value of `10000` is used.", "MinimumScalingStepSize": "The minimum number of container instances that Amazon ECS scales in or scales out at one time. If this parameter is omitted, the default value of `1` is used.", - "Status": "Determines whether to enable managed scaling for the capacity provider.", + "Status": "Determines whether to use managed scaling for the capacity provider.", "TargetCapacity": "The target capacity value for the capacity provider. The specified value must be greater than `0` and less than or equal to `100` . A value of `100` results in the Amazon EC2 instances in your Auto Scaling group being completely used." } }, @@ -13917,7 +13919,7 @@ }, "AWS::ECS::Cluster.ClusterSettings": { "attributes": {}, - "description": "The settings to use when creating a cluster. This parameter is used to enable CloudWatch Container Insights for a cluster.", + "description": "The settings to use when creating a cluster. This parameter is used to turn on CloudWatch Container Insights for a cluster.", "properties": { "Name": "The name of the cluster setting. The only supported value is `containerInsights` .", "Value": "The value to set for the cluster setting. The supported values are `enabled` and `disabled` . If `enabled` is specified, CloudWatch Container Insights will be enabled for the cluster, otherwise it will be disabled unless the `containerInsights` account setting is enabled. If a cluster value is specified, it will override the `containerInsights` value set with [PutAccountSetting](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_PutAccountSetting.html) or [PutAccountSettingDefault](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_PutAccountSettingDefault.html) ." @@ -13936,7 +13938,7 @@ "attributes": {}, "description": "The log configuration for the results of the execute command actions. The logs can be sent to CloudWatch Logs or an Amazon S3 bucket.", "properties": { - "CloudWatchEncryptionEnabled": "Determines whether to enable encryption on the CloudWatch logs. If not specified, encryption will be disabled.", + "CloudWatchEncryptionEnabled": "Determines whether to use encryption on the CloudWatch logs. If not specified, encryption will be disabled.", "CloudWatchLogGroupName": "The name of the CloudWatch log group to send logs to.\n\n> The CloudWatch log group must already be created.", "S3BucketName": "The name of the S3 bucket to send logs to.\n\n> The S3 bucket must already be created.", "S3EncryptionEnabled": "Determines whether to use encryption on the S3 logs. If not specified, encryption is not used.", @@ -13987,7 +13989,7 @@ "DeploymentConfiguration": "Optional deployment parameters that control how many tasks run during the deployment and the ordering of stopping and starting tasks.", "DeploymentController": "The deployment controller to use for the service. If no deployment controller is specified, the default value of `ECS` is used.", "DesiredCount": "The number of instantiations of the specified task definition to place and keep running on your cluster.\n\nFor new services, if a desired count is not specified, a default value of `1` is used. When using the `DAEMON` scheduling strategy, the desired count is not required.\n\nFor existing services, if a desired count is not specified, it is omitted from the operation.", - "EnableECSManagedTags": "Specifies whether to enable Amazon ECS managed tags for the tasks within the service. For more information, see [Tagging Your Amazon ECS Resources](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-using-tags.html) in the *Amazon Elastic Container Service Developer Guide* .", + "EnableECSManagedTags": "Specifies whether to turn on Amazon ECS managed tags for the tasks within the service. For more information, see [Tagging Your Amazon ECS Resources](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-using-tags.html) in the *Amazon Elastic Container Service Developer Guide* .", "EnableExecuteCommand": "Determines whether the execute command functionality is enabled for the service. If `true` , the execute command functionality is enabled for all containers in tasks as part of the service.", "HealthCheckGracePeriodSeconds": "The period of time, in seconds, that the Amazon ECS service scheduler ignores unhealthy Elastic Load Balancing target health checks after a task has first started. This is only used when your service is configured to use a load balancer. If your service has a load balancer defined and you don't specify a health check grace period value, the default value of `0` is used.\n\nIf you do not use an Elastic Load Balancing, we recomend that you use the `startPeriod` in the task definition healtch check parameters. For more information, see [Health check](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_HealthCheck.html) .\n\nIf your service's tasks take a while to start and respond to Elastic Load Balancing health checks, you can specify a health check grace period of up to 2,147,483,647 seconds (about 69 years). During that time, the Amazon ECS service scheduler ignores health check status. This grace period can prevent the service scheduler from marking tasks as unhealthy and stopping them before they have time to come up.", "LaunchType": "The launch type on which to run your service. For more information, see [Amazon ECS Launch Types](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/launch_types.html) in the *Amazon Elastic Container Service Developer Guide* .", @@ -14027,8 +14029,8 @@ "attributes": {}, "description": "> The deployment circuit breaker can only be used for services using the rolling update ( `ECS` ) deployment type. \n\nThe `DeploymentCircuitBreaker` property determines whether a service deployment will fail if the service can't reach a steady state. If deployment circuit breaker is enabled, a service deployment will transition to a failed state and stop launching new tasks. If rollback is enabled, when a service deployment fails, the service is rolled back to the last deployment that completed successfully.", "properties": { - "Enable": "Determines whether to enable the deployment circuit breaker logic for the service.", - "Rollback": "Determines whether to enable Amazon ECS to roll back the service if a service deployment fails. If rollback is enabled, when a service deployment fails, the service is rolled back to the last deployment that completed successfully." + "Enable": "Determines whether to use the deployment circuit breaker logic for the service.", + "Rollback": "Determines whether to configure Amazon ECS to roll back the service if a service deployment fails. If rollback is enabled, when a service deployment fails, the service is rolled back to the last deployment that completed successfully." } }, "AWS::ECS::Service.DeploymentConfiguration": { @@ -14129,7 +14131,7 @@ "properties": { "Command": "The command that's passed to the container. This parameter maps to `Cmd` in the [Create a container](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/#operation/ContainerCreate) section of the [Docker Remote API](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/) and the `COMMAND` parameter to [docker run](https://docs.aws.amazon.com/https://docs.docker.com/engine/reference/run/#security-configuration) . For more information, see [https://docs.docker.com/engine/reference/builder/#cmd](https://docs.aws.amazon.com/https://docs.docker.com/engine/reference/builder/#cmd) . If there are multiple arguments, each argument is a separated string in the array.", "Cpu": "The number of `cpu` units reserved for the container. This parameter maps to `CpuShares` in the [Create a container](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/#operation/ContainerCreate) section of the [Docker Remote API](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/) and the `--cpu-shares` option to [docker run](https://docs.aws.amazon.com/https://docs.docker.com/engine/reference/run/#security-configuration) .\n\nThis field is optional for tasks using the Fargate launch type, and the only requirement is that the total amount of CPU reserved for all containers within a task be lower than the task-level `cpu` value.\n\n> You can determine the number of CPU units that are available per EC2 instance type by multiplying the vCPUs listed for that instance type on the [Amazon EC2 Instances](https://docs.aws.amazon.com/ec2/instance-types/) detail page by 1,024. \n\nLinux containers share unallocated CPU units with other containers on the container instance with the same ratio as their allocated amount. For example, if you run a single-container task on a single-core instance type with 512 CPU units specified for that container, and that's the only task running on the container instance, that container could use the full 1,024 CPU unit share at any given time. However, if you launched another copy of the same task on that container instance, each task is guaranteed a minimum of 512 CPU units when needed. Moreover, each container could float to higher CPU usage if the other container was not using it. If both tasks were 100% active all of the time, they would be limited to 512 CPU units.\n\nOn Linux container instances, the Docker daemon on the container instance uses the CPU value to calculate the relative CPU share ratios for running containers. For more information, see [CPU share constraint](https://docs.aws.amazon.com/https://docs.docker.com/engine/reference/run/#cpu-share-constraint) in the Docker documentation. The minimum valid CPU share value that the Linux kernel allows is 2. However, the CPU parameter isn't required, and you can use CPU values below 2 in your container definitions. For CPU values below 2 (including null), the behavior varies based on your Amazon ECS container agent version:\n\n- *Agent versions less than or equal to 1.1.0:* Null and zero CPU values are passed to Docker as 0, which Docker then converts to 1,024 CPU shares. CPU values of 1 are passed to Docker as 1, which the Linux kernel converts to two CPU shares.\n- *Agent versions greater than or equal to 1.2.0:* Null, zero, and CPU values of 1 are passed to Docker as 2.\n\nOn Windows container instances, the CPU limit is enforced as an absolute limit, or a quota. Windows containers only have access to the specified amount of CPU that's described in the task definition. A null or zero CPU value is passed to Docker as `0` , which Windows interprets as 1% of one CPU.", - "DependsOn": "The dependencies defined for container startup and shutdown. A container can contain multiple dependencies. When a dependency is defined for container startup, for container shutdown it is reversed.\n\nFor tasks using the EC2 launch type, the container instances require at least version 1.26.0 of the container agent to enable container dependencies. However, we recommend using the latest container agent version. For information about checking your agent version and updating to the latest version, see [Updating the Amazon ECS Container Agent](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-agent-update.html) in the *Amazon Elastic Container Service Developer Guide* . If you're using an Amazon ECS-optimized Linux AMI, your instance needs at least version 1.26.0-1 of the `ecs-init` package. If your container instances are launched from version `20190301` or later, then they contain the required versions of the container agent and `ecs-init` . For more information, see [Amazon ECS-optimized Linux AMI](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-optimized_AMI.html) in the *Amazon Elastic Container Service Developer Guide* .\n\nFor tasks using the Fargate launch type, the task or service requires the following platforms:\n\n- Linux platform version `1.3.0` or later.\n- Windows platform version `1.0.0` or later.", + "DependsOn": "The dependencies defined for container startup and shutdown. A container can contain multiple dependencies. When a dependency is defined for container startup, for container shutdown it is reversed.\n\nFor tasks using the EC2 launch type, the container instances require at least version 1.26.0 of the container agent to turn on container dependencies. However, we recommend using the latest container agent version. For information about checking your agent version and updating to the latest version, see [Updating the Amazon ECS Container Agent](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-agent-update.html) in the *Amazon Elastic Container Service Developer Guide* . If you're using an Amazon ECS-optimized Linux AMI, your instance needs at least version 1.26.0-1 of the `ecs-init` package. If your container instances are launched from version `20190301` or later, then they contain the required versions of the container agent and `ecs-init` . For more information, see [Amazon ECS-optimized Linux AMI](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-optimized_AMI.html) in the *Amazon Elastic Container Service Developer Guide* .\n\nFor tasks using the Fargate launch type, the task or service requires the following platforms:\n\n- Linux platform version `1.3.0` or later.\n- Windows platform version `1.0.0` or later.", "DisableNetworking": "When this parameter is true, networking is disabled within the container. This parameter maps to `NetworkDisabled` in the [Create a container](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/#operation/ContainerCreate) section of the [Docker Remote API](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/) .\n\n> This parameter is not supported for Windows containers.", "DnsSearchDomains": "A list of DNS search domains that are presented to the container. This parameter maps to `DnsSearch` in the [Create a container](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/#operation/ContainerCreate) section of the [Docker Remote API](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/) and the `--dns-search` option to [docker run](https://docs.aws.amazon.com/https://docs.docker.com/engine/reference/run/#security-configuration) .\n\n> This parameter is not supported for Windows containers.", "DnsServers": "A list of DNS servers that are presented to the container. This parameter maps to `Dns` in the [Create a container](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/#operation/ContainerCreate) section of the [Docker Remote API](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/) and the `--dns` option to [docker run](https://docs.aws.amazon.com/https://docs.docker.com/engine/reference/run/#security-configuration) .\n\n> This parameter is not supported for Windows containers.", @@ -14159,8 +14161,8 @@ "RepositoryCredentials": "The private repository authentication credentials to use.", "ResourceRequirements": "The type and amount of a resource to assign to a container. The only supported resource is a GPU.", "Secrets": "The secrets to pass to the container. For more information, see [Specifying Sensitive Data](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data.html) in the *Amazon Elastic Container Service Developer Guide* .", - "StartTimeout": "Time duration (in seconds) to wait before giving up on resolving dependencies for a container. For example, you specify two containers in a task definition with containerA having a dependency on containerB reaching a `COMPLETE` , `SUCCESS` , or `HEALTHY` status. If a `startTimeout` value is specified for containerB and it doesn't reach the desired status within that time then containerA gives up and not start. This results in the task transitioning to a `STOPPED` state.\n\n> When the `ECS_CONTAINER_START_TIMEOUT` container agent configuration variable is used, it's enforced independently from this start timeout value. \n\nFor tasks using the Fargate launch type, the task or service requires the following platforms:\n\n- Linux platform version `1.3.0` or later.\n- Windows platform version `1.0.0` or later.\n\nFor tasks using the EC2 launch type, your container instances require at least version `1.26.0` of the container agent to enable a container start timeout value. However, we recommend using the latest container agent version. For information about checking your agent version and updating to the latest version, see [Updating the Amazon ECS Container Agent](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-agent-update.html) in the *Amazon Elastic Container Service Developer Guide* . If you're using an Amazon ECS-optimized Linux AMI, your instance needs at least version `1.26.0-1` of the `ecs-init` package. If your container instances are launched from version `20190301` or later, then they contain the required versions of the container agent and `ecs-init` . For more information, see [Amazon ECS-optimized Linux AMI](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-optimized_AMI.html) in the *Amazon Elastic Container Service Developer Guide* .", - "StopTimeout": "Time duration (in seconds) to wait before the container is forcefully killed if it doesn't exit normally on its own.\n\nFor tasks using the Fargate launch type, the task or service requires the following platforms:\n\n- Linux platform version `1.3.0` or later.\n- Windows platform version `1.0.0` or later.\n\nThe max stop timeout value is 120 seconds and if the parameter is not specified, the default value of 30 seconds is used.\n\nFor tasks that use the EC2 launch type, if the `stopTimeout` parameter isn't specified, the value set for the Amazon ECS container agent configuration variable `ECS_CONTAINER_STOP_TIMEOUT` is used. If neither the `stopTimeout` parameter or the `ECS_CONTAINER_STOP_TIMEOUT` agent configuration variable are set, then the default values of 30 seconds for Linux containers and 30 seconds on Windows containers are used. Your container instances require at least version 1.26.0 of the container agent to enable a container stop timeout value. However, we recommend using the latest container agent version. For information about checking your agent version and updating to the latest version, see [Updating the Amazon ECS Container Agent](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-agent-update.html) in the *Amazon Elastic Container Service Developer Guide* . If you're using an Amazon ECS-optimized Linux AMI, your instance needs at least version 1.26.0-1 of the `ecs-init` package. If your container instances are launched from version `20190301` or later, then they contain the required versions of the container agent and `ecs-init` . For more information, see [Amazon ECS-optimized Linux AMI](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-optimized_AMI.html) in the *Amazon Elastic Container Service Developer Guide* .", + "StartTimeout": "Time duration (in seconds) to wait before giving up on resolving dependencies for a container. For example, you specify two containers in a task definition with containerA having a dependency on containerB reaching a `COMPLETE` , `SUCCESS` , or `HEALTHY` status. If a `startTimeout` value is specified for containerB and it doesn't reach the desired status within that time then containerA gives up and not start. This results in the task transitioning to a `STOPPED` state.\n\n> When the `ECS_CONTAINER_START_TIMEOUT` container agent configuration variable is used, it's enforced independently from this start timeout value. \n\nFor tasks using the Fargate launch type, the task or service requires the following platforms:\n\n- Linux platform version `1.3.0` or later.\n- Windows platform version `1.0.0` or later.\n\nFor tasks using the EC2 launch type, your container instances require at least version `1.26.0` of the container agent to use a container start timeout value. However, we recommend using the latest container agent version. For information about checking your agent version and updating to the latest version, see [Updating the Amazon ECS Container Agent](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-agent-update.html) in the *Amazon Elastic Container Service Developer Guide* . If you're using an Amazon ECS-optimized Linux AMI, your instance needs at least version `1.26.0-1` of the `ecs-init` package. If your container instances are launched from version `20190301` or later, then they contain the required versions of the container agent and `ecs-init` . For more information, see [Amazon ECS-optimized Linux AMI](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-optimized_AMI.html) in the *Amazon Elastic Container Service Developer Guide* .", + "StopTimeout": "Time duration (in seconds) to wait before the container is forcefully killed if it doesn't exit normally on its own.\n\nFor tasks using the Fargate launch type, the task or service requires the following platforms:\n\n- Linux platform version `1.3.0` or later.\n- Windows platform version `1.0.0` or later.\n\nThe max stop timeout value is 120 seconds and if the parameter is not specified, the default value of 30 seconds is used.\n\nFor tasks that use the EC2 launch type, if the `stopTimeout` parameter isn't specified, the value set for the Amazon ECS container agent configuration variable `ECS_CONTAINER_STOP_TIMEOUT` is used. If neither the `stopTimeout` parameter or the `ECS_CONTAINER_STOP_TIMEOUT` agent configuration variable are set, then the default values of 30 seconds for Linux containers and 30 seconds on Windows containers are used. Your container instances require at least version 1.26.0 of the container agent to use a container stop timeout value. However, we recommend using the latest container agent version. For information about checking your agent version and updating to the latest version, see [Updating the Amazon ECS Container Agent](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-agent-update.html) in the *Amazon Elastic Container Service Developer Guide* . If you're using an Amazon ECS-optimized Linux AMI, your instance needs at least version 1.26.0-1 of the `ecs-init` package. If your container instances are launched from version `20190301` or later, then they contain the required versions of the container agent and `ecs-init` . For more information, see [Amazon ECS-optimized Linux AMI](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-optimized_AMI.html) in the *Amazon Elastic Container Service Developer Guide* .", "SystemControls": "A list of namespaced kernel parameters to set in the container. This parameter maps to `Sysctls` in the [Create a container](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/#operation/ContainerCreate) section of the [Docker Remote API](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/) and the `--sysctl` option to [docker run](https://docs.aws.amazon.com/https://docs.docker.com/engine/reference/run/#security-configuration) .\n\n> We don't recommended that you specify network-related `systemControls` parameters for multiple containers in a single task that also uses either the `awsvpc` or `host` network modes. For tasks that use the `awsvpc` network mode, the container that's started last determines which `systemControls` parameters take effect. For tasks that use the `host` network mode, it changes the container instance's namespaced kernel parameters as well as the containers.", "Ulimits": "A list of `ulimits` to set in the container. This parameter maps to `Ulimits` in the [Create a container](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/#operation/ContainerCreate) section of the [Docker Remote API](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/) and the `--ulimit` option to [docker run](https://docs.aws.amazon.com/https://docs.docker.com/engine/reference/run/) . Valid naming values are displayed in the [Ulimit](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_Ulimit.html) data type. This parameter requires version 1.18 of the Docker Remote API or greater on your container instance. To check the Docker Remote API version on your container instance, log in to your container instance and run the following command: `sudo docker version --format '{{.Server.APIVersion}}'`\n\n> This parameter is not supported for Windows containers.", "User": "The user to use inside the container. This parameter maps to `User` in the [Create a container](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/#operation/ContainerCreate) section of the [Docker Remote API](https://docs.aws.amazon.com/https://docs.docker.com/engine/api/v1.35/) and the `--user` option to [docker run](https://docs.aws.amazon.com/https://docs.docker.com/engine/reference/run/#security-configuration) .\n\n> When running tasks using the `host` network mode, don't run containers using the root user (UID 0). We recommend using a non-root user for better security. \n\nYou can specify the `user` using the following formats. If specifying a UID or GID, you must specify it as a positive integer.\n\n- `user`\n- `user:group`\n- `uid`\n- `uid:gid`\n- `user:gid`\n- `uid:group`\n\n> This parameter is not supported for Windows containers.", @@ -14203,7 +14205,7 @@ "AuthorizationConfig": "The authorization configuration details for the Amazon EFS file system.", "FilesystemId": "The Amazon EFS file system ID to use.", "RootDirectory": "The directory within the Amazon EFS file system to mount as the root directory inside the host. If this parameter is omitted, the root of the Amazon EFS volume will be used. Specifying `/` will have the same effect as omitting this parameter.\n\n> If an EFS access point is specified in the `authorizationConfig` , the root directory parameter must either be omitted or set to `/` which will enforce the path set on the EFS access point.", - "TransitEncryption": "Determines whether to enable encryption for Amazon EFS data in transit between the Amazon ECS host and the Amazon EFS server. Transit encryption must be enabled if Amazon EFS IAM authorization is used. If this parameter is omitted, the default value of `DISABLED` is used. For more information, see [Encrypting Data in Transit](https://docs.aws.amazon.com/efs/latest/ug/encryption-in-transit.html) in the *Amazon Elastic File System User Guide* .", + "TransitEncryption": "Determines whether to use encryption for Amazon EFS data in transit between the Amazon ECS host and the Amazon EFS server. Transit encryption must be enabled if Amazon EFS IAM authorization is used. If this parameter is omitted, the default value of `DISABLED` is used. For more information, see [Encrypting Data in Transit](https://docs.aws.amazon.com/efs/latest/ug/encryption-in-transit.html) in the *Amazon Elastic File System User Guide* .", "TransitEncryptionPort": "The port to use when sending encrypted data between the Amazon ECS host and the Amazon EFS server. If you do not specify a transit encryption port, it will use the port selection strategy that the Amazon EFS mount helper uses. For more information, see [EFS Mount Helper](https://docs.aws.amazon.com/efs/latest/ug/efs-mount-helper.html) in the *Amazon Elastic File System User Guide* ." } }, @@ -14467,7 +14469,7 @@ }, "AWS::ECS::TaskSet.ServiceRegistry": { "attributes": {}, - "description": "The details for the service registry.", + "description": "The details for the service registry.\n\nEach service may be associated with one service registry. Multiple service registries for each service are not supported.\n\nWhen you add, update, or remove the service registries configuration, Amazon ECS starts a new deployment. New tasks are registered and deregistered to the updated service registry configuration.", "properties": { "ContainerName": "The container name value to be used for your service discovery service. It's already specified in the task definition. If the task definition that your service task specifies uses the `bridge` or `host` network mode, you must specify a `containerName` and `containerPort` combination from the task definition. If the task definition that your service task specifies uses the `awsvpc` network mode and a type SRV DNS record is used, you must specify either a `containerName` and `containerPort` combination or a `port` value. However, you can't specify both.", "ContainerPort": "The port value to be used for your service discovery service. It's already specified in the task definition. If the task definition your service task specifies uses the `bridge` or `host` network mode, you must specify a `containerName` and `containerPort` combination from the task definition. If the task definition your service task specifies uses the `awsvpc` network mode and a type SRV DNS record is used, you must specify either a `containerName` and `containerPort` combination or a `port` value. However, you can't specify both.", @@ -14585,7 +14587,7 @@ "AWS::EKS::Addon": { "attributes": { "Arn": "The ARN of the add-on, such as `arn:aws:eks:us-west-2:111122223333:addon/1-19/vpc-cni/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` .", - "Ref": "`Ref` returns the resource name. For example:\n\n`{ \"Ref\": \"vpc-cni\" }`\n\nFor the add-on `vpc-cni` , `Ref` returns the name of the add-on. For example, `|` ." + "Ref": "`Ref` returns the resource name. For example:\n\n`{ \"Ref\": \"vpc-cni\" }`\n\nFor the add-on `vpc-cni` , `Ref` returns the name of the add-on. For example, `cluster-name|vpc-cni` ." }, "description": "Creates an Amazon EKS add-on.\n\nAmazon EKS add-ons help to automate the provisioning and lifecycle management of common operational software for Amazon EKS clusters. Amazon EKS add-ons require clusters running version 1.18 or later because Amazon EKS add-ons rely on the Server-side Apply Kubernetes feature, which is only available in Kubernetes 1.18 and later. For more information, see [Amazon EKS add-ons](https://docs.aws.amazon.com/eks/latest/userguide/eks-add-ons.html) in the *Amazon EKS User Guide* .", "properties": { @@ -14605,7 +14607,7 @@ "EncryptionConfigKeyArn": "Amazon Resource Name (ARN) or alias of the customer master key (CMK).", "Endpoint": "The endpoint for your Kubernetes API server, such as `https://5E1D0CEXAMPLEA591B746AFC5AB30262.yl4.us-west-2.eks.amazonaws.com` .", "KubernetesNetworkConfig.ServiceIpv6Cidr": "The CIDR block that Kubernetes Service IP addresses are assigned from if you created a 1.21 or later cluster with version 1.10.1 or later of the Amazon VPC CNI add-on and specified `ipv6` for *ipFamily* when you created the cluster. Kubernetes assigns Service addresses from the unique local address range ( `fc00::/7` ) because you can't specify a custom IPv6 CIDR block when you create the cluster.", - "OpenIdConnectIssuerUrl": "The issuer URL for the OIDC identity provider of the cluster, such as `https://oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E` . If you need to remove `https://` from this output value, you can include the following code in your template.\n\n`!Select [1, !Split [\"//\", !GetAtt EKSCluster.OpenIdConnectIssuerUrl]]`", + "OpenIdConnectIssuerUrl": "", "Ref": "`Ref` returns the resource name. For example:\n\n`{ \"Ref\": \"myCluster\" }`\n\nFor the Amazon EKS cluster `myCluster` , `Ref` returns the name of the cluster." }, "description": "Creates an Amazon EKS control plane.\n\nThe Amazon EKS control plane consists of control plane instances that run the Kubernetes software, such as `etcd` and the API server. The control plane runs in an account managed by AWS , and the Kubernetes API is exposed by the Amazon EKS API server endpoint. Each Amazon EKS cluster control plane is single tenant and unique. It runs on its own set of Amazon EC2 instances.\n\nThe cluster control plane is provisioned across multiple Availability Zones and fronted by an Elastic Load Balancing Network Load Balancer. Amazon EKS also provisions elastic network interfaces in your VPC subnets to provide connectivity from the control plane instances to the nodes (for example, to support `kubectl exec` , `logs` , and `proxy` data flows).\n\nAmazon EKS nodes run in your AWS account and connect to your cluster's control plane over the Kubernetes API server endpoint and a certificate file that is created for your cluster.\n\nIn most cases, it takes several minutes to create a cluster. After you create an Amazon EKS cluster, you must configure your Kubernetes tooling to communicate with the API server and launch nodes into your cluster. For more information, see [Managing Cluster Authentication](https://docs.aws.amazon.com/eks/latest/userguide/managing-auth.html) and [Launching Amazon EKS nodes](https://docs.aws.amazon.com/eks/latest/userguide/launch-workers.html) in the *Amazon EKS User Guide* .", @@ -14671,8 +14673,8 @@ }, "AWS::EKS::FargateProfile": { "attributes": { - "Arn": "The ARN of the Fargate profile, such as `arn:aws:eks:us-west-2:111122223333:fargateprofile/myCluster/myFargateProfile/1cb1a11a-1dc1-1d11-cf11-1111f11fa111` .", - "Ref": "`Ref` returns the resource name. For example:\n\n`{ \"Ref\": \"myFargateProfile\" }`\n\nFor the Fargate profile `myFargateProfile` , Ref returns the physical resource ID of the Fargate profile. For example, `/` ." + "Arn": "The ARN of the cluster, such as `arn:aws:eks:us-west-2:666666666666:fargateprofile/myCluster/myFargateProfile/1cb1a11a-1dc1-1d11-cf11-1111f11fa111` .", + "Ref": "`Ref` returns the resource name. For example:\n\n`{ \"Ref\": \"myFargateProfile\" }`\n\nFor the Fargate profile `myFargateProfile` , Ref returns the physical resource ID of the Fargate profile. For example, `/` ." }, "description": "Creates an AWS Fargate profile for your Amazon EKS cluster. You must have at least one Fargate profile in a cluster to be able to run pods on Fargate.\n\nThe Fargate profile allows an administrator to declare which pods run on Fargate and specify which pods run on which Fargate profile. This declaration is done through the profile\u2019s selectors. Each profile can have up to five selectors that contain a namespace and labels. A namespace is required for every selector. The label field consists of multiple optional key-value pairs. Pods that match the selectors are scheduled on Fargate. If a to-be-scheduled pod matches any of the selectors in the Fargate profile, then that pod is run on Fargate.\n\nWhen you create a Fargate profile, you must specify a pod execution role to use with the pods that are scheduled with the profile. This role is added to the cluster's Kubernetes [Role Based Access Control](https://docs.aws.amazon.com/https://kubernetes.io/docs/admin/authorization/rbac/) (RBAC) for authorization so that the `kubelet` that is running on the Fargate infrastructure can register with your Amazon EKS cluster so that it can appear in your cluster as a node. The pod execution role also provides IAM permissions to the Fargate infrastructure to allow read access to Amazon ECR image repositories. For more information, see [Pod Execution Role](https://docs.aws.amazon.com/eks/latest/userguide/pod-execution-role.html) in the *Amazon EKS User Guide* .\n\nFargate profiles are immutable. However, you can create a new updated profile to replace an existing profile and then delete the original after the updated profile has finished creating.\n\nIf any Fargate profiles in a cluster are in the `DELETING` status, you must wait for that Fargate profile to finish deleting before you can create any other profiles in that cluster.\n\nFor more information, see [AWS Fargate Profile](https://docs.aws.amazon.com/eks/latest/userguide/fargate-profile.html) in the *Amazon EKS User Guide* .", "properties": { @@ -14700,13 +14702,48 @@ "Namespace": "The Kubernetes namespace that the selector should match." } }, + "AWS::EKS::IdentityProviderConfig": { + "attributes": { + "IdentityProviderConfigArn": "The Amazon Resource Name (ARN) associated with the identity provider config.", + "Ref": "`Ref` returns the resource name. For example:\n\n`{ \"Ref\": \"myIdentityProviderConfig\" }`\n\nFor the IdentityProviderConfig, Ref returns the physical resource ID of the config. For example, `cluster-name/oidc/identity-provider-config-name` ." + }, + "description": "Associate an identity provider configuration to a cluster.\n\nIf you want to authenticate identities using an identity provider, you can create an identity provider configuration and associate it to your cluster. After configuring authentication to your cluster you can create Kubernetes `roles` and `clusterroles` to assign permissions to the roles, and then bind the roles to the identities using Kubernetes `rolebindings` and `clusterrolebindings` . For more information see [Using RBAC Authorization](https://docs.aws.amazon.com/https://kubernetes.io/docs/reference/access-authn-authz/rbac/) in the Kubernetes documentation.\n\nThis resource isn't available in all AWS Regions .", + "properties": { + "ClusterName": "The cluster that the configuration is associated to.", + "IdentityProviderConfigName": "The name of the configuration.", + "Oidc": "An object that represents an OpenID Connect (OIDC) identity provider configuration.", + "Tags": "The metadata to apply to the provider configuration to assist with categorization and organization. Each tag consists of a key and an optional value. You define both.", + "Type": "The type of the identity provider configuration. The only type available is `oidc` ." + } + }, + "AWS::EKS::IdentityProviderConfig.OidcIdentityProviderConfig": { + "attributes": {}, + "description": "An object that represents the configuration for an OpenID Connect (OIDC) identity provider.\n\nThis resource isn't available in all AWS Regions .", + "properties": { + "ClientId": "This is also known as *audience* . The ID of the client application that makes authentication requests to the OIDC identity provider.", + "GroupsClaim": "The JSON web token (JWT) claim that the provider uses to return your groups.", + "GroupsPrefix": "The prefix that is prepended to group claims to prevent clashes with existing names (such as `system:` groups). For example, the value `oidc:` creates group names like `oidc:engineering` and `oidc:infra` . The prefix can't contain `system:`", + "IssuerUrl": "The URL of the OIDC identity provider that allows the API server to discover public signing keys for verifying tokens.", + "RequiredClaims": "The key-value pairs that describe required claims in the identity token. If set, each claim is verified to be present in the token with a matching value.", + "UsernameClaim": "The JSON Web token (JWT) claim that is used as the username.", + "UsernamePrefix": "The prefix that is prepended to username claims to prevent clashes with existing names. The prefix can't contain `system:`" + } + }, + "AWS::EKS::IdentityProviderConfig.RequiredClaim": { + "attributes": {}, + "description": "A key-value pair that describes a required claim in the identity token. If set, each claim is verified to be present in the token with a matching value.\n\nThis resource isn't available in all AWS Regions .", + "properties": { + "Key": "The key to match from the token.", + "Value": "The value for the key from the token." + } + }, "AWS::EKS::Nodegroup": { "attributes": { "Arn": "The Amazon Resource Name (ARN) associated with the managed node group.", "ClusterName": "The name of the cluster that the managed node group resides in.", "Id": "", "NodegroupName": "The name associated with an Amazon EKS managed node group.", - "Ref": "`Ref` returns the resource name. For example:\n\n`{ \"Ref\": \"myNodegroup\" }`\n\nFor the Amazon EKS node group `myNodegroup` , Ref returns the physical resource ID of the node group. For example, `/` ." + "Ref": "`Ref` returns the resource name. For example:\n\n`{ \"Ref\": \"myNodegroup\" }`\n\nFor the Amazon EKS node group `myNodegroup` , Ref returns the physical resource ID of the node group. For example, `cluster-name/nodegroup_name` ." }, "description": "Creates a managed node group for an Amazon EKS cluster. You can only create a node group for your cluster that is equal to the current Kubernetes version for the cluster. All node groups are created with the latest AMI release version for the respective minor Kubernetes version of the cluster, unless you deploy a custom AMI using a launch template. For more information about using launch templates, see [Launch template support](https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html) .\n\nAn Amazon EKS managed node group is an Amazon EC2 Auto Scaling group and associated Amazon EC2 instances that are managed by AWS for an Amazon EKS cluster. Each node group uses a version of the Amazon EKS optimized Amazon Linux 2 AMI. For more information, see [Managed Node Groups](https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html) in the *Amazon EKS User Guide* .", "properties": { @@ -15551,7 +15588,7 @@ "description": "The `AWS::ElastiCache::ReplicationGroup` resource creates an Amazon ElastiCache Redis replication group. A Redis (cluster mode disabled) replication group is a collection of cache clusters, where one of the clusters is a primary read-write cluster and the others are read-only replicas.\n\nA Redis (cluster mode enabled) cluster is comprised of from 1 to 90 shards (API/CLI: node groups). Each shard has a primary node and up to 5 read-only replica nodes. The configuration can range from 90 shards and 0 replicas to 15 shards and 5 replicas, which is the maximum number or replicas allowed.\n\nThe node or shard limit can be increased to a maximum of 500 per cluster if the Redis engine version is 5.0.6 or higher. For example, you can choose to configure a 500 node cluster that ranges between 83 shards (one primary and 5 replicas per shard) and 500 shards (single primary and no replicas). Make sure there are enough available IP addresses to accommodate the increase. Common pitfalls include the subnets in the subnet group have too small a CIDR range or the subnets are shared and heavily used by other clusters. For more information, see [Creating a Subnet Group](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/SubnetGroups.Creating.html) . For versions below 5.0.6, the limit is 250 per cluster.\n\nTo request a limit increase, see [Amazon Service Limits](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html) and choose the limit type *Nodes per cluster per instance type* .", "properties": { "AtRestEncryptionEnabled": "A flag that enables encryption at rest when set to `true` .\n\nYou cannot modify the value of `AtRestEncryptionEnabled` after the replication group is created. To enable encryption at rest on a replication group you must set `AtRestEncryptionEnabled` to `true` when you create the replication group.\n\n*Required:* Only available when creating a replication group in an Amazon VPC using redis version `3.2.6` or `4.x` onward.\n\nDefault: `false`", - "AuthToken": "*Reserved parameter.* The password used to access a password protected server.\n\n`AuthToken` can be specified only on replication groups where `TransitEncryptionEnabled` is `true` . For more information, see [Authenticating Users with the Redis AUTH Command](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/auth.html) .\n\n> For HIPAA compliance, you must specify `TransitEncryptionEnabled` as `true` , an `AuthToken` , and a `CacheSubnetGroup` . \n\nPassword constraints:\n\n- Must be only printable ASCII characters.\n- Must be at least 16 characters and no more than 128 characters in length.\n- Cannot contain any of the following characters: '/', '\"', or '@'.\n\nFor more information, see [AUTH password](https://docs.aws.amazon.com/http://redis.io/commands/AUTH) at http://redis.io/commands/AUTH.", + "AuthToken": "*Reserved parameter.* The password used to access a password protected server.\n\n`AuthToken` can be specified only on replication groups where `TransitEncryptionEnabled` is `true` . For more information, see [Authenticating Users with the Redis AUTH Command](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/auth.html) .\n\n> For HIPAA compliance, you must specify `TransitEncryptionEnabled` as `true` , an `AuthToken` , and a `CacheSubnetGroup` . \n\nPassword constraints:\n\n- Must be only printable ASCII characters.\n- Must be at least 16 characters and no more than 128 characters in length.\n- Nonalphanumeric characters are restricted to (!, &, #, $, ^, <, >, -, ).\n\nFor more information, see [AUTH password](https://docs.aws.amazon.com/http://redis.io/commands/AUTH) at http://redis.io/commands/AUTH.", "AutoMinorVersionUpgrade": "If you are running Redis engine version 6.0 or later, set this parameter to yes if you want to opt-in to the next minor version upgrade campaign. This parameter is disabled for previous versions.", "AutomaticFailoverEnabled": "Specifies whether a read-only replica is automatically promoted to read/write primary if the existing primary fails.\n\n`AutomaticFailoverEnabled` must be enabled for Redis (cluster mode enabled) replication groups.\n\nDefault: false", "CacheNodeType": "The compute and memory capacity of the nodes in the node group (shard).\n\nThe following node types are supported by ElastiCache. Generally speaking, the current generation types provide more memory and computational power at lower cost when compared to their equivalent previous generation counterparts.\n\n- General purpose:\n\n- Current generation:\n\n*M6g node types:* `cache.m6g.large` , `cache.m6g.xlarge` , `cache.m6g.2xlarge` , `cache.m6g.4xlarge` , `cache.m6g.12xlarge` , `cache.m6g.24xlarge`\n\n*M5 node types:* `cache.m5.large` , `cache.m5.xlarge` , `cache.m5.2xlarge` , `cache.m5.4xlarge` , `cache.m5.12xlarge` , `cache.m5.24xlarge`\n\n*M4 node types:* `cache.m4.large` , `cache.m4.xlarge` , `cache.m4.2xlarge` , `cache.m4.4xlarge` , `cache.m4.10xlarge`\n\n*T4g node types:* `cache.t4g.micro` , `cache.t4g.small` , `cache.t4g.medium`\n\n*T3 node types:* `cache.t3.micro` , `cache.t3.small` , `cache.t3.medium`\n\n*T2 node types:* `cache.t2.micro` , `cache.t2.small` , `cache.t2.medium`\n- Previous generation: (not recommended)\n\n*T1 node types:* `cache.t1.micro`\n\n*M1 node types:* `cache.m1.small` , `cache.m1.medium` , `cache.m1.large` , `cache.m1.xlarge`\n\n*M3 node types:* `cache.m3.medium` , `cache.m3.large` , `cache.m3.xlarge` , `cache.m3.2xlarge`\n- Compute optimized:\n\n- Previous generation: (not recommended)\n\n*C1 node types:* `cache.c1.xlarge`\n- Memory optimized:\n\n- Current generation:\n\n*R6gd node types:* `cache.r6gd.xlarge` , `cache.r6gd.2xlarge` , `cache.r6gd.4xlarge` , `cache.r6gd.8xlarge` , `cache.r6gd.12xlarge` , `cache.r6gd.16xlarge`\n\n> The `r6gd` family is available in the following regions: `us-east-2` , `us-east-1` , `us-west-2` , `us-west-1` , `eu-west-1` , `eu-central-1` , `ap-northeast-1` , `ap-southeast-1` , `ap-southeast-2` . \n\n*R6g node types:* `cache.r6g.large` , `cache.r6g.xlarge` , `cache.r6g.2xlarge` , `cache.r6g.4xlarge` , `cache.r6g.12xlarge` , `cache.r6g.24xlarge`\n\n*R5 node types:* `cache.r5.large` , `cache.r5.xlarge` , `cache.r5.2xlarge` , `cache.r5.4xlarge` , `cache.r5.12xlarge` , `cache.r5.24xlarge`\n\n*R4 node types:* `cache.r4.large` , `cache.r4.xlarge` , `cache.r4.2xlarge` , `cache.r4.4xlarge` , `cache.r4.8xlarge` , `cache.r4.16xlarge`\n- Previous generation: (not recommended)\n\n*M2 node types:* `cache.m2.xlarge` , `cache.m2.2xlarge` , `cache.m2.4xlarge`\n\n*R3 node types:* `cache.r3.large` , `cache.r3.xlarge` , `cache.r3.2xlarge` , `cache.r3.4xlarge` , `cache.r3.8xlarge`\n\nFor region availability, see [Supported Node Types by Amazon Region](https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/CacheNodes.SupportedTypes.html#CacheNodes.SupportedTypesByRegion)", @@ -20508,6 +20545,7 @@ "attributes": { "Arn": "Returns the Amazon Resource Name (ARN) of the image. For example, `arn:aws:imagebuilder:us-west-2:123456789012:image/mybasicrecipe/2019.12.03/1` .", "ImageId": "Returns the AMI ID of the Amazon EC2 AMI in the Region in which you are using Image Builder.", + "ImageUri": "", "Name": "Returns the name of the image.", "Ref": "`Ref` returns the resource ARN, such as `arn:aws:imagebuilder:us-west-2:123456789012:image/my-example-image` ." }, @@ -32900,7 +32938,7 @@ "AllowMajorVersionUpgrade": "A value that indicates whether major version upgrades are allowed. Changing this parameter doesn't result in an outage and the change is asynchronously applied as soon as possible.\n\nConstraints: Major version upgrades must be allowed when specifying a value for the `EngineVersion` parameter that is a different major version than the DB instance's current version.", "AssociatedRoles": "The AWS Identity and Access Management (IAM) roles associated with the DB instance.", "AutoMinorVersionUpgrade": "A value that indicates whether minor engine upgrades are applied automatically to the DB instance during the maintenance window. By default, minor engine upgrades are applied automatically.", - "AvailabilityZone": "The Availability Zone that the database instance will be created in.\n\nDefault: A random, system-chosen Availability Zone in the endpoint's region.\n\nExample: `us-east-1d`\n\nConstraint: The AvailabilityZone parameter cannot be specified if the MultiAZ parameter is set to `true` . The specified Availability Zone must be in the same region as the current endpoint.", + "AvailabilityZone": "The Availability Zone (AZ) where the database will be created. For information on AWS Regions and Availability Zones, see [Regions and Availability Zones](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html) .\n\n*Amazon Aurora*\n\nNot applicable. Availability Zones are managed by the DB cluster.\n\nDefault: A random, system-chosen Availability Zone in the endpoint's AWS Region.\n\nExample: `us-east-1d`\n\nConstraint: The `AvailabilityZone` parameter can't be specified if the DB instance is a Multi-AZ deployment. The specified Availability Zone must be in the same AWS Region as the current endpoint.\n\n> If you're creating a DB instance in an RDS on VMware environment, specify the identifier of the custom Availability Zone to create the DB instance in.\n> \n> For more information about RDS on VMware, see the [RDS on VMware User Guide.](https://docs.aws.amazon.com/AmazonRDS/latest/RDSonVMwareUserGuide/rds-on-vmware.html)", "BackupRetentionPeriod": "The number of days for which automated backups are retained. Setting this parameter to a positive number enables backups. Setting this parameter to 0 disables automated backups.\n\n*Amazon Aurora*\n\nNot applicable. The retention period for automated backups is managed by the DB cluster.\n\nDefault: 1\n\nConstraints:\n\n- Must be a value from 0 to 35\n- Can't be set to 0 if the DB instance is a source to read replicas", "CACertificateIdentifier": "The identifier of the CA certificate for this DB instance.\n\n> Specifying or updating this property triggers a reboot. \n\nFor more information about CA certificate identifiers for RDS DB engines, see [Rotating Your SSL/TLS Certificate](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL-certificate-rotation.html) in the *Amazon RDS User Guide* .\n\nFor more information about CA certificate identifiers for Aurora DB engines, see [Rotating Your SSL/TLS Certificate](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.SSL-certificate-rotation.html) in the *Amazon Aurora User Guide* .", "CharacterSetName": "For supported engines, indicates that the DB instance should be associated with the specified character set.\n\n*Amazon Aurora*\n\nNot applicable. The character set is managed by the DB cluster. For more information, see [AWS::RDS::DBCluster](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-dbcluster.html) .", @@ -32972,7 +33010,7 @@ }, "description": "The `AWS::RDS::DBParameterGroup` resource creates a custom parameter group for an RDS database family.\n\nThis type can be declared in a template and referenced in the `DBParameterGroupName` property of an `[AWS::RDS::DBInstance](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-database-instance.html)` resource.\n\nFor information about configuring parameters for Amazon RDS DB instances, see [Working with DB parameter groups](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithParamGroups.html) in the *Amazon RDS User Guide* .\n\nFor information about configuring parameters for Amazon Aurora DB instances, see [Working with DB parameter groups and DB cluster parameter groups](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/USER_WorkingWithParamGroups.html) in the *Amazon Aurora User Guide* .\n\n> Applying a parameter group to a DB instance may require the DB instance to reboot, resulting in a database outage for the duration of the reboot.", "properties": { - "Description": "Provides the customer-specified description for this DB Parameter Group.", + "Description": "Provides the customer-specified description for this DB parameter group.", "Family": "The DB parameter group family name. A DB parameter group can be associated with one and only one DB parameter group family, and can be applied only to a DB instance running a DB engine and engine version compatible with that DB parameter group family.\n\n> The DB parameter group family can't be changed when updating a DB parameter group. \n\nTo list all of the available parameter group families, use the following command:\n\n`aws rds describe-db-engine-versions --query \"DBEngineVersions[].DBParameterGroupFamily\"`\n\nThe output contains duplicates.\n\nFor more information, see `[CreateDBParameterGroup](https://docs.aws.amazon.com//AmazonRDS/latest/APIReference/API_CreateDBParameterGroup.html)` .", "Parameters": "An array of parameter names and values for the parameter update. At least one parameter name and value must be supplied. Subsequent arguments are optional.\n\nFor more information about DB parameters and DB parameter groups for Amazon RDS DB engines, see [Working with DB Parameter Groups](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithParamGroups.html) in the *Amazon RDS User Guide* .\n\nFor more information about DB cluster and DB instance parameters and parameter groups for Amazon Aurora DB engines, see [Working with DB Parameter Groups and DB Cluster Parameter Groups](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/USER_WorkingWithParamGroups.html) in the *Amazon Aurora User Guide* .\n\n> AWS CloudFormation doesn't support specifying an apply method for each individual parameter. The default apply method for each parameter is used.", "Tags": "Tags to assign to the DB parameter group." @@ -33076,7 +33114,7 @@ "properties": { "DBSecurityGroupIngress": "Ingress rules to be applied to the DB security group.", "EC2VpcId": "The identifier of an Amazon VPC. This property indicates the VPC that this DB security group belongs to.\n\n> The `EC2VpcId` property is for backward compatibility with older regions, and is no longer recommended for providing security information to an RDS DB instance.", - "GroupDescription": "Provides the description of the DB Security Group.", + "GroupDescription": "Provides the description of the DB security group.", "Tags": "Tags to assign to the DB security group." } }, @@ -33085,9 +33123,9 @@ "description": "The `Ingress` property type specifies an individual ingress rule within an `AWS::RDS::DBSecurityGroup` resource.", "properties": { "CIDRIP": "The IP range to authorize.", - "EC2SecurityGroupId": "Id of the EC2 Security Group to authorize. For VPC DB Security Groups, `EC2SecurityGroupId` must be provided. Otherwise, EC2SecurityGroupOwnerId and either `EC2SecurityGroupName` or `EC2SecurityGroupId` must be provided.", - "EC2SecurityGroupName": "Name of the EC2 Security Group to authorize. For VPC DB Security Groups, `EC2SecurityGroupId` must be provided. Otherwise, EC2SecurityGroupOwnerId and either `EC2SecurityGroupName` or `EC2SecurityGroupId` must be provided.", - "EC2SecurityGroupOwnerId": "AWS Account Number of the owner of the EC2 Security Group specified in the EC2SecurityGroupName parameter. The AWS Access Key ID is not an acceptable value. For VPC DB Security Groups, `EC2SecurityGroupId` must be provided. Otherwise, EC2SecurityGroupOwnerId and either `EC2SecurityGroupName` or `EC2SecurityGroupId` must be provided." + "EC2SecurityGroupId": "Id of the EC2 security group to authorize. For VPC DB security groups, `EC2SecurityGroupId` must be provided. Otherwise, `EC2SecurityGroupOwnerId` and either `EC2SecurityGroupName` or `EC2SecurityGroupId` must be provided.", + "EC2SecurityGroupName": "Name of the EC2 security group to authorize. For VPC DB security groups, `EC2SecurityGroupId` must be provided. Otherwise, `EC2SecurityGroupOwnerId` and either `EC2SecurityGroupName` or `EC2SecurityGroupId` must be provided.", + "EC2SecurityGroupOwnerId": "AWS account number of the owner of the EC2 security group specified in the `EC2SecurityGroupName` parameter. The AWS access key ID isn't an acceptable value. For VPC DB security groups, `EC2SecurityGroupId` must be provided. Otherwise, `EC2SecurityGroupOwnerId` and either `EC2SecurityGroupName` or `EC2SecurityGroupId` must be provided." } }, "AWS::RDS::DBSecurityGroupIngress": { @@ -33097,10 +33135,10 @@ "description": "The `AWS::RDS::DBSecurityGroupIngress` resource enables ingress to a DB security group using one of two forms of authorization. First, you can add EC2 or VPC security groups to the DB security group if the application using the database is running on EC2 or VPC instances. Second, IP ranges are available if the application accessing your database is running on the Internet.\n\nThis type supports updates. For more information about updating stacks, see [AWS CloudFormation Stacks Updates](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks.html) .\n\nFor details about the settings for DB security group ingress, see [AuthorizeDBSecurityGroupIngress](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_AuthorizeDBSecurityGroupIngress.html) .", "properties": { "CIDRIP": "The IP range to authorize.", - "DBSecurityGroupName": "The name of the DB Security Group to add authorization to.", - "EC2SecurityGroupId": "Id of the EC2 Security Group to authorize. For VPC DB Security Groups, `EC2SecurityGroupId` must be provided. Otherwise, EC2SecurityGroupOwnerId and either `EC2SecurityGroupName` or `EC2SecurityGroupId` must be provided.", - "EC2SecurityGroupName": "Name of the EC2 Security Group to authorize. For VPC DB Security Groups, `EC2SecurityGroupId` must be provided. Otherwise, EC2SecurityGroupOwnerId and either `EC2SecurityGroupName` or `EC2SecurityGroupId` must be provided.", - "EC2SecurityGroupOwnerId": "AWS Account Number of the owner of the EC2 Security Group specified in the EC2SecurityGroupName parameter. The AWS Access Key ID is not an acceptable value. For VPC DB Security Groups, `EC2SecurityGroupId` must be provided. Otherwise, EC2SecurityGroupOwnerId and either `EC2SecurityGroupName` or `EC2SecurityGroupId` must be provided." + "DBSecurityGroupName": "The name of the DB security group to add authorization to.", + "EC2SecurityGroupId": "Id of the EC2 security group to authorize. For VPC DB security groups, `EC2SecurityGroupId` must be provided. Otherwise, `EC2SecurityGroupOwnerId` and either `EC2SecurityGroupName` or `EC2SecurityGroupId` must be provided.", + "EC2SecurityGroupName": "Name of the EC2 security group to authorize. For VPC DB security groups, `EC2SecurityGroupId` must be provided. Otherwise, `EC2SecurityGroupOwnerId` and either `EC2SecurityGroupName` or `EC2SecurityGroupId` must be provided.", + "EC2SecurityGroupOwnerId": "AWS account number of the owner of the EC2 security group specified in the `EC2SecurityGroupName` parameter. The AWS access key ID isn't an acceptable value. For VPC DB security groups, `EC2SecurityGroupId` must be provided. Otherwise, `EC2SecurityGroupOwnerId` and either `EC2SecurityGroupName` or `EC2SecurityGroupId` must be provided." } }, "AWS::RDS::DBSubnetGroup": { @@ -33109,9 +33147,9 @@ }, "description": "The `AWS::RDS::DBSubnetGroup` resource creates a database subnet group. Subnet groups must contain at least two subnets in two different Availability Zones in the same region.\n\nFor more information, see [Working with DB subnet groups](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html#USER_VPC.Subnets) in the *Amazon RDS User Guide* .", "properties": { - "DBSubnetGroupDescription": "The description for the DB Subnet Group.", + "DBSubnetGroupDescription": "The description for the DB subnet group.", "DBSubnetGroupName": "The name for the DB subnet group. This value is stored as a lowercase string.\n\nConstraints: Must contain no more than 255 lowercase alphanumeric characters or hyphens. Must not be \"Default\".\n\nExample: `mysubnetgroup`", - "SubnetIds": "The EC2 Subnet IDs for the DB Subnet Group.", + "SubnetIds": "The EC2 Subnet IDs for the DB subnet group.", "Tags": "Tags to assign to the DB subnet group." } }, @@ -33121,8 +33159,8 @@ }, "description": "The `AWS::RDS::EventSubscription` resource allows you to receive notifications for Amazon Relational Database Service events through the Amazon Simple Notification Service (Amazon SNS). For more information, see [Using Amazon RDS Event Notification](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Events.html) in the *Amazon RDS User Guide* .", "properties": { - "Enabled": "A Boolean value; set to *true* to activate the subscription, set to *false* to create the subscription but not active it.", - "EventCategories": "A list of event categories for a SourceType that you want to subscribe to. You can see a list of the categories for a given SourceType in the [Events](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Events.html) topic in the Amazon RDS User Guide or by using the *DescribeEventCategories* action.", + "Enabled": "A value that indicates whether to activate the subscription. If the event notification subscription isn't activated, the subscription is created but not active.", + "EventCategories": "A list of event categories for a particular source type ( `SourceType` ) that you want to subscribe to. You can see a list of the categories for a given source type in the \"Amazon RDS event categories and event messages\" section of the [*Amazon RDS User Guide*](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Events.Messages.html) or the [*Amazon Aurora User Guide*](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/USER_Events.Messages.html) . You can also see this list by using the `DescribeEventCategories` operation.", "SnsTopicArn": "The Amazon Resource Name (ARN) of the SNS topic created for event notification. The ARN is created by Amazon SNS when you create a topic and subscribe to it.", "SourceIds": "The list of identifiers of the event sources for which events are returned. If not specified, then all sources are included in the response. An identifier must begin with a letter and must contain only ASCII letters, digits, and hyphens. It can't end with a hyphen or contain two consecutive hyphens.\n\nConstraints:\n\n- If a `SourceIds` value is supplied, `SourceType` must also be provided.\n- If the source type is a DB instance, a `DBInstanceIdentifier` value must be supplied.\n- If the source type is a DB cluster, a `DBClusterIdentifier` value must be supplied.\n- If the source type is a DB parameter group, a `DBParameterGroupName` value must be supplied.\n- If the source type is a DB security group, a `DBSecurityGroupName` value must be supplied.\n- If the source type is a DB snapshot, a `DBSnapshotIdentifier` value must be supplied.\n- If the source type is a DB cluster snapshot, a `DBClusterSnapshotIdentifier` value must be supplied.", "SourceType": "The type of source that is generating the events. For example, if you want to be notified of events generated by a DB instance, set this parameter to `db-instance` . If this value isn't specified, all events are returned.\n\nValid values: `db-instance` | `db-cluster` | `db-parameter-group` | `db-security-group` | `db-snapshot` | `db-cluster-snapshot`" @@ -37559,11 +37597,11 @@ "description": "Specifies that you want to create a hosted Lambda rotation function.\n\nTo use these values, you must specify `Transform: AWS::SecretsManager-2020-07-23` at the beginning of the CloudFormation template.", "properties": { "KmsKeyArn": "The ARN of the KMS key that Secrets Manager uses to encrypt the secret. If you don't specify this value, then Secrets Manager uses the key `aws/secretsmanager` . If `aws/secretsmanager` doesn't yet exist, then Secrets Manager creates it for you automatically the first time it encrypts the secret value.", - "MasterSecretArn": "The ARN of the secret that contains elevated credentials. The Lambda rotation function uses this secret for the [Alternating users rotation strategy](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets_strategies.html#rotating-secrets-two-users) .", + "MasterSecretArn": "The ARN of the secret that contains elevated credentials. You must create the elevated secret before you can set this property. The Lambda rotation function uses this secret for the [Alternating users rotation strategy](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets_strategies.html#rotating-secrets-two-users) .", "MasterSecretKmsKeyArn": "The ARN of the KMS key that Secrets Manager uses to encrypt the elevated secret if you use the [alternating users strategy](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets_strategies.html#rotating-secrets-two-users) . If you don't specify this value and you use the alternating users strategy, then Secrets Manager uses the key `aws/secretsmanager` . If `aws/secretsmanager` doesn't yet exist, then Secrets Manager creates it for you automatically the first time it encrypts the secret value.", "RotationLambdaName": "The name of the Lambda rotation function.", "RotationType": "The type of rotation template to use. For more information, see [Secrets Manager rotation function templates](https://docs.aws.amazon.com/secretsmanager/latest/userguide/reference_available-rotation-templates.html) .\n\nYou can specify one of the following `RotationTypes` :\n\n- MySQLSingleUser\n- MySQLMultiUser\n- PostgreSQLSingleUser\n- PostgreSQLMultiUser\n- OracleSingleUser\n- OracleMultiUser\n- MariaDBSingleUser\n- MariaDBMultiUser\n- SQLServerSingleUser\n- SQLServerMultiUser\n- RedshiftSingleUser\n- RedshiftMultiUser\n- MongoDBSingleUser\n- MongoDBMultiUser", - "SuperuserSecretArn": "The ARN of the secret that contains elevated credentials. The Lambda rotation function uses this secret for the [Alternating users rotation strategy](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets_strategies.html#rotating-secrets-two-users) .", + "SuperuserSecretArn": "The ARN of the secret that contains elevated credentials. You must create the superuser secret before you can set this property. The Lambda rotation function uses this secret for the [Alternating users rotation strategy](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets_strategies.html#rotating-secrets-two-users) .", "SuperuserSecretKmsKeyArn": "The ARN of the KMS key that Secrets Manager uses to encrypt the elevated secret if you use the [alternating users strategy](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets_strategies.html#rotating-secrets-two-users) . If you don't specify this value and you use the alternating users strategy, then Secrets Manager uses the key `aws/secretsmanager` . If `aws/secretsmanager` doesn't yet exist, then Secrets Manager creates it for you automatically the first time it encrypts the secret value.", "VpcSecurityGroupIds": "A comma-separated list of security group IDs applied to the target database.\n\nThe templates applies the same security groups as on the Lambda rotation function that is created as part of this stack.", "VpcSubnetIds": "A comma separated list of VPC subnet IDs of the target database network. The Lambda rotation function is in the same subnet group." @@ -38263,7 +38301,7 @@ "attributes": {}, "description": "Use this structure to input your script code for the canary. This structure contains the Lambda handler with the location where the canary should start running the script. If the script is stored in an S3 bucket, the bucket name, key, and version are also included. If the script is passed into the canary directly, the script code is contained in the value of `Script` .", "properties": { - "Handler": "The entry point to use for the source code when running the canary. This value must end with the string `.handler` . The string is limited to 29 characters or fewer.", + "Handler": "The entry point to use for the source code when running the canary. For canaries that use the `syn-python-selenium-1.0` runtime or a `syn-nodejs.puppeteer` runtime earlier than `syn-nodejs.puppeteer-3.4` , the handler must be specified as `*fileName* .handler` . For `syn-python-selenium-1.1` , `syn-nodejs.puppeteer-3.4` , and later runtimes, the handler can be specified as `*fileName* . *functionName*` , or you can specify a folder where canary scripts reside as `*folder* / *fileName* . *functionName*` .", "S3Bucket": "If your canary script is located in S3, specify the bucket name here. The bucket must already exist.", "S3Key": "The S3 key of your script. For more information, see [Working with Amazon S3 Objects](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingObjects.html) .", "S3ObjectVersion": "The S3 version ID of your script.", @@ -39031,21 +39069,21 @@ }, "description": "Defines an association between logging destinations and a web ACL resource, for logging from AWS WAF . As part of the association, you can specify parts of the standard logging fields to keep out of the logs and you can specify filters so that you log only a subset of the logging records.\n\n> You can define one logging destination per web ACL. \n\nYou can access information about the traffic that AWS WAF inspects using the following steps:\n\n- Create your logging destination. You can use an Amazon CloudWatch Logs log group, an Amazon Simple Storage Service (Amazon S3) bucket, or an Amazon Kinesis Data Firehose. For information about configuring logging destinations and the permissions that are required for each, see [Logging web ACL traffic information](https://docs.aws.amazon.com/waf/latest/developerguide/logging.html) in the *AWS WAF Developer Guide* .\n- Associate your logging destination to your web ACL using a `PutLoggingConfiguration` request.\n\nWhen you successfully enable logging using a `PutLoggingConfiguration` request, AWS WAF creates an additional role or policy that is required to write logs to the logging destination. For an Amazon CloudWatch Logs log group, AWS WAF creates a resource policy on the log group. For an Amazon S3 bucket, AWS WAF creates a bucket policy. For an Amazon Kinesis Data Firehose, AWS WAF creates a service-linked role.\n\nFor additional information about web ACL logging, see [Logging web ACL traffic information](https://docs.aws.amazon.com/waf/latest/developerguide/logging.html) in the *AWS WAF Developer Guide* .", "properties": { - "LogDestinationConfigs": "The Amazon Resource Names (ARNs) of the logging destinations that you want to associate with the web ACL.", + "LogDestinationConfigs": "The logging destination configuration that you want to associate with the web ACL.\n\n> You can associate one logging destination to a web ACL.", "LoggingFilter": "Filtering that specifies which web requests are kept in the logs and which are dropped. You can filter on the rule action and on the web request labels that were applied by matching rules during web ACL evaluation.", - "RedactedFields": "The parts of the request that you want to keep out of the logs. For example, if you redact the `SingleHeader` field, the `HEADER` field in the firehose will be `xxx` .\n\n> You can specify only the following fields for redaction: `UriPath` , `QueryString` , `SingleHeader` , `Method` , and `JsonBody` .", + "RedactedFields": "The parts of the request that you want to keep out of the logs. For example, if you redact the `SingleHeader` field, the `HEADER` field in the logs will be `xxx` .\n\n> You can specify only the following fields for redaction: `UriPath` , `QueryString` , `SingleHeader` , `Method` , and `JsonBody` .", "ResourceArn": "The Amazon Resource Name (ARN) of the web ACL that you want to associate with `LogDestinationConfigs` ." } }, "AWS::WAFv2::LoggingConfiguration.FieldToMatch": { "attributes": {}, - "description": "The parts of the request that you want to keep out of the logs. For example, if you redact the `SingleHeader` field, the `HEADER` field in the firehose will be `xxx` .\n\nJSON specification for a `QueryString` field to match:\n\n`\"FieldToMatch\": { \"QueryString\": {} }`\n\nExample JSON for a `Method` field to match specification:\n\n`\"FieldToMatch\": { \"Method\": { \"Name\": \"DELETE\" } }`", + "description": "The part of a web request that you want AWS WAF to inspect. Include the single `FieldToMatch` type that you want to inspect, with additional specifications as needed, according to the type. You specify a single request component in `FieldToMatch` for each rule statement that requires it. To inspect more than one component of a web request, create a separate rule statement for each component.\n\nJSON specification for a `QueryString` field to match:\n\n`\"FieldToMatch\": { \"QueryString\": {} }`\n\nExample JSON for a `Method` field to match specification:\n\n`\"FieldToMatch\": { \"Method\": { \"Name\": \"DELETE\" } }`", "properties": { - "JsonBody": "Redact the JSON body from the logs.", - "Method": "Redact the method from the logs.", - "QueryString": "Redact the query string from the logs.", - "SingleHeader": "Redact the header from the logs.", - "UriPath": "Redact the URI path from the logs." + "JsonBody": "Inspect the request body as JSON. The request body immediately follows the request headers. This is the part of a request that contains any additional data that you want to send to your web server as the HTTP request body, such as data from a form.\n\nNote that only the first 8 KB (8192 bytes) of the request body are forwarded to AWS WAF for inspection by the underlying host service. If you don't need to inspect more than 8 KB, you can guarantee that you don't allow additional bytes in by combining a statement that inspects the body of the web request, such as `ByteMatchStatement` or `RegexPatternSetReferenceStatement` , with a `SizeConstraintStatement` that enforces an 8 KB size limit on the body of the request. AWS WAF doesn't support inspecting the entire contents of web requests whose bodies exceed the 8 KB limit.", + "Method": "Inspect the HTTP method. The method indicates the type of operation that the request is asking the origin to perform.", + "QueryString": "Inspect the query string. This is the part of a URL that appears after a `?` character, if any.", + "SingleHeader": "Inspect a single header. Provide the name of the header to inspect, for example, `User-Agent` or `Referer` . This setting isn't case sensitive.\n\nExample JSON: `\"SingleHeader\": { \"Name\": \"haystack\" }`", + "UriPath": "Inspect the request URI path. This is the part of a web request that identifies a resource, for example, `/images/daily-ad.jpg` ." } }, "AWS::WAFv2::RegexPatternSet": { @@ -39553,7 +39591,7 @@ }, "AWS::WAFv2::WebACL.ManagedRuleGroupConfig": { "attributes": {}, - "description": "Additional information that's used by a managed rule group. Most managed rule groups don't require this.\n\nUse this for the account takeover prevention managed rule group `AWSManagedRulesATPRuleSet` , to provide information about the sign-in page of your application.", + "description": "Additional information that's used by a managed rule group. Most managed rule groups don't require this.\n\nUse this for the account takeover prevention managed rule group `AWSManagedRulesATPRuleSet` , to provide information about the sign-in page of your application.\n\nYou can provide multiple individual `ManagedRuleGroupConfig` objects for any rule group configuration, for example `UsernameField` and `PasswordField` . The configuration that you provide depends on the needs of the managed rule group. For the ATP managed rule group, you provide the following individual configuration objects: `LoginPath` , `PasswordField` , `PayloadType` and `UsernameField` .", "properties": { "LoginPath": "The path of the login endpoint for your application. For example, for the URL `https://example.com/web/login` , you would provide the path `/web/login` .", "PasswordField": "Details about your login page password field.", @@ -39566,7 +39604,7 @@ "description": "A rule statement used to run the rules that are defined in a managed rule group. To use this, provide the vendor name and the name of the rule group in this statement.\n\nYou can't nest a `ManagedRuleGroupStatement` , for example for use inside a `NotStatement` or `OrStatement` . It can only be referenced as a top-level statement within a rule.", "properties": { "ExcludedRules": "The rules whose actions are set to `COUNT` by the web ACL, regardless of the action that is configured in the rule. This effectively excludes the rule from acting on web requests.", - "ManagedRuleGroupConfigs": "Additional information that's used by a managed rule group. Most managed rule groups don't require this.\n\nUse this for the account takeover prevention managed rule group `AWSManagedRulesATPRuleSet` , to provide information about the sign-in page of your application.", + "ManagedRuleGroupConfigs": "Additional information that's used by a managed rule group. Most managed rule groups don't require this.\n\nUse this for the account takeover prevention managed rule group `AWSManagedRulesATPRuleSet` , to provide information about the sign-in page of your application.\n\nYou can provide multiple individual `ManagedRuleGroupConfig` objects for any rule group configuration, for example `UsernameField` and `PasswordField` . The configuration that you provide depends on the needs of the managed rule group. For the ATP managed rule group, you provide the following individual configuration objects: `LoginPath` , `PasswordField` , `PayloadType` and `UsernameField` .", "Name": "The name of the managed rule group. You use this, along with the vendor name, to identify the rule group.", "ScopeDownStatement": "Statement nested inside a managed rule group statement to narrow the scope of the requests that AWS WAF evaluates using the rule group. Requests that match the scope-down statement are evaluated using the rule group. Requests that don't match the scope-down statement are not a match for the managed rule group statement, without any further evaluation.", "VendorName": "The name of the managed rule group vendor. You use this, along with the rule group name, to identify the rule group.", @@ -39649,10 +39687,10 @@ }, "AWS::WAFv2::WebACL.RuleGroupReferenceStatement": { "attributes": {}, - "description": "A rule statement used to run the rules that are defined in a `RuleGroup` . To use this, create a rule group with your rules, then provide the ARN of the rule group in this statement.\n\nYou cannot nest a `RuleGroupReferenceStatement` , for example for use inside a `NotStatement` or `OrStatement` . It can only be referenced as a top-level statement within a rule.", + "description": "A rule statement used to run the rules that are defined in a `RuleGroup` . To use this, create a rule group with your rules, then provide the ARN of the rule group in this statement.\n\nYou cannot nest a `RuleGroupReferenceStatement` , for example for use inside a `NotStatement` or `OrStatement` . You can only use a rule group reference statement at the top level inside a web ACL.", "properties": { "Arn": "The Amazon Resource Name (ARN) of the entity.", - "ExcludedRules": "The names of rules that are in the referenced rule group, but that you want AWS WAF to exclude from processing for this rule statement." + "ExcludedRules": "The rules in the referenced rule group whose actions are set to `Count` . When you exclude a rule, AWS WAF evaluates it exactly as it would if the rule action setting were `Count` . This is a useful option for testing the rules in a rule group without modifying how they handle your web traffic." } }, "AWS::WAFv2::WebACL.SizeConstraintStatement": { diff --git a/packages/@aws-cdk/lambda-layer-awscli/layer/requirements.txt b/packages/@aws-cdk/lambda-layer-awscli/layer/requirements.txt index 2550f9594c2c7..96070a4e696a9 100644 --- a/packages/@aws-cdk/lambda-layer-awscli/layer/requirements.txt +++ b/packages/@aws-cdk/lambda-layer-awscli/layer/requirements.txt @@ -1 +1 @@ -awscli==1.22.63 +awscli==1.22.68 diff --git a/packages/@aws-cdk/pipelines/lib/codepipeline/codepipeline-source.ts b/packages/@aws-cdk/pipelines/lib/codepipeline/codepipeline-source.ts index 062df5b4b446f..0f95d41f5c940 100644 --- a/packages/@aws-cdk/pipelines/lib/codepipeline/codepipeline-source.ts +++ b/packages/@aws-cdk/pipelines/lib/codepipeline/codepipeline-source.ts @@ -139,21 +139,27 @@ export abstract class CodePipelineSource extends Step implements ICodePipelineAc * What attributes are available depends on the type of source. These attributes * are supported: * - * - GitHub, CodeCommit, and CodeStar connection + * - GitHub, CodeCommit, and CodeStarSourceConnection * - `AuthorDate` * - `BranchName` * - `CommitId` * - `CommitMessage` + * - GitHub, CodeCommit and ECR + * - `RepositoryName` * - GitHub and CodeCommit * - `CommitterDate` - * - `RepositoryName` * - GitHub * - `CommitUrl` - * - CodeStar Connection + * - CodeStarSourceConnection * - `FullRepositoryName` * - S3 * - `ETag` * - `VersionId` + * - ECR + * - `ImageDigest` + * - `ImageTag` + * - `ImageURI` + * - `RegistryId` * * @see https://docs.aws.amazon.com/codepipeline/latest/userguide/reference-variables.html#reference-variables-list */ diff --git a/packages/aws-cdk/lib/cli.ts b/packages/aws-cdk/lib/cli.ts index f63c60ca5ced0..00b9c16d4017b 100644 --- a/packages/aws-cdk/lib/cli.ts +++ b/packages/aws-cdk/lib/cli.ts @@ -235,10 +235,6 @@ if (!process.stdout.isTTY) { } async function initCommandLine() { - void refreshNotices() - .then(_ => debug('Notices refreshed')) - .catch(e => debug(`Notices refresh failed: ${e}`)); - const argv = await parseCommandLineArguments(); if (argv.verbose) { setLogLevel(argv.verbose); @@ -254,6 +250,12 @@ async function initCommandLine() { }); await configuration.load(); + if (shouldDisplayNotices()) { + void refreshNotices() + .then(_ => debug('Notices refreshed')) + .catch(e => debug(`Notices refresh failed: ${e}`)); + } + const sdkProvider = await SdkProvider.withAwsCliCompatibleDefaults({ profile: configuration.settings.get(['profile']), ec2creds: argv.ec2creds, @@ -326,10 +328,10 @@ async function initCommandLine() { }); } } + } - function shouldDisplayNotices(): boolean { - return configuration.settings.get(['notices']) ?? true; - } + function shouldDisplayNotices(): boolean { + return configuration.settings.get(['notices']) ?? true; } async function main(command: string, args: any): Promise { diff --git a/packages/aws-cdk/lib/notices.ts b/packages/aws-cdk/lib/notices.ts index 83b38412aa87b..fd92f4bf853c0 100644 --- a/packages/aws-cdk/lib/notices.ts +++ b/packages/aws-cdk/lib/notices.ts @@ -43,13 +43,14 @@ export async function displayNotices(props: DisplayNoticesProps) { export async function generateMessage(dataSource: NoticeDataSource, props: DisplayNoticesProps) { const data = await dataSource.fetch(); - const individualMessages = formatNotices(filterNotices(data, { + const filteredNotices = filterNotices(data, { outdir: props.outdir, acknowledgedIssueNumbers: new Set(props.acknowledgedIssueNumbers), - })); + }); - if (individualMessages.length > 0) { - return finalMessage(individualMessages, data[0].issueNumber); + if (filteredNotices.length > 0) { + const individualMessages = formatNotices(filteredNotices); + return finalMessage(individualMessages, filteredNotices[0].issueNumber); } return ''; } @@ -108,18 +109,15 @@ export class WebsiteNoticeDataSource implements NoticeDataSource { const timeout = 3000; return new Promise((resolve) => { + setTimeout(() => resolve([]), timeout); try { const req = https.get('https://cli.cdk.dev-tools.aws.dev/notices.json', { timeout }, res => { - const startTime = Date.now(); if (res.statusCode === 200) { res.setEncoding('utf8'); let rawData = ''; res.on('data', (chunk) => { - if (Date.now() - startTime > timeout) { - resolve([]); - } rawData += chunk; }); res.on('end', () => { diff --git a/packages/aws-cdk/test/integ/cli/cli.integtest.ts b/packages/aws-cdk/test/integ/cli/cli.integtest.ts index a0deaf1b3c3bc..42a4f55729a97 100644 --- a/packages/aws-cdk/test/integ/cli/cli.integtest.ts +++ b/packages/aws-cdk/test/integ/cli/cli.integtest.ts @@ -757,6 +757,20 @@ integTest('templates on disk contain metadata resource, also in nested assemblie expect(JSON.parse(nestedTemplateContents).Resources.CDKMetadata).toBeTruthy(); })); +integTest('skips notice refresh', withDefaultFixture(async (fixture) => { + const output = await fixture.cdkSynth({ + options: ['--no-notices'], + modEnv: { + INTEG_STACK_SET: 'stage-using-context', + }, + allowErrExit: true, + }); + + // Neither succeeds nor fails, but skips the refresh + await expect(output).not.toContain('Notices refreshed'); + await expect(output).not.toContain('Notices refresh failed'); +})); + async function listChildren(parent: string, pred: (x: string) => Promise) { const ret = new Array(); for (const child of await fs.readdir(parent, { encoding: 'utf-8' })) { diff --git a/packages/aws-cdk/test/integ/run-against-release b/packages/aws-cdk/test/integ/run-against-release index 1e4c0a8b3aba1..5bfcbbfae7e4f 100755 --- a/packages/aws-cdk/test/integ/run-against-release +++ b/packages/aws-cdk/test/integ/run-against-release @@ -5,6 +5,16 @@ # - Run the script set -eu scriptdir=$(cd $(dirname $0) && pwd) +CLI_INSTALLER="${CLI_INSTALLER:=npm}" + +if [ ${CLI_INSTALLER} = "npm" ]; then + install_command="install" +elif [ ${CLI_INSTALLER} = "yarn" ]; then + install_command="add" +else + echo "CLI_INSTALLER can only be set to either npm or yarn (got ${CLI_INSTALLER})" + exit 1 +fi # NPM Workspace. Will have CDK CLI installed into it. npmws=/tmp/cdk-runrelease @@ -12,7 +22,7 @@ rm -rf $npmws mkdir -p $npmws # Install the CLI and put it on the PATH -(cd $npmws && npm install aws-cdk@${RELEASE_TAG:-latest}) +(cd $npmws && ${CLI_INSTALLER} ${install_command} aws-cdk@${RELEASE_TAG:-latest}) # FRAMEWORK_VERSION is the version that will be 'npm install'ed by the tests if [[ "${FRAMEWORK_VERSION:-}" = "" ]]; then