From e0f863a4c56041860e14c75b9aa5a6d35860fae6 Mon Sep 17 00:00:00 2001 From: MayForBlue <60128296+MayForBlue@users.noreply.github.com> Date: Sat, 5 Mar 2022 16:04:10 +0900 Subject: [PATCH 01/17] feat(s3): add `s3:ObjectRestore:Delete` to `EventType` for notification (#19250) closes #19223 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-s3/lib/bucket.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) 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 From 37edda4653a819f2477adf42d1267b0353d91de8 Mon Sep 17 00:00:00 2001 From: Alex Pulver Date: Sun, 6 Mar 2022 19:44:11 +0200 Subject: [PATCH 02/17] chore(pipelines): ecr source attributes (#19260) Document the values for Amazon ECR source ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../lib/codepipeline/codepipeline-source.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) 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 */ From b1fce4f1641c90a4b7d1d33139453260b452d5cd Mon Sep 17 00:00:00 2001 From: Roger Chi Date: Sun, 6 Mar 2022 23:55:27 -0500 Subject: [PATCH 03/17] fix(aws-apigateway): missing comma to make failure response payload valid json (#19253) The failure response from a StepFunctionsRestApi integration is not valid JSON, it is missing a comma. This fixes the issue by adding a comma. Fixes #19252 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-apigateway/lib/integrations/stepfunctions.ts | 2 +- .../aws-apigateway/test/integ.stepfunctions-api.expected.json | 2 +- .../aws-apigateway/test/integrations/stepfunctions.test.ts | 2 +- packages/@aws-cdk/aws-apigateway/test/stepfunctions-api.test.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) 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', From e9e3067d37cd3fcdb55e86baac0941979912a2d0 Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Mon, 7 Mar 2022 01:42:14 -0800 Subject: [PATCH 04/17] docs(cfnspec): update CloudFormation documentation (#19263) Co-authored-by: AWS CDK Team --- .../spec-source/cfn-docs/cfn-docs.json | 100 ++++++++++++------ 1 file changed, 69 insertions(+), 31 deletions(-) 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..db50671e338e1 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* .", @@ -14700,6 +14702,41 @@ "Namespace": "The Kubernetes namespace that the selector should match." } }, + "AWS::EKS::IdentityProviderConfig": { + "attributes": { + "IdentityProviderConfigArn": "", + "Ref": "" + }, + "description": "An object representing an identity provider configuration.", + "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." + } + }, + "AWS::EKS::IdentityProviderConfig.OidcIdentityProviderConfig": { + "attributes": {}, + "description": "An object that represents the configuration for an OpenID Connect (OIDC) identity provider.", + "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": "", + "properties": { + "Key": "", + "Value": "" + } + }, "AWS::EKS::Nodegroup": { "attributes": { "Arn": "The Amazon Resource Name (ARN) associated with the managed node group.", @@ -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": { From 6cffa4bf40428042923b40cc7c5366c0a520acb8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Mar 2022 10:51:37 +0000 Subject: [PATCH 05/17] chore(deps): Bump actions/checkout from 2 to 3 (#19264) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
Release notes

Sourced from actions/checkout's releases.

v3.0.0

  • Update default runtime to node16

v2.4.0

  • Convert SSH URLs like org-<ORG_ID>@github.com: to https://github.com/ - pr

v2.3.5

Update dependencies

v2.3.4

v2.3.3

v2.3.2

Add Third Party License Information to Dist Files

v2.3.1

Fix default branch resolution for .wiki and when using SSH

v2.3.0

Fallback to the default branch

v2.2.0

Fetch all history for all tags and branches when fetch-depth=0

v2.1.1

Changes to support GHES (here and here)

v2.1.0

Changelog

Sourced from actions/checkout's changelog.

Changelog

v2.3.1

v2.3.0

v2.2.0

v2.1.1

  • Changes to support GHES (here and here)

v2.1.0

v2.0.0

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=2&new-version=3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- .github/workflows/cr-checklist.yml | 2 +- .github/workflows/pr-linter.yml | 2 +- .github/workflows/v2-pull-request.yml | 2 +- .github/workflows/yarn-upgrade.yml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) 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 From 242836b977f190c3f5eb7e13fde8f3d5fb68d707 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 7 Mar 2022 11:34:31 +0000 Subject: [PATCH 06/17] chore(deps): Bump awscli from 1.22.63 to 1.22.68 in /packages/@aws-cdk/lambda-layer-awscli (#19265) Bumps [awscli](https://github.com/aws/aws-cli) from 1.22.63 to 1.22.68.
Changelog

Sourced from awscli's changelog.

1.22.68

  • api-change:ec2: Documentation updates for Amazon EC2.
  • api-change:synthetics: Allow custom handler function.
  • api-change:transfer: Add waiters for server online and offline.
  • api-change:connect: This release updates the *InstanceStorageConfig APIs so they support a new ResourceType: REAL_TIME_CONTACT_ANALYSIS_SEGMENTS. Use this resource type to enable streaming for real-time contact analysis and to associate the Kinesis stream where real-time contact analysis segments will be published.
  • api-change:macie: Amazon Macie Classic (macie) has been discontinued and is no longer available. A new Amazon Macie (macie2) is now available with significant design improvements and additional features.
  • api-change:sts: Documentation updates for AWS Security Token Service.
  • api-change:devops-guru: Amazon DevOps Guru now integrates with Amazon CodeGuru Profiler. You can view CodeGuru Profiler recommendations for your AWS Lambda function in DevOps Guru. This feature is enabled by default for new customers as of 3/4/2022. Existing customers can enable this feature with UpdateEventSourcesConfig.

1.22.67

  • api-change:timestream-query: Documentation only update for SDK and CLI
  • api-change:greengrassv2: Doc only update that clarifies Create Deployment section.
  • api-change:kendra: Amazon Kendra now suggests spell corrections for a query. For more information, see https://docs.aws.amazon.com/kendra/latest/dg/query-spell-check.html
  • api-change:fsx: This release adds support for data repository associations to use root ("/") as the file system path
  • api-change:appflow: Launching Amazon AppFlow Marketo as a destination connector SDK.

1.22.66

  • api-change:athena: This release adds support for S3 Object Ownership by allowing the S3 bucket owner full control canned ACL to be set when Athena writes query results to S3 buckets.
  • api-change:ecr: This release adds support for tracking images lastRecordedPullTime.
  • api-change:keyspaces: This release adds support for data definition language (DDL) operations
  • api-change:gamelift: Minor updates to address errors.
  • api-change:cloudtrail: Add bytesScanned field into responses of DescribeQuery and GetQueryResults.

1.22.65

  • api-change:mgn: Add support for GP3 and IO2 volume types. Add bootMode to LaunchConfiguration object (and as a parameter to UpdateLaunchConfigurationRequest).
  • api-change:rds: Documentation updates for Multi-AZ DB clusters.
  • api-change:mediapackage: This release adds Hybridcast as an available profile option for Dash Origin Endpoints.
  • api-change:kafkaconnect: Adds operation for custom plugin deletion (DeleteCustomPlugin) and adds new StateDescription field to DescribeCustomPlugin and DescribeConnector responses to return errors from asynchronous resource creation.

1.22.64

  • api-change:ec2: This release adds support for new AMI property 'lastLaunchedTime'
  • api-change:fsx: This release adds support for the following FSx for OpenZFS features: snapshot lifecycle transition messages, force flag for deleting file systems with child resources, LZ4 data compression, custom record sizes, and unsetting volume quotas and reservations.
  • api-change:route53-recovery-cluster: This release adds a new API option to enable overriding safety rules to allow routing control state updates.
  • api-change:fis: This release adds logging support for AWS Fault Injection Simulator experiments. Experiment templates can now be configured to send experiment activity logs to Amazon CloudWatch Logs or to an S3 bucket.
  • api-change:servicecatalog-appregistry: AppRegistry is deprecating Application and Attribute-Group Name update feature. In this release, we are marking the name attributes for Update APIs as deprecated to give a heads up to our customers.
  • api-change:athena: This release adds support for updating an existing named query.

... (truncated)

Commits
  • 76ff8d9 Merge branch 'release-1.22.68'
  • 85ea723 Bumping version to 1.22.68
  • 63be387 Update changelog based on model updates
  • aeed389 Merge branch 'release-1.22.67'
  • 6f29be5 Merge branch 'release-1.22.67' into develop
  • 93cbb34 Bumping version to 1.22.67
  • 86e5e12 Update changelog based on model updates
  • 2a336bb New CLI Examples for cognito-idp, deploy (#6761)
  • 1e708d0 Update CLI examples for secretsmanager (#6760)
  • ab613f2 Merge branch 'release-1.22.66'
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=awscli&package-manager=pip&previous-version=1.22.63&new-version=1.22.68)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- packages/@aws-cdk/lambda-layer-awscli/layer/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 7c3099e958d7bf0ddb5a7b08afb672a0c652b27d Mon Sep 17 00:00:00 2001 From: Adam Brodziak Date: Mon, 7 Mar 2022 15:00:45 +0100 Subject: [PATCH 07/17] feat(eks): Service Account names validation (#19251) Kubernetes has got specific requirements to names of resources: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/ Without checks user will learn about invalid name at `cdk deploy` stage. That could leave EKS cluster in an inconsistent state. fixes #18189 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-eks/lib/service-account.ts | 34 +++++++ .../aws-eks/test/service-account.test.ts | 97 +++++++++++++++++++ 2 files changed, 131 insertions(+) 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); + }); + }); }); From b3c5fe8d0b695e06558bce23a6dd39b20265594f Mon Sep 17 00:00:00 2001 From: Otavio Macedo Date: Mon, 7 Mar 2022 16:04:59 +0000 Subject: [PATCH 08/17] fix(cli): notices refresh doesn't respect the --no-notices flag (#19226) The `--no-notices` flag is only being considered for actually displaying the notices, but not in the refresh step, used to mask latency. Also handling request timeout on the `Promise` level. If the promise doesn't resolve within the time limit, resolve with an empty array, no matter what. Fixes https://github.com/aws/aws-cdk/issues/19201. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/lib/cli.ts | 16 +++++++++------- packages/aws-cdk/lib/notices.ts | 14 ++++++-------- packages/aws-cdk/test/integ/cli/cli.integtest.ts | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 15 deletions(-) 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' })) { From 5de7b86d916be6ab892e75e18c54a327fe1f65ff Mon Sep 17 00:00:00 2001 From: Jonathan Goldwasser Date: Mon, 7 Mar 2022 17:47:10 +0100 Subject: [PATCH 09/17] fix(lambda-nodejs): local tsc detection with pre compilation (#19266) The package name is `typescript`, the bin is `tsc`. Closes #19242 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts | 2 +- packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) 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', () => { From 4eac4deb98411e921e5a2e6477185207b8588f75 Mon Sep 17 00:00:00 2001 From: Tommi <91956246+codemeddler@users.noreply.github.com> Date: Mon, 7 Mar 2022 17:08:31 -0500 Subject: [PATCH 10/17] feat(codebuild): improved support for ARM build images (#19052) Fixes #18916 Fixes #9817 ### Motivation CDK currently has poor and hidden support for using ARM build images for CodeBuild that do not match what you can do with the Console. Currently, CDK has under LinuxBuildImage two constants not mentioned in the documentation. The constants internally map to a hidden ArmBuildImage class, which provides support for the standard CodeBuild ARM build images. That is the extent of the support, making ARM a second class citizen compared to x86-64 Linux and Windows build images as, for example, you can't use custom aarch64 ECR images. ### Changes This pull request addresses the missing support by: - renaming the previously hidden class ArmBuildImage to LinuxArmBuildImage (in case there are Windows ARM Build Images in the future). - exporting LinuxArmBuildImage so it can be used. - adding the two ARM constants present in LinuxBuildImage also to LinuxArmBuildImage. The constants are also left under LinuxBuildImage to not break backwards compatibility. - adding the method fromEcrRepository() to support custom ARM build images. - making the LinuxArmBuildImage closer to the LinuxBuildImage and WindowsBuildImage (built with props instead of just image name). - updating documentation to show examples of ARM and highlighting the LinuxBuildImage is for x86-64. ### Testing The unit test for ARM image is still valid. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-codebuild/README.md | 9 +- packages/@aws-cdk/aws-codebuild/lib/index.ts | 1 + .../lib/linux-arm-build-image.ts | 105 ++++++ .../@aws-cdk/aws-codebuild/lib/project.ts | 52 +-- .../test/linux-arm-build-image.test.ts | 328 ++++++++++++++++++ 5 files changed, 458 insertions(+), 37 deletions(-) create mode 100644 packages/@aws-cdk/aws-codebuild/lib/linux-arm-build-image.ts create mode 100644 packages/@aws-cdk/aws-codebuild/test/linux-arm-build-image.test.ts 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', + })]), + }, + }); + }); + }); +}); From 98b12f2731bf273add0af345b6966c89bfd40b48 Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Mon, 7 Mar 2022 15:50:36 -0800 Subject: [PATCH 11/17] chore: allow `yarn` as a canary installer (#19268) As preparation for adding yarn canaries, and not just npm. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/test/integ/run-against-release | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) 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 From a9dc8ac1c594fa276ae1931c571d9f390a82a5e4 Mon Sep 17 00:00:00 2001 From: Joel Knight Date: Mon, 7 Mar 2022 18:14:46 -0700 Subject: [PATCH 12/17] chore(aws-events-targets): fix StepFunctions doc & tests role usage (#19178) The role used in the aws-events-targets example and test code needs to be passed to the SfnStateMachine target, not to the StateMachine resource. The role's trust policy trusts events.amazonaws.com so the state machine resource would be unable to use this role anyways. This PR modifies the example in README.md and the test code to have the StateMachine construct create its own role and pass the manually created role to SfnStateMachine where EventBridge will use it to start the state machine. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-events-targets/README.md | 4 ++-- .../test/stepfunctions/statemachine.test.ts | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) 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', ], }, From a554412f7cebbe4ab1ac13bbdcd4ca9f2bcd10b4 Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Tue, 8 Mar 2022 01:44:35 -0800 Subject: [PATCH 13/17] docs(cfnspec): update CloudFormation documentation (#19277) Co-authored-by: AWS CDK Team --- .../spec-source/cfn-docs/cfn-docs.json | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) 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 db50671e338e1..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 @@ -13882,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." } }, @@ -13919,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) ." @@ -13938,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.", @@ -13989,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* .", @@ -14029,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": { @@ -14131,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.", @@ -14161,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.", @@ -14205,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* ." } }, @@ -14469,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.", @@ -14587,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": { @@ -14607,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* .", @@ -14673,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": { @@ -14704,21 +14704,21 @@ }, "AWS::EKS::IdentityProviderConfig": { "attributes": { - "IdentityProviderConfigArn": "", - "Ref": "" + "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": "An object representing an identity provider configuration.", + "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." + "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.", + "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.", @@ -14731,10 +14731,10 @@ }, "AWS::EKS::IdentityProviderConfig.RequiredClaim": { "attributes": {}, - "description": "", + "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": "", - "Value": "" + "Key": "The key to match from the token.", + "Value": "The value for the key from the token." } }, "AWS::EKS::Nodegroup": { @@ -14743,7 +14743,7 @@ "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": { From 05f8b6f3e9fc7b1fc6d07e4e985014693576b26f Mon Sep 17 00:00:00 2001 From: Otavio Macedo Date: Tue, 8 Mar 2022 13:27:01 +0000 Subject: [PATCH 14/17] chore(ec2): add isolated subnets to the dummy VpcContextResponse (#19279) The lack of isolated subnet groups in the dummy response causes VPC lookups to fail. Fixes https://github.com/aws/aws-cdk/issues/19122. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-ec2/lib/vpc.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) 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', }; From 1e352ca2ab458bfe4e1de6cf431166654ce9aa58 Mon Sep 17 00:00:00 2001 From: Otavio Macedo Date: Tue, 8 Mar 2022 15:58:28 +0000 Subject: [PATCH 15/17] fix(apigatewayv2-integrations): in case of multiple routes, only one execute permission is created (#18716) When multiple routes are defined for a single lambda integration, only one of the routes gets permission to execute the function. This is because the permissions are added when the integration is bound to the route, which happens only once per integration. Split the `_bindToRoute` workflow into two parts: 1. The actual bind, followed by the creation of an `HttpIntegration`. We keep doing this only once per integration. 2. A post-bind step, that happens for every route. In the case of `HttpLambdaIntegration`, adding the permission has been moved to the post bind step. All other integrations remain the same. Fixes https://github.com/aws/aws-cdk/issues/18201. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../lib/http/lambda.ts | 4 +- .../test/http/lambda.test.ts | 37 ++++++++++++++++++- .../aws-apigatewayv2/lib/http/integration.ts | 13 +++++++ 3 files changed, 52 insertions(+), 2 deletions(-) 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. */ From 0da57da9606d982788350a6257f0f0ed6e9fd92a Mon Sep 17 00:00:00 2001 From: Cory Hall <43035978+corymhall@users.noreply.github.com> Date: Tue, 8 Mar 2022 11:44:16 -0500 Subject: [PATCH 16/17] fix(lambda-python): asset bundling fails on windows (#19270) The output directory should always use posix paths since this directory is being used within a linux docker container. I did not add any tests because it looks like there is no way to mock the `path` platform detection. fixes #18861 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-lambda-python/lib/bundling.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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, From dc7a17cd20198a6eb52c2ab25857e73bd7048d26 Mon Sep 17 00:00:00 2001 From: Jonathan Goldwasser Date: Tue, 8 Mar 2022 20:29:29 +0100 Subject: [PATCH 17/17] fix(rds): subnet selection not respected for multi user secret rotation (#19237) The subnet selection was always overriden by the subnet selection of the instance/cluster. Avoid these kinds of errors by explicitely defining rotation options and their defaults. Closes #19233 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/aws-rds/lib/cluster.ts | 12 ++- packages/@aws-cdk/aws-rds/lib/instance.ts | 12 ++- packages/@aws-cdk/aws-rds/lib/private/util.ts | 14 +++- packages/@aws-cdk/aws-rds/lib/props.ts | 2 +- .../aws-rds/lib/serverless-cluster.ts | 11 +-- .../@aws-cdk/aws-rds/test/cluster.test.ts | 83 ++++++++++++++---- .../@aws-cdk/aws-rds/test/instance.test.ts | 84 ++++++++++++++----- 7 files changed, 158 insertions(+), 60 deletions(-) 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 });