From c6a38b72157bc44150ad1516de9fb67fbd4f9664 Mon Sep 17 00:00:00 2001 From: Calvin Combs <66279577+comcalvi@users.noreply.github.com> Date: Fri, 29 Oct 2021 09:43:23 -0700 Subject: [PATCH 01/70] chore (mergify): change ownership of aws-logs, aws-groundsstation, and aws-cloudtrail to @comcalvi --- .github/workflows/issue-label-assign.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/issue-label-assign.yml b/.github/workflows/issue-label-assign.yml index f4d9f3b293c48..3309598c4e5e3 100644 --- a/.github/workflows/issue-label-assign.yml +++ b/.github/workflows/issue-label-assign.yml @@ -60,7 +60,7 @@ jobs: {"area":"@aws-cdk/aws-cloudformation","keywords":["aws-cloudformation","nestedstack"],"labels":["@aws-cdk/aws-cloudformation"],"assignees":["rix0rrr"]}, {"area":"@aws-cdk/aws-cloudfront","keywords":["aws-cloudfront","cloud front","cachepolicy","cloudfrontwebdistribution"],"labels":["@aws-cdk/aws-cloudfront"],"assignees":["njlynch"]}, {"area":"@aws-cdk/aws-cloudfront-origins","keywords":["aws-cloudfront-origins","cloudfront origins"],"labels":["@aws-cdk/aws-cloudfront-origins"],"assignees":["njlynch"]}, - {"area":"@aws-cdk/aws-cloudtrail","keywords":["aws-cloudtrail","cloud trail","trail"],"labels":["@aws-cdk/aws-cloudtrail"],"assignees":["rix0rrr"]}, + {"area":"@aws-cdk/aws-cloudtrail","keywords":["aws-cloudtrail","cloud trail","trail"],"labels":["@aws-cdk/aws-cloudtrail"],"assignees":["comcalvi"]}, {"area":"@aws-cdk/aws-cloudwatch","keywords":["aws-cloudwatch","cloud watch","compositealarm","dashboard"],"labels":["@aws-cdk/aws-cloudwatch"],"assignees":["madeline-k"]}, {"area":"@aws-cdk/aws-cloudwatch-actions","keywords":["aws-cloudwatch-actions","cloudwatch actions","applicationscalingaction","autoscalingaction","ec2action","snsaction"],"labels":["@aws-cdk/aws-cloudwatch-actions"],"assignees":["madeline-k"]}, {"area":"@aws-cdk/aws-codeartifact","keywords":["aws-codeartifact","code-artifact"],"labels":["@aws-cdk/aws-codeartifact"],"assignees":["njlynch"]}, @@ -120,7 +120,7 @@ jobs: {"area":"@aws-cdk/aws-glue","keywords":["aws-glue","glue"],"labels":["@aws-cdk/aws-glue"],"assignees":["kaizen3031593"]}, {"area":"@aws-cdk/aws-greengrass","keywords":["aws-greengrass","green-grass"],"labels":["@aws-cdk/aws-greengrass"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-greengrassv2","keywords":["(aws-greengrassv2)","(greengrassv2)"],"labels":["@aws-cdk/aws-greengrassv2"],"assignees":["skinny85"]}, - {"area":"@aws-cdk/aws-groundstation","keywords":["(aws-groundstation)","(groundstation)"],"labels":["@aws-cdk/aws-groundstation"],"assignees":["rix0rrr"]}, + {"area":"@aws-cdk/aws-groundstation","keywords":["(aws-groundstation)","(groundstation)"],"labels":["@aws-cdk/aws-groundstation"],"assignees":["comcalvi"]}, {"area":"@aws-cdk/aws-guardduty","keywords":["aws-guardduty","guard-duty"],"labels":["@aws-cdk/aws-guardduty"],"assignees":["rix0rrr"]}, {"area":"@aws-cdk/aws-iam","keywords":["aws-iam","iam","managedpolicy","policy","role"],"labels":["@aws-cdk/aws-iam"],"assignees":["rix0rrr"]}, {"area":"@aws-cdk/aws-imagebuilder","keywords":["aws-imagebuilder","imagebuilder"],"labels":["@aws-cdk/aws-imagebuilder"],"assignees":["skinny85"]}, @@ -148,7 +148,7 @@ jobs: {"area":"@aws-cdk/aws-lambda-nodejs","keywords":["nodejsfunction","aws-lambda-nodejs","lambda-nodejs"],"labels":["@aws-cdk/aws-lambda-nodejs"],"assignees":["nija-at"]}, {"area":"@aws-cdk/aws-lambda-python","keywords":["aws-lambda-python","lambda-python","pythonfunction"],"labels":["@aws-cdk/aws-lambda-python"],"assignees":["nija-at"]}, {"area":"@aws-cdk/aws-licensemanager","keywords":["(aws-licensemanager)","(licensemanager)"],"labels":["@aws-cdk/aws-licensemanager"],"assignees":["njlynch"]}, - {"area":"@aws-cdk/aws-logs","keywords":["loggroup","aws-logs","logs","logretention"],"labels":["@aws-cdk/aws-logs"],"assignees":["rix0rrr"]}, + {"area":"@aws-cdk/aws-logs","keywords":["loggroup","aws-logs","logs","logretention"],"labels":["@aws-cdk/aws-logs"],"assignees":["comcalvi"]}, {"area":"@aws-cdk/aws-logs-destinations","keywords":["aws-logs-destinations","lambdadestination","kinesisdestination","logs-destinations"],"labels":["@aws-cdk/aws-logs-destinations"],"assignees":["rix0rrr"]}, {"area":"@aws-cdk/aws-lookoutmetrics","keywords":["(aws-lookoutmetrics)","(lookoutmetrics)"],"labels":["@aws-cdk/aws-lookoutmetrics"],"assignees":["comcalvi"]}, {"area":"@aws-cdk/aws-lookoutvision","keywords":["(aws-lookoutvision)","(lookoutvision)"],"labels":["@aws-cdk/aws-lookoutvision"],"assignees":["comcalvi"]}, From e9a461d6dcbad933fcb9d671a8c5b5ad8f5ece8d Mon Sep 17 00:00:00 2001 From: nom3ad <19239479+nom3ad@users.noreply.github.com> Date: Mon, 1 Nov 2021 21:22:58 +0530 Subject: [PATCH 02/70] feat(logs): add support for cloudwatch logs resource policy (#17015) CloudFormation now supports [Cloudwatch logs Resource policies](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-resourcepolicy.html) This PR adds L2 support for it. And now its possible to grant access to service principals as follows. Previously this was throwing an error - see #5343 ```ts const eventsTargetLogs = new logs.LogGroup(this, 'EventsTargetLogGroup'); eventsTargetLogs.grantWrite(new iam.ServicePrincipal('events.amazonaws.com')).assertSuccess(); ``` In future, following custom resource implementation of `LogGroupResourcePolicy` could be replaced. https://github.com/aws/aws-cdk/blob/83b8df8c390a27e10bf362f49babfb24ee425506/packages/@aws-cdk/aws-elasticsearch/lib/log-group-resource-policy.ts#L25 https://github.com/aws/aws-cdk/blob/a872e672f8990fc3879413e5d797533d3916e1fd/packages/@aws-cdk/aws-events-targets/lib/log-group-resource-policy.ts#L26 https://github.com/aws/aws-cdk/blob/a872e672f8990fc3879413e5d797533d3916e1fd/packages/@aws-cdk/aws-events-targets/lib/log-group-resource-policy.ts#L26 closes #5343 ---- *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-logs/README.md | 40 ++++++++++++++- packages/@aws-cdk/aws-logs/lib/log-group.ts | 25 +++++++-- packages/@aws-cdk/aws-logs/lib/policy.ts | 47 +++++++++++++++++ .../@aws-cdk/aws-logs/test/loggroup.test.ts | 51 +++++++++++++++++++ 4 files changed, 157 insertions(+), 6 deletions(-) create mode 100644 packages/@aws-cdk/aws-logs/lib/policy.ts diff --git a/packages/@aws-cdk/aws-logs/README.md b/packages/@aws-cdk/aws-logs/README.md index 1fcd323ca621c..631bc382365e0 100644 --- a/packages/@aws-cdk/aws-logs/README.md +++ b/packages/@aws-cdk/aws-logs/README.md @@ -48,6 +48,44 @@ By default, the log group will be created in the same region as the stack. The ` log groups in other regions. This is typically useful when controlling retention for log groups auto-created by global services that publish their log group to a specific region, such as AWS Chatbot creating a log group in `us-east-1`. +## Resource Policy + +CloudWatch Resource Policies allow other AWS services or IAM Principals to put log events into the log groups. +A resource policy is automatically created when `addToResourcePolicy` is called on the LogGroup for the first time. + +`ResourcePolicy` can also be created manually. + +```ts +const logGroup = new LogGroup(this, 'LogGroup'); +const resourcePolicy = new ResourcePolicy(this, 'ResourcePolicy'); +resourcePolicy.document.addStatements(new iam.PolicyStatement({ + actions: ['logs:CreateLogStream', 'logs:PutLogEvents'], + principals: [new iam.ServicePrincipal('es.amazonaws.com')], + resources: [logGroup.logGroupArn], +})); +``` + +Or more conveniently, write permissions to the log group can be granted as follows which gives same result as in the above example. + +```ts +const logGroup = new LogGroup(this, 'LogGroup'); +logGroup.grantWrite(iam.ServicePrincipal('es.amazonaws.com')); +``` + +Optionally name and policy statements can also be passed on `ResourcePolicy` construction. + +```ts +const policyStatement = new new iam.PolicyStatement({ + resources: ["*"], + actions: ['logs:PutLogEvents'], + principals: [new iam.ArnPrincipal('arn:aws:iam::123456789012:user/user-name')], +}); +const resourcePolicy = new ResourcePolicy(this, 'ResourcePolicy', { + policyName: 'myResourcePolicy', + policyStatements: [policyStatement], +}); +``` + ## Encrypting Log Groups By default, log group data is always encrypted in CloudWatch Logs. You have the @@ -182,7 +220,6 @@ line. all of the terms in any of the groups (specified as arrays) matches. This is an OR match. - Examples: ```ts @@ -231,7 +268,6 @@ and then descending into it, such as `$.field` or `$.list[0].field`. given JSON patterns match. This makes an OR combination of the given patterns. - Example: ```ts diff --git a/packages/@aws-cdk/aws-logs/lib/log-group.ts b/packages/@aws-cdk/aws-logs/lib/log-group.ts index 4c74dbf02f3ee..c701f4b5e4c9f 100644 --- a/packages/@aws-cdk/aws-logs/lib/log-group.ts +++ b/packages/@aws-cdk/aws-logs/lib/log-group.ts @@ -1,15 +1,16 @@ import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; -import { IResource, RemovalPolicy, Resource, Stack, Token } from '@aws-cdk/core'; +import { RemovalPolicy, Resource, Stack, Token } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { LogStream } from './log-stream'; import { CfnLogGroup } from './logs.generated'; import { MetricFilter } from './metric-filter'; import { FilterPattern, IFilterPattern } from './pattern'; +import { ResourcePolicy } from './policy'; import { ILogSubscriptionDestination, SubscriptionFilter } from './subscription-filter'; -export interface ILogGroup extends IResource { +export interface ILogGroup extends iam.IResourceWithPolicy { /** * The ARN of this log group, with ':*' appended * @@ -93,6 +94,9 @@ abstract class LogGroupBase extends Resource implements ILogGroup { */ public abstract readonly logGroupName: string; + + private policy?: ResourcePolicy; + /** * Create a new Log Stream for this Log Group * @@ -169,13 +173,13 @@ abstract class LogGroupBase extends Resource implements ILogGroup { * Give the indicated permissions on this log group and all streams */ public grant(grantee: iam.IGrantable, ...actions: string[]) { - return iam.Grant.addToPrincipal({ + return iam.Grant.addToPrincipalOrResource({ grantee, actions, // A LogGroup ARN out of CloudFormation already includes a ':*' at the end to include the log streams under the group. // See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-loggroup.html#w2ab1c21c10c63c43c11 resourceArns: [this.logGroupArn], - scope: this, + resource: this, }); } @@ -186,6 +190,19 @@ abstract class LogGroupBase extends Resource implements ILogGroup { public logGroupPhysicalName(): string { return this.physicalName; } + + /** + * Adds a statement to the resource policy associated with this log group. + * A resource policy will be automatically created upon the first call to `addToResourcePolicy`. + * @param statement The policy statement to add + */ + public addToResourcePolicy(statement: iam.PolicyStatement): iam.AddToResourcePolicyResult { + if (!this.policy) { + this.policy = new ResourcePolicy(this, 'Policy'); + } + this.policy.document.addStatements(statement); + return { statementAdded: true, policyDependable: this.policy }; + } } /** diff --git a/packages/@aws-cdk/aws-logs/lib/policy.ts b/packages/@aws-cdk/aws-logs/lib/policy.ts new file mode 100644 index 0000000000000..974f517d48b25 --- /dev/null +++ b/packages/@aws-cdk/aws-logs/lib/policy.ts @@ -0,0 +1,47 @@ +import { PolicyDocument, PolicyStatement } from '@aws-cdk/aws-iam'; +import { Resource, Lazy, Names } from '@aws-cdk/core'; +import { Construct } from 'constructs'; +import { CfnResourcePolicy } from './logs.generated'; + +/** + * Properties to define Cloudwatch log group resource policy + */ +export interface ResourcePolicyProps { + /** + * Name of the log group resource policy + * @default - Uses a unique id based on the construct path + */ + readonly policyName?: string; + + /** + * Initial statements to add to the resource policy + * + * @default - No statements + */ + readonly policyStatements?: PolicyStatement[]; +} + +/** + * Creates Cloudwatch log group resource policies + */ +export class ResourcePolicy extends Resource { + /** + * The IAM policy document for this resource policy. + */ + public readonly document = new PolicyDocument(); + + constructor(scope: Construct, id: string, props?: ResourcePolicyProps) { + super(scope, id); + new CfnResourcePolicy(this, 'Resource', { + policyName: Lazy.string({ + produce: () => props?.policyName ?? Names.uniqueId(this), + }), + policyDocument: Lazy.string({ + produce: () => JSON.stringify(this.document), + }), + }); + if (props?.policyStatements) { + this.document.addStatements(...props.policyStatements); + } + } +} diff --git a/packages/@aws-cdk/aws-logs/test/loggroup.test.ts b/packages/@aws-cdk/aws-logs/test/loggroup.test.ts index 72b3c390a2f96..d7fa5cb600b76 100644 --- a/packages/@aws-cdk/aws-logs/test/loggroup.test.ts +++ b/packages/@aws-cdk/aws-logs/test/loggroup.test.ts @@ -335,6 +335,57 @@ describe('log group', () => { }); + test('grant to service principal', () => { + // GIVEN + const stack = new Stack(); + const lg = new LogGroup(stack, 'LogGroup'); + const sp = new iam.ServicePrincipal('es.amazonaws.com'); + + // WHEN + lg.grantWrite(sp); + + // THEN + expect(stack).toHaveResource('AWS::Logs::ResourcePolicy', { + PolicyDocument: { + 'Fn::Join': [ + '', + [ + '{"Statement":[{"Action":["logs:CreateLogStream","logs:PutLogEvents"],"Effect":"Allow","Principal":{"Service":"es.amazonaws.com"},"Resource":"', + { + 'Fn::GetAtt': [ + 'LogGroupF5B46931', + 'Arn', + ], + }, + '"}],"Version":"2012-10-17"}', + ], + ], + }, + PolicyName: 'LogGroupPolicy643B329C', + }); + + }); + + + test('can add a policy to the log group', () => { + // GIVEN + const stack = new Stack(); + const lg = new LogGroup(stack, 'LogGroup'); + + // WHEN + lg.addToResourcePolicy(new iam.PolicyStatement({ + resources: ['*'], + actions: ['logs:PutLogEvents'], + principals: [new iam.ArnPrincipal('arn:aws:iam::123456789012:user/user-name')], + })); + + // THEN + expect(stack).toHaveResource('AWS::Logs::ResourcePolicy', { + PolicyDocument: '{"Statement":[{"Action":"logs:PutLogEvents","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::123456789012:user/user-name"},"Resource":"*"}],"Version":"2012-10-17"}', + PolicyName: 'LogGroupPolicy643B329C', + }); + }); + test('correctly returns physical name of the log group', () => { // GIVEN const stack = new Stack(); From a9aae097daad475dd57bbf4842956327a6d5a220 Mon Sep 17 00:00:00 2001 From: Tatsuya Yamamoto Date: Tue, 2 Nov 2021 01:47:28 +0900 Subject: [PATCH 03/70] feat(iot): allow setting `description` and `enabled` of TopicRule (#17225) I'm trying to implement aws-iot L2 Constructs. This PR is one of steps after following PR: - https://github.com/aws/aws-cdk/pull/16681#issuecomment-942233029 ---- *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-iot/README.md | 11 +++++++ packages/@aws-cdk/aws-iot/lib/topic-rule.ts | 16 ++++++++++ .../@aws-cdk/aws-iot/test/topic-rule.test.ts | 30 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/packages/@aws-cdk/aws-iot/README.md b/packages/@aws-cdk/aws-iot/README.md index 6a9640629891a..42ab651f26f81 100644 --- a/packages/@aws-cdk/aws-iot/README.md +++ b/packages/@aws-cdk/aws-iot/README.md @@ -59,6 +59,8 @@ const func = new lambda.Function(this, 'MyFunction', { }); new iot.TopicRule(this, 'TopicRule', { + topicRuleName: 'MyTopicRule', // optional + description: 'invokes the lambda finction', // optional sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, timestamp() as timestamp FROM 'device/+/data'"), actions: [new actions.LambdaFunctionAction(func)], }); @@ -72,3 +74,12 @@ const topicRule = new iot.TopicRule(this, 'TopicRule', { }); topicRule.addAction(new actions.LambdaFunctionAction(func)) ``` + +If you wanna make the topic rule disable, add property `enabled: false` as following: + +```ts +new iot.TopicRule(this, 'TopicRule', { + sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, timestamp() as timestamp FROM 'device/+/data'"), + enabled: false, +}); +``` diff --git a/packages/@aws-cdk/aws-iot/lib/topic-rule.ts b/packages/@aws-cdk/aws-iot/lib/topic-rule.ts index a8cd21fe2bd96..8860a611e4af3 100644 --- a/packages/@aws-cdk/aws-iot/lib/topic-rule.ts +++ b/packages/@aws-cdk/aws-iot/lib/topic-rule.ts @@ -41,6 +41,20 @@ export interface TopicRuleProps { */ readonly actions?: IAction[]; + /** + * A textual description of the topic rule. + * + * @default None + */ + readonly description?: string; + + /** + * Specifies whether the rule is enabled. + * + * @default true + */ + readonly enabled?: boolean + /** * A simplified SQL syntax to filter messages received on an MQTT topic and push the data elsewhere. * @@ -102,6 +116,8 @@ export class TopicRule extends Resource implements ITopicRule { topicRulePayload: { actions: Lazy.any({ produce: () => this.actions }), awsIotSqlVersion: sqlConfig.awsIotSqlVersion, + description: props.description, + ruleDisabled: props.enabled === undefined ? undefined : !props.enabled, sql: sqlConfig.sql, }, }); diff --git a/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts b/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts index 66246e860dddb..6e4a49c234e60 100644 --- a/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts +++ b/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts @@ -71,6 +71,36 @@ test('can set physical name', () => { }); }); +test('can set description', () => { + const stack = new cdk.Stack(); + + new iot.TopicRule(stack, 'MyTopicRule', { + description: 'test-description', + sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"), + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', { + TopicRulePayload: { + Description: 'test-description', + }, + }); +}); + +test('can set ruleDisabled', () => { + const stack = new cdk.Stack(); + + new iot.TopicRule(stack, 'MyTopicRule', { + enabled: false, + sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"), + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', { + TopicRulePayload: { + RuleDisabled: true, + }, + }); +}); + test.each([ ['fromStringAsVer20151008', iot.IotSql.fromStringAsVer20151008, '2015-10-08'], ['fromStringAsVer20160323', iot.IotSql.fromStringAsVer20160323, '2016-03-23'], From e26f5befc2adedeb524fd263424c7920989b2288 Mon Sep 17 00:00:00 2001 From: Julian Michel Date: Mon, 1 Nov 2021 18:42:51 +0100 Subject: [PATCH 04/70] feat(certificatemanager): requesting private certificates issued by Private Certificate Authority (#16315) Support requesting private certificates issued by Private Certificate Authority. Similar to the existing construct named `Certificate`, a new construct `PrivateCertificate` was introduced. There are two main differences between them. `PrivateCertificate` has an additional property `certificateAuthority` to specify the Private certificate authority (CA) that will be used to issue the certificate. The validation options are removed because no validation is necessary for private certificates. Closes #10076. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-certificatemanager/README.md | 15 +++ .../aws-certificatemanager/lib/index.ts | 1 + .../lib/private-certificate.ts | 66 ++++++++++++ .../aws-certificatemanager/package.json | 5 +- .../test/private-certificate.test.ts | 102 ++++++++++++++++++ 5 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 packages/@aws-cdk/aws-certificatemanager/lib/private-certificate.ts create mode 100644 packages/@aws-cdk/aws-certificatemanager/test/private-certificate.test.ts diff --git a/packages/@aws-cdk/aws-certificatemanager/README.md b/packages/@aws-cdk/aws-certificatemanager/README.md index 7068591d9c076..331d40ad27276 100644 --- a/packages/@aws-cdk/aws-certificatemanager/README.md +++ b/packages/@aws-cdk/aws-certificatemanager/README.md @@ -113,6 +113,21 @@ new acm.DnsValidatedCertificate(this, 'CrossRegionCertificate', { }); ``` +## Requesting private certificates + +AWS Certificate Manager can create [private certificates](https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-private.html) issued by [Private Certificate Authority (PCA)](https://docs.aws.amazon.com/acm-pca/latest/userguide/PcaWelcome.html). Validation of private certificates is not necessary. + +```ts +import * as acmpca from '@aws-cdk/aws-acmpca'; + +new acm.PrivateCertificate(stack, 'PrivateCertificate', { + domainName: 'test.example.com', + subjectAlternativeNames: ['cool.example.com', 'test.example.net'], // optional + certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA', + 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'), +}); +``` + ## Importing If you want to import an existing certificate, you can do so from its ARN: diff --git a/packages/@aws-cdk/aws-certificatemanager/lib/index.ts b/packages/@aws-cdk/aws-certificatemanager/lib/index.ts index ee15ab71b8d4b..60be9ebed1c5c 100644 --- a/packages/@aws-cdk/aws-certificatemanager/lib/index.ts +++ b/packages/@aws-cdk/aws-certificatemanager/lib/index.ts @@ -1,5 +1,6 @@ export * from './certificate'; export * from './dns-validated-certificate'; +export * from './private-certificate'; export * from './util'; // AWS::CertificateManager CloudFormation Resources: diff --git a/packages/@aws-cdk/aws-certificatemanager/lib/private-certificate.ts b/packages/@aws-cdk/aws-certificatemanager/lib/private-certificate.ts new file mode 100644 index 0000000000000..366b3ea623ac6 --- /dev/null +++ b/packages/@aws-cdk/aws-certificatemanager/lib/private-certificate.ts @@ -0,0 +1,66 @@ +import * as acmpca from '@aws-cdk/aws-acmpca'; +import { Construct } from 'constructs'; +import { ICertificate } from './certificate'; +import { CertificateBase } from './certificate-base'; +import { CfnCertificate } from './certificatemanager.generated'; + +/** + * Properties for your private certificate + */ +export interface PrivateCertificateProps { + /** + * Fully-qualified domain name to request a private certificate for. + * + * May contain wildcards, such as ``*.domain.com``. + */ + readonly domainName: string; + + /** + * Alternative domain names on your private certificate. + * + * Use this to register alternative domain names that represent the same site. + * + * @default - No additional FQDNs will be included as alternative domain names. + */ + readonly subjectAlternativeNames?: string[]; + + /** + * Private certificate authority (CA) that will be used to issue the certificate. + */ + readonly certificateAuthority: acmpca.ICertificateAuthority; +} + +/** + * A private certificate managed by AWS Certificate Manager + * + * @resource AWS::CertificateManager::Certificate + */ +export class PrivateCertificate extends CertificateBase implements ICertificate { + /** + * Import a certificate + */ + public static fromCertificateArn(scope: Construct, id: string, certificateArn: string): ICertificate { + class Import extends CertificateBase { + public readonly certificateArn = certificateArn; + } + + return new Import(scope, id); + } + + /** + * The certificate's ARN + */ + public readonly certificateArn: string; + + constructor(scope: Construct, id: string, props: PrivateCertificateProps) { + super(scope, id); + + const cert = new CfnCertificate(this, 'Resource', { + domainName: props.domainName, + subjectAlternativeNames: props.subjectAlternativeNames, + certificateAuthorityArn: props.certificateAuthority.certificateAuthorityArn, + }); + + this.certificateArn = cert.ref; + } +} diff --git a/packages/@aws-cdk/aws-certificatemanager/package.json b/packages/@aws-cdk/aws-certificatemanager/package.json index 990c09fc3aa55..dae2a8a3a24dc 100644 --- a/packages/@aws-cdk/aws-certificatemanager/package.json +++ b/packages/@aws-cdk/aws-certificatemanager/package.json @@ -79,6 +79,7 @@ "@types/jest": "^26.0.24" }, "dependencies": { + "@aws-cdk/aws-acmpca": "0.0.0", "@aws-cdk/aws-cloudwatch": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", @@ -88,6 +89,7 @@ }, "homepage": "https://github.com/aws/aws-cdk", "peerDependencies": { + "@aws-cdk/aws-acmpca": "0.0.0", "@aws-cdk/aws-cloudwatch": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", @@ -101,7 +103,8 @@ "awslint": { "exclude": [ "props-physical-name:@aws-cdk/aws-certificatemanager.CertificateProps", - "props-physical-name:@aws-cdk/aws-certificatemanager.DnsValidatedCertificateProps" + "props-physical-name:@aws-cdk/aws-certificatemanager.DnsValidatedCertificateProps", + "props-physical-name:@aws-cdk/aws-certificatemanager.PrivateCertificateProps" ] }, "stability": "stable", diff --git a/packages/@aws-cdk/aws-certificatemanager/test/private-certificate.test.ts b/packages/@aws-cdk/aws-certificatemanager/test/private-certificate.test.ts new file mode 100644 index 0000000000000..e43a4ca005691 --- /dev/null +++ b/packages/@aws-cdk/aws-certificatemanager/test/private-certificate.test.ts @@ -0,0 +1,102 @@ +import '@aws-cdk/assert-internal/jest'; +import * as acmpca from '@aws-cdk/aws-acmpca'; +import { Duration, Lazy, Stack } from '@aws-cdk/core'; +import { PrivateCertificate } from '../lib'; + +test('private certificate authority', () => { + const stack = new Stack(); + + new PrivateCertificate(stack, 'Certificate', { + domainName: 'test.example.com', + certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA', + 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'), + }); + + expect(stack).toHaveResource('AWS::CertificateManager::Certificate', { + DomainName: 'test.example.com', + CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77', + }); +}); + +test('private certificate authority with subjectAlternativeNames', () => { + const stack = new Stack(); + + new PrivateCertificate(stack, 'Certificate', { + domainName: 'test.example.com', + subjectAlternativeNames: ['extra.example.com'], + certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA', + 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'), + }); + + expect(stack).toHaveResource('AWS::CertificateManager::Certificate', { + DomainName: 'test.example.com', + SubjectAlternativeNames: ['extra.example.com'], + CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77', + }); +}); + +test('private certificate authority with multiple subjectAlternativeNames', () => { + const stack = new Stack(); + + new PrivateCertificate(stack, 'Certificate', { + domainName: 'test.example.com', + subjectAlternativeNames: ['*.test.example.com', '*.foo.test.example.com', 'bar.test.example.com'], + certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA', + 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'), + }); + + expect(stack).toHaveResource('AWS::CertificateManager::Certificate', { + DomainName: 'test.example.com', + SubjectAlternativeNames: ['*.test.example.com', '*.foo.test.example.com', 'bar.test.example.com'], + CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77', + }); +}); + +test('private certificate authority with tokens', () => { + const stack = new Stack(); + + const certificateAuthority = Lazy.string({ + produce: () => 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77', + }); + + const domainName = Lazy.string({ + produce: () => 'test.example.com', + }); + + const domainNameAlternative = Lazy.string({ + produce: () => 'extra.example.com', + }); + + new PrivateCertificate(stack, 'Certificate', { + domainName, + subjectAlternativeNames: [domainNameAlternative], + certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA', certificateAuthority), + }); + + expect(stack).toHaveResource('AWS::CertificateManager::Certificate', { + DomainName: 'test.example.com', + SubjectAlternativeNames: ['extra.example.com'], + CertificateAuthorityArn: 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77', + }); +}); + +test('metricDaysToExpiry', () => { + const stack = new Stack(); + + const certificate = new PrivateCertificate(stack, 'Certificate', { + domainName: 'test.example.com', + certificateAuthority: acmpca.CertificateAuthority.fromCertificateAuthorityArn(stack, 'CA', + 'arn:aws:acm-pca:us-east-1:123456789012:certificate-authority/023077d8-2bfa-4eb0-8f22-05c96deade77'), + }); + + expect(stack.resolve(certificate.metricDaysToExpiry().toMetricConfig())).toEqual({ + metricStat: { + dimensions: [{ name: 'CertificateArn', value: stack.resolve(certificate.certificateArn) }], + metricName: 'DaysToExpiry', + namespace: 'AWS/CertificateManager', + period: Duration.days(1), + statistic: 'Minimum', + }, + renderingProperties: expect.anything(), + }); +}); From 19b38f5fd2b054f234d4c0b0debe7caa432f561c Mon Sep 17 00:00:00 2001 From: Julian Michel Date: Mon, 1 Nov 2021 19:37:58 +0100 Subject: [PATCH 05/70] chore(rds): add Aurora Postgres ver 13.4, 12.8, 11.13, 10.18 and Mysql ver 8.0.26 (#17247) Add new RDS versions: **AuroraPostgresEngineVersion 13.4, 12.8, 11.13, and 10.18** Announcement: https://aws.amazon.com/about-aws/whats-new/2021/10/amazon-aurora-postgresql-supports-releases/ s3Export and s3Import are supported, see `aws rds describe-db-engine-versions --region us-east-1 --engine aurora-postgresql --engine-version xxx`. **MysqlEngineVersion 8.0.26** Announcement: https://aws.amazon.com/about-aws/whats-new/2021/10/amazon-rds-mysql-version-8-0-26-global-transaction-identifiers-gitds-delayed-replication/ ---- *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-engine.ts | 8 ++++++++ packages/@aws-cdk/aws-rds/lib/instance-engine.ts | 2 ++ 2 files changed, 10 insertions(+) diff --git a/packages/@aws-cdk/aws-rds/lib/cluster-engine.ts b/packages/@aws-cdk/aws-rds/lib/cluster-engine.ts index 606fddd75edbf..cde235257ff8e 100644 --- a/packages/@aws-cdk/aws-rds/lib/cluster-engine.ts +++ b/packages/@aws-cdk/aws-rds/lib/cluster-engine.ts @@ -451,6 +451,8 @@ export class AuroraPostgresEngineVersion { public static readonly VER_10_14 = AuroraPostgresEngineVersion.of('10.14', '10', { s3Import: true, s3Export: true }); /** Version "10.16". */ public static readonly VER_10_16 = AuroraPostgresEngineVersion.of('10.16', '10', { s3Import: true, s3Export: true }); + /** Version "10.18". */ + public static readonly VER_10_18 = AuroraPostgresEngineVersion.of('10.18', '10', { s3Import: true, s3Export: true }); /** Version "11.4". */ public static readonly VER_11_4 = AuroraPostgresEngineVersion.of('11.4', '11', { s3Import: true }); /** Version "11.6". */ @@ -463,12 +465,18 @@ export class AuroraPostgresEngineVersion { public static readonly VER_11_9 = AuroraPostgresEngineVersion.of('11.9', '11', { s3Import: true, s3Export: true }); /** Version "11.11". */ public static readonly VER_11_11 = AuroraPostgresEngineVersion.of('11.11', '11', { s3Import: true, s3Export: true }); + /** Version "11.13". */ + public static readonly VER_11_13 = AuroraPostgresEngineVersion.of('11.13', '11', { s3Import: true, s3Export: true }); /** Version "12.4". */ public static readonly VER_12_4 = AuroraPostgresEngineVersion.of('12.4', '12', { s3Import: true, s3Export: true }); /** Version "12.6". */ public static readonly VER_12_6 = AuroraPostgresEngineVersion.of('12.6', '12', { s3Import: true, s3Export: true }); + /** Version "12.8". */ + public static readonly VER_12_8 = AuroraPostgresEngineVersion.of('12.8', '12', { s3Import: true, s3Export: true }); /** Version "13.3". */ public static readonly VER_13_3 = AuroraPostgresEngineVersion.of('13.3', '13', { s3Import: true, s3Export: true }); + /** Version "13.4". */ + public static readonly VER_13_4 = AuroraPostgresEngineVersion.of('13.4', '13', { s3Import: true, s3Export: true }); /** * Create a new AuroraPostgresEngineVersion with an arbitrary version. diff --git a/packages/@aws-cdk/aws-rds/lib/instance-engine.ts b/packages/@aws-cdk/aws-rds/lib/instance-engine.ts index dfea03877a0d2..05d045e56c8f3 100644 --- a/packages/@aws-cdk/aws-rds/lib/instance-engine.ts +++ b/packages/@aws-cdk/aws-rds/lib/instance-engine.ts @@ -497,6 +497,8 @@ export class MysqlEngineVersion { public static readonly VER_8_0_23 = MysqlEngineVersion.of('8.0.23', '8.0'); /** Version "8.0.25". */ public static readonly VER_8_0_25 = MysqlEngineVersion.of('8.0.25', '8.0'); + /** Version "8.0.26". */ + public static readonly VER_8_0_26 = MysqlEngineVersion.of('8.0.26', '8.0'); /** * Create a new MysqlEngineVersion with an arbitrary version. From 73eb185ab7c11b50511c671e02cf2039c297bd61 Mon Sep 17 00:00:00 2001 From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com> Date: Mon, 1 Nov 2021 15:31:49 -0400 Subject: [PATCH 06/70] docs(rds): make examples compile (#17146) ---- *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/README.md | 121 +++++++++++------- .../aws-rds/rosetta/default.ts-fixture | 18 +++ 2 files changed, 91 insertions(+), 48 deletions(-) create mode 100644 packages/@aws-cdk/aws-rds/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-rds/README.md b/packages/@aws-cdk/aws-rds/README.md index cad785735dfb6..42283697f6181 100644 --- a/packages/@aws-cdk/aws-rds/README.md +++ b/packages/@aws-cdk/aws-rds/README.md @@ -12,7 +12,7 @@ -```ts +```ts nofixture import * as rds from '@aws-cdk/aws-rds'; ``` @@ -23,6 +23,7 @@ always launch a database in a VPC. Use the `vpcSubnets` attribute to control whe your instances will be launched privately or publicly: ```ts +declare const vpc: ec2.Vpc; const cluster = new rds.DatabaseCluster(this, 'Database', { engine: rds.DatabaseClusterEngine.auroraMysql({ version: rds.AuroraMysqlEngineVersion.VER_2_08_1 }), credentials: rds.Credentials.fromGeneratedSecret('clusteradmin'), // Optional - will default to 'admin' username and generated password @@ -52,7 +53,8 @@ Your cluster will be empty by default. To add a default database upon constructi Use `DatabaseClusterFromSnapshot` to create a cluster from a snapshot: ```ts -new rds.DatabaseClusterFromSnapshot(stack, 'Database', { +declare const vpc: ec2.Vpc; +new rds.DatabaseClusterFromSnapshot(this, 'Database', { engine: rds.DatabaseClusterEngine.aurora({ version: rds.AuroraEngineVersion.VER_1_22_2 }), instanceProps: { vpc, @@ -68,6 +70,7 @@ always launch a database in a VPC. Use the `vpcSubnets` attribute to control whe your instances will be launched privately or publicly: ```ts +declare const vpc: ec2.Vpc; const instance = new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.oracleSe2({ version: rds.OracleEngineVersion.VER_19_0_0_0_2020_04_R1 }), // optional, defaults to m5.large @@ -75,7 +78,7 @@ const instance = new rds.DatabaseInstance(this, 'Instance', { credentials: rds.Credentials.fromGeneratedSecret('syscdk'), // Optional - will default to 'admin' username and generated password vpc, vpcSubnets: { - subnetType: ec2.SubnetType.PRIVATE + subnetType: ec2.SubnetType.PRIVATE, } }); ``` @@ -95,6 +98,7 @@ This is the upper limit to which RDS can automatically scale the storage. More i Example for max storage configuration: ```ts +declare const vpc: ec2.Vpc; const instance = new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_3 }), // optional, defaults to m5.large @@ -108,7 +112,8 @@ Use `DatabaseInstanceFromSnapshot` and `DatabaseInstanceReadReplica` to create a a source database respectively: ```ts -new rds.DatabaseInstanceFromSnapshot(stack, 'Instance', { +declare const vpc: ec2.Vpc; +new rds.DatabaseInstanceFromSnapshot(this, 'Instance', { snapshotIdentifier: 'my-snapshot', engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_3 }), // optional, defaults to m5.large @@ -116,7 +121,8 @@ new rds.DatabaseInstanceFromSnapshot(stack, 'Instance', { vpc, }); -new rds.DatabaseInstanceReadReplica(stack, 'ReadReplica', { +declare const sourceInstance: rds.DatabaseInstance; +new rds.DatabaseInstanceReadReplica(this, 'ReadReplica', { sourceDatabaseInstance: sourceInstance, instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.LARGE), vpc, @@ -136,8 +142,9 @@ The default value depends on `vpcSubnets`. It will be `true` if `vpcSubnets` is `subnetType: SubnetType.PUBLIC`, `false` otherwise. ```ts +declare const vpc: ec2.Vpc; // Setting public accessibility for DB instance -new rds.DatabaseInstance(stack, 'Instance', { +new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.mysql({ version: rds.MysqlEngineVersion.VER_8_0_19, }), @@ -149,15 +156,14 @@ new rds.DatabaseInstance(stack, 'Instance', { }); // Setting public accessibility for DB cluster -new rds.DatabaseCluster(stack, 'DatabaseCluster', { - engine: DatabaseClusterEngine.AURORA, +new rds.DatabaseCluster(this, 'DatabaseCluster', { + engine: rds.DatabaseClusterEngine.AURORA, instanceProps: { vpc, vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE, }, publiclyAccessible: true, - copyTagsToSnapshot: true, // whether to save the cluster tags when creating the snapshot. Default is 'true' }, }); ``` @@ -168,6 +174,8 @@ To define Amazon CloudWatch event rules for database instances, use the `onEvent method: ```ts +declare const instance: rds.DatabaseInstance; +declare const fn: lambda.Function; const rule = instance.onEvent('InstanceEvent', { target: new targets.LambdaFunction(fn) }); ``` @@ -179,6 +187,7 @@ An alternative username (and password) may be specified for the admin user inste The following examples use a `DatabaseInstance`, but the same usage is applicable to `DatabaseCluster`. ```ts +declare const vpc: ec2.Vpc; const engine = rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_3 }); new rds.DatabaseInstance(this, 'InstanceWithUsername', { engine, @@ -203,7 +212,9 @@ new rds.DatabaseInstance(this, 'InstanceWithSecretLogin', { Secrets generated by `fromGeneratedSecret()` can be customized: ```ts -const myKey = kms.Key(this, 'MyKey'); +declare const vpc: ec2.Vpc; +const engine = rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_3 }); +const myKey = new kms.Key(this, 'MyKey'); new rds.DatabaseInstance(this, 'InstanceWithCustomizedSecret', { engine, @@ -211,7 +222,7 @@ new rds.DatabaseInstance(this, 'InstanceWithCustomizedSecret', { credentials: rds.Credentials.fromGeneratedSecret('postgres', { secretName: 'my-cool-name', encryptionKey: myKey, - excludeCharacters: ['!&*^#@()'], + excludeCharacters: '!&*^#@()', replicaRegions: [{ region: 'eu-west-1' }, { region: 'eu-west-2' }], }), }); @@ -223,19 +234,22 @@ To control who can access the cluster or instance, use the `.connections` attrib a default port, so you don't need to specify the port: ```ts -cluster.connections.allowFromAnyIpv4('Open to the world'); +declare const cluster: rds.DatabaseCluster; +cluster.connections.allowFromAnyIpv4(ec2.Port.allTraffic(), 'Open to the world'); ``` The endpoints to access your database cluster will be available as the `.clusterEndpoint` and `.readerEndpoint` attributes: ```ts +declare const cluster: rds.DatabaseCluster; const writeAddress = cluster.clusterEndpoint.socketAddress; // "HOSTNAME:PORT" ``` For an instance database: ```ts +declare const instance: rds.DatabaseInstance; const address = instance.instanceEndpoint.socketAddress; // "HOSTNAME:PORT" ``` @@ -244,6 +258,9 @@ const address = instance.instanceEndpoint.socketAddress; // "HOSTNAME:PORT" When the master password is generated and stored in AWS Secrets Manager, it can be rotated automatically: ```ts +import * as cdk from '@aws-cdk/core'; + +declare const instance: rds.DatabaseInstance; instance.addRotationSingleUser({ automaticallyAfter: cdk.Duration.days(7), // defaults to 30 days excludeCharacters: '!@#$%^&*', // defaults to the set " %+~`#$&*()|[]{}:;<>?!'/@\"\\" @@ -255,6 +272,8 @@ instance.addRotationSingleUser({ The multi user rotation scheme is also available: ```ts +declare const instance: rds.DatabaseInstance; +declare const myImportedSecret: rds.DatabaseSecret; instance.addRotationMultiUser('MyUser', { secret: myImportedSecret, // This secret must have the `masterarn` key }); @@ -263,6 +282,7 @@ instance.addRotationMultiUser('MyUser', { It's also possible to create user credentials together with the instance/cluster and add rotation: ```ts +declare const instance: rds.DatabaseInstance; const myUserSecret = new rds.DatabaseSecret(this, 'MyUserSecret', { username: 'myuser', secretName: 'my-user-secret', // optional, defaults to a CloudFormation-generated name @@ -290,30 +310,32 @@ and a list of supported versions and limitations. The following example shows enabling IAM authentication for a database instance and granting connection access to an IAM role. ```ts -const instance = new rds.DatabaseInstance(stack, 'Instance', { +declare const vpc: ec2.Vpc; +const instance = new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.mysql({ version: rds.MysqlEngineVersion.VER_8_0_19 }), vpc, iamAuthentication: true, // Optional - will be automatically set if you call grantConnect(). }); -const role = new Role(stack, 'DBRole', { assumedBy: new AccountPrincipal(stack.account) }); +const role = new iam.Role(this, 'DBRole', { assumedBy: new iam.AccountPrincipal(this.account) }); instance.grantConnect(role); // Grant the role connection access to the DB. ``` The following example shows granting connection access for RDS Proxy to an IAM role. ```ts -const cluster = new rds.DatabaseCluster(stack, 'Database', { +declare const vpc: ec2.Vpc; +const cluster = new rds.DatabaseCluster(this, 'Database', { engine: rds.DatabaseClusterEngine.AURORA, instanceProps: { vpc }, }); -const proxy = new rds.DatabaseProxy(stack, 'Proxy', { +const proxy = new rds.DatabaseProxy(this, 'Proxy', { proxyTarget: rds.ProxyTarget.fromCluster(cluster), secrets: [cluster.secret!], vpc, }); -const role = new Role(stack, 'DBProxyRole', { assumedBy: new AccountPrincipal(stack.account) }); +const role = new iam.Role(this, 'DBProxyRole', { assumedBy: new iam.AccountPrincipal(this.account) }); proxy.grantConnect(role, 'admin'); // Grant the role connection access to the DB Proxy for database user 'admin'. ``` @@ -330,13 +352,14 @@ The following example shows enabling domain support for a database instance and Directory Services. ```ts -const role = new iam.Role(stack, 'RDSDirectoryServicesRole', { +declare const vpc: ec2.Vpc; +const role = new iam.Role(this, 'RDSDirectoryServicesRole', { assumedBy: new iam.ServicePrincipal('rds.amazonaws.com'), managedPolicies: [ iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonRDSDirectoryServiceAccess'), ], }); -const instance = new rds.DatabaseInstance(stack, 'Instance', { +const instance = new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.mysql({ version: rds.MysqlEngineVersion.VER_8_0_19 }), vpc, domain: 'd-????????', // The ID of the domain for the instance to join. @@ -356,13 +379,15 @@ Database instances and clusters both expose metrics (`cloudwatch.Metric`): ```ts // The number of database connections in use (average over 5 minutes) +declare const instance: rds.DatabaseInstance; const dbConnections = instance.metricDatabaseConnections(); // Average CPU utilization over 5 minutes +declare const cluster: rds.DatabaseCluster; const cpuUtilization = cluster.metricCPUUtilization(); // The average amount of time taken per disk I/O operation (average over 1 minute) -const readLatency = instance.metric('ReadLatency', { statistic: 'Average', periodSec: 60 }); +const readLatency = instance.metric('ReadLatency', { statistic: 'Average', period: Duration.seconds(60) }); ``` ## Enabling S3 integration @@ -388,10 +413,14 @@ The following snippet sets up a database cluster with different S3 buckets where ```ts import * as s3 from '@aws-cdk/aws-s3'; +declare const vpc: ec2.Vpc; const importBucket = new s3.Bucket(this, 'importbucket'); const exportBucket = new s3.Bucket(this, 'exportbucket'); new rds.DatabaseCluster(this, 'dbcluster', { - // ... + engine: rds.DatabaseClusterEngine.AURORA, + instanceProps: { + vpc, + }, s3ImportBuckets: [importBucket], s3ExportBuckets: [exportBucket], }); @@ -405,18 +434,13 @@ connections to the database and improve scalability of the application. Learn mo The following code configures an RDS Proxy for a `DatabaseInstance`. ```ts -import * as cdk from '@aws-cdk/core'; -import * as ec2 from '@aws-cdk/aws-ec2'; -import * as rds from '@aws-cdk/aws-rds'; -import * as secrets from '@aws-cdk/aws-secretsmanager'; - -const vpc: ec2.IVpc = ...; -const securityGroup: ec2.ISecurityGroup = ...; -const secrets: secrets.ISecret[] = [...]; -const dbInstance: rds.IDatabaseInstance = ...; +declare const vpc: ec2.Vpc; +declare const securityGroup: ec2.SecurityGroup; +declare const secrets: secretsmanager.Secret[]; +declare const dbInstance: rds.DatabaseInstance; const proxy = dbInstance.addProxy('proxy', { - connectionBorrowTimeout: cdk.Duration.seconds(30), + borrowTimeout: Duration.seconds(30), maxConnectionsPercent: 50, secrets, vpc, @@ -430,12 +454,18 @@ store the data in highly durable storage, and manage the data with the CloudWatc instances and clusters; the types of logs available depend on the database type and engine being used. ```ts +import * as logs from '@aws-cdk/aws-logs'; +declare const myLogsPublishingRole: iam.Role; +declare const vpc: ec2.Vpc; + // Exporting logs from a cluster const cluster = new rds.DatabaseCluster(this, 'Database', { engine: rds.DatabaseClusterEngine.aurora({ version: rds.AuroraEngineVersion.VER_1_17_9, // different version class for each engine type + }), + instanceProps: { + vpc, }, - // ... cloudwatchLogsExports: ['error', 'general', 'slowquery', 'audit'], // Export all available MySQL-based logs cloudwatchLogsRetention: logs.RetentionDays.THREE_MONTHS, // Optional - default is to never expire logs cloudwatchLogsRetentionRole: myLogsPublishingRole, // Optional - a role will be created if not provided @@ -447,7 +477,7 @@ const instance = new rds.DatabaseInstance(this, 'Instance', { engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_12_3, }), - // ... + vpc, cloudwatchLogsExports: ['postgresql'], // Export the PostgreSQL logs // ... }); @@ -460,9 +490,10 @@ Amazon RDS uses option groups to enable and configure these features. An option that are available for a particular Amazon RDS DB instance. ```ts -const vpc: ec2.IVpc = ...; -const securityGroup: ec2.ISecurityGroup = ...; -new rds.OptionGroup(stack, 'Options', { +declare const vpc: ec2.Vpc; +declare const securityGroup: ec2.SecurityGroup; + +new rds.OptionGroup(this, 'Options', { engine: rds.DatabaseInstanceEngine.oracleSe2({ version: rds.OracleEngineVersion.VER_19, }), @@ -489,10 +520,7 @@ Aurora Serverless clusters can specify scaling properties which will be used to automatically scale the database cluster seamlessly based on the workload. ```ts -import * as ec2 from '@aws-cdk/aws-ec2'; -import * as rds from '@aws-cdk/aws-rds'; - -const vpc = new ec2.Vpc(this, 'myrdsvpc'); +declare const vpc: ec2.Vpc; const cluster = new rds.ServerlessCluster(this, 'AnotherCluster', { engine: rds.DatabaseClusterEngine.AURORA_POSTGRESQL, @@ -532,11 +560,7 @@ You can access your Aurora Serverless DB cluster using the built-in Data API. Th The following example shows granting Data API access to a Lamba function. ```ts -import * as ec2 from '@aws-cdk/aws-ec2'; -import * as lambda from '@aws-cdk/aws-lambda'; -import * as rds from '@aws-cdk/aws-rds'; - -const vpc = new ec2.Vpc(this, 'MyVPC'); +declare const vpc: ec2.Vpc; const cluster = new rds.ServerlessCluster(this, 'AnotherCluster', { engine: rds.DatabaseClusterEngine.AURORA_MYSQL, @@ -544,16 +568,17 @@ const cluster = new rds.ServerlessCluster(this, 'AnotherCluster', { enableDataApi: true, // Optional - will be automatically set if you call grantDataApiAccess() }); +declare const code: lambda.Code; const fn = new lambda.Function(this, 'MyFunction', { runtime: lambda.Runtime.NODEJS_12_X, handler: 'index.handler', - code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), + code, environment: { CLUSTER_ARN: cluster.clusterArn, - SECRET_ARN: cluster.secret.secretArn, + SECRET_ARN: cluster.secret!.secretArn, }, }); -cluster.grantDataApiAccess(fn) +cluster.grantDataApiAccess(fn); ``` **Note**: To invoke the Data API, the resource will need to read the secret associated with the cluster. diff --git a/packages/@aws-cdk/aws-rds/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-rds/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..7e78fde1372a1 --- /dev/null +++ b/packages/@aws-cdk/aws-rds/rosetta/default.ts-fixture @@ -0,0 +1,18 @@ +// Fixture with packages imported, but nothing else +import { Duration, SecretValue, Stack } from '@aws-cdk/core'; +import { Construct } from 'constructs'; +import ec2 = require('@aws-cdk/aws-ec2'); +import rds = require('@aws-cdk/aws-rds'); +import targets = require('@aws-cdk/aws-events-targets'); +import lambda = require('@aws-cdk/aws-lambda'); +import kms = require('@aws-cdk/aws-kms'); +import iam = require('@aws-cdk/aws-iam'); +import secretsmanager = require('@aws-cdk/aws-secretsmanager'); + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} From 25cea1807539a8d45f3f4ff8b775b3417387d6fe Mon Sep 17 00:00:00 2001 From: Robert Djurasaj Date: Mon, 1 Nov 2021 14:27:15 -0600 Subject: [PATCH 07/70] feat(ec2): add c6i instances (#17237) New C6I instances just got released: https://aws.amazon.com/blogs/aws/new-amazon-ec2-c6i-instances-powered-by-the-latest-generation-intel-xeon-scalable-processors/ Docs have already been updated: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-instancetype Screen Shot 2021-10-29 at 3 11 00 PM ---- *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/instance-types.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/@aws-cdk/aws-ec2/lib/instance-types.ts b/packages/@aws-cdk/aws-ec2/lib/instance-types.ts index a2c5ccdadc760..1fc4e02f25daa 100644 --- a/packages/@aws-cdk/aws-ec2/lib/instance-types.ts +++ b/packages/@aws-cdk/aws-ec2/lib/instance-types.ts @@ -208,6 +208,16 @@ export enum InstanceClass { */ C5 = 'c5', + /** + * Compute optimized instances, 6th generation + */ + COMPUTE6_INTEL = 'c6i', + + /** + * Compute optimized instances, 6th generation + */ + C6I = 'c6i', + /** * Compute optimized instances with local NVME drive, 5th generation */ From d6585253067a0e4013d2a2d41a3d3adfd40d823c Mon Sep 17 00:00:00 2001 From: Nick Lynch Date: Mon, 1 Nov 2021 21:21:16 +0000 Subject: [PATCH 08/70] chore: use fixed deprecated list for strip-deprecated (#17260) This is a continuation (and the final piece!) of https://github.com/aws/jsii/pull/3085 and https://github.com/aws/aws-cdk/pull/17120. Changes cdk-build to use the fixed deprecated list, rather than stripping all deprecated elements. This will enable us to deprecate new elements going forward without stripping them from v2 and breaking customers. closes #16566 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- tools/@aws-cdk/cdk-build-tools/lib/package-info.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/@aws-cdk/cdk-build-tools/lib/package-info.ts b/tools/@aws-cdk/cdk-build-tools/lib/package-info.ts index 5b79a2d675a0a..b264d3043b1b6 100644 --- a/tools/@aws-cdk/cdk-build-tools/lib/package-info.ts +++ b/tools/@aws-cdk/cdk-build-tools/lib/package-info.ts @@ -99,7 +99,7 @@ export function packageCompiler(compilers: CompilerOverrides, options?: CDKBuild if (isJsii()) { const args = ['--silence-warnings=reserved-word']; if (options?.stripDeprecated) { - args.push('--strip-deprecated'); + args.push(`--strip-deprecated ${path.join(__dirname, '..', '..', '..', '..', 'deprecated_apis.txt')}`); } return [compilers.jsii || require.resolve('jsii/bin/jsii'), ...args]; } else { From 606a2d3e6ba23c184cd6ef989f68122f16627565 Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Tue, 2 Nov 2021 00:15:13 +0200 Subject: [PATCH 09/70] chore: simplify auto approve mechanism (#17264) Currently, PR's are auto approved if they either: 1. Contain the `pr/auto-approve` label. 2. Created by `dependabot` 3. Created by `aws-cdk-automation` This is somewhat convoluted, and complicates the responsibility of the `auto-approve` workflow. In addition, this makes it impossible to formulate a single GitHub query to lookup all automated PR's that we expect to be approved and merged without human intervention. This PR switches to a simpler mechanism, by which the `auto-approve` workflow will **only** approve PR's that contain the appropriate label, forcing all PR creators to add the label if they wish to be auto-approved. This means we can now use a simple `label:pr/auto-approve` query to find all those automated PR's. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .github/workflows/auto-approve.yml | 6 +----- .github/workflows/pr-labeler.yml | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/pr-labeler.yml diff --git a/.github/workflows/auto-approve.yml b/.github/workflows/auto-approve.yml index 6e186b15f078f..ed29d53382d1f 100644 --- a/.github/workflows/auto-approve.yml +++ b/.github/workflows/auto-approve.yml @@ -7,11 +7,7 @@ on: jobs: auto-approve: - if: > - github.event.pull_request.user.login == 'dependabot[bot]' - || github.event.pull_request.user.login == 'dependabot-preview[bot]' - || (contains(github.event.pull_request.labels.*.name, 'pr/auto-approve') - && github.event.pull_request.user.login == 'aws-cdk-automation') + if: contains(github.event.pull_request.labels.*.name, 'pr/auto-approve') runs-on: ubuntu-latest permissions: pull-requests: write diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml new file mode 100644 index 0000000000000..b8a816623a9e0 --- /dev/null +++ b/.github/workflows/pr-labeler.yml @@ -0,0 +1,17 @@ +# Apply various labels on PRs + +name: pr-labeler +on: + pull_request: + types: [ opened ] + +jobs: + auto-approve: + if: github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'dependabot-preview[bot]' + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - run: gh pr edit ${{ github.event.pull_request.number }} --add-label "pr/auto-approve" -R ${{ github.repository }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 135f7d33db5e96c3af4a8691c13b419e7b14ceae Mon Sep 17 00:00:00 2001 From: Julian Michel Date: Tue, 2 Nov 2021 00:09:24 +0100 Subject: [PATCH 10/70] feat(docdb): add the ability to exclude characters when generating passwords (#17262) Add property `excludeCharaters` to provide the ability to exclude characters when generating passwords in DocumentDB. Requested in #15732. ---- *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-docdb/README.md | 1 + packages/@aws-cdk/aws-docdb/lib/cluster.ts | 1 + .../@aws-cdk/aws-docdb/lib/database-secret.ts | 9 ++++++- packages/@aws-cdk/aws-docdb/lib/props.ts | 7 ++++++ .../@aws-cdk/aws-docdb/test/cluster.test.ts | 25 ++++++++++++++++++- 5 files changed, 41 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-docdb/README.md b/packages/@aws-cdk/aws-docdb/README.md index 6f7ed89e28e11..12f8e08a08387 100644 --- a/packages/@aws-cdk/aws-docdb/README.md +++ b/packages/@aws-cdk/aws-docdb/README.md @@ -21,6 +21,7 @@ your instances will be launched privately or publicly: const cluster = new DatabaseCluster(this, 'Database', { masterUser: { username: 'myuser' // NOTE: 'admin' is reserved by DocumentDB + excludeCharacters: '\"@/:', // optional, defaults to the set "\"@/" }, instanceType: ec2.InstanceType.of(ec2.InstanceClass.R5, ec2.InstanceSize.LARGE), vpcSubnets: { diff --git a/packages/@aws-cdk/aws-docdb/lib/cluster.ts b/packages/@aws-cdk/aws-docdb/lib/cluster.ts index 56b5a724dd439..c2b4c7c9737a2 100644 --- a/packages/@aws-cdk/aws-docdb/lib/cluster.ts +++ b/packages/@aws-cdk/aws-docdb/lib/cluster.ts @@ -352,6 +352,7 @@ export class DatabaseCluster extends DatabaseClusterBase { secret = new DatabaseSecret(this, 'Secret', { username: props.masterUser.username, encryptionKey: props.masterUser.kmsKey, + excludeCharacters: props.masterUser.excludeCharacters, }); } diff --git a/packages/@aws-cdk/aws-docdb/lib/database-secret.ts b/packages/@aws-cdk/aws-docdb/lib/database-secret.ts index 605609b4b6ab2..8f1bca671da6d 100644 --- a/packages/@aws-cdk/aws-docdb/lib/database-secret.ts +++ b/packages/@aws-cdk/aws-docdb/lib/database-secret.ts @@ -32,6 +32,13 @@ export interface DatabaseSecretProps { * @default - no master secret information will be included */ readonly masterSecret?: ISecret; + + /** + * Characters to not include in the generated password. + * + * @default "\"@/" + */ + readonly excludeCharacters?: string; } /** @@ -61,7 +68,7 @@ export class DatabaseSecret extends Secret { masterarn: props.masterSecret?.secretArn, }), generateStringKey: 'password', - excludeCharacters: '"@/', + excludeCharacters: props.excludeCharacters ?? '"@/', }, }); } diff --git a/packages/@aws-cdk/aws-docdb/lib/props.ts b/packages/@aws-cdk/aws-docdb/lib/props.ts index 9cd24b1fce1bc..d02f8768973a9 100644 --- a/packages/@aws-cdk/aws-docdb/lib/props.ts +++ b/packages/@aws-cdk/aws-docdb/lib/props.ts @@ -53,6 +53,13 @@ export interface Login { * @default default master key */ readonly kmsKey?: kms.IKey; + + /** + * Specifies characters to not include in generated passwords. + * + * @default "\"@/" + */ + readonly excludeCharacters?: string; } /** diff --git a/packages/@aws-cdk/aws-docdb/test/cluster.test.ts b/packages/@aws-cdk/aws-docdb/test/cluster.test.ts index cb1f8653509df..6628520118c84 100644 --- a/packages/@aws-cdk/aws-docdb/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-docdb/test/cluster.test.ts @@ -1,4 +1,4 @@ -import { expect as expectCDK, haveResource, ResourcePart, arrayWith } from '@aws-cdk/assert-internal'; +import { expect as expectCDK, haveResource, ResourcePart, arrayWith, haveResourceLike, objectLike } from '@aws-cdk/assert-internal'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as kms from '@aws-cdk/aws-kms'; import * as cdk from '@aws-cdk/core'; @@ -293,6 +293,29 @@ describe('DatabaseCluster', () => { })); }); + test('creates a secret with excludeCharacters', () => { + // GIVEN + const stack = testStack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + + // WHEN + new DatabaseCluster(stack, 'Database', { + masterUser: { + username: 'admin', + excludeCharacters: '"@/()[]', + }, + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + vpc, + }); + + // THEN + expectCDK(stack).to(haveResourceLike('AWS::SecretsManager::Secret', { + GenerateSecretString: objectLike({ + ExcludeCharacters: '\"@/()[]', + }), + })); + }); + test('create an encrypted cluster with custom KMS key', () => { // GIVEN const stack = testStack(); From 1ab9b265e9899ffcd093b3600d658c8a6519cc69 Mon Sep 17 00:00:00 2001 From: Yuto Osawa <7953650+tandfy@users.noreply.github.com> Date: Tue, 2 Nov 2021 09:03:29 +0900 Subject: [PATCH 11/70] feat(synthetics): add static cron method to schedule class (#17250) closes #16402 ---- *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-synthetics/README.md | 8 ++- .../@aws-cdk/aws-synthetics/lib/schedule.ts | 72 +++++++++++++++++++ .../aws-synthetics/test/canary.test.ts | 21 ++++++ .../aws-synthetics/test/schedule.test.ts | 26 +++++++ 4 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 packages/@aws-cdk/aws-synthetics/test/schedule.test.ts diff --git a/packages/@aws-cdk/aws-synthetics/README.md b/packages/@aws-cdk/aws-synthetics/README.md index 7f7665e02238c..013205a4ce3e4 100644 --- a/packages/@aws-cdk/aws-synthetics/README.md +++ b/packages/@aws-cdk/aws-synthetics/README.md @@ -97,13 +97,15 @@ object to the `schedule` property. Configure a run rate of up to 60 minutes with `Schedule.rate`: ```ts -Schedule.rate(Duration.minutes(5)), // Runs every 5 minutes. +Schedule.rate(Duration.minutes(5)) // Runs every 5 minutes. ``` -You can also specify a [cron expression](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_cron.html) via `Schedule.expression`: +You can also specify a [cron expression](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_cron.html) with `Schedule.cron`: ```ts -Schedule.expression('cron(0 0,8,16 * * ? *)'), // Run at 12am, 8am, 4pm UTC every day +Schedule.cron({ + hour: '0,8,16' // Run at 12am, 8am, 4pm UTC every day +}) ``` If you want the canary to run just once upon deployment, you can use `Schedule.once()`. diff --git a/packages/@aws-cdk/aws-synthetics/lib/schedule.ts b/packages/@aws-cdk/aws-synthetics/lib/schedule.ts index 3bd92c81b4d0b..248b44e4c59cb 100644 --- a/packages/@aws-cdk/aws-synthetics/lib/schedule.ts +++ b/packages/@aws-cdk/aws-synthetics/lib/schedule.ts @@ -42,9 +42,81 @@ export class Schedule { return new Schedule(`rate(${minutes} minutes)`); } + /** + * Create a schedule from a set of cron fields + */ + public static cron(options: CronOptions): Schedule { + if (options.weekDay !== undefined && options.day !== undefined) { + throw new Error('Cannot supply both \'day\' and \'weekDay\', use at most one'); + } + + const minute = fallback(options.minute, '*'); + const hour = fallback(options.hour, '*'); + const month = fallback(options.month, '*'); + + // Weekday defaults to '?' if not supplied. If it is supplied, day must become '?' + const day = fallback(options.day, options.weekDay !== undefined ? '?' : '*'); + const weekDay = fallback(options.weekDay, '?'); + + // '*' is only allowed in the year field + const year = '*'; + + return new Schedule(`cron(${minute} ${hour} ${day} ${month} ${weekDay} ${year})`); + } + private constructor( /** * The Schedule expression */ public readonly expressionString: string) {} } + + +/** + * Options to configure a cron expression + * + * All fields are strings so you can use complex expressions. Absence of + * a field implies '*' or '?', whichever one is appropriate. + * + * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_cron.html + */ +export interface CronOptions { + /** + * The minute to run this rule at + * + * @default - Every minute + */ + readonly minute?: string; + + /** + * The hour to run this rule at + * + * @default - Every hour + */ + readonly hour?: string; + + /** + * The day of the month to run this rule at + * + * @default - Every day of the month + */ + readonly day?: string; + + /** + * The month to run this rule at + * + * @default - Every month + */ + readonly month?: string; + + /** + * The day of the week to run this rule at + * + * @default - Any day of the week + */ + readonly weekDay?: string; +} + +function fallback(x: string | undefined, def: string): string { + return x ?? def; +} diff --git a/packages/@aws-cdk/aws-synthetics/test/canary.test.ts b/packages/@aws-cdk/aws-synthetics/test/canary.test.ts index 27491d01b2850..83ba173562834 100644 --- a/packages/@aws-cdk/aws-synthetics/test/canary.test.ts +++ b/packages/@aws-cdk/aws-synthetics/test/canary.test.ts @@ -292,6 +292,27 @@ test('Schedule can be set to 1 minute', () => { }); }); +test('Schedule can be set with Cron', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new synthetics.Canary(stack, 'Canary', { + schedule: synthetics.Schedule.cron({ minute: '30' }), + test: synthetics.Test.custom({ + handler: 'index.handler', + code: synthetics.Code.fromInline('/* Synthetics handler code */'), + }), + runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_3, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Schedule: Match.objectLike({ Expression: 'cron(30 * * * ? *)' }), + }); +}); + + test('Schedule can be set with Expression', () => { // GIVEN const stack = new Stack(); diff --git a/packages/@aws-cdk/aws-synthetics/test/schedule.test.ts b/packages/@aws-cdk/aws-synthetics/test/schedule.test.ts new file mode 100644 index 0000000000000..664f27774b61f --- /dev/null +++ b/packages/@aws-cdk/aws-synthetics/test/schedule.test.ts @@ -0,0 +1,26 @@ +import * as synthetics from '../lib'; + +describe('cron', () => { + test('day and weekDay are mutex: given week day', () => { + expect(synthetics.Schedule.cron({ + weekDay: 'MON-FRI', + }).expressionString).toEqual('cron(* * ? * MON-FRI *)'); + }); + + test('day and weekDay are mutex: given month day', () => { + expect(synthetics.Schedule.cron({ + day: '1', + }).expressionString).toEqual('cron(* * 1 * ? *)'); + }); + + test('day and weekDay are mutex: given neither', () => { + expect(synthetics.Schedule.cron({}).expressionString).toEqual('cron(* * * * ? *)'); + }); + + test('day and weekDay are mutex: throw if given both', () => { + expect(() => synthetics.Schedule.cron({ + day: '1', + weekDay: 'MON', + })).toThrow('Cannot supply both \'day\' and \'weekDay\', use at most one'); + }); +}); From 864c50ed2f3ae133af0cffd17ed77a6cf32ac6f4 Mon Sep 17 00:00:00 2001 From: Nick Lynch Date: Tue, 2 Nov 2021 15:54:59 +0000 Subject: [PATCH 12/70] fix(cli): cdk ls --long outputs less-friendly stack IDs for nested assemblies (#17263) Since #14379, `cdk ls` has outputted friendlier stack names for nested assemblies (e.g., with pipelines). However, `cdk ls --long` still outputs the less-friendly stack IDs. ---- *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/cdk-toolkit.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk/lib/cdk-toolkit.ts b/packages/aws-cdk/lib/cdk-toolkit.ts index 6bc109dd37822..65aa443190a57 100644 --- a/packages/aws-cdk/lib/cdk-toolkit.ts +++ b/packages/aws-cdk/lib/cdk-toolkit.ts @@ -282,7 +282,7 @@ export class CdkToolkit { const long = []; for (const stack of stacks.stackArtifacts) { long.push({ - id: stack.id, + id: stack.hierarchicalId, name: stack.stackName, environment: stack.environment, }); From d4952c3cbe12e7c8c27e1bca7f9d8536d93fd3cb Mon Sep 17 00:00:00 2001 From: Peter Woodworth <44349620+peterwoodworth@users.noreply.github.com> Date: Tue, 2 Nov 2021 10:35:39 -0700 Subject: [PATCH 13/70] fix(ec2): functions addIngressRule and addEgressRule detect unresolved tokens as duplicates (#17221) fixes #17201 The issue is when the same security group uses these functions, so I added a private counter to `SecurityGroupBase`. However, to modify this private counter, `determineRuleScope` and `renderPeer` need to be member functions. These originally weren't member functions for a reason, and that's because `SecurityGroup` also uses these functions. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-ec2/lib/security-group.ts | 152 +++++++++--------- .../aws-ec2/test/security-group.test.ts | 24 +++ 2 files changed, 104 insertions(+), 72 deletions(-) diff --git a/packages/@aws-cdk/aws-ec2/lib/security-group.ts b/packages/@aws-cdk/aws-ec2/lib/security-group.ts index 54695f2d17b71..692df3629ebbf 100644 --- a/packages/@aws-cdk/aws-ec2/lib/security-group.ts +++ b/packages/@aws-cdk/aws-ec2/lib/security-group.ts @@ -68,6 +68,8 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup { public readonly connections: Connections = new Connections({ securityGroups: [this] }); public readonly defaultPort?: Port; + private peerAsTokenCount: number = 0; + constructor(scope: Construct, id: string, props?: ResourceProps) { super(scope, id, props); @@ -83,7 +85,7 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup { description = `from ${peer.uniqueId}:${connection}`; } - const [scope, id] = determineRuleScope(this, peer, connection, 'from', remoteRule); + const [scope, id] = this.determineRuleScope(peer, connection, 'from', remoteRule); // Skip duplicates if (scope.node.tryFindChild(id) === undefined) { @@ -101,7 +103,7 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup { description = `to ${peer.uniqueId}:${connection}`; } - const [scope, id] = determineRuleScope(this, peer, connection, 'to', remoteRule); + const [scope, id] = this.determineRuleScope(peer, connection, 'to', remoteRule); // Skip duplicates if (scope.node.tryFindChild(id) === undefined) { @@ -121,75 +123,82 @@ abstract class SecurityGroupBase extends Resource implements ISecurityGroup { public toEgressRuleConfig(): any { return { destinationSecurityGroupId: this.securityGroupId }; } -} -/** - * Determine where to parent a new ingress/egress rule - * - * A SecurityGroup rule is parented under the group it's related to, UNLESS - * we're in a cross-stack scenario with another Security Group. In that case, - * we respect the 'remoteRule' flag and will parent under the other security - * group. - * - * This is necessary to avoid cyclic dependencies between stacks, since both - * ingress and egress rules will reference both security groups, and a naive - * parenting will lead to the following situation: - * - * ╔════════════════════╗ ╔════════════════════╗ - * ║ ┌───────────┐ ║ ║ ┌───────────┐ ║ - * ║ │ GroupA │◀────╬─┐ ┌───╬───▶│ GroupB │ ║ - * ║ └───────────┘ ║ │ │ ║ └───────────┘ ║ - * ║ ▲ ║ │ │ ║ ▲ ║ - * ║ │ ║ │ │ ║ │ ║ - * ║ │ ║ │ │ ║ │ ║ - * ║ ┌───────────┐ ║ └───┼───╬────┌───────────┐ ║ - * ║ │ EgressA │─────╬─────┘ ║ │ IngressB │ ║ - * ║ └───────────┘ ║ ║ └───────────┘ ║ - * ║ ║ ║ ║ - * ╚════════════════════╝ ╚════════════════════╝ - * - * By having the ability to switch the parent, we avoid the cyclic reference by - * keeping all rules in a single stack. - * - * If this happens, we also have to change the construct ID, because - * otherwise we might have two objects with the same ID if we have - * multiple reversed security group relationships. - * - * ╔═══════════════════════════════════╗ - * ║┌───────────┐ ║ - * ║│ GroupB │ ║ - * ║└───────────┘ ║ - * ║ ▲ ║ - * ║ │ ┌───────────┐ ║ - * ║ ├────"from A"──│ IngressB │ ║ - * ║ │ └───────────┘ ║ - * ║ │ ┌───────────┐ ║ - * ║ ├─────"to B"───│ EgressA │ ║ - * ║ │ └───────────┘ ║ - * ║ │ ┌───────────┐ ║ - * ║ └─────"to B"───│ EgressC │ ║ <-- oops - * ║ └───────────┘ ║ - * ╚═══════════════════════════════════╝ - */ -function determineRuleScope( - group: SecurityGroupBase, - peer: IPeer, - connection: Port, - fromTo: 'from' | 'to', - remoteRule?: boolean): [SecurityGroupBase, string] { - - if (remoteRule && SecurityGroupBase.isSecurityGroup(peer) && differentStacks(group, peer)) { - // Reversed - const reversedFromTo = fromTo === 'from' ? 'to' : 'from'; - return [peer, `${group.uniqueId}:${connection} ${reversedFromTo}`]; - } else { - // Regular (do old ID escaping to in order to not disturb existing deployments) - return [group, `${fromTo} ${renderPeer(peer)}:${connection}`.replace('/', '_')]; + /** + * Determine where to parent a new ingress/egress rule + * + * A SecurityGroup rule is parented under the group it's related to, UNLESS + * we're in a cross-stack scenario with another Security Group. In that case, + * we respect the 'remoteRule' flag and will parent under the other security + * group. + * + * This is necessary to avoid cyclic dependencies between stacks, since both + * ingress and egress rules will reference both security groups, and a naive + * parenting will lead to the following situation: + * + * ╔════════════════════╗ ╔════════════════════╗ + * ║ ┌───────────┐ ║ ║ ┌───────────┐ ║ + * ║ │ GroupA │◀────╬─┐ ┌───╬───▶│ GroupB │ ║ + * ║ └───────────┘ ║ │ │ ║ └───────────┘ ║ + * ║ ▲ ║ │ │ ║ ▲ ║ + * ║ │ ║ │ │ ║ │ ║ + * ║ │ ║ │ │ ║ │ ║ + * ║ ┌───────────┐ ║ └───┼───╬────┌───────────┐ ║ + * ║ │ EgressA │─────╬─────┘ ║ │ IngressB │ ║ + * ║ └───────────┘ ║ ║ └───────────┘ ║ + * ║ ║ ║ ║ + * ╚════════════════════╝ ╚════════════════════╝ + * + * By having the ability to switch the parent, we avoid the cyclic reference by + * keeping all rules in a single stack. + * + * If this happens, we also have to change the construct ID, because + * otherwise we might have two objects with the same ID if we have + * multiple reversed security group relationships. + * + * ╔═══════════════════════════════════╗ + * ║┌───────────┐ ║ + * ║│ GroupB │ ║ + * ║└───────────┘ ║ + * ║ ▲ ║ + * ║ │ ┌───────────┐ ║ + * ║ ├────"from A"──│ IngressB │ ║ + * ║ │ └───────────┘ ║ + * ║ │ ┌───────────┐ ║ + * ║ ├─────"to B"───│ EgressA │ ║ + * ║ │ └───────────┘ ║ + * ║ │ ┌───────────┐ ║ + * ║ └─────"to B"───│ EgressC │ ║ <-- oops + * ║ └───────────┘ ║ + * ╚═══════════════════════════════════╝ + */ + + protected determineRuleScope( + peer: IPeer, + connection: Port, + fromTo: 'from' | 'to', + remoteRule?: boolean): [SecurityGroupBase, string] { + + if (remoteRule && SecurityGroupBase.isSecurityGroup(peer) && differentStacks(this, peer)) { + // Reversed + const reversedFromTo = fromTo === 'from' ? 'to' : 'from'; + return [peer, `${this.uniqueId}:${connection} ${reversedFromTo}`]; + } else { + // Regular (do old ID escaping to in order to not disturb existing deployments) + return [this, `${fromTo} ${this.renderPeer(peer)}:${connection}`.replace('/', '_')]; + } } -} -function renderPeer(peer: IPeer) { - return Token.isUnresolved(peer.uniqueId) ? '{IndirectPeer}' : peer.uniqueId; + private renderPeer(peer: IPeer) { + if (Token.isUnresolved(peer.uniqueId)) { + // Need to return a unique value each time a peer + // is an unresolved token, else the duplicate skipper + // in `sg.addXxxRule` can detect unique rules as duplicates + return this.peerAsTokenCount++ ? `'{IndirectPeer${this.peerAsTokenCount}}'` : '{IndirectPeer}'; + } else { + return peer.uniqueId; + } + } } function differentStacks(group1: SecurityGroupBase, group2: SecurityGroupBase) { @@ -565,13 +574,12 @@ export class SecurityGroup extends SecurityGroupBase { */ private removeNoTrafficRule() { if (this.disableInlineRules) { - const [scope, id] = determineRuleScope( - this, + const [scope, id] = this.determineRuleScope( NO_TRAFFIC_PEER, NO_TRAFFIC_PORT, 'to', - false); - + false, + ); scope.node.tryRemoveChild(id); } else { const i = this.directEgressRules.findIndex(r => egressRulesEqual(r, MATCH_NO_TRAFFIC)); diff --git a/packages/@aws-cdk/aws-ec2/test/security-group.test.ts b/packages/@aws-cdk/aws-ec2/test/security-group.test.ts index 09ccc6cdc682e..70dbe64cef335 100644 --- a/packages/@aws-cdk/aws-ec2/test/security-group.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/security-group.test.ts @@ -208,6 +208,30 @@ describe('security group', () => { }); + test('can add multiple rules using tokens on same security group', () => { + // GIVEN + const stack = new Stack(undefined, 'TestStack', { env: { account: '12345678', region: 'dummy' } }); + const vpc = new Vpc(stack, 'VPC'); + const sg = new SecurityGroup(stack, 'SG', { vpc }); + + const p1 = Lazy.string({ produce: () => 'dummyid1' }); + const p2 = Lazy.string({ produce: () => 'dummyid2' }); + const peer1 = Peer.prefixList(p1); + const peer2 = Peer.prefixList(p2); + + // WHEN + sg.addIngressRule(peer1, Port.tcp(5432), 'Rule 1'); + sg.addIngressRule(peer2, Port.tcp(5432), 'Rule 2'); + + // THEN -- no crash + expect(stack).toHaveResourceLike('AWS::EC2::SecurityGroupIngress', { + Description: 'Rule 1', + }); + expect(stack).toHaveResourceLike('AWS::EC2::SecurityGroupIngress', { + Description: 'Rule 2', + }); + }); + test('if tokens are used in ports, `canInlineRule` should be false to avoid cycles', () => { // GIVEN const p1 = Lazy.number({ produce: () => 80 }); From f8d0ef550df07e43aeab35dde4406c92f7551ed0 Mon Sep 17 00:00:00 2001 From: arcrank Date: Tue, 2 Nov 2021 14:30:17 -0400 Subject: [PATCH 14/70] feat(servicecatalog): allow creating a CFN Product Version with CDK code (#17144) Add ability to define a product version entirely within CDK as opposed to referencing templates or local assets. The service catalog `ProductStack` is similar to `NestedStacks` that do not deploy themselves but rather are referenced by the parent stacks. The resources defined in your product are added to the product stack like any other cdk app. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* Co-authored-by: Dillon Ponzo --- .../@aws-cdk/aws-servicecatalog/README.md | 39 +++++- .../lib/cloudformation-template.ts | 26 ++++ .../@aws-cdk/aws-servicecatalog/lib/index.ts | 1 + .../lib/private/product-stack-synthesizer.ts | 34 ++++++ .../aws-servicecatalog/lib/product-stack.ts | 77 ++++++++++++ .../@aws-cdk/aws-servicecatalog/package.json | 3 +- .../rosetta/basic-portfolio.ts-fixture | 6 +- .../test/integ.product.expected.json | 114 ++++++++++++++++++ .../aws-servicecatalog/test/integ.product.ts | 15 +++ .../test/product-stack.test.ts | 88 ++++++++++++++ .../aws-servicecatalog/test/product.test.ts | 88 ++++++++++++++ 11 files changed, 485 insertions(+), 6 deletions(-) create mode 100644 packages/@aws-cdk/aws-servicecatalog/lib/private/product-stack-synthesizer.ts create mode 100644 packages/@aws-cdk/aws-servicecatalog/lib/product-stack.ts create mode 100644 packages/@aws-cdk/aws-servicecatalog/test/product-stack.test.ts diff --git a/packages/@aws-cdk/aws-servicecatalog/README.md b/packages/@aws-cdk/aws-servicecatalog/README.md index 4bb6885c601eb..2d7694d3e84b6 100644 --- a/packages/@aws-cdk/aws-servicecatalog/README.md +++ b/packages/@aws-cdk/aws-servicecatalog/README.md @@ -30,6 +30,8 @@ enables organizations to create and manage catalogs of products for their end us - [Granting access to a portfolio](#granting-access-to-a-portfolio) - [Sharing a portfolio with another AWS account](#sharing-a-portfolio-with-another-aws-account) - [Product](#product) + - [Creating a product from a local asset](#creating-a-product-from-local-asset) + - [Creating a product from a stack](#creating-a-product-from-a-stack) - [Adding a product to a portfolio](#adding-a-product-to-a-portfolio) - [TagOptions](#tag-options) - [Constraints](#constraints) @@ -125,10 +127,12 @@ const product = new servicecatalog.CloudFormationProduct(this, 'MyFirstProduct', cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromUrl( 'https://raw.githubusercontent.com/awslabs/aws-cloudformation-templates/master/aws/services/ServiceCatalog/Product.yaml'), }, - ] + ], }); ``` +### Creating a product from a local asset + A `CloudFormationProduct` can also be created using a Cloudformation template from an Asset. Assets are files that are uploaded to an S3 Bucket before deployment. `CloudFormationTemplate.fromAsset` can be utilized to create a Product by passing the path to a local template file on your disk: @@ -149,7 +153,38 @@ const product = new servicecatalog.CloudFormationProduct(this, 'MyFirstProduct', productVersionName: "v2", cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromAsset(path.join(__dirname, 'development-environment.template.json')), }, - ] + ], +}); +``` + +### Creating a product from a stack + +You can define a service catalog `CloudFormationProduct` entirely within CDK using a service catalog `ProductStack`. +A separate child stack for your product is created and you can add resources like you would for any other CDK stack, +such as an S3 Bucket, IAM roles, and EC2 instances. This stack is passed in as a product version to your +product. This will not create a separate stack during deployment. + +```ts +import * as s3 from '@aws-cdk/aws-s3'; +import * as cdk from '@aws-cdk/core'; + +class S3BucketProduct extends servicecatalog.ProductStack { + constructor(scope: cdk.Construct, id: string) { + super(scope, id); + + new s3.Bucket(this, 'BucketProduct'); + } +} + +const product = new servicecatalog.CloudFormationProduct(this, 'MyFirstProduct', { + productName: "My Product", + owner: "Product Owner", + productVersions: [ + { + productVersionName: "v1", + cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(new S3BucketProduct(this, 'S3BucketProduct')), + }, + ], }); ``` diff --git a/packages/@aws-cdk/aws-servicecatalog/lib/cloudformation-template.ts b/packages/@aws-cdk/aws-servicecatalog/lib/cloudformation-template.ts index be0cb9adf2022..4086db6655fda 100644 --- a/packages/@aws-cdk/aws-servicecatalog/lib/cloudformation-template.ts +++ b/packages/@aws-cdk/aws-servicecatalog/lib/cloudformation-template.ts @@ -1,5 +1,6 @@ import * as s3_assets from '@aws-cdk/aws-s3-assets'; import { hashValues } from './private/util'; +import { ProductStack } from './product-stack'; // 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 @@ -26,6 +27,13 @@ export abstract class CloudFormationTemplate { return new CloudFormationAssetTemplate(path, options); } + /** + * Creates a product with the resources defined in the given product stack. + */ + public static fromProductStack(productStack: ProductStack): CloudFormationTemplate { + return new CloudFormationProductStackTemplate(productStack); + } + /** * Called when the product is initialized to allow this object to bind * to the stack, add resources and have fun. @@ -88,3 +96,21 @@ class CloudFormationAssetTemplate extends CloudFormationTemplate { }; } } + +/** + * Template from a CDK defined product stack. + */ +class CloudFormationProductStackTemplate extends CloudFormationTemplate { + /** + * @param stack A service catalog product stack. + */ + constructor(public readonly productStack: ProductStack) { + super(); + } + + public bind(_scope: Construct): CloudFormationTemplateConfig { + return { + httpUrl: this.productStack._getTemplateUrl(), + }; + } +} diff --git a/packages/@aws-cdk/aws-servicecatalog/lib/index.ts b/packages/@aws-cdk/aws-servicecatalog/lib/index.ts index 8a7b0f0ff9ac6..cc26e880fdd2e 100644 --- a/packages/@aws-cdk/aws-servicecatalog/lib/index.ts +++ b/packages/@aws-cdk/aws-servicecatalog/lib/index.ts @@ -3,6 +3,7 @@ export * from './constraints'; export * from './cloudformation-template'; export * from './portfolio'; export * from './product'; +export * from './product-stack'; export * from './tag-options'; // AWS::ServiceCatalog CloudFormation Resources: diff --git a/packages/@aws-cdk/aws-servicecatalog/lib/private/product-stack-synthesizer.ts b/packages/@aws-cdk/aws-servicecatalog/lib/private/product-stack-synthesizer.ts new file mode 100644 index 0000000000000..4840a7e756fe5 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalog/lib/private/product-stack-synthesizer.ts @@ -0,0 +1,34 @@ +import * as cdk from '@aws-cdk/core'; + +/** + * Deployment environment for an AWS Service Catalog product stack. + * + * Interoperates with the StackSynthesizer of the parent stack. + */ +export class ProductStackSynthesizer extends cdk.StackSynthesizer { + private stack?: cdk.Stack; + + public bind(stack: cdk.Stack): void { + if (this.stack !== undefined) { + throw new Error('A Stack Synthesizer can only be bound once, create a new instance to use with a different Stack'); + } + this.stack = stack; + } + + public addFileAsset(_asset: cdk.FileAssetSource): cdk.FileAssetLocation { + throw new Error('Service Catalog Product Stacks cannot use Assets'); + } + + public addDockerImageAsset(_asset: cdk.DockerImageAssetSource): cdk.DockerImageAssetLocation { + throw new Error('Service Catalog Product Stacks cannot use Assets'); + } + + public synthesize(session: cdk.ISynthesisSession): void { + if (!this.stack) { + throw new Error('You must call bindStack() first'); + } + // Synthesize the template, but don't emit as a cloud assembly artifact. + // It will be registered as an S3 asset of its parent instead. + this.synthesizeStackTemplate(this.stack, session); + } +} diff --git a/packages/@aws-cdk/aws-servicecatalog/lib/product-stack.ts b/packages/@aws-cdk/aws-servicecatalog/lib/product-stack.ts new file mode 100644 index 0000000000000..b96224a8b2c60 --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalog/lib/product-stack.ts @@ -0,0 +1,77 @@ +import * as crypto from 'crypto'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as cdk from '@aws-cdk/core'; +import { ProductStackSynthesizer } from './private/product-stack-synthesizer'; + +// 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 +import { Construct } from 'constructs'; + +/** + * A Service Catalog product stack, which is similar in form to a Cloudformation nested stack. + * You can add the resources to this stack that you want to define for your service catalog product. + * + * This stack will not be treated as an independent deployment + * artifact (won't be listed in "cdk list" or deployable through "cdk deploy"), + * but rather only synthesized as a template and uploaded as an asset to S3. + * + */ +export class ProductStack extends cdk.Stack { + public readonly templateFile: string; + private _templateUrl?: string; + private _parentStack: cdk.Stack; + + constructor(scope: Construct, id: string) { + super(scope, id, { + synthesizer: new ProductStackSynthesizer(), + }); + + this._parentStack = findParentStack(scope); + + // this is the file name of the synthesized template file within the cloud assembly + this.templateFile = `${cdk.Names.uniqueId(this)}.product.template.json`; + } + + /** + * Fetch the template URL. + * + * @internal + */ + public _getTemplateUrl(): string { + return cdk.Lazy.uncachedString({ produce: () => this._templateUrl }); + } + + /** + * Synthesize the product stack template, overrides the `super` class method. + * + * Defines an asset at the parent stack which represents the template of this + * product stack. + * + * @internal + */ + public _synthesizeTemplate(session: cdk.ISynthesisSession): void { + const cfn = JSON.stringify(this._toCloudFormation(), undefined, 2); + const templateHash = crypto.createHash('sha256').update(cfn).digest('hex'); + + this._templateUrl = this._parentStack.synthesizer.addFileAsset({ + packaging: cdk.FileAssetPackaging.FILE, + sourceHash: templateHash, + fileName: this.templateFile, + }).httpUrl; + + fs.writeFileSync(path.join(session.assembly.outdir, this.templateFile), cfn); + } +} + +/** + * Validates the scope for a product stack, which must be defined within the scope of another `Stack`. + */ +function findParentStack(scope: Construct): cdk.Stack { + try { + const parentStack = cdk.Stack.of(scope); + return parentStack as cdk.Stack; + } catch (e) { + throw new Error('Product stacks must be defined within scope of another non-product stack'); + } +} diff --git a/packages/@aws-cdk/aws-servicecatalog/package.json b/packages/@aws-cdk/aws-servicecatalog/package.json index de3bfcfb667a5..3d96fbe55edcc 100644 --- a/packages/@aws-cdk/aws-servicecatalog/package.json +++ b/packages/@aws-cdk/aws-servicecatalog/package.json @@ -104,7 +104,8 @@ "resource-attribute:@aws-cdk/aws-servicecatalog.CloudFormationProduct.cloudFormationProductProvisioningArtifactNames", "props-physical-name:@aws-cdk/aws-servicecatalog.CloudFormationProductProps", "resource-attribute:@aws-cdk/aws-servicecatalog.Portfolio.portfolioName", - "props-physical-name:@aws-cdk/aws-servicecatalog.PortfolioProps" + "props-physical-name:@aws-cdk/aws-servicecatalog.PortfolioProps", + "props-physical-name:@aws-cdk/aws-servicecatalog.ProductStack" ] }, "maturity": "experimental", diff --git a/packages/@aws-cdk/aws-servicecatalog/rosetta/basic-portfolio.ts-fixture b/packages/@aws-cdk/aws-servicecatalog/rosetta/basic-portfolio.ts-fixture index d8925e6645aa7..3029872ea1f0d 100644 --- a/packages/@aws-cdk/aws-servicecatalog/rosetta/basic-portfolio.ts-fixture +++ b/packages/@aws-cdk/aws-servicecatalog/rosetta/basic-portfolio.ts-fixture @@ -1,9 +1,9 @@ // Fixture with packages imported, but nothing else -import { Construct, Stack } from '@aws-cdk/core'; +import * as cdk from '@aws-cdk/core'; import * as servicecatalog from '@aws-cdk/aws-servicecatalog'; -class Fixture extends Stack { - constructor(scope: Construct, id: string) { +class Fixture extends cdk.Stack { + constructor(scope: cdk.Construct, id: string) { super(scope, id); const portfolio = new servicecatalog.Portfolio(this, "MyFirstPortfolio", { diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.expected.json b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.expected.json index 786fdcad0f8fc..f54d640e1d0ca 100644 --- a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.expected.json +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.expected.json @@ -113,6 +113,108 @@ ] } } + }, + { + "DisableTemplateValidation": false, + "Info": { + "LoadTemplateFromURL": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Ref": "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3BucketB4751C98" + }, + "/", + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3VersionKeyEB38C6F9" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3VersionKeyEB38C6F9" + } + ] + } + ] + } + ] + ] + } + } + }, + { + "DisableTemplateValidation": false, + "Info": { + "LoadTemplateFromURL": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Ref": "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3BucketB4751C98" + }, + "/", + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3VersionKeyEB38C6F9" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3VersionKeyEB38C6F9" + } + ] + } + ] + } + ] + ] + } + } } ] } @@ -142,6 +244,18 @@ "AssetParameters6412a5f4524c6b41d26fbeee226c68c2dad735393940a51008d77e6f8b1038f5ArtifactHashDC26AFAC": { "Type": "String", "Description": "Artifact hash for asset \"6412a5f4524c6b41d26fbeee226c68c2dad735393940a51008d77e6f8b1038f5\"" + }, + "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3BucketB4751C98": { + "Type": "String", + "Description": "S3 bucket for asset \"dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f\"" + }, + "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fS3VersionKeyEB38C6F9": { + "Type": "String", + "Description": "S3 key for asset version \"dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f\"" + }, + "AssetParametersdd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1fArtifactHash5C1F9228": { + "Type": "String", + "Description": "Artifact hash for asset \"dd2d087eeb6ede1d2a9166639ccbde7bd1b10eef9ba2b4cb3d9855faa4fe8c1f\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.ts b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.ts index 5c4192cc9b25c..7a88c98a466d1 100644 --- a/packages/@aws-cdk/aws-servicecatalog/test/integ.product.ts +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.product.ts @@ -1,10 +1,19 @@ import * as path from 'path'; +import * as sns from '@aws-cdk/aws-sns'; import * as cdk from '@aws-cdk/core'; import * as servicecatalog from '../lib'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'integ-servicecatalog-product'); +class TestProductStack extends servicecatalog.ProductStack { + constructor(scope: any, id: string) { + super(scope, id); + + new sns.Topic(this, 'TopicProduct'); + } +} + new servicecatalog.CloudFormationProduct(stack, 'TestProduct', { productName: 'testProduct', owner: 'testOwner', @@ -20,6 +29,12 @@ new servicecatalog.CloudFormationProduct(stack, 'TestProduct', { { cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromAsset(path.join(__dirname, 'product2.template.json')), }, + { + cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(new TestProductStack(stack, 'SNSTopicProduct1')), + }, + { + cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(new TestProductStack(stack, 'SNSTopicProduct2')), + }, ], }); diff --git a/packages/@aws-cdk/aws-servicecatalog/test/product-stack.test.ts b/packages/@aws-cdk/aws-servicecatalog/test/product-stack.test.ts new file mode 100644 index 0000000000000..e024421d724dc --- /dev/null +++ b/packages/@aws-cdk/aws-servicecatalog/test/product-stack.test.ts @@ -0,0 +1,88 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import * as s3_assets from '@aws-cdk/aws-s3-assets'; +import * as sns from '@aws-cdk/aws-sns'; +import * as cdk from '@aws-cdk/core'; +import * as servicecatalog from '../lib'; + +/* eslint-disable quote-props */ +describe('ProductStack', () => { + test('fails to add asset to a product stack', () => { + // GIVEN + const app = new cdk.App(); + const mainStack = new cdk.Stack(app, 'MyStack'); + const productStack = new servicecatalog.ProductStack(mainStack, 'MyProductStack'); + + // THEN + expect(() => { + new s3_assets.Asset(productStack, 'testAsset', { + path: path.join(__dirname, 'product1.template.json'), + }); + }).toThrow(/Service Catalog Product Stacks cannot use Assets/); + }), + + test('fails if defined at root', () => { + // GIVEN + const app = new cdk.App(); + + // THEN + expect(() => { + new servicecatalog.ProductStack(app, 'ProductStack'); + }).toThrow(/must be defined within scope of another non-product stack/); + }), + + test('fails if defined without a parent stack', () => { + // GIVEN + const app = new cdk.App(); + const group = new cdk.Construct(app, 'group'); + + // THEN + expect(() => { + new servicecatalog.ProductStack(group, 'ProductStack'); + }).toThrow(/must be defined within scope of another non-product stack/); + }), + + test('can be defined as a direct child or an indirect child of a Stack', () => { + // GIVEN + const parent = new cdk.Stack(); + + // THEN + expect(() => { + new servicecatalog.ProductStack(parent, 'direct'); + }).not.toThrow(); + }); + + test('product stack is not synthesized as a stack artifact into the assembly', () => { + // GIVEN + const app = new cdk.App(); + const parentStack = new cdk.Stack(app, 'ParentStack'); + new servicecatalog.ProductStack(parentStack, 'ProductStack'); + + // WHEN + const assembly = app.synth(); + + // THEN + expect(assembly.artifacts.length).toEqual(2); + }); + + test('the template of the product stack is synthesized into the cloud assembly', () => { + // GIVEN + const app = new cdk.App(); + const parent = new cdk.Stack(app, 'ParentStack'); + const productStack = new servicecatalog.ProductStack(parent, 'ProductStack'); + new sns.Topic(productStack, 'SNSTopicProduct'); + + // WHEN + const assembly = app.synth(); + + // THEN + const template = JSON.parse(fs.readFileSync(path.join(assembly.directory, productStack.templateFile), 'utf-8')); + expect(template).toEqual({ + Resources: { + SNSTopicProduct20605D98: { + Type: 'AWS::SNS::Topic', + }, + }, + }); + }); +}); diff --git a/packages/@aws-cdk/aws-servicecatalog/test/product.test.ts b/packages/@aws-cdk/aws-servicecatalog/test/product.test.ts index f3e485b30e951..f399a79dcdb83 100644 --- a/packages/@aws-cdk/aws-servicecatalog/test/product.test.ts +++ b/packages/@aws-cdk/aws-servicecatalog/test/product.test.ts @@ -1,5 +1,6 @@ import * as path from 'path'; import { Match, Template } from '@aws-cdk/assertions'; +import * as sns from '@aws-cdk/aws-sns'; import * as cdk from '@aws-cdk/core'; import * as servicecatalog from '../lib'; @@ -101,6 +102,93 @@ describe('Product', () => { expect(synthesized.assets.length).toEqual(2); }), + test('product test from product stack', () => { + const productStack = new servicecatalog.ProductStack(stack, 'ProductStack'); + + new sns.Topic(productStack, 'SNSTopicProductStack'); + + new servicecatalog.CloudFormationProduct(stack, 'MyProduct', { + productName: 'testProduct', + owner: 'testOwner', + productVersions: [ + { + productVersionName: 'v1', + cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(productStack), + }, + ], + }); + + const assembly = app.synth(); + expect(assembly.artifacts.length).toEqual(2); + expect(assembly.stacks[0].assets.length).toBe(1); + expect(assembly.stacks[0].assets[0].path).toEqual('ProductStack.product.template.json'); + }), + + test('multiple product versions from product stack', () => { + const productStackVersion1 = new servicecatalog.ProductStack(stack, 'ProductStackV1'); + const productStackVersion2 = new servicecatalog.ProductStack(stack, 'ProductStackV2'); + + new sns.Topic(productStackVersion1, 'SNSTopicProductStack1'); + + new sns.Topic(productStackVersion2, 'SNSTopicProductStack2', { + displayName: 'a test', + }); + + new servicecatalog.CloudFormationProduct(stack, 'MyProduct', { + productName: 'testProduct', + owner: 'testOwner', + productVersions: [ + { + productVersionName: 'v1', + cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(productStackVersion1), + }, + { + productVersionName: 'v2', + cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(productStackVersion2), + }, + ], + }); + + const assembly = app.synth(); + + expect(assembly.stacks[0].assets.length).toBe(2); + expect(assembly.stacks[0].assets[0].path).toEqual('ProductStackV1.product.template.json'); + expect(assembly.stacks[0].assets[1].path).toEqual('ProductStackV2.product.template.json'); + }), + + test('identical product versions from product stack creates one asset', () => { + class TestProductStack extends servicecatalog.ProductStack { + constructor(scope: any, id: string) { + super(scope, id); + + new sns.Topic(this, 'TopicProduct'); + } + } + + new servicecatalog.CloudFormationProduct(stack, 'MyProduct', { + productName: 'testProduct', + owner: 'testOwner', + productVersions: [ + { + productVersionName: 'v1', + cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(new TestProductStack(stack, 'v1')), + }, + { + productVersionName: 'v2', + cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(new TestProductStack(stack, 'v2')), + }, + { + productVersionName: 'v3', + cloudFormationTemplate: servicecatalog.CloudFormationTemplate.fromProductStack(new TestProductStack(stack, 'v3')), + }, + ], + }); + + const assembly = app.synth(); + + expect(assembly.stacks[0].assets.length).toBe(1); + }), + test('product test from multiple sources', () => { new servicecatalog.CloudFormationProduct(stack, 'MyProduct', { productName: 'testProduct', From 1e2218941af13297b6ddaf02a1d8e07606ed3058 Mon Sep 17 00:00:00 2001 From: Adam Ruka Date: Tue, 2 Nov 2021 12:24:16 -0700 Subject: [PATCH 15/70] chore: add the new aws-iot-actions module to the assignment GitHub Action (#17259) We've created a new module in https://github.com/aws/aws-cdk/pull/17112, so now we need to add it to our assignment GitHub Action. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .github/workflows/issue-label-assign.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/issue-label-assign.yml b/.github/workflows/issue-label-assign.yml index 3309598c4e5e3..4cc8f06bbbf5e 100644 --- a/.github/workflows/issue-label-assign.yml +++ b/.github/workflows/issue-label-assign.yml @@ -126,6 +126,7 @@ jobs: {"area":"@aws-cdk/aws-imagebuilder","keywords":["aws-imagebuilder","imagebuilder"],"labels":["@aws-cdk/aws-imagebuilder"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-inspector","keywords":["aws-inspector","inspector"],"labels":["@aws-cdk/aws-inspector"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-iot","keywords":["internet-of-things","aws-iot","iot"],"labels":["@aws-cdk/aws-iot"],"assignees":["skinny85"]}, + {"area":"@aws-cdk/aws-iot-actions","keywords":["aws-iot-actions","iot-actions",],"labels":["@aws-cdk/aws-iot-actions"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-iot1click","keywords":["aws-iot1click","iot1click"],"labels":["@aws-cdk/aws-iot1click"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-iotanalytics","keywords":["aws-iotanalytics","iotanalytics"],"labels":["@aws-cdk/aws-iotanalytics"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-iotevents","keywords":["aws-iotevents","iotevents"],"labels":["@aws-cdk/aws-iotevents"],"assignees":["skinny85"]}, From a7c869e6d57932389df572cd7f104a4c9ea8f8a5 Mon Sep 17 00:00:00 2001 From: Tatsuya Yamamoto Date: Wed, 3 Nov 2021 05:18:35 +0900 Subject: [PATCH 16/70] feat(iot-actions): Add the action to put CloudWatch Logs (#17228) I'm trying to implement aws-iot L2 Constructs. This PR is one of steps after following PR: - https://github.com/aws/aws-cdk/pull/16681#issuecomment-942233029 ---- *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-iot-actions/README.md | 18 ++ .../lib/cloudwatch-logs-action.ts | 49 +++++ .../@aws-cdk/aws-iot-actions/lib/index.ts | 1 + .../aws-iot-actions/lib/private/role.ts | 27 +++ .../@aws-cdk/aws-iot-actions/package.json | 2 + .../cloudwatch-logs-action.test.ts | 199 ++++++++++++++++++ ...integ.cloudwatch-logs-action.expected.json | 92 ++++++++ .../integ.cloudwatch-logs-action.ts | 25 +++ 8 files changed, 413 insertions(+) create mode 100644 packages/@aws-cdk/aws-iot-actions/lib/cloudwatch-logs-action.ts create mode 100644 packages/@aws-cdk/aws-iot-actions/lib/private/role.ts create mode 100644 packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/cloudwatch-logs-action.test.ts create mode 100644 packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.expected.json create mode 100644 packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.ts diff --git a/packages/@aws-cdk/aws-iot-actions/README.md b/packages/@aws-cdk/aws-iot-actions/README.md index 67d9b2924dd53..b18182a80a9ad 100644 --- a/packages/@aws-cdk/aws-iot-actions/README.md +++ b/packages/@aws-cdk/aws-iot-actions/README.md @@ -48,3 +48,21 @@ new iot.TopicRule(this, 'TopicRule', { actions: [new actions.LambdaFunctionAction(func)], }); ``` + +## Put logs to CloudWatch Logs + +The code snippet below creates an AWS IoT Rule that put logs to CloudWatch Logs +when it is triggered. + +```ts +import * as iot from '@aws-cdk/aws-iot'; +import * as actions from '@aws-cdk/aws-iot-actions'; +import * as logs from '@aws-cdk/aws-logs'; + +const logGroup = new logs.LogGroup(this, 'MyLogGroup'); + +new iot.TopicRule(this, 'TopicRule', { + sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id FROM 'device/+/data'"), + actions: [new actions.CloudWatchLogsAction(logGroup)], +}); +``` diff --git a/packages/@aws-cdk/aws-iot-actions/lib/cloudwatch-logs-action.ts b/packages/@aws-cdk/aws-iot-actions/lib/cloudwatch-logs-action.ts new file mode 100644 index 0000000000000..dda14de887774 --- /dev/null +++ b/packages/@aws-cdk/aws-iot-actions/lib/cloudwatch-logs-action.ts @@ -0,0 +1,49 @@ +import * as iam from '@aws-cdk/aws-iam'; +import * as iot from '@aws-cdk/aws-iot'; +import * as logs from '@aws-cdk/aws-logs'; +import { singletonActionRole } from './private/role'; + +/** + * Configuration properties of an action for CloudWatch Logs. + */ +export interface CloudWatchLogsActionProps { + /** + * The IAM role that allows access to the CloudWatch log group. + * + * @default a new role will be created + */ + readonly role?: iam.IRole; +} + +/** + * The action to send data to Amazon CloudWatch Logs + */ +export class CloudWatchLogsAction implements iot.IAction { + private readonly role?: iam.IRole; + + /** + * @param logGroup The CloudWatch log group to which the action sends data + * @param props Optional properties to not use default + */ + constructor( + private readonly logGroup: logs.ILogGroup, + props: CloudWatchLogsActionProps = {}, + ) { + this.role = props.role; + } + + bind(rule: iot.ITopicRule): iot.ActionConfig { + const role = this.role ?? singletonActionRole(rule); + this.logGroup.grantWrite(role); + this.logGroup.grant(role, 'logs:DescribeLogStreams'); + + return { + configuration: { + cloudwatchLogs: { + logGroupName: this.logGroup.logGroupName, + roleArn: role.roleArn, + }, + }, + }; + } +} diff --git a/packages/@aws-cdk/aws-iot-actions/lib/index.ts b/packages/@aws-cdk/aws-iot-actions/lib/index.ts index 751863744ffe2..ef917fd0e2181 100644 --- a/packages/@aws-cdk/aws-iot-actions/lib/index.ts +++ b/packages/@aws-cdk/aws-iot-actions/lib/index.ts @@ -1 +1,2 @@ +export * from './cloudwatch-logs-action'; export * from './lambda-function-action'; diff --git a/packages/@aws-cdk/aws-iot-actions/lib/private/role.ts b/packages/@aws-cdk/aws-iot-actions/lib/private/role.ts new file mode 100644 index 0000000000000..78c72b914f56b --- /dev/null +++ b/packages/@aws-cdk/aws-iot-actions/lib/private/role.ts @@ -0,0 +1,27 @@ +import * as iam from '@aws-cdk/aws-iam'; +import { IConstruct, PhysicalName } from '@aws-cdk/core'; + +// 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 +import { Construct } from '@aws-cdk/core'; + +/** + * Obtain the Role for the TopicRule + * + * If a role already exists, it will be returned. This ensures that if a rule have multiple + * actions, they will share a role. + * @internal + */ +export function singletonActionRole(scope: IConstruct): iam.IRole { + const id = 'TopicRuleActionRole'; + const existing = scope.node.tryFindChild(id) as iam.IRole; + if (existing) { + return existing; + }; + + const role = new iam.Role(scope as Construct, id, { + roleName: PhysicalName.GENERATE_IF_NEEDED, + assumedBy: new iam.ServicePrincipal('iot.amazonaws.com'), + }); + return role; +} diff --git a/packages/@aws-cdk/aws-iot-actions/package.json b/packages/@aws-cdk/aws-iot-actions/package.json index 3b66b73a1562e..d60ae4c5e1376 100644 --- a/packages/@aws-cdk/aws-iot-actions/package.json +++ b/packages/@aws-cdk/aws-iot-actions/package.json @@ -82,6 +82,7 @@ "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-iot": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", + "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/core": "0.0.0", "constructs": "^3.3.69" }, @@ -90,6 +91,7 @@ "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-iot": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", + "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/core": "0.0.0", "constructs": "^3.3.69" }, diff --git a/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/cloudwatch-logs-action.test.ts b/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/cloudwatch-logs-action.test.ts new file mode 100644 index 0000000000000..4e25f43367c31 --- /dev/null +++ b/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/cloudwatch-logs-action.test.ts @@ -0,0 +1,199 @@ +import { Template } from '@aws-cdk/assertions'; +import * as iam from '@aws-cdk/aws-iam'; +import * as iot from '@aws-cdk/aws-iot'; +import * as logs from '@aws-cdk/aws-logs'; +import * as cdk from '@aws-cdk/core'; +import * as actions from '../../lib'; + +test('Default cloudwatch logs action', () => { + // GIVEN + const stack = new cdk.Stack(); + const topicRule = new iot.TopicRule(stack, 'MyTopicRule', { + sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id FROM 'device/+/data'"), + }); + const logGroup = new logs.LogGroup(stack, 'MyLogGroup'); + + // WHEN + topicRule.addAction( + new actions.CloudWatchLogsAction(logGroup), + ); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', { + TopicRulePayload: { + Actions: [ + { + CloudwatchLogs: { + LogGroupName: { Ref: 'MyLogGroup5C0DAD85' }, + RoleArn: { + 'Fn::GetAtt': [ + 'MyTopicRuleTopicRuleActionRoleCE2D05DA', + 'Arn', + ], + }, + }, + }, + ], + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: 'iot.amazonaws.com', + }, + }, + ], + Version: '2012-10-17', + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: ['logs:CreateLogStream', 'logs:PutLogEvents'], + Effect: 'Allow', + Resource: { + 'Fn::GetAtt': ['MyLogGroup5C0DAD85', 'Arn'], + }, + }, + { + Action: 'logs:DescribeLogStreams', + Effect: 'Allow', + Resource: { + 'Fn::GetAtt': ['MyLogGroup5C0DAD85', 'Arn'], + }, + }, + ], + Version: '2012-10-17', + }, + PolicyName: 'MyTopicRuleTopicRuleActionRoleDefaultPolicy54A701F7', + Roles: [ + { Ref: 'MyTopicRuleTopicRuleActionRoleCE2D05DA' }, + ], + }); +}); + +test('can set role', () => { + // GIVEN + const stack = new cdk.Stack(); + const topicRule = new iot.TopicRule(stack, 'MyTopicRule', { + sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id FROM 'device/+/data'"), + }); + const logGroup = new logs.LogGroup(stack, 'MyLogGroup'); + const role = iam.Role.fromRoleArn(stack, 'MyRole', 'arn:aws:iam::123456789012:role/ForTest'); + + // WHEN + topicRule.addAction( + new actions.CloudWatchLogsAction(logGroup, { + role, + }), + ); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', { + TopicRulePayload: { + Actions: [ + { + CloudwatchLogs: { + LogGroupName: { Ref: 'MyLogGroup5C0DAD85' }, + RoleArn: 'arn:aws:iam::123456789012:role/ForTest', + }, + }, + ], + }, + }); +}); + +test('The specified role is added a policy needed for sending data to logs', () => { + // GIVEN + const stack = new cdk.Stack(); + const topicRule = new iot.TopicRule(stack, 'MyTopicRule', { + sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id FROM 'device/+/data'"), + }); + const logGroup = new logs.LogGroup(stack, 'MyLogGroup'); + const role = iam.Role.fromRoleArn(stack, 'MyRole', 'arn:aws:iam::123456789012:role/ForTest'); + + // WHEN + topicRule.addAction( + new actions.CloudWatchLogsAction(logGroup, { + role, + }), + ); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: ['logs:CreateLogStream', 'logs:PutLogEvents'], + Effect: 'Allow', + Resource: { + 'Fn::GetAtt': ['MyLogGroup5C0DAD85', 'Arn'], + }, + }, + { + Action: 'logs:DescribeLogStreams', + Effect: 'Allow', + Resource: { + 'Fn::GetAtt': ['MyLogGroup5C0DAD85', 'Arn'], + }, + }, + ], + Version: '2012-10-17', + }, + PolicyName: 'MyRolePolicy64AB00A5', + Roles: ['ForTest'], + }); +}); + + +test('When multiple actions are omitted role property, the actions use same one role', () => { + // GIVEN + // GIVEN + const stack = new cdk.Stack(); + const topicRule = new iot.TopicRule(stack, 'MyTopicRule', { + sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id FROM 'device/+/data'"), + }); + const logGroup1 = new logs.LogGroup(stack, 'MyLogGroup1'); + const logGroup2 = new logs.LogGroup(stack, 'MyLogGroup2'); + + // WHEN + topicRule.addAction(new actions.CloudWatchLogsAction(logGroup1)); + topicRule.addAction(new actions.CloudWatchLogsAction(logGroup2)); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', { + TopicRulePayload: { + Actions: [ + { + CloudwatchLogs: { + LogGroupName: { Ref: 'MyLogGroup14A6E382A' }, + RoleArn: { + 'Fn::GetAtt': [ + 'MyTopicRuleTopicRuleActionRoleCE2D05DA', + 'Arn', + ], + }, + }, + }, + { + CloudwatchLogs: { + LogGroupName: { Ref: 'MyLogGroup279D6359D' }, + RoleArn: { + 'Fn::GetAtt': [ + 'MyTopicRuleTopicRuleActionRoleCE2D05DA', + 'Arn', + ], + }, + }, + }, + ], + }, + }); +}); diff --git a/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.expected.json b/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.expected.json new file mode 100644 index 0000000000000..7d1748a084c77 --- /dev/null +++ b/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.expected.json @@ -0,0 +1,92 @@ +{ + "Resources": { + "TopicRule40A4EA44": { + "Type": "AWS::IoT::TopicRule", + "Properties": { + "TopicRulePayload": { + "Actions": [ + { + "CloudwatchLogs": { + "LogGroupName": { + "Ref": "MyLogGroup5C0DAD85" + }, + "RoleArn": { + "Fn::GetAtt": [ + "TopicRuleTopicRuleActionRole246C4F77", + "Arn" + ] + } + } + } + ], + "AwsIotSqlVersion": "2016-03-23", + "Sql": "SELECT topic(2) as device_id FROM 'device/+/data'" + } + } + }, + "TopicRuleTopicRuleActionRole246C4F77": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "iot.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "TopicRuleTopicRuleActionRoleDefaultPolicy99ADD687": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyLogGroup5C0DAD85", + "Arn" + ] + } + }, + { + "Action": "logs:DescribeLogStreams", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyLogGroup5C0DAD85", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "TopicRuleTopicRuleActionRoleDefaultPolicy99ADD687", + "Roles": [ + { + "Ref": "TopicRuleTopicRuleActionRole246C4F77" + } + ] + } + }, + "MyLogGroup5C0DAD85": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "RetentionInDays": 731 + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.ts b/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.ts new file mode 100644 index 0000000000000..802f485b77e37 --- /dev/null +++ b/packages/@aws-cdk/aws-iot-actions/test/cloudwatch-logs/integ.cloudwatch-logs-action.ts @@ -0,0 +1,25 @@ +/// !cdk-integ pragma:ignore-assets +import * as iot from '@aws-cdk/aws-iot'; +import * as logs from '@aws-cdk/aws-logs'; +import * as cdk from '@aws-cdk/core'; +import * as actions from '../../lib'; + +const app = new cdk.App(); + +class TestStack extends cdk.Stack { + constructor(scope: cdk.App, id: string, props?: cdk.StackProps) { + super(scope, id, props); + + const topicRule = new iot.TopicRule(this, 'TopicRule', { + sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id FROM 'device/+/data'"), + }); + + const logGroup = new logs.LogGroup(this, 'MyLogGroup', { + removalPolicy: cdk.RemovalPolicy.DESTROY, + }); + topicRule.addAction(new actions.CloudWatchLogsAction(logGroup)); + } +} + +new TestStack(app, 'test-stack'); +app.synth(); From ca9320bbc22934a0f708364a6426f3977ea67f5a Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Tue, 2 Nov 2021 22:14:18 +0100 Subject: [PATCH 17/70] chore: bootstrap stack too old for integ tests (#17277) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The integ tests try to be clever to save time, and rebootstrap an account and region pair only if the bootstrap stack does not exist yet. This is not good enough if the **version** of the bootstrap stack changes though (no rebootstrapping will happen), and the following error will occur: ``` ❌ cdktest-0n94n0po827f-test-2 failed: Error: cdktest-0n94n0po827f-test-2: This CDK deployment requires bootstrap stack version '6', found '4'. Please run 'cdk bootstrap'. ``` Instead, always bootstrap every account/region pair at least once per run. It will take some time, but in most cases we'll be able to short-circuit the CFN deployment, so it will take ~2s instead of ~20 per case. ---- *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/helpers/cdk.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/aws-cdk/test/integ/helpers/cdk.ts b/packages/aws-cdk/test/integ/helpers/cdk.ts index edf996ba36ed6..340aae771f275 100644 --- a/packages/aws-cdk/test/integ/helpers/cdk.ts +++ b/packages/aws-cdk/test/integ/helpers/cdk.ts @@ -541,11 +541,12 @@ let sanityChecked: boolean | undefined; * by hand so let's just mass-automate it. */ async function ensureBootstrapped(fixture: TestFixture) { - // Use the default name for the bootstrap stack - if (await fixture.aws.stackStatus('CDKToolkit') === undefined) { - // use whatever version of bootstrap is the default for this particular version of the CLI - await fixture.cdk(['bootstrap', `aws://${await fixture.aws.account()}/${fixture.aws.region}`]); - } + // use whatever version of bootstrap is the default for this particular version of the CLI + const envSpecifier = `aws://${await fixture.aws.account()}/${fixture.aws.region}`; + if (ALREADY_BOOTSTRAPPED_IN_THIS_RUN.has(envSpecifier)) { return; } + + await fixture.cdk(['bootstrap', envSpecifier]); + ALREADY_BOOTSTRAPPED_IN_THIS_RUN.add(envSpecifier); } /** @@ -689,3 +690,5 @@ const installNpm7 = memoize0(async (): Promise => { return path.join(installDir, 'node_modules', '.bin', 'npm'); }); + +const ALREADY_BOOTSTRAPPED_IN_THIS_RUN = new Set(); \ No newline at end of file From 30e96da2f185b8e1bc0dcdfeedf45c170d480165 Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Wed, 3 Nov 2021 02:05:09 +0200 Subject: [PATCH 18/70] chore: integ tests breaking on lambda node runtime (#17282) Looks like lambda stopped supporting node 10 for new functions: ```console The runtime parameter of nodejs10.x is no longer supported for creating or updating AWS Lambda functions. We recommend you use the new runtime (nodejs14.x) while creating or updating functions ``` Switch to 12. ---- *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/cli/app/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk/test/integ/cli/app/app.js b/packages/aws-cdk/test/integ/cli/app/app.js index 450662ac268e0..f0e332eb351fa 100644 --- a/packages/aws-cdk/test/integ/cli/app/app.js +++ b/packages/aws-cdk/test/integ/cli/app/app.js @@ -195,7 +195,7 @@ class LambdaStack extends cdk.Stack { const fn = new lambda.Function(this, 'my-function', { code: lambda.Code.asset(path.join(__dirname, 'lambda')), - runtime: lambda.Runtime.NODEJS_10_X, + runtime: lambda.Runtime.NODEJS_12_X, handler: 'index.handler' }); From 02d53725fa4b7675d65bf8946379033a9cf8df59 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Wed, 3 Nov 2021 10:42:24 +0100 Subject: [PATCH 19/70] chore(cli): integ tests install matching framework version (#17276) If the regression tests are running in straight up integ test mode, and not regression mode, they don't run with a `FRAMEWORK_VERSION` set. The end result is that they install the version `*` of every library, which always resolves to the v1 version. If we're running in straight-up integ test mode, copy the framework version from the CLI. ---- *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-dist | 5 +++++ packages/aws-cdk/test/integ/run-against-release | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/packages/aws-cdk/test/integ/run-against-dist b/packages/aws-cdk/test/integ/run-against-dist index ed17ddee88243..0cd683b112dca 100755 --- a/packages/aws-cdk/test/integ/run-against-dist +++ b/packages/aws-cdk/test/integ/run-against-dist @@ -24,6 +24,11 @@ if [[ ! -f $dist_root/build.json ]]; then fi export CANDIDATE_VERSION=$(node -p "require('${dist_root}/build.json').version") + +# FRAMEWORK_VERSION is the version that will be 'npm install'ed by the tests +if [[ "${FRAMEWORK_VERSION}" = "" ]]; then + export FRAMEWORK_VERSION=${CANDIDATE_VERSION} +fi export TEST_RUNNER=dist serve_npm_packages diff --git a/packages/aws-cdk/test/integ/run-against-release b/packages/aws-cdk/test/integ/run-against-release index 0865bd331a25d..b3ebe1e4fc409 100755 --- a/packages/aws-cdk/test/integ/run-against-release +++ b/packages/aws-cdk/test/integ/run-against-release @@ -13,6 +13,13 @@ mkdir -p $npmws # Install the CLI and put it on the PATH (cd $npmws && npm install aws-cdk) + +# FRAMEWORK_VERSION is the version that will be 'npm install'ed by the tests +if [[ "${FRAMEWORK_VERSION}" = "" ]]; then + cli_version=$(cd $npmws && node -p "require('aws-cdk/package.json').version") + export FRAMEWORK_VERSION=${cli_version} +fi + export PATH=$npmws/node_modules/.bin:$PATH export TEST_RUNNER=release From 58090a0608a244fa0204974ee659d5c793e85dcc Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Wed, 3 Nov 2021 13:09:33 +0200 Subject: [PATCH 20/70] chore: regression suite patch for lambda runtime deprecation (#17297) Follow up on https://github.com/aws/aws-cdk/pull/17282 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../cli-regression-patches/v1.130.0/NOTES.md | 4 + .../v1.130.0/app/app.js | 378 ++++++++++++++++++ 2 files changed, 382 insertions(+) create mode 100644 packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md create mode 100644 packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/app/app.js diff --git a/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md new file mode 100644 index 0000000000000..9a9338f4d04fb --- /dev/null +++ b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md @@ -0,0 +1,4 @@ +On november 2nd 2021, lambda started deprecating the nodejs10.x runtime. This meant we can no longer create functions with this runtime. +Our integration tests use this runtime for one of its stacks. + +This patch brings https://github.com/aws/aws-cdk/pull/17282 into the regression suite. \ No newline at end of file diff --git a/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/app/app.js b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/app/app.js new file mode 100644 index 0000000000000..f0e332eb351fa --- /dev/null +++ b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/app/app.js @@ -0,0 +1,378 @@ +const path = require('path'); + +var constructs = require('constructs'); +if (process.env.PACKAGE_LAYOUT_VERSION === '1') { + var cdk = require('@aws-cdk/core'); + var ec2 = require('@aws-cdk/aws-ec2'); + var ssm = require('@aws-cdk/aws-ssm'); + var iam = require('@aws-cdk/aws-iam'); + var sns = require('@aws-cdk/aws-sns'); + var lambda = require('@aws-cdk/aws-lambda'); + var docker = require('@aws-cdk/aws-ecr-assets'); +} else { + var cdk = require('aws-cdk-lib'); + var { + aws_ec2: ec2, + aws_ssm: ssm, + aws_iam: iam, + aws_sns: sns, + aws_lambda: lambda, + aws_ecr_assets: docker + } = require('aws-cdk-lib'); +} + +const { Annotations } = cdk; +const { StackWithNestedStack, StackWithNestedStackUsingParameters } = require('./nested-stack'); + +const stackPrefix = process.env.STACK_NAME_PREFIX; +if (!stackPrefix) { + throw new Error(`the STACK_NAME_PREFIX environment variable is required`); +} + +class MyStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + new sns.Topic(this, 'topic'); + + if (cdk.AvailabilityZoneProvider) { // <= 0.34.0 + new cdk.AvailabilityZoneProvider(this).availabilityZones; + } else if (cdk.Context) { // <= 0.35.0 + cdk.Context.getAvailabilityZones(this); + } else { + this.availabilityZones; + } + + const parameterName = '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'; + getSsmParameterValue(this, parameterName); + } +} + +function getSsmParameterValue(scope, parameterName) { + return ssm.StringParameter.valueFromLookup(scope, parameterName); +} + +class YourStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + new sns.Topic(this, 'topic1'); + new sns.Topic(this, 'topic2'); + } +} + +class StackUsingContext extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + new cdk.CfnResource(this, 'Handle', { + type: 'AWS::CloudFormation::WaitConditionHandle' + }); + + new cdk.CfnOutput(this, 'Output', { + value: this.availabilityZones, + }); + } +} + +class ParameterStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + new sns.Topic(this, 'TopicParameter', { + topicName: new cdk.CfnParameter(this, 'TopicNameParam').valueAsString + }); + } +} + +class OtherParameterStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + new sns.Topic(this, 'TopicParameter', { + topicName: new cdk.CfnParameter(this, 'OtherTopicNameParam').valueAsString + }); + } +} + +class MultiParameterStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + new sns.Topic(this, 'TopicParameter', { + displayName: new cdk.CfnParameter(this, 'DisplayNameParam').valueAsString + }); + new sns.Topic(this, 'OtherTopicParameter', { + displayName: new cdk.CfnParameter(this, 'OtherDisplayNameParam').valueAsString + }); + } +} + +class OutputsStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + const topic = new sns.Topic(this, 'MyOutput', { + topicName: `${cdk.Stack.of(this).stackName}MyTopic` + }); + + new cdk.CfnOutput(this, 'TopicName', { + value: topic.topicName + }) + } +} + +class AnotherOutputsStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + const topic = new sns.Topic(this, 'MyOtherOutput', { + topicName: `${cdk.Stack.of(this).stackName}MyOtherTopic` + }); + + new cdk.CfnOutput(this, 'TopicName', { + value: topic.topicName + }); + } +} + +class IamStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + new iam.Role(this, 'SomeRole', { + assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com') + }); + } +} + +class ProvidingStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + this.topic = new sns.Topic(this, 'BogusTopic'); // Some filler + } +} + +class StackWithError extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + this.topic = new sns.Topic(this, 'BogusTopic'); // Some filler + Annotations.of(this).addError('This is an error'); + } +} + +class StageWithError extends cdk.Stage { + constructor(parent, id, props) { + super(parent, id, props); + + new StackWithError(this, 'Stack'); + } +} + +class ConsumingStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + new sns.Topic(this, 'BogusTopic'); // Some filler + new cdk.CfnOutput(this, 'IConsumedSomething', { value: props.providingStack.topic.topicArn }); + } +} + +class MissingSSMParameterStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + const parameterName = constructs.Node.of(this).tryGetContext('test:ssm-parameter-name'); + if (parameterName) { + const param = getSsmParameterValue(this, parameterName); + new iam.Role(this, 'PhonyRole', { assumedBy: new iam.AccountPrincipal(param) }); + } + } +} + +class LambdaStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + const fn = new lambda.Function(this, 'my-function', { + code: lambda.Code.asset(path.join(__dirname, 'lambda')), + runtime: lambda.Runtime.NODEJS_12_X, + handler: 'index.handler' + }); + + new cdk.CfnOutput(this, 'FunctionArn', { value: fn.functionArn }); + } +} + +class DockerStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + new docker.DockerImageAsset(this, 'image', { + directory: path.join(__dirname, 'docker') + }); + + // Add at least a single resource (WaitConditionHandle), otherwise this stack will never + // be deployed (and its assets never built) + new cdk.CfnResource(this, 'Handle', { + type: 'AWS::CloudFormation::WaitConditionHandle' + }); + } +} + +class DockerStackWithCustomFile extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + new docker.DockerImageAsset(this, 'image', { + directory: path.join(__dirname, 'docker'), + file: 'Dockerfile.Custom' + }); + + // Add at least a single resource (WaitConditionHandle), otherwise this stack will never + // be deployed (and its assets never built) + new cdk.CfnResource(this, 'Handle', { + type: 'AWS::CloudFormation::WaitConditionHandle' + }); + } +} + +class FailedStack extends cdk.Stack { + + constructor(parent, id, props) { + super(parent, id, props); + + // fails on 'Property PolicyDocument cannot be empty'. + new cdk.CfnResource(this, 'EmptyPolicy', { + type: 'AWS::IAM::Policy' + }) + + } + +} + +const VPC_TAG_NAME = 'custom-tag'; +const VPC_TAG_VALUE = `${stackPrefix}-bazinga!`; + +class DefineVpcStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + const vpc = new ec2.Vpc(this, 'VPC', { + maxAzs: 1, + }) + cdk.Aspects.of(vpc).add(new cdk.Tag(VPC_TAG_NAME, VPC_TAG_VALUE)); + } +} + +class ImportVpcStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + ec2.Vpc.fromLookup(this, 'DefaultVPC', { isDefault: true }); + ec2.Vpc.fromLookup(this, 'ByTag', { tags: { [VPC_TAG_NAME]: VPC_TAG_VALUE } }); + } +} + +class ConditionalResourceStack extends cdk.Stack { + constructor(parent, id, props) { + super(parent, id, props); + + if (!process.env.NO_RESOURCE) { + new iam.User(this, 'User'); + } + } +} + +class SomeStage extends cdk.Stage { + constructor(parent, id, props) { + super(parent, id, props); + + new YourStack(this, 'StackInStage'); + } +} + +class StageUsingContext extends cdk.Stage { + constructor(parent, id, props) { + super(parent, id, props); + + new StackUsingContext(this, 'StackInStage'); + } +} + +const app = new cdk.App(); + +const defaultEnv = { + account: process.env.CDK_DEFAULT_ACCOUNT, + region: process.env.CDK_DEFAULT_REGION +}; + +// Sometimes we don't want to synthesize all stacks because it will impact the results +const stackSet = process.env.INTEG_STACK_SET || 'default'; + +switch (stackSet) { + case 'default': + // Deploy all does a wildcard ${stackPrefix}-test-* + new MyStack(app, `${stackPrefix}-test-1`, { env: defaultEnv }); + new YourStack(app, `${stackPrefix}-test-2`); + // Deploy wildcard with parameters does ${stackPrefix}-param-test-* + new ParameterStack(app, `${stackPrefix}-param-test-1`); + new OtherParameterStack(app, `${stackPrefix}-param-test-2`); + // Deploy stack with multiple parameters + new MultiParameterStack(app, `${stackPrefix}-param-test-3`); + // Deploy stack with outputs does ${stackPrefix}-outputs-test-* + new OutputsStack(app, `${stackPrefix}-outputs-test-1`); + new AnotherOutputsStack(app, `${stackPrefix}-outputs-test-2`); + // Not included in wildcard + new IamStack(app, `${stackPrefix}-iam-test`, { env: defaultEnv }); + const providing = new ProvidingStack(app, `${stackPrefix}-order-providing`); + new ConsumingStack(app, `${stackPrefix}-order-consuming`, { providingStack: providing }); + + new MissingSSMParameterStack(app, `${stackPrefix}-missing-ssm-parameter`, { env: defaultEnv }); + + new LambdaStack(app, `${stackPrefix}-lambda`); + new DockerStack(app, `${stackPrefix}-docker`); + new DockerStackWithCustomFile(app, `${stackPrefix}-docker-with-custom-file`); + new FailedStack(app, `${stackPrefix}-failed`) + + if (process.env.ENABLE_VPC_TESTING) { // Gating so we don't do context fetching unless that's what we are here for + const env = { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION }; + if (process.env.ENABLE_VPC_TESTING === 'DEFINE') + new DefineVpcStack(app, `${stackPrefix}-define-vpc`, { env }); + if (process.env.ENABLE_VPC_TESTING === 'IMPORT') + new ImportVpcStack(app, `${stackPrefix}-import-vpc`, { env }); + } + + new ConditionalResourceStack(app, `${stackPrefix}-conditional-resource`) + + new StackWithNestedStack(app, `${stackPrefix}-with-nested-stack`); + new StackWithNestedStackUsingParameters(app, `${stackPrefix}-with-nested-stack-using-parameters`); + + new YourStack(app, `${stackPrefix}-termination-protection`, { + terminationProtection: process.env.TERMINATION_PROTECTION !== 'FALSE' ? true : false, + }); + + new SomeStage(app, `${stackPrefix}-stage`); + break; + + case 'stage-using-context': + // Cannot be combined with other test stacks, because we use this to test + // that stage context is propagated up and causes synth to fail when combined + // with '--no-lookups'. + + // Needs a dummy stack at the top level because the CLI will fail otherwise + new YourStack(app, `${stackPrefix}-toplevel`, { env: defaultEnv }); + new StageUsingContext(app, `${stackPrefix}-stage-using-context`, { + env: defaultEnv, + }); + break; + + case 'stage-with-errors': + const stage = new StageWithError(app, `${stackPrefix}-stage-with-errors`); + stage.synth({ validateOnSynthesis: true }); + break; + + default: + throw new Error(`Unrecognized INTEG_STACK_SET: '${stackSet}'`); +} + +app.synth(); From b98c42eba121c63ea53434326e52954ab3a9d64a Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Wed, 3 Nov 2021 13:04:24 +0100 Subject: [PATCH 21/70] chore: integ test trying to downgrade bootstrap stack (#17298) This is a follow-up to #17277: we switched to *always* bootstrapping the environment using the default settings, to automatically upgrade whenever an upgrade was available. However, if we run the integ test using a v1 CLI, the default bootstrap stack will be the legacy bootstrap, and we would actually be trying to *downgrade* it. Instead, always use the modern bootstrap stack. Since legacy apps can be deployed to the modern bootstrap stack, this is not an issue, and if a test actually needs the legacy stack to test something, it will explicitly try to create a fresh legacy bootstrap stack. ---- *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/helpers/cdk.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk/test/integ/helpers/cdk.ts b/packages/aws-cdk/test/integ/helpers/cdk.ts index 340aae771f275..12e60efe243f7 100644 --- a/packages/aws-cdk/test/integ/helpers/cdk.ts +++ b/packages/aws-cdk/test/integ/helpers/cdk.ts @@ -541,11 +541,21 @@ let sanityChecked: boolean | undefined; * by hand so let's just mass-automate it. */ async function ensureBootstrapped(fixture: TestFixture) { - // use whatever version of bootstrap is the default for this particular version of the CLI + // Always use the modern bootstrap stack, otherwise we may get the error + // "refusing to downgrade from version 7 to version 0" when bootstrapping with default + // settings using a v1 CLI. + // + // It doesn't matter for tests: when they want to test something about an actual legacy + // bootstrap stack, they'll create a bootstrap stack with a non-default name to test that exact property. const envSpecifier = `aws://${await fixture.aws.account()}/${fixture.aws.region}`; if (ALREADY_BOOTSTRAPPED_IN_THIS_RUN.has(envSpecifier)) { return; } - await fixture.cdk(['bootstrap', envSpecifier]); + await fixture.cdk(['bootstrap', envSpecifier], { + modEnv: { + // Even for v1, use new bootstrap + CDK_NEW_BOOTSTRAP: '1', + }, + }); ALREADY_BOOTSTRAPPED_IN_THIS_RUN.add(envSpecifier); } From 0a6499d056d8eb14a5aca0a33c43cfee2aa862b2 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Wed, 3 Nov 2021 13:58:22 +0100 Subject: [PATCH 22/70] chore: fix invalid JSON in assignment JSON (#17299) The JSON is currently breaking GitHub actions. ![image](https://user-images.githubusercontent.com/524162/140036931-deccb6eb-9acb-4286-886b-4aabf63aecdb.png) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .github/workflows/issue-label-assign.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/issue-label-assign.yml b/.github/workflows/issue-label-assign.yml index 4cc8f06bbbf5e..17b33b8455c95 100644 --- a/.github/workflows/issue-label-assign.yml +++ b/.github/workflows/issue-label-assign.yml @@ -126,7 +126,7 @@ jobs: {"area":"@aws-cdk/aws-imagebuilder","keywords":["aws-imagebuilder","imagebuilder"],"labels":["@aws-cdk/aws-imagebuilder"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-inspector","keywords":["aws-inspector","inspector"],"labels":["@aws-cdk/aws-inspector"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-iot","keywords":["internet-of-things","aws-iot","iot"],"labels":["@aws-cdk/aws-iot"],"assignees":["skinny85"]}, - {"area":"@aws-cdk/aws-iot-actions","keywords":["aws-iot-actions","iot-actions",],"labels":["@aws-cdk/aws-iot-actions"],"assignees":["skinny85"]}, + {"area":"@aws-cdk/aws-iot-actions","keywords":["aws-iot-actions","iot-actions"],"labels":["@aws-cdk/aws-iot-actions"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-iot1click","keywords":["aws-iot1click","iot1click"],"labels":["@aws-cdk/aws-iot1click"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-iotanalytics","keywords":["aws-iotanalytics","iotanalytics"],"labels":["@aws-cdk/aws-iotanalytics"],"assignees":["skinny85"]}, {"area":"@aws-cdk/aws-iotevents","keywords":["aws-iotevents","iotevents"],"labels":["@aws-cdk/aws-iotevents"],"assignees":["skinny85"]}, From b240201de40055049ff02be7d0b865bd51b9fcad Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Wed, 3 Nov 2021 19:23:20 +0530 Subject: [PATCH 23/70] chore: npm-check-updates && yarn upgrade (#17294) Ran npm-check-updates and yarn upgrade to keep the `yarn.lock` file up-to-date. --- package.json | 10 +- packages/@aws-cdk/app-delivery/package.json | 2 +- .../aws-apigatewayv2-authorizers/package.json | 2 +- .../aws-applicationautoscaling/package.json | 2 +- .../aws-autoscaling-common/package.json | 2 +- .../package.json | 4 +- .../@aws-cdk/aws-cloudformation/package.json | 2 +- .../aws-codepipeline-actions/package.json | 2 +- .../aws-global-table-coordinator/package.json | 2 +- packages/@aws-cdk/aws-dynamodb/package.json | 2 +- packages/@aws-cdk/aws-ec2/package.json | 2 +- packages/@aws-cdk/aws-eks/package.json | 2 +- packages/@aws-cdk/aws-iam/package.json | 2 +- .../@aws-cdk/aws-lambda-nodejs/package.json | 2 +- packages/@aws-cdk/aws-lambda/package.json | 4 +- packages/@aws-cdk/aws-logs/package.json | 4 +- .../aws-route53-targets/jest.config.js | 10 +- packages/@aws-cdk/aws-route53/package.json | 2 +- packages/@aws-cdk/aws-s3/package.json | 2 +- packages/@aws-cdk/aws-ses/package.json | 2 +- .../cloud-assembly-schema/package.json | 2 +- .../@aws-cdk/cloudformation-diff/package.json | 2 +- packages/@aws-cdk/core/package.json | 6 +- .../@aws-cdk/custom-resources/package.json | 4 +- packages/@aws-cdk/cx-api/package.json | 2 +- .../lib/example-resource.ts | 6 +- .../test/example-resource.test.ts | 42 + .../rewrite-imports/package.json | 2 +- packages/aws-cdk-migration/package.json | 2 +- packages/aws-cdk/package.json | 8 +- packages/awslint/package.json | 4 +- packages/cdk-assets/package.json | 4 +- packages/cdk-dasm/package.json | 2 +- packages/decdk/package.json | 4 +- .../cdk-build-tools/config/jest.config.js | 1 + tools/@aws-cdk/cdk-build-tools/package.json | 8 +- tools/@aws-cdk/cdk-release/package.json | 2 +- tools/@aws-cdk/cfn2ts/package.json | 2 +- tools/@aws-cdk/eslint-plugin/package.json | 2 +- tools/@aws-cdk/pkglint/package.json | 4 +- tools/@aws-cdk/prlint/package.json | 4 +- tools/@aws-cdk/yarn-cling/package.json | 2 +- yarn.lock | 909 +++++++++--------- 43 files changed, 564 insertions(+), 522 deletions(-) diff --git a/package.json b/package.json index 7a521b7db98e1..e0f41dbbeabf1 100644 --- a/package.json +++ b/package.json @@ -20,13 +20,13 @@ "fs-extra": "^9.1.0", "graceful-fs": "^4.2.8", "jest-junit": "^12.3.0", - "jsii-diff": "^1.41.0", - "jsii-pacmak": "^1.41.0", - "jsii-reflect": "^1.41.0", - "jsii-rosetta": "^1.41.0", + "jsii-diff": "^1.42.0", + "jsii-pacmak": "^1.42.0", + "jsii-reflect": "^1.42.0", + "jsii-rosetta": "^1.42.0", "lerna": "^4.0.0", "patch-package": "^6.4.7", - "standard-version": "^9.3.1", + "standard-version": "^9.3.2", "typescript": "~3.9.10" }, "resolutions": { diff --git a/packages/@aws-cdk/app-delivery/package.json b/packages/@aws-cdk/app-delivery/package.json index ef9a52c744e36..fe89215e39094 100644 --- a/packages/@aws-cdk/app-delivery/package.json +++ b/packages/@aws-cdk/app-delivery/package.json @@ -66,7 +66,7 @@ "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^26.0.24", - "fast-check": "^2.18.0", + "fast-check": "^2.19.0", "jest": "^26.6.3" }, "repository": { diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/package.json b/packages/@aws-cdk/aws-apigatewayv2-authorizers/package.json index 13c9a7d48efd3..01d8903715957 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/package.json +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/package.json @@ -78,7 +78,7 @@ "@aws-cdk/cdk-build-tools": "0.0.0", "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/aws-lambda": "^8.10.84", + "@types/aws-lambda": "^8.10.85", "@types/jest": "^26.0.24" }, "dependencies": { diff --git a/packages/@aws-cdk/aws-applicationautoscaling/package.json b/packages/@aws-cdk/aws-applicationautoscaling/package.json index e0fb58dda98e7..64308f0005133 100644 --- a/packages/@aws-cdk/aws-applicationautoscaling/package.json +++ b/packages/@aws-cdk/aws-applicationautoscaling/package.json @@ -77,7 +77,7 @@ "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^26.0.24", - "fast-check": "^2.18.0", + "fast-check": "^2.19.0", "jest": "^26.6.3" }, "dependencies": { diff --git a/packages/@aws-cdk/aws-autoscaling-common/package.json b/packages/@aws-cdk/aws-autoscaling-common/package.json index 2253a1669614f..f12569cbbc76d 100644 --- a/packages/@aws-cdk/aws-autoscaling-common/package.json +++ b/packages/@aws-cdk/aws-autoscaling-common/package.json @@ -69,7 +69,7 @@ "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^26.0.24", - "fast-check": "^2.18.0", + "fast-check": "^2.19.0", "jest": "^26.6.3" }, "dependencies": { diff --git a/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package.json b/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package.json index 6c6198071796b..af5f69aa16046 100644 --- a/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package.json +++ b/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/package.json @@ -29,7 +29,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@types/aws-lambda": "^8.10.84", + "@types/aws-lambda": "^8.10.85", "@types/sinon": "^9.0.11", "@aws-cdk/cdk-build-tools": "0.0.0", "aws-sdk": "^2.596.0", @@ -43,7 +43,7 @@ "jest": "^26.6.3", "lambda-tester": "^3.6.0", "sinon": "^9.2.4", - "nock": "^13.1.3", + "nock": "^13.1.4", "ts-jest": "^26.5.6" } } diff --git a/packages/@aws-cdk/aws-cloudformation/package.json b/packages/@aws-cdk/aws-cloudformation/package.json index 3a8c455bf4557..39e73c2be2948 100644 --- a/packages/@aws-cdk/aws-cloudformation/package.json +++ b/packages/@aws-cdk/aws-cloudformation/package.json @@ -79,7 +79,7 @@ "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/aws-lambda": "^8.10.84", + "@types/aws-lambda": "^8.10.85", "@types/jest": "^26.0.24", "jest": "^26.6.3" }, diff --git a/packages/@aws-cdk/aws-codepipeline-actions/package.json b/packages/@aws-cdk/aws-codepipeline-actions/package.json index 6f08ecc470c28..bfc1de1719831 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/package.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/package.json @@ -76,7 +76,7 @@ "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^26.0.24", - "@types/lodash": "^4.14.175", + "@types/lodash": "^4.14.176", "jest": "^26.6.3", "lodash": "^4.17.21" }, diff --git a/packages/@aws-cdk/aws-dynamodb-global/lambda-packages/aws-global-table-coordinator/package.json b/packages/@aws-cdk/aws-dynamodb-global/lambda-packages/aws-global-table-coordinator/package.json index 8e4e5cd1e6ff8..ee17747324574 100644 --- a/packages/@aws-cdk/aws-dynamodb-global/lambda-packages/aws-global-table-coordinator/package.json +++ b/packages/@aws-cdk/aws-dynamodb-global/lambda-packages/aws-global-table-coordinator/package.json @@ -39,6 +39,6 @@ "eslint-plugin-standard": "^4.1.0", "jest": "^26.6.3", "lambda-tester": "^3.6.0", - "nock": "^13.1.3" + "nock": "^13.1.4" } } diff --git a/packages/@aws-cdk/aws-dynamodb/package.json b/packages/@aws-cdk/aws-dynamodb/package.json index ba59f3f99b223..8fb374922fa25 100644 --- a/packages/@aws-cdk/aws-dynamodb/package.json +++ b/packages/@aws-cdk/aws-dynamodb/package.json @@ -77,7 +77,7 @@ "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/aws-lambda": "^8.10.84", + "@types/aws-lambda": "^8.10.85", "@types/jest": "^26.0.24", "@types/sinon": "^9.0.11", "aws-sdk": "^2.848.0", diff --git a/packages/@aws-cdk/aws-ec2/package.json b/packages/@aws-cdk/aws-ec2/package.json index 6cf7d368e25a2..8eaa9d1e5d64a 100644 --- a/packages/@aws-cdk/aws-ec2/package.json +++ b/packages/@aws-cdk/aws-ec2/package.json @@ -79,7 +79,7 @@ "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/aws-lambda": "^8.10.84", + "@types/aws-lambda": "^8.10.85", "@types/jest": "^26.0.24", "jest": "^26.6.3" }, diff --git a/packages/@aws-cdk/aws-eks/package.json b/packages/@aws-cdk/aws-eks/package.json index 7864034ff146b..e5c7869f9bc13 100644 --- a/packages/@aws-cdk/aws-eks/package.json +++ b/packages/@aws-cdk/aws-eks/package.json @@ -77,7 +77,7 @@ "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/aws-lambda": "^8.10.84", + "@types/aws-lambda": "^8.10.85", "@types/jest": "^26.0.24", "@types/sinon": "^9.0.11", "@types/yaml": "1.9.6", diff --git a/packages/@aws-cdk/aws-iam/package.json b/packages/@aws-cdk/aws-iam/package.json index 0e951bb0cdf2c..338e97338adfa 100644 --- a/packages/@aws-cdk/aws-iam/package.json +++ b/packages/@aws-cdk/aws-iam/package.json @@ -77,7 +77,7 @@ "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/aws-lambda": "^8.10.84", + "@types/aws-lambda": "^8.10.85", "@types/jest": "^26.0.24", "@types/sinon": "^9.0.11", "jest": "^26.6.3", diff --git a/packages/@aws-cdk/aws-lambda-nodejs/package.json b/packages/@aws-cdk/aws-lambda-nodejs/package.json index 185aeed69b3ec..fc627ab9e0227 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/package.json +++ b/packages/@aws-cdk/aws-lambda-nodejs/package.json @@ -71,7 +71,7 @@ "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^26.0.24", "delay": "5.0.0", - "esbuild": "^0.13.5" + "esbuild": "^0.13.12" }, "dependencies": { "@aws-cdk/aws-lambda": "0.0.0", diff --git a/packages/@aws-cdk/aws-lambda/package.json b/packages/@aws-cdk/aws-lambda/package.json index f139f180e7420..1a4baf8ea0d80 100644 --- a/packages/@aws-cdk/aws-lambda/package.json +++ b/packages/@aws-cdk/aws-lambda/package.json @@ -82,9 +82,9 @@ "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/cfnspec": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/aws-lambda": "^8.10.84", + "@types/aws-lambda": "^8.10.85", "@types/jest": "^26.0.24", - "@types/lodash": "^4.14.175", + "@types/lodash": "^4.14.176", "jest": "^26.6.3", "lodash": "^4.17.21" }, diff --git a/packages/@aws-cdk/aws-logs/package.json b/packages/@aws-cdk/aws-logs/package.json index a21e787888c1c..fa78fe76b2c9f 100644 --- a/packages/@aws-cdk/aws-logs/package.json +++ b/packages/@aws-cdk/aws-logs/package.json @@ -77,13 +77,13 @@ "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/aws-lambda": "^8.10.84", + "@types/aws-lambda": "^8.10.85", "@types/jest": "^26.0.24", "@types/sinon": "^9.0.11", "aws-sdk": "^2.848.0", "aws-sdk-mock": "^5.4.0", "jest": "^26.6.3", - "nock": "^13.1.3", + "nock": "^13.1.4", "sinon": "^9.2.4" }, "dependencies": { diff --git a/packages/@aws-cdk/aws-route53-targets/jest.config.js b/packages/@aws-cdk/aws-route53-targets/jest.config.js index 3a2fd93a1228a..53d601eeeff94 100644 --- a/packages/@aws-cdk/aws-route53-targets/jest.config.js +++ b/packages/@aws-cdk/aws-route53-targets/jest.config.js @@ -1,2 +1,10 @@ const baseConfig = require('@aws-cdk/cdk-build-tools/config/jest.config'); -module.exports = baseConfig; +module.exports = { + ...baseConfig, + coverageThreshold: { + global: { + branches: 70, + statements: 80, + } + } +}; diff --git a/packages/@aws-cdk/aws-route53/package.json b/packages/@aws-cdk/aws-route53/package.json index 2fc93edef1b21..9354619e6db4e 100644 --- a/packages/@aws-cdk/aws-route53/package.json +++ b/packages/@aws-cdk/aws-route53/package.json @@ -77,7 +77,7 @@ "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/aws-lambda": "^8.10.84", + "@types/aws-lambda": "^8.10.85", "@types/jest": "^26.0.24", "aws-sdk": "^2.848.0", "jest": "^26.6.3" diff --git a/packages/@aws-cdk/aws-s3/package.json b/packages/@aws-cdk/aws-s3/package.json index 3117d2919f6a6..afb95aeaa0d2e 100644 --- a/packages/@aws-cdk/aws-s3/package.json +++ b/packages/@aws-cdk/aws-s3/package.json @@ -77,7 +77,7 @@ "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/aws-lambda": "^8.10.84", + "@types/aws-lambda": "^8.10.85", "@types/jest": "^26.0.24", "jest": "^26.6.3" }, diff --git a/packages/@aws-cdk/aws-ses/package.json b/packages/@aws-cdk/aws-ses/package.json index a2a797e38b8cb..492108f1f04d9 100644 --- a/packages/@aws-cdk/aws-ses/package.json +++ b/packages/@aws-cdk/aws-ses/package.json @@ -77,7 +77,7 @@ "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/aws-lambda": "^8.10.84", + "@types/aws-lambda": "^8.10.85", "@types/jest": "^26.0.24", "jest": "^26.6.3" }, diff --git a/packages/@aws-cdk/cloud-assembly-schema/package.json b/packages/@aws-cdk/cloud-assembly-schema/package.json index 11226b0f1521a..06499db17d01e 100644 --- a/packages/@aws-cdk/cloud-assembly-schema/package.json +++ b/packages/@aws-cdk/cloud-assembly-schema/package.json @@ -64,7 +64,7 @@ "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^26.0.24", "@types/mock-fs": "^4.13.1", - "@types/semver": "^7.3.8", + "@types/semver": "^7.3.9", "jest": "^26.6.3", "mock-fs": "^4.14.0", "typescript-json-schema": "^0.51.0" diff --git a/packages/@aws-cdk/cloudformation-diff/package.json b/packages/@aws-cdk/cloudformation-diff/package.json index 3a3ad220ff70f..d101afe2b69d2 100644 --- a/packages/@aws-cdk/cloudformation-diff/package.json +++ b/packages/@aws-cdk/cloudformation-diff/package.json @@ -36,7 +36,7 @@ "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^26.0.24", "@types/string-width": "^4.0.1", - "fast-check": "^2.18.0", + "fast-check": "^2.19.0", "jest": "^26.6.3", "ts-jest": "^26.5.6" }, diff --git a/packages/@aws-cdk/core/package.json b/packages/@aws-cdk/core/package.json index f7cd653ca7e7f..45e4232abb477 100644 --- a/packages/@aws-cdk/core/package.json +++ b/packages/@aws-cdk/core/package.json @@ -171,14 +171,14 @@ "@aws-cdk/cdk-build-tools": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/aws-lambda": "^8.10.84", + "@types/aws-lambda": "^8.10.85", "@types/fs-extra": "^8.1.2", "@types/jest": "^26.0.24", - "@types/lodash": "^4.14.175", + "@types/lodash": "^4.14.176", "@types/minimatch": "^3.0.5", "@types/node": "^10.17.60", "@types/sinon": "^9.0.11", - "fast-check": "^2.18.0", + "fast-check": "^2.19.0", "jest": "^26.6.3", "lodash": "^4.17.21", "sinon": "^9.2.4", diff --git a/packages/@aws-cdk/custom-resources/package.json b/packages/@aws-cdk/custom-resources/package.json index 698596d6ae0c0..f30e67b0a5838 100644 --- a/packages/@aws-cdk/custom-resources/package.json +++ b/packages/@aws-cdk/custom-resources/package.json @@ -80,14 +80,14 @@ "@aws-cdk/cdk-integ-tools": "0.0.0", "@aws-cdk/cfn2ts": "0.0.0", "@aws-cdk/pkglint": "0.0.0", - "@types/aws-lambda": "^8.10.84", + "@types/aws-lambda": "^8.10.85", "@types/fs-extra": "^8.1.2", "@types/jest": "^26.0.24", "@types/sinon": "^9.0.11", "aws-sdk": "^2.848.0", "aws-sdk-mock": "^5.4.0", "fs-extra": "^9.1.0", - "nock": "^13.1.3", + "nock": "^13.1.4", "sinon": "^9.2.4" }, "dependencies": { diff --git a/packages/@aws-cdk/cx-api/package.json b/packages/@aws-cdk/cx-api/package.json index 0a92e1c3492b6..6ed3341b1a082 100644 --- a/packages/@aws-cdk/cx-api/package.json +++ b/packages/@aws-cdk/cx-api/package.json @@ -70,7 +70,7 @@ "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^26.0.24", "@types/mock-fs": "^4.13.1", - "@types/semver": "^7.3.8", + "@types/semver": "^7.3.9", "jest": "^26.6.3", "mock-fs": "^4.14.0" }, diff --git a/packages/@aws-cdk/example-construct-library/lib/example-resource.ts b/packages/@aws-cdk/example-construct-library/lib/example-resource.ts index 6c4630dab6ae4..3c514d01ba19c 100644 --- a/packages/@aws-cdk/example-construct-library/lib/example-resource.ts +++ b/packages/@aws-cdk/example-construct-library/lib/example-resource.ts @@ -137,7 +137,7 @@ export interface IExampleResource extends * The details of which metric methods you should have of course depends on the * resource that is being modeled. */ - metricCount(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric; + metricCount(props?: cloudwatch.MetricOptions): cloudwatch.Metric; } /** @@ -212,12 +212,12 @@ abstract class ExampleResourceBase extends core.Resource implements IExampleReso } /** Implement the {@link IExampleResource.metricCount} method. */ - public metricCount(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric { + public metricCount(props?: cloudwatch.MetricOptions): cloudwatch.Metric { return new cloudwatch.Metric({ // of course, you would put your resource-specific values here namespace: 'AWS/ExampleResource', + metricName: 'Count', dimensions: { ExampleResource: this.exampleResourceName }, - metricName, ...props, }).attachTo(this); } diff --git a/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts b/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts index db1e8d68d4830..7ef95e9a6e671 100644 --- a/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts +++ b/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts @@ -6,9 +6,11 @@ import { Match, Template } from '@aws-cdk/assertions'; +import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as core from '@aws-cdk/core'; + // Always import the module you're testing qualified - // don't import individual classes from it! // Importing it qualified tests whether everything that needs to be exported @@ -18,6 +20,12 @@ import * as er from '../lib'; /* We allow quotes in the object keys used for CloudFormation template assertions */ /* eslint-disable quote-props */ +const EXAMPLE_RESOURCE_NAME = { + 'Fn::Select': [1, { + 'Fn::Split': ['/', { 'Ref': 'ExampleResourceAC53F4AE' }], + }], +}; + describe('Example Resource', () => { let stack: core.Stack; @@ -111,6 +119,40 @@ describe('Example Resource', () => { }, }); }); + + test('onEvent adds an Event Rule', () => { + exampleResource.onEvent('MyEvent'); + + Template.fromStack(stack).hasResourceProperties('AWS::Events::Rule', { + EventPattern: { + detail: { + 'example-resource-name': [EXAMPLE_RESOURCE_NAME], + }, + }, + }); + }); + + test('metricCount returns a metric with correct dimensions', () => { + const countMetric = exampleResource.metricCount(); + + new cloudwatch.Alarm(stack, 'Alarm', { + metric: countMetric, + threshold: 10, + evaluationPeriods: 2, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + EvaluationPeriods: 2, + Dimensions: [ + { + Name: 'ExampleResource', + Value: EXAMPLE_RESOURCE_NAME, + }, + ], + MetricName: 'Count', + Namespace: 'AWS/ExampleResource', + }); + }); }); describe('created with a VPC', () => { diff --git a/packages/@monocdk-experiment/rewrite-imports/package.json b/packages/@monocdk-experiment/rewrite-imports/package.json index 7f602376d551a..3142c44c79526 100644 --- a/packages/@monocdk-experiment/rewrite-imports/package.json +++ b/packages/@monocdk-experiment/rewrite-imports/package.json @@ -35,7 +35,7 @@ "typescript": "~3.9.10" }, "devDependencies": { - "@types/glob": "^7.1.4", + "@types/glob": "^7.2.0", "@types/jest": "^26.0.24", "@types/node": "^10.17.60", "@aws-cdk/cdk-build-tools": "0.0.0", diff --git a/packages/aws-cdk-migration/package.json b/packages/aws-cdk-migration/package.json index 1ce16c5670458..34a387cadab5f 100644 --- a/packages/aws-cdk-migration/package.json +++ b/packages/aws-cdk-migration/package.json @@ -38,7 +38,7 @@ "typescript": "~3.9.10" }, "devDependencies": { - "@types/glob": "^7.1.4", + "@types/glob": "^7.2.0", "@types/jest": "^26.0.24", "@types/node": "^10.17.60", "@aws-cdk/cdk-build-tools": "0.0.0", diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index 4492f92549b45..c71dddbf206f4 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -41,13 +41,13 @@ "@octokit/rest": "^18.12.0", "@types/archiver": "^5.3.0", "@types/fs-extra": "^8.1.2", - "@types/glob": "^7.1.4", + "@types/glob": "^7.2.0", "@types/jest": "^26.0.24", "@types/minimatch": "^3.0.5", "@types/mockery": "^1.4.30", "@types/node": "^10.17.60", "@types/promptly": "^3.0.2", - "@types/semver": "^7.3.8", + "@types/semver": "^7.3.9", "@types/sinon": "^9.0.11", "@types/table": "^6.0.0", "@types/uuid": "^8.3.1", @@ -59,7 +59,7 @@ "jest": "^26.6.3", "make-runnable": "^1.3.10", "mockery": "^2.1.0", - "nock": "^13.1.3", + "nock": "^13.1.4", "@aws-cdk/pkglint": "0.0.0", "sinon": "^9.2.4", "ts-jest": "^26.5.6", @@ -71,7 +71,7 @@ "@aws-cdk/cloudformation-diff": "0.0.0", "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/region-info": "0.0.0", - "@jsii/check-node": "1.40.0", + "@jsii/check-node": "1.42.0", "archiver": "^5.3.0", "aws-sdk": "^2.979.0", "camelcase": "^6.2.0", diff --git a/packages/awslint/package.json b/packages/awslint/package.json index df07c732685ef..626809090c391 100644 --- a/packages/awslint/package.json +++ b/packages/awslint/package.json @@ -18,11 +18,11 @@ "awslint": "bin/awslint" }, "dependencies": { - "@jsii/spec": "^1.41.0", + "@jsii/spec": "^1.42.0", "camelcase": "^6.2.0", "colors": "^1.4.0", "fs-extra": "^9.1.0", - "jsii-reflect": "^1.41.0", + "jsii-reflect": "^1.42.0", "yargs": "^16.2.0" }, "devDependencies": { diff --git a/packages/cdk-assets/package.json b/packages/cdk-assets/package.json index e5572280b04df..d594eccfc0e02 100644 --- a/packages/cdk-assets/package.json +++ b/packages/cdk-assets/package.json @@ -31,7 +31,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/archiver": "^5.3.0", - "@types/glob": "^7.1.4", + "@types/glob": "^7.2.0", "@types/jest": "^26.0.24", "@types/mime": "^2.0.3", "@types/mock-fs": "^4.13.1", @@ -49,7 +49,7 @@ "archiver": "^5.3.0", "aws-sdk": "^2.848.0", "glob": "^7.2.0", - "mime": "^2.5.2", + "mime": "^2.6.0", "yargs": "^16.2.0" }, "repository": { diff --git a/packages/cdk-dasm/package.json b/packages/cdk-dasm/package.json index c7147f7e5b4a5..6589159649794 100644 --- a/packages/cdk-dasm/package.json +++ b/packages/cdk-dasm/package.json @@ -28,7 +28,7 @@ }, "license": "Apache-2.0", "dependencies": { - "codemaker": "^1.39.0", + "codemaker": "^1.42.0", "yaml": "1.10.2" }, "devDependencies": { diff --git a/packages/decdk/package.json b/packages/decdk/package.json index 7ebd9cc3d632c..3d181528f325e 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -244,7 +244,7 @@ "@aws-cdk/region-info": "0.0.0", "constructs": "^3.3.69", "fs-extra": "^9.1.0", - "jsii-reflect": "^1.41.0", + "jsii-reflect": "^1.42.0", "jsonschema": "^1.4.0", "yaml": "1.10.2", "yargs": "^16.2.0" @@ -255,7 +255,7 @@ "@types/yaml": "1.9.7", "@types/yargs": "^15.0.14", "jest": "^26.6.3", - "jsii": "^1.41.0" + "jsii": "^1.42.0" }, "keywords": [ "aws", diff --git a/tools/@aws-cdk/cdk-build-tools/config/jest.config.js b/tools/@aws-cdk/cdk-build-tools/config/jest.config.js index b8e056af3c8a3..367fff38462a4 100644 --- a/tools/@aws-cdk/cdk-build-tools/config/jest.config.js +++ b/tools/@aws-cdk/cdk-build-tools/config/jest.config.js @@ -21,6 +21,7 @@ module.exports = { coveragePathIgnorePatterns: [ "/lib/.*\\.generated\\.[jt]s", "/test/.*\\.[jt]s", + "/.*\\.jsii\\.js", ], reporters: [ "default", diff --git a/tools/@aws-cdk/cdk-build-tools/package.json b/tools/@aws-cdk/cdk-build-tools/package.json index a99a32059c006..5e2015222bc13 100644 --- a/tools/@aws-cdk/cdk-build-tools/package.json +++ b/tools/@aws-cdk/cdk-build-tools/package.json @@ -38,7 +38,7 @@ "@aws-cdk/pkglint": "0.0.0", "@types/fs-extra": "^8.1.2", "@types/jest": "^26.0.24", - "@types/semver": "^7.3.8", + "@types/semver": "^7.3.9", "@types/yargs": "^15.0.14" }, "dependencies": { @@ -56,9 +56,9 @@ "fs-extra": "^9.1.0", "jest": "^27.3.1", "jest-junit": "^11.1.0", - "jsii": "^1.41.0", - "jsii-pacmak": "^1.41.0", - "jsii-reflect": "^1.41.0", + "jsii": "^1.42.0", + "jsii-pacmak": "^1.42.0", + "jsii-reflect": "^1.42.0", "markdownlint-cli": "^0.29.0", "nyc": "^15.1.0", "semver": "^7.3.5", diff --git a/tools/@aws-cdk/cdk-release/package.json b/tools/@aws-cdk/cdk-release/package.json index ed0b5705e94df..26b5d08f9764e 100644 --- a/tools/@aws-cdk/cdk-release/package.json +++ b/tools/@aws-cdk/cdk-release/package.json @@ -43,7 +43,7 @@ "conventional-changelog-config-spec": "^2.1.0", "conventional-changelog-preset-loader": "^2.3.4", "conventional-changelog-writer": "^4.1.0", - "conventional-commits-parser": "^3.2.2", + "conventional-commits-parser": "^3.2.3", "detect-indent": "^6.1.0", "detect-newline": "^3.1.0", "fs-extra": "^9.1.0", diff --git a/tools/@aws-cdk/cfn2ts/package.json b/tools/@aws-cdk/cfn2ts/package.json index dbb024e64cb32..8b484144ee4f8 100644 --- a/tools/@aws-cdk/cfn2ts/package.json +++ b/tools/@aws-cdk/cfn2ts/package.json @@ -32,7 +32,7 @@ "license": "Apache-2.0", "dependencies": { "@aws-cdk/cfnspec": "0.0.0", - "codemaker": "^1.39.0", + "codemaker": "^1.42.0", "fast-json-patch": "^3.1.0", "fs-extra": "^9.1.0", "yargs": "^16.2.0" diff --git a/tools/@aws-cdk/eslint-plugin/package.json b/tools/@aws-cdk/eslint-plugin/package.json index 87c004f94d846..19b0e287247d2 100644 --- a/tools/@aws-cdk/eslint-plugin/package.json +++ b/tools/@aws-cdk/eslint-plugin/package.json @@ -14,7 +14,7 @@ "build+extract": "npm run build" }, "devDependencies": { - "@types/eslint": "^7.28.1", + "@types/eslint": "^7.28.2", "@types/fs-extra": "^8.1.2", "@types/jest": "^26.0.24", "@types/node": "^10.17.60", diff --git a/tools/@aws-cdk/pkglint/package.json b/tools/@aws-cdk/pkglint/package.json index 72283bad492b2..463b2b96c3e5e 100644 --- a/tools/@aws-cdk/pkglint/package.json +++ b/tools/@aws-cdk/pkglint/package.json @@ -39,9 +39,9 @@ "devDependencies": { "@aws-cdk/eslint-plugin": "0.0.0", "@types/fs-extra": "^8.1.2", - "@types/glob": "^7.1.4", + "@types/glob": "^7.2.0", "@types/jest": "^26.0.24", - "@types/semver": "^7.3.8", + "@types/semver": "^7.3.9", "@types/yargs": "^15.0.14", "@typescript-eslint/eslint-plugin": "^4.33.0", "@typescript-eslint/parser": "^4.33.0", diff --git a/tools/@aws-cdk/prlint/package.json b/tools/@aws-cdk/prlint/package.json index 1c45caf95233d..c85296b6a292a 100644 --- a/tools/@aws-cdk/prlint/package.json +++ b/tools/@aws-cdk/prlint/package.json @@ -13,14 +13,14 @@ "dependencies": { "@actions/core": "^1.6.0", "@actions/github": "^2.2.0", - "conventional-commits-parser": "^3.2.2", + "conventional-commits-parser": "^3.2.3", "fs-extra": "^9.1.0", "github-api": "^3.4.0", "glob": "^7.2.0" }, "devDependencies": { "@types/fs-extra": "^9.0.13", - "@types/glob": "^7.1.4", + "@types/glob": "^7.2.0", "@types/jest": "^26.0.24", "jest": "^26.6.3", "make-runnable": "^1.3.10", diff --git a/tools/@aws-cdk/yarn-cling/package.json b/tools/@aws-cdk/yarn-cling/package.json index b8c930eb66867..036cf5377eac2 100644 --- a/tools/@aws-cdk/yarn-cling/package.json +++ b/tools/@aws-cdk/yarn-cling/package.json @@ -40,7 +40,7 @@ "@aws-cdk/pkglint": "0.0.0", "@types/jest": "^26.0.24", "@types/node": "^10.17.60", - "@types/semver": "^7.3.8", + "@types/semver": "^7.3.9", "@types/yarnpkg__lockfile": "^1.1.5", "jest": "^26.6.3", "typescript": "~3.9.10" diff --git a/yarn.lock b/yarn.lock index 48ecde5d6ee28..88df4ad3d4edb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -32,32 +32,32 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5", "@babel/code-frame@^7.15.8": - version "7.15.8" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz#45990c47adadb00c03677baa89221f7cc23d2503" - integrity sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg== - dependencies: - "@babel/highlight" "^7.14.5" - -"@babel/compat-data@^7.15.0": - version "7.15.0" - resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" - integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== - -"@babel/core@^7.1.0", "@babel/core@^7.7.2", "@babel/core@^7.7.5": - version "7.15.8" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz#195b9f2bffe995d2c6c159e72fe525b4114e8c10" - integrity sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og== - dependencies: - "@babel/code-frame" "^7.15.8" - "@babel/generator" "^7.15.8" - "@babel/helper-compilation-targets" "^7.15.4" - "@babel/helper-module-transforms" "^7.15.8" - "@babel/helpers" "^7.15.4" - "@babel/parser" "^7.15.8" - "@babel/template" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.6" +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431" + integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA== + dependencies: + "@babel/highlight" "^7.16.0" + +"@babel/compat-data@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.0.tgz#ea269d7f78deb3a7826c39a4048eecda541ebdaa" + integrity sha512-DGjt2QZse5SGd9nfOSqO4WLJ8NN/oHkijbXbPrxuoJO3oIPJL3TciZs9FX+cOHNiY9E9l0opL8g7BmLe3T+9ew== + +"@babel/core@^7.1.0", "@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.7.5": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.16.0.tgz#c4ff44046f5fe310525cc9eb4ef5147f0c5374d4" + integrity sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ== + dependencies: + "@babel/code-frame" "^7.16.0" + "@babel/generator" "^7.16.0" + "@babel/helper-compilation-targets" "^7.16.0" + "@babel/helper-module-transforms" "^7.16.0" + "@babel/helpers" "^7.16.0" + "@babel/parser" "^7.16.0" + "@babel/template" "^7.16.0" + "@babel/traverse" "^7.16.0" + "@babel/types" "^7.16.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" @@ -65,113 +65,113 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.15.4", "@babel/generator@^7.15.8", "@babel/generator@^7.7.2": - version "7.15.8" - resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz#fa56be6b596952ceb231048cf84ee499a19c0cd1" - integrity sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g== +"@babel/generator@^7.16.0", "@babel/generator@^7.7.2": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.16.0.tgz#d40f3d1d5075e62d3500bccb67f3daa8a95265b2" + integrity sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew== dependencies: - "@babel/types" "^7.15.6" + "@babel/types" "^7.16.0" jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-compilation-targets@^7.15.4": - version "7.15.4" - resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz#cf6d94f30fbefc139123e27dd6b02f65aeedb7b9" - integrity sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ== +"@babel/helper-compilation-targets@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.0.tgz#01d615762e796c17952c29e3ede9d6de07d235a8" + integrity sha512-S7iaOT1SYlqK0sQaCi21RX4+13hmdmnxIEAnQUB/eh7GeAnRjOUgTYpLkUOiRXzD+yog1JxP0qyAQZ7ZxVxLVg== dependencies: - "@babel/compat-data" "^7.15.0" + "@babel/compat-data" "^7.16.0" "@babel/helper-validator-option" "^7.14.5" browserslist "^4.16.6" semver "^6.3.0" -"@babel/helper-function-name@^7.15.4": - version "7.15.4" - resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc" - integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw== +"@babel/helper-function-name@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz#b7dd0797d00bbfee4f07e9c4ea5b0e30c8bb1481" + integrity sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog== dependencies: - "@babel/helper-get-function-arity" "^7.15.4" - "@babel/template" "^7.15.4" - "@babel/types" "^7.15.4" + "@babel/helper-get-function-arity" "^7.16.0" + "@babel/template" "^7.16.0" + "@babel/types" "^7.16.0" -"@babel/helper-get-function-arity@^7.15.4": - version "7.15.4" - resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b" - integrity sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA== +"@babel/helper-get-function-arity@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz#0088c7486b29a9cb5d948b1a1de46db66e089cfa" + integrity sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ== dependencies: - "@babel/types" "^7.15.4" + "@babel/types" "^7.16.0" -"@babel/helper-hoist-variables@^7.15.4": - version "7.15.4" - resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df" - integrity sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA== +"@babel/helper-hoist-variables@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz#4c9023c2f1def7e28ff46fc1dbcd36a39beaa81a" + integrity sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg== dependencies: - "@babel/types" "^7.15.4" + "@babel/types" "^7.16.0" -"@babel/helper-member-expression-to-functions@^7.15.4": - version "7.15.4" - resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz#bfd34dc9bba9824a4658b0317ec2fd571a51e6ef" - integrity sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA== +"@babel/helper-member-expression-to-functions@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.0.tgz#29287040efd197c77636ef75188e81da8bccd5a4" + integrity sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ== dependencies: - "@babel/types" "^7.15.4" + "@babel/types" "^7.16.0" -"@babel/helper-module-imports@^7.15.4": - version "7.15.4" - resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz#e18007d230632dea19b47853b984476e7b4e103f" - integrity sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA== +"@babel/helper-module-imports@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz#90538e60b672ecf1b448f5f4f5433d37e79a3ec3" + integrity sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg== dependencies: - "@babel/types" "^7.15.4" + "@babel/types" "^7.16.0" -"@babel/helper-module-transforms@^7.15.8": - version "7.15.8" - resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz#d8c0e75a87a52e374a8f25f855174786a09498b2" - integrity sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg== +"@babel/helper-module-transforms@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.0.tgz#1c82a8dd4cb34577502ebd2909699b194c3e9bb5" + integrity sha512-My4cr9ATcaBbmaEa8M0dZNA74cfI6gitvUAskgDtAFmAqyFKDSHQo5YstxPbN+lzHl2D9l/YOEFqb2mtUh4gfA== dependencies: - "@babel/helper-module-imports" "^7.15.4" - "@babel/helper-replace-supers" "^7.15.4" - "@babel/helper-simple-access" "^7.15.4" - "@babel/helper-split-export-declaration" "^7.15.4" + "@babel/helper-module-imports" "^7.16.0" + "@babel/helper-replace-supers" "^7.16.0" + "@babel/helper-simple-access" "^7.16.0" + "@babel/helper-split-export-declaration" "^7.16.0" "@babel/helper-validator-identifier" "^7.15.7" - "@babel/template" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.6" + "@babel/template" "^7.16.0" + "@babel/traverse" "^7.16.0" + "@babel/types" "^7.16.0" -"@babel/helper-optimise-call-expression@^7.15.4": - version "7.15.4" - resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz#f310a5121a3b9cc52d9ab19122bd729822dee171" - integrity sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw== +"@babel/helper-optimise-call-expression@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz#cecdb145d70c54096b1564f8e9f10cd7d193b338" + integrity sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw== dependencies: - "@babel/types" "^7.15.4" + "@babel/types" "^7.16.0" "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0": version "7.14.5" resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== -"@babel/helper-replace-supers@^7.15.4": - version "7.15.4" - resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz#52a8ab26ba918c7f6dee28628b07071ac7b7347a" - integrity sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw== +"@babel/helper-replace-supers@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.0.tgz#73055e8d3cf9bcba8ddb55cad93fedc860f68f17" + integrity sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA== dependencies: - "@babel/helper-member-expression-to-functions" "^7.15.4" - "@babel/helper-optimise-call-expression" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.4" + "@babel/helper-member-expression-to-functions" "^7.16.0" + "@babel/helper-optimise-call-expression" "^7.16.0" + "@babel/traverse" "^7.16.0" + "@babel/types" "^7.16.0" -"@babel/helper-simple-access@^7.15.4": - version "7.15.4" - resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz#ac368905abf1de8e9781434b635d8f8674bcc13b" - integrity sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg== +"@babel/helper-simple-access@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.0.tgz#21d6a27620e383e37534cf6c10bba019a6f90517" + integrity sha512-o1rjBT/gppAqKsYfUdfHq5Rk03lMQrkPHG1OWzHWpLgVXRH4HnMM9Et9CVdIqwkCQlobnGHEJMsgWP/jE1zUiw== dependencies: - "@babel/types" "^7.15.4" + "@babel/types" "^7.16.0" -"@babel/helper-split-export-declaration@^7.15.4": - version "7.15.4" - resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz#aecab92dcdbef6a10aa3b62ab204b085f776e257" - integrity sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw== +"@babel/helper-split-export-declaration@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz#29672f43663e936df370aaeb22beddb3baec7438" + integrity sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw== dependencies: - "@babel/types" "^7.15.4" + "@babel/types" "^7.16.0" -"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.15.7": +"@babel/helper-validator-identifier@^7.15.7": version "7.15.7" resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== @@ -181,28 +181,28 @@ resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== -"@babel/helpers@^7.15.4": - version "7.15.4" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz#5f40f02050a3027121a3cf48d497c05c555eaf43" - integrity sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ== +"@babel/helpers@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.0.tgz#875519c979c232f41adfbd43a3b0398c2e388183" + integrity sha512-dVRM0StFMdKlkt7cVcGgwD8UMaBfWJHl3A83Yfs8GQ3MO0LHIIIMvK7Fa0RGOGUQ10qikLaX6D7o5htcQWgTMQ== dependencies: - "@babel/template" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.4" + "@babel/template" "^7.16.0" + "@babel/traverse" "^7.16.0" + "@babel/types" "^7.16.0" -"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": - version "7.14.5" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== +"@babel/highlight@^7.10.4", "@babel/highlight@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a" + integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g== dependencies: - "@babel/helper-validator-identifier" "^7.14.5" + "@babel/helper-validator-identifier" "^7.15.7" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.15.4", "@babel/parser@^7.15.8", "@babel/parser@^7.7.2": - version "7.15.8" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz#7bacdcbe71bdc3ff936d510c15dcea7cf0b99016" - integrity sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.0", "@babel/parser@^7.7.2": + version "7.16.2" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.16.2.tgz#3723cd5c8d8773eef96ce57ea1d9b7faaccd12ac" + integrity sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw== "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -289,42 +289,42 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript@^7.7.2": - version "7.14.5" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716" - integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q== + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.0.tgz#2feeb13d9334cc582ea9111d3506f773174179bb" + integrity sha512-Xv6mEXqVdaqCBfJFyeab0fH2DnUoMsDmhamxsSi4j8nLd4Vtw213WMJr55xxqipC/YVWyPY3K0blJncPYji+dQ== dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/template@^7.15.4", "@babel/template@^7.3.3": - version "7.15.4" - resolved "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" - integrity sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/parser" "^7.15.4" - "@babel/types" "^7.15.4" - -"@babel/traverse@^7.1.0", "@babel/traverse@^7.15.4", "@babel/traverse@^7.7.2": - version "7.15.4" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d" - integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.15.4" - "@babel/helper-function-name" "^7.15.4" - "@babel/helper-hoist-variables" "^7.15.4" - "@babel/helper-split-export-declaration" "^7.15.4" - "@babel/parser" "^7.15.4" - "@babel/types" "^7.15.4" +"@babel/template@^7.16.0", "@babel/template@^7.3.3": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6" + integrity sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A== + dependencies: + "@babel/code-frame" "^7.16.0" + "@babel/parser" "^7.16.0" + "@babel/types" "^7.16.0" + +"@babel/traverse@^7.1.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.7.2": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.0.tgz#965df6c6bfc0a958c1e739284d3c9fa4a6e3c45b" + integrity sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ== + dependencies: + "@babel/code-frame" "^7.16.0" + "@babel/generator" "^7.16.0" + "@babel/helper-function-name" "^7.16.0" + "@babel/helper-hoist-variables" "^7.16.0" + "@babel/helper-split-export-declaration" "^7.16.0" + "@babel/parser" "^7.16.0" + "@babel/types" "^7.16.0" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.15.4", "@babel/types@^7.15.6", "@babel/types@^7.3.0", "@babel/types@^7.3.3": - version "7.15.6" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f" - integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig== +"@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba" + integrity sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg== dependencies: - "@babel/helper-validator-identifier" "^7.14.9" + "@babel/helper-validator-identifier" "^7.15.7" to-fast-properties "^2.0.0" "@balena/dockerignore@^1.0.2": @@ -387,9 +387,9 @@ minimatch "^3.0.4" "@humanwhocodes/object-schema@^1.2.0": - version "1.2.0" - resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" - integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== + version "1.2.1" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== "@hutson/parse-repository-url@^3.0.0": version "3.0.2" @@ -752,26 +752,18 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" -"@jsii/check-node@1.40.0": - version "1.40.0" - resolved "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.40.0.tgz#49882a61ad1b3a37cd35c35fa1a2301955f1c058" - integrity sha512-rk0hFXxFQR8rDGUfsZT9ua6OufOpnLQWsNFyFU86AvpoKQ0ciw2KlGdWs7OYFnzPq8sQGhSS+iuBrUboaHW3jg== - dependencies: - chalk "^4.1.2" - semver "^7.3.5" - -"@jsii/check-node@1.41.0": - version "1.41.0" - resolved "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.41.0.tgz#17b6895e1fcc0b8bbb8fa81b52b17c47c9c47674" - integrity sha512-lV/vMK1HZQcUye2vXPu6XsmnTk7fEui0GnQsPAX1eLWfRMkxkRblT4VZ9DQTYjMno2HuVP4IH51fiFoICMmnkA== +"@jsii/check-node@1.42.0": + version "1.42.0" + resolved "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.42.0.tgz#10dd84fbefa020344c9574079361c1a18754872a" + integrity sha512-URX4s0iOmuxbERL2rO10JlwedYbAT/3vM2HqswgjtJUbZTFgHsmg+Tzh3JglJzKuCg8Xm4m6CP4UlFMPqPRcqA== dependencies: chalk "^4.1.2" semver "^7.3.5" -"@jsii/spec@^1.41.0": - version "1.41.0" - resolved "https://registry.npmjs.org/@jsii/spec/-/spec-1.41.0.tgz#d504c8536139a97986b1ec63201d3575972e1e9c" - integrity sha512-sN7x6C0DGLngiO6SkrM/7gVaHyeja59bDZODZtBXIq8kBIC+GgAFS8P0s1e5FpU9mHHvvHq4rvzvcIbxw0nkXw== +"@jsii/spec@^1.42.0": + version "1.42.0" + resolved "https://registry.npmjs.org/@jsii/spec/-/spec-1.42.0.tgz#39e787e5ac2ddc96256b73421603bc734c56f7d8" + integrity sha512-SS2Q1Ds/yiTejd/0KO5lC6SUGqlfjuqZ6nAxJxLU76JQ99v1spRJeS7oi/2OW+ZmTEwBy81DgjOxA8bwUc0U/Q== dependencies: jsonschema "^1.4.0" @@ -1468,9 +1460,9 @@ fastq "^1.6.0" "@npmcli/ci-detect@^1.0.0": - version "1.3.0" - resolved "https://registry.npmjs.org/@npmcli/ci-detect/-/ci-detect-1.3.0.tgz#6c1d2c625fb6ef1b9dea85ad0a5afcbef85ef22a" - integrity sha512-oN3y7FAROHhrAt7Rr7PnTSwrHrZVRTS2ZbyxeQwSSYD0ifwM3YNgQqbaRmjcWoPyq77MjchusjJDspbzMmip1Q== + version "1.4.0" + resolved "https://registry.npmjs.org/@npmcli/ci-detect/-/ci-detect-1.4.0.tgz#18478bbaa900c37bfbd8a2006a6262c62e8b0fe1" + integrity sha512-3BGrt6FLjqM6br5AhWRKTr3u5GIVkjRYeAFrMp3HjnfICrg4xOrVRwFavKT6tsp++bq5dluL5t8ME/Nha/6c1Q== "@npmcli/fs@^1.0.0": version "1.0.0" @@ -1774,10 +1766,10 @@ dependencies: "@types/glob" "*" -"@types/aws-lambda@^8.10.84": - version "8.10.84" - resolved "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.84.tgz#b1f391ceeb6908b28d8416d93f27afe8d1348d4e" - integrity sha512-5V78eLtmN0d4RA14hKDwcsMQRl3JotQJlhGFDBo/jdE2TyDFRaYwB/UmMUC4SzhSvRGn+YMkh7jGPnXi8COAng== +"@types/aws-lambda@^8.10.85": + version "8.10.85" + resolved "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.85.tgz#26cd76897b1972247cbc1a34b6f21d023e987437" + integrity sha512-cMRXVxb+NMb6EekKel1fPBfz2ZqE5cGhIS14G7FVUM4Bqilx0lHKnZbsDLWLSeckDpkvlp5six2F7UWyEEJSoQ== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.7": version "7.1.16" @@ -1817,10 +1809,10 @@ resolved "https://registry.npmjs.org/@types/changelog-parser/-/changelog-parser-2.7.1.tgz#da124373fc8abfb6951fef83718ea5f041fea527" integrity sha512-OFZB7OlG6nrkcnvJhcyV2Zm/PUGk40oHyfaEBRjlm+ghrKxbFQI+xao/IzYL0G72fpLCTGGs3USrhe38/FF6QQ== -"@types/eslint@^7.28.1": - version "7.28.1" - resolved "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.1.tgz#50b07747f1f84c2ba8cd394cf0fe0ba07afce320" - integrity sha512-XhZKznR3i/W5dXqUhgU9fFdJekufbeBd5DALmkuXoeFcjbQcPk+2cL+WLHf6Q81HWAnM2vrslIHpGVyCAviRwg== +"@types/eslint@^7.28.2": + version "7.28.2" + resolved "https://registry.npmjs.org/@types/eslint/-/eslint-7.28.2.tgz#0ff2947cdd305897c52d5372294e8c76f351db68" + integrity sha512-KubbADPkfoU75KgKeKLsFHXnU4ipH7wYg0TRT33NK3N3yiu7jlFAAoygIWBV+KbuHx/G+AvuGX6DllnK35gfJA== dependencies: "@types/estree" "*" "@types/json-schema" "*" @@ -1844,10 +1836,10 @@ dependencies: "@types/node" "*" -"@types/glob@*", "@types/glob@^7.1.4": - version "7.1.4" - resolved "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz#ea59e21d2ee5c517914cb4bc8e4153b99e566672" - integrity sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA== +"@types/glob@*", "@types/glob@^7.2.0": + version "7.2.0" + resolved "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== dependencies: "@types/minimatch" "*" "@types/node" "*" @@ -1896,10 +1888,10 @@ resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= -"@types/lodash@^4.14.175": - version "4.14.175" - resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.175.tgz#b78dfa959192b01fae0ad90e166478769b215f45" - integrity sha512-XmdEOrKQ8a1Y/yxQFOMbC47G/V2VDO1GvMRnl4O75M4GW/abC5tnfzadQYkqEveqRM1dEJGFFegfPNA2vvx2iw== +"@types/lodash@^4.14.176": + version "4.14.176" + resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.176.tgz#641150fc1cda36fbfa329de603bbb175d7ee20c0" + integrity sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ== "@types/md5@^2.3.1": version "2.3.1" @@ -1936,9 +1928,9 @@ integrity sha512-uv53RrNdhbkV/3VmVCtfImfYCWC3GTTRn3R11Whni3EJ+gb178tkZBVNj2edLY5CMrB749dQi+SJkg87jsN8UQ== "@types/node@*", "@types/node@>= 8", "@types/node@^16.9.2": - version "16.10.5" - resolved "https://registry.npmjs.org/@types/node/-/node-16.10.5.tgz#7fe4123b061753f1a58a6cd077ff0bb069ee752d" - integrity sha512-9iI3OOlkyOjLQQ9s+itIJNMRepDhB/96jW3fqduJ2FTPQj1dJjw6Q3QCImF9FE1wmdBs5QSun4FjDSFS8d8JLw== + version "16.11.6" + resolved "https://registry.npmjs.org/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae" + integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w== "@types/node@^10.17.60": version "10.17.60" @@ -1977,10 +1969,10 @@ resolved "https://registry.npmjs.org/@types/punycode/-/punycode-2.1.0.tgz#89e4f3d09b3f92e87a80505af19be7e0c31d4e83" integrity sha512-PG5aLpW6PJOeV2fHRslP4IOMWn+G+Uq8CfnyJ+PDS8ndCbU+soO+fB3NKCKo0p/Jh2Y4aPaiQZsrOXFdzpcA6g== -"@types/semver@^7.3.8": - version "7.3.8" - resolved "https://registry.npmjs.org/@types/semver/-/semver-7.3.8.tgz#508a27995498d7586dcecd77c25e289bfaf90c59" - integrity sha512-D/2EJvAlCEtYFEYmmlGwbGXuK886HzyCc3nZX/tkFTQdEU8jZDAgiv08P162yB17y4ZXZoq7yFAnW4GDBb9Now== +"@types/semver@^7.3.9": + version "7.3.9" + resolved "https://registry.npmjs.org/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc" + integrity sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ== "@types/sinon@^9.0.11": version "9.0.11" @@ -2484,9 +2476,9 @@ astral-regex@^2.0.0: integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== async@^3.2.0: - version "3.2.1" - resolved "https://registry.npmjs.org/async/-/async-3.2.1.tgz#d3274ec66d107a47476a4c49136aacdb00665fc8" - integrity sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg== + version "3.2.2" + resolved "https://registry.npmjs.org/async/-/async-3.2.2.tgz#2eb7671034bb2194d45d30e31e24ec7e7f9670cd" + integrity sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g== asynckit@^0.4.0: version "0.4.0" @@ -2523,9 +2515,9 @@ aws-sdk-mock@^5.4.0: traverse "^0.6.6" aws-sdk@^2.596.0, aws-sdk@^2.848.0, aws-sdk@^2.928.0, aws-sdk@^2.979.0: - version "2.1006.0" - resolved "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1006.0.tgz#fc2f7e267d19a6297f732e19449461bb944682af" - integrity sha512-lwXAy706+1HVQqMnHaahdeBZZbdu6TWrtTY0ydeG0qanwldTFNMLczwnETTZWYsqNAU+wjl1VzmFdMO4gePLNQ== + version "2.1020.0" + resolved "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1020.0.tgz#91fee48f3897e21b0fa6fbd066ea716ac2f0957d" + integrity sha512-cCFLGRfzJn0whOioljFjcFpQTXWB4PTdVnrpNhX2R687W3Yz6WriHxHqIxVnIke1yp9twU00z4kW522U809l0g== dependencies: buffer "4.9.2" events "1.1.1" @@ -2583,14 +2575,14 @@ babel-jest@^27.3.1: slash "^3.0.0" babel-plugin-istanbul@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" - integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ== + version "6.1.1" + resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@istanbuljs/load-nyc-config" "^1.0.0" "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^4.0.0" + istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" babel-plugin-jest-hoist@^26.6.2: @@ -2733,15 +2725,15 @@ browser-process-hrtime@^1.0.0: integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== browserslist@^4.16.6: - version "4.17.3" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.17.3.tgz#2844cd6eebe14d12384b0122d217550160d2d624" - integrity sha512-59IqHJV5VGdcJZ+GZ2hU5n4Kv3YiASzW6Xk5g9tf5a/MAzGeFwgGWU39fVzNIOVcgB3+Gp+kiQu0HEfTVU/3VQ== + version "4.17.6" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.17.6.tgz#c76be33e7786b497f66cad25a73756c8b938985d" + integrity sha512-uPgz3vyRTlEiCv4ee9KlsKgo2V6qPk7Jsn0KAn2OBqbqKo3iNcPEC1Ti6J4dwnz+aIRfEEEuOzC9IBk8tXUomw== dependencies: - caniuse-lite "^1.0.30001264" - electron-to-chromium "^1.3.857" + caniuse-lite "^1.0.30001274" + electron-to-chromium "^1.3.886" escalade "^3.1.1" - node-releases "^1.1.77" - picocolors "^0.2.1" + node-releases "^2.0.1" + picocolors "^1.0.0" bs-logger@0.x: version "0.2.6" @@ -2890,10 +2882,10 @@ camelcase@^6.0.0, camelcase@^6.2.0: resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== -caniuse-lite@^1.0.30001264: - version "1.0.30001265" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz#0613c9e6c922e422792e6fcefdf9a3afeee4f8c3" - integrity sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw== +caniuse-lite@^1.0.30001274: + version "1.0.30001275" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001275.tgz#26f5076629fe4e52bbd245f9046ad7b90aafdf57" + integrity sha512-ihJVvj8RX0kn9GgP43HKhb5q9s2XQn4nEQhdldEJvZhCsuiB2XOq6fAMYQZaN6FPWfsr2qU0cdL0CSbETwbJAg== capture-exit@^2.0.0: version "2.0.0" @@ -3081,19 +3073,10 @@ co@^4.6.0: resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= -codemaker@^1.39.0: - version "1.39.0" - resolved "https://registry.npmjs.org/codemaker/-/codemaker-1.39.0.tgz#d8103f4b587210b1d6aa073d62ffb510ac20bc42" - integrity sha512-1PPD7ZCC05nrkN47elPcno3zm4Md7XSkG52CvIbNsEcXddc0Ma2xgoMZnWPu+Ab6801FunSqov9X4O+OZle95A== - dependencies: - camelcase "^6.2.0" - decamelize "^5.0.1" - fs-extra "^9.1.0" - -codemaker@^1.41.0: - version "1.41.0" - resolved "https://registry.npmjs.org/codemaker/-/codemaker-1.41.0.tgz#814edff6ffd241727794e76f81c5f9e4df135162" - integrity sha512-Iow0udcpshcVmztwSSJDTRhJxTbH0nXU3pxf7iF0gv6+BWC5Nd2aWQ2W5rHECySQPIvmWn4KEpV/SvXgvfl0aA== +codemaker@^1.42.0: + version "1.42.0" + resolved "https://registry.npmjs.org/codemaker/-/codemaker-1.42.0.tgz#dab2ae818e424803d7aa5f837838d7ec5f1dab4b" + integrity sha512-pjLw1YeWKdY09tDmr6HmeZCGd6G+Ku1UP3cK/oX79x5iEL2ZEm8kJrGQisasK6pk/Er75sDZA86c5Cn7sIx4GQ== dependencies: camelcase "^6.2.0" decamelize "^5.0.1" @@ -3270,16 +3253,7 @@ conventional-changelog-config-spec@2.1.0, conventional-changelog-config-spec@^2. resolved "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz#874a635287ef8b581fd8558532bf655d4fb59f2d" integrity sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ== -conventional-changelog-conventionalcommits@4.5.0: - version "4.5.0" - resolved "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.5.0.tgz#a02e0b06d11d342fdc0f00c91d78265ed0bc0a62" - integrity sha512-buge9xDvjjOxJlyxUnar/+6i/aVEVGA7EEh4OafBCXPlLUQPGbRUBhBUveWRxzvR8TEjhKEP4BdepnpG2FSZXw== - dependencies: - compare-func "^2.0.0" - lodash "^4.17.15" - q "^1.5.1" - -conventional-changelog-conventionalcommits@^4.5.0: +conventional-changelog-conventionalcommits@4.6.1, conventional-changelog-conventionalcommits@^4.5.0: version "4.6.1" resolved "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.1.tgz#f4c0921937050674e578dc7875f908351ccf4014" integrity sha512-lzWJpPZhbM1R0PIzkwzGBCnAkH5RKJzJfFQZcl/D+2lsJxAwGnDKBqn/F4C1RD31GJNn8NuKWQzAZDAVXPp2Mw== @@ -3405,10 +3379,10 @@ conventional-commits-filter@^2.0.7: lodash.ismatch "^4.4.0" modify-values "^1.0.0" -conventional-commits-parser@^3.2.0, conventional-commits-parser@^3.2.2: - version "3.2.2" - resolved "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.2.tgz#190fb9900c6e02be0c0bca9b03d57e24982639fd" - integrity sha512-Jr9KAKgqAkwXMRHjxDwO/zOCDKod1XdAESHAGuJX38iZ7ZzVti/tvVoysO0suMsdAObp9NQ2rHSsSbnAqZ5f5g== +conventional-commits-parser@^3.2.0, conventional-commits-parser@^3.2.3: + version "3.2.3" + resolved "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.3.tgz#fc43704698239451e3ef35fd1d8ed644f46bd86e" + integrity sha512-YyRDR7On9H07ICFpRm/igcdjIqebXbvf4Cff+Pf0BrBys1i1EOzx9iFXNlAbdrLAR8jf7bkUYkDAr8pEy0q4Pw== dependencies: JSONStream "^1.0.4" is-text-path "^1.0.1" @@ -3876,10 +3850,10 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -electron-to-chromium@^1.3.857: - version "1.3.867" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.867.tgz#7cb484db4b57c28da0b65c51e434c3a1f3f9aa0d" - integrity sha512-WbTXOv7hsLhjJyl7jBfDkioaY++iVVZomZ4dU6TMe/SzucV6mUAs2VZn/AehBwuZMiNEQDaPuTGn22YK5o+aDw== +electron-to-chromium@^1.3.886: + version "1.3.887" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.887.tgz#b36aeed12a28aaa19460a467823f5bbe1f3c6f06" + integrity sha512-QQUumrEjFDKSVYVdaeBmFdyQGoaV+fCSMyWHvfx/u22bRHSTeBQYt6P4jMY+gFd4kgKB9nqk7RMtWkDB49OYPA== emittery@^0.7.1: version "0.7.2" @@ -4008,107 +3982,113 @@ es6-error@^4.0.1: resolved "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== -esbuild-android-arm64@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.5.tgz#a299a18fd8a016ae19fd948fc659b3f65d1b992f" - integrity sha512-xaNH58b9XRAWT5q0rwA2GNTgJynb51JhdotlNKdLmSCyKXPVlF87yqNLNdmlX/zndzRDrZdtpCWSALdn/J63Ug== - -esbuild-darwin-64@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.5.tgz#01359f2c6921bd2704d0a895f5603ab33f2eeb1b" - integrity sha512-ClGQeUObXIxEpZviGzjTinDikXy9XodojP9jLKwqLCBpZ9wdV3MW7JOmw60fgXgnbNRvkZCqM6uEi+ur8p80Ow== - -esbuild-darwin-arm64@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.5.tgz#1dbe362ebc9afcdab4f9af9bb320dacd73e2aedc" - integrity sha512-qro6M/qzs1dBPh14Ca+5moIkLo2KE3ll3dOpiN7aAususkM1HmqQptCEchi0XwX+6nfqWI96YvVqPJ3DfUUK5A== - -esbuild-freebsd-64@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.5.tgz#fecee59fa491a3f544c731b0c0319bd5a9da7d50" - integrity sha512-vklf7L7fghREEvS1sjAFcxcw/Qqt+Z+L0ySN+pEeb7rA8nPLfRBSFdXAru8UNuHsMWns6CrcZ5eDOKTerZZ5ng== - -esbuild-freebsd-arm64@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.5.tgz#4e98c0e33ed19a63ffd4db87314986b9d93850b5" - integrity sha512-kJoouhbZt4QvjiPak7/Lz57Azok0CgFnNtixiOsqEQXTabIaKmMmnq4qgjD6EBFeU/hvSXDrPe6U8dWhBZOrWQ== - -esbuild-linux-32@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.5.tgz#00083740af7f1416951c634a461e3d01ed812cd0" - integrity sha512-/QufG6tTGKAf42pIYkOVZzKBPxF01xH1kCPyOFJZukZBV/Tk3TeOZfhJIAf7pxl4jhfa+c4Jcdp7CvIAjXrmJg== - -esbuild-linux-64@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.5.tgz#49bd1648fd2070594fe3aad31925108ee2916216" - integrity sha512-NmNFMXEthuFJTFaD4cLhAHCxg+y3uXzo7nqH/WNNSZ8PPY11jbeOvMbdArYlbo2Wy1N/mTHXMcK1synSJj+4Iw== - -esbuild-linux-arm64@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.5.tgz#78ef0f20d2b175403552075cc6d6af80f55a22d8" - integrity sha512-dOS5EZsZj8Lw0TgEj3zy1/slTBbfBw4v7uHEqZXP34dUaRq2oltNaUYIj735CtgB7I5/MXrXEUYkXLqcVfzJQQ== - -esbuild-linux-arm@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.5.tgz#27c4e92a6597376a8c3fe8c79177d72ba77f8500" - integrity sha512-69nQmbKLBRaAxf88diyaOyarrI7yIdBkZ8bmVzQ7XVWneY+nYIcGtugTSOs5znNGfPqGOElAjh1lX+0sGYHNpA== - -esbuild-linux-mips64le@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.5.tgz#4061cbef41f96e4a176bebf7e7b2d6d397e05e86" - integrity sha512-dmKA8ZI/nHwpxIQW/L5crk7Ac4wJJ2Kquvdo1CdXPW1UljMyKUDuHc4K7D1Iws5igqJmNO6U5vdRUKrdnIov6Q== - -esbuild-linux-ppc64le@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.5.tgz#290a5caca6751b8c80c5d075cafe857102263118" - integrity sha512-HkVGKkPL3XOhJqNOJ752Q1li5zeidrJHv+XWX6qCnCipNsVuGqaAGfxeWbL/+A/giolMlP7wvAuiKgoe+a5UAw== - -esbuild-openbsd-64@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.5.tgz#223eb2730a6fede7930a2b44b0b1d5b067a3cef5" - integrity sha512-BuOZzmdsdreSs0qDgbuiEhSbUDDW2Wyp4VtpNGBmaLwPMHftdprOJXLkeFud3HlnRB2n9qdiTVKg1B8YqMogSw== - -esbuild-sunos-64@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.5.tgz#6f121ac285c298f09467748607cc0496ebbfd23e" - integrity sha512-YJNB6Og1QYAPikvYDbqvk5xCqr6WL2i5cRWPGGgWOEItQPnq6gFsWogS3DiYM8TQKe50KRiD3Lwu7eNYsdPO4w== - -esbuild-windows-32@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.5.tgz#0da6d240152f76f3dd764c0bb0391d894acd403f" - integrity sha512-CigOlBSKsZ61IS+FyhD3luqCpl7LN9ntDaBZXumls/0IZ/8BJ5txqw4a6pv4LtnfIgt0ixGHSH7kAUmApw/HAw== - -esbuild-windows-64@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.5.tgz#330266a2c95b26c2f949e9de9b0c366924fec53f" - integrity sha512-pg2BZXLpcPcrIcmToGapLRExzj6sm0VmQlqlmnMOtIJh0YQV9c0CRbhfIT0gYvJqCz5JEGiRvYpArRlxWADN3Q== - -esbuild-windows-arm64@0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.5.tgz#e0501e82b88f4165cce7cd017db83428f459f775" - integrity sha512-KKRDmUOIE4oCvJp0I4p4QyazK2X79spF29vsZr2U8qHhmxbTLSQWvYmb2WlF5Clb1URRsX0L013rhwHx1SEu0w== - -esbuild@^0.13.5: - version "0.13.5" - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.13.5.tgz#f9add2c2c899a9023dd7f7b64c452320f008aa79" - integrity sha512-Q9/f1njsZaO+Qqe3dqAdtu4zGHNZIbcEtdg44/NooyPhqCerns4FeC1UPYeB4pKD08iDuWcmyINFJTqpdN+pqg== +esbuild-android-arm64@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.12.tgz#e1f199dc05405cdc6670c00fb6c793822bf8ae4c" + integrity sha512-TSVZVrb4EIXz6KaYjXfTzPyyRpXV5zgYIADXtQsIenjZ78myvDGaPi11o4ZSaHIwFHsuwkB6ne5SZRBwAQ7maw== + +esbuild-darwin-64@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.12.tgz#f5c59e622955c01f050e5a7ac9c1d41db714b94d" + integrity sha512-c51C+N+UHySoV2lgfWSwwmlnLnL0JWj/LzuZt9Ltk9ub1s2Y8cr6SQV5W3mqVH1egUceew6KZ8GyI4nwu+fhsw== + +esbuild-darwin-arm64@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.12.tgz#8abae74c2956a8aa568fc52c78829338c4a4b988" + integrity sha512-JvAMtshP45Hd8A8wOzjkY1xAnTKTYuP/QUaKp5eUQGX+76GIie3fCdUUr2ZEKdvpSImNqxiZSIMziEiGB5oUmQ== + +esbuild-freebsd-64@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.12.tgz#6ad2ab8c0364ee7dd2d6e324d876a8e60ae75d12" + integrity sha512-r6On/Skv9f0ZjTu6PW5o7pdXr8aOgtFOEURJZYf1XAJs0IQ+gW+o1DzXjVkIoT+n1cm3N/t1KRJfX71MPg/ZUA== + +esbuild-freebsd-arm64@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.12.tgz#6f38155f4c300ac4c8adde1fde3cc6a4440a8294" + integrity sha512-F6LmI2Q1gii073kmBE3NOTt/6zLL5zvZsxNLF8PMAwdHc+iBhD1vzfI8uQZMJA1IgXa3ocr3L3DJH9fLGXy6Yw== + +esbuild-linux-32@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.12.tgz#b1d15e330188a8c21de75c3f0058628a3eefade7" + integrity sha512-U1UZwG3UIwF7/V4tCVAo/nkBV9ag5KJiJTt+gaCmLVWH3bPLX7y+fNlhIWZy8raTMnXhMKfaTvWZ9TtmXzvkuQ== + +esbuild-linux-64@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.12.tgz#25bd64b66162b02348e32d8f12e4c9ee61f1d070" + integrity sha512-YpXSwtu2NxN3N4ifJxEdsgd6Q5d8LYqskrAwjmoCT6yQnEHJSF5uWcxv783HWN7lnGpJi9KUtDvYsnMdyGw71Q== + +esbuild-linux-arm64@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.12.tgz#ba582298457cc5c9ac823a275de117620c06537f" + integrity sha512-sgDNb8kb3BVodtAlcFGgwk+43KFCYjnFOaOfJibXnnIojNWuJHpL6aQJ4mumzNWw8Rt1xEtDQyuGK9f+Y24jGA== + +esbuild-linux-arm@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.12.tgz#6bc81c957bff22725688cc6359c29a25765be09b" + integrity sha512-SyiT/JKxU6J+DY2qUiSLZJqCAftIt3uoGejZ0HDnUM2MGJqEGSGh7p1ecVL2gna3PxS4P+j6WAehCwgkBPXNIw== + +esbuild-linux-mips64le@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.12.tgz#ef3c4aba3e585d847cbade5945a8b4a5c62c7ce2" + integrity sha512-qQJHlZBG+QwVIA8AbTEtbvF084QgDi4DaUsUnA+EolY1bxrG+UyOuGflM2ZritGhfS/k7THFjJbjH2wIeoKA2g== + +esbuild-linux-ppc64le@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.12.tgz#a21fb64e80c38bef06122e48283990fc6db578e1" + integrity sha512-2dSnm1ldL7Lppwlo04CGQUpwNn5hGqXI38OzaoPOkRsBRWFBozyGxTFSee/zHFS+Pdh3b28JJbRK3owrrRgWNw== + +esbuild-netbsd-64@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.12.tgz#1ea7fc8cfce88a20a4047b867ef184049a6641ae" + integrity sha512-D4raxr02dcRiQNbxOLzpqBzcJNFAdsDNxjUbKkDMZBkL54Z0vZh4LRndycdZAMcIdizC/l/Yp/ZsBdAFxc5nbA== + +esbuild-openbsd-64@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.12.tgz#adde32f2f1b05dc4bd4fc544d6ea5a4379f9ca4d" + integrity sha512-KuLCmYMb2kh05QuPJ+va60bKIH5wHL8ypDkmpy47lzwmdxNsuySeCMHuTv5o2Af1RUn5KLO5ZxaZeq4GEY7DaQ== + +esbuild-sunos-64@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.12.tgz#a7ecaf52b7364fbee76dc8aa707fa3e1cff3342c" + integrity sha512-jBsF+e0woK3miKI8ufGWKG3o3rY9DpHvCVRn5eburMIIE+2c+y3IZ1srsthKyKI6kkXLvV4Cf/E7w56kLipMXw== + +esbuild-windows-32@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.12.tgz#a8756033dc905c4b7bea19be69f7ee68809f8770" + integrity sha512-L9m4lLFQrFeR7F+eLZXG82SbXZfUhyfu6CexZEil6vm+lc7GDCE0Q8DiNutkpzjv1+RAbIGVva9muItQ7HVTkQ== + +esbuild-windows-64@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.12.tgz#ae694aa66ca078acb8509b2da31197ed1f40f798" + integrity sha512-k4tX4uJlSbSkfs78W5d9+I9gpd+7N95W7H2bgOMFPsYREVJs31+Q2gLLHlsnlY95zBoPQMIzHooUIsixQIBjaQ== + +esbuild-windows-arm64@0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.12.tgz#782c5a8bd6d717ea55aaafe648f9926ca36a4a88" + integrity sha512-2tTv/BpYRIvuwHpp2M960nG7uvL+d78LFW/ikPItO+2GfK51CswIKSetSpDii+cjz8e9iSPgs+BU4o8nWICBwQ== + +esbuild@^0.13.12: + version "0.13.12" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.13.12.tgz#9cac641594bf03cf34145258c093d743ebbde7ca" + integrity sha512-vTKKUt+yoz61U/BbrnmlG9XIjwpdIxmHB8DlPR0AAW6OdS+nBQBci6LUHU2q9WbBobMEIQxxDpKbkmOGYvxsow== optionalDependencies: - esbuild-android-arm64 "0.13.5" - esbuild-darwin-64 "0.13.5" - esbuild-darwin-arm64 "0.13.5" - esbuild-freebsd-64 "0.13.5" - esbuild-freebsd-arm64 "0.13.5" - esbuild-linux-32 "0.13.5" - esbuild-linux-64 "0.13.5" - esbuild-linux-arm "0.13.5" - esbuild-linux-arm64 "0.13.5" - esbuild-linux-mips64le "0.13.5" - esbuild-linux-ppc64le "0.13.5" - esbuild-openbsd-64 "0.13.5" - esbuild-sunos-64 "0.13.5" - esbuild-windows-32 "0.13.5" - esbuild-windows-64 "0.13.5" - esbuild-windows-arm64 "0.13.5" + esbuild-android-arm64 "0.13.12" + esbuild-darwin-64 "0.13.12" + esbuild-darwin-arm64 "0.13.12" + esbuild-freebsd-64 "0.13.12" + esbuild-freebsd-arm64 "0.13.12" + esbuild-linux-32 "0.13.12" + esbuild-linux-64 "0.13.12" + esbuild-linux-arm "0.13.12" + esbuild-linux-arm64 "0.13.12" + esbuild-linux-mips64le "0.13.12" + esbuild-linux-ppc64le "0.13.12" + esbuild-netbsd-64 "0.13.12" + esbuild-openbsd-64 "0.13.12" + esbuild-sunos-64 "0.13.12" + esbuild-windows-32 "0.13.12" + esbuild-windows-64 "0.13.12" + esbuild-windows-arm64 "0.13.12" escalade@^3.1.1: version "3.1.1" @@ -4179,9 +4159,9 @@ eslint-import-resolver-typescript@^2.5.0: tsconfig-paths "^3.9.0" eslint-module-utils@^2.7.0: - version "2.7.0" - resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.0.tgz#9e97c12688113401259b39d960e6a1f09f966435" - integrity sha512-hqSE88MmHl3ru9SYvDyGrlo0JwROlf9fiEMplEV7j/EAuq9iSlIlyCFbBT6pdULQBSnBYtYKiMLps+hKkyP7Gg== + version "2.7.1" + resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz#b435001c9f8dd4ab7f6d0efcae4b9696d4c24b7c" + integrity sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ== dependencies: debug "^3.2.7" find-up "^2.1.0" @@ -4360,9 +4340,9 @@ estraverse@^4.1.1, estraverse@^4.2.0: integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + version "5.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== esutils@^2.0.2: version "2.0.3" @@ -4523,14 +4503,14 @@ extsprintf@1.3.0: integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + version "1.4.1" + resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== -fast-check@^2.18.0: - version "2.18.0" - resolved "https://registry.npmjs.org/fast-check/-/fast-check-2.18.0.tgz#0337d82e7d7cb4eed5806c42b9e61ed0fb6592b2" - integrity sha512-7KKUw0wtAJOVrJ1DgmFILd9EmeqMLGtfe5HoEtkYZfYIxohm6Zy7zPq1Zl8t6tPL8A3e86YZrheyGg2m5j8cLA== +fast-check@^2.19.0: + version "2.19.0" + resolved "https://registry.npmjs.org/fast-check/-/fast-check-2.19.0.tgz#e87666450e417cd163a564bd546ee763d27c0f19" + integrity sha512-qY4Rc0Nljl2aJx2qgbK3o6wPBjL9QvhKdD/VqJgaKd5ewn8l4ViqgDpUHJq/JkHTBnFKomYYvkFkOYGDVTT8bw== dependencies: pure-rand "^5.0.0" @@ -4705,9 +4685,9 @@ flatted@^3.1.0: integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA== follow-redirects@^1.11.0, follow-redirects@^1.14.0: - version "1.14.4" - resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz#838fdf48a8bbdd79e52ee51fb1c94e3ed98b9379" - integrity sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g== + version "1.14.5" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381" + integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA== for-in@^1.0.2: version "1.0.2" @@ -5037,9 +5017,9 @@ globals@^11.1.0: integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.6.0, globals@^13.9.0: - version "13.11.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz#40ef678da117fe7bd2e28f1fab24951bd0255be7" - integrity sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g== + version "13.12.0" + resolved "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e" + integrity sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg== dependencies: type-fest "^0.20.2" @@ -5467,9 +5447,9 @@ is-ci@^2.0.0: ci-info "^2.0.0" is-core-module@^2.2.0, is-core-module@^2.5.0, is-core-module@^2.7.0: - version "2.7.0" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3" - integrity sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ== + version "2.8.0" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" + integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== dependencies: has "^1.0.3" @@ -5760,10 +5740,10 @@ isstream@~0.1.2: resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.0.0-alpha.1: - version "3.0.2" - resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.2.tgz#36786d4d82aad2ea5911007e255e2da6b5f80d86" - integrity sha512-o5+eTUYzCJ11/+JhW5/FUCdfsdoYVdQ/8I/OveE2XsjehYn5DdeSnNQAbjYaO8gQ6hvGTN6GM6ddQqpTVG5j8g== +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.0.0-alpha.1, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== istanbul-lib-hook@^3.0.0: version "3.0.0" @@ -5782,6 +5762,17 @@ istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: istanbul-lib-coverage "^3.0.0" semver "^6.3.0" +istanbul-lib-instrument@^5.0.4: + version "5.1.0" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" + integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + istanbul-lib-processinfo@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz#e1426514662244b2f25df728e8fd1ba35fe53b9c" @@ -5814,9 +5805,9 @@ istanbul-lib-source-maps@^4.0.0: source-map "^0.6.1" istanbul-reports@^3.0.2: - version "3.0.4" - resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.4.tgz#5c38ce8136edf484c0fcfbf7514aafb0363ed1db" - integrity sha512-bFjUnc95rHjdCR63WMHUS7yfJJh8T9IPSWavvR02hhjVwezWALZ5axF9EqjmwZHpXqkzbgAMP8DmAtiyNxrdrQ== + version "3.0.5" + resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz#a2580107e71279ea6d661ddede929ffc6d693384" + integrity sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" @@ -6692,57 +6683,57 @@ jsesc@^2.5.1: resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== -jsii-diff@^1.41.0: - version "1.41.0" - resolved "https://registry.npmjs.org/jsii-diff/-/jsii-diff-1.41.0.tgz#ef88aa98081e4bb41f13d24074fce9bee1574d24" - integrity sha512-LTfqGh0f0fUuWu8DBkEUgl0fteIBfzyEiExcqLBXbztg/8JRbt3DYUr63hHULJj4O/rnRTaaYNH7oT1sg4gpSQ== +jsii-diff@^1.42.0: + version "1.42.0" + resolved "https://registry.npmjs.org/jsii-diff/-/jsii-diff-1.42.0.tgz#08fab1b90575239daa5f3ae853e2e921d4d26e90" + integrity sha512-ErMGIBt14Z12b2/FGCv8/H8X19nKr/fcq0UA3xJ6/dIvJyATGNlzxcWHmTUcSoaIxlKjFHYErPvZNUrJslbH4Q== dependencies: - "@jsii/check-node" "1.41.0" - "@jsii/spec" "^1.41.0" + "@jsii/check-node" "1.42.0" + "@jsii/spec" "^1.42.0" fs-extra "^9.1.0" - jsii-reflect "^1.41.0" + jsii-reflect "^1.42.0" log4js "^6.3.0" typescript "~3.9.10" yargs "^16.2.0" -jsii-pacmak@^1.41.0: - version "1.41.0" - resolved "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.41.0.tgz#b94575f4a7c658d3fbd1c5f30876ce53a22ed126" - integrity sha512-B3ohEObc2xSnWoawK0q4qVkxa9Dh4A+x1y9K31AAS5jGbhdjbdS/FfphlUbukIoSR0NBJLgJg9pT+h/PIlUqdA== +jsii-pacmak@^1.42.0: + version "1.42.0" + resolved "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.42.0.tgz#eee5c15222042b85340ce8e497a70c8c4a48fba6" + integrity sha512-JqgvmI2gIEedB+BvfG7kXkxc5o38TI1VwdQTgUW5hbr0631AgKs/hrpWqcUQ9aNQFwTyzaKWPb0vF8bDitCF6A== dependencies: - "@jsii/check-node" "1.41.0" - "@jsii/spec" "^1.41.0" + "@jsii/check-node" "1.42.0" + "@jsii/spec" "^1.42.0" clone "^2.1.2" - codemaker "^1.41.0" + codemaker "^1.42.0" commonmark "^0.30.0" escape-string-regexp "^4.0.0" fs-extra "^9.1.0" - jsii-reflect "^1.41.0" - jsii-rosetta "^1.41.0" + jsii-reflect "^1.42.0" + jsii-rosetta "^1.42.0" semver "^7.3.5" spdx-license-list "^6.4.0" xmlbuilder "^15.1.1" yargs "^16.2.0" -jsii-reflect@^1.41.0: - version "1.41.0" - resolved "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.41.0.tgz#3c8fbcbbb7e2853b7c2a59384524ccbd2d9d832c" - integrity sha512-KQaAXQ38hyREs7IuBChZldSyvW1gezHRezGKGc6BZILwlIX330F3GIauJ2rJKJinh/Lo/DlMfd0k1mxdBz/W9A== +jsii-reflect@^1.42.0: + version "1.42.0" + resolved "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.42.0.tgz#cab5e6ef64b0ae678efaabf10cefdb76c55818b5" + integrity sha512-gwVZqk2vEnEEYfOU2awHaqZqJd9lA+rEBrlaiMlun42Ve2ZY5HMDBtP/DxgFJG68LCzdlS0xQuHleuBlLYWy0A== dependencies: - "@jsii/check-node" "1.41.0" - "@jsii/spec" "^1.41.0" + "@jsii/check-node" "1.42.0" + "@jsii/spec" "^1.42.0" colors "^1.4.0" fs-extra "^9.1.0" - oo-ascii-tree "^1.41.0" + oo-ascii-tree "^1.42.0" yargs "^16.2.0" -jsii-rosetta@^1.41.0: - version "1.41.0" - resolved "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.41.0.tgz#ddf3f49738489d8330aa4eff96f0a9c8c811792d" - integrity sha512-wSjMqRBhjBKB8kx+gIXE7YXoiOlTFH/ugksHz2K4UwqriPmEHue8b7LkV3d/mD8xuhXWS6ekGAz67Gd1RSB7Sg== +jsii-rosetta@^1.42.0: + version "1.42.0" + resolved "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.42.0.tgz#84f80a91446b0a6e4ed8c981b1807eb7fce0b79e" + integrity sha512-F7GLNdoHBAYN4eqw7c6Tv12lqGOoMazsjuXDJRubjjbbwZ0tM6a78rHhrZwE4w1XV7mIkTxKmkj4DnbSIPW8wg== dependencies: - "@jsii/check-node" "1.41.0" - "@jsii/spec" "^1.41.0" + "@jsii/check-node" "1.42.0" + "@jsii/spec" "^1.42.0" "@xmldom/xmldom" "^0.7.5" commonmark "^0.30.0" fs-extra "^9.1.0" @@ -6751,13 +6742,13 @@ jsii-rosetta@^1.41.0: workerpool "^6.1.5" yargs "^16.2.0" -jsii@^1.41.0: - version "1.41.0" - resolved "https://registry.npmjs.org/jsii/-/jsii-1.41.0.tgz#926e033d7ba57c65d6d070dee1d4d19da0fa9508" - integrity sha512-5pjfWjSaMzE+mkpW//llBSGLcXJGNjE0KFSf73USPZTfJC09dBEJ4KJM85SogCNnWHwG5QecEpZStxNvt8GI7g== +jsii@^1.42.0: + version "1.42.0" + resolved "https://registry.npmjs.org/jsii/-/jsii-1.42.0.tgz#2f8a534c9f981149f4455ec1272bfab7ba1fa6a3" + integrity sha512-Ctbaudn3t3wJ3ihsgCLuEjQGM5CfZl1PJDXfOlELUV6ELwTbvT3TCbyVdt/CCWTOObigQR8OftAB3jl7ymqd3w== dependencies: - "@jsii/check-node" "1.41.0" - "@jsii/spec" "^1.41.0" + "@jsii/check-node" "1.42.0" + "@jsii/spec" "^1.42.0" case "^1.6.3" colors "^1.4.0" deep-equal "^2.0.5" @@ -6951,9 +6942,9 @@ lambda-tester@^3.6.0: vandium-utils "^1.1.1" lazystream@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" - integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= + version "1.0.1" + resolved "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638" + integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw== dependencies: readable-stream "^2.0.5" @@ -7293,12 +7284,12 @@ make-runnable@^1.3.10: bluebird "^3.5.0" yargs "^16.2.0" -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" - integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== dependencies: - tmpl "1.0.x" + tmpl "1.0.5" map-cache@^0.2.2: version "0.2.2" @@ -7450,10 +7441,10 @@ mime-types@^2.1.12, mime-types@~2.1.19: dependencies: mime-db "1.50.0" -mime@^2.5.2: - version "2.5.2" - resolved "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" - integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== +mime@^2.6.0: + version "2.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== mimic-fn@^2.1.0: version "2.1.0" @@ -7707,10 +7698,10 @@ nise@^5.1.0: just-extend "^4.0.2" path-to-regexp "^1.7.0" -nock@^13.1.3: - version "13.1.3" - resolved "https://registry.npmjs.org/nock/-/nock-13.1.3.tgz#110b005965654a8ffb798e87bad18b467bff15f9" - integrity sha512-YKj0rKQWMGiiIO+Y65Ut8OEgYM3PplLU2+GAhnPmqZdBd6z5IskgdBqWmjzA6lH3RF0S2a3wiAlrMOF5Iv2Jeg== +nock@^13.1.4: + version "13.1.4" + resolved "https://registry.npmjs.org/nock/-/nock-13.1.4.tgz#367c917d4c532a889404b85ade92762c29e80262" + integrity sha512-hr5+mknLpIbTOXifB13lx9mAKF1zQPUCMh53Galx79ic5opvNOd55jiB0iGCp2xqh+hwnFbNE/ddBKHsJNQrbw== dependencies: debug "^4.1.0" json-stringify-safe "^5.0.1" @@ -7718,9 +7709,9 @@ nock@^13.1.3: propagate "^2.0.0" node-fetch@^2.6.1: - version "2.6.5" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd" - integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ== + version "2.6.6" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89" + integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA== dependencies: whatwg-url "^5.0.0" @@ -7786,10 +7777,10 @@ node-preload@^0.2.1: dependencies: process-on-spawn "^1.0.0" -node-releases@^1.1.77: - version "1.1.77" - resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.77.tgz#50b0cfede855dd374e7585bf228ff34e57c1c32e" - integrity sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ== +node-releases@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" + integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== nopt@^4.0.1: version "4.0.3" @@ -8096,10 +8087,10 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -oo-ascii-tree@^1.41.0: - version "1.41.0" - resolved "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.41.0.tgz#88883d2b8446ded7082a96faf3294e1092aeeb46" - integrity sha512-WxQIFO+JMCIJBlIMUATsp+PW5kqDMy2CD7u5uC9qQk29XInUMO+RN7/QVZJsPHO3o73eJFN9CFc9XDWQJwVKBQ== +oo-ascii-tree@^1.42.0: + version "1.42.0" + resolved "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.42.0.tgz#e9ab47834b004ec2789a5e8b3e477b3fac770804" + integrity sha512-qlynjsWdGidfoWT2uEIr0iNsNmHU2ZhKwtjpJw4VSd3jlxoDpWDDmd5cud/ZBhFT2F1UFSbz+Gl9YtlPYMgQ5Q== open@^7.4.2: version "7.4.2" @@ -8471,10 +8462,10 @@ performance-now@^2.1.0: resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picocolors@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" - integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== picomatch@^2.0.4, picomatch@^2.2.3: version "2.3.0" @@ -9526,15 +9517,15 @@ stack-utils@^2.0.2, stack-utils@^2.0.3: dependencies: escape-string-regexp "^2.0.0" -standard-version@^9.3.1: - version "9.3.1" - resolved "https://registry.npmjs.org/standard-version/-/standard-version-9.3.1.tgz#786c16c318847f58a31a2434f97e8db33a635853" - integrity sha512-5qMxXw/FxLouC5nANyx/5RY1kiorJx9BppUso8gN07MG64q2uLRmrPb4KfXp3Ql4s/gxjZwZ89e0FwxeLubGww== +standard-version@^9.3.2: + version "9.3.2" + resolved "https://registry.npmjs.org/standard-version/-/standard-version-9.3.2.tgz#28db8c1be66fd2d736f28f7c5de7619e64cd6dab" + integrity sha512-u1rfKP4o4ew7Yjbfycv80aNMN2feTiqseAhUhrrx2XtdQGmu7gucpziXe68Z4YfHVqlxVEzo4aUA0Iu3VQOTgQ== dependencies: chalk "^2.4.2" conventional-changelog "3.1.24" conventional-changelog-config-spec "2.1.0" - conventional-changelog-conventionalcommits "4.5.0" + conventional-changelog-conventionalcommits "4.6.1" conventional-recommended-bump "6.1.0" detect-indent "^6.0.0" detect-newline "^3.1.0" @@ -9582,7 +9573,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -string-width@*, string-width@^1.0.1, "string-width@^1.0.2 || 2", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +string-width@*, string-width@^1.0.1, "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -9873,7 +9864,7 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" -tmpl@1.0.x: +tmpl@1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== @@ -9981,9 +9972,9 @@ ts-mock-imports@^1.3.7: integrity sha512-zy4B3QSGaOhjaX9j0h9YKwM1oHG4Kd1KIUJBeXlXIQrFnATNLgh4+NyRcaAHsPeqwe3TWeRtHXkNXPxySEKk3w== ts-node@^10.2.1: - version "10.3.0" - resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.3.0.tgz#a797f2ed3ff50c9a5d814ce400437cb0c1c048b4" - integrity sha512-RYIy3i8IgpFH45AX4fQHExrT8BxDeKTdC83QFJkNzkvt8uFB6QJ8XMyhynYiKMLxt9a7yuXaDBZNOYS3XjDcYw== + version "10.4.0" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7" + integrity sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A== dependencies: "@cspotcode/source-map-support" "0.7.0" "@tsconfig/node10" "^1.0.7" @@ -10149,9 +10140,9 @@ uc.micro@^1.0.1, uc.micro@^1.0.5: integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== uglify-js@^3.1.4: - version "3.14.2" - resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz#d7dd6a46ca57214f54a2d0a43cad0f35db82ac99" - integrity sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A== + version "3.14.3" + resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.3.tgz#c0f25dfea1e8e5323eccf59610be08b6043c15cf" + integrity sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g== uid-number@0.0.6: version "0.0.6" @@ -10347,9 +10338,9 @@ verror@1.10.0: extsprintf "^1.2.0" vm2@^3.9.3: - version "3.9.4" - resolved "https://registry.npmjs.org/vm2/-/vm2-3.9.4.tgz#2e118290fefe7bd8ea09ebe2f5faf53730dbddaa" - integrity sha512-sOdharrJ7KEePIpHekiWaY1DwgueuiBeX/ZBJUPgETsVlJsXuEx0K0/naATq2haFvJrvZnRiORQRubR0b7Ye6g== + version "3.9.5" + resolved "https://registry.npmjs.org/vm2/-/vm2-3.9.5.tgz#5288044860b4bbace443101fcd3bddb2a0aa2496" + integrity sha512-LuCAHZN75H9tdrAiLFf030oW7nJV5xwNMuk1ymOZwopmuK3d2H4L1Kv4+GFHgarKiLfXXLFU+7LDABHnwOkWng== w3c-hr-time@^1.0.2: version "1.0.2" @@ -10366,11 +10357,11 @@ w3c-xmlserializer@^2.0.0: xml-name-validator "^3.0.0" walker@^1.0.7, walker@~1.0.5: - version "1.0.7" - resolved "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" - integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + version "1.0.8" + resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== dependencies: - makeerror "1.0.x" + makeerror "1.0.12" wcwidth@^1.0.0: version "1.0.1" @@ -10476,11 +10467,11 @@ which@^2.0.1, which@^2.0.2: isexe "^2.0.0" wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + version "1.1.5" + resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== dependencies: - string-width "^1.0.2 || 2" + string-width "^1.0.2 || 2 || 3 || 4" windows-release@^3.1.0: version "3.3.3" From e4616010c1915206758be3bf4cd6da9f14d2101a Mon Sep 17 00:00:00 2001 From: kaylanm <1063516+kaylanm@users.noreply.github.com> Date: Wed, 3 Nov 2021 11:05:45 -0400 Subject: [PATCH 24/70] feat(eks): expose FargateCluster's defaultProfile (#17130) Expose FargateCluster's defaultProfile. Fixes #16149 ---- *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-eks/README.md | 2 ++ packages/@aws-cdk/aws-eks/lib/fargate-cluster.ts | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-eks/README.md b/packages/@aws-cdk/aws-eks/README.md index 3b04f5d9e7f61..cd6e324ecf788 100644 --- a/packages/@aws-cdk/aws-eks/README.md +++ b/packages/@aws-cdk/aws-eks/README.md @@ -342,6 +342,8 @@ const cluster = new eks.FargateCluster(this, 'MyCluster', { }); ``` +`FargateCluster` will create a default `FargateProfile` which can be accessed via the cluster's `defaultProfile` property. The created profile can also be customized by passing options as with `addFargateProfile`. + **NOTE**: Classic Load Balancers and Network Load Balancers are not supported on pods running on Fargate. For ingress, we recommend that you use the [ALB Ingress Controller](https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html) diff --git a/packages/@aws-cdk/aws-eks/lib/fargate-cluster.ts b/packages/@aws-cdk/aws-eks/lib/fargate-cluster.ts index 11036875a9d30..022d6bc6ecdbf 100644 --- a/packages/@aws-cdk/aws-eks/lib/fargate-cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/fargate-cluster.ts @@ -1,6 +1,6 @@ import { Construct } from 'constructs'; import { Cluster, ClusterOptions, CoreDnsComputeType } from './cluster'; -import { FargateProfileOptions } from './fargate-profile'; +import { FargateProfile, FargateProfileOptions } from './fargate-profile'; /** * Configuration props for EKS Fargate. @@ -23,6 +23,11 @@ export interface FargateClusterProps extends ClusterOptions { * `addFargateProfile`. */ export class FargateCluster extends Cluster { + /** + * Fargate Profile that was created with the cluster. + */ + public readonly defaultProfile: FargateProfile; + constructor(scope: Construct, id: string, props: FargateClusterProps) { super(scope, id, { ...props, @@ -31,7 +36,7 @@ export class FargateCluster extends Cluster { version: props.version, }); - this.addFargateProfile( + this.defaultProfile = this.addFargateProfile( props.defaultProfile?.fargateProfileName ?? (props.defaultProfile ? 'custom' : 'default'), props.defaultProfile ?? { selectors: [ From e2f2a972df588ab760bcd7b6f3c9d2f49741f489 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Wed, 3 Nov 2021 16:59:36 +0100 Subject: [PATCH 25/70] chore: activate 'rosetta infuse' feature (#17191) (#17305) `jsii-rosetta infuse` will modify all the assemblies in-place to add examples to types that don't have examples yet. This feature depends on jsii 1.41, and should not be merged before jsii has been upgraded to that version (either by #17187 or by #17190). Depends-On: #17190 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- pack.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pack.sh b/pack.sh index 168a17f972406..3c2d7dbce6c1a 100755 --- a/pack.sh +++ b/pack.sh @@ -39,12 +39,17 @@ function lerna_scopes() { # Compile examples with respect to "decdk" directory, as all packages will # be symlinked there so they can all be included. echo "Extracting code samples" >&2 -node --experimental-worker $(which $ROSETTA) \ +$ROSETTA extract \ --compile \ --output samples.tabl.json \ --directory packages/decdk \ $(cat $TMPDIR/jsii.txt) +echo "Infusing examples back into assemblies" >&2 +$ROSETTA infuse \ + samples.tabl.json \ + $(cat $TMPDIR/jsii.txt) + # Jsii packaging (all at once using jsii-pacmak) echo "Packaging jsii modules" >&2 $PACMAK \ From 89d8fc7ef9649c66a233ee2207b3e7999b3c87ab Mon Sep 17 00:00:00 2001 From: Paolo Lazzari Date: Wed, 3 Nov 2021 17:26:26 +0000 Subject: [PATCH 26/70] docs: fix typo in CONTRIBUTING.md (#17303) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b6568c7be1263..5af7da4ecc25a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -113,7 +113,7 @@ $ yarn build $ yarn test ``` -However, if you wish to build the the entire repository, the following command will achieve this. +However, if you wish to build the entire repository, the following command will achieve this. ```console cd From e05bd012d0d3e956dfe75418cc9a428d57bf1ad6 Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Wed, 3 Nov 2021 20:20:03 +0200 Subject: [PATCH 27/70] chore: integ failures due to unbound variable on `FRAMEWORK_VERSION` (#17308) Follow up fix for https://github.com/aws/aws-cdk/pull/17276 ```console export CANDIDATE_VERSION=1.131.0-rc.0 -- 690 | + CANDIDATE_VERSION=1.131.0-rc.0 691 | /codebuild/output/src644443490/src/package/test/integ/run-against-dist: line 29: FRAMEWORK_VERSION: unbound variable 692 | ++ run_traps ``` ---- *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-dist | 2 +- packages/aws-cdk/test/integ/run-against-release | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk/test/integ/run-against-dist b/packages/aws-cdk/test/integ/run-against-dist index 0cd683b112dca..c7ade80dbb1f3 100755 --- a/packages/aws-cdk/test/integ/run-against-dist +++ b/packages/aws-cdk/test/integ/run-against-dist @@ -26,7 +26,7 @@ fi export CANDIDATE_VERSION=$(node -p "require('${dist_root}/build.json').version") # FRAMEWORK_VERSION is the version that will be 'npm install'ed by the tests -if [[ "${FRAMEWORK_VERSION}" = "" ]]; then +if [[ "${FRAMEWORK_VERSION:-}" = "" ]]; then export FRAMEWORK_VERSION=${CANDIDATE_VERSION} fi export TEST_RUNNER=dist diff --git a/packages/aws-cdk/test/integ/run-against-release b/packages/aws-cdk/test/integ/run-against-release index b3ebe1e4fc409..366fd081f5380 100755 --- a/packages/aws-cdk/test/integ/run-against-release +++ b/packages/aws-cdk/test/integ/run-against-release @@ -15,7 +15,7 @@ mkdir -p $npmws (cd $npmws && npm install aws-cdk) # FRAMEWORK_VERSION is the version that will be 'npm install'ed by the tests -if [[ "${FRAMEWORK_VERSION}" = "" ]]; then +if [[ "${FRAMEWORK_VERSION:-}" = "" ]]; then cli_version=$(cd $npmws && node -p "require('aws-cdk/package.json').version") export FRAMEWORK_VERSION=${cli_version} fi From af61fa64003e74c680be6dd2437d2dc40cfe4552 Mon Sep 17 00:00:00 2001 From: Madeline Kusters <80541297+madeline-k@users.noreply.github.com> Date: Wed, 3 Nov 2021 12:14:31 -0700 Subject: [PATCH 28/70] chore(CDK V2 canaries): allow canary tests to run with a specific aws-cdk version (#17285) If an environment variable, `$RELEASE_TAG` is defined, it will be appended to the end of the `npm install aws-cdk@` command. This will allow us to run canaries that test against v2 by specifying `RELEASE_TAG=next` in the environment variables. If `$RELEASE_TAG` is not defined, `npm install aws-cdk@latest` will be used. This PR also includes a comment in `release-notes.ts` that the v2 publishing verification canary is dependent on the format of the release notes. part of #16593, see https://github.com/cdklabs/cdk-ops/pull/1769 ---- *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 | 2 +- tools/@aws-cdk/cdk-release/lib/release-notes.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk/test/integ/run-against-release b/packages/aws-cdk/test/integ/run-against-release index 366fd081f5380..1e4c0a8b3aba1 100755 --- a/packages/aws-cdk/test/integ/run-against-release +++ b/packages/aws-cdk/test/integ/run-against-release @@ -12,7 +12,7 @@ rm -rf $npmws mkdir -p $npmws # Install the CLI and put it on the PATH -(cd $npmws && npm install aws-cdk) +(cd $npmws && npm install aws-cdk@${RELEASE_TAG:-latest}) # FRAMEWORK_VERSION is the version that will be 'npm install'ed by the tests if [[ "${FRAMEWORK_VERSION:-}" = "" ]]; then diff --git a/tools/@aws-cdk/cdk-release/lib/release-notes.ts b/tools/@aws-cdk/cdk-release/lib/release-notes.ts index 4647b4db71533..694613b6c7a0f 100644 --- a/tools/@aws-cdk/cdk-release/lib/release-notes.ts +++ b/tools/@aws-cdk/cdk-release/lib/release-notes.ts @@ -40,6 +40,8 @@ async function releaseNoteContents(currentVersion: Versions, opts: ReleaseNotesO return [ stableChangelogContents, '---', + // DO NOT CHANGE THE FORMAT OF THE FOLLOWING LINE. This will cause the v2 publishing verification canary to skip verification of Alpha modules. + // See https://github.com/cdklabs/cdk-ops/pull/1769. `## Alpha modules (${currentVersion.alphaVersion})`, alphaChangelogContents, ].join('\n'); From ca208058256703759ae5e35d04194edbdc6b1756 Mon Sep 17 00:00:00 2001 From: Cory Hall <43035978+corymhall@users.noreply.github.com> Date: Wed, 3 Nov 2021 17:44:41 -0400 Subject: [PATCH 29/70] chore(init-templates): move init templates to new assertions module (#17062) this updates both v1 and v2 init templates to use the new assertions module. I also added tests for the python app templates since those were missing. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../v1/app/go/%name%.template.go | 12 ++-- .../v1/app/go/%name%_test.template.go | 40 +++++------ .../init-templates/v1/app/go/go.template.mod | 4 -- .../v1/app/java/pom.template.xml | 18 ++--- .../%name.PascalCased%Stack.template.java | 7 ++ .../%name.PascalCased%Test.template.java | 40 +++++------ .../javascript/lib/%name%-stack.template.js | 6 ++ .../v1/app/javascript/package.template.json | 2 +- .../javascript/test/%name%.test.template.js | 27 ++++--- .../%name.PythonModule%_stack.template.py | 11 ++- .../v1/app/python/requirements-dev.txt | 1 + .../v1/app/python/requirements.template.txt | 2 + .../v1/app/python/requirements.txt | 1 - .../v1/app/python/setup.template.py | 43 ----------- .../v1/app/python/tests/__init__.py | 0 .../v1/app/python/tests/unit/__init__.py | 0 ...test_%name.PythonModule%_stack.template.py | 18 +++++ .../typescript/lib/%name%-stack.template.ts | 6 ++ .../v1/app/typescript/package.template.json | 2 +- .../typescript/test/%name%.test.template.ts | 26 ++++--- .../v1/lib/typescript/lib/index.template.ts | 6 ++ .../v1/lib/typescript/package.template.json | 2 +- .../typescript/test/%name%.test.template.ts | 29 ++++---- .../v1/sample-app/go/%name%.template.go | 71 +++++++++++++++++++ .../v1/sample-app/go/%name%_test.template.go | 25 +++++++ .../v1/sample-app/go/.template.gitignore | 19 +++++ .../init-templates/v1/sample-app/go/README.md | 14 ++++ .../v1/sample-app/go/cdk.template.json | 3 + .../v1/sample-app/go/go.template.mod | 9 +++ .../v1/sample-app/java/pom.template.xml | 18 ++--- .../%name.PascalCased%StackTest.template.java | 19 +++-- .../javascript/package.template.json | 2 +- .../javascript/test/%name%.test.template.js | 22 +++--- .../v1/sample-app/python/requirements-dev.txt | 1 + .../python/requirements.template.txt | 7 ++ .../v1/sample-app/python/requirements.txt | 2 - .../v1/sample-app/python/setup.template.py | 48 ------------- ...test_%name.PythonModule%_stack.template.py | 25 ++++--- .../typescript/package.template.json | 2 +- .../typescript/test/%name%.test.template.ts | 18 +++-- .../v2/app/go/%name%.template.go | 12 ++-- .../v2/app/go/%name%_test.template.go | 40 +++++------ .../init-templates/v2/app/go/go.template.mod | 5 +- .../v2/app/java/pom.template.xml | 18 ++--- .../%name.PascalCased%Stack.template.java | 7 ++ .../%name.PascalCased%Test.template.java | 41 +++++------ .../javascript/lib/%name%-stack.template.js | 8 ++- .../v2/app/javascript/package.template.json | 1 + .../javascript/test/%name%.test.template.js | 24 ++++--- .../%name.PythonModule%_stack.template.py | 12 +++- .../v2/app/python/requirements-dev.txt | 1 + .../v2/app/python/requirements.template.txt | 3 + .../v2/app/python/requirements.txt | 1 - .../v2/app/python/setup.template.py | 44 ------------ .../v2/app/python/tests/__init__.py | 0 .../v2/app/python/tests/unit/__init__.py | 0 ...test_%name.PythonModule%_stack.template.py | 15 ++++ .../typescript/lib/%name%-stack.template.ts | 6 ++ .../v2/app/typescript/package.template.json | 1 + .../typescript/test/%name%.test.template.ts | 24 ++++--- .../v2/lib/typescript/lib/index.template.ts | 6 ++ .../v2/lib/typescript/package.template.json | 1 + .../typescript/test/%name%.test.template.ts | 26 ++++--- .../v2/sample-app/go/%name%.template.go | 71 +++++++++++++++++++ .../v2/sample-app/go/%name%_test.template.go | 25 +++++++ .../v2/sample-app/go/.template.gitignore | 19 +++++ .../init-templates/v2/sample-app/go/README.md | 14 ++++ .../v2/sample-app/go/cdk.template.json | 3 + .../v2/sample-app/go/go.template.mod | 10 +++ .../v2/sample-app/java/pom.template.xml | 18 ++--- .../%name.PascalCased%StackTest.template.java | 20 +++--- .../javascript/package.template.json | 1 + .../javascript/test/%name%.test.template.js | 18 +++-- .../v2/sample-app/python/requirements-dev.txt | 1 + .../python/requirements.template.txt | 3 + .../v2/sample-app/python/requirements.txt | 2 - .../v2/sample-app/python/setup.template.py | 44 ------------ ...test_%name.PythonModule%_stack.template.py | 24 ++++--- .../typescript/package.template.json | 1 + .../typescript/test/%name%.test.template.ts | 19 +++-- packages/aws-cdk/test/integ/init/test-go.sh | 6 +- packages/aws-cdk/test/integ/init/test-java.sh | 1 + .../aws-cdk/test/integ/init/test-python.sh | 2 + 83 files changed, 725 insertions(+), 481 deletions(-) create mode 100644 packages/aws-cdk/lib/init-templates/v1/app/python/requirements-dev.txt create mode 100644 packages/aws-cdk/lib/init-templates/v1/app/python/requirements.template.txt delete mode 100644 packages/aws-cdk/lib/init-templates/v1/app/python/requirements.txt delete mode 100644 packages/aws-cdk/lib/init-templates/v1/app/python/setup.template.py create mode 100644 packages/aws-cdk/lib/init-templates/v1/app/python/tests/__init__.py create mode 100644 packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/__init__.py create mode 100644 packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/test_%name.PythonModule%_stack.template.py create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%.template.go create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%_test.template.go create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/go/.template.gitignore create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/go/README.md create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/go/cdk.template.json create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/go/go.template.mod create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements-dev.txt create mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.template.txt delete mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.txt delete mode 100644 packages/aws-cdk/lib/init-templates/v1/sample-app/python/setup.template.py create mode 100644 packages/aws-cdk/lib/init-templates/v2/app/python/requirements-dev.txt create mode 100644 packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt delete mode 100644 packages/aws-cdk/lib/init-templates/v2/app/python/requirements.txt delete mode 100644 packages/aws-cdk/lib/init-templates/v2/app/python/setup.template.py create mode 100644 packages/aws-cdk/lib/init-templates/v2/app/python/tests/__init__.py create mode 100644 packages/aws-cdk/lib/init-templates/v2/app/python/tests/unit/__init__.py create mode 100644 packages/aws-cdk/lib/init-templates/v2/app/python/tests/unit/test_%name.PythonModule%_stack.template.py create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%.template.go create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%_test.template.go create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/go/.template.gitignore create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/go/README.md create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/go/cdk.template.json create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/go/go.template.mod create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements-dev.txt create mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt delete mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.txt delete mode 100644 packages/aws-cdk/lib/init-templates/v2/sample-app/python/setup.template.py diff --git a/packages/aws-cdk/lib/init-templates/v1/app/go/%name%.template.go b/packages/aws-cdk/lib/init-templates/v1/app/go/%name%.template.go index 24a2b0e90b616..742ed4c64ce7b 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/go/%name%.template.go +++ b/packages/aws-cdk/lib/init-templates/v1/app/go/%name%.template.go @@ -2,9 +2,9 @@ package main import ( "github.com/aws/aws-cdk-go/awscdk" - "github.com/aws/aws-cdk-go/awscdk/awssns" + // "github.com/aws/aws-cdk-go/awscdk/awssqs" "github.com/aws/constructs-go/constructs/v3" - "github.com/aws/jsii-runtime-go" + // "github.com/aws/jsii-runtime-go" ) type %name.PascalCased%StackProps struct { @@ -20,10 +20,10 @@ func New%name.PascalCased%Stack(scope constructs.Construct, id string, props *%n // The code that defines your stack goes here - // as an example, here's how you would define an AWS SNS topic: - awssns.NewTopic(stack, jsii.String("MyTopic"), &awssns.TopicProps{ - DisplayName: jsii.String("MyCoolTopic"), - }) + // example resource + // queue := awssqs.NewQueue(stack, jsii.String("%name.PascalCased%Queue"), &awssqs.QueueProps{ + // VisibilityTimeout: awscdk.Duration_Seconds(jsii.Number(300)), + // }) return stack } diff --git a/packages/aws-cdk/lib/init-templates/v1/app/go/%name%_test.template.go b/packages/aws-cdk/lib/init-templates/v1/app/go/%name%_test.template.go index c0534249b6282..78742540bc2f7 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/go/%name%_test.template.go +++ b/packages/aws-cdk/lib/init-templates/v1/app/go/%name%_test.template.go @@ -1,28 +1,26 @@ package main -import ( - "encoding/json" - "testing" +// import ( +// "testing" - "github.com/aws/aws-cdk-go/awscdk" - "github.com/stretchr/testify/assert" - "github.com/tidwall/gjson" -) +// "github.com/aws/aws-cdk-go/awscdk" +// "github.com/aws/aws-cdk-go/awscdk/assertions" +// "github.com/aws/jsii-runtime-go" +// ) -func Test%name.PascalCased%Stack(t *testing.T) { - // GIVEN - app := awscdk.NewApp(nil) +// example tests. To run these tests, uncomment this file along with the +// example resource in %name%_test.go +// func Test%name.PascalCased%Stack(t *testing.T) { +// // GIVEN +// app := awscdk.NewApp(nil) - // WHEN - stack := New%name.PascalCased%Stack(app, "MyStack", nil) +// // WHEN +// stack := New%name.PascalCased%Stack(app, "MyStack", nil) - // THEN - bytes, err := json.Marshal(app.Synth(nil).GetStackArtifact(stack.ArtifactId()).Template()) - if err != nil { - t.Error(err) - } +// // THEN +// template := assertions.Template_FromStack(stack) - template := gjson.ParseBytes(bytes) - displayName := template.Get("Resources.MyTopic86869434.Properties.DisplayName").String() - assert.Equal(t, "MyCoolTopic", displayName) -} +// template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{ +// "VisibilityTimeout": 300, +// }) +// } diff --git a/packages/aws-cdk/lib/init-templates/v1/app/go/go.template.mod b/packages/aws-cdk/lib/init-templates/v1/app/go/go.template.mod index a1dcb391c1614..5dbef39984826 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/go/go.template.mod +++ b/packages/aws-cdk/lib/init-templates/v1/app/go/go.template.mod @@ -6,8 +6,4 @@ require ( github.com/aws/aws-cdk-go/awscdk v%cdk-version%-devpreview github.com/aws/constructs-go/constructs/v3 v3.3.71 github.com/aws/jsii-runtime-go v1.26.0 - - // for testing - github.com/tidwall/gjson v1.7.4 - github.com/stretchr/testify v1.7.0 ) diff --git a/packages/aws-cdk/lib/init-templates/v1/app/java/pom.template.xml b/packages/aws-cdk/lib/init-templates/v1/app/java/pom.template.xml index fb0b6cf828aaf..b8b00e798209c 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/java/pom.template.xml +++ b/packages/aws-cdk/lib/init-templates/v1/app/java/pom.template.xml @@ -43,24 +43,18 @@ core ${cdk.version} - - org.junit.jupiter - junit-jupiter-api - ${junit.version} - test + software.amazon.awscdk + assertions + ${cdk.version} + test + org.junit.jupiter - junit-jupiter-engine + junit-jupiter ${junit.version} test - - org.assertj - assertj-core - 3.18.1 - test - diff --git a/packages/aws-cdk/lib/init-templates/v1/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java b/packages/aws-cdk/lib/init-templates/v1/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java index e0d4b5a0be8b1..a4dbab1dbd8b9 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java +++ b/packages/aws-cdk/lib/init-templates/v1/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java @@ -3,6 +3,8 @@ import software.amazon.awscdk.core.Construct; import software.amazon.awscdk.core.Stack; import software.amazon.awscdk.core.StackProps; +// import software.amazon.awscdk.services.sqs.Queue; +// import software.amazon.awscdk.core.Duration; public class %name.PascalCased%Stack extends Stack { public %name.PascalCased%Stack(final Construct scope, final String id) { @@ -13,5 +15,10 @@ public class %name.PascalCased%Stack extends Stack { super(scope, id, props); // The code that defines your stack goes here + + // example resource + // final Queue queue = Queue.Builder.create(this, "%name.PascalCased%Queue") + // .visibilityTimeout(Duration.seconds(300)) + // .build(); } } diff --git a/packages/aws-cdk/lib/init-templates/v1/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java b/packages/aws-cdk/lib/init-templates/v1/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java index 9494caf63d628..f96ca04987f31 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java +++ b/packages/aws-cdk/lib/init-templates/v1/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java @@ -1,28 +1,26 @@ -package com.myorg; +// package com.myorg; -import software.amazon.awscdk.core.App; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; +// import software.amazon.awscdk.core.App; +// import software.amazon.awscdk.assertions.Template; +// import java.io.IOException; -import java.io.IOException; +// import java.util.Map; -import org.junit.jupiter.api.Test; -import static org.assertj.core.api.Assertions.assertThat; +// import org.junit.jupiter.api.Test; -public class %name.PascalCased%Test { - private final static ObjectMapper JSON = - new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true); +// example test. To run these tests, uncomment this file, along with the +// example resource in java/src/main/java/com/myorg/%name.PascalCased%Stack.java +// public class %name.PascalCased%Test { - @Test - public void testStack() throws IOException { - App app = new App(); - %name.PascalCased%Stack stack = new %name.PascalCased%Stack(app, "test"); +// @Test +// public void testStack() throws IOException { +// App app = new App(); +// %name.PascalCased%Stack stack = new %name.PascalCased%Stack(app, "test"); - // synthesize the stack to a CloudFormation template - JsonNode actual = JSON.valueToTree(app.synth().getStackArtifact(stack.getArtifactId()).getTemplate()); +// Template template = Template.fromStack(stack); - // Update once resources have been added to the stack - assertThat(actual.get("Resources")).isNull(); - } -} +// template.hasResourceProperties("AWS::SQS::Queue", Map.of( +// "VisibilityTimeout", 300 +// )); +// } +// } diff --git a/packages/aws-cdk/lib/init-templates/v1/app/javascript/lib/%name%-stack.template.js b/packages/aws-cdk/lib/init-templates/v1/app/javascript/lib/%name%-stack.template.js index 2c52c5f65244c..8004c54a568aa 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/javascript/lib/%name%-stack.template.js +++ b/packages/aws-cdk/lib/init-templates/v1/app/javascript/lib/%name%-stack.template.js @@ -1,4 +1,5 @@ const cdk = require('@aws-cdk/core'); +// const sqs = require('@aws-cdk/aws-sqs'); class %name.PascalCased%Stack extends cdk.Stack { /** @@ -11,6 +12,11 @@ class %name.PascalCased%Stack extends cdk.Stack { super(scope, id, props); // The code that defines your stack goes here + + // example resource + // const queue = new sqs.Queue(this, '%name.PascalCased%Queue', { + // visibilityTimeout: cdk.Duration.seconds(300) + // }); } } diff --git a/packages/aws-cdk/lib/init-templates/v1/app/javascript/package.template.json b/packages/aws-cdk/lib/init-templates/v1/app/javascript/package.template.json index 5547dacf3a673..abe1218b79d96 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/javascript/package.template.json +++ b/packages/aws-cdk/lib/init-templates/v1/app/javascript/package.template.json @@ -10,7 +10,7 @@ "test": "jest" }, "devDependencies": { - "@aws-cdk/assert": "%cdk-version%", + "@aws-cdk/assertions": "%cdk-version%", "aws-cdk": "%cdk-version%", "jest": "^26.4.2" }, diff --git a/packages/aws-cdk/lib/init-templates/v1/app/javascript/test/%name%.test.template.js b/packages/aws-cdk/lib/init-templates/v1/app/javascript/test/%name%.test.template.js index 54e6bb172e0a9..514cd34e9faf1 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/javascript/test/%name%.test.template.js +++ b/packages/aws-cdk/lib/init-templates/v1/app/javascript/test/%name%.test.template.js @@ -1,13 +1,18 @@ -const { expect, matchTemplate, MatchStyle } = require('@aws-cdk/assert'); -const cdk = require('@aws-cdk/core'); -const %name.PascalCased% = require('../lib/%name%-stack'); +// const { Template } = require('@aws-cdk/assertions'); +// const cdk = require('@aws-cdk/core'); +// const %name.PascalCased% = require('../lib/%name%-stack'); -test('Empty Stack', () => { - const app = new cdk.App(); - // WHEN - const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); - // THEN - expect(stack).to(matchTemplate({ - "Resources": {} - }, MatchStyle.EXACT)) +// example test. To run these tests, uncomment this file along with the +// example resource in lib/%name%-stack.js +test('SQS Queue Created', () => { +// const app = new cdk.App(); +// // WHEN +// const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); +// // THEN +// const template = Template.fromStack(stack); + +// template.hasResourceProperties('AWS::SQS::Queue', { +// VisibilityTimeout: 300 +// }); }); + diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py b/packages/aws-cdk/lib/init-templates/v1/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py index 6b4ed6e8ea6ed..9c5de032e839d 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py +++ b/packages/aws-cdk/lib/init-templates/v1/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py @@ -1,4 +1,7 @@ -from aws_cdk import core as cdk +from aws_cdk import ( + core as cdk + # aws_sqs as sqs, +) # For consistency with other languages, `cdk` is the preferred import name for # the CDK's core module. The following line also imports it as `core` for use @@ -13,3 +16,9 @@ def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # The code that defines your stack goes here + + # example resource + # queue = sqs.Queue( + # self, "%name.PascalCased%Queue", + # visibility_timeout=cdk.Duration.seconds(300), + # ) diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/requirements-dev.txt b/packages/aws-cdk/lib/init-templates/v1/app/python/requirements-dev.txt new file mode 100644 index 0000000000000..927094516e657 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v1/app/python/requirements-dev.txt @@ -0,0 +1 @@ +pytest==6.2.5 diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.template.txt b/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.template.txt new file mode 100644 index 0000000000000..e14ce6e77e499 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.template.txt @@ -0,0 +1,2 @@ +aws-cdk.core>=%cdk-version%, +aws-cdk.assertions>=%cdk-version%, diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.txt b/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.txt deleted file mode 100644 index d6e1198b1ab1f..0000000000000 --- a/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.txt +++ /dev/null @@ -1 +0,0 @@ --e . diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/setup.template.py b/packages/aws-cdk/lib/init-templates/v1/app/python/setup.template.py deleted file mode 100644 index 113bf29e54755..0000000000000 --- a/packages/aws-cdk/lib/init-templates/v1/app/python/setup.template.py +++ /dev/null @@ -1,43 +0,0 @@ -import setuptools - - -with open("README.md") as fp: - long_description = fp.read() - - -setuptools.setup( - name="%name.PythonModule%", - version="0.0.1", - - description="An empty CDK Python app", - long_description=long_description, - long_description_content_type="text/markdown", - - author="author", - - package_dir={"": "%name.PythonModule%"}, - packages=setuptools.find_packages(where="%name.PythonModule%"), - - install_requires=[ - "aws-cdk.core==%cdk-version%", - ], - - python_requires=">=3.6", - - classifiers=[ - "Development Status :: 4 - Beta", - - "Intended Audience :: Developers", - - "Programming Language :: JavaScript", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - - "Topic :: Software Development :: Code Generators", - "Topic :: Utilities", - - "Typing :: Typed", - ], -) diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/tests/__init__.py b/packages/aws-cdk/lib/init-templates/v1/app/python/tests/__init__.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/__init__.py b/packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/__init__.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/test_%name.PythonModule%_stack.template.py b/packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/test_%name.PythonModule%_stack.template.py new file mode 100644 index 0000000000000..94f2234e02aa6 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/test_%name.PythonModule%_stack.template.py @@ -0,0 +1,18 @@ +# from aws_cdk import ( +# core, +# assertions +# ) + +# from %name.PythonModule%.%name.PythonModule%_stack import %name.PascalCased%Stack + + +# example tests. To run these tests, uncomment this file along with the example +# resource in %name.PythonModule%/%name.PythonModule%_stack.py +# def test_sqs_queue_created(): +# app = core.App() +# stack = %name.PascalCased%Stack(app, "%name.StackName%") +# template = assertions.Template.from_stack(stack) + +# template.has_resource_properties("AWS::SQS::Queue", { +# "VisibilityTimeout": 300 +# }) diff --git a/packages/aws-cdk/lib/init-templates/v1/app/typescript/lib/%name%-stack.template.ts b/packages/aws-cdk/lib/init-templates/v1/app/typescript/lib/%name%-stack.template.ts index 80fa43a59ea24..82fd9a48ac0dd 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/typescript/lib/%name%-stack.template.ts +++ b/packages/aws-cdk/lib/init-templates/v1/app/typescript/lib/%name%-stack.template.ts @@ -1,9 +1,15 @@ import * as cdk from '@aws-cdk/core'; +// import * as sqs from '@aws-cdk/aws-sqs'; export class %name.PascalCased%Stack extends cdk.Stack { constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // The code that defines your stack goes here + + // example resource + // const queue = new sqs.Queue(this, '%name.PascalCased%Queue', { + // visibilityTimeout: cdk.Duration.seconds(300) + // }); } } diff --git a/packages/aws-cdk/lib/init-templates/v1/app/typescript/package.template.json b/packages/aws-cdk/lib/init-templates/v1/app/typescript/package.template.json index df89ae6a206bb..94bbd07dae3ac 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/typescript/package.template.json +++ b/packages/aws-cdk/lib/init-templates/v1/app/typescript/package.template.json @@ -11,7 +11,7 @@ "cdk": "cdk" }, "devDependencies": { - "@aws-cdk/assert": "%cdk-version%", + "@aws-cdk/assertions": "%cdk-version%", "@types/jest": "^26.0.10", "@types/node": "10.17.27", "jest": "^26.4.2", diff --git a/packages/aws-cdk/lib/init-templates/v1/app/typescript/test/%name%.test.template.ts b/packages/aws-cdk/lib/init-templates/v1/app/typescript/test/%name%.test.template.ts index a574690020687..d41f3aaf74d04 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/typescript/test/%name%.test.template.ts +++ b/packages/aws-cdk/lib/init-templates/v1/app/typescript/test/%name%.test.template.ts @@ -1,13 +1,17 @@ -import { expect as expectCDK, matchTemplate, MatchStyle } from '@aws-cdk/assert'; -import * as cdk from '@aws-cdk/core'; -import * as %name.PascalCased% from '../lib/%name%-stack'; +// import { Template } from '@aws-cdk/assertions'; +// import * as cdk from '@aws-cdk/core'; +// import * as %name.PascalCased% from '../lib/%name%-stack'; -test('Empty Stack', () => { - const app = new cdk.App(); - // WHEN - const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); - // THEN - expectCDK(stack).to(matchTemplate({ - "Resources": {} - }, MatchStyle.EXACT)); +// example test. To run these tests, uncomment this file along with the +// example resource in lib/%name%-stack.ts +test('SQS Queue Created', () => { +// const app = new cdk.App(); +// // WHEN +// const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); +// // THEN +// const template = Template.fromStack(stack); + +// template.hasResourceProperties('AWS::SQS::Queue', { +// VisibilityTimeout: 300 +// }); }); diff --git a/packages/aws-cdk/lib/init-templates/v1/lib/typescript/lib/index.template.ts b/packages/aws-cdk/lib/init-templates/v1/lib/typescript/lib/index.template.ts index d05d444fc8f09..49c002d8e8271 100644 --- a/packages/aws-cdk/lib/init-templates/v1/lib/typescript/lib/index.template.ts +++ b/packages/aws-cdk/lib/init-templates/v1/lib/typescript/lib/index.template.ts @@ -1,4 +1,5 @@ import * as cdk from '@aws-cdk/core'; +// import * as sqs from '@aws-cdk/aws-sqs'; export interface %name.PascalCased%Props { // Define construct properties here @@ -10,5 +11,10 @@ export class %name.PascalCased% extends cdk.Construct { super(scope, id); // Define construct contents here + + // example resource + // const queue = new sqs.Queue(this, '%name.PascalCased%Queue', { + // visibilityTimeout: cdk.Duration.seconds(300) + // }); } } diff --git a/packages/aws-cdk/lib/init-templates/v1/lib/typescript/package.template.json b/packages/aws-cdk/lib/init-templates/v1/lib/typescript/package.template.json index 8d9ef219c74ca..4e99fa16cbc8f 100644 --- a/packages/aws-cdk/lib/init-templates/v1/lib/typescript/package.template.json +++ b/packages/aws-cdk/lib/init-templates/v1/lib/typescript/package.template.json @@ -9,7 +9,7 @@ "test": "jest" }, "devDependencies": { - "@aws-cdk/assert": "%cdk-version%", + "@aws-cdk/assertions": "%cdk-version%", "@types/jest": "^26.0.10", "@types/node": "10.17.27", "jest": "^26.4.2", diff --git a/packages/aws-cdk/lib/init-templates/v1/lib/typescript/test/%name%.test.template.ts b/packages/aws-cdk/lib/init-templates/v1/lib/typescript/test/%name%.test.template.ts index 0b49cb3cc99d1..641b974082aa7 100644 --- a/packages/aws-cdk/lib/init-templates/v1/lib/typescript/test/%name%.test.template.ts +++ b/packages/aws-cdk/lib/init-templates/v1/lib/typescript/test/%name%.test.template.ts @@ -1,15 +1,18 @@ -import { expect as expectCDK, countResources } from '@aws-cdk/assert'; -import * as cdk from '@aws-cdk/core'; -import * as %name.PascalCased% from '../lib/index'; +// import { Template } from '@aws-cdk/assertions'; +// import * as cdk from '@aws-cdk/core'; +// import * as %name.PascalCased% from '../lib/index'; -/* - * Example test - */ -test('SNS Topic Created', () => { - const app = new cdk.App(); - const stack = new cdk.Stack(app, "TestStack"); - // WHEN - new %name.PascalCased%.%name.PascalCased%(stack, 'MyTestConstruct'); - // THEN - expectCDK(stack).to(countResources("AWS::SNS::Topic",0)); +// example test. To run these tests, uncomment this file along with the +// example resource in lib/index.ts +test('SQS Queue Created', () => { +// const app = new cdk.App(); +// const stack = new cdk.Stack(app, 'TestStack'); +// // WHEN +// new %name.PascalCased%.%name.PascalCased%(stack, 'MyTestConstruct'); +// // THEN +// const template = Template.fromStack(stack); + +// template.hasResourceProperties('AWS::SQS::Queue', { +// VisibilityTimeout: 300 +// }); }); diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%.template.go b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%.template.go new file mode 100644 index 0000000000000..5ac97c495740f --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%.template.go @@ -0,0 +1,71 @@ +package main + +import ( + "github.com/aws/aws-cdk-go/awscdk" + "github.com/aws/aws-cdk-go/awscdk/awssns" + "github.com/aws/aws-cdk-go/awscdk/awssnssubscriptions" + "github.com/aws/aws-cdk-go/awscdk/awssqs" + "github.com/aws/constructs-go/constructs/v3" + "github.com/aws/jsii-runtime-go" +) + +type %name.PascalCased%StackProps struct { + awscdk.StackProps +} + +func New%name.PascalCased%Stack(scope constructs.Construct, id string, props *%name.PascalCased%StackProps) awscdk.Stack { + var sprops awscdk.StackProps + if props != nil { + sprops = props.StackProps + } + stack := awscdk.NewStack(scope, &id, &sprops) + + + queue := awssqs.NewQueue(stack, jsii.String("%name.PascalCased%Queue"), &awssqs.QueueProps{ + VisibilityTimeout: awscdk.Duration_Seconds(jsii.Number(300)), + }) + + topic := awssns.NewTopic(stack, jsii.String("%name.PascalCased%Topic"), &awssns.TopicProps{}) + topic.AddSubscription(awssnssubscriptions.NewSqsSubscription(queue, &awssnssubscriptions.SqsSubscriptionProps{})) + + return stack +} + +func main() { + app := awscdk.NewApp(nil) + + New%name.PascalCased%Stack(app, "%name.PascalCased%Stack", &%name.PascalCased%StackProps{ + awscdk.StackProps{ + Env: env(), + }, + }) + + app.Synth(nil) +} + +// env determines the AWS environment (account+region) in which our stack is to +// be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html +func env() *awscdk.Environment { + // If unspecified, this stack will be "environment-agnostic". + // Account/Region-dependent features and context lookups will not work, but a + // single synthesized template can be deployed anywhere. + //--------------------------------------------------------------------------- + return nil + + // Uncomment if you know exactly what account and region you want to deploy + // the stack to. This is the recommendation for production stacks. + //--------------------------------------------------------------------------- + // return &awscdk.Environment{ + // Account: jsii.String("123456789012"), + // Region: jsii.String("us-east-1"), + // } + + // Uncomment to specialize this stack for the AWS Account and Region that are + // implied by the current CLI configuration. This is recommended for dev + // stacks. + //--------------------------------------------------------------------------- + // return &awscdk.Environment{ + // Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")), + // Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")), + // } +} diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%_test.template.go b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%_test.template.go new file mode 100644 index 0000000000000..834f4830cf23e --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/%name%_test.template.go @@ -0,0 +1,25 @@ +package main + +import ( + "testing" + + "github.com/aws/aws-cdk-go/awscdk" + "github.com/aws/aws-cdk-go/awscdk/assertions" + "github.com/aws/jsii-runtime-go" +) + +func Test%name.PascalCased%Stack(t *testing.T) { + // GIVEN + app := awscdk.NewApp(nil) + + // WHEN + stack := New%name.PascalCased%Stack(app, "MyStack", nil) + + // THEN + template := assertions.Template_FromStack(stack) + + template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{ + "VisibilityTimeout": 300, + }) + template.ResourceCountIs(jsii.String("AWS::SNS::Topic"), jsii.Number(1)) +} diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/go/.template.gitignore b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/.template.gitignore new file mode 100644 index 0000000000000..92fe1ec34b4b6 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/.template.gitignore @@ -0,0 +1,19 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# go.sum should be committed +!go.sum + +# CDK asset staging directory +.cdk.staging +cdk.out diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/go/README.md b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/README.md new file mode 100644 index 0000000000000..9b8d4b29f26e3 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/README.md @@ -0,0 +1,14 @@ +# Welcome to your CDK Go project! + +This is a blank project for Go development with CDK. + +**NOTICE**: Go support is still in Developer Preview. This implies that APIs may +change while we address early feedback from the community. We would love to hear +about your experience through GitHub issues. + +## Useful commands + + * `cdk deploy` deploy this stack to your default AWS account/region + * `cdk diff` compare deployed stack with current state + * `cdk synth` emits the synthesized CloudFormation template + * `go test` run unit tests diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/go/cdk.template.json b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/cdk.template.json new file mode 100644 index 0000000000000..ad88cd7ef75f3 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/cdk.template.json @@ -0,0 +1,3 @@ +{ + "app": "go mod download && go run %name%.go" +} \ No newline at end of file diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/go/go.template.mod b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/go.template.mod new file mode 100644 index 0000000000000..5dbef39984826 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/go/go.template.mod @@ -0,0 +1,9 @@ +module %name% + +go 1.16 + +require ( + github.com/aws/aws-cdk-go/awscdk v%cdk-version%-devpreview + github.com/aws/constructs-go/constructs/v3 v3.3.71 + github.com/aws/jsii-runtime-go v1.26.0 +) diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/java/pom.template.xml b/packages/aws-cdk/lib/init-templates/v1/sample-app/java/pom.template.xml index 5d679d2570040..e25c5e7c23a9b 100644 --- a/packages/aws-cdk/lib/init-templates/v1/sample-app/java/pom.template.xml +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/java/pom.template.xml @@ -55,24 +55,18 @@ sqs ${cdk.version} - - org.junit.jupiter - junit-jupiter-api - ${junit.version} - test + software.amazon.awscdk + assertions + ${cdk.version} + test + org.junit.jupiter - junit-jupiter-engine + junit-jupiter ${junit.version} test - - org.assertj - assertj-core - 3.18.1 - test - diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java b/packages/aws-cdk/lib/init-templates/v1/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java index 93b00f5d770c2..b648a3a72dc46 100644 --- a/packages/aws-cdk/lib/init-templates/v1/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java @@ -1,27 +1,26 @@ package com.myorg; import software.amazon.awscdk.core.App; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; +import software.amazon.awscdk.assertions.Template; +import software.amazon.awscdk.assertions.Match; import java.io.IOException; +import java.util.Map; + import org.junit.jupiter.api.Test; -import static org.assertj.core.api.Assertions.assertThat; public class %name.PascalCased%StackTest { - private final static ObjectMapper JSON = - new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true); @Test public void testStack() throws IOException { App app = new App(); %name.PascalCased%Stack stack = new %name.PascalCased%Stack(app, "test"); - JsonNode actual = JSON.valueToTree(app.synth().getStackArtifact(stack.getArtifactId()).getTemplate()); + Template template = Template.fromStack(stack); - assertThat(actual.toString()) - .contains("AWS::SQS::Queue") - .contains("AWS::SNS::Topic"); + template.hasResourceProperties("AWS::SQS::Queue", Map.of( + "VisibilityTimeout", 300 + )); + template.resourceCountIs("AWS::SNS::Topic", 1); } } diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/package.template.json b/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/package.template.json index 7594be2ffb151..43b6f94c6f314 100644 --- a/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/package.template.json +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/package.template.json @@ -10,7 +10,7 @@ "test": "jest" }, "devDependencies": { - "@aws-cdk/assert": "%cdk-version%", + "@aws-cdk/assertions": "%cdk-version%", "aws-cdk": "%cdk-version%", "jest": "^26.4.2" }, diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/test/%name%.test.template.js b/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/test/%name%.test.template.js index 7e786e6ee3753..4e53341387c69 100644 --- a/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/test/%name%.test.template.js +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/test/%name%.test.template.js @@ -1,15 +1,17 @@ -const { expect, haveResource } = require('@aws-cdk/assert'); +const { Template, Match } = require('@aws-cdk/assertions'); const cdk = require('@aws-cdk/core'); const %name.PascalCased% = require('../lib/%name%-stack'); test('SQS Queue Created', () => { - const app = new cdk.App(); - // WHEN - const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); - // THEN - expect(stack).to(haveResource("AWS::SQS::Queue",{ - VisibilityTimeout: 300 - })); + const app = new cdk.App(); + // WHEN + const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); + // THEN + const template = Template.fromStack(stack); + + template.hasResourceProperties('AWS::SQS::Queue', { + VisibilityTimeout: 300 + }); }); test('SNS Topic Created', () => { @@ -17,5 +19,7 @@ test('SNS Topic Created', () => { // WHEN const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); // THEN - expect(stack).to(haveResource("AWS::SNS::Topic")); + const template = Template.fromStack(stack); + + template.resourceCountIs('AWS::SNS::Topic', 1); }); diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements-dev.txt b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements-dev.txt new file mode 100644 index 0000000000000..927094516e657 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements-dev.txt @@ -0,0 +1 @@ +pytest==6.2.5 diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.template.txt b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.template.txt new file mode 100644 index 0000000000000..6c20aced0687a --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.template.txt @@ -0,0 +1,7 @@ +aws-cdk.core==%cdk-version% +aws-cdk.aws_iam==%cdk-version% +aws-cdk.aws_sqs==%cdk-version% +aws-cdk.aws_sns==%cdk-version% +aws-cdk.aws_sns_subscriptions==%cdk-version% +aws-cdk.aws_s3==%cdk-version% +aws-cdk.assertions==%cdk-version% diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.txt b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.txt deleted file mode 100644 index ae60ed5f14ca8..0000000000000 --- a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ --e . -pytest diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/setup.template.py b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/setup.template.py deleted file mode 100644 index d79611021c860..0000000000000 --- a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/setup.template.py +++ /dev/null @@ -1,48 +0,0 @@ -import setuptools - - -with open("README.md") as fp: - long_description = fp.read() - - -setuptools.setup( - name="%name.PythonModule%", - version="0.0.1", - - description="A sample CDK Python app", - long_description=long_description, - long_description_content_type="text/markdown", - - author="author", - - package_dir={"": "%name.PythonModule%"}, - packages=setuptools.find_packages(where="%name.PythonModule%"), - - install_requires=[ - "aws-cdk.core==%cdk-version%", - "aws-cdk.aws_iam==%cdk-version%", - "aws-cdk.aws_sqs==%cdk-version%", - "aws-cdk.aws_sns==%cdk-version%", - "aws-cdk.aws_sns_subscriptions==%cdk-version%", - "aws-cdk.aws_s3==%cdk-version%", - ], - - python_requires=">=3.6", - - classifiers=[ - "Development Status :: 4 - Beta", - - "Intended Audience :: Developers", - - "Programming Language :: JavaScript", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - - "Topic :: Software Development :: Code Generators", - "Topic :: Utilities", - - "Typing :: Typed", - ], -) diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py index 182d07fe09855..99a6a26b4a15e 100644 --- a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py @@ -1,19 +1,24 @@ -import json -import pytest +from aws_cdk import ( + core, + assertions + ) -from aws_cdk import core from %name.PythonModule%.%name.PythonModule%_stack import %name.PascalCased%Stack -def get_template(): +def test_sqs_queue_created(): app = core.App() - %name.PascalCased%Stack(app, "%name.StackName%") - return json.dumps(app.synth().get_stack("%name.StackName%").template) - + stack = %name.PascalCased%Stack(app, "%name.StackName%") + template = assertions.Template.from_stack(stack) -def test_sqs_queue_created(): - assert("AWS::SQS::Queue" in get_template()) + template.has_resource_properties("AWS::SQS::Queue", { + "VisibilityTimeout": 300 + }) def test_sns_topic_created(): - assert("AWS::SNS::Topic" in get_template()) + app = core.App() + stack = %name.PascalCased%Stack(app, "%name.StackName%") + template = assertions.Template.from_stack(stack) + + template.resource_count_is("AWS::SNS::Topic", 1) diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/package.template.json b/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/package.template.json index 98942aa31c167..550691f4eb2c5 100644 --- a/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/package.template.json +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/package.template.json @@ -12,7 +12,7 @@ }, "devDependencies": { "aws-cdk": "%cdk-version%", - "@aws-cdk/assert": "%cdk-version%", + "@aws-cdk/assertions": "%cdk-version%", "@types/jest": "^26.0.10", "@types/node": "10.17.27", "jest": "^26.4.2", diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/test/%name%.test.template.ts b/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/test/%name%.test.template.ts index 3a602380d6f6d..45cd6cca71ba4 100644 --- a/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/test/%name%.test.template.ts +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/test/%name%.test.template.ts @@ -1,15 +1,17 @@ -import { expect as expectCDK, haveResource } from '@aws-cdk/assert'; +import { Template, Match } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as %name.PascalCased% from '../lib/%name%-stack'; test('SQS Queue Created', () => { - const app = new cdk.App(); + const app = new cdk.App(); // WHEN - const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); + const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); // THEN - expectCDK(stack).to(haveResource("AWS::SQS::Queue",{ - VisibilityTimeout: 300 - })); + const template = Template.fromStack(stack); + + template.hasResourceProperties('AWS::SQS::Queue', { + VisibilityTimeout: 300 + }); }); test('SNS Topic Created', () => { @@ -17,5 +19,7 @@ test('SNS Topic Created', () => { // WHEN const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); // THEN - expectCDK(stack).to(haveResource("AWS::SNS::Topic")); + const template = Template.fromStack(stack); + + template.resourceCountIs('AWS::SNS::Topic', 1); }); diff --git a/packages/aws-cdk/lib/init-templates/v2/app/go/%name%.template.go b/packages/aws-cdk/lib/init-templates/v2/app/go/%name%.template.go index 46577faef90f6..a2ab8b5d8f8fd 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/go/%name%.template.go +++ b/packages/aws-cdk/lib/init-templates/v2/app/go/%name%.template.go @@ -2,9 +2,9 @@ package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" - "github.com/aws/aws-cdk-go/awscdk/v2/awssns" + // "github.com/aws/aws-cdk-go/awscdk/v2/awssqs" "github.com/aws/constructs-go/constructs/v10" - "github.com/aws/jsii-runtime-go" + // "github.com/aws/jsii-runtime-go" ) type %name.PascalCased%StackProps struct { @@ -20,10 +20,10 @@ func New%name.PascalCased%Stack(scope constructs.Construct, id string, props *%n // The code that defines your stack goes here - // as an example, here's how you would define an AWS SNS topic: - awssns.NewTopic(stack, jsii.String("MyTopic"), &awssns.TopicProps{ - DisplayName: jsii.String("MyCoolTopic"), - }) + // example resource + // queue := awssqs.NewQueue(stack, jsii.String("%name.PascalCased%Queue"), &awssqs.QueueProps{ + // VisibilityTimeout: awscdk.Duration_Seconds(jsii.Number(300)), + // }) return stack } diff --git a/packages/aws-cdk/lib/init-templates/v2/app/go/%name%_test.template.go b/packages/aws-cdk/lib/init-templates/v2/app/go/%name%_test.template.go index 6c166d681b0ce..e1b5f2c91adcb 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/go/%name%_test.template.go +++ b/packages/aws-cdk/lib/init-templates/v2/app/go/%name%_test.template.go @@ -1,28 +1,26 @@ package main -import ( - "encoding/json" - "testing" +// import ( +// "testing" - "github.com/aws/aws-cdk-go/awscdk/v2" - "github.com/stretchr/testify/assert" - "github.com/tidwall/gjson" -) +// "github.com/aws/aws-cdk-go/awscdk/v2" +// assertions "github.com/aws/aws-cdk-go/awscdkassertionsalpha/v2" +// "github.com/aws/jsii-runtime-go" +// ) -func Test%name.PascalCased%Stack(t *testing.T) { - // GIVEN - app := awscdk.NewApp(nil) +// example tests. To run these tests, uncomment this file along with the +// example resource in %name%_test.go +// func Test%name.PascalCased%Stack(t *testing.T) { +// // GIVEN +// app := awscdk.NewApp(nil) - // WHEN - stack := New%name.PascalCased%Stack(app, "MyStack", nil) +// // WHEN +// stack := New%name.PascalCased%Stack(app, "MyStack", nil) - // THEN - bytes, err := json.Marshal(app.Synth(nil).GetStackArtifact(stack.ArtifactId()).Template()) - if err != nil { - t.Error(err) - } +// // THEN +// template := assertions.Template_FromStack(stack) - template := gjson.ParseBytes(bytes) - displayName := template.Get("Resources.MyTopic86869434.Properties.DisplayName").String() - assert.Equal(t, "MyCoolTopic", displayName) -} +// template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{ +// "VisibilityTimeout": 300, +// }) +// } diff --git a/packages/aws-cdk/lib/init-templates/v2/app/go/go.template.mod b/packages/aws-cdk/lib/init-templates/v2/app/go/go.template.mod index 50f21389478f4..3f1a4a639d1e3 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/go/go.template.mod +++ b/packages/aws-cdk/lib/init-templates/v2/app/go/go.template.mod @@ -4,10 +4,7 @@ go 1.16 require ( github.com/aws/aws-cdk-go/awscdk/v2 v%cdk-version% + github.com/aws/aws-cdk-go/awscdkassertionsalpha/v2 v%cdk-version% github.com/aws/constructs-go/constructs/v10 v10.0.5 github.com/aws/jsii-runtime-go v1.29.0 - - // for testing - github.com/tidwall/gjson v1.7.4 - github.com/stretchr/testify v1.7.0 ) diff --git a/packages/aws-cdk/lib/init-templates/v2/app/java/pom.template.xml b/packages/aws-cdk/lib/init-templates/v2/app/java/pom.template.xml index 1d0eb742d4f8e..3173c567c1149 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/java/pom.template.xml +++ b/packages/aws-cdk/lib/init-templates/v2/app/java/pom.template.xml @@ -50,24 +50,18 @@ constructs ${constructs.version} - - org.junit.jupiter - junit-jupiter-api - ${junit.version} - test + software.amazon.awscdk + assertions-alpha + ${cdk.version} + test + org.junit.jupiter - junit-jupiter-engine + junit-jupiter ${junit.version} test - - org.assertj - assertj-core - 3.18.1 - test - diff --git a/packages/aws-cdk/lib/init-templates/v2/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java b/packages/aws-cdk/lib/init-templates/v2/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java index 0d8cbf10bf988..e944bde388603 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java +++ b/packages/aws-cdk/lib/init-templates/v2/app/java/src/main/java/com/myorg/%name.PascalCased%Stack.template.java @@ -3,6 +3,8 @@ import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; +// import software.amazon.awscdk.Duration; +// import software.amazon.awscdk.services.sqs.Queue; public class %name.PascalCased%Stack extends Stack { public %name.PascalCased%Stack(final Construct scope, final String id) { @@ -13,5 +15,10 @@ public class %name.PascalCased%Stack extends Stack { super(scope, id, props); // The code that defines your stack goes here + + // example resource + // final Queue queue = Queue.Builder.create(this, "%name.PascalCased%Queue") + // .visibilityTimeout(Duration.seconds(300)) + // .build(); } } diff --git a/packages/aws-cdk/lib/init-templates/v2/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java b/packages/aws-cdk/lib/init-templates/v2/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java index 715840abd0de1..5e9d7806654d0 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java +++ b/packages/aws-cdk/lib/init-templates/v2/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java @@ -1,29 +1,26 @@ -package com.myorg; +// package com.myorg; -import software.amazon.awscdk.App; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; +// import software.amazon.awscdk.App; +// import software.amazon.awscdk.assertions.alpha.Template; +// import java.io.IOException; -import java.io.IOException; +// import java.util.Map; -import org.junit.jupiter.api.Test; -import static org.assertj.core.api.Assertions.assertThat; +// import org.junit.jupiter.api.Test; -public class %name.PascalCased%Test { - private final static ObjectMapper JSON = - new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true); +// example test. To run these tests, uncomment this file, along with the +// example resource in java/src/main/java/com/myorg/%name.PascalCased%Stack.java +// public class %name.PascalCased%Test { - @Test - public void testStack() throws IOException { - App app = new App(); - %name.PascalCased%Stack stack = new %name.PascalCased%Stack(app, "test"); +// @Test +// public void testStack() throws IOException { +// App app = new App(); +// %name.PascalCased%Stack stack = new %name.PascalCased%Stack(app, "test"); - // synthesize the stack to a CloudFormation template and compare against - // a checked-in JSON file. - JsonNode actual = JSON.valueToTree(app.synth().getStackArtifact(stack.getArtifactId()).getTemplate()); +// Template template = Template.fromStack(stack); - // Update once resources have been added to the stack - assertThat(actual.get("Resources")).isNull(); - } -} +// template.hasResourceProperties("AWS::SQS::Queue", Map.of( +// "VisibilityTimeout", 300 +// )); +// } +// } diff --git a/packages/aws-cdk/lib/init-templates/v2/app/javascript/lib/%name%-stack.template.js b/packages/aws-cdk/lib/init-templates/v2/app/javascript/lib/%name%-stack.template.js index d5d66d9bd229e..cb7c095969484 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/javascript/lib/%name%-stack.template.js +++ b/packages/aws-cdk/lib/init-templates/v2/app/javascript/lib/%name%-stack.template.js @@ -1,4 +1,5 @@ -const { Stack } = require('aws-cdk-lib'); +const { Stack, Duration } = require('aws-cdk-lib'); +// const sqs = require('aws-cdk-lib/aws-sqs'); class %name.PascalCased%Stack extends Stack { /** @@ -11,6 +12,11 @@ class %name.PascalCased%Stack extends Stack { super(scope, id, props); // The code that defines your stack goes here + + // example resource + // const queue = new sqs.Queue(this, '%name.PascalCased%Queue', { + // visibilityTimeout: Duration.seconds(300) + // }); } } diff --git a/packages/aws-cdk/lib/init-templates/v2/app/javascript/package.template.json b/packages/aws-cdk/lib/init-templates/v2/app/javascript/package.template.json index 550e7544f9b44..3fcda877c39da 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/javascript/package.template.json +++ b/packages/aws-cdk/lib/init-templates/v2/app/javascript/package.template.json @@ -11,6 +11,7 @@ }, "devDependencies": { "aws-cdk": "%cdk-version%", + "@aws-cdk/assertions-alpha": "%cdk-version%", "jest": "^26.4.2" }, "dependencies": { diff --git a/packages/aws-cdk/lib/init-templates/v2/app/javascript/test/%name%.test.template.js b/packages/aws-cdk/lib/init-templates/v2/app/javascript/test/%name%.test.template.js index 79db241da8e0e..874a74f5b17d8 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/javascript/test/%name%.test.template.js +++ b/packages/aws-cdk/lib/init-templates/v2/app/javascript/test/%name%.test.template.js @@ -1,11 +1,17 @@ -const cdk = require('aws-cdk-lib'); -const %name.PascalCased% = require('../lib/%name%-stack'); +// const cdk = require('aws-cdk-lib'); +// const { Template } = require('@aws-cdk/assertions-alpha'); +// const %name.PascalCased% = require('../lib/%name%-stack'); -test('Empty Stack', () => { - const app = new cdk.App(); - // WHEN - const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); - // THEN - const actual = app.synth().getStackArtifact(stack.artifactId).template; - expect(actual.Resources || {}).toEqual({}); +// example test. To run these tests, uncomment this file along with the +// example resource in lib/%name%-stack.js +test('SQS Queue Created', () => { +// const app = new cdk.App(); +// // WHEN +// const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); +// // THEN +// const template = Template.fromStack(stack); + +// template.hasResourceProperties('AWS::SQS::Queue', { +// VisibilityTimeout: 300 +// }); }); diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py b/packages/aws-cdk/lib/init-templates/v2/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py index 4599c4f6e19f6..b93133ce944cf 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py +++ b/packages/aws-cdk/lib/init-templates/v2/app/python/%name.PythonModule%/%name.PythonModule%_stack.template.py @@ -1,4 +1,8 @@ -from aws_cdk import Stack +from aws_cdk import ( + # Duration, + Stack, + # aws_sqs as sqs, +) from constructs import Construct class %name.PascalCased%Stack(Stack): @@ -7,3 +11,9 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # The code that defines your stack goes here + + # example resource + # queue = sqs.Queue( + # self, "%name.PascalCased%Queue", + # visibility_timeout=Duration.seconds(300), + # ) diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/requirements-dev.txt b/packages/aws-cdk/lib/init-templates/v2/app/python/requirements-dev.txt new file mode 100644 index 0000000000000..927094516e657 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v2/app/python/requirements-dev.txt @@ -0,0 +1 @@ +pytest==6.2.5 diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt b/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt new file mode 100644 index 0000000000000..5ba3f43115a07 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt @@ -0,0 +1,3 @@ +aws-cdk-lib==%cdk-version% +aws-cdk.assertions-alpha==%cdk-version% +constructs>=%constructs-version% diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.txt b/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.txt deleted file mode 100644 index d6e1198b1ab1f..0000000000000 --- a/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.txt +++ /dev/null @@ -1 +0,0 @@ --e . diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/setup.template.py b/packages/aws-cdk/lib/init-templates/v2/app/python/setup.template.py deleted file mode 100644 index d819a7bcadb77..0000000000000 --- a/packages/aws-cdk/lib/init-templates/v2/app/python/setup.template.py +++ /dev/null @@ -1,44 +0,0 @@ -import setuptools - - -with open("README.md") as fp: - long_description = fp.read() - - -setuptools.setup( - name="%name.PythonModule%", - version="0.0.1", - - description="An empty CDK Python app", - long_description=long_description, - long_description_content_type="text/markdown", - - author="author", - - package_dir={"": "%name.PythonModule%"}, - packages=setuptools.find_packages(where="%name.PythonModule%"), - - install_requires=[ - "aws-cdk-lib==%cdk-version%", - "constructs%constructs-version%", - ], - - python_requires=">=3.6", - - classifiers=[ - "Development Status :: 4 - Beta", - - "Intended Audience :: Developers", - - "Programming Language :: JavaScript", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - - "Topic :: Software Development :: Code Generators", - "Topic :: Utilities", - - "Typing :: Typed", - ], -) diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/tests/__init__.py b/packages/aws-cdk/lib/init-templates/v2/app/python/tests/__init__.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/tests/unit/__init__.py b/packages/aws-cdk/lib/init-templates/v2/app/python/tests/unit/__init__.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/tests/unit/test_%name.PythonModule%_stack.template.py b/packages/aws-cdk/lib/init-templates/v2/app/python/tests/unit/test_%name.PythonModule%_stack.template.py new file mode 100644 index 0000000000000..19c612a3da691 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v2/app/python/tests/unit/test_%name.PythonModule%_stack.template.py @@ -0,0 +1,15 @@ +# import aws_cdk as core +# import aws_cdk.assertions_alpha as assertions + +# from %name.PythonModule%.%name.PythonModule%_stack import %name.PascalCased%Stack + +# example tests. To run these tests, uncomment this file along with the example +# resource in %name.PythonModule%/%name.PythonModule%_stack.py +# def test_sqs_queue_created(): +# app = core.App() +# stack = %name.PascalCased%Stack(app, "%name.StackName%") +# template = assertions.Template.from_stack(stack) + +# template.has_resource_properties("AWS::SQS::Queue", { +# "VisibilityTimeout": 300 +# }) diff --git a/packages/aws-cdk/lib/init-templates/v2/app/typescript/lib/%name%-stack.template.ts b/packages/aws-cdk/lib/init-templates/v2/app/typescript/lib/%name%-stack.template.ts index 82d70c083134e..3d6c54bd3dca2 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/typescript/lib/%name%-stack.template.ts +++ b/packages/aws-cdk/lib/init-templates/v2/app/typescript/lib/%name%-stack.template.ts @@ -1,10 +1,16 @@ import { Stack, StackProps } from 'aws-cdk-lib'; import { Construct } from 'constructs'; +// import * as sqs from 'aws-cdk-lib/aws-sqs'; export class %name.PascalCased%Stack extends Stack { constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); // The code that defines your stack goes here + + // example resource + // const queue = new sqs.Queue(this, '%name.PascalCased%Queue', { + // visibilityTimeout: cdk.Duration.seconds(300) + // }); } } diff --git a/packages/aws-cdk/lib/init-templates/v2/app/typescript/package.template.json b/packages/aws-cdk/lib/init-templates/v2/app/typescript/package.template.json index a599c63f6ec35..9f6f0d47cade9 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/typescript/package.template.json +++ b/packages/aws-cdk/lib/init-templates/v2/app/typescript/package.template.json @@ -11,6 +11,7 @@ "cdk": "cdk" }, "devDependencies": { + "@aws-cdk/assertions-alpha": "%cdk-version%", "@types/jest": "^26.0.10", "@types/node": "10.17.27", "jest": "^26.4.2", diff --git a/packages/aws-cdk/lib/init-templates/v2/app/typescript/test/%name%.test.template.ts b/packages/aws-cdk/lib/init-templates/v2/app/typescript/test/%name%.test.template.ts index a2542902315c8..61e6e96d0dcab 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/typescript/test/%name%.test.template.ts +++ b/packages/aws-cdk/lib/init-templates/v2/app/typescript/test/%name%.test.template.ts @@ -1,11 +1,17 @@ -import * as cdk from 'aws-cdk-lib'; -import * as %name.PascalCased% from '../lib/%name%-stack'; +// import * as cdk from 'aws-cdk-lib'; +// import { Template } from '@aws-cdk/assertions-alpha'; +// import * as %name.PascalCased% from '../lib/%name%-stack'; -test('Empty Stack', () => { - const app = new cdk.App(); - // WHEN - const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); - // THEN - const actual = app.synth().getStackArtifact(stack.artifactId).template; - expect(actual.Resources ?? {}).toEqual({}); +// example test. To run these tests, uncomment this file along with the +// example resource in lib/%name%-stack.ts +test('SQS Queue Created', () => { +// const app = new cdk.App(); +// // WHEN +// const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); +// // THEN +// const template = Template.fromStack(stack); + +// template.hasResourceProperties('AWS::SQS::Queue', { +// VisibilityTimeout: 300 +// }); }); diff --git a/packages/aws-cdk/lib/init-templates/v2/lib/typescript/lib/index.template.ts b/packages/aws-cdk/lib/init-templates/v2/lib/typescript/lib/index.template.ts index 3c48194882c3d..bbd6f13d470bd 100644 --- a/packages/aws-cdk/lib/init-templates/v2/lib/typescript/lib/index.template.ts +++ b/packages/aws-cdk/lib/init-templates/v2/lib/typescript/lib/index.template.ts @@ -1,4 +1,5 @@ import { Construct } from 'constructs'; +// import * as sqs from 'aws-cdk-lib/aws-sqs'; export interface %name.PascalCased%Props { // Define construct properties here @@ -10,5 +11,10 @@ export class %name.PascalCased% extends Construct { super(scope, id); // Define construct contents here + + // example resource + // const queue = new sqs.Queue(this, '%name.PascalCased%Queue', { + // visibilityTimeout: cdk.Duration.seconds(300) + // }); } } diff --git a/packages/aws-cdk/lib/init-templates/v2/lib/typescript/package.template.json b/packages/aws-cdk/lib/init-templates/v2/lib/typescript/package.template.json index b388f5270b769..59211fe81715c 100644 --- a/packages/aws-cdk/lib/init-templates/v2/lib/typescript/package.template.json +++ b/packages/aws-cdk/lib/init-templates/v2/lib/typescript/package.template.json @@ -12,6 +12,7 @@ "@types/jest": "^26.0.10", "@types/node": "10.17.27", "aws-cdk-lib": "%cdk-version%", + "@aws-cdk/assertions-alpha": "%cdk-version%", "constructs": "%constructs-version%", "jest": "^26.4.2", "ts-jest": "^26.2.0", diff --git a/packages/aws-cdk/lib/init-templates/v2/lib/typescript/test/%name%.test.template.ts b/packages/aws-cdk/lib/init-templates/v2/lib/typescript/test/%name%.test.template.ts index 0aa210d01ae5c..f7200d5dd5cc9 100644 --- a/packages/aws-cdk/lib/init-templates/v2/lib/typescript/test/%name%.test.template.ts +++ b/packages/aws-cdk/lib/init-templates/v2/lib/typescript/test/%name%.test.template.ts @@ -1,12 +1,18 @@ -import * as cdk from 'aws-cdk-lib'; -import * as %name.PascalCased% from '../lib/index'; +// import * as cdk from 'aws-cdk-lib'; +// import { Template } from '@aws-cdk/assertions-alpha'; +// import * as %name.PascalCased% from '../lib/index'; -test('Empty Stack', () => { - const app = new cdk.App(); - const stack = new cdk.Stack(app, "TestStack"); - // WHEN - new %name.PascalCased%.%name.PascalCased%(stack, 'MyTestConstruct'); - // THEN - const actual = app.synth().getStackArtifact(stack.artifactId).template; - expect(actual.Resources ?? {}).toEqual({}); +// example test. To run these tests, uncomment this file along with the +// example resource in lib/index.ts +test('SQS Queue Created', () => { +// const app = new cdk.App(); +// const stack = new cdk.Stack(app, "TestStack"); +// // WHEN +// new %name.PascalCased%.%name.PascalCased%(stack, 'MyTestConstruct'); +// // THEN +// const template = Template.fromStack(stack); + +// template.hasResourceProperties('AWS::SQS::Queue', { +// VisibilityTimeout: 300 +// }); }); diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%.template.go b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%.template.go new file mode 100644 index 0000000000000..1ae8249703373 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%.template.go @@ -0,0 +1,71 @@ +package main + +import ( + "github.com/aws/aws-cdk-go/awscdk/v2" + "github.com/aws/aws-cdk-go/awscdk/v2/awssns" + "github.com/aws/aws-cdk-go/awscdk/v2/awssnssubscriptions" + "github.com/aws/aws-cdk-go/awscdk/v2/awssqs" + "github.com/aws/constructs-go/constructs/v10" + "github.com/aws/jsii-runtime-go" +) + +type %name.PascalCased%StackProps struct { + awscdk.StackProps +} + +func New%name.PascalCased%Stack(scope constructs.Construct, id string, props *%name.PascalCased%StackProps) awscdk.Stack { + var sprops awscdk.StackProps + if props != nil { + sprops = props.StackProps + } + stack := awscdk.NewStack(scope, &id, &sprops) + + + queue := awssqs.NewQueue(stack, jsii.String("%name.PascalCased%Queue"), &awssqs.QueueProps{ + VisibilityTimeout: awscdk.Duration_Seconds(jsii.Number(300)), + }) + + topic := awssns.NewTopic(stack, jsii.String("%name.PascalCased%Topic"), &awssns.TopicProps{}) + topic.AddSubscription(awssnssubscriptions.NewSqsSubscription(queue, &awssnssubscriptions.SqsSubscriptionProps{})) + + return stack +} + +func main() { + app := awscdk.NewApp(nil) + + New%name.PascalCased%Stack(app, "%name.PascalCased%Stack", &%name.PascalCased%StackProps{ + awscdk.StackProps{ + Env: env(), + }, + }) + + app.Synth(nil) +} + +// env determines the AWS environment (account+region) in which our stack is to +// be deployed. For more information see: https://docs.aws.amazon.com/cdk/latest/guide/environments.html +func env() *awscdk.Environment { + // If unspecified, this stack will be "environment-agnostic". + // Account/Region-dependent features and context lookups will not work, but a + // single synthesized template can be deployed anywhere. + //--------------------------------------------------------------------------- + return nil + + // Uncomment if you know exactly what account and region you want to deploy + // the stack to. This is the recommendation for production stacks. + //--------------------------------------------------------------------------- + // return &awscdk.Environment{ + // Account: jsii.String("123456789012"), + // Region: jsii.String("us-east-1"), + // } + + // Uncomment to specialize this stack for the AWS Account and Region that are + // implied by the current CLI configuration. This is recommended for dev + // stacks. + //--------------------------------------------------------------------------- + // return &awscdk.Environment{ + // Account: jsii.String(os.Getenv("CDK_DEFAULT_ACCOUNT")), + // Region: jsii.String(os.Getenv("CDK_DEFAULT_REGION")), + // } +} diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%_test.template.go b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%_test.template.go new file mode 100644 index 0000000000000..53b15a49266d1 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/%name%_test.template.go @@ -0,0 +1,25 @@ +package main + +import ( + "testing" + + "github.com/aws/aws-cdk-go/awscdk/v2" + assertions "github.com/aws/aws-cdk-go/awscdkassertionsalpha/v2" + "github.com/aws/jsii-runtime-go" +) + +func Test%name.PascalCased%Stack(t *testing.T) { + // GIVEN + app := awscdk.NewApp(nil) + + // WHEN + stack := New%name.PascalCased%Stack(app, "MyStack", nil) + + // THEN + template := assertions.Template_FromStack(stack) + + template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{ + "VisibilityTimeout": 300, + }) + template.ResourceCountIs(jsii.String("AWS::SNS::Topic"), jsii.Number(1)) +} diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/go/.template.gitignore b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/.template.gitignore new file mode 100644 index 0000000000000..92fe1ec34b4b6 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/.template.gitignore @@ -0,0 +1,19 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# go.sum should be committed +!go.sum + +# CDK asset staging directory +.cdk.staging +cdk.out diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/go/README.md b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/README.md new file mode 100644 index 0000000000000..9b8d4b29f26e3 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/README.md @@ -0,0 +1,14 @@ +# Welcome to your CDK Go project! + +This is a blank project for Go development with CDK. + +**NOTICE**: Go support is still in Developer Preview. This implies that APIs may +change while we address early feedback from the community. We would love to hear +about your experience through GitHub issues. + +## Useful commands + + * `cdk deploy` deploy this stack to your default AWS account/region + * `cdk diff` compare deployed stack with current state + * `cdk synth` emits the synthesized CloudFormation template + * `go test` run unit tests diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/go/cdk.template.json b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/cdk.template.json new file mode 100644 index 0000000000000..ad88cd7ef75f3 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/cdk.template.json @@ -0,0 +1,3 @@ +{ + "app": "go mod download && go run %name%.go" +} \ No newline at end of file diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/go/go.template.mod b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/go.template.mod new file mode 100644 index 0000000000000..3f1a4a639d1e3 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/go/go.template.mod @@ -0,0 +1,10 @@ +module %name% + +go 1.16 + +require ( + github.com/aws/aws-cdk-go/awscdk/v2 v%cdk-version% + github.com/aws/aws-cdk-go/awscdkassertionsalpha/v2 v%cdk-version% + github.com/aws/constructs-go/constructs/v10 v10.0.5 + github.com/aws/jsii-runtime-go v1.29.0 +) diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/java/pom.template.xml b/packages/aws-cdk/lib/init-templates/v2/sample-app/java/pom.template.xml index 79c769157ceee..78217b2650669 100644 --- a/packages/aws-cdk/lib/init-templates/v2/sample-app/java/pom.template.xml +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/java/pom.template.xml @@ -44,24 +44,18 @@ constructs ${constructs.version} - - org.junit.jupiter - junit-jupiter-api - ${junit.version} - test + software.amazon.awscdk + assertions-alpha + ${cdk.version} + test + org.junit.jupiter - junit-jupiter-engine + junit-jupiter ${junit.version} test - - org.assertj - assertj-core - 3.18.1 - test - diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java b/packages/aws-cdk/lib/init-templates/v2/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java index a6f7c4f4590b4..c728c6eb6323c 100644 --- a/packages/aws-cdk/lib/init-templates/v2/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java @@ -1,27 +1,27 @@ package com.myorg; import software.amazon.awscdk.App; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; +import software.amazon.awscdk.assertions.alpha.Template; +import software.amazon.awscdk.assertions.alpha.Match; import java.io.IOException; +import java.util.Map; + import org.junit.jupiter.api.Test; -import static org.assertj.core.api.Assertions.assertThat; public class %name.PascalCased%StackTest { - private final static ObjectMapper JSON = - new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true); @Test public void testStack() throws IOException { App app = new App(); %name.PascalCased%Stack stack = new %name.PascalCased%Stack(app, "test"); - JsonNode actual = JSON.valueToTree(app.synth().getStackArtifact(stack.getArtifactId()).getTemplate()); + Template template = Template.fromStack(stack); + + template.hasResourceProperties("AWS::SQS::Queue", Map.of( + "VisibilityTimeout", 300 + )); - assertThat(actual.toString()) - .contains("AWS::SQS::Queue") - .contains("AWS::SNS::Topic"); + template.resourceCountIs("AWS::SNS::Topic", 1); } } diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/package.template.json b/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/package.template.json index 550e7544f9b44..3fcda877c39da 100644 --- a/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/package.template.json +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/package.template.json @@ -11,6 +11,7 @@ }, "devDependencies": { "aws-cdk": "%cdk-version%", + "@aws-cdk/assertions-alpha": "%cdk-version%", "jest": "^26.4.2" }, "dependencies": { diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/test/%name%.test.template.js b/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/test/%name%.test.template.js index b741d4045225b..93294bf407633 100644 --- a/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/test/%name%.test.template.js +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/test/%name%.test.template.js @@ -1,12 +1,16 @@ const cdk = require('aws-cdk-lib'); +const { Template, Match } = require('@aws-cdk/assertions-alpha'); const %name.PascalCased% = require('../lib/%name%-stack'); test('SQS Queue and SNS Topic Created', () => { - const app = new cdk.App(); - // WHEN - const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); - // THEN - const actual = JSON.stringify(app.synth().getStackArtifact(stack.artifactId).template); - expect(actual).toContain('AWS::SQS::Queue'); - expect(actual).toContain('AWS::SNS::Topic'); + const app = new cdk.App(); + // WHEN + const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); + // THEN + const template = Template.fromStack(stack); + template.hasResourceProperties('AWS::SQS::Queue', { + VisibilityTimeout: 300, + }); + + template.resourceCountIs('AWS::SNS::Topic', 1); }); diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements-dev.txt b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements-dev.txt new file mode 100644 index 0000000000000..927094516e657 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements-dev.txt @@ -0,0 +1 @@ +pytest==6.2.5 diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt new file mode 100644 index 0000000000000..5ba3f43115a07 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt @@ -0,0 +1,3 @@ +aws-cdk-lib==%cdk-version% +aws-cdk.assertions-alpha==%cdk-version% +constructs>=%constructs-version% diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.txt b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.txt deleted file mode 100644 index ae60ed5f14ca8..0000000000000 --- a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ --e . -pytest diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/setup.template.py b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/setup.template.py deleted file mode 100644 index f9eb461178472..0000000000000 --- a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/setup.template.py +++ /dev/null @@ -1,44 +0,0 @@ -import setuptools - - -with open("README.md") as fp: - long_description = fp.read() - - -setuptools.setup( - name="%name.PythonModule%", - version="0.0.1", - - description="A sample CDK Python app", - long_description=long_description, - long_description_content_type="text/markdown", - - author="author", - - package_dir={"": "%name.PythonModule%"}, - packages=setuptools.find_packages(where="%name.PythonModule%"), - - install_requires=[ - "aws-cdk-lib==%cdk-version%", - "constructs%constructs-version%", - ], - - python_requires=">=3.6", - - classifiers=[ - "Development Status :: 4 - Beta", - - "Intended Audience :: Developers", - - "Programming Language :: JavaScript", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - - "Topic :: Software Development :: Code Generators", - "Topic :: Utilities", - - "Typing :: Typed", - ], -) diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py index b51a164ff8c5e..50632eb42dae6 100644 --- a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/tests/unit/test_%name.PythonModule%_stack.template.py @@ -1,19 +1,21 @@ -import json -import pytest - -import aws_cdk_lib as core +import aws_cdk as core +import aws_cdk.assertions_alpha as assertions from %name.PythonModule%.%name.PythonModule%_stack import %name.PascalCased%Stack -def get_template(): +def test_sqs_queue_created(): app = core.App() - %name.PascalCased%Stack(app, "%name.StackName%") - return json.dumps(app.synth().get_stack("%name.StackName%").template) - + stack = %name.PascalCased%Stack(app, "%name.StackName%") + template = assertions.Template.from_stack(stack) -def test_sqs_queue_created(): - assert("AWS::SQS::Queue" in get_template()) + template.has_resource_properties("AWS::SQS::Queue", { + "VisibilityTimeout": 300 + }) def test_sns_topic_created(): - assert("AWS::SNS::Topic" in get_template()) + app = core.App() + stack = %name.PascalCased%Stack(app, "%name.StackName%") + template = assertions.Template.from_stack(stack) + + template.resource_count_is("AWS::SNS::Topic", 1) diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/package.template.json b/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/package.template.json index d4d76c656ba2e..20e4c3829d597 100644 --- a/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/package.template.json +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/package.template.json @@ -12,6 +12,7 @@ }, "devDependencies": { "aws-cdk": "%cdk-version%", + "@aws-cdk/assertions-alpha": "%cdk-version%", "@types/jest": "^26.0.10", "@types/node": "10.17.27", "jest": "^26.4.2", diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/test/%name%.test.template.ts b/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/test/%name%.test.template.ts index a563f50309295..5cfaa87ab2ce5 100644 --- a/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/test/%name%.test.template.ts +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/test/%name%.test.template.ts @@ -1,12 +1,17 @@ import * as cdk from 'aws-cdk-lib'; +import { Template, Match } from '@aws-cdk/assertions-alpha'; import * as %name.PascalCased% from '../lib/%name%-stack'; test('SQS Queue and SNS Topic Created', () => { - const app = new cdk.App(); - // WHEN - const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); - // THEN - const actual = JSON.stringify(app.synth().getStackArtifact(stack.artifactId).template); - expect(actual).toContain('AWS::SQS::Queue'); - expect(actual).toContain('AWS::SNS::Topic'); + const app = new cdk.App(); + // WHEN + const stack = new %name.PascalCased%.%name.PascalCased%Stack(app, 'MyTestStack'); + // THEN + + const template = Template.fromStack(stack); + + template.hasResourceProperties('AWS::SQS::Queue', { + VisibilityTimeout: 300 + }); + template.resourceCountIs('AWS::SNS::Topic', 1); }); diff --git a/packages/aws-cdk/test/integ/init/test-go.sh b/packages/aws-cdk/test/integ/init/test-go.sh index 6b461f3e25ef5..58959855073f0 100755 --- a/packages/aws-cdk/test/integ/init/test-go.sh +++ b/packages/aws-cdk/test/integ/init/test-go.sh @@ -5,13 +5,14 @@ set -eu scriptdir=$(cd $(dirname $0) && pwd) source ${scriptdir}/common.bash +dist_root=$(cd ${DIST_ROOT:-.} && pwd) header Go #------------------------------------------------------------------ if [[ "${1:-}" == "" ]]; then - templates="app" + templates="app sample-app" else templates="$@" fi @@ -22,5 +23,8 @@ for template in $templates; do setup cdk init -l go $template + go mod edit -replace github.com/aws/aws-cdk-go/awscdk=$dist_root/go/awscdk + go mod tidy + go test cdk synth done diff --git a/packages/aws-cdk/test/integ/init/test-java.sh b/packages/aws-cdk/test/integ/init/test-java.sh index f27441809da3c..d2c95984fb178 100755 --- a/packages/aws-cdk/test/integ/init/test-java.sh +++ b/packages/aws-cdk/test/integ/init/test-java.sh @@ -22,5 +22,6 @@ for template in $templates; do setup cdk init -l java $template + mvn package cdk synth done diff --git a/packages/aws-cdk/test/integ/init/test-python.sh b/packages/aws-cdk/test/integ/init/test-python.sh index 1f5163df5ae48..d40d94d4534ca 100755 --- a/packages/aws-cdk/test/integ/init/test-python.sh +++ b/packages/aws-cdk/test/integ/init/test-python.sh @@ -26,6 +26,8 @@ for template in $templates; do source .venv/bin/activate type -p pip pip install -r requirements.txt + ./.venv/bin/pip install -r requirements-dev.txt + pytest cdk synth done From 8d4aaca2d11d860f20659dd76bc7f9c68b17466f Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Thu, 4 Nov 2021 04:08:21 +0530 Subject: [PATCH 30/70] chore: npm-check-updates && yarn upgrade (#17304) Ran npm-check-updates and yarn upgrade to keep the `yarn.lock` file up-to-date. --- packages/@aws-cdk/core/package.json | 2 +- .../test/example-resource.test.ts | 4 ++++ packages/aws-cdk-lib/package.json | 2 +- packages/monocdk/package.json | 2 +- yarn.lock | 8 ++++---- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/@aws-cdk/core/package.json b/packages/@aws-cdk/core/package.json index 45e4232abb477..a57f69397dba1 100644 --- a/packages/@aws-cdk/core/package.json +++ b/packages/@aws-cdk/core/package.json @@ -191,7 +191,7 @@ "@balena/dockerignore": "^1.0.2", "constructs": "^3.3.69", "fs-extra": "^9.1.0", - "ignore": "^5.1.8", + "ignore": "^5.1.9", "minimatch": "^3.0.4" }, "bundledDependencies": [ diff --git a/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts b/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts index 7ef95e9a6e671..cbfb43344ad25 100644 --- a/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts +++ b/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts @@ -188,6 +188,10 @@ describe('Example Resource', () => { 'my-example-resource-name'); }); + test('throws when accessing connections', () => { + expect(() => exampleResource.connections).toThrow(); + }); + test('has the same name as it was imported with', () => { expect(exampleResource.exampleResourceName).toEqual('my-example-resource-name'); }); diff --git a/packages/aws-cdk-lib/package.json b/packages/aws-cdk-lib/package.json index de4d8379cac35..1d2d0c73daa50 100644 --- a/packages/aws-cdk-lib/package.json +++ b/packages/aws-cdk-lib/package.json @@ -114,7 +114,7 @@ "diff": "^5.0.0", "fast-deep-equal": "^3.1.3", "fs-extra": "^9.1.0", - "ignore": "^5.1.8", + "ignore": "^5.1.9", "jsonschema": "^1.4.0", "minimatch": "^3.0.4", "punycode": "^2.1.1", diff --git a/packages/monocdk/package.json b/packages/monocdk/package.json index 7e0b967fe70ab..49e11473c6be6 100644 --- a/packages/monocdk/package.json +++ b/packages/monocdk/package.json @@ -111,7 +111,7 @@ "diff": "^5.0.0", "fast-deep-equal": "^3.1.3", "fs-extra": "^9.1.0", - "ignore": "^5.1.8", + "ignore": "^5.1.9", "jsonschema": "^1.4.0", "minimatch": "^3.0.4", "punycode": "^2.1.1", diff --git a/yarn.lock b/yarn.lock index 88df4ad3d4edb..97a3298a6c72f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5277,10 +5277,10 @@ ignore@^4.0.6: resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8, ignore@~5.1.8: - version "5.1.8" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8, ignore@^5.1.9, ignore@~5.1.8: + version "5.1.9" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.1.9.tgz#9ec1a5cbe8e1446ec60d4420060d43aa6e7382fb" + integrity sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ== immediate@~3.0.5: version "3.0.6" From 5333c72a66955995a65cb365c6a788b82f02afd2 Mon Sep 17 00:00:00 2001 From: Roman <491247+moltar@users.noreply.github.com> Date: Thu, 4 Nov 2021 06:31:37 +0700 Subject: [PATCH 31/70] docs(aws-stepfunctions-tasks): fixes action example to be camelCase (#17292) > Use camelCase for actions and PascalCase for parameter names. ---- *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-stepfunctions-tasks/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md index cedf89eefe07c..2f5d463067a35 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md @@ -348,7 +348,7 @@ action name does not match with the API service/action name: ```ts const listBuckets = new tasks.CallAwsService(this, 'ListBuckets', { service: 's3', - action: 'ListBuckets', + action: 'listBuckets', iamResources: ['*'], iamAction: 's3:ListAllMyBuckets', }); From 30ac0cc2d95ef3fd79d0658428975ea675b6916f Mon Sep 17 00:00:00 2001 From: Berend de Boer Date: Thu, 4 Nov 2021 13:25:20 +1300 Subject: [PATCH 32/70] fix(s3): enforce that fromBucketAttributes supplies a valid bucket name (#16915) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-apigateway/test/domains.test.ts | 8 +- .../aws-cloudtrail/test/cloudtrail.test.ts | 4 +- .../aws-codebuild/test/project.test.ts | 8 +- .../aws-ec2/test/cfn-init-element.test.ts | 4 +- .../@aws-cdk/aws-ec2/test/cfn-init.test.ts | 2 +- packages/@aws-cdk/aws-glue/test/code.test.ts | 8 +- .../aws-glue/test/job-executable.test.ts | 2 +- packages/@aws-cdk/aws-glue/test/job.test.ts | 28 +++--- .../test/notifications.test.ts | 14 +-- packages/@aws-cdk/aws-s3/lib/bucket.ts | 90 ++++++++++--------- packages/@aws-cdk/aws-s3/test/bucket.test.ts | 26 ++++-- .../pipelines/test/compliance/synths.test.ts | 4 +- .../test/compliance/validations.test.ts | 4 +- 13 files changed, 108 insertions(+), 94 deletions(-) diff --git a/packages/@aws-cdk/aws-apigateway/test/domains.test.ts b/packages/@aws-cdk/aws-apigateway/test/domains.test.ts index 7ad0f4224d70b..7b8817df48853 100644 --- a/packages/@aws-cdk/aws-apigateway/test/domains.test.ts +++ b/packages/@aws-cdk/aws-apigateway/test/domains.test.ts @@ -388,7 +388,7 @@ describe('domains', () => { test('accepts a mutual TLS configuration', () => { const stack = new Stack(); - const bucket = Bucket.fromBucketName(stack, 'testBucket', 'exampleBucket'); + const bucket = Bucket.fromBucketName(stack, 'testBucket', 'example-bucket'); new apigw.DomainName(stack, 'another-domain', { domainName: 'example.com', mtls: { @@ -402,14 +402,14 @@ describe('domains', () => { 'DomainName': 'example.com', 'EndpointConfiguration': { 'Types': ['REGIONAL'] }, 'RegionalCertificateArn': 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d', - 'MutualTlsAuthentication': { 'TruststoreUri': 's3://exampleBucket/someca.pem' }, + 'MutualTlsAuthentication': { 'TruststoreUri': 's3://example-bucket/someca.pem' }, }); }); test('mTLS should allow versions to be set on the s3 bucket', () => { const stack = new Stack(); - const bucket = Bucket.fromBucketName(stack, 'testBucket', 'exampleBucket'); + const bucket = Bucket.fromBucketName(stack, 'testBucket', 'example-bucket'); new apigw.DomainName(stack, 'another-domain', { domainName: 'example.com', certificate: acm.Certificate.fromCertificateArn(stack, 'cert2', 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d'), @@ -423,7 +423,7 @@ describe('domains', () => { 'DomainName': 'example.com', 'EndpointConfiguration': { 'Types': ['REGIONAL'] }, 'RegionalCertificateArn': 'arn:aws:acm:us-east-1:1111111:certificate/11-3336f1-44483d-adc7-9cd375c5169d', - 'MutualTlsAuthentication': { 'TruststoreUri': 's3://exampleBucket/someca.pem', 'TruststoreVersion': 'version' }, + 'MutualTlsAuthentication': { 'TruststoreUri': 's3://example-bucket/someca.pem', 'TruststoreVersion': 'version' }, }); }); diff --git a/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts b/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts index c00f01d43acc4..89bd89d84c31c 100644 --- a/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts +++ b/packages/@aws-cdk/aws-cloudtrail/test/cloudtrail.test.ts @@ -131,13 +131,13 @@ describe('cloudtrail', () => { test('with imported s3 bucket', () => { // GIVEN const stack = getTestStack(); - const bucket = s3.Bucket.fromBucketName(stack, 'S3', 'SomeBucket'); + const bucket = s3.Bucket.fromBucketName(stack, 'S3', 'somebucket'); // WHEN new Trail(stack, 'Trail', { bucket }); expect(stack).toHaveResource('AWS::CloudTrail::Trail', { - S3BucketName: 'SomeBucket', + S3BucketName: 'somebucket', }); }); diff --git a/packages/@aws-cdk/aws-codebuild/test/project.test.ts b/packages/@aws-cdk/aws-codebuild/test/project.test.ts index 08fbe3e8f8768..0041d1651ec9d 100644 --- a/packages/@aws-cdk/aws-codebuild/test/project.test.ts +++ b/packages/@aws-cdk/aws-codebuild/test/project.test.ts @@ -673,7 +673,7 @@ describe('Environment', () => { test('logs config - s3', () => { // GIVEN const stack = new cdk.Stack(); - const bucket = s3.Bucket.fromBucketName(stack, 'LogBucket', 'MyBucketName'); + const bucket = s3.Bucket.fromBucketName(stack, 'LogBucket', 'mybucketname'); // WHEN new codebuild.Project(stack, 'Project', { @@ -693,7 +693,7 @@ describe('Environment', () => { expect(stack).toHaveResourceLike('AWS::CodeBuild::Project', { LogsConfig: objectLike({ S3Logs: { - Location: 'MyBucketName/my-logs', + Location: 'mybucketname/my-logs', Status: 'ENABLED', }, }), @@ -703,7 +703,7 @@ describe('Environment', () => { test('logs config - cloudWatch and s3', () => { // GIVEN const stack = new cdk.Stack(); - const bucket = s3.Bucket.fromBucketName(stack, 'LogBucket2', 'MyBucketName'); + const bucket = s3.Bucket.fromBucketName(stack, 'LogBucket2', 'mybucketname'); const logGroup = logs.LogGroup.fromLogGroupName(stack, 'LogGroup2', 'MyLogGroupName'); // WHEN @@ -730,7 +730,7 @@ describe('Environment', () => { Status: 'ENABLED', }, S3Logs: { - Location: 'MyBucketName', + Location: 'mybucketname', Status: 'ENABLED', }, }), diff --git a/packages/@aws-cdk/aws-ec2/test/cfn-init-element.test.ts b/packages/@aws-cdk/aws-ec2/test/cfn-init-element.test.ts index 75896912f3661..8f1c4951d2bf3 100644 --- a/packages/@aws-cdk/aws-ec2/test/cfn-init-element.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/cfn-init-element.test.ts @@ -664,7 +664,7 @@ describe('InitSource', () => { test('fromS3Object uses object URL', () => { // GIVEN - const bucket = s3.Bucket.fromBucketName(stack, 'bucket', 'MyBucket'); + const bucket = s3.Bucket.fromBucketName(stack, 'bucket', 'mybucket'); const source = ec2.InitSource.fromS3Object('/tmp/foo', bucket, 'myKey'); // WHEN @@ -672,7 +672,7 @@ describe('InitSource', () => { // THEN expect(rendered).toEqual({ - '/tmp/foo': expect.stringContaining('/MyBucket/myKey'), + '/tmp/foo': expect.stringContaining('/mybucket/myKey'), }); }); diff --git a/packages/@aws-cdk/aws-ec2/test/cfn-init.test.ts b/packages/@aws-cdk/aws-ec2/test/cfn-init.test.ts index 37d4fe2d72d28..2a9cce5e76719 100644 --- a/packages/@aws-cdk/aws-ec2/test/cfn-init.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/cfn-init.test.ts @@ -667,7 +667,7 @@ class SingletonLocationSythesizer extends DefaultStackSynthesizer { public addFileAsset(_asset: FileAssetSource): FileAssetLocation { const httpUrl = 'https://MyBucket.s3.amazonaws.com/MyAsset'; return { - bucketName: 'MyAssetBucket', + bucketName: 'myassetbucket', objectKey: 'MyAssetFile', httpUrl, s3ObjectUrl: httpUrl, diff --git a/packages/@aws-cdk/aws-glue/test/code.test.ts b/packages/@aws-cdk/aws-glue/test/code.test.ts index 061f6d26c351f..8049bc1b29c6a 100644 --- a/packages/@aws-cdk/aws-glue/test/code.test.ts +++ b/packages/@aws-cdk/aws-glue/test/code.test.ts @@ -17,7 +17,7 @@ describe('Code', () => { let bucket: s3.IBucket; test('with valid bucket name and key and bound by job sets the right path and grants the job permissions to read from it', () => { - bucket = s3.Bucket.fromBucketName(stack, 'Bucket', 'bucketName'); + bucket = s3.Bucket.fromBucketName(stack, 'Bucket', 'bucketname'); script = glue.Code.fromBucket(bucket, key); new glue.Job(stack, 'Job1', { executable: glue.JobExecutable.pythonShell({ @@ -29,7 +29,7 @@ describe('Code', () => { Template.fromStack(stack).hasResourceProperties('AWS::Glue::Job', { Command: { - ScriptLocation: 's3://bucketName/script', + ScriptLocation: 's3://bucketname/script', }, }); @@ -53,7 +53,7 @@ describe('Code', () => { { Ref: 'AWS::Partition', }, - ':s3:::bucketName', + ':s3:::bucketname', ], ], }, @@ -65,7 +65,7 @@ describe('Code', () => { { Ref: 'AWS::Partition', }, - ':s3:::bucketName/script', + ':s3:::bucketname/script', ], ], }, diff --git a/packages/@aws-cdk/aws-glue/test/job-executable.test.ts b/packages/@aws-cdk/aws-glue/test/job-executable.test.ts index 481bd16dc8944..5fcf3b1487764 100644 --- a/packages/@aws-cdk/aws-glue/test/job-executable.test.ts +++ b/packages/@aws-cdk/aws-glue/test/job-executable.test.ts @@ -31,7 +31,7 @@ describe('JobExecutable', () => { beforeEach(() => { stack = new cdk.Stack(); - bucket = s3.Bucket.fromBucketName(stack, 'Bucket', 'bucketName'); + bucket = s3.Bucket.fromBucketName(stack, 'Bucket', 'bucketname'); script = glue.Code.fromBucket(bucket, 'script.py'); }); diff --git a/packages/@aws-cdk/aws-glue/test/job.test.ts b/packages/@aws-cdk/aws-glue/test/job.test.ts index 625e4743570fd..c338b4d09cb42 100644 --- a/packages/@aws-cdk/aws-glue/test/job.test.ts +++ b/packages/@aws-cdk/aws-glue/test/job.test.ts @@ -55,7 +55,7 @@ describe('Job', () => { describe('new', () => { const className = 'com.amazon.test.ClassName'; - const codeBucketName = 'bucketName'; + const codeBucketName = 'bucketname'; const codeBucketAccessStatement = { Action: [ 's3:GetObject*', @@ -166,7 +166,7 @@ describe('Job', () => { Template.fromStack(stack).hasResourceProperties('AWS::Glue::Job', { Command: { Name: 'glueetl', - ScriptLocation: 's3://bucketName/script', + ScriptLocation: 's3://bucketname/script', }, Role: { 'Fn::GetAtt': [ @@ -383,7 +383,7 @@ describe('Job', () => { }); describe('with bucket provided', () => { - const sparkUIBucketName = 'sparkBucketName'; + const sparkUIBucketName = 'sparkbucketname'; let sparkUIBucket: s3.IBucket; beforeEach(() => { @@ -420,7 +420,7 @@ describe('Job', () => { { Ref: 'AWS::Partition', }, - ':s3:::sparkBucketName', + ':s3:::sparkbucketname', ], ], }, @@ -432,7 +432,7 @@ describe('Job', () => { { Ref: 'AWS::Partition', }, - ':s3:::sparkBucketName/*', + ':s3:::sparkbucketname/*', ], ], }, @@ -460,7 +460,7 @@ describe('Job', () => { }); describe('with bucket and path provided', () => { - const sparkUIBucketName = 'sparkBucketName'; + const sparkUIBucketName = 'sparkbucketname'; const prefix = 'some/path/'; let sparkUIBucket: s3.IBucket; @@ -516,7 +516,7 @@ describe('Job', () => { Template.fromStack(stack).hasResourceProperties('AWS::Glue::Job', { Command: { Name: 'glueetl', - ScriptLocation: 's3://bucketName/script', + ScriptLocation: 's3://bucketname/script', }, Role: { 'Fn::GetAtt': [ @@ -614,7 +614,7 @@ describe('Job', () => { GlueVersion: '2.0', Command: { Name: 'glueetl', - ScriptLocation: 's3://bucketName/script', + ScriptLocation: 's3://bucketname/script', PythonVersion: '3', }, Role: { @@ -625,9 +625,9 @@ describe('Job', () => { }, DefaultArguments: { '--job-language': 'python', - '--extra-jars': 's3://bucketName/file1.jar,s3://bucketName/file2.jar', - '--extra-py-files': 's3://bucketName/file1.py,s3://bucketName/file2.py', - '--extra-files': 's3://bucketName/file1.txt,s3://bucketName/file2.txt', + '--extra-jars': 's3://bucketname/file1.jar,s3://bucketname/file2.jar', + '--extra-py-files': 's3://bucketname/file1.py,s3://bucketname/file2.py', + '--extra-files': 's3://bucketname/file1.txt,s3://bucketname/file2.txt', '--user-jars-first': 'true', }, }); @@ -649,7 +649,7 @@ describe('Job', () => { GlueVersion: '2.0', Command: { Name: 'gluestreaming', - ScriptLocation: 's3://bucketName/script', + ScriptLocation: 's3://bucketname/script', }, Role: { 'Fn::GetAtt': [ @@ -660,8 +660,8 @@ describe('Job', () => { DefaultArguments: { '--job-language': 'scala', '--class': 'com.amazon.test.ClassName', - '--extra-jars': 's3://bucketName/file1.jar,s3://bucketName/file2.jar', - '--extra-files': 's3://bucketName/file1.txt,s3://bucketName/file2.txt', + '--extra-jars': 's3://bucketname/file1.jar,s3://bucketname/file2.jar', + '--extra-files': 's3://bucketname/file1.txt,s3://bucketname/file2.txt', '--user-jars-first': 'true', }, }); diff --git a/packages/@aws-cdk/aws-s3-notifications/test/notifications.test.ts b/packages/@aws-cdk/aws-s3-notifications/test/notifications.test.ts index 43922fb54cc5d..2bfe968f99279 100644 --- a/packages/@aws-cdk/aws-s3-notifications/test/notifications.test.ts +++ b/packages/@aws-cdk/aws-s3-notifications/test/notifications.test.ts @@ -336,7 +336,7 @@ describe('CloudWatch Events', () => { test('onCloudTrailPutObject contains the Bucket ARN itself when path is undefined', () => { const stack = new cdk.Stack(); const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', { - bucketName: 'MyBucket', + bucketName: 'mybucket', }); bucket.onCloudTrailPutObject('PutRule', { target: { @@ -363,7 +363,7 @@ describe('CloudWatch Events', () => { { 'Ref': 'AWS::Partition', }, - ':s3:::MyBucket', + ':s3:::mybucket', ], ], }, @@ -378,7 +378,7 @@ describe('CloudWatch Events', () => { test("onCloudTrailPutObject contains the path when it's provided", () => { const stack = new cdk.Stack(); const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', { - bucketName: 'MyBucket', + bucketName: 'mybucket', }); bucket.onCloudTrailPutObject('PutRule', { target: { @@ -406,7 +406,7 @@ describe('CloudWatch Events', () => { { 'Ref': 'AWS::Partition', }, - ':s3:::MyBucket/my/path.zip', + ':s3:::mybucket/my/path.zip', ], ], }, @@ -421,7 +421,7 @@ describe('CloudWatch Events', () => { test('onCloudTrailWriteObject matches on events CompleteMultipartUpload, CopyObject, and PutObject', () => { const stack = new cdk.Stack(); const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', { - bucketName: 'MyBucket', + bucketName: 'mybucket', }); bucket.onCloudTrailWriteObject('OnCloudTrailWriteObjectRule', { target: { @@ -449,7 +449,7 @@ describe('CloudWatch Events', () => { test('onCloudTrailWriteObject matches on the requestParameter bucketName when the path is not provided', () => { const stack = new cdk.Stack(); const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', { - bucketName: 'MyBucket', + bucketName: 'mybucket', }); bucket.onCloudTrailWriteObject('OnCloudTrailWriteObjectRule', { target: { @@ -476,7 +476,7 @@ describe('CloudWatch Events', () => { test('onCloudTrailWriteObject matches on the requestParameters bucketName and key when the path is provided', () => { const stack = new cdk.Stack(); const bucket = s3.Bucket.fromBucketAttributes(stack, 'Bucket', { - bucketName: 'MyBucket', + bucketName: 'mybucket', }); bucket.onCloudTrailWriteObject('OnCloudTrailWriteObjectRule', { target: { diff --git a/packages/@aws-cdk/aws-s3/lib/bucket.ts b/packages/@aws-cdk/aws-s3/lib/bucket.ts index 67037f874bc3e..157aa31a3ed5f 100644 --- a/packages/@aws-cdk/aws-s3/lib/bucket.ts +++ b/packages/@aws-cdk/aws-s3/lib/bucket.ts @@ -1396,6 +1396,7 @@ export class Bucket extends BucketBase { if (!bucketName) { throw new Error('Bucket name is required'); } + Bucket.validateBucketName(bucketName); const newUrlFormat = attrs.bucketWebsiteNewUrlFormat === undefined ? false @@ -1434,6 +1435,52 @@ export class Bucket extends BucketBase { }); } + /** + * Thrown an exception if the given bucket name is not valid. + * + * @param physicalName name of the bucket. + */ + public static validateBucketName(physicalName: string): void { + const bucketName = physicalName; + if (!bucketName || Token.isUnresolved(bucketName)) { + // the name is a late-bound value, not a defined string, + // so skip validation + return; + } + + const errors: string[] = []; + + // Rules codified from https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html + if (bucketName.length < 3 || bucketName.length > 63) { + errors.push('Bucket name must be at least 3 and no more than 63 characters'); + } + const charsetMatch = bucketName.match(/[^a-z0-9.-]/); + if (charsetMatch) { + errors.push('Bucket name must only contain lowercase characters and the symbols, period (.) and dash (-) ' + + `(offset: ${charsetMatch.index})`); + } + if (!/[a-z0-9]/.test(bucketName.charAt(0))) { + errors.push('Bucket name must start and end with a lowercase character or number ' + + '(offset: 0)'); + } + if (!/[a-z0-9]/.test(bucketName.charAt(bucketName.length - 1))) { + errors.push('Bucket name must start and end with a lowercase character or number ' + + `(offset: ${bucketName.length - 1})`); + } + const consecSymbolMatch = bucketName.match(/\.-|-\.|\.\./); + if (consecSymbolMatch) { + errors.push('Bucket name must not have dash next to period, or period next to dash, or consecutive periods ' + + `(offset: ${consecSymbolMatch.index})`); + } + if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(bucketName)) { + errors.push('Bucket name must not resemble an IP address'); + } + + if (errors.length > 0) { + throw new Error(`Invalid S3 bucket name (value: ${bucketName})${EOL}${errors.join(EOL)}`); + } + } + public readonly bucketArn: string; public readonly bucketName: string; public readonly bucketDomainName: string; @@ -1462,7 +1509,7 @@ export class Bucket extends BucketBase { const { bucketEncryption, encryptionKey } = this.parseEncryption(props); - this.validateBucketName(this.physicalName); + Bucket.validateBucketName(this.physicalName); const websiteConfiguration = this.renderWebsiteConfiguration(props); this.isWebsite = (websiteConfiguration !== undefined); @@ -1600,47 +1647,6 @@ export class Bucket extends BucketBase { this.addToResourcePolicy(statement); } - private validateBucketName(physicalName: string): void { - const bucketName = physicalName; - if (!bucketName || Token.isUnresolved(bucketName)) { - // the name is a late-bound value, not a defined string, - // so skip validation - return; - } - - const errors: string[] = []; - - // Rules codified from https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html - if (bucketName.length < 3 || bucketName.length > 63) { - errors.push('Bucket name must be at least 3 and no more than 63 characters'); - } - const charsetMatch = bucketName.match(/[^a-z0-9.-]/); - if (charsetMatch) { - errors.push('Bucket name must only contain lowercase characters and the symbols, period (.) and dash (-) ' - + `(offset: ${charsetMatch.index})`); - } - if (!/[a-z0-9]/.test(bucketName.charAt(0))) { - errors.push('Bucket name must start and end with a lowercase character or number ' - + '(offset: 0)'); - } - if (!/[a-z0-9]/.test(bucketName.charAt(bucketName.length - 1))) { - errors.push('Bucket name must start and end with a lowercase character or number ' - + `(offset: ${bucketName.length - 1})`); - } - const consecSymbolMatch = bucketName.match(/\.-|-\.|\.\./); - if (consecSymbolMatch) { - errors.push('Bucket name must not have dash next to period, or period next to dash, or consecutive periods ' - + `(offset: ${consecSymbolMatch.index})`); - } - if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(bucketName)) { - errors.push('Bucket name must not resemble an IP address'); - } - - if (errors.length > 0) { - throw new Error(`Invalid S3 bucket name (value: ${bucketName})${EOL}${errors.join(EOL)}`); - } - } - /** * Set up key properties and return the Bucket encryption property from the * user's configuration. diff --git a/packages/@aws-cdk/aws-s3/test/bucket.test.ts b/packages/@aws-cdk/aws-s3/test/bucket.test.ts index 3ef166722c1b6..67d263aa60ea5 100644 --- a/packages/@aws-cdk/aws-s3/test/bucket.test.ts +++ b/packages/@aws-cdk/aws-s3/test/bucket.test.ts @@ -3,9 +3,9 @@ import { EOL } from 'os'; import { ResourcePart, SynthUtils, arrayWith, objectLike } from '@aws-cdk/assert-internal'; import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; +import { testFutureBehavior, testLegacyBehavior } from '@aws-cdk/cdk-build-tools/lib/feature-flag'; import * as cdk from '@aws-cdk/core'; import * as cxapi from '@aws-cdk/cx-api'; -import { testFutureBehavior, testLegacyBehavior } from '@aws-cdk/cdk-build-tools/lib/feature-flag'; import * as s3 from '../lib'; // to make it easy to copy & paste from output: @@ -103,8 +103,6 @@ describe('bucket', () => { expect(() => new s3.Bucket(stack, 'MyBucket2', { bucketName: '124.pp--33', })).not.toThrow(); - - }); test('bucket validation skips tokenized values', () => { @@ -746,14 +744,24 @@ describe('bucket', () => { }); const bucket = s3.Bucket.fromBucketAttributes(stack, 'ImportedBucket', { - bucketName: 'myBucket', + bucketName: 'mybucket', region: 'eu-west-1', }); - expect(bucket.bucketRegionalDomainName).toEqual(`myBucket.s3.eu-west-1.${stack.urlSuffix}`); - expect(bucket.bucketWebsiteDomainName).toEqual(`myBucket.s3-website-eu-west-1.${stack.urlSuffix}`); + expect(bucket.bucketRegionalDomainName).toEqual(`mybucket.s3.eu-west-1.${stack.urlSuffix}`); + expect(bucket.bucketWebsiteDomainName).toEqual(`mybucket.s3-website-eu-west-1.${stack.urlSuffix}`); + + }); + + test('import needs to specify a valid bucket name', () => { + const stack = new cdk.Stack(undefined, undefined, { + env: { region: 'us-east-1' }, + }); + expect(() => s3.Bucket.fromBucketAttributes(stack, 'MyBucket3', { + bucketName: 'arn:aws:s3:::example-com', + })).toThrow(); }); }); @@ -2129,11 +2137,11 @@ describe('bucket', () => { const stack = new cdk.Stack(); // WHEN - const bucket = s3.Bucket.fromBucketArn(stack, 'my-bucket', 'arn:aws:s3:::my_corporate_bucket'); + const bucket = s3.Bucket.fromBucketArn(stack, 'my-bucket', 'arn:aws:s3:::my-corporate-bucket'); // THEN - expect(bucket.bucketName).toEqual('my_corporate_bucket'); - expect(bucket.bucketArn).toEqual('arn:aws:s3:::my_corporate_bucket'); + expect(bucket.bucketName).toEqual('my-corporate-bucket'); + expect(bucket.bucketArn).toEqual('arn:aws:s3:::my-corporate-bucket'); }); diff --git a/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts b/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts index 4b5a072099469..acbce1d765f36 100644 --- a/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts +++ b/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts @@ -748,7 +748,7 @@ behavior('Pipeline action contains a hash that changes as the buildspec changes' behavior('Synth CodeBuild project role can be granted permissions', (suite) => { let bucket: s3.IBucket; beforeEach(() => { - bucket = s3.Bucket.fromBucketArn(pipelineStack, 'Bucket', 'arn:aws:s3:::ThisParticularBucket'); + bucket = s3.Bucket.fromBucketArn(pipelineStack, 'Bucket', 'arn:aws:s3:::this-particular-bucket'); }); @@ -787,7 +787,7 @@ behavior('Synth CodeBuild project role can be granted permissions', (suite) => { PolicyDocument: { Statement: Match.arrayWith([Match.objectLike({ Action: ['s3:GetObject*', 's3:GetBucket*', 's3:List*'], - Resource: ['arn:aws:s3:::ThisParticularBucket', 'arn:aws:s3:::ThisParticularBucket/*'], + Resource: ['arn:aws:s3:::this-particular-bucket', 'arn:aws:s3:::this-particular-bucket/*'], })]), }, }); diff --git a/packages/@aws-cdk/pipelines/test/compliance/validations.test.ts b/packages/@aws-cdk/pipelines/test/compliance/validations.test.ts index 7a6a562a8707a..c61cd40474388 100644 --- a/packages/@aws-cdk/pipelines/test/compliance/validations.test.ts +++ b/packages/@aws-cdk/pipelines/test/compliance/validations.test.ts @@ -463,7 +463,7 @@ behavior('can add policy statements to shell script action', (suite) => { behavior('can grant permissions to shell script action', (suite) => { let bucket: s3.IBucket; beforeEach(() => { - bucket = s3.Bucket.fromBucketArn(pipelineStack, 'Bucket', 'arn:aws:s3:::ThisParticularBucket'); + bucket = s3.Bucket.fromBucketArn(pipelineStack, 'Bucket', 'arn:aws:s3:::this-particular-bucket'); }); suite.legacy(() => { @@ -505,7 +505,7 @@ behavior('can grant permissions to shell script action', (suite) => { PolicyDocument: { Statement: Match.arrayWith([Match.objectLike({ Action: ['s3:GetObject*', 's3:GetBucket*', 's3:List*'], - Resource: ['arn:aws:s3:::ThisParticularBucket', 'arn:aws:s3:::ThisParticularBucket/*'], + Resource: ['arn:aws:s3:::this-particular-bucket', 'arn:aws:s3:::this-particular-bucket/*'], })]), }, }); From e32b61652b5d01c44b05c2ac6d5fb1e99b50e059 Mon Sep 17 00:00:00 2001 From: Adam Ruka Date: Thu, 4 Nov 2021 02:53:56 -0700 Subject: [PATCH 33/70] fix(cli): no longer disable rollback by default for hotswap deployments (#17317) Previously, we would default the `--rollback` flag to `false` if it wasn't explicitly provided if the `--hotswap` option was also passed to `cdk deploy`. However, disable rollback does not play well with deployments that cause replacements - they fail, and leave the Stack in a weird state. For that reason, stop disabling rollback by default. It's still possible to disable rollback easily if a customer wants to by using the `-R` switch. Fixes #17267 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/bin/cdk.ts | 9 ++++++--- packages/aws-cdk/lib/api/deploy-stack.ts | 2 +- packages/aws-cdk/lib/cdk-toolkit.ts | 1 + packages/aws-cdk/test/api/deploy-stack.test.ts | 4 ++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/aws-cdk/bin/cdk.ts b/packages/aws-cdk/bin/cdk.ts index aaaef0deb3182..b5b60f895c8ca 100644 --- a/packages/aws-cdk/bin/cdk.ts +++ b/packages/aws-cdk/bin/cdk.ts @@ -105,10 +105,13 @@ async function parseCommandLineArguments() { .option('outputs-file', { type: 'string', alias: 'O', desc: 'Path to file where stack outputs will be written as JSON', requiresArg: true }) .option('previous-parameters', { type: 'boolean', default: true, desc: 'Use previous values for existing parameters (you must specify all parameters on every deployment if this is disabled)' }) .option('progress', { type: 'string', choices: [StackActivityProgress.BAR, StackActivityProgress.EVENTS], desc: 'Display mode for stack activity events' }) - .option('rollback', { type: 'boolean', desc: 'Rollback stack to stable state on failure (iterate more rapidly with --no-rollback or -R)' }) + .option('rollback', { + type: 'boolean', + desc: "Rollback stack to stable state on failure. Defaults to 'true', iterate more rapidly with --no-rollback or -R. " + + 'Note: do **not** disable this flag for deployments with resource replacements, as that will always fail', + }) // Hack to get '-R' as an alias for '--no-rollback', suggested by: https://github.com/yargs/yargs/issues/1729 - .option('R', { type: 'boolean', hidden: true }) - .middleware(yargsNegativeAlias('R', 'rollback'), true) + .option('R', { type: 'boolean', hidden: true }).middleware(yargsNegativeAlias('R', 'rollback'), true) .option('hotswap', { type: 'boolean', desc: "Attempts to perform a 'hotswap' deployment, " + diff --git a/packages/aws-cdk/lib/api/deploy-stack.ts b/packages/aws-cdk/lib/api/deploy-stack.ts index ab662d34b517c..2d35a3a01aea0 100644 --- a/packages/aws-cdk/lib/api/deploy-stack.ts +++ b/packages/aws-cdk/lib/api/deploy-stack.ts @@ -317,7 +317,7 @@ async function prepareAndExecuteChangeSet( if (execute) { debug('Initiating execution of changeset %s on stack %s', changeSet.Id, deployName); - const shouldDisableRollback = (options.rollback === undefined && options.hotswap === true) || options.rollback === false; + const shouldDisableRollback = options.rollback === false; // Do a bit of contortions to only pass the `DisableRollback` flag if it's true. That way, // CloudFormation won't balk at the unrecognized option in regions where the feature is not available yet. const disableRollback = shouldDisableRollback ? { DisableRollback: true } : undefined; diff --git a/packages/aws-cdk/lib/cdk-toolkit.ts b/packages/aws-cdk/lib/cdk-toolkit.ts index 65aa443190a57..cd5e591dce866 100644 --- a/packages/aws-cdk/lib/cdk-toolkit.ts +++ b/packages/aws-cdk/lib/cdk-toolkit.ts @@ -650,6 +650,7 @@ export interface DeployOptions { * @default true */ readonly rollback?: boolean; + /* * Whether to perform a 'hotswap' deployment. * A 'hotswap' deployment will attempt to short-circuit CloudFormation diff --git a/packages/aws-cdk/test/api/deploy-stack.test.ts b/packages/aws-cdk/test/api/deploy-stack.test.ts index 13e4640ff01ec..4770e2ad9528f 100644 --- a/packages/aws-cdk/test/api/deploy-stack.test.ts +++ b/packages/aws-cdk/test/api/deploy-stack.test.ts @@ -98,7 +98,7 @@ test("does not call tryHotswapDeployment() if 'hotswap' is false", async () => { expect(tryHotswapDeployment).not.toHaveBeenCalled(); }); -test("rollback defaults to disabled if 'hotswap' is true", async () => { +test("rollback still defaults to enabled even if 'hotswap' is enabled", async () => { // WHEN await deployStack({ ...standardDeployStackArguments(), @@ -107,7 +107,7 @@ test("rollback defaults to disabled if 'hotswap' is true", async () => { }); // THEN - expect(cfnMocks.executeChangeSet).toHaveBeenCalledWith(expect.objectContaining({ + expect(cfnMocks.executeChangeSet).not.toHaveBeenCalledWith(expect.objectContaining({ DisableRollback: true, })); }); From c8cd515b3984ce0d8bfbe2d19cd56d299785e78b Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Thu, 4 Nov 2021 12:18:29 +0200 Subject: [PATCH 34/70] revert: "chore: activate 'rosetta infuse' feature (#17191)" (#17329) revert: "chore: activate 'rosetta infuse' feature (#17191)" --- pack.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/pack.sh b/pack.sh index 3c2d7dbce6c1a..168a17f972406 100755 --- a/pack.sh +++ b/pack.sh @@ -39,17 +39,12 @@ function lerna_scopes() { # Compile examples with respect to "decdk" directory, as all packages will # be symlinked there so they can all be included. echo "Extracting code samples" >&2 -$ROSETTA extract \ +node --experimental-worker $(which $ROSETTA) \ --compile \ --output samples.tabl.json \ --directory packages/decdk \ $(cat $TMPDIR/jsii.txt) -echo "Infusing examples back into assemblies" >&2 -$ROSETTA infuse \ - samples.tabl.json \ - $(cat $TMPDIR/jsii.txt) - # Jsii packaging (all at once using jsii-pacmak) echo "Packaging jsii modules" >&2 $PACMAK \ From d9f7b58a91a625ffd9bc366767794a3101b0afeb Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Thu, 4 Nov 2021 17:08:34 +0530 Subject: [PATCH 35/70] feat(cfnspec): cloudformation spec v46.0.0 (#17223) * feat: cloudformation spec v46.0.0 * fix generated code for new libraries: aws-panorama, aws-rekognition, aws-wisdom * fix ec2 * Revert "fix ec2" This reverts commit d961ddedc5c0cb76a0e07f3ec4c798bf2cf0bb41. * add awslint excludes to ec2 module * fix secretsmanager - add default RemovalPolicy * update snapshot tests in aws-docdb because of secretsmanager removal policy change * amplify * elasticsearch and opensearch * esc snapshots * rds snapshots Co-authored-by: AWS CDK Team Co-authored-by: Madeline Kusters Co-authored-by: Eli Polonsky --- .../aws-amplify/test/integ.app.expected.json | 4 +- .../integ.cluster-rotation.lit.expected.json | 4 +- .../test/integ.cluster.expected.json | 14 +- packages/@aws-cdk/aws-ec2/package.json | 2 + .../ec2/integ.secret-json-field.expected.json | 4 +- .../test/fargate/integ.secret.expected.json | 4 +- .../integ.elasticsearch-vpc.expected.json | 18 +- ...elasticsearch.custom-kms-key.expected.json | 18 +- .../test/integ.elasticsearch.expected.json | 18 +- ...sticsearch.unsignedbasicauth.expected.json | 22 +- ...eg.opensearch.custom-kms-key.expected.json | 18 +- .../test/integ.opensearch.expected.json | 18 +- ...opensearch.unsignedbasicauth.expected.json | 22 +- packages/@aws-cdk/aws-panorama/.eslintrc.js | 3 + packages/@aws-cdk/aws-panorama/.gitignore | 19 + packages/@aws-cdk/aws-panorama/.npmignore | 29 + packages/@aws-cdk/aws-panorama/LICENSE | 201 ++ packages/@aws-cdk/aws-panorama/NOTICE | 2 + packages/@aws-cdk/aws-panorama/README.md | 20 + packages/@aws-cdk/aws-panorama/jest.config.js | 2 + packages/@aws-cdk/aws-panorama/lib/index.ts | 2 + packages/@aws-cdk/aws-panorama/package.json | 105 + .../aws-panorama/test/aws-panorama.test.ts | 6 + .../integ.cluster-rotation.lit.expected.json | 4 +- ...ance-from-generated-password.expected.json | 22 +- .../integ.instance-s3-postgres.expected.json | 4 +- .../test/integ.instance-s3.expected.json | 18 +- .../aws-rds/test/integ.instance-s3.ts | 2 +- .../test/integ.instance.lit.expected.json | 54 +- .../aws-rds/test/integ.instance.lit.ts | 2 +- .../aws-rds/test/integ.proxy.expected.json | 16 +- .../@aws-cdk/aws-rekognition/.eslintrc.js | 3 + packages/@aws-cdk/aws-rekognition/.gitignore | 19 + packages/@aws-cdk/aws-rekognition/.npmignore | 29 + packages/@aws-cdk/aws-rekognition/LICENSE | 201 ++ packages/@aws-cdk/aws-rekognition/NOTICE | 2 + packages/@aws-cdk/aws-rekognition/README.md | 20 + .../@aws-cdk/aws-rekognition/jest.config.js | 2 + .../@aws-cdk/aws-rekognition/lib/index.ts | 2 + .../@aws-cdk/aws-rekognition/package.json | 105 + .../test/aws-rekognition.test.ts | 6 + .../@aws-cdk/aws-secretsmanager/lib/secret.ts | 6 +- .../test/integ.hosted-rotation.expected.json | 4 +- .../test/integ.lambda-rotation.expected.json | 4 +- .../test/integ.replica.expected.json | 4 +- .../integ.secret-name-parsed.expected.json | 16 +- .../test/integ.secret.lit.expected.json | 10 +- packages/@aws-cdk/aws-wisdom/.eslintrc.js | 3 + packages/@aws-cdk/aws-wisdom/.gitignore | 19 + packages/@aws-cdk/aws-wisdom/.npmignore | 29 + packages/@aws-cdk/aws-wisdom/LICENSE | 201 ++ packages/@aws-cdk/aws-wisdom/NOTICE | 2 + packages/@aws-cdk/aws-wisdom/README.md | 20 + packages/@aws-cdk/aws-wisdom/jest.config.js | 2 + packages/@aws-cdk/aws-wisdom/lib/index.ts | 2 + packages/@aws-cdk/aws-wisdom/package.json | 105 + .../aws-wisdom/test/aws-wisdom.test.ts | 6 + packages/@aws-cdk/cfnspec/CHANGELOG.md | 245 ++ packages/@aws-cdk/cfnspec/cfn.version | 2 +- ...0_CloudFormationResourceSpecification.json | 2703 ++++++++++++++++- .../cfn-lint/StatefulResources/000.json | 3 +- .../cloudformation-include/package.json | 6 + packages/aws-cdk-lib/package.json | 3 + packages/decdk/package.json | 3 + packages/monocdk/package.json | 3 + packages/monocdk/rosetta/basic.ts-fixture | 12 + .../monocdk/rosetta/client-vpn.ts-fixture | 2 +- packages/monocdk/rosetta/conns.ts-fixture | 26 - packages/monocdk/rosetta/default.ts-fixture | 82 +- packages/monocdk/rosetta/function.ts-fixture | 18 - packages/monocdk/rosetta/init.ts-fixture | 3 + .../monocdk/rosetta/with-batch-job.ts-fixture | 38 - .../monocdk/rosetta/with-objects.ts-fixture | 49 + yarn.lock | 2 +- 74 files changed, 4361 insertions(+), 338 deletions(-) create mode 100644 packages/@aws-cdk/aws-panorama/.eslintrc.js create mode 100644 packages/@aws-cdk/aws-panorama/.gitignore create mode 100644 packages/@aws-cdk/aws-panorama/.npmignore create mode 100644 packages/@aws-cdk/aws-panorama/LICENSE create mode 100644 packages/@aws-cdk/aws-panorama/NOTICE create mode 100644 packages/@aws-cdk/aws-panorama/README.md create mode 100644 packages/@aws-cdk/aws-panorama/jest.config.js create mode 100644 packages/@aws-cdk/aws-panorama/lib/index.ts create mode 100644 packages/@aws-cdk/aws-panorama/package.json create mode 100644 packages/@aws-cdk/aws-panorama/test/aws-panorama.test.ts create mode 100644 packages/@aws-cdk/aws-rekognition/.eslintrc.js create mode 100644 packages/@aws-cdk/aws-rekognition/.gitignore create mode 100644 packages/@aws-cdk/aws-rekognition/.npmignore create mode 100644 packages/@aws-cdk/aws-rekognition/LICENSE create mode 100644 packages/@aws-cdk/aws-rekognition/NOTICE create mode 100644 packages/@aws-cdk/aws-rekognition/README.md create mode 100644 packages/@aws-cdk/aws-rekognition/jest.config.js create mode 100644 packages/@aws-cdk/aws-rekognition/lib/index.ts create mode 100644 packages/@aws-cdk/aws-rekognition/package.json create mode 100644 packages/@aws-cdk/aws-rekognition/test/aws-rekognition.test.ts create mode 100644 packages/@aws-cdk/aws-wisdom/.eslintrc.js create mode 100644 packages/@aws-cdk/aws-wisdom/.gitignore create mode 100644 packages/@aws-cdk/aws-wisdom/.npmignore create mode 100644 packages/@aws-cdk/aws-wisdom/LICENSE create mode 100644 packages/@aws-cdk/aws-wisdom/NOTICE create mode 100644 packages/@aws-cdk/aws-wisdom/README.md create mode 100644 packages/@aws-cdk/aws-wisdom/jest.config.js create mode 100644 packages/@aws-cdk/aws-wisdom/lib/index.ts create mode 100644 packages/@aws-cdk/aws-wisdom/package.json create mode 100644 packages/@aws-cdk/aws-wisdom/test/aws-wisdom.test.ts create mode 100644 packages/monocdk/rosetta/basic.ts-fixture delete mode 100644 packages/monocdk/rosetta/conns.ts-fixture delete mode 100644 packages/monocdk/rosetta/function.ts-fixture create mode 100644 packages/monocdk/rosetta/init.ts-fixture delete mode 100644 packages/monocdk/rosetta/with-batch-job.ts-fixture create mode 100644 packages/monocdk/rosetta/with-objects.ts-fixture diff --git a/packages/@aws-cdk/aws-amplify/test/integ.app.expected.json b/packages/@aws-cdk/aws-amplify/test/integ.app.expected.json index d7ddd233378e1..bd8f69d9f66d8 100644 --- a/packages/@aws-cdk/aws-amplify/test/integ.app.expected.json +++ b/packages/@aws-cdk/aws-amplify/test/integ.app.expected.json @@ -24,7 +24,9 @@ "GenerateStringKey": "password", "SecretStringTemplate": "{\"username\":\"aws\"}" } - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "AppF1B96344": { "Type": "AWS::Amplify::App", diff --git a/packages/@aws-cdk/aws-docdb/test/integ.cluster-rotation.lit.expected.json b/packages/@aws-cdk/aws-docdb/test/integ.cluster-rotation.lit.expected.json index 6187414b9eb75..c063376359496 100644 --- a/packages/@aws-cdk/aws-docdb/test/integ.cluster-rotation.lit.expected.json +++ b/packages/@aws-cdk/aws-docdb/test/integ.cluster-rotation.lit.expected.json @@ -601,7 +601,9 @@ "PasswordLength": 41, "SecretStringTemplate": "{\"username\":\"docdb\"}" } - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "DatabaseSecretAttachmentE5D1B020": { "Type": "AWS::SecretsManager::SecretTargetAttachment", diff --git a/packages/@aws-cdk/aws-docdb/test/integ.cluster.expected.json b/packages/@aws-cdk/aws-docdb/test/integ.cluster.expected.json index e8737956c6440..1b661827dd1ec 100644 --- a/packages/@aws-cdk/aws-docdb/test/integ.cluster.expected.json +++ b/packages/@aws-cdk/aws-docdb/test/integ.cluster.expected.json @@ -95,15 +95,15 @@ "VPCPublicSubnet1NATGatewayE0556630": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, "AllocationId": { "Fn::GetAtt": [ "VPCPublicSubnet1EIP6AD938E8", "AllocationId" ] }, - "SubnetId": { - "Ref": "VPCPublicSubnet1SubnetB4246D30" - }, "Tags": [ { "Key": "Name", @@ -192,15 +192,15 @@ "VPCPublicSubnet2NATGateway3C070193": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, "AllocationId": { "Fn::GetAtt": [ "VPCPublicSubnet2EIP4947BC00", "AllocationId" ] }, - "SubnetId": { - "Ref": "VPCPublicSubnet2Subnet74179F39" - }, "Tags": [ { "Key": "Name", @@ -506,4 +506,4 @@ "DeletionPolicy": "Delete" } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ec2/package.json b/packages/@aws-cdk/aws-ec2/package.json index 8eaa9d1e5d64a..a82b70b68ab52 100644 --- a/packages/@aws-cdk/aws-ec2/package.json +++ b/packages/@aws-cdk/aws-ec2/package.json @@ -117,6 +117,7 @@ }, "awslint": { "exclude": [ + "resource-attribute:@aws-cdk/aws-ec2.NetworkAclEntry.networkAclEntryId", "resource-attribute:@aws-cdk/aws-ec2.ISecurityGroup.securityGroupVpcId", "no-unused-type:@aws-cdk/aws-ec2.ConnectionRule", "no-unused-type:@aws-cdk/aws-ec2.Protocol", @@ -131,6 +132,7 @@ "props-physical-name:@aws-cdk/aws-ec2.InterfaceVpcEndpointProps", "props-physical-name:@aws-cdk/aws-ec2.VpcEndpointServiceProps", "from-method:@aws-cdk/aws-ec2.Instance", + "from-method:@aws-cdk/aws-ec2.NetworkAclEntry", "from-method:@aws-cdk/aws-ec2.VpcEndpointService", "attribute-tag:@aws-cdk/aws-ec2.BastionHostLinux.instance", "attribute-tag:@aws-cdk/aws-ec2.Instance.instance", diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.secret-json-field.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.secret-json-field.expected.json index 6fe13e7abc27e..b14c1d7855e8c 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/integ.secret-json-field.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.secret-json-field.expected.json @@ -7,7 +7,9 @@ "GenerateStringKey": "password", "SecretStringTemplate": "{\"username\":\"user\"}" } - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "TaskDefTaskRole1EDB4A67": { "Type": "AWS::IAM::Role", diff --git a/packages/@aws-cdk/aws-ecs/test/fargate/integ.secret.expected.json b/packages/@aws-cdk/aws-ecs/test/fargate/integ.secret.expected.json index 2ef36fdc4d94a..f86ae24841bbf 100644 --- a/packages/@aws-cdk/aws-ecs/test/fargate/integ.secret.expected.json +++ b/packages/@aws-cdk/aws-ecs/test/fargate/integ.secret.expected.json @@ -7,7 +7,9 @@ "GenerateStringKey": "password", "SecretStringTemplate": "{\"username\":\"user\"}" } - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "TaskDefTaskRole1EDB4A67": { "Type": "AWS::IAM::Role", diff --git a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch-vpc.expected.json b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch-vpc.expected.json index fc046ff8065b2..1883358d70fe7 100644 --- a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch-vpc.expected.json +++ b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch-vpc.expected.json @@ -95,15 +95,15 @@ "VpcPublicSubnet1NATGateway4D7517AA": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, "AllocationId": { "Fn::GetAtt": [ "VpcPublicSubnet1EIPD7E02669", "AllocationId" ] }, - "SubnetId": { - "Ref": "VpcPublicSubnet1Subnet5C2D37C4" - }, "Tags": [ { "Key": "Name", @@ -192,15 +192,15 @@ "VpcPublicSubnet2NATGateway9182C01D": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + }, "AllocationId": { "Fn::GetAtt": [ "VpcPublicSubnet2EIP3C605A87", "AllocationId" ] }, - "SubnetId": { - "Ref": "VpcPublicSubnet2Subnet691E08A3" - }, "Tags": [ { "Key": "Name", @@ -289,15 +289,15 @@ "VpcPublicSubnet3NATGateway7640CD1D": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet3SubnetBE12F0B6" + }, "AllocationId": { "Fn::GetAtt": [ "VpcPublicSubnet3EIP3A666A23", "AllocationId" ] }, - "SubnetId": { - "Ref": "VpcPublicSubnet3SubnetBE12F0B6" - }, "Tags": [ { "Key": "Name", diff --git a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.custom-kms-key.expected.json b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.custom-kms-key.expected.json index 33066ad9091b6..8cbc696c94e14 100644 --- a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.custom-kms-key.expected.json +++ b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.custom-kms-key.expected.json @@ -359,7 +359,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParametersf4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924S3BucketA716C641" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E" }, "S3Key": { "Fn::Join": [ @@ -372,7 +372,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersf4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924S3VersionKey2B40A946" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" } ] } @@ -385,7 +385,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersf4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924S3VersionKey2B40A946" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" } ] } @@ -412,17 +412,17 @@ } }, "Parameters": { - "AssetParametersf4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924S3BucketA716C641": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E": { "Type": "String", - "Description": "S3 bucket for asset \"f4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924\"" + "Description": "S3 bucket for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" }, - "AssetParametersf4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924S3VersionKey2B40A946": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632": { "Type": "String", - "Description": "S3 key for asset version \"f4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924\"" + "Description": "S3 key for asset version \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" }, - "AssetParametersf4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924ArtifactHash2B031F57": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2ArtifactHash4BE92B79": { "Type": "String", - "Description": "Artifact hash for asset \"f4b39c228007db80daf4497318957f3b455415dce70fdbb7aeb6151a0b6da924\"" + "Description": "Artifact hash for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.expected.json b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.expected.json index e976e19e502a2..3734722a35ca7 100644 --- a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.expected.json +++ b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.expected.json @@ -296,7 +296,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParametersf2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3ddS3Bucket292EB571" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E" }, "S3Key": { "Fn::Join": [ @@ -309,7 +309,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersf2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3ddS3VersionKeyCE9A5F79" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" } ] } @@ -322,7 +322,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersf2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3ddS3VersionKeyCE9A5F79" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" } ] } @@ -608,17 +608,17 @@ } }, "Parameters": { - "AssetParametersf2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3ddS3Bucket292EB571": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E": { "Type": "String", - "Description": "S3 bucket for asset \"f2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3dd\"" + "Description": "S3 bucket for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" }, - "AssetParametersf2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3ddS3VersionKeyCE9A5F79": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632": { "Type": "String", - "Description": "S3 key for asset version \"f2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3dd\"" + "Description": "S3 key for asset version \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" }, - "AssetParametersf2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3ddArtifactHash86854188": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2ArtifactHash4BE92B79": { "Type": "String", - "Description": "Artifact hash for asset \"f2b7671fc0b80f63e3c94441727cbff799bb0f4991339d990d7b4c419e1ab3dd\"" + "Description": "Artifact hash for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.unsignedbasicauth.expected.json b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.unsignedbasicauth.expected.json index 7ff999080fed6..d74ea6423a7bd 100644 --- a/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.unsignedbasicauth.expected.json +++ b/packages/@aws-cdk/aws-elasticsearch/test/integ.elasticsearch.unsignedbasicauth.expected.json @@ -8,7 +8,9 @@ "GenerateStringKey": "password", "SecretStringTemplate": "{\"username\":\"admin\"}" } - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "Domain66AC69E0": { "Type": "AWS::Elasticsearch::Domain", @@ -191,7 +193,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParameters4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02cS3BucketD609D0D9" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E" }, "S3Key": { "Fn::Join": [ @@ -204,7 +206,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02cS3VersionKey77CF589B" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" } ] } @@ -217,7 +219,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02cS3VersionKey77CF589B" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" } ] } @@ -243,17 +245,17 @@ } }, "Parameters": { - "AssetParameters4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02cS3BucketD609D0D9": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E": { "Type": "String", - "Description": "S3 bucket for asset \"4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02c\"" + "Description": "S3 bucket for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" }, - "AssetParameters4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02cS3VersionKey77CF589B": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632": { "Type": "String", - "Description": "S3 key for asset version \"4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02c\"" + "Description": "S3 key for asset version \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" }, - "AssetParameters4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02cArtifactHash86CFA15D": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2ArtifactHash4BE92B79": { "Type": "String", - "Description": "Artifact hash for asset \"4600faecd25ab407ff0a9d16f935c93062aaea5d415e97046bb8befe6c8ec02c\"" + "Description": "Artifact hash for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.custom-kms-key.expected.json b/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.custom-kms-key.expected.json index 5a2791399497d..63a1cb0c236d5 100644 --- a/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.custom-kms-key.expected.json +++ b/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.custom-kms-key.expected.json @@ -232,7 +232,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3BucketF2AC65B6" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E" }, "S3Key": { "Fn::Join": [ @@ -245,7 +245,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3VersionKey8025D5E5" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" } ] } @@ -258,7 +258,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3VersionKey8025D5E5" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" } ] } @@ -285,17 +285,17 @@ } }, "Parameters": { - "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3BucketF2AC65B6": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E": { "Type": "String", - "Description": "S3 bucket for asset \"5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7d\"" + "Description": "S3 bucket for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" }, - "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3VersionKey8025D5E5": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632": { "Type": "String", - "Description": "S3 key for asset version \"5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7d\"" + "Description": "S3 key for asset version \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" }, - "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dArtifactHash30B93F3B": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2ArtifactHash4BE92B79": { "Type": "String", - "Description": "Artifact hash for asset \"5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7d\"" + "Description": "Artifact hash for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.expected.json b/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.expected.json index f317e3a7eb835..da98a9b24ab35 100644 --- a/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.expected.json +++ b/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.expected.json @@ -296,7 +296,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParameters0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85eS3BucketF2C16119" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E" }, "S3Key": { "Fn::Join": [ @@ -309,7 +309,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85eS3VersionKey60E022E2" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" } ] } @@ -322,7 +322,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85eS3VersionKey60E022E2" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" } ] } @@ -608,17 +608,17 @@ } }, "Parameters": { - "AssetParameters0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85eS3BucketF2C16119": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E": { "Type": "String", - "Description": "S3 bucket for asset \"0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85e\"" + "Description": "S3 bucket for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" }, - "AssetParameters0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85eS3VersionKey60E022E2": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632": { "Type": "String", - "Description": "S3 key for asset version \"0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85e\"" + "Description": "S3 key for asset version \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" }, - "AssetParameters0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85eArtifactHash4E1710B0": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2ArtifactHash4BE92B79": { "Type": "String", - "Description": "Artifact hash for asset \"0036020ad5459434aa7b01d7769825c4b189b2a7722cc47c4a1bc6dbd9ccf85e\"" + "Description": "Artifact hash for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.unsignedbasicauth.expected.json b/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.unsignedbasicauth.expected.json index c2e8d28a0d35f..b1a9048f14dc1 100644 --- a/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.unsignedbasicauth.expected.json +++ b/packages/@aws-cdk/aws-opensearchservice/test/integ.opensearch.unsignedbasicauth.expected.json @@ -8,7 +8,9 @@ "GenerateStringKey": "password", "SecretStringTemplate": "{\"username\":\"admin\"}" } - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "Domain66AC69E0": { "Type": "AWS::OpenSearchService::Domain", @@ -191,7 +193,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3BucketF2AC65B6" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E" }, "S3Key": { "Fn::Join": [ @@ -204,7 +206,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3VersionKey8025D5E5" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" } ] } @@ -217,7 +219,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3VersionKey8025D5E5" + "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" } ] } @@ -243,17 +245,17 @@ } }, "Parameters": { - "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3BucketF2AC65B6": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E": { "Type": "String", - "Description": "S3 bucket for asset \"5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7d\"" + "Description": "S3 bucket for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" }, - "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dS3VersionKey8025D5E5": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632": { "Type": "String", - "Description": "S3 key for asset version \"5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7d\"" + "Description": "S3 key for asset version \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" }, - "AssetParameters5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7dArtifactHash30B93F3B": { + "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2ArtifactHash4BE92B79": { "Type": "String", - "Description": "Artifact hash for asset \"5d4cb1694db181d27240b1dabc7e4d79a7e1051022a41b773652782433c07f7d\"" + "Description": "Artifact hash for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-panorama/.eslintrc.js b/packages/@aws-cdk/aws-panorama/.eslintrc.js new file mode 100644 index 0000000000000..2658ee8727166 --- /dev/null +++ b/packages/@aws-cdk/aws-panorama/.eslintrc.js @@ -0,0 +1,3 @@ +const baseConfig = require('@aws-cdk/cdk-build-tools/config/eslintrc'); +baseConfig.parserOptions.project = __dirname + '/tsconfig.json'; +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-panorama/.gitignore b/packages/@aws-cdk/aws-panorama/.gitignore new file mode 100644 index 0000000000000..62ebc95d75ce6 --- /dev/null +++ b/packages/@aws-cdk/aws-panorama/.gitignore @@ -0,0 +1,19 @@ +*.js +*.js.map +*.d.ts +tsconfig.json +node_modules +*.generated.ts +dist +.jsii + +.LAST_BUILD +.nyc_output +coverage +.nycrc +.LAST_PACKAGE +*.snk +nyc.config.js +!.eslintrc.js +!jest.config.js +junit.xml diff --git a/packages/@aws-cdk/aws-panorama/.npmignore b/packages/@aws-cdk/aws-panorama/.npmignore new file mode 100644 index 0000000000000..f931fede67c44 --- /dev/null +++ b/packages/@aws-cdk/aws-panorama/.npmignore @@ -0,0 +1,29 @@ +# Don't include original .ts files when doing `npm pack` +*.ts +!*.d.ts +coverage +.nyc_output +*.tgz + +dist +.LAST_PACKAGE +.LAST_BUILD +!*.js + +# Include .jsii +!.jsii + +*.snk + +*.tsbuildinfo + +tsconfig.json + +.eslintrc.js +jest.config.js + +# exclude cdk artifacts +**/cdk.out +junit.xml +test/ +!*.lit.ts diff --git a/packages/@aws-cdk/aws-panorama/LICENSE b/packages/@aws-cdk/aws-panorama/LICENSE new file mode 100644 index 0000000000000..28e4bdcec77ec --- /dev/null +++ b/packages/@aws-cdk/aws-panorama/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/@aws-cdk/aws-panorama/NOTICE b/packages/@aws-cdk/aws-panorama/NOTICE new file mode 100644 index 0000000000000..5fc3826926b5b --- /dev/null +++ b/packages/@aws-cdk/aws-panorama/NOTICE @@ -0,0 +1,2 @@ +AWS Cloud Development Kit (AWS CDK) +Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/packages/@aws-cdk/aws-panorama/README.md b/packages/@aws-cdk/aws-panorama/README.md new file mode 100644 index 0000000000000..334264b4ea581 --- /dev/null +++ b/packages/@aws-cdk/aws-panorama/README.md @@ -0,0 +1,20 @@ +# AWS::Panorama Construct Library + + +--- + +![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge) + +> All classes with the `Cfn` prefix in this module ([CFN Resources]) are always stable and safe to use. +> +> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib + +--- + + + +This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project. + +```ts +import aws-panorama = require('@aws-cdk/aws-panorama'); +``` diff --git a/packages/@aws-cdk/aws-panorama/jest.config.js b/packages/@aws-cdk/aws-panorama/jest.config.js new file mode 100644 index 0000000000000..3a2fd93a1228a --- /dev/null +++ b/packages/@aws-cdk/aws-panorama/jest.config.js @@ -0,0 +1,2 @@ +const baseConfig = require('@aws-cdk/cdk-build-tools/config/jest.config'); +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-panorama/lib/index.ts b/packages/@aws-cdk/aws-panorama/lib/index.ts new file mode 100644 index 0000000000000..1ef8b1378379a --- /dev/null +++ b/packages/@aws-cdk/aws-panorama/lib/index.ts @@ -0,0 +1,2 @@ +// AWS::Panorama CloudFormation Resources: +export * from './panorama.generated'; diff --git a/packages/@aws-cdk/aws-panorama/package.json b/packages/@aws-cdk/aws-panorama/package.json new file mode 100644 index 0000000000000..08af6d8c5a82d --- /dev/null +++ b/packages/@aws-cdk/aws-panorama/package.json @@ -0,0 +1,105 @@ +{ + "name": "@aws-cdk/aws-panorama", + "version": "0.0.0", + "description": "The CDK Construct Library for AWS::Panorama", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "jsii": { + "outdir": "dist", + "projectReferences": true, + "targets": { + "dotnet": { + "namespace": "Amazon.CDK.AWS.Panorama", + "packageId": "Amazon.CDK.AWS.Panorama", + "signAssembly": true, + "assemblyOriginatorKeyFile": "../../key.snk", + "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png" + }, + "java": { + "package": "software.amazon.awscdk.services.panorama", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "panorama" + } + }, + "python": { + "classifiers": [ + "Framework :: AWS CDK", + "Framework :: AWS CDK :: 1" + ], + "distName": "aws-cdk.aws-panorama", + "module": "aws_cdk.aws_panorama" + } + } + }, + "repository": { + "type": "git", + "url": "https://github.com/aws/aws-cdk.git", + "directory": "packages/@aws-cdk/aws-panorama" + }, + "homepage": "https://github.com/aws/aws-cdk", + "scripts": { + "build": "cdk-build", + "watch": "cdk-watch", + "lint": "cdk-lint", + "test": "cdk-test", + "integ": "cdk-integ", + "pkglint": "pkglint -f", + "package": "cdk-package", + "awslint": "cdk-awslint", + "cfn2ts": "cfn2ts", + "build+test": "yarn build && yarn test", + "build+test+package": "yarn build+test && yarn package", + "compat": "cdk-compat", + "gen": "cfn2ts", + "rosetta:extract": "yarn --silent jsii-rosetta extract", + "build+extract": "yarn build && yarn rosetta:extract", + "build+test+extract": "yarn build+test && yarn rosetta:extract" + }, + "cdk-build": { + "cloudformation": "AWS::Panorama", + "jest": true, + "env": { + "AWSLINT_BASE_CONSTRUCT": "true" + } + }, + "keywords": [ + "aws", + "cdk", + "constructs", + "AWS::Panorama", + "aws-panorama" + ], + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "organization": true + }, + "license": "Apache-2.0", + "devDependencies": { + "@aws-cdk/assertions": "0.0.0", + "@aws-cdk/cdk-build-tools": "0.0.0", + "@aws-cdk/cfn2ts": "0.0.0", + "@aws-cdk/pkglint": "0.0.0", + "@types/jest": "^26.0.22" + }, + "dependencies": { + "@aws-cdk/core": "0.0.0", + "constructs": "^3.3.69" + }, + "peerDependencies": { + "@aws-cdk/core": "0.0.0", + "constructs": "^3.3.69" + }, + "engines": { + "node": ">= 10.13.0 <13 || >=13.7.0" + }, + "stability": "experimental", + "maturity": "cfn-only", + "awscdkio": { + "announce": false + }, + "publishConfig": { + "tag": "latest" + } +} diff --git a/packages/@aws-cdk/aws-panorama/test/aws-panorama.test.ts b/packages/@aws-cdk/aws-panorama/test/aws-panorama.test.ts new file mode 100644 index 0000000000000..465c7bdea0693 --- /dev/null +++ b/packages/@aws-cdk/aws-panorama/test/aws-panorama.test.ts @@ -0,0 +1,6 @@ +import '@aws-cdk/assertions'; +import {} from '../lib'; + +test('No tests are specified for this package', () => { + expect(true).toBe(true); +}); diff --git a/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.expected.json b/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.expected.json index 91b189023f587..19fbeabb515b1 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.expected.json +++ b/packages/@aws-cdk/aws-rds/test/integ.cluster-rotation.lit.expected.json @@ -599,7 +599,9 @@ "PasswordLength": 30, "SecretStringTemplate": "{\"username\":\"admin\"}" } - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "DatabaseSecretAttachmentE5D1B020": { "Type": "AWS::SecretsManager::SecretTargetAttachment", diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance-from-generated-password.expected.json b/packages/@aws-cdk/aws-rds/test/integ.instance-from-generated-password.expected.json index ca2ee08c781ad..219202e5fa587 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.instance-from-generated-password.expected.json +++ b/packages/@aws-cdk/aws-rds/test/integ.instance-from-generated-password.expected.json @@ -95,15 +95,15 @@ "VpcPublicSubnet1NATGateway4D7517AA": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, "AllocationId": { "Fn::GetAtt": [ "VpcPublicSubnet1EIPD7E02669", "AllocationId" ] }, - "SubnetId": { - "Ref": "VpcPublicSubnet1Subnet5C2D37C4" - }, "Tags": [ { "Key": "Name", @@ -192,15 +192,15 @@ "VpcPublicSubnet2NATGateway9182C01D": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + }, "AllocationId": { "Fn::GetAtt": [ "VpcPublicSubnet2EIP3C605A87", "AllocationId" ] }, - "SubnetId": { - "Ref": "VpcPublicSubnet2Subnet691E08A3" - }, "Tags": [ { "Key": "Name", @@ -289,15 +289,15 @@ "VpcPublicSubnet3NATGateway7640CD1D": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet3SubnetBE12F0B6" + }, "AllocationId": { "Fn::GetAtt": [ "VpcPublicSubnet3EIP3A666A23", "AllocationId" ] }, - "SubnetId": { - "Ref": "VpcPublicSubnet3SubnetBE12F0B6" - }, "Tags": [ { "Key": "Name", @@ -567,7 +567,9 @@ "PasswordLength": 30, "SecretStringTemplate": "{\"username\":\"admin\"}" } - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "InstanceSecretAttachment83BEE581": { "Type": "AWS::SecretsManager::SecretTargetAttachment", diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.expected.json b/packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.expected.json index 2a55df00bab2c..c623afaf92464 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.expected.json +++ b/packages/@aws-cdk/aws-rds/test/integ.instance-s3-postgres.expected.json @@ -512,7 +512,9 @@ "PasswordLength": 30, "SecretStringTemplate": "{\"username\":\"postgres\"}" } - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "InstanceSecretAttachment83BEE581": { "Type": "AWS::SecretsManager::SecretTargetAttachment", diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance-s3.expected.json b/packages/@aws-cdk/aws-rds/test/integ.instance-s3.expected.json index 2b144dedcc3aa..5b851784caef0 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.instance-s3.expected.json +++ b/packages/@aws-cdk/aws-rds/test/integ.instance-s3.expected.json @@ -95,15 +95,15 @@ "VPCPublicSubnet1NATGatewayE0556630": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, "AllocationId": { "Fn::GetAtt": [ "VPCPublicSubnet1EIP6AD938E8", "AllocationId" ] }, - "SubnetId": { - "Ref": "VPCPublicSubnet1SubnetB4246D30" - }, "Tags": [ { "Key": "Name", @@ -192,15 +192,15 @@ "VPCPublicSubnet2NATGateway3C070193": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, "AllocationId": { "Fn::GetAtt": [ "VPCPublicSubnet2EIP4947BC00", "AllocationId" ] }, - "SubnetId": { - "Ref": "VPCPublicSubnet2Subnet74179F39" - }, "Tags": [ { "Key": "Name", @@ -535,7 +535,9 @@ "PasswordLength": 30, "SecretStringTemplate": "{\"username\":\"admin\"}" } - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "DatabaseSecretAttachmentE5D1B020": { "Type": "AWS::SecretsManager::SecretTargetAttachment", @@ -570,7 +572,7 @@ "Ref": "DatabaseSubnetGroup7D60F180" }, "Engine": "sqlserver-se", - "EngineVersion": "14.00.3192.2.v1", + "EngineVersion": "14.00", "LicenseModel": "license-included", "MasterUsername": { "Fn::Join": [ diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance-s3.ts b/packages/@aws-cdk/aws-rds/test/integ.instance-s3.ts index 876ac2251e8fc..317e3c74abb57 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.instance-s3.ts +++ b/packages/@aws-cdk/aws-rds/test/integ.instance-s3.ts @@ -12,7 +12,7 @@ const importBucket = new s3.Bucket(stack, 'ImportBucket', { removalPolicy: cdk.R const exportBucket = new s3.Bucket(stack, 'ExportBucket', { removalPolicy: cdk.RemovalPolicy.DESTROY }); new DatabaseInstance(stack, 'Database', { - engine: DatabaseInstanceEngine.sqlServerSe({ version: SqlServerEngineVersion.VER_14_00_3192_2_V1 }), + engine: DatabaseInstanceEngine.sqlServerSe({ version: SqlServerEngineVersion.VER_14 }), vpc, licenseModel: LicenseModel.LICENSE_INCLUDED, s3ImportBuckets: [importBucket], diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance.lit.expected.json b/packages/@aws-cdk/aws-rds/test/integ.instance.lit.expected.json index 5214516968486..7b4328ccc3341 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.instance.lit.expected.json +++ b/packages/@aws-cdk/aws-rds/test/integ.instance.lit.expected.json @@ -96,15 +96,15 @@ "VPCPublicSubnet1NATGatewayE0556630": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, "AllocationId": { "Fn::GetAtt": [ "VPCPublicSubnet1EIP6AD938E8", "AllocationId" ] }, - "SubnetId": { - "Ref": "VPCPublicSubnet1SubnetB4246D30" - }, "Tags": [ { "Key": "Name", @@ -193,15 +193,15 @@ "VPCPublicSubnet2NATGateway3C070193": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, "AllocationId": { "Fn::GetAtt": [ "VPCPublicSubnet2EIP4947BC00", "AllocationId" ] }, - "SubnetId": { - "Ref": "VPCPublicSubnet2Subnet74179F39" - }, "Tags": [ { "Key": "Name", @@ -554,7 +554,9 @@ "PasswordLength": 30, "SecretStringTemplate": "{\"username\":\"syscdk\"}" } - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "InstanceSecretAttachment83BEE581": { "Type": "AWS::SecretsManager::SecretTargetAttachment", @@ -1006,7 +1008,7 @@ "Runtime": "nodejs14.x", "Code": { "S3Bucket": { - "Ref": "AssetParameters884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147S3BucketAE1150B3" + "Ref": "AssetParametersdd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9S3BucketE7DA8D4B" }, "S3Key": { "Fn::Join": [ @@ -1019,7 +1021,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147S3VersionKeyC76660C1" + "Ref": "AssetParametersdd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9S3VersionKey534293E7" } ] } @@ -1032,7 +1034,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147S3VersionKeyC76660C1" + "Ref": "AssetParametersdd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9S3VersionKey534293E7" } ] } @@ -1118,27 +1120,13 @@ ] }, "Handler": "index.handler", - "Runtime": "nodejs10.x" + "Runtime": "nodejs12.x" }, "DependsOn": [ "FunctionServiceRole675BB04A" ] } }, - "Parameters": { - "AssetParameters884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147S3BucketAE1150B3": { - "Type": "String", - "Description": "S3 bucket for asset \"884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147\"" - }, - "AssetParameters884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147S3VersionKeyC76660C1": { - "Type": "String", - "Description": "S3 key for asset version \"884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147\"" - }, - "AssetParameters884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147ArtifactHash717FC602": { - "Type": "String", - "Description": "Artifact hash for asset \"884431e2bc651d2b61bd699a29dc9684b0f66911f06bd3ed0635f854bf18e147\"" - } - }, "Mappings": { "InstanceRotationSingleUserSARMappingFEA0C86E": { "aws": { @@ -1150,5 +1138,19 @@ "semanticVersion": "1.1.37" } } + }, + "Parameters": { + "AssetParametersdd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9S3BucketE7DA8D4B": { + "Type": "String", + "Description": "S3 bucket for asset \"dd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9\"" + }, + "AssetParametersdd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9S3VersionKey534293E7": { + "Type": "String", + "Description": "S3 key for asset version \"dd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9\"" + }, + "AssetParametersdd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9ArtifactHash3CB520C3": { + "Type": "String", + "Description": "Artifact hash for asset \"dd4b26cf376ea5894e31041be239fc518713becdafb8f2894b069a53984fafe9\"" + } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts b/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts index eafe7a2953735..3e869950a0a46 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts +++ b/packages/@aws-cdk/aws-rds/test/integ.instance.lit.ts @@ -85,7 +85,7 @@ class DatabaseInstanceStack extends cdk.Stack { const fn = new lambda.Function(this, 'Function', { code: lambda.Code.fromInline('exports.handler = (event) => console.log(event);'), handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_10_X, + runtime: lambda.Runtime.NODEJS_12_X, }); const availabilityRule = instance.onEvent('Availability', { target: new targets.LambdaFunction(fn) }); diff --git a/packages/@aws-cdk/aws-rds/test/integ.proxy.expected.json b/packages/@aws-cdk/aws-rds/test/integ.proxy.expected.json index a18c5f5843512..8ec23ce0fe7db 100644 --- a/packages/@aws-cdk/aws-rds/test/integ.proxy.expected.json +++ b/packages/@aws-cdk/aws-rds/test/integ.proxy.expected.json @@ -95,15 +95,15 @@ "vpcPublicSubnet1NATGateway9C16659E": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "vpcPublicSubnet1Subnet2E65531E" + }, "AllocationId": { "Fn::GetAtt": [ "vpcPublicSubnet1EIPDA49DCBE", "AllocationId" ] }, - "SubnetId": { - "Ref": "vpcPublicSubnet1Subnet2E65531E" - }, "Tags": [ { "Key": "Name", @@ -192,15 +192,15 @@ "vpcPublicSubnet2NATGateway9B8AE11A": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "vpcPublicSubnet2Subnet009B674F" + }, "AllocationId": { "Fn::GetAtt": [ "vpcPublicSubnet2EIP9B3743B1", "AllocationId" ] }, - "SubnetId": { - "Ref": "vpcPublicSubnet2Subnet009B674F" - }, "Tags": [ { "Key": "Name", @@ -436,7 +436,9 @@ "PasswordLength": 30, "SecretStringTemplate": "{\"username\":\"master\"}" } - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "dbInstanceSecretAttachment88CFBDAE": { "Type": "AWS::SecretsManager::SecretTargetAttachment", diff --git a/packages/@aws-cdk/aws-rekognition/.eslintrc.js b/packages/@aws-cdk/aws-rekognition/.eslintrc.js new file mode 100644 index 0000000000000..2658ee8727166 --- /dev/null +++ b/packages/@aws-cdk/aws-rekognition/.eslintrc.js @@ -0,0 +1,3 @@ +const baseConfig = require('@aws-cdk/cdk-build-tools/config/eslintrc'); +baseConfig.parserOptions.project = __dirname + '/tsconfig.json'; +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-rekognition/.gitignore b/packages/@aws-cdk/aws-rekognition/.gitignore new file mode 100644 index 0000000000000..62ebc95d75ce6 --- /dev/null +++ b/packages/@aws-cdk/aws-rekognition/.gitignore @@ -0,0 +1,19 @@ +*.js +*.js.map +*.d.ts +tsconfig.json +node_modules +*.generated.ts +dist +.jsii + +.LAST_BUILD +.nyc_output +coverage +.nycrc +.LAST_PACKAGE +*.snk +nyc.config.js +!.eslintrc.js +!jest.config.js +junit.xml diff --git a/packages/@aws-cdk/aws-rekognition/.npmignore b/packages/@aws-cdk/aws-rekognition/.npmignore new file mode 100644 index 0000000000000..f931fede67c44 --- /dev/null +++ b/packages/@aws-cdk/aws-rekognition/.npmignore @@ -0,0 +1,29 @@ +# Don't include original .ts files when doing `npm pack` +*.ts +!*.d.ts +coverage +.nyc_output +*.tgz + +dist +.LAST_PACKAGE +.LAST_BUILD +!*.js + +# Include .jsii +!.jsii + +*.snk + +*.tsbuildinfo + +tsconfig.json + +.eslintrc.js +jest.config.js + +# exclude cdk artifacts +**/cdk.out +junit.xml +test/ +!*.lit.ts diff --git a/packages/@aws-cdk/aws-rekognition/LICENSE b/packages/@aws-cdk/aws-rekognition/LICENSE new file mode 100644 index 0000000000000..28e4bdcec77ec --- /dev/null +++ b/packages/@aws-cdk/aws-rekognition/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/@aws-cdk/aws-rekognition/NOTICE b/packages/@aws-cdk/aws-rekognition/NOTICE new file mode 100644 index 0000000000000..5fc3826926b5b --- /dev/null +++ b/packages/@aws-cdk/aws-rekognition/NOTICE @@ -0,0 +1,2 @@ +AWS Cloud Development Kit (AWS CDK) +Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/packages/@aws-cdk/aws-rekognition/README.md b/packages/@aws-cdk/aws-rekognition/README.md new file mode 100644 index 0000000000000..9e158afddf5de --- /dev/null +++ b/packages/@aws-cdk/aws-rekognition/README.md @@ -0,0 +1,20 @@ +# AWS::Rekognition Construct Library + + +--- + +![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge) + +> All classes with the `Cfn` prefix in this module ([CFN Resources]) are always stable and safe to use. +> +> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib + +--- + + + +This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project. + +```ts +import aws-rekognition = require('@aws-cdk/aws-rekognition'); +``` diff --git a/packages/@aws-cdk/aws-rekognition/jest.config.js b/packages/@aws-cdk/aws-rekognition/jest.config.js new file mode 100644 index 0000000000000..3a2fd93a1228a --- /dev/null +++ b/packages/@aws-cdk/aws-rekognition/jest.config.js @@ -0,0 +1,2 @@ +const baseConfig = require('@aws-cdk/cdk-build-tools/config/jest.config'); +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-rekognition/lib/index.ts b/packages/@aws-cdk/aws-rekognition/lib/index.ts new file mode 100644 index 0000000000000..a0fee8d99d632 --- /dev/null +++ b/packages/@aws-cdk/aws-rekognition/lib/index.ts @@ -0,0 +1,2 @@ +// AWS::Rekognition CloudFormation Resources: +export * from './rekognition.generated'; diff --git a/packages/@aws-cdk/aws-rekognition/package.json b/packages/@aws-cdk/aws-rekognition/package.json new file mode 100644 index 0000000000000..0639bc97ec905 --- /dev/null +++ b/packages/@aws-cdk/aws-rekognition/package.json @@ -0,0 +1,105 @@ +{ + "name": "@aws-cdk/aws-rekognition", + "version": "0.0.0", + "description": "The CDK Construct Library for AWS::Rekognition", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "jsii": { + "outdir": "dist", + "projectReferences": true, + "targets": { + "dotnet": { + "namespace": "Amazon.CDK.AWS.Rekognition", + "packageId": "Amazon.CDK.AWS.Rekognition", + "signAssembly": true, + "assemblyOriginatorKeyFile": "../../key.snk", + "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png" + }, + "java": { + "package": "software.amazon.awscdk.services.rekognition", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "rekognition" + } + }, + "python": { + "classifiers": [ + "Framework :: AWS CDK", + "Framework :: AWS CDK :: 1" + ], + "distName": "aws-cdk.aws-rekognition", + "module": "aws_cdk.aws_rekognition" + } + } + }, + "repository": { + "type": "git", + "url": "https://github.com/aws/aws-cdk.git", + "directory": "packages/@aws-cdk/aws-rekognition" + }, + "homepage": "https://github.com/aws/aws-cdk", + "scripts": { + "build": "cdk-build", + "watch": "cdk-watch", + "lint": "cdk-lint", + "test": "cdk-test", + "integ": "cdk-integ", + "pkglint": "pkglint -f", + "package": "cdk-package", + "awslint": "cdk-awslint", + "cfn2ts": "cfn2ts", + "build+test": "yarn build && yarn test", + "build+test+package": "yarn build+test && yarn package", + "compat": "cdk-compat", + "gen": "cfn2ts", + "rosetta:extract": "yarn --silent jsii-rosetta extract", + "build+extract": "yarn build && yarn rosetta:extract", + "build+test+extract": "yarn build+test && yarn rosetta:extract" + }, + "cdk-build": { + "cloudformation": "AWS::Rekognition", + "jest": true, + "env": { + "AWSLINT_BASE_CONSTRUCT": "true" + } + }, + "keywords": [ + "aws", + "cdk", + "constructs", + "AWS::Rekognition", + "aws-rekognition" + ], + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "organization": true + }, + "license": "Apache-2.0", + "devDependencies": { + "@aws-cdk/assertions": "0.0.0", + "@aws-cdk/cdk-build-tools": "0.0.0", + "@aws-cdk/cfn2ts": "0.0.0", + "@aws-cdk/pkglint": "0.0.0", + "@types/jest": "^26.0.22" + }, + "dependencies": { + "@aws-cdk/core": "0.0.0", + "constructs": "^3.3.69" + }, + "peerDependencies": { + "@aws-cdk/core": "0.0.0", + "constructs": "^3.3.69" + }, + "engines": { + "node": ">= 10.13.0 <13 || >=13.7.0" + }, + "stability": "experimental", + "maturity": "cfn-only", + "awscdkio": { + "announce": false + }, + "publishConfig": { + "tag": "latest" + } +} diff --git a/packages/@aws-cdk/aws-rekognition/test/aws-rekognition.test.ts b/packages/@aws-cdk/aws-rekognition/test/aws-rekognition.test.ts new file mode 100644 index 0000000000000..465c7bdea0693 --- /dev/null +++ b/packages/@aws-cdk/aws-rekognition/test/aws-rekognition.test.ts @@ -0,0 +1,6 @@ +import '@aws-cdk/assertions'; +import {} from '../lib'; + +test('No tests are specified for this package', () => { + expect(true).toBe(true); +}); diff --git a/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts b/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts index 119b02ccc507d..70144db7d2dbd 100644 --- a/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts +++ b/packages/@aws-cdk/aws-secretsmanager/lib/secret.ts @@ -467,9 +467,9 @@ export class Secret extends SecretBase { replicaRegions: Lazy.any({ produce: () => this.replicaRegions }, { omitEmptyArray: true }), }); - if (props.removalPolicy) { - resource.applyRemovalPolicy(props.removalPolicy); - } + resource.applyRemovalPolicy(props.removalPolicy, { + default: RemovalPolicy.DESTROY, + }); this.secretArn = this.getResourceArnAttribute(resource.ref, { service: 'secretsmanager', diff --git a/packages/@aws-cdk/aws-secretsmanager/test/integ.hosted-rotation.expected.json b/packages/@aws-cdk/aws-secretsmanager/test/integ.hosted-rotation.expected.json index be2f63be0aa79..19c9a9d4c7f1e 100644 --- a/packages/@aws-cdk/aws-secretsmanager/test/integ.hosted-rotation.expected.json +++ b/packages/@aws-cdk/aws-secretsmanager/test/integ.hosted-rotation.expected.json @@ -5,7 +5,9 @@ "Type": "AWS::SecretsManager::Secret", "Properties": { "GenerateSecretString": {} - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "SecretSchedule18F2CB66": { "Type": "AWS::SecretsManager::RotationSchedule", diff --git a/packages/@aws-cdk/aws-secretsmanager/test/integ.lambda-rotation.expected.json b/packages/@aws-cdk/aws-secretsmanager/test/integ.lambda-rotation.expected.json index 12ea99df10a85..f1d540cbd42a7 100644 --- a/packages/@aws-cdk/aws-secretsmanager/test/integ.lambda-rotation.expected.json +++ b/packages/@aws-cdk/aws-secretsmanager/test/integ.lambda-rotation.expected.json @@ -165,7 +165,9 @@ "Arn" ] } - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "SecretSchedule18F2CB66": { "Type": "AWS::SecretsManager::RotationSchedule", diff --git a/packages/@aws-cdk/aws-secretsmanager/test/integ.replica.expected.json b/packages/@aws-cdk/aws-secretsmanager/test/integ.replica.expected.json index 99fd65c02e2b4..6483de751a884 100644 --- a/packages/@aws-cdk/aws-secretsmanager/test/integ.replica.expected.json +++ b/packages/@aws-cdk/aws-secretsmanager/test/integ.replica.expected.json @@ -9,7 +9,9 @@ "Region": "eu-central-1" } ] - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-secretsmanager/test/integ.secret-name-parsed.expected.json b/packages/@aws-cdk/aws-secretsmanager/test/integ.secret-name-parsed.expected.json index b1b91a239d649..01e9e10d4eed9 100644 --- a/packages/@aws-cdk/aws-secretsmanager/test/integ.secret-name-parsed.expected.json +++ b/packages/@aws-cdk/aws-secretsmanager/test/integ.secret-name-parsed.expected.json @@ -4,27 +4,35 @@ "Type": "AWS::SecretsManager::Secret", "Properties": { "GenerateSecretString": {} - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "NamedSecret7CD5422D": { "Type": "AWS::SecretsManager::Secret", "Properties": { "GenerateSecretString": {}, "Name": "namedSecret" - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "NamedSecretWithHyphen6DC9716A": { "Type": "AWS::SecretsManager::Secret", "Properties": { "GenerateSecretString": {}, "Name": "named-secret-1" - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "AReallyLongLogicalIThatWillBeTrimmedBeforeItsUsedInTheName83476586": { "Type": "AWS::SecretsManager::Secret", "Properties": { "GenerateSecretString": {} - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "CustomIntegVerificationSecretNameMatchesCustomResourceProviderRole4A6F8B2A": { "Type": "AWS::IAM::Role", diff --git a/packages/@aws-cdk/aws-secretsmanager/test/integ.secret.lit.expected.json b/packages/@aws-cdk/aws-secretsmanager/test/integ.secret.lit.expected.json index 5411df31be1ba..7a69272a9550f 100644 --- a/packages/@aws-cdk/aws-secretsmanager/test/integ.secret.lit.expected.json +++ b/packages/@aws-cdk/aws-secretsmanager/test/integ.secret.lit.expected.json @@ -62,7 +62,9 @@ "Type": "AWS::SecretsManager::Secret", "Properties": { "GenerateSecretString": {} - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "User00B015A1": { "Type": "AWS::IAM::User", @@ -90,7 +92,9 @@ "GenerateStringKey": "password", "SecretStringTemplate": "{\"username\":\"user\"}" } - } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" }, "OtherUser6093621C": { "Type": "AWS::IAM::User", @@ -124,4 +128,4 @@ } } } -} +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-wisdom/.eslintrc.js b/packages/@aws-cdk/aws-wisdom/.eslintrc.js new file mode 100644 index 0000000000000..2658ee8727166 --- /dev/null +++ b/packages/@aws-cdk/aws-wisdom/.eslintrc.js @@ -0,0 +1,3 @@ +const baseConfig = require('@aws-cdk/cdk-build-tools/config/eslintrc'); +baseConfig.parserOptions.project = __dirname + '/tsconfig.json'; +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-wisdom/.gitignore b/packages/@aws-cdk/aws-wisdom/.gitignore new file mode 100644 index 0000000000000..62ebc95d75ce6 --- /dev/null +++ b/packages/@aws-cdk/aws-wisdom/.gitignore @@ -0,0 +1,19 @@ +*.js +*.js.map +*.d.ts +tsconfig.json +node_modules +*.generated.ts +dist +.jsii + +.LAST_BUILD +.nyc_output +coverage +.nycrc +.LAST_PACKAGE +*.snk +nyc.config.js +!.eslintrc.js +!jest.config.js +junit.xml diff --git a/packages/@aws-cdk/aws-wisdom/.npmignore b/packages/@aws-cdk/aws-wisdom/.npmignore new file mode 100644 index 0000000000000..f931fede67c44 --- /dev/null +++ b/packages/@aws-cdk/aws-wisdom/.npmignore @@ -0,0 +1,29 @@ +# Don't include original .ts files when doing `npm pack` +*.ts +!*.d.ts +coverage +.nyc_output +*.tgz + +dist +.LAST_PACKAGE +.LAST_BUILD +!*.js + +# Include .jsii +!.jsii + +*.snk + +*.tsbuildinfo + +tsconfig.json + +.eslintrc.js +jest.config.js + +# exclude cdk artifacts +**/cdk.out +junit.xml +test/ +!*.lit.ts diff --git a/packages/@aws-cdk/aws-wisdom/LICENSE b/packages/@aws-cdk/aws-wisdom/LICENSE new file mode 100644 index 0000000000000..28e4bdcec77ec --- /dev/null +++ b/packages/@aws-cdk/aws-wisdom/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/@aws-cdk/aws-wisdom/NOTICE b/packages/@aws-cdk/aws-wisdom/NOTICE new file mode 100644 index 0000000000000..5fc3826926b5b --- /dev/null +++ b/packages/@aws-cdk/aws-wisdom/NOTICE @@ -0,0 +1,2 @@ +AWS Cloud Development Kit (AWS CDK) +Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/packages/@aws-cdk/aws-wisdom/README.md b/packages/@aws-cdk/aws-wisdom/README.md new file mode 100644 index 0000000000000..d942b3358d363 --- /dev/null +++ b/packages/@aws-cdk/aws-wisdom/README.md @@ -0,0 +1,20 @@ +# AWS::Wisdom Construct Library + + +--- + +![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge) + +> All classes with the `Cfn` prefix in this module ([CFN Resources]) are always stable and safe to use. +> +> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib + +--- + + + +This module is part of the [AWS Cloud Development Kit](https://github.com/aws/aws-cdk) project. + +```ts +import aws-wisdom = require('@aws-cdk/aws-wisdom'); +``` diff --git a/packages/@aws-cdk/aws-wisdom/jest.config.js b/packages/@aws-cdk/aws-wisdom/jest.config.js new file mode 100644 index 0000000000000..3a2fd93a1228a --- /dev/null +++ b/packages/@aws-cdk/aws-wisdom/jest.config.js @@ -0,0 +1,2 @@ +const baseConfig = require('@aws-cdk/cdk-build-tools/config/jest.config'); +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-wisdom/lib/index.ts b/packages/@aws-cdk/aws-wisdom/lib/index.ts new file mode 100644 index 0000000000000..368aee100e245 --- /dev/null +++ b/packages/@aws-cdk/aws-wisdom/lib/index.ts @@ -0,0 +1,2 @@ +// AWS::Wisdom CloudFormation Resources: +export * from './wisdom.generated'; diff --git a/packages/@aws-cdk/aws-wisdom/package.json b/packages/@aws-cdk/aws-wisdom/package.json new file mode 100644 index 0000000000000..44465292a4350 --- /dev/null +++ b/packages/@aws-cdk/aws-wisdom/package.json @@ -0,0 +1,105 @@ +{ + "name": "@aws-cdk/aws-wisdom", + "version": "0.0.0", + "description": "The CDK Construct Library for AWS::Wisdom", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "jsii": { + "outdir": "dist", + "projectReferences": true, + "targets": { + "dotnet": { + "namespace": "Amazon.CDK.AWS.Wisdom", + "packageId": "Amazon.CDK.AWS.Wisdom", + "signAssembly": true, + "assemblyOriginatorKeyFile": "../../key.snk", + "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png" + }, + "java": { + "package": "software.amazon.awscdk.services.wisdom", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "wisdom" + } + }, + "python": { + "classifiers": [ + "Framework :: AWS CDK", + "Framework :: AWS CDK :: 1" + ], + "distName": "aws-cdk.aws-wisdom", + "module": "aws_cdk.aws_wisdom" + } + } + }, + "repository": { + "type": "git", + "url": "https://github.com/aws/aws-cdk.git", + "directory": "packages/@aws-cdk/aws-wisdom" + }, + "homepage": "https://github.com/aws/aws-cdk", + "scripts": { + "build": "cdk-build", + "watch": "cdk-watch", + "lint": "cdk-lint", + "test": "cdk-test", + "integ": "cdk-integ", + "pkglint": "pkglint -f", + "package": "cdk-package", + "awslint": "cdk-awslint", + "cfn2ts": "cfn2ts", + "build+test": "yarn build && yarn test", + "build+test+package": "yarn build+test && yarn package", + "compat": "cdk-compat", + "gen": "cfn2ts", + "rosetta:extract": "yarn --silent jsii-rosetta extract", + "build+extract": "yarn build && yarn rosetta:extract", + "build+test+extract": "yarn build+test && yarn rosetta:extract" + }, + "cdk-build": { + "cloudformation": "AWS::Wisdom", + "jest": true, + "env": { + "AWSLINT_BASE_CONSTRUCT": "true" + } + }, + "keywords": [ + "aws", + "cdk", + "constructs", + "AWS::Wisdom", + "aws-wisdom" + ], + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "organization": true + }, + "license": "Apache-2.0", + "devDependencies": { + "@aws-cdk/assertions": "0.0.0", + "@aws-cdk/cdk-build-tools": "0.0.0", + "@aws-cdk/cfn2ts": "0.0.0", + "@aws-cdk/pkglint": "0.0.0", + "@types/jest": "^26.0.22" + }, + "dependencies": { + "@aws-cdk/core": "0.0.0", + "constructs": "^3.3.69" + }, + "peerDependencies": { + "@aws-cdk/core": "0.0.0", + "constructs": "^3.3.69" + }, + "engines": { + "node": ">= 10.13.0 <13 || >=13.7.0" + }, + "stability": "experimental", + "maturity": "cfn-only", + "awscdkio": { + "announce": false + }, + "publishConfig": { + "tag": "latest" + } +} diff --git a/packages/@aws-cdk/aws-wisdom/test/aws-wisdom.test.ts b/packages/@aws-cdk/aws-wisdom/test/aws-wisdom.test.ts new file mode 100644 index 0000000000000..465c7bdea0693 --- /dev/null +++ b/packages/@aws-cdk/aws-wisdom/test/aws-wisdom.test.ts @@ -0,0 +1,6 @@ +import '@aws-cdk/assertions'; +import {} from '../lib'; + +test('No tests are specified for this package', () => { + expect(true).toBe(true); +}); diff --git a/packages/@aws-cdk/cfnspec/CHANGELOG.md b/packages/@aws-cdk/cfnspec/CHANGELOG.md index 19c814c818182..51d94432f3293 100644 --- a/packages/@aws-cdk/cfnspec/CHANGELOG.md +++ b/packages/@aws-cdk/cfnspec/CHANGELOG.md @@ -1,3 +1,248 @@ +# CloudFormation Resource Specification v46.0.0 + +## New Resource Types + +* AWS::Connect::HoursOfOperation +* AWS::Connect::User +* AWS::Connect::UserHierarchyGroup +* AWS::EC2::CapacityReservationFleet +* AWS::IoT::JobTemplate +* AWS::Lightsail::Database +* AWS::Lightsail::StaticIp +* AWS::Panorama::ApplicationInstance +* AWS::Panorama::Package +* AWS::Panorama::PackageVersion +* AWS::Rekognition::Project +* AWS::Route53Resolver::ResolverConfig +* AWS::Wisdom::Assistant +* AWS::Wisdom::AssistantAssociation +* AWS::Wisdom::KnowledgeBase + +## Attribute Changes + +* AWS::ApiGateway::Authorizer AuthorizerId (__added__) +* AWS::AutoScaling::LifecycleHook Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html +* AWS::EC2::NetworkAcl Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkacl.html +* AWS::EC2::NetworkAcl Id (__added__) +* AWS::EC2::NetworkAclEntry Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html +* AWS::EC2::NetworkAclEntry Id (__added__) +* AWS::EC2::RouteTable Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-routetable.html +* AWS::EC2::RouteTable RouteTableId (__added__) +* AWS::Lightsail::Instance KeyPairName (__deleted__) +* AWS::Lightsail::Instance UserData (__deleted__) +* AWS::Route53Resolver::ResolverRule TargetIps.PrimitiveType (__deleted__) +* AWS::Route53Resolver::ResolverRule TargetIps.DuplicatesAllowed (__added__) +* AWS::Route53Resolver::ResolverRule TargetIps.ItemType (__added__) +* AWS::Route53Resolver::ResolverRule TargetIps.Type (__added__) +* AWS::StepFunctions::Activity Arn (__added__) + +## Property Changes + +* AWS::ApiGateway::Authorizer Name.Required (__changed__) + * Old: false + * New: true +* AWS::ApiGateway::VpcLink Tags (__added__) +* AWS::AutoScaling::AutoScalingGroup DesiredCapacityType (__added__) +* AWS::AutoScaling::LifecycleHook AutoScalingGroupName.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-autoscalinggroupname + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-autoscalinggroupname +* AWS::AutoScaling::LifecycleHook DefaultResult.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-defaultresult + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-defaultresult +* AWS::AutoScaling::LifecycleHook HeartbeatTimeout.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-heartbeattimeout + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-heartbeattimeout +* AWS::AutoScaling::LifecycleHook LifecycleHookName.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-autoscaling-lifecyclehook-lifecyclehookname + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-lifecyclehookname +* AWS::AutoScaling::LifecycleHook LifecycleTransition.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-lifecycletransition + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-lifecycletransition +* AWS::AutoScaling::LifecycleHook NotificationMetadata.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-notificationmetadata + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-notificationmetadata +* AWS::AutoScaling::LifecycleHook NotificationTargetARN.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-notificationtargetarn + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-notificationtargetarn +* AWS::AutoScaling::LifecycleHook RoleARN.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-rolearn + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-rolearn +* AWS::Batch::ComputeEnvironment UnmanagedvCpus (__added__) +* AWS::Batch::JobDefinition SchedulingPriority (__added__) +* AWS::Batch::JobQueue SchedulingPolicyArn (__added__) +* AWS::Budgets::BudgetsAction Subscribers.Required (__changed__) + * Old: false + * New: true +* AWS::Cassandra::Table DefaultTimeToLive (__added__) +* AWS::CodeStarNotifications::NotificationRule CreatedBy (__added__) +* AWS::CodeStarNotifications::NotificationRule EventTypeId (__added__) +* AWS::CodeStarNotifications::NotificationRule TargetAddress (__added__) +* AWS::EC2::NetworkAcl Tags.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html#cfn-ec2-networkacl-tags + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkacl.html#cfn-ec2-networkacl-tags +* AWS::EC2::NetworkAcl VpcId.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html#cfn-ec2-networkacl-vpcid + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkacl.html#cfn-ec2-networkacl-vpcid +* AWS::EC2::NetworkAclEntry CidrBlock.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-cidrblock + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-cidrblock +* AWS::EC2::NetworkAclEntry Egress.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-egress + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-egress +* AWS::EC2::NetworkAclEntry Icmp.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-icmp + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-icmp +* AWS::EC2::NetworkAclEntry Ipv6CidrBlock.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-ipv6cidrblock + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-ipv6cidrblock +* AWS::EC2::NetworkAclEntry NetworkAclId.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-networkaclid + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-networkaclid +* AWS::EC2::NetworkAclEntry PortRange.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-portrange + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-portrange +* AWS::EC2::NetworkAclEntry Protocol.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-protocol + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-protocol +* AWS::EC2::NetworkAclEntry RuleAction.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-ruleaction + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-ruleaction +* AWS::EC2::NetworkAclEntry RuleNumber.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-rulenumber + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-rulenumber +* AWS::EC2::RouteTable Tags.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html#cfn-ec2-routetable-tags + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-routetable.html#cfn-ec2-routetable-tags +* AWS::EC2::RouteTable VpcId.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html#cfn-ec2-routetable-vpcid + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-routetable.html#cfn-ec2-routetable-vpcid +* AWS::ECS::TaskDefinition RuntimePlatform (__added__) +* AWS::FMS::Policy ResourcesCleanUp (__added__) +* AWS::Glue::Registry Tags.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::Glue::Schema Tags.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::ImageBuilder::InfrastructureConfiguration InstanceMetadataOptions (__added__) +* AWS::Lightsail::Instance KeyPairName (__added__) +* AWS::Lightsail::Instance UserData (__added__) +* AWS::Location::Tracker PositionFiltering (__added__) +* AWS::MWAA::Environment Tags.Type (__deleted__) +* AWS::MWAA::Environment Tags.PrimitiveType (__added__) +* AWS::MemoryDB::Cluster ACLName.Required (__changed__) + * Old: false + * New: true +* AWS::MemoryDB::Cluster NodeType.Required (__changed__) + * Old: false + * New: true +* AWS::MemoryDB::ParameterGroup Family.Required (__changed__) + * Old: false + * New: true +* AWS::MemoryDB::SubnetGroup SubnetIds.Required (__changed__) + * Old: false + * New: true +* AWS::Pinpoint::Campaign Priority (__added__) +* AWS::QuickSight::Analysis SourceEntity.Required (__changed__) + * Old: false + * New: true +* AWS::QuickSight::Dashboard SourceEntity.Required (__changed__) + * Old: false + * New: true +* AWS::QuickSight::Template SourceEntity.Required (__changed__) + * Old: false + * New: true +* AWS::Route53RecoveryControl::Cluster Tags (__added__) +* AWS::Route53RecoveryControl::ControlPanel Tags (__added__) +* AWS::Route53RecoveryControl::SafetyRule Tags (__added__) +* AWS::Route53Resolver::ResolverRule Tags.DuplicatesAllowed (__added__) +* AWS::Route53Resolver::ResolverRule TargetIps.DuplicatesAllowed (__added__) +* AWS::SageMaker::NotebookInstance PlatformIdentifier (__added__) +* AWS::StepFunctions::Activity Tags.DuplicatesAllowed (__added__) +* AWS::Synthetics::Canary ArtifactConfig (__added__) + +## Property Type Changes + +* AWS::MWAA::Environment.TagMap (__removed__) +* AWS::AppFlow::ConnectorProfile.OAuthProperties (__added__) +* AWS::AppFlow::ConnectorProfile.SAPODataConnectorProfileCredentials (__added__) +* AWS::AppFlow::ConnectorProfile.SAPODataConnectorProfileProperties (__added__) +* AWS::AppFlow::Flow.S3InputFormatConfig (__added__) +* AWS::AppFlow::Flow.SAPODataSourceProperties (__added__) +* AWS::AutoScaling::AutoScalingGroup.AcceleratorCountRequest (__added__) +* AWS::AutoScaling::AutoScalingGroup.AcceleratorTotalMemoryMiBRequest (__added__) +* AWS::AutoScaling::AutoScalingGroup.BaselineEbsBandwidthMbpsRequest (__added__) +* AWS::AutoScaling::AutoScalingGroup.InstanceRequirements (__added__) +* AWS::AutoScaling::AutoScalingGroup.MemoryGiBPerVCpuRequest (__added__) +* AWS::AutoScaling::AutoScalingGroup.MemoryMiBRequest (__added__) +* AWS::AutoScaling::AutoScalingGroup.NetworkInterfaceCountRequest (__added__) +* AWS::AutoScaling::AutoScalingGroup.TotalLocalStorageGBRequest (__added__) +* AWS::AutoScaling::AutoScalingGroup.VCpuCountRequest (__added__) +* AWS::EC2::EC2Fleet.AcceleratorCountRequest (__added__) +* AWS::EC2::EC2Fleet.AcceleratorTotalMemoryMiBRequest (__added__) +* AWS::EC2::EC2Fleet.BaselineEbsBandwidthMbpsRequest (__added__) +* AWS::EC2::EC2Fleet.InstanceRequirementsRequest (__added__) +* AWS::EC2::EC2Fleet.MemoryGiBPerVCpuRequest (__added__) +* AWS::EC2::EC2Fleet.MemoryMiBRequest (__added__) +* AWS::EC2::EC2Fleet.NetworkInterfaceCountRequest (__added__) +* AWS::EC2::EC2Fleet.TotalLocalStorageGBRequest (__added__) +* AWS::EC2::EC2Fleet.VCpuCountRangeRequest (__added__) +* AWS::EC2::SpotFleet.AcceleratorCountRequest (__added__) +* AWS::EC2::SpotFleet.AcceleratorTotalMemoryMiBRequest (__added__) +* AWS::EC2::SpotFleet.BaselineEbsBandwidthMbpsRequest (__added__) +* AWS::EC2::SpotFleet.InstanceRequirementsRequest (__added__) +* AWS::EC2::SpotFleet.MemoryGiBPerVCpuRequest (__added__) +* AWS::EC2::SpotFleet.MemoryMiBRequest (__added__) +* AWS::EC2::SpotFleet.NetworkInterfaceCountRequest (__added__) +* AWS::EC2::SpotFleet.TotalLocalStorageGBRequest (__added__) +* AWS::EC2::SpotFleet.VCpuCountRangeRequest (__added__) +* AWS::ECS::TaskDefinition.RuntimePlatform (__added__) +* AWS::ImageBuilder::InfrastructureConfiguration.InstanceMetadataOptions (__added__) +* AWS::Pinpoint::Campaign.CampaignInAppMessage (__added__) +* AWS::Pinpoint::Campaign.DefaultButtonConfiguration (__added__) +* AWS::Pinpoint::Campaign.InAppMessageBodyConfig (__added__) +* AWS::Pinpoint::Campaign.InAppMessageButton (__added__) +* AWS::Pinpoint::Campaign.InAppMessageContent (__added__) +* AWS::Pinpoint::Campaign.InAppMessageHeaderConfig (__added__) +* AWS::Pinpoint::Campaign.OverrideButtonConfiguration (__added__) +* AWS::QuickSight::DataSource.AmazonOpenSearchParameters (__added__) +* AWS::Synthetics::Canary.ArtifactConfig (__added__) +* AWS::Synthetics::Canary.S3Encryption (__added__) +* AWS::AppFlow::ConnectorProfile.ConnectorProfileCredentials SAPOData (__added__) +* AWS::AppFlow::ConnectorProfile.ConnectorProfileProperties SAPOData (__added__) +* AWS::AppFlow::Flow.ConnectorOperator SAPOData (__added__) +* AWS::AppFlow::Flow.S3SourceProperties S3InputFormatConfig (__added__) +* AWS::AppFlow::Flow.SourceConnectorProperties SAPOData (__added__) +* AWS::AutoScaling::AutoScalingGroup.LaunchTemplateOverrides InstanceRequirements (__added__) +* AWS::Backup::BackupSelection.BackupSelectionResourceType Conditions (__added__) +* AWS::Backup::BackupSelection.BackupSelectionResourceType NotResources (__added__) +* AWS::CodeBuild::Project.ProjectBuildBatchConfig BatchReportMode (__added__) +* AWS::EC2::EC2Fleet.FleetLaunchTemplateOverridesRequest InstanceRequirements (__added__) +* AWS::EC2::EC2Fleet.SpotOptionsRequest MaintenanceStrategies (__added__) +* AWS::EC2::EC2Fleet.TargetCapacitySpecificationRequest TargetCapacityUnitType (__added__) +* AWS::EC2::SpotFleet.LaunchTemplateOverrides InstanceRequirements (__added__) +* AWS::EC2::SpotFleet.SpotCapacityRebalance TerminationDelay (__added__) +* AWS::EC2::SpotFleet.SpotFleetLaunchSpecification InstanceRequirements (__added__) +* AWS::EC2::SpotFleet.SpotFleetLaunchSpecification InstanceType.Required (__changed__) + * Old: true + * New: false +* AWS::EC2::SpotFleet.SpotFleetRequestConfigData TargetCapacityUnitType (__added__) +* AWS::ImageBuilder::ContainerRecipe.EbsInstanceBlockDeviceSpecification Throughput (__added__) +* AWS::ImageBuilder::ImageRecipe.EbsInstanceBlockDeviceSpecification Throughput (__added__) +* AWS::Lightsail::Instance.Networking MonthlyTransfer.Type (__added__) +* AWS::Pinpoint::Campaign.Limits Session (__added__) +* AWS::Pinpoint::Campaign.MessageConfiguration InAppMessage (__added__) +* AWS::QuickSight::DataSource.DataSourceParameters AmazonOpenSearchParameters (__added__) + + # CloudFormation Resource Specification v43.0.0 ## New Resource Types diff --git a/packages/@aws-cdk/cfnspec/cfn.version b/packages/@aws-cdk/cfnspec/cfn.version index f3986a67888db..783c5bb1ce5c2 100644 --- a/packages/@aws-cdk/cfnspec/cfn.version +++ b/packages/@aws-cdk/cfnspec/cfn.version @@ -1 +1 @@ -43.0.0 +46.0.0 diff --git a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json index b5b29349fe4e4..2db5051c26ccf 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json +++ b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json @@ -2557,6 +2557,12 @@ "Type": "RedshiftConnectorProfileCredentials", "UpdateType": "Mutable" }, + "SAPOData": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-connectorprofilecredentials.html#cfn-appflow-connectorprofile-connectorprofilecredentials-sapodata", + "Required": false, + "Type": "SAPODataConnectorProfileCredentials", + "UpdateType": "Mutable" + }, "Salesforce": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-connectorprofilecredentials.html#cfn-appflow-connectorprofile-connectorprofilecredentials-salesforce", "Required": false, @@ -2640,6 +2646,12 @@ "Type": "RedshiftConnectorProfileProperties", "UpdateType": "Mutable" }, + "SAPOData": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-connectorprofileproperties.html#cfn-appflow-connectorprofile-connectorprofileproperties-sapodata", + "Required": false, + "Type": "SAPODataConnectorProfileProperties", + "UpdateType": "Mutable" + }, "Salesforce": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-connectorprofileproperties.html#cfn-appflow-connectorprofile-connectorprofileproperties-salesforce", "Required": false, @@ -2843,6 +2855,31 @@ } } }, + "AWS::AppFlow::ConnectorProfile.OAuthProperties": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-oauthproperties.html", + "Properties": { + "AuthCodeUrl": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-oauthproperties.html#cfn-appflow-connectorprofile-oauthproperties-authcodeurl", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "OAuthScopes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-oauthproperties.html#cfn-appflow-connectorprofile-oauthproperties-oauthscopes", + "DuplicatesAllowed": false, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "TokenUrl": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-oauthproperties.html#cfn-appflow-connectorprofile-oauthproperties-tokenurl", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::AppFlow::ConnectorProfile.RedshiftConnectorProfileCredentials": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-redshiftconnectorprofilecredentials.html", "Properties": { @@ -2889,6 +2926,70 @@ } } }, + "AWS::AppFlow::ConnectorProfile.SAPODataConnectorProfileCredentials": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofilecredentials.html", + "Properties": { + "BasicAuthCredentials": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofilecredentials.html#cfn-appflow-connectorprofile-sapodataconnectorprofilecredentials-basicauthcredentials", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Mutable" + }, + "OAuthCredentials": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofilecredentials.html#cfn-appflow-connectorprofile-sapodataconnectorprofilecredentials-oauthcredentials", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::AppFlow::ConnectorProfile.SAPODataConnectorProfileProperties": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html", + "Properties": { + "ApplicationHostUrl": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html#cfn-appflow-connectorprofile-sapodataconnectorprofileproperties-applicationhosturl", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ApplicationServicePath": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html#cfn-appflow-connectorprofile-sapodataconnectorprofileproperties-applicationservicepath", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ClientNumber": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html#cfn-appflow-connectorprofile-sapodataconnectorprofileproperties-clientnumber", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "LogonLanguage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html#cfn-appflow-connectorprofile-sapodataconnectorprofileproperties-logonlanguage", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "OAuthProperties": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html#cfn-appflow-connectorprofile-sapodataconnectorprofileproperties-oauthproperties", + "Required": false, + "Type": "OAuthProperties", + "UpdateType": "Mutable" + }, + "PortNumber": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html#cfn-appflow-connectorprofile-sapodataconnectorprofileproperties-portnumber", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "PrivateLinkServiceName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-sapodataconnectorprofileproperties.html#cfn-appflow-connectorprofile-sapodataconnectorprofileproperties-privatelinkservicename", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::AppFlow::ConnectorProfile.SalesforceConnectorProfileCredentials": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-connectorprofile-salesforceconnectorprofilecredentials.html", "Properties": { @@ -3224,6 +3325,12 @@ "Required": false, "UpdateType": "Mutable" }, + "SAPOData": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-connectoroperator.html#cfn-appflow-flow-connectoroperator-sapodata", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "Salesforce": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-connectoroperator.html#cfn-appflow-flow-connectoroperator-salesforce", "PrimitiveType": "String", @@ -3530,6 +3637,17 @@ } } }, + "AWS::AppFlow::Flow.S3InputFormatConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-s3inputformatconfig.html", + "Properties": { + "S3InputFileType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-s3inputformatconfig.html#cfn-appflow-flow-s3inputformatconfig-s3inputfiletype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::AppFlow::Flow.S3OutputFormatConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-s3outputformatconfig.html", "Properties": { @@ -3567,6 +3685,23 @@ "PrimitiveType": "String", "Required": true, "UpdateType": "Mutable" + }, + "S3InputFormatConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-s3sourceproperties.html#cfn-appflow-flow-s3sourceproperties-s3inputformatconfig", + "Required": false, + "Type": "S3InputFormatConfig", + "UpdateType": "Mutable" + } + } + }, + "AWS::AppFlow::Flow.SAPODataSourceProperties": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-sapodatasourceproperties.html", + "Properties": { + "ObjectPath": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-sapodatasourceproperties.html#cfn-appflow-flow-sapodatasourceproperties-objectpath", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" } } }, @@ -3771,6 +3906,12 @@ "Type": "S3SourceProperties", "UpdateType": "Mutable" }, + "SAPOData": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-sourceconnectorproperties.html#cfn-appflow-flow-sourceconnectorproperties-sapodata", + "Required": false, + "Type": "SAPODataSourceProperties", + "UpdateType": "Mutable" + }, "Salesforce": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appflow-flow-sourceconnectorproperties.html#cfn-appflow-flow-sourceconnectorproperties-salesforce", "Required": false, @@ -8309,6 +8450,202 @@ } } }, + "AWS::AutoScaling::AutoScalingGroup.AcceleratorCountRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-acceleratorcountrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-acceleratorcountrequest.html#cfn-autoscaling-autoscalinggroup-acceleratorcountrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-acceleratorcountrequest.html#cfn-autoscaling-autoscalinggroup-acceleratorcountrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::AutoScaling::AutoScalingGroup.AcceleratorTotalMemoryMiBRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-acceleratortotalmemorymibrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-acceleratortotalmemorymibrequest.html#cfn-autoscaling-autoscalinggroup-acceleratortotalmemorymibrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-acceleratortotalmemorymibrequest.html#cfn-autoscaling-autoscalinggroup-acceleratortotalmemorymibrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::AutoScaling::AutoScalingGroup.BaselineEbsBandwidthMbpsRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-baselineebsbandwidthmbpsrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-baselineebsbandwidthmbpsrequest.html#cfn-autoscaling-autoscalinggroup-baselineebsbandwidthmbpsrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-baselineebsbandwidthmbpsrequest.html#cfn-autoscaling-autoscalinggroup-baselineebsbandwidthmbpsrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::AutoScaling::AutoScalingGroup.InstanceRequirements": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html", + "Properties": { + "AcceleratorCount": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-acceleratorcount", + "Required": false, + "Type": "AcceleratorCountRequest", + "UpdateType": "Mutable" + }, + "AcceleratorManufacturers": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-acceleratormanufacturers", + "DuplicatesAllowed": false, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "AcceleratorNames": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-acceleratornames", + "DuplicatesAllowed": false, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "AcceleratorTotalMemoryMiB": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-acceleratortotalmemorymib", + "Required": false, + "Type": "AcceleratorTotalMemoryMiBRequest", + "UpdateType": "Mutable" + }, + "AcceleratorTypes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-acceleratortypes", + "DuplicatesAllowed": false, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "BareMetal": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-baremetal", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "BaselineEbsBandwidthMbps": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-baselineebsbandwidthmbps", + "Required": false, + "Type": "BaselineEbsBandwidthMbpsRequest", + "UpdateType": "Mutable" + }, + "BurstablePerformance": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-burstableperformance", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "CpuManufacturers": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-cpumanufacturers", + "DuplicatesAllowed": false, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "ExcludedInstanceTypes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-excludedinstancetypes", + "DuplicatesAllowed": false, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "InstanceGenerations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-instancegenerations", + "DuplicatesAllowed": false, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "LocalStorage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-localstorage", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "LocalStorageTypes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-localstoragetypes", + "DuplicatesAllowed": false, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "MemoryGiBPerVCpu": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-memorygibpervcpu", + "Required": false, + "Type": "MemoryGiBPerVCpuRequest", + "UpdateType": "Mutable" + }, + "MemoryMiB": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-memorymib", + "Required": false, + "Type": "MemoryMiBRequest", + "UpdateType": "Mutable" + }, + "NetworkInterfaceCount": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-networkinterfacecount", + "Required": false, + "Type": "NetworkInterfaceCountRequest", + "UpdateType": "Mutable" + }, + "OnDemandMaxPricePercentageOverLowestPrice": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-ondemandmaxpricepercentageoverlowestprice", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "RequireHibernateSupport": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-requirehibernatesupport", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "SpotMaxPricePercentageOverLowestPrice": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-spotmaxpricepercentageoverlowestprice", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "TotalLocalStorageGB": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-totallocalstoragegb", + "Required": false, + "Type": "TotalLocalStorageGBRequest", + "UpdateType": "Mutable" + }, + "VCpuCount": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancerequirements.html#cfn-autoscaling-autoscalinggroup-instancerequirements-vcpucount", + "Required": false, + "Type": "VCpuCountRequest", + "UpdateType": "Mutable" + } + } + }, "AWS::AutoScaling::AutoScalingGroup.InstancesDistribution": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-instancesdistribution.html", "Properties": { @@ -8372,6 +8709,12 @@ "AWS::AutoScaling::AutoScalingGroup.LaunchTemplateOverrides": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-launchtemplateoverrides.html", "Properties": { + "InstanceRequirements": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-launchtemplateoverrides.html#cfn-as-mixedinstancespolicy-instancerequirements", + "Required": false, + "Type": "InstanceRequirements", + "UpdateType": "Mutable" + }, "InstanceType": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-as-mixedinstancespolicy-launchtemplateoverrides.html#cfn-autoscaling-autoscalinggroup-launchtemplateoverrides-instancetype", "PrimitiveType": "String", @@ -8462,6 +8805,40 @@ } } }, + "AWS::AutoScaling::AutoScalingGroup.MemoryGiBPerVCpuRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-memorygibpervcpurequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-memorygibpervcpurequest.html#cfn-autoscaling-autoscalinggroup-memorygibpervcpurequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-memorygibpervcpurequest.html#cfn-autoscaling-autoscalinggroup-memorygibpervcpurequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::AutoScaling::AutoScalingGroup.MemoryMiBRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-memorymibrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-memorymibrequest.html#cfn-autoscaling-autoscalinggroup-memorymibrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-memorymibrequest.html#cfn-autoscaling-autoscalinggroup-memorymibrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::AutoScaling::AutoScalingGroup.MetricsCollection": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-metricscollection.html", "Properties": { @@ -8498,6 +8875,23 @@ } } }, + "AWS::AutoScaling::AutoScalingGroup.NetworkInterfaceCountRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-networkinterfacecountrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-networkinterfacecountrequest.html#cfn-autoscaling-autoscalinggroup-networkinterfacecountrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-networkinterfacecountrequest.html#cfn-autoscaling-autoscalinggroup-networkinterfacecountrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::AutoScaling::AutoScalingGroup.NotificationConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-notificationconfigurations.html", "Properties": { @@ -8540,6 +8934,40 @@ } } }, + "AWS::AutoScaling::AutoScalingGroup.TotalLocalStorageGBRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-totallocalstoragegbrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-totallocalstoragegbrequest.html#cfn-autoscaling-autoscalinggroup-totallocalstoragegbrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-totallocalstoragegbrequest.html#cfn-autoscaling-autoscalinggroup-totallocalstoragegbrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::AutoScaling::AutoScalingGroup.VCpuCountRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-vcpucountrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-vcpucountrequest.html#cfn-autoscaling-autoscalinggroup-vcpucountrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-autoscaling-autoscalinggroup-vcpucountrequest.html#cfn-autoscaling-autoscalinggroup-vcpucountrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::AutoScaling::LaunchConfiguration.BlockDevice": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-launchconfig-blockdev-template.html", "Properties": { @@ -9318,6 +9746,12 @@ "AWS::Backup::BackupSelection.BackupSelectionResourceType": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-backup-backupselection-backupselectionresourcetype.html", "Properties": { + "Conditions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-backup-backupselection-backupselectionresourcetype.html#cfn-backup-backupselection-backupselectionresourcetype-conditions", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Immutable" + }, "IamRoleArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-backup-backupselection-backupselectionresourcetype.html#cfn-backup-backupselection-backupselectionresourcetype-iamrolearn", "PrimitiveType": "String", @@ -9332,6 +9766,14 @@ "Type": "List", "UpdateType": "Immutable" }, + "NotResources": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-backup-backupselection-backupselectionresourcetype.html#cfn-backup-backupselection-backupselectionresourcetype-notresources", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, "Resources": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-backup-backupselection-backupselectionresourcetype.html#cfn-backup-backupselection-backupselectionresourcetype-resources", "DuplicatesAllowed": true, @@ -12684,6 +13126,12 @@ "AWS::CodeBuild::Project.ProjectBuildBatchConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-projectbuildbatchconfig.html", "Properties": { + "BatchReportMode": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-projectbuildbatchconfig.html#cfn-codebuild-project-projectbuildbatchconfig-batchreportmode", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "CombineArtifacts": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-projectbuildbatchconfig.html#cfn-codebuild-project-projectbuildbatchconfig-combineartifacts", "PrimitiveType": "Boolean", @@ -15284,6 +15732,46 @@ } } }, + "AWS::Connect::HoursOfOperation.HoursOfOperationConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationconfig.html", + "Properties": { + "Day": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationconfig.html#cfn-connect-hoursofoperation-hoursofoperationconfig-day", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "EndTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationconfig.html#cfn-connect-hoursofoperation-hoursofoperationconfig-endtime", + "Required": true, + "Type": "HoursOfOperationTimeSlice", + "UpdateType": "Mutable" + }, + "StartTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationconfig.html#cfn-connect-hoursofoperation-hoursofoperationconfig-starttime", + "Required": true, + "Type": "HoursOfOperationTimeSlice", + "UpdateType": "Mutable" + } + } + }, + "AWS::Connect::HoursOfOperation.HoursOfOperationTimeSlice": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationtimeslice.html", + "Properties": { + "Hours": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationtimeslice.html#cfn-connect-hoursofoperation-hoursofoperationtimeslice-hours", + "PrimitiveType": "Integer", + "Required": true, + "UpdateType": "Mutable" + }, + "Minutes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-hoursofoperation-hoursofoperationtimeslice.html#cfn-connect-hoursofoperation-hoursofoperationtimeslice-minutes", + "PrimitiveType": "Integer", + "Required": true, + "UpdateType": "Mutable" + } + } + }, "AWS::Connect::QuickConnect.PhoneNumberQuickConnectConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-quickconnect-phonenumberquickconnectconfig.html", "Properties": { @@ -15358,6 +15846,58 @@ } } }, + "AWS::Connect::User.UserIdentityInfo": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-useridentityinfo.html", + "Properties": { + "Email": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-useridentityinfo.html#cfn-connect-user-useridentityinfo-email", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "FirstName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-useridentityinfo.html#cfn-connect-user-useridentityinfo-firstname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "LastName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-useridentityinfo.html#cfn-connect-user-useridentityinfo-lastname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Connect::User.UserPhoneConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-userphoneconfig.html", + "Properties": { + "AfterContactWorkTimeLimit": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-userphoneconfig.html#cfn-connect-user-userphoneconfig-aftercontactworktimelimit", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "AutoAccept": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-userphoneconfig.html#cfn-connect-user-userphoneconfig-autoaccept", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "DeskPhoneNumber": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-userphoneconfig.html#cfn-connect-user-userphoneconfig-deskphonenumber", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "PhoneType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-connect-user-userphoneconfig.html#cfn-connect-user-userphoneconfig-phonetype", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, "AWS::CustomerProfiles::Integration.ConnectorOperator": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-customerprofiles-integration-connectoroperator.html", "Properties": { @@ -19032,6 +19572,72 @@ } } }, + "AWS::EC2::CapacityReservationFleet.InstanceTypeSpecification": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html", + "Properties": { + "AvailabilityZone": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html#cfn-ec2-capacityreservationfleet-instancetypespecification-availabilityzone", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "AvailabilityZoneId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html#cfn-ec2-capacityreservationfleet-instancetypespecification-availabilityzoneid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "EbsOptimized": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html#cfn-ec2-capacityreservationfleet-instancetypespecification-ebsoptimized", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Immutable" + }, + "InstancePlatform": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html#cfn-ec2-capacityreservationfleet-instancetypespecification-instanceplatform", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "InstanceType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html#cfn-ec2-capacityreservationfleet-instancetypespecification-instancetype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Priority": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html#cfn-ec2-capacityreservationfleet-instancetypespecification-priority", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "Weight": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-instancetypespecification.html#cfn-ec2-capacityreservationfleet-instancetypespecification-weight", + "PrimitiveType": "Double", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::EC2::CapacityReservationFleet.TagSpecification": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-tagspecification.html", + "Properties": { + "ResourceType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-tagspecification.html#cfn-ec2-capacityreservationfleet-tagspecification-resourcetype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-capacityreservationfleet-tagspecification.html#cfn-ec2-capacityreservationfleet-tagspecification-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + } + } + }, "AWS::EC2::ClientVpnEndpoint.CertificateAuthenticationRequest": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-clientvpnendpoint-certificateauthenticationrequest.html", "Properties": { @@ -19158,6 +19764,57 @@ } } }, + "AWS::EC2::EC2Fleet.AcceleratorCountRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-acceleratorcountrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-acceleratorcountrequest.html#cfn-ec2-ec2fleet-acceleratorcountrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-acceleratorcountrequest.html#cfn-ec2-ec2fleet-acceleratorcountrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::EC2::EC2Fleet.AcceleratorTotalMemoryMiBRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-acceleratortotalmemorymibrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-acceleratortotalmemorymibrequest.html#cfn-ec2-ec2fleet-acceleratortotalmemorymibrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-acceleratortotalmemorymibrequest.html#cfn-ec2-ec2fleet-acceleratortotalmemorymibrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::EC2::EC2Fleet.BaselineEbsBandwidthMbpsRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-baselineebsbandwidthmbpsrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-baselineebsbandwidthmbpsrequest.html#cfn-ec2-ec2fleet-baselineebsbandwidthmbpsrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-baselineebsbandwidthmbpsrequest.html#cfn-ec2-ec2fleet-baselineebsbandwidthmbpsrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, "AWS::EC2::EC2Fleet.CapacityReservationOptionsRequest": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-capacityreservationoptionsrequest.html", "Properties": { @@ -19197,6 +19854,12 @@ "Required": false, "UpdateType": "Immutable" }, + "InstanceRequirements": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest-instancerequirements", + "Required": false, + "Type": "InstanceRequirementsRequest", + "UpdateType": "Immutable" + }, "InstanceType": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest.html#cfn-ec2-ec2fleet-fleetlaunchtemplateoverridesrequest-instancetype", "PrimitiveType": "String", @@ -19258,6 +19921,202 @@ } } }, + "AWS::EC2::EC2Fleet.InstanceRequirementsRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html", + "Properties": { + "AcceleratorCount": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-acceleratorcount", + "Required": false, + "Type": "AcceleratorCountRequest", + "UpdateType": "Immutable" + }, + "AcceleratorManufacturers": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-acceleratormanufacturers", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "AcceleratorNames": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-acceleratornames", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "AcceleratorTotalMemoryMiB": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-acceleratortotalmemorymib", + "Required": false, + "Type": "AcceleratorTotalMemoryMiBRequest", + "UpdateType": "Immutable" + }, + "AcceleratorTypes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-acceleratortypes", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "BareMetal": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-baremetal", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "BaselineEbsBandwidthMbps": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-baselineebsbandwidthmbps", + "Required": false, + "Type": "BaselineEbsBandwidthMbpsRequest", + "UpdateType": "Immutable" + }, + "BurstablePerformance": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-burstableperformance", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "CpuManufacturers": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-cpumanufacturers", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "ExcludedInstanceTypes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-excludedinstancetypes", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "InstanceGenerations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-instancegenerations", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "LocalStorage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-localstorage", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "LocalStorageTypes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-localstoragetypes", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "MemoryGiBPerVCpu": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-memorygibpervcpu", + "Required": false, + "Type": "MemoryGiBPerVCpuRequest", + "UpdateType": "Immutable" + }, + "MemoryMiB": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-memorymib", + "Required": false, + "Type": "MemoryMiBRequest", + "UpdateType": "Immutable" + }, + "NetworkInterfaceCount": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-networkinterfacecount", + "Required": false, + "Type": "NetworkInterfaceCountRequest", + "UpdateType": "Immutable" + }, + "OnDemandMaxPricePercentageOverLowestPrice": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-ondemandmaxpricepercentageoverlowestprice", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "RequireHibernateSupport": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-requirehibernatesupport", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Immutable" + }, + "SpotMaxPricePercentageOverLowestPrice": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-spotmaxpricepercentageoverlowestprice", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "TotalLocalStorageGB": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-totallocalstoragegb", + "Required": false, + "Type": "TotalLocalStorageGBRequest", + "UpdateType": "Immutable" + }, + "VCpuCount": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-instancerequirementsrequest.html#cfn-ec2-ec2fleet-instancerequirementsrequest-vcpucount", + "Required": false, + "Type": "VCpuCountRangeRequest", + "UpdateType": "Immutable" + } + } + }, + "AWS::EC2::EC2Fleet.MemoryGiBPerVCpuRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-memorygibpervcpurequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-memorygibpervcpurequest.html#cfn-ec2-ec2fleet-memorygibpervcpurequest-max", + "PrimitiveType": "Double", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-memorygibpervcpurequest.html#cfn-ec2-ec2fleet-memorygibpervcpurequest-min", + "PrimitiveType": "Double", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::EC2::EC2Fleet.MemoryMiBRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-memorymibrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-memorymibrequest.html#cfn-ec2-ec2fleet-memorymibrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-memorymibrequest.html#cfn-ec2-ec2fleet-memorymibrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::EC2::EC2Fleet.NetworkInterfaceCountRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-networkinterfacecountrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-networkinterfacecountrequest.html#cfn-ec2-ec2fleet-networkinterfacecountrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-networkinterfacecountrequest.html#cfn-ec2-ec2fleet-networkinterfacecountrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, "AWS::EC2::EC2Fleet.OnDemandOptionsRequest": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-ondemandoptionsrequest.html", "Properties": { @@ -19373,6 +20232,12 @@ "Required": false, "UpdateType": "Immutable" }, + "MaintenanceStrategies": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-spotoptionsrequest.html#cfn-ec2-ec2fleet-spotoptionsrequest-maintenancestrategies", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Immutable" + }, "MaxTotalPrice": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-spotoptionsrequest.html#cfn-ec2-ec2fleet-spotoptionsrequest-maxtotalprice", "PrimitiveType": "String", @@ -19439,6 +20304,12 @@ "Required": false, "UpdateType": "Mutable" }, + "TargetCapacityUnitType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-targetcapacityspecificationrequest.html#cfn-ec2-ec2fleet-targetcapacityspecificationrequest-targetcapacityunittype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "TotalTargetCapacity": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-targetcapacityspecificationrequest.html#cfn-ec2-ec2fleet-targetcapacityspecificationrequest-totaltargetcapacity", "PrimitiveType": "Integer", @@ -19447,6 +20318,40 @@ } } }, + "AWS::EC2::EC2Fleet.TotalLocalStorageGBRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-totallocalstoragegbrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-totallocalstoragegbrequest.html#cfn-ec2-ec2fleet-totallocalstoragegbrequest-max", + "PrimitiveType": "Double", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-totallocalstoragegbrequest.html#cfn-ec2-ec2fleet-totallocalstoragegbrequest-min", + "PrimitiveType": "Double", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::EC2::EC2Fleet.VCpuCountRangeRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-vcpucountrangerequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-vcpucountrangerequest.html#cfn-ec2-ec2fleet-vcpucountrangerequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-vcpucountrangerequest.html#cfn-ec2-ec2fleet-vcpucountrangerequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, "AWS::EC2::Instance.AssociationParameter": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance-ssmassociations-associationparameters.html", "Properties": { @@ -21478,6 +22383,57 @@ } } }, + "AWS::EC2::SpotFleet.AcceleratorCountRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-acceleratorcountrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-acceleratorcountrequest.html#cfn-ec2-spotfleet-acceleratorcountrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-acceleratorcountrequest.html#cfn-ec2-spotfleet-acceleratorcountrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::EC2::SpotFleet.AcceleratorTotalMemoryMiBRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-acceleratortotalmemorymibrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-acceleratortotalmemorymibrequest.html#cfn-ec2-spotfleet-acceleratortotalmemorymibrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-acceleratortotalmemorymibrequest.html#cfn-ec2-spotfleet-acceleratortotalmemorymibrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::EC2::SpotFleet.BaselineEbsBandwidthMbpsRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-baselineebsbandwidthmbpsrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-baselineebsbandwidthmbpsrequest.html#cfn-ec2-spotfleet-baselineebsbandwidthmbpsrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-baselineebsbandwidthmbpsrequest.html#cfn-ec2-spotfleet-baselineebsbandwidthmbpsrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, "AWS::EC2::SpotFleet.BlockDeviceMapping": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-blockdevicemapping.html", "Properties": { @@ -21705,6 +22661,151 @@ } } }, + "AWS::EC2::SpotFleet.InstanceRequirementsRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html", + "Properties": { + "AcceleratorCount": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-acceleratorcount", + "Required": false, + "Type": "AcceleratorCountRequest", + "UpdateType": "Immutable" + }, + "AcceleratorManufacturers": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-acceleratormanufacturers", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "AcceleratorNames": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-acceleratornames", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "AcceleratorTotalMemoryMiB": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-acceleratortotalmemorymib", + "Required": false, + "Type": "AcceleratorTotalMemoryMiBRequest", + "UpdateType": "Immutable" + }, + "AcceleratorTypes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-acceleratortypes", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "BareMetal": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-baremetal", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "BaselineEbsBandwidthMbps": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-baselineebsbandwidthmbps", + "Required": false, + "Type": "BaselineEbsBandwidthMbpsRequest", + "UpdateType": "Immutable" + }, + "BurstablePerformance": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-burstableperformance", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "CpuManufacturers": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-cpumanufacturers", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "ExcludedInstanceTypes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-excludedinstancetypes", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "InstanceGenerations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-instancegenerations", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "LocalStorage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-localstorage", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "LocalStorageTypes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-localstoragetypes", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "MemoryGiBPerVCpu": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-memorygibpervcpu", + "Required": false, + "Type": "MemoryGiBPerVCpuRequest", + "UpdateType": "Immutable" + }, + "MemoryMiB": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-memorymib", + "Required": false, + "Type": "MemoryMiBRequest", + "UpdateType": "Immutable" + }, + "NetworkInterfaceCount": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-networkinterfacecount", + "Required": false, + "Type": "NetworkInterfaceCountRequest", + "UpdateType": "Immutable" + }, + "OnDemandMaxPricePercentageOverLowestPrice": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-ondemandmaxpricepercentageoverlowestprice", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "RequireHibernateSupport": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-requirehibernatesupport", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Immutable" + }, + "SpotMaxPricePercentageOverLowestPrice": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-spotmaxpricepercentageoverlowestprice", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "TotalLocalStorageGB": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-totallocalstoragegb", + "Required": false, + "Type": "TotalLocalStorageGBRequest", + "UpdateType": "Immutable" + }, + "VCpuCount": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-instancerequirementsrequest.html#cfn-ec2-spotfleet-instancerequirementsrequest-vcpucount", + "Required": false, + "Type": "VCpuCountRangeRequest", + "UpdateType": "Immutable" + } + } + }, "AWS::EC2::SpotFleet.LaunchTemplateConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateconfig.html", "Properties": { @@ -21733,6 +22834,12 @@ "Required": false, "UpdateType": "Immutable" }, + "InstanceRequirements": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateoverrides.html#cfn-ec2-spotfleet-launchtemplateoverrides-instancerequirements", + "Required": false, + "Type": "InstanceRequirementsRequest", + "UpdateType": "Immutable" + }, "InstanceType": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-launchtemplateoverrides.html#cfn-ec2-spotfleet-launchtemplateoverrides-instancetype", "PrimitiveType": "String", @@ -21776,6 +22883,57 @@ } } }, + "AWS::EC2::SpotFleet.MemoryGiBPerVCpuRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-memorygibpervcpurequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-memorygibpervcpurequest.html#cfn-ec2-spotfleet-memorygibpervcpurequest-max", + "PrimitiveType": "Double", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-memorygibpervcpurequest.html#cfn-ec2-spotfleet-memorygibpervcpurequest-min", + "PrimitiveType": "Double", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::EC2::SpotFleet.MemoryMiBRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-memorymibrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-memorymibrequest.html#cfn-ec2-spotfleet-memorymibrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-memorymibrequest.html#cfn-ec2-spotfleet-memorymibrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::EC2::SpotFleet.NetworkInterfaceCountRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-networkinterfacecountrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-networkinterfacecountrequest.html#cfn-ec2-spotfleet-networkinterfacecountrequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-networkinterfacecountrequest.html#cfn-ec2-spotfleet-networkinterfacecountrequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, "AWS::EC2::SpotFleet.PrivateIpAddressSpecification": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-privateipaddressspecification.html", "Properties": { @@ -21801,6 +22959,12 @@ "PrimitiveType": "String", "Required": false, "UpdateType": "Immutable" + }, + "TerminationDelay": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotcapacityrebalance.html#cfn-ec2-spotfleet-spotcapacityrebalance-terminationdelay", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" } } }, @@ -21833,10 +22997,16 @@ "Required": true, "UpdateType": "Immutable" }, + "InstanceRequirements": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetlaunchspecification.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-instancerequirements", + "Required": false, + "Type": "InstanceRequirementsRequest", + "UpdateType": "Immutable" + }, "InstanceType": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetlaunchspecification.html#cfn-ec2-spotfleet-spotfleetlaunchspecification-instancetype", "PrimitiveType": "String", - "Required": true, + "Required": false, "UpdateType": "Immutable" }, "KernelId": { @@ -22039,6 +23209,12 @@ "Required": true, "UpdateType": "Mutable" }, + "TargetCapacityUnitType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-targetcapacityunittype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "TerminateInstancesWithExpiration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-spotfleetrequestconfigdata.html#cfn-ec2-spotfleet-spotfleetrequestconfigdata-terminateinstanceswithexpiration", "PrimitiveType": "Boolean", @@ -22142,6 +23318,40 @@ } } }, + "AWS::EC2::SpotFleet.TotalLocalStorageGBRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-totallocalstoragegbrequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-totallocalstoragegbrequest.html#cfn-ec2-spotfleet-totallocalstoragegbrequest-max", + "PrimitiveType": "Double", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-totallocalstoragegbrequest.html#cfn-ec2-spotfleet-totallocalstoragegbrequest-min", + "PrimitiveType": "Double", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::EC2::SpotFleet.VCpuCountRangeRequest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-vcpucountrangerequest.html", + "Properties": { + "Max": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-vcpucountrangerequest.html#cfn-ec2-spotfleet-vcpucountrangerequest-max", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, + "Min": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-spotfleet-vcpucountrangerequest.html#cfn-ec2-spotfleet-vcpucountrangerequest-min", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, "AWS::EC2::TrafficMirrorFilterRule.TrafficMirrorPortRange": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-trafficmirrorfilterrule-trafficmirrorportrange.html", "Properties": { @@ -23419,6 +24629,23 @@ } } }, + "AWS::ECS::TaskDefinition.RuntimePlatform": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-runtimeplatform.html", + "Properties": { + "CpuArchitecture": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-runtimeplatform.html#cfn-ecs-taskdefinition-runtimeplatform-cpuarchitecture", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "OperatingSystemFamily": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-runtimeplatform.html#cfn-ecs-taskdefinition-runtimeplatform-operatingsystemfamily", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + } + } + }, "AWS::ECS::TaskDefinition.Secret": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-secret.html", "Properties": { @@ -32696,6 +33923,12 @@ "Required": false, "UpdateType": "Immutable" }, + "Throughput": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-containerrecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-containerrecipe-ebsinstanceblockdevicespecification-throughput", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, "VolumeSize": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-containerrecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-containerrecipe-ebsinstanceblockdevicespecification-volumesize", "PrimitiveType": "Integer", @@ -32971,6 +34204,12 @@ "Required": false, "UpdateType": "Immutable" }, + "Throughput": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification-throughput", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + }, "VolumeSize": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification.html#cfn-imagebuilder-imagerecipe-ebsinstanceblockdevicespecification-volumesize", "PrimitiveType": "Integer", @@ -33025,6 +34264,23 @@ } } }, + "AWS::ImageBuilder::InfrastructureConfiguration.InstanceMetadataOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-infrastructureconfiguration-instancemetadataoptions.html", + "Properties": { + "HttpPutResponseHopLimit": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-infrastructureconfiguration-instancemetadataoptions.html#cfn-imagebuilder-infrastructureconfiguration-instancemetadataoptions-httpputresponsehoplimit", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "HttpTokens": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-infrastructureconfiguration-instancemetadataoptions.html#cfn-imagebuilder-infrastructureconfiguration-instancemetadataoptions-httptokens", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::ImageBuilder::InfrastructureConfiguration.Logging": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-imagebuilder-infrastructureconfiguration-logging.html", "Properties": { @@ -41896,6 +43152,59 @@ } } }, + "AWS::Lightsail::Database.RelationalDatabaseParameter": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html", + "Properties": { + "AllowedValues": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-allowedvalues", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ApplyMethod": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-applymethod", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ApplyType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-applytype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "DataType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-datatype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "IsModifiable": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-ismodifiable", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "ParameterName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-parametername", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ParameterValue": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-database-relationaldatabaseparameter.html#cfn-lightsail-database-relationaldatabaseparameter-parametervalue", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::Lightsail::Disk.AddOn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-disk-addon.html", "Properties": { @@ -42070,6 +43379,7 @@ "MonthlyTransfer": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lightsail-instance-networking.html#cfn-lightsail-instance-networking-monthlytransfer", "Required": false, + "Type": "MonthlyTransfer", "UpdateType": "Mutable" }, "Ports": { @@ -43106,9 +44416,6 @@ } } }, - "AWS::MWAA::Environment.TagMap": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-mwaa-environment-tagmap.html" - }, "AWS::Macie::FindingsFilter.Criterion": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-macie-findingsfilter-criterion.html" }, @@ -50954,6 +52261,28 @@ } } }, + "AWS::Panorama::ApplicationInstance.ManifestOverridesPayload": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-panorama-applicationinstance-manifestoverridespayload.html", + "Properties": { + "PayloadData": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-panorama-applicationinstance-manifestoverridespayload.html#cfn-panorama-applicationinstance-manifestoverridespayload-payloaddata", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::Panorama::ApplicationInstance.ManifestPayload": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-panorama-applicationinstance-manifestpayload.html", + "Properties": { + "PayloadData": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-panorama-applicationinstance-manifestpayload.html#cfn-panorama-applicationinstance-manifestpayload-payloaddata", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + } + } + }, "AWS::Pinpoint::ApplicationSettings.CampaignHook": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-applicationsettings-campaignhook.html", "Properties": { @@ -51110,6 +52439,30 @@ } } }, + "AWS::Pinpoint::Campaign.CampaignInAppMessage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-campaigninappmessage.html", + "Properties": { + "Content": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-campaigninappmessage.html#cfn-pinpoint-campaign-campaigninappmessage-content", + "ItemType": "InAppMessageContent", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "CustomConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-campaigninappmessage.html#cfn-pinpoint-campaign-campaigninappmessage-customconfig", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Mutable" + }, + "Layout": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-campaigninappmessage.html#cfn-pinpoint-campaign-campaigninappmessage-layout", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::Pinpoint::Campaign.CampaignSmsMessage": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-campaignsmsmessage.html", "Properties": { @@ -51151,6 +52504,47 @@ } } }, + "AWS::Pinpoint::Campaign.DefaultButtonConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-defaultbuttonconfiguration.html", + "Properties": { + "BackgroundColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-defaultbuttonconfiguration.html#cfn-pinpoint-campaign-defaultbuttonconfiguration-backgroundcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "BorderRadius": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-defaultbuttonconfiguration.html#cfn-pinpoint-campaign-defaultbuttonconfiguration-borderradius", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "ButtonAction": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-defaultbuttonconfiguration.html#cfn-pinpoint-campaign-defaultbuttonconfiguration-buttonaction", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Link": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-defaultbuttonconfiguration.html#cfn-pinpoint-campaign-defaultbuttonconfiguration-link", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Text": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-defaultbuttonconfiguration.html#cfn-pinpoint-campaign-defaultbuttonconfiguration-text", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "TextColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-defaultbuttonconfiguration.html#cfn-pinpoint-campaign-defaultbuttonconfiguration-textcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::Pinpoint::Campaign.EventDimensions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-eventdimensions.html", "Properties": { @@ -51174,6 +52568,122 @@ } } }, + "AWS::Pinpoint::Campaign.InAppMessageBodyConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebodyconfig.html", + "Properties": { + "Alignment": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebodyconfig.html#cfn-pinpoint-campaign-inappmessagebodyconfig-alignment", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Body": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebodyconfig.html#cfn-pinpoint-campaign-inappmessagebodyconfig-body", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "TextColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebodyconfig.html#cfn-pinpoint-campaign-inappmessagebodyconfig-textcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Pinpoint::Campaign.InAppMessageButton": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebutton.html", + "Properties": { + "Android": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebutton.html#cfn-pinpoint-campaign-inappmessagebutton-android", + "Required": false, + "Type": "OverrideButtonConfiguration", + "UpdateType": "Mutable" + }, + "DefaultConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebutton.html#cfn-pinpoint-campaign-inappmessagebutton-defaultconfig", + "Required": false, + "Type": "DefaultButtonConfiguration", + "UpdateType": "Mutable" + }, + "IOS": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebutton.html#cfn-pinpoint-campaign-inappmessagebutton-ios", + "Required": false, + "Type": "OverrideButtonConfiguration", + "UpdateType": "Mutable" + }, + "Web": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagebutton.html#cfn-pinpoint-campaign-inappmessagebutton-web", + "Required": false, + "Type": "OverrideButtonConfiguration", + "UpdateType": "Mutable" + } + } + }, + "AWS::Pinpoint::Campaign.InAppMessageContent": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagecontent.html", + "Properties": { + "BackgroundColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagecontent.html#cfn-pinpoint-campaign-inappmessagecontent-backgroundcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "BodyConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagecontent.html#cfn-pinpoint-campaign-inappmessagecontent-bodyconfig", + "Required": false, + "Type": "InAppMessageBodyConfig", + "UpdateType": "Mutable" + }, + "HeaderConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagecontent.html#cfn-pinpoint-campaign-inappmessagecontent-headerconfig", + "Required": false, + "Type": "InAppMessageHeaderConfig", + "UpdateType": "Mutable" + }, + "ImageUrl": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagecontent.html#cfn-pinpoint-campaign-inappmessagecontent-imageurl", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "PrimaryBtn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagecontent.html#cfn-pinpoint-campaign-inappmessagecontent-primarybtn", + "Required": false, + "Type": "InAppMessageButton", + "UpdateType": "Mutable" + }, + "SecondaryBtn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessagecontent.html#cfn-pinpoint-campaign-inappmessagecontent-secondarybtn", + "Required": false, + "Type": "InAppMessageButton", + "UpdateType": "Mutable" + } + } + }, + "AWS::Pinpoint::Campaign.InAppMessageHeaderConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessageheaderconfig.html", + "Properties": { + "Alignment": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessageheaderconfig.html#cfn-pinpoint-campaign-inappmessageheaderconfig-alignment", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Header": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessageheaderconfig.html#cfn-pinpoint-campaign-inappmessageheaderconfig-header", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "TextColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-inappmessageheaderconfig.html#cfn-pinpoint-campaign-inappmessageheaderconfig-textcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::Pinpoint::Campaign.Limits": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-limits.html", "Properties": { @@ -51195,6 +52705,12 @@ "Required": false, "UpdateType": "Mutable" }, + "Session": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-limits.html#cfn-pinpoint-campaign-limits-session", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, "Total": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-limits.html#cfn-pinpoint-campaign-limits-total", "PrimitiveType": "Integer", @@ -51319,6 +52835,12 @@ "Type": "Message", "UpdateType": "Mutable" }, + "InAppMessage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-messageconfiguration.html#cfn-pinpoint-campaign-messageconfiguration-inappmessage", + "Required": false, + "Type": "CampaignInAppMessage", + "UpdateType": "Mutable" + }, "SMSMessage": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-messageconfiguration.html#cfn-pinpoint-campaign-messageconfiguration-smsmessage", "Required": false, @@ -51344,6 +52866,23 @@ } } }, + "AWS::Pinpoint::Campaign.OverrideButtonConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-overridebuttonconfiguration.html", + "Properties": { + "ButtonAction": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-overridebuttonconfiguration.html#cfn-pinpoint-campaign-overridebuttonconfiguration-buttonaction", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Link": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-overridebuttonconfiguration.html#cfn-pinpoint-campaign-overridebuttonconfiguration-link", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::Pinpoint::Campaign.QuietTime": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-campaign-schedule-quiettime.html", "Properties": { @@ -53139,6 +54678,17 @@ } } }, + "AWS::QuickSight::DataSource.AmazonOpenSearchParameters": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-amazonopensearchparameters.html", + "Properties": { + "Domain": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-amazonopensearchparameters.html#cfn-quicksight-datasource-amazonopensearchparameters-domain", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, "AWS::QuickSight::DataSource.AthenaParameters": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-athenaparameters.html", "Properties": { @@ -53263,6 +54813,12 @@ "Type": "AmazonElasticsearchParameters", "UpdateType": "Mutable" }, + "AmazonOpenSearchParameters": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-datasourceparameters.html#cfn-quicksight-datasource-datasourceparameters-amazonopensearchparameters", + "Required": false, + "Type": "AmazonOpenSearchParameters", + "UpdateType": "Mutable" + }, "AthenaParameters": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-datasource-datasourceparameters.html#cfn-quicksight-datasource-datasourceparameters-athenaparameters", "Required": false, @@ -60918,6 +62474,17 @@ } } }, + "AWS::Synthetics::Canary.ArtifactConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-artifactconfig.html", + "Properties": { + "S3Encryption": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-artifactconfig.html#cfn-synthetics-canary-artifactconfig-s3encryption", + "Required": false, + "Type": "S3Encryption", + "UpdateType": "Mutable" + } + } + }, "AWS::Synthetics::Canary.BaseScreenshot": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-basescreenshot.html", "Properties": { @@ -61001,6 +62568,23 @@ } } }, + "AWS::Synthetics::Canary.S3Encryption": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-s3encryption.html", + "Properties": { + "EncryptionMode": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-s3encryption.html#cfn-synthetics-canary-s3encryption-encryptionmode", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "KmsKeyArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-s3encryption.html#cfn-synthetics-canary-s3encryption-kmskeyarn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::Synthetics::Canary.Schedule": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-synthetics-canary-schedule.html", "Properties": { @@ -63150,6 +64734,79 @@ } } }, + "AWS::Wisdom::Assistant.ServerSideEncryptionConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-assistant-serversideencryptionconfiguration.html", + "Properties": { + "KmsKeyId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-assistant-serversideencryptionconfiguration.html#cfn-wisdom-assistant-serversideencryptionconfiguration-kmskeyid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::Wisdom::AssistantAssociation.AssociationData": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-assistantassociation-associationdata.html", + "Properties": { + "KnowledgeBaseId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-assistantassociation-associationdata.html#cfn-wisdom-assistantassociation-associationdata-knowledgebaseid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, + "AWS::Wisdom::KnowledgeBase.AppIntegrationsConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-appintegrationsconfiguration.html", + "Properties": { + "AppIntegrationArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-appintegrationsconfiguration.html#cfn-wisdom-knowledgebase-appintegrationsconfiguration-appintegrationarn", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "ObjectFields": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-appintegrationsconfiguration.html#cfn-wisdom-knowledgebase-appintegrationsconfiguration-objectfields", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Immutable" + } + } + }, + "AWS::Wisdom::KnowledgeBase.RenderingConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-renderingconfiguration.html", + "Properties": { + "TemplateUri": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-renderingconfiguration.html#cfn-wisdom-knowledgebase-renderingconfiguration-templateuri", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Wisdom::KnowledgeBase.ServerSideEncryptionConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-serversideencryptionconfiguration.html", + "Properties": { + "KmsKeyId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-serversideencryptionconfiguration.html#cfn-wisdom-knowledgebase-serversideencryptionconfiguration-kmskeyid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::Wisdom::KnowledgeBase.SourceConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-sourceconfiguration.html", + "Properties": { + "AppIntegrations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-wisdom-knowledgebase-sourceconfiguration.html#cfn-wisdom-knowledgebase-sourceconfiguration-appintegrations", + "Required": false, + "Type": "AppIntegrationsConfiguration", + "UpdateType": "Immutable" + } + } + }, "AWS::WorkSpaces::ConnectionAlias.ConnectionAliasAssociation": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-workspaces-connectionalias-connectionaliasassociation.html", "Properties": { @@ -63503,7 +65160,7 @@ } } }, - "ResourceSpecificationVersion": "43.0.0", + "ResourceSpecificationVersion": "46.0.0", "ResourceTypes": { "AWS::ACMPCA::Certificate": { "Attributes": { @@ -64373,6 +66030,11 @@ } }, "AWS::ApiGateway::Authorizer": { + "Attributes": { + "AuthorizerId": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-authorizer.html", "Properties": { "AuthType": { @@ -64414,7 +66076,7 @@ "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-authorizer.html#cfn-apigateway-authorizer-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "ProviderARNs": { @@ -65165,6 +66827,13 @@ "Required": true, "UpdateType": "Mutable" }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-vpclink.html#cfn-apigateway-vpclink-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "TargetArns": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-vpclink.html#cfn-apigateway-vpclink-targetarns", "PrimitiveItemType": "String", @@ -68042,6 +69711,12 @@ "Required": false, "UpdateType": "Mutable" }, + "DesiredCapacityType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-group.html#cfn-as-group-desiredcapacitytype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "HealthCheckGracePeriod": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-group.html#cfn-as-group-healthcheckgraceperiod", "PrimitiveType": "Integer", @@ -68306,52 +69981,52 @@ } }, "AWS::AutoScaling::LifecycleHook": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html", "Properties": { "AutoScalingGroupName": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-autoscalinggroupname", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-autoscalinggroupname", "PrimitiveType": "String", "Required": true, "UpdateType": "Immutable" }, "DefaultResult": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-defaultresult", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-defaultresult", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" }, "HeartbeatTimeout": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-heartbeattimeout", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-heartbeattimeout", "PrimitiveType": "Integer", "Required": false, "UpdateType": "Mutable" }, "LifecycleHookName": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-autoscaling-lifecyclehook-lifecyclehookname", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-lifecyclehookname", "PrimitiveType": "String", "Required": false, "UpdateType": "Immutable" }, "LifecycleTransition": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-lifecycletransition", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-lifecycletransition", "PrimitiveType": "String", "Required": true, "UpdateType": "Mutable" }, "NotificationMetadata": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-notificationmetadata", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-notificationmetadata", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" }, "NotificationTargetARN": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-notificationtargetarn", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-notificationtargetarn", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" }, "RoleARN": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html#cfn-as-lifecyclehook-rolearn", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html#cfn-autoscaling-lifecyclehook-rolearn", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" @@ -68771,6 +70446,12 @@ "PrimitiveType": "String", "Required": true, "UpdateType": "Immutable" + }, + "UnmanagedvCpus": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-batch-computeenvironment.html#cfn-batch-computeenvironment-unmanagedvcpus", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" } } }, @@ -68820,6 +70501,12 @@ "Type": "RetryStrategy", "UpdateType": "Mutable" }, + "SchedulingPriority": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-batch-jobdefinition.html#cfn-batch-jobdefinition-schedulingpriority", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-batch-jobdefinition.html#cfn-batch-jobdefinition-tags", "PrimitiveType": "Json", @@ -68862,6 +70549,12 @@ "Required": true, "UpdateType": "Mutable" }, + "SchedulingPolicyArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-batch-jobqueue.html#cfn-batch-jobqueue-schedulingpolicyarn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "State": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-batch-jobqueue.html#cfn-batch-jobqueue-state", "PrimitiveType": "String", @@ -68947,7 +70640,7 @@ "Subscribers": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-budgets-budgetsaction.html#cfn-budgets-budgetsaction-subscribers", "ItemType": "Subscriber", - "Required": false, + "Required": true, "Type": "List", "UpdateType": "Mutable" } @@ -69202,6 +70895,12 @@ "Type": "List", "UpdateType": "Immutable" }, + "DefaultTimeToLive": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cassandra-table.html#cfn-cassandra-table-defaulttimetolive", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, "EncryptionSpecification": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cassandra-table.html#cfn-cassandra-table-encryptionspecification", "Required": false, @@ -71591,12 +73290,24 @@ }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html", "Properties": { + "CreatedBy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html#cfn-codestarnotifications-notificationrule-createdby", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "DetailType": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html#cfn-codestarnotifications-notificationrule-detailtype", "PrimitiveType": "String", "Required": true, "UpdateType": "Mutable" }, + "EventTypeId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html#cfn-codestarnotifications-notificationrule-eventtypeid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "EventTypeIds": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html#cfn-codestarnotifications-notificationrule-eventtypeids", "DuplicatesAllowed": true, @@ -71629,6 +73340,12 @@ "Required": false, "UpdateType": "Immutable" }, + "TargetAddress": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html#cfn-codestarnotifications-notificationrule-targetaddress", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "Targets": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codestarnotifications-notificationrule.html#cfn-codestarnotifications-notificationrule-targets", "DuplicatesAllowed": true, @@ -72711,6 +74428,56 @@ } } }, + "AWS::Connect::HoursOfOperation": { + "Attributes": { + "HoursOfOperationArn": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-hoursofoperation.html", + "Properties": { + "Config": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-hoursofoperation.html#cfn-connect-hoursofoperation-config", + "DuplicatesAllowed": false, + "ItemType": "HoursOfOperationConfig", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-hoursofoperation.html#cfn-connect-hoursofoperation-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "InstanceArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-hoursofoperation.html#cfn-connect-hoursofoperation-instancearn", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-hoursofoperation.html#cfn-connect-hoursofoperation-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-hoursofoperation.html#cfn-connect-hoursofoperation-tags", + "DuplicatesAllowed": false, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "TimeZone": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-hoursofoperation.html#cfn-connect-hoursofoperation-timezone", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, "AWS::Connect::QuickConnect": { "Attributes": { "QuickConnectArn": { @@ -72753,6 +74520,108 @@ } } }, + "AWS::Connect::User": { + "Attributes": { + "UserArn": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html", + "Properties": { + "DirectoryUserId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-directoryuserid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "HierarchyGroupArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-hierarchygrouparn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "IdentityInfo": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-identityinfo", + "Required": false, + "Type": "UserIdentityInfo", + "UpdateType": "Mutable" + }, + "InstanceArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-instancearn", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Password": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-password", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "PhoneConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-phoneconfig", + "Required": true, + "Type": "UserPhoneConfig", + "UpdateType": "Mutable" + }, + "RoutingProfileArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-routingprofilearn", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "SecurityProfileArns": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-securityprofilearns", + "DuplicatesAllowed": false, + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-tags", + "DuplicatesAllowed": false, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "Username": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-user.html#cfn-connect-user-username", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::Connect::UserHierarchyGroup": { + "Attributes": { + "UserHierarchyGroupArn": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-userhierarchygroup.html", + "Properties": { + "InstanceArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-userhierarchygroup.html#cfn-connect-userhierarchygroup-instancearn", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-userhierarchygroup.html#cfn-connect-userhierarchygroup-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "ParentGroupArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-connect-userhierarchygroup.html#cfn-connect-userhierarchygroup-parentgrouparn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + } + } + }, "AWS::CustomerProfiles::Domain": { "Attributes": { "CreatedAt": { @@ -75121,6 +76990,74 @@ } } }, + "AWS::EC2::CapacityReservationFleet": { + "Attributes": { + "CapacityReservationFleetId": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html", + "Properties": { + "AllocationStrategy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-allocationstrategy", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "EndDate": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-enddate", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "InstanceMatchCriteria": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-instancematchcriteria", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "InstanceTypeSpecifications": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-instancetypespecifications", + "DuplicatesAllowed": false, + "ItemType": "InstanceTypeSpecification", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "NoRemoveEndDate": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-noremoveenddate", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "RemoveEndDate": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-removeenddate", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "TagSpecifications": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-tagspecifications", + "DuplicatesAllowed": true, + "ItemType": "TagSpecification", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "Tenancy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-tenancy", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "TotalTargetCapacity": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-capacityreservationfleet.html#cfn-ec2-capacityreservationfleet-totaltargetcapacity", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::EC2::CarrierGateway": { "Attributes": { "CarrierGatewayId": { @@ -76150,10 +78087,15 @@ } }, "AWS::EC2::NetworkAcl": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html", + "Attributes": { + "Id": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkacl.html", "Properties": { "Tags": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html#cfn-ec2-networkacl-tags", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkacl.html#cfn-ec2-networkacl-tags", "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, @@ -76161,7 +78103,7 @@ "UpdateType": "Mutable" }, "VpcId": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl.html#cfn-ec2-networkacl-vpcid", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkacl.html#cfn-ec2-networkacl-vpcid", "PrimitiveType": "String", "Required": true, "UpdateType": "Immutable" @@ -76169,58 +78111,63 @@ } }, "AWS::EC2::NetworkAclEntry": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html", + "Attributes": { + "Id": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html", "Properties": { "CidrBlock": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-cidrblock", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-cidrblock", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" }, "Egress": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-egress", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-egress", "PrimitiveType": "Boolean", "Required": false, "UpdateType": "Immutable" }, "Icmp": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-icmp", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-icmp", "Required": false, "Type": "Icmp", "UpdateType": "Mutable" }, "Ipv6CidrBlock": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-ipv6cidrblock", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-ipv6cidrblock", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" }, "NetworkAclId": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-networkaclid", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-networkaclid", "PrimitiveType": "String", "Required": true, "UpdateType": "Immutable" }, "PortRange": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-portrange", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-portrange", "Required": false, "Type": "PortRange", "UpdateType": "Mutable" }, "Protocol": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-protocol", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-protocol", "PrimitiveType": "Integer", "Required": true, "UpdateType": "Mutable" }, "RuleAction": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-ruleaction", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-ruleaction", "PrimitiveType": "String", "Required": true, "UpdateType": "Mutable" }, "RuleNumber": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-acl-entry.html#cfn-ec2-networkaclentry-rulenumber", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkaclentry.html#cfn-ec2-networkaclentry-rulenumber", "PrimitiveType": "Integer", "Required": true, "UpdateType": "Immutable" @@ -76633,10 +78580,15 @@ } }, "AWS::EC2::RouteTable": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html", + "Attributes": { + "RouteTableId": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-routetable.html", "Properties": { "Tags": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html#cfn-ec2-routetable-tags", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-routetable.html#cfn-ec2-routetable-tags", "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, @@ -76644,7 +78596,7 @@ "UpdateType": "Mutable" }, "VpcId": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route-table.html#cfn-ec2-routetable-vpcid", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-routetable.html#cfn-ec2-routetable-vpcid", "PrimitiveType": "String", "Required": true, "UpdateType": "Immutable" @@ -78693,6 +80645,12 @@ "Type": "List", "UpdateType": "Immutable" }, + "RuntimePlatform": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html#cfn-ecs-taskdefinition-runtimeplatform", + "Required": false, + "Type": "RuntimePlatform", + "UpdateType": "Immutable" + }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html#cfn-ecs-taskdefinition-tags", "ItemType": "Tag", @@ -81713,6 +83671,12 @@ "Type": "List", "UpdateType": "Mutable" }, + "ResourcesCleanUp": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-fms-policy.html#cfn-fms-policy-resourcescleanup", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, "SecurityServicePolicyData": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-fms-policy.html#cfn-fms-policy-securityservicepolicydata", "PrimitiveType": "Json", @@ -83325,7 +85289,7 @@ "ItemType": "Tag", "Required": false, "Type": "List", - "UpdateType": "Immutable" + "UpdateType": "Mutable" } } }, @@ -83387,7 +85351,7 @@ "ItemType": "Tag", "Required": false, "Type": "List", - "UpdateType": "Immutable" + "UpdateType": "Mutable" } } }, @@ -85586,6 +87550,12 @@ "Required": false, "UpdateType": "Mutable" }, + "InstanceMetadataOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-instancemetadataoptions", + "Required": false, + "Type": "InstanceMetadataOptions", + "UpdateType": "Mutable" + }, "InstanceProfileName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-imagebuilder-infrastructureconfiguration.html#cfn-imagebuilder-infrastructureconfiguration-instanceprofilename", "PrimitiveType": "String", @@ -86183,6 +88153,78 @@ } } }, + "AWS::IoT::JobTemplate": { + "Attributes": { + "Arn": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html", + "Properties": { + "AbortConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-abortconfig", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Immutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-description", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Document": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-document", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "DocumentSource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-documentsource", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "JobArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-jobarn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "JobExecutionsRolloutConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-jobexecutionsrolloutconfig", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Immutable" + }, + "JobTemplateId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-jobtemplateid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "PresignedUrlConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-presignedurlconfig", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-tags", + "DuplicatesAllowed": false, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "TimeoutConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-jobtemplate.html#cfn-iot-jobtemplate-timeoutconfig", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Immutable" + } + } + }, "AWS::IoT::MitigationAction": { "Attributes": { "MitigationActionArn": { @@ -88957,6 +90999,110 @@ } } }, + "AWS::Lightsail::Database": { + "Attributes": { + "DatabaseArn": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html", + "Properties": { + "AvailabilityZone": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-availabilityzone", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "BackupRetention": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-backupretention", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "CaCertificateIdentifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-cacertificateidentifier", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "MasterDatabaseName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-masterdatabasename", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "MasterUserPassword": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-masteruserpassword", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "MasterUsername": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-masterusername", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "PreferredBackupWindow": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-preferredbackupwindow", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "PreferredMaintenanceWindow": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-preferredmaintenancewindow", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "PubliclyAccessible": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-publiclyaccessible", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "RelationalDatabaseBlueprintId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-relationaldatabaseblueprintid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "RelationalDatabaseBundleId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-relationaldatabasebundleid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "RelationalDatabaseName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-relationaldatabasename", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "RelationalDatabaseParameters": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-relationaldatabaseparameters", + "DuplicatesAllowed": false, + "ItemType": "RelationalDatabaseParameter", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "RotateMasterUserPassword": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-rotatemasteruserpassword", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-database.html#cfn-lightsail-database-tags", + "DuplicatesAllowed": false, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "AWS::Lightsail::Disk": { "Attributes": { "AttachedTo": { @@ -89038,9 +91184,6 @@ "IsStaticIp": { "PrimitiveType": "Boolean" }, - "KeyPairName": { - "PrimitiveType": "String" - }, "Location.AvailabilityZone": { "PrimitiveType": "String" }, @@ -89071,9 +91214,6 @@ "SupportCode": { "PrimitiveType": "String" }, - "UserData": { - "PrimitiveType": "String" - }, "UserName": { "PrimitiveType": "String" } @@ -89117,6 +91257,12 @@ "Required": true, "UpdateType": "Immutable" }, + "KeyPairName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-instance.html#cfn-lightsail-instance-keypairname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "Location": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-instance.html#cfn-lightsail-instance-location", "Required": false, @@ -89142,6 +91288,40 @@ "Required": false, "Type": "List", "UpdateType": "Mutable" + }, + "UserData": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-instance.html#cfn-lightsail-instance-userdata", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Lightsail::StaticIp": { + "Attributes": { + "IpAddress": { + "PrimitiveType": "String" + }, + "IsAttached": { + "PrimitiveType": "Boolean" + }, + "StaticIpArn": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-staticip.html", + "Properties": { + "AttachedTo": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-staticip.html#cfn-lightsail-staticip-attachedto", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "StaticIpName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lightsail-staticip.html#cfn-lightsail-staticip-staticipname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" } } }, @@ -89361,6 +91541,12 @@ "Required": false, "UpdateType": "Immutable" }, + "PositionFiltering": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-location-tracker.html#cfn-location-tracker-positionfiltering", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, "PricingPlan": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-location-tracker.html#cfn-location-tracker-pricingplan", "PrimitiveType": "String", @@ -89941,8 +92127,8 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-mwaa-environment.html#cfn-mwaa-environment-tags", + "PrimitiveType": "Json", "Required": false, - "Type": "TagMap", "UpdateType": "Mutable" }, "WebserverAccessMode": { @@ -91230,7 +93416,7 @@ "ACLName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-memorydb-cluster.html#cfn-memorydb-cluster-aclname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "AutoMinorVersionUpgrade": { @@ -91284,7 +93470,7 @@ "NodeType": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-memorydb-cluster.html#cfn-memorydb-cluster-nodetype", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "NumReplicasPerShard": { @@ -91396,7 +93582,7 @@ "Family": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-memorydb-parametergroup.html#cfn-memorydb-parametergroup-family", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Immutable" }, "ParameterGroupName": { @@ -91445,7 +93631,7 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-memorydb-subnetgroup.html#cfn-memorydb-subnetgroup-subnetids", "DuplicatesAllowed": false, "PrimitiveItemType": "String", - "Required": false, + "Required": true, "Type": "List", "UpdateType": "Mutable" }, @@ -93403,6 +95589,190 @@ } } }, + "AWS::Panorama::ApplicationInstance": { + "Attributes": { + "ApplicationInstanceId": { + "PrimitiveType": "String" + }, + "Arn": { + "PrimitiveType": "String" + }, + "CreatedTime": { + "PrimitiveType": "Integer" + }, + "DefaultRuntimeContextDeviceName": { + "PrimitiveType": "String" + }, + "HealthStatus": { + "PrimitiveType": "String" + }, + "LastUpdatedTime": { + "PrimitiveType": "Integer" + }, + "Status": { + "PrimitiveType": "String" + }, + "StatusDescription": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html", + "Properties": { + "ApplicationInstanceIdToReplace": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-applicationinstanceidtoreplace", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "DefaultRuntimeContextDevice": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-defaultruntimecontextdevice", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "DeviceId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-deviceid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ManifestOverridesPayload": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-manifestoverridespayload", + "Required": false, + "Type": "ManifestOverridesPayload", + "UpdateType": "Immutable" + }, + "ManifestPayload": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-manifestpayload", + "Required": true, + "Type": "ManifestPayload", + "UpdateType": "Immutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-name", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "RuntimeRoleArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-runtimerolearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "StatusFilter": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-statusfilter", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-applicationinstance.html#cfn-panorama-applicationinstance-tags", + "DuplicatesAllowed": false, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::Panorama::Package": { + "Attributes": { + "Arn": { + "PrimitiveType": "String" + }, + "CreatedTime": { + "PrimitiveType": "Integer" + }, + "PackageId": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-package.html", + "Properties": { + "PackageName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-package.html#cfn-panorama-package-packagename", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-package.html#cfn-panorama-package-tags", + "DuplicatesAllowed": false, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::Panorama::PackageVersion": { + "Attributes": { + "IsLatestPatch": { + "PrimitiveType": "Boolean" + }, + "PackageArn": { + "PrimitiveType": "String" + }, + "PackageName": { + "PrimitiveType": "String" + }, + "RegisteredTime": { + "PrimitiveType": "Integer" + }, + "Status": { + "PrimitiveType": "String" + }, + "StatusDescription": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-packageversion.html", + "Properties": { + "MarkLatest": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-packageversion.html#cfn-panorama-packageversion-marklatest", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "OwnerAccount": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-packageversion.html#cfn-panorama-packageversion-owneraccount", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "PackageId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-packageversion.html#cfn-panorama-packageversion-packageid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "PackageVersion": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-packageversion.html#cfn-panorama-packageversion-packageversion", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "PatchVersion": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-packageversion.html#cfn-panorama-packageversion-patchversion", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "UpdatedLatestPatchVersion": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-panorama-packageversion.html#cfn-panorama-packageversion-updatedlatestpatchversion", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::Pinpoint::ADMChannel": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-admchannel.html", "Properties": { @@ -93820,6 +96190,12 @@ "Required": true, "UpdateType": "Mutable" }, + "Priority": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-campaign.html#cfn-pinpoint-campaign-priority", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, "Schedule": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-campaign.html#cfn-pinpoint-campaign-schedule", "Required": true, @@ -94487,7 +96863,7 @@ }, "SourceEntity": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-quicksight-analysis.html#cfn-quicksight-analysis-sourceentity", - "Required": false, + "Required": true, "Type": "AnalysisSourceEntity", "UpdateType": "Mutable" }, @@ -94562,7 +96938,7 @@ }, "SourceEntity": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-quicksight-dashboard.html#cfn-quicksight-dashboard-sourceentity", - "Required": false, + "Required": true, "Type": "DashboardSourceEntity", "UpdateType": "Mutable" }, @@ -94824,7 +97200,7 @@ }, "SourceEntity": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-quicksight-template.html#cfn-quicksight-template-sourceentity", - "Required": false, + "Required": true, "Type": "TemplateSourceEntity", "UpdateType": "Mutable" }, @@ -96416,6 +98792,22 @@ } } }, + "AWS::Rekognition::Project": { + "Attributes": { + "Arn": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rekognition-project.html", + "Properties": { + "ProjectName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rekognition-project.html#cfn-rekognition-project-projectname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, "AWS::ResourceGroups::Group": { "Attributes": { "Arn": { @@ -96947,6 +99339,13 @@ "PrimitiveType": "String", "Required": false, "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-cluster.html#cfn-route53recoverycontrol-cluster-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" } } }, @@ -96978,6 +99377,13 @@ "PrimitiveType": "String", "Required": true, "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-controlpanel.html#cfn-route53recoverycontrol-controlpanel-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" } } }, @@ -97052,6 +99458,13 @@ "Required": true, "Type": "RuleConfig", "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-safetyrule.html#cfn-route53recoverycontrol-safetyrule-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" } } }, @@ -97374,6 +99787,34 @@ } } }, + "AWS::Route53Resolver::ResolverConfig": { + "Attributes": { + "AutodefinedReverse": { + "PrimitiveType": "String" + }, + "Id": { + "PrimitiveType": "String" + }, + "OwnerId": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53resolver-resolverconfig.html", + "Properties": { + "AutodefinedReverseFlag": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53resolver-resolverconfig.html#cfn-route53resolver-resolverconfig-autodefinedreverseflag", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "ResourceId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53resolver-resolverconfig.html#cfn-route53resolver-resolverconfig-resourceid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, "AWS::Route53Resolver::ResolverDNSSECConfig": { "Attributes": { "Id": { @@ -97549,7 +99990,9 @@ "PrimitiveType": "String" }, "TargetIps": { - "PrimitiveType": "String" + "DuplicatesAllowed": true, + "ItemType": "TargetAddress", + "Type": "List" } }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53resolver-resolverrule.html", @@ -97580,6 +100023,7 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53resolver-resolverrule.html#cfn-route53resolver-resolverrule-tags", + "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, "Type": "List", @@ -97587,6 +100031,7 @@ }, "TargetIps": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53resolver-resolverrule.html#cfn-route53resolver-resolverrule-targetips", + "DuplicatesAllowed": true, "ItemType": "TargetAddress", "Required": false, "Type": "List", @@ -100361,6 +102806,12 @@ "Required": false, "UpdateType": "Immutable" }, + "PlatformIdentifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-notebookinstance.html#cfn-sagemaker-notebookinstance-platformidentifier", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, "RoleArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-notebookinstance.html#cfn-sagemaker-notebookinstance-rolearn", "PrimitiveType": "String", @@ -101785,6 +104236,9 @@ }, "AWS::StepFunctions::Activity": { "Attributes": { + "Arn": { + "PrimitiveType": "String" + }, "Name": { "PrimitiveType": "String" } @@ -101799,6 +104253,7 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-stepfunctions-activity.html#cfn-stepfunctions-activity-tags", + "DuplicatesAllowed": true, "ItemType": "TagsEntry", "Required": false, "Type": "List", @@ -101893,6 +104348,12 @@ }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-synthetics-canary.html", "Properties": { + "ArtifactConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-synthetics-canary.html#cfn-synthetics-canary-artifactconfig", + "Required": false, + "Type": "ArtifactConfig", + "UpdateType": "Mutable" + }, "ArtifactS3Location": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-synthetics-canary.html#cfn-synthetics-canary-artifacts3location", "PrimitiveType": "String", @@ -102886,6 +105347,150 @@ } } }, + "AWS::Wisdom::Assistant": { + "Attributes": { + "AssistantArn": { + "PrimitiveType": "String" + }, + "AssistantId": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistant.html", + "Properties": { + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistant.html#cfn-wisdom-assistant-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistant.html#cfn-wisdom-assistant-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "ServerSideEncryptionConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistant.html#cfn-wisdom-assistant-serversideencryptionconfiguration", + "Required": false, + "Type": "ServerSideEncryptionConfiguration", + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistant.html#cfn-wisdom-assistant-tags", + "DuplicatesAllowed": false, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + }, + "Type": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistant.html#cfn-wisdom-assistant-type", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, + "AWS::Wisdom::AssistantAssociation": { + "Attributes": { + "AssistantArn": { + "PrimitiveType": "String" + }, + "AssistantAssociationArn": { + "PrimitiveType": "String" + }, + "AssistantAssociationId": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistantassociation.html", + "Properties": { + "AssistantId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistantassociation.html#cfn-wisdom-assistantassociation-assistantid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Association": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistantassociation.html#cfn-wisdom-assistantassociation-association", + "Required": true, + "Type": "AssociationData", + "UpdateType": "Immutable" + }, + "AssociationType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistantassociation.html#cfn-wisdom-assistantassociation-associationtype", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-assistantassociation.html#cfn-wisdom-assistantassociation-tags", + "DuplicatesAllowed": false, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + } + } + }, + "AWS::Wisdom::KnowledgeBase": { + "Attributes": { + "KnowledgeBaseArn": { + "PrimitiveType": "String" + }, + "KnowledgeBaseId": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html", + "Properties": { + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html#cfn-wisdom-knowledgebase-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "KnowledgeBaseType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html#cfn-wisdom-knowledgebase-knowledgebasetype", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html#cfn-wisdom-knowledgebase-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "RenderingConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html#cfn-wisdom-knowledgebase-renderingconfiguration", + "Required": false, + "Type": "RenderingConfiguration", + "UpdateType": "Mutable" + }, + "ServerSideEncryptionConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html#cfn-wisdom-knowledgebase-serversideencryptionconfiguration", + "Required": false, + "Type": "ServerSideEncryptionConfiguration", + "UpdateType": "Immutable" + }, + "SourceConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html#cfn-wisdom-knowledgebase-sourceconfiguration", + "Required": false, + "Type": "SourceConfiguration", + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-wisdom-knowledgebase.html#cfn-wisdom-knowledgebase-tags", + "DuplicatesAllowed": false, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Immutable" + } + } + }, "AWS::WorkSpaces::ConnectionAlias": { "Attributes": { "AliasId": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/cfn-lint/StatefulResources/000.json b/packages/@aws-cdk/cfnspec/spec-source/cfn-lint/StatefulResources/000.json index 7037f14238497..dbfa3dfcdd033 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/cfn-lint/StatefulResources/000.json +++ b/packages/@aws-cdk/cfnspec/spec-source/cfn-lint/StatefulResources/000.json @@ -25,6 +25,7 @@ "AWS::SQS::Queue" : {}, "AWS::S3::Bucket" : { "DeleteRequiresEmptyResource": true - } + }, + "AWS::SecretsManager::Secret" : {} } } diff --git a/packages/@aws-cdk/cloudformation-include/package.json b/packages/@aws-cdk/cloudformation-include/package.json index 28e63ecaed94c..c78117ba94df0 100644 --- a/packages/@aws-cdk/cloudformation-include/package.json +++ b/packages/@aws-cdk/cloudformation-include/package.json @@ -195,6 +195,7 @@ "@aws-cdk/aws-opensearchservice": "0.0.0", "@aws-cdk/aws-opsworks": "0.0.0", "@aws-cdk/aws-opsworkscm": "0.0.0", + "@aws-cdk/aws-panorama": "0.0.0", "@aws-cdk/aws-pinpoint": "0.0.0", "@aws-cdk/aws-pinpointemail": "0.0.0", "@aws-cdk/aws-qldb": "0.0.0", @@ -202,6 +203,7 @@ "@aws-cdk/aws-ram": "0.0.0", "@aws-cdk/aws-rds": "0.0.0", "@aws-cdk/aws-redshift": "0.0.0", + "@aws-cdk/aws-rekognition": "0.0.0", "@aws-cdk/aws-resourcegroups": "0.0.0", "@aws-cdk/aws-robomaker": "0.0.0", "@aws-cdk/aws-route53": "0.0.0", @@ -234,6 +236,7 @@ "@aws-cdk/aws-waf": "0.0.0", "@aws-cdk/aws-wafregional": "0.0.0", "@aws-cdk/aws-wafv2": "0.0.0", + "@aws-cdk/aws-wisdom": "0.0.0", "@aws-cdk/aws-workspaces": "0.0.0", "@aws-cdk/aws-xray": "0.0.0", "@aws-cdk/core": "0.0.0", @@ -370,6 +373,7 @@ "@aws-cdk/aws-opensearchservice": "0.0.0", "@aws-cdk/aws-opsworks": "0.0.0", "@aws-cdk/aws-opsworkscm": "0.0.0", + "@aws-cdk/aws-panorama": "0.0.0", "@aws-cdk/aws-pinpoint": "0.0.0", "@aws-cdk/aws-pinpointemail": "0.0.0", "@aws-cdk/aws-qldb": "0.0.0", @@ -377,6 +381,7 @@ "@aws-cdk/aws-ram": "0.0.0", "@aws-cdk/aws-rds": "0.0.0", "@aws-cdk/aws-redshift": "0.0.0", + "@aws-cdk/aws-rekognition": "0.0.0", "@aws-cdk/aws-resourcegroups": "0.0.0", "@aws-cdk/aws-robomaker": "0.0.0", "@aws-cdk/aws-route53": "0.0.0", @@ -409,6 +414,7 @@ "@aws-cdk/aws-waf": "0.0.0", "@aws-cdk/aws-wafregional": "0.0.0", "@aws-cdk/aws-wafv2": "0.0.0", + "@aws-cdk/aws-wisdom": "0.0.0", "@aws-cdk/aws-workspaces": "0.0.0", "@aws-cdk/aws-xray": "0.0.0", "@aws-cdk/core": "0.0.0", diff --git a/packages/aws-cdk-lib/package.json b/packages/aws-cdk-lib/package.json index 1d2d0c73daa50..3e8a5932ffcc1 100644 --- a/packages/aws-cdk-lib/package.json +++ b/packages/aws-cdk-lib/package.json @@ -280,6 +280,7 @@ "@aws-cdk/aws-opensearchservice": "0.0.0", "@aws-cdk/aws-opsworks": "0.0.0", "@aws-cdk/aws-opsworkscm": "0.0.0", + "@aws-cdk/aws-panorama": "0.0.0", "@aws-cdk/aws-pinpoint": "0.0.0", "@aws-cdk/aws-pinpointemail": "0.0.0", "@aws-cdk/aws-qldb": "0.0.0", @@ -287,6 +288,7 @@ "@aws-cdk/aws-ram": "0.0.0", "@aws-cdk/aws-rds": "0.0.0", "@aws-cdk/aws-redshift": "0.0.0", + "@aws-cdk/aws-rekognition": "0.0.0", "@aws-cdk/aws-resourcegroups": "0.0.0", "@aws-cdk/aws-robomaker": "0.0.0", "@aws-cdk/aws-route53": "0.0.0", @@ -327,6 +329,7 @@ "@aws-cdk/aws-waf": "0.0.0", "@aws-cdk/aws-wafregional": "0.0.0", "@aws-cdk/aws-wafv2": "0.0.0", + "@aws-cdk/aws-wisdom": "0.0.0", "@aws-cdk/aws-workspaces": "0.0.0", "@aws-cdk/aws-xray": "0.0.0", "@aws-cdk/cdk-build-tools": "0.0.0", diff --git a/packages/decdk/package.json b/packages/decdk/package.json index 3d181528f325e..5867570ec77f1 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -183,6 +183,7 @@ "@aws-cdk/aws-opensearchservice": "0.0.0", "@aws-cdk/aws-opsworks": "0.0.0", "@aws-cdk/aws-opsworkscm": "0.0.0", + "@aws-cdk/aws-panorama": "0.0.0", "@aws-cdk/aws-pinpoint": "0.0.0", "@aws-cdk/aws-pinpointemail": "0.0.0", "@aws-cdk/aws-qldb": "0.0.0", @@ -190,6 +191,7 @@ "@aws-cdk/aws-ram": "0.0.0", "@aws-cdk/aws-rds": "0.0.0", "@aws-cdk/aws-redshift": "0.0.0", + "@aws-cdk/aws-rekognition": "0.0.0", "@aws-cdk/aws-resourcegroups": "0.0.0", "@aws-cdk/aws-robomaker": "0.0.0", "@aws-cdk/aws-route53": "0.0.0", @@ -230,6 +232,7 @@ "@aws-cdk/aws-waf": "0.0.0", "@aws-cdk/aws-wafregional": "0.0.0", "@aws-cdk/aws-wafv2": "0.0.0", + "@aws-cdk/aws-wisdom": "0.0.0", "@aws-cdk/aws-workspaces": "0.0.0", "@aws-cdk/aws-xray": "0.0.0", "@aws-cdk/cfnspec": "0.0.0", diff --git a/packages/monocdk/package.json b/packages/monocdk/package.json index 49e11473c6be6..1f2e65a012070 100644 --- a/packages/monocdk/package.json +++ b/packages/monocdk/package.json @@ -277,6 +277,7 @@ "@aws-cdk/aws-opensearchservice": "0.0.0", "@aws-cdk/aws-opsworks": "0.0.0", "@aws-cdk/aws-opsworkscm": "0.0.0", + "@aws-cdk/aws-panorama": "0.0.0", "@aws-cdk/aws-pinpoint": "0.0.0", "@aws-cdk/aws-pinpointemail": "0.0.0", "@aws-cdk/aws-qldb": "0.0.0", @@ -284,6 +285,7 @@ "@aws-cdk/aws-ram": "0.0.0", "@aws-cdk/aws-rds": "0.0.0", "@aws-cdk/aws-redshift": "0.0.0", + "@aws-cdk/aws-rekognition": "0.0.0", "@aws-cdk/aws-resourcegroups": "0.0.0", "@aws-cdk/aws-robomaker": "0.0.0", "@aws-cdk/aws-route53": "0.0.0", @@ -324,6 +326,7 @@ "@aws-cdk/aws-waf": "0.0.0", "@aws-cdk/aws-wafregional": "0.0.0", "@aws-cdk/aws-wafv2": "0.0.0", + "@aws-cdk/aws-wisdom": "0.0.0", "@aws-cdk/aws-workspaces": "0.0.0", "@aws-cdk/aws-xray": "0.0.0", "@aws-cdk/cdk-build-tools": "0.0.0", diff --git a/packages/monocdk/rosetta/basic.ts-fixture b/packages/monocdk/rosetta/basic.ts-fixture new file mode 100644 index 0000000000000..0cc6d1104d521 --- /dev/null +++ b/packages/monocdk/rosetta/basic.ts-fixture @@ -0,0 +1,12 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { Stack, Duration } from '@aws-cdk/core'; + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} + diff --git a/packages/monocdk/rosetta/client-vpn.ts-fixture b/packages/monocdk/rosetta/client-vpn.ts-fixture index 4886d590211df..34c83a31ced35 100644 --- a/packages/monocdk/rosetta/client-vpn.ts-fixture +++ b/packages/monocdk/rosetta/client-vpn.ts-fixture @@ -9,7 +9,7 @@ class Fixture extends Stack { const vpc = new ec2.Vpc(this, 'VPC'); const samlProvider = new iam.SamlProvider(this, 'Provider', { - metadataDocument: SamlMetadataDocument.fromXml('xml'), + metadataDocument: iam.SamlMetadataDocument.fromXml('xml'), }) /// here diff --git a/packages/monocdk/rosetta/conns.ts-fixture b/packages/monocdk/rosetta/conns.ts-fixture deleted file mode 100644 index f29d9a1816a6e..0000000000000 --- a/packages/monocdk/rosetta/conns.ts-fixture +++ /dev/null @@ -1,26 +0,0 @@ -// Fixture with fake connectables -import { Construct, Stack } from '@aws-cdk/core'; -import ec2 = require('@aws-cdk/aws-ec2'); - -class Fixture extends Stack { - constructor(scope: Construct, id: string) { - super(scope, id); - - const vpc = new ec2.Vpc(this, 'VPC'); - - const loadBalancer = new FakeConnectable(); - const appFleet = new FakeConnectable(); - const dbFleet = new FakeConnectable(); - const rdsDatabase = new FakeConnectable(); - const fleet1 = new FakeConnectable(); - const fleet2 = new FakeConnectable(); - const listener = new FakeConnectable(); - const myEndpoint = new FakeConnectable(); - - /// here - } -} - -class FakeConnectable implements ec2.IConnectable { - public readonly connections = new ec2.Connections({ securityGroups: [] }); -} diff --git a/packages/monocdk/rosetta/default.ts-fixture b/packages/monocdk/rosetta/default.ts-fixture index 558cc09b1c049..61a973840f007 100644 --- a/packages/monocdk/rosetta/default.ts-fixture +++ b/packages/monocdk/rosetta/default.ts-fixture @@ -1,65 +1,29 @@ -import * as cfn from '@aws-cdk/aws-cloudformation'; -import * as customresources from '@aws-cdk/custom-resources'; -import * as iam from '@aws-cdk/aws-iam'; -import * as lambda from '@aws-cdk/aws-lambda'; -import * as sns from '@aws-cdk/aws-sns'; -import * as sqs from '@aws-cdk/aws-sqs'; -import * as s3 from '@aws-cdk/aws-s3'; -import { - App, - Aws, - CfnCondition, - CfnDynamicReference, - CfnDynamicReferenceService, - CfnInclude, - CfnJson, - CfnMapping, - CfnOutput, - CfnParameter, - CfnResource, - CfnResourceProps, - ConcreteDependable, - Construct, - CustomResource, - CustomResourceProvider, - CustomResourceProviderRuntime, - DependableTrait, - Duration, - Fn, - IConstruct, - SecretValue, - Size, - SizeRoundingBehavior, - Stack, - StackProps, - Stage, - Token, -} from '@aws-cdk/core'; +// Fixture with packages imported, but nothing else +import { Construct, CfnOutput, Stage, Stack, StackProps, StageProps } from '@aws-cdk/core'; +import cdk = require('@aws-cdk/core'); +import codepipeline = require('@aws-cdk/aws-codepipeline'); +import cpactions = require('@aws-cdk/aws-codepipeline-actions'); +import codebuild = require('@aws-cdk/aws-codebuild'); +import codecommit = require('@aws-cdk/aws-codecommit'); +import dynamodb = require('@aws-cdk/aws-dynamodb'); +import ecr = require('@aws-cdk/aws-ecr'); +import ec2 = require('@aws-cdk/aws-ec2'); +import iam = require('@aws-cdk/aws-iam'); +import pipelines = require('@aws-cdk/pipelines'); +import secretsmanager = require('@aws-cdk/aws-secretsmanager'); +import sns = require('@aws-cdk/aws-sns'); +import subscriptions = require('@aws-cdk/aws-sns-subscriptions'); +import s3 = require('@aws-cdk/aws-s3'); -declare const app: App; -declare const arn: 'arn:partition:service:region:account-id:resource-id'; -declare const cfnResource: CfnResource; -declare const construct: Construct; -declare const constructA: Construct; -declare const constructB: Construct; -declare const constructC: Construct; -declare const functionProps: lambda.FunctionProps; -declare const isCompleteHandler: lambda.Function; -declare const myBucket: s3.IBucket; -declare const myFunction: lambda.IFunction; -declare const myProvider: CustomResourceProvider; -declare const myTopic: sns.ITopic; -declare const onEventHandler: lambda.Function; -declare const resourceProps: CfnResourceProps; -declare const stack: Stack; - -declare class MyStack extends Stack {} -declare class YourStack extends Stack {} +class MyApplicationStage extends Stage { + constructor(scope: Construct, id: string, props?: StageProps) { + super(scope, id, props); + } +} -class fixture$construct extends Construct { - public constructor(scope: Construct, id: string) { +class Fixture extends Stack { + constructor(scope: Construct, id: string) { super(scope, id); - /// here } } diff --git a/packages/monocdk/rosetta/function.ts-fixture b/packages/monocdk/rosetta/function.ts-fixture deleted file mode 100644 index 91eafe0abfcc0..0000000000000 --- a/packages/monocdk/rosetta/function.ts-fixture +++ /dev/null @@ -1,18 +0,0 @@ -// Fixture with function (`fn`) already created -import * as path from 'path'; -import { Construct, Stack } from '@aws-cdk/core'; -import { Alias, Code, Function, Runtime } from '@aws-cdk/aws-lambda'; - -class Fixture extends Stack { - constructor(scope: Construct, id: string) { - super(scope, id); - - const fn = new Function(this, 'MyFunction', { - runtime: Runtime.NODEJS_12_X, - handler: 'index.handler', - code: Code.fromAsset(path.join(__dirname, 'lambda-handler')), - }); - - /// here - } -} diff --git a/packages/monocdk/rosetta/init.ts-fixture b/packages/monocdk/rosetta/init.ts-fixture new file mode 100644 index 0000000000000..ce18625a2744b --- /dev/null +++ b/packages/monocdk/rosetta/init.ts-fixture @@ -0,0 +1,3 @@ +import { Template } from '@aws-cdk/assertions'; + +/// here \ No newline at end of file diff --git a/packages/monocdk/rosetta/with-batch-job.ts-fixture b/packages/monocdk/rosetta/with-batch-job.ts-fixture deleted file mode 100644 index 47672ba140841..0000000000000 --- a/packages/monocdk/rosetta/with-batch-job.ts-fixture +++ /dev/null @@ -1,38 +0,0 @@ -// Fixture with packages imported, but nothing else -import { Stack } from '@aws-cdk/core'; -import { Construct } from 'constructs'; -import * as sfn from '@aws-cdk/aws-stepfunctions'; -import * as tasks from '@aws-cdk/aws-stepfunctions-tasks'; -import * as batch from '@aws-cdk/aws-batch'; -import * as ec2 from '@aws-cdk/aws-ec2'; -import * as ecs from '@aws-cdk/aws-ecs'; -import * as path from 'path'; - -class Fixture extends Stack { - constructor(scope: Construct, id: string) { - super(scope, id); - - const vpc = ec2.Vpc.fromLookup(this, 'Vpc', { - isDefault: true, - }); - - const batchQueue = new batch.JobQueue(this, 'JobQueue', { - computeEnvironments: [ - { - order: 1, - computeEnvironment: new batch.ComputeEnvironment(this, 'ComputeEnv', { - computeResources: { vpc }, - }), - }, - ], - }); - - const batchJobDefinition = new batch.JobDefinition(this, 'JobDefinition', { - container: { - image: ecs.ContainerImage.fromAsset(path.resolve(__dirname, 'batchjob-image')), - }, - }); - - /// here - } -} diff --git a/packages/monocdk/rosetta/with-objects.ts-fixture b/packages/monocdk/rosetta/with-objects.ts-fixture new file mode 100644 index 0000000000000..1251aad728423 --- /dev/null +++ b/packages/monocdk/rosetta/with-objects.ts-fixture @@ -0,0 +1,49 @@ +// Fixture with packages imported, but nothing else +import { Construct, Stack } from '@aws-cdk/core'; +import appsync = require('@aws-cdk/aws-appsync'); +const pluralize = require('pluralize'); + +const args = { + after: appsync.GraphqlType.string(), + first: appsync.GraphqlType.int(), + before: appsync.GraphqlType.string(), + last: appsync.GraphqlType.int(), +}; + +const Node = new appsync.InterfaceType('Node', { + definition: { id: appsync.GraphqlType.string() } +}); + +const FilmNode = new appsync.ObjectType('FilmNode', { + interfaceTypes: [Node], + definition: { filmName: appsync.GraphqlType.string() } +}); + +function generateEdgeAndConnection(base: appsync.ObjectType) { + const edge = new appsync.ObjectType(`${base.name}Edge`, { + definition: { node: base.attribute(), cursor: appsync.GraphqlType.string() } + }); + const connection = new appsync.ObjectType(`${base.name}Connection`, { + definition: { + edges: edge.attribute({ isList: true }), + [pluralize(base.name)]: base.attribute({ isList: true }), + totalCount: appsync.GraphqlType.int(), + } + }); + return { edge: edge, connection: connection }; +} + +const demo = new appsync.ObjectType('Demo', { + definition: { + id: appsync.GraphqlType.string({ isRequired: true }), + version: appsync.GraphqlType.string({ isRequired: true }), + }, +}); + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} diff --git a/yarn.lock b/yarn.lock index 97a3298a6c72f..026281159396d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1870,7 +1870,7 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^26.0.24": +"@types/jest@^26.0.22", "@types/jest@^26.0.24": version "26.0.24" resolved "https://registry.npmjs.org/@types/jest/-/jest-26.0.24.tgz#943d11976b16739185913a1936e0de0c4a7d595a" integrity sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w== From a5e51116260dff9ccf3fb91308e6d1bb279b2778 Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 4 Nov 2021 13:46:13 +0100 Subject: [PATCH 36/70] docs(codebuild): describe use of CodeBuild caching in more detail (#17332) I spent a good couple of hours figuring out things that the docs should have told me. Add this in for the future. ---- *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 | 57 +++++++++++++++++++++-- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/packages/@aws-cdk/aws-codebuild/README.md b/packages/@aws-cdk/aws-codebuild/README.md index 8a5fa30ac408b..29d06892bc682 100644 --- a/packages/@aws-cdk/aws-codebuild/README.md +++ b/packages/@aws-cdk/aws-codebuild/README.md @@ -184,23 +184,53 @@ You can save time when your project builds by using a cache. A cache can store r ### S3 Caching -With S3 caching, the cache is stored in an S3 bucket which is available from multiple hosts. +With S3 caching, the cache is stored in an S3 bucket which is available +regardless from what CodeBuild instance gets selected to run your CodeBuild job +on. When using S3 caching, you must also add in a `cache` section to your +buildspec which indicates the files to be cached: ```ts +declare const myCachingBucket: s3.Bucket; + new codebuild.Project(this, 'Project', { source: codebuild.Source.bitBucket({ owner: 'awslabs', repo: 'aws-cdk', }), - cache: codebuild.Cache.bucket(new s3.Bucket(this, 'Bucket')) + + cache: codebuild.Cache.bucket(myCachingBucket), + + // BuildSpec with a 'cache' section necessary for S3 caching. This can + // also come from 'buildspec.yml' in your source. + buildSpec: codebuild.BuildSpec.fromObject({ + version: '0.2', + phases: { + build: { + commands: ['...'], + }, + }, + cache: { + paths: [ + // The '**/*' is required to indicate all files in this directory + '/root/cachedir/**/*', + ], + }, + }), }); ``` +Note that two different CodeBuild Projects using the same S3 bucket will *not* +share their cache: each Project will get a unique file in the S3 bucket to store +the cache in. + ### Local Caching -With local caching, the cache is stored on the codebuild instance itself. This is simple, -cheap and fast, but CodeBuild cannot guarantee a reuse of instance and hence cannot -guarantee cache hits. For example, when a build starts and caches files locally, if two subsequent builds start at the same time afterwards only one of those builds would get the cache. Three different cache modes are supported, which can be turned on individually. +With local caching, the cache is stored on the codebuild instance itself. This +is simple, cheap and fast, but CodeBuild cannot guarantee a reuse of instance +and hence cannot guarantee cache hits. For example, when a build starts and +caches files locally, if two subsequent builds start at the same time afterwards +only one of those builds would get the cache. Three different cache modes are +supported, which can be turned on individually. * `LocalCacheMode.SOURCE` caches Git metadata for primary and secondary sources. * `LocalCacheMode.DOCKER_LAYER` caches existing Docker layers. @@ -214,6 +244,23 @@ new codebuild.Project(this, 'Project', { // Enable Docker AND custom caching cache: codebuild.Cache.local(codebuild.LocalCacheMode.DOCKER_LAYER, codebuild.LocalCacheMode.CUSTOM) + + // BuildSpec with a 'cache' section necessary for 'CUSTOM' caching. This can + // also come from 'buildspec.yml' in your source. + buildSpec: codebuild.BuildSpec.fromObject({ + version: '0.2', + phases: { + build: { + commands: ['...'], + }, + }, + cache: { + paths: [ + // The '**/*' is required to indicate all files in this directory + '/root/cachedir/**/*', + ], + }, + }), }); ``` From ea779aa3df08f8ae3aa1720a8df51e0a60813984 Mon Sep 17 00:00:00 2001 From: Nick Lynch Date: Thu, 4 Nov 2021 13:40:23 +0000 Subject: [PATCH 37/70] chore(cli): v2 python init templates have incorrect constructs version (#17333) The init templates were modified as part of #17062. One change was for the 'app' and 'sample-app' templates to use 'requirements.txt' instead of 'setup.py'. In that conversion, a quirk of the `%constructsversion%` replacement was lost; that replacement inserts the version comparison `>=` itself, so having it in the requirements.txt results in a broken specifier. This was caught in the forward-merge to v2, where there are additional tests verfying the constructs versions. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../lib/init-templates/v2/app/python/requirements.template.txt | 2 +- .../v2/sample-app/python/requirements.template.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt b/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt index 5ba3f43115a07..f8d8c52349751 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt +++ b/packages/aws-cdk/lib/init-templates/v2/app/python/requirements.template.txt @@ -1,3 +1,3 @@ aws-cdk-lib==%cdk-version% aws-cdk.assertions-alpha==%cdk-version% -constructs>=%constructs-version% +constructs%constructs-version% diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt index 5ba3f43115a07..f8d8c52349751 100644 --- a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/requirements.template.txt @@ -1,3 +1,3 @@ aws-cdk-lib==%cdk-version% aws-cdk.assertions-alpha==%cdk-version% -constructs>=%constructs-version% +constructs%constructs-version% From e0f118046c4a0350bdd614fbff4b96ba7772402e Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Thu, 4 Nov 2021 20:10:43 +0530 Subject: [PATCH 38/70] feat(cfnspec): cloudformation spec v46.0.0 (#17334) Co-authored-by: AWS CDK Team Co-authored-by: Eli Polonsky Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- packages/monocdk/rosetta/basic-portfolio.ts-fixture | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/monocdk/rosetta/basic-portfolio.ts-fixture b/packages/monocdk/rosetta/basic-portfolio.ts-fixture index d8925e6645aa7..3029872ea1f0d 100644 --- a/packages/monocdk/rosetta/basic-portfolio.ts-fixture +++ b/packages/monocdk/rosetta/basic-portfolio.ts-fixture @@ -1,9 +1,9 @@ // Fixture with packages imported, but nothing else -import { Construct, Stack } from '@aws-cdk/core'; +import * as cdk from '@aws-cdk/core'; import * as servicecatalog from '@aws-cdk/aws-servicecatalog'; -class Fixture extends Stack { - constructor(scope: Construct, id: string) { +class Fixture extends cdk.Stack { + constructor(scope: cdk.Construct, id: string) { super(scope, id); const portfolio = new servicecatalog.Portfolio(this, "MyFirstPortfolio", { From cdb0c0a79e08f7fc6587422c617556c8fde60c64 Mon Sep 17 00:00:00 2001 From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com> Date: Thu, 4 Nov 2021 11:35:04 -0400 Subject: [PATCH 39/70] chore(sns): make examples compile (#17316) Includes: - chore(sns): make examples compile - chore(sns-subscriptions): make examples compile ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-sns-subscriptions/README.md | 36 +++--- .../rosetta/default.ts-fixture | 15 +++ packages/@aws-cdk/aws-sns/README.md | 113 ++++++++++-------- .../aws-sns/rosetta/default.ts-fixture | 15 +++ 4 files changed, 106 insertions(+), 73 deletions(-) create mode 100644 packages/@aws-cdk/aws-sns-subscriptions/rosetta/default.ts-fixture create mode 100644 packages/@aws-cdk/aws-sns/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-sns-subscriptions/README.md b/packages/@aws-cdk/aws-sns-subscriptions/README.md index ca06d08689736..048ca4dd9fdda 100644 --- a/packages/@aws-cdk/aws-sns-subscriptions/README.md +++ b/packages/@aws-cdk/aws-sns-subscriptions/README.md @@ -27,8 +27,6 @@ Subscriptions to Amazon SQS and AWS Lambda can be added on topics across regions Create an Amazon SNS Topic to add subscriptions. ```ts -import * as sns from '@aws-cdk/aws-sns'; - const myTopic = new sns.Topic(this, 'MyTopic'); ``` @@ -37,7 +35,7 @@ const myTopic = new sns.Topic(this, 'MyTopic'); Add an HTTP or HTTPS Subscription to your topic: ```ts -import * as subscriptions from '@aws-cdk/aws-sns-subscriptions'; +const myTopic = new sns.Topic(this, 'MyTopic'); myTopic.addSubscription(new subscriptions.UrlSubscription('https://foobar.com/')); ``` @@ -48,8 +46,10 @@ parameter](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parame following code defines a CloudFormation parameter and uses it in a URL subscription. ```ts +const myTopic = new sns.Topic(this, 'MyTopic'); const url = new CfnParameter(this, 'url-param'); -myTopic.addSubscription(new subscriptions.UrlSubscription(url.valueAsString())); + +myTopic.addSubscription(new subscriptions.UrlSubscription(url.valueAsString)); ``` ### Amazon SQS @@ -57,12 +57,10 @@ myTopic.addSubscription(new subscriptions.UrlSubscription(url.valueAsString())); Subscribe a queue to your topic: ```ts -import * as sqs from '@aws-cdk/aws-sqs'; -import * as subscriptions from '@aws-cdk/aws-sns-subscriptions'; - const myQueue = new sqs.Queue(this, 'MyQueue'); +const myTopic = new sns.Topic(this, 'MyTopic'); -myTopic.addSubscription(new subscriptions.SqsSubscription(queue)); +myTopic.addSubscription(new subscriptions.SqsSubscription(myQueue)); ``` KMS key permissions will automatically be granted to SNS when a subscription is made to @@ -77,14 +75,9 @@ Subscribe an AWS Lambda function to your topic: ```ts import * as lambda from '@aws-cdk/aws-lambda'; -import * as subscriptions from '@aws-cdk/aws-sns-subscriptions'; - -const myFunction = new lambda.Function(this, 'Echo', { - handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_12_X, - code: lambda.Code.fromInline(`exports.handler = ${handler.toString()}`) -}); +const myTopic = new sns.Topic(this, 'myTopic'); +declare const myFunction: lambda.Function; myTopic.addSubscription(new subscriptions.LambdaSubscription(myFunction)); ``` @@ -93,8 +86,7 @@ myTopic.addSubscription(new subscriptions.LambdaSubscription(myFunction)); Subscribe an email address to your topic: ```ts -import * as subscriptions from '@aws-cdk/aws-sns-subscriptions'; - +const myTopic = new sns.Topic(this, 'MyTopic'); myTopic.addSubscription(new subscriptions.EmailSubscription('foo@bar.com')); ``` @@ -104,8 +96,10 @@ parameter](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parame following code defines a CloudFormation parameter and uses it in an email subscription. ```ts +const myTopic = new sns.Topic(this, 'Topic'); const emailAddress = new CfnParameter(this, 'email-param'); -myTopic.addSubscription(new subscriptions.EmailSubscription(emailAddress.valueAsString())); + +myTopic.addSubscription(new subscriptions.EmailSubscription(emailAddress.valueAsString)); ``` Note that email subscriptions require confirmation by visiting the link sent to the @@ -116,7 +110,7 @@ email address. Subscribe an sms number to your topic: ```ts -import * as subscriptions from '@aws-cdk/aws-sns-subscriptions'; +const myTopic = new sns.Topic(this, 'Topic'); myTopic.addSubscription(new subscriptions.SmsSubscription('+15551231234')); ``` @@ -127,6 +121,8 @@ parameter](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parame following code defines a CloudFormation parameter and uses it in an sms subscription. ```ts +const myTopic = new sns.Topic(this, 'Topic'); const smsNumber = new CfnParameter(this, 'sms-param'); -myTopic.addSubscription(new subscriptions.SmsSubscription(smsNumber.valueAsString())); + +myTopic.addSubscription(new subscriptions.SmsSubscription(smsNumber.valueAsString)); ``` diff --git a/packages/@aws-cdk/aws-sns-subscriptions/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-sns-subscriptions/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..8fd7cde78ac48 --- /dev/null +++ b/packages/@aws-cdk/aws-sns-subscriptions/rosetta/default.ts-fixture @@ -0,0 +1,15 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { CfnParameter, Duration, Stack } from '@aws-cdk/core'; +import * as sns from '@aws-cdk/aws-sns'; +import * as sqs from '@aws-cdk/aws-sqs'; +import * as subscriptions from '@aws-cdk/aws-sns-subscriptions'; +import * as iam from '@aws-cdk/aws-iam'; + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} diff --git a/packages/@aws-cdk/aws-sns/README.md b/packages/@aws-cdk/aws-sns/README.md index 23ee15e4af508..72678ff0f8a3d 100644 --- a/packages/@aws-cdk/aws-sns/README.md +++ b/packages/@aws-cdk/aws-sns/README.md @@ -14,23 +14,19 @@ Add an SNS Topic to your stack: ```ts -import * as sns from '@aws-cdk/aws-sns'; - const topic = new sns.Topic(this, 'Topic', { - displayName: 'Customer subscription topic' + displayName: 'Customer subscription topic', }); ``` Add a FIFO SNS topic with content-based de-duplication to your stack: ```ts -import * as sns from '@aws-cdk/aws-sns'; - const topic = new sns.Topic(this, 'Topic', { - contentBasedDeduplication: true, - displayName: 'Customer subscription topic', - fifo: true, - topicName: 'customerTopic', + contentBasedDeduplication: true, + displayName: 'Customer subscription topic', + fifo: true, + topicName: 'customerTopic', }); ``` @@ -46,17 +42,18 @@ default implementations of which can be found in the Add an HTTPS Subscription to your topic: ```ts -import * as subs from '@aws-cdk/aws-sns-subscriptions'; - const myTopic = new sns.Topic(this, 'MyTopic'); -myTopic.addSubscription(new subs.UrlSubscription('https://foobar.com/')); +myTopic.addSubscription(new subscriptions.UrlSubscription('https://foobar.com/')); ``` Subscribe a queue to the topic: ```ts -myTopic.addSubscription(new subs.SqsSubscription(queue)); +declare const queue: sqs.Queue; +const myTopic = new sns.Topic(this, 'MyTopic'); + +myTopic.addSubscription(new subscriptions.SqsSubscription(queue)); ``` Note that subscriptions of queues in different accounts need to be manually confirmed by @@ -69,44 +66,48 @@ A filter policy can be specified when subscribing an endpoint to a topic. Example with a Lambda subscription: ```ts +import * as lambda from '@aws-cdk/aws-lambda'; + const myTopic = new sns.Topic(this, 'MyTopic'); -const fn = new lambda.Function(this, 'Function', ...); +declare const fn: lambda.Function; // Lambda should receive only message matching the following conditions on attributes: // color: 'red' or 'orange' or begins with 'bl' // size: anything but 'small' or 'medium' // price: between 100 and 200 or greater than 300 // store: attribute must be present -topic.addSubscription(new subs.LambdaSubscription(fn, { - filterPolicy: { - color: sns.SubscriptionFilter.stringFilter({ - allowlist: ['red', 'orange'], - matchPrefixes: ['bl'] - }), - size: sns.SubscriptionFilter.stringFilter({ - denylist: ['small', 'medium'], - }), - price: sns.SubscriptionFilter.numericFilter({ - between: { start: 100, stop: 200 }, - greaterThan: 300 - }), - store: sns.SubscriptionFilter.existsFilter(), - } +myTopic.addSubscription(new subscriptions.LambdaSubscription(fn, { + filterPolicy: { + color: sns.SubscriptionFilter.stringFilter({ + allowlist: ['red', 'orange'], + matchPrefixes: ['bl'], + }), + size: sns.SubscriptionFilter.stringFilter({ + denylist: ['small', 'medium'], + }), + price: sns.SubscriptionFilter.numericFilter({ + between: { start: 100, stop: 200 }, + greaterThan: 300, + }), + store: sns.SubscriptionFilter.existsFilter(), + }, })); ``` ### Example of Firehose Subscription -```typescript - import { Subscription, SubscriptionProtocol, Topic } from '@aws-cdk/aws-sns'; - import { DeliveryStream } from '@aws-cdk/aws-kinesisfirehose'; - const topic = new Topic(stack, 'Topic'); - const stream = new DeliveryStream(stack, 'DeliveryStream', ...) - new Subscription(stack, 'Subscription', { - endpoint: stream.deliveryStreamArn, - protocol: SubscriptionProtocol.FIREHOSE, - subscriptionRoleArn: "SAMPLE_ARN", //role with permissions to send messages to a firehose delivery stream - }) +```ts +import { DeliveryStream } from '@aws-cdk/aws-kinesisfirehose'; + +const topic = new sns.Topic(this, 'Topic'); +declare const stream: DeliveryStream; + +new sns.Subscription(this, 'Subscription', { + topic, + endpoint: stream.deliveryStreamArn, + protocol: sns.SubscriptionProtocol.FIREHOSE, + subscriptionRoleArn: "SAMPLE_ARN", //role with permissions to send messages to a firehose delivery stream +}); ``` ## DLQ setup for SNS Subscription @@ -117,17 +118,17 @@ See the [SNS DLQ configuration docs](https://docs.aws.amazon.com/sns/latest/dg/s Example of usage with user provided DLQ. ```ts -const topic = new sns.Topic(stack, 'Topic'); -const dlQueue = new Queue(stack, 'DeadLetterQueue', { - queueName: 'MySubscription_DLQ', - retentionPeriod: cdk.Duration.days(14), +const topic = new sns.Topic(this, 'Topic'); +const dlQueue = new sqs.Queue(this, 'DeadLetterQueue', { + queueName: 'MySubscription_DLQ', + retentionPeriod: Duration.days(14), }); -new sns.Subscription(stack, 'Subscription', { - endpoint: 'endpoint', - protocol: sns.SubscriptionProtocol.LAMBDA, - topic, - deadLetterQueue: dlQueue, +new sns.Subscription(this, 'Subscription', { + endpoint: 'endpoint', + protocol: sns.SubscriptionProtocol.LAMBDA, + topic, + deadLetterQueue: dlQueue, }); ``` @@ -138,9 +139,15 @@ SNS topics can be used as targets for CloudWatch event rules. Use the `@aws-cdk/aws-events-targets.SnsTopic`: ```ts +import * as codecommit from '@aws-cdk/aws-codecommit'; import * as targets from '@aws-cdk/aws-events-targets'; -codeCommitRepository.onCommit(new targets.SnsTopic(myTopic)); +declare const repo: codecommit.Repository; +const myTopic = new sns.Topic(this, 'Topic'); + +repo.onCommit('OnCommit', { + target: new targets.SnsTopic(myTopic), +}); ``` This will result in adding a target to the event rule and will also modify the @@ -153,8 +160,8 @@ one doesn't already exist. Using `addToResourcePolicy` is the simplest way to add policies, but a `TopicPolicy` can also be created manually. ```ts -const topic = new sns.Topic(stack, 'Topic'); -const topicPolicy = new sns.TopicPolicy(stack, 'TopicPolicy', { +const topic = new sns.Topic(this, 'Topic'); +const topicPolicy = new sns.TopicPolicy(this, 'TopicPolicy', { topics: [topic], }); @@ -168,14 +175,14 @@ topicPolicy.document.addStatements(new iam.PolicyStatement({ A policy document can also be passed on `TopicPolicy` construction ```ts -const topic = new sns.Topic(stack, 'Topic'); +const topic = new sns.Topic(this, 'Topic'); const policyDocument = new iam.PolicyDocument({ assignSids: true, statements: [ new iam.PolicyStatement({ actions: ["sns:Subscribe"], principals: [new iam.AnyPrincipal()], - resources: [topic.topicArn] + resources: [topic.topicArn], }), ], }); diff --git a/packages/@aws-cdk/aws-sns/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-sns/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..72fda381ecb7a --- /dev/null +++ b/packages/@aws-cdk/aws-sns/rosetta/default.ts-fixture @@ -0,0 +1,15 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { Duration, Stack } from '@aws-cdk/core'; +import * as sns from '@aws-cdk/aws-sns'; +import * as sqs from '@aws-cdk/aws-sqs'; +import * as subscriptions from '@aws-cdk/aws-sns-subscriptions'; +import * as iam from '@aws-cdk/aws-iam'; + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} From d24e0673e6e2f97c0a44abb845b943712745db48 Mon Sep 17 00:00:00 2001 From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com> Date: Thu, 4 Nov 2021 12:29:42 -0400 Subject: [PATCH 40/70] chore(sqs): make examples compile (#17314) ---- *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-sqs/README.md | 8 ++++---- .../@aws-cdk/aws-sqs/rosetta/default.ts-fixture | 13 +++++++++++++ 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 packages/@aws-cdk/aws-sqs/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-sqs/README.md b/packages/@aws-cdk/aws-sqs/README.md index c824f9410e8ad..11dbb164e5c56 100644 --- a/packages/@aws-cdk/aws-sqs/README.md +++ b/packages/@aws-cdk/aws-sqs/README.md @@ -22,7 +22,7 @@ without losing messages or requiring other services to be available. Import to your project: -```ts +```ts nofixture import * as sqs from '@aws-cdk/aws-sqs'; ``` @@ -44,15 +44,15 @@ can manage yourself. ```ts // Use managed key new sqs.Queue(this, 'Queue', { - encryption: QueueEncryption.KMS_MANAGED, + encryption: sqs.QueueEncryption.KMS_MANAGED, }); // Use custom key const myKey = new kms.Key(this, 'Key'); new sqs.Queue(this, 'Queue', { - encryption: QueueEncryption.KMS, - encryptionMasterKey: myKey + encryption: sqs.QueueEncryption.KMS, + encryptionMasterKey: myKey, }); ``` diff --git a/packages/@aws-cdk/aws-sqs/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-sqs/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..968d51c8ae916 --- /dev/null +++ b/packages/@aws-cdk/aws-sqs/rosetta/default.ts-fixture @@ -0,0 +1,13 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { Stack } from '@aws-cdk/core'; +import sqs = require('@aws-cdk/aws-sqs'); +import kms = require('@aws-cdk/aws-kms'); + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} From a91cc051ed319526535b5e0877b47fe5ca2161ef Mon Sep 17 00:00:00 2001 From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com> Date: Thu, 4 Nov 2021 13:23:21 -0400 Subject: [PATCH 41/70] chore(dynamodb): make examples compile (#17313) ---- *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-dynamodb/README.md | 47 ++++++++----------- .../aws-dynamodb/rosetta/default.ts-fixture | 13 +++++ 2 files changed, 32 insertions(+), 28 deletions(-) create mode 100644 packages/@aws-cdk/aws-dynamodb/rosetta/default.ts-fixture diff --git a/packages/@aws-cdk/aws-dynamodb/README.md b/packages/@aws-cdk/aws-dynamodb/README.md index b07946c52d65f..b79b1e0efe465 100644 --- a/packages/@aws-cdk/aws-dynamodb/README.md +++ b/packages/@aws-cdk/aws-dynamodb/README.md @@ -14,10 +14,8 @@ Here is a minimal deployable DynamoDB table definition: ```ts -import * as dynamodb from '@aws-cdk/aws-dynamodb'; - const table = new dynamodb.Table(this, 'Table', { - partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING } + partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, }); ``` @@ -28,7 +26,8 @@ factory method. This method accepts table name or table ARN which describes the existing table: ```ts -const table = Table.fromTableArn(this, 'ImportedTable', 'arn:aws:dynamodb:us-east-1:111111111:table/my-table'); +declare const user: iam.User; +const table = dynamodb.Table.fromTableArn(this, 'ImportedTable', 'arn:aws:dynamodb:us-east-1:111111111:table/my-table'); // now you can just call methods on the table table.grantReadWriteData(user); ``` @@ -50,11 +49,9 @@ DynamoDB supports two billing modes: * PAY_PER_REQUEST - on-demand pricing and scaling. You only pay for what you use and there is no read and write capacity for the table or its global secondary indexes. ```ts -import * as dynamodb from '@aws-cdk/aws-dynamodb'; - const table = new dynamodb.Table(this, 'Table', { partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, - billingMode: dynamodb.BillingMode.PAY_PER_REQUEST + billingMode: dynamodb.BillingMode.PAY_PER_REQUEST, }); ``` @@ -81,8 +78,6 @@ https://aws.amazon.com/blogs/database/how-to-use-aws-cloudformation-to-configure You can create DynamoDB Global Tables by setting the `replicationRegions` property on a `Table`: ```ts -import * as dynamodb from '@aws-cdk/aws-dynamodb'; - const globalTable = new dynamodb.Table(this, 'Table', { partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, replicationRegions: ['us-east-1', 'us-east-2', 'us-west-2'], @@ -100,7 +95,7 @@ you have to make sure write auto-scaling is enabled for that Table: const globalTable = new dynamodb.Table(this, 'Table', { partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, replicationRegions: ['us-east-1', 'us-east-2', 'us-west-2'], - billingMode: BillingMode.PROVISIONED, + billingMode: dynamodb.BillingMode.PROVISIONED, }); globalTable.autoScaleWriteCapacity({ @@ -131,11 +126,9 @@ All user data stored in Amazon DynamoDB is fully encrypted at rest. When creatin Creating a Table encrypted with a customer managed CMK: ```ts -import dynamodb = require('@aws-cdk/aws-dynamodb'); - -const table = new dynamodb.Table(stack, 'MyTable', { +const table = new dynamodb.Table(this, 'MyTable', { partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, - encryption: TableEncryption.CUSTOMER_MANAGED, + encryption: dynamodb.TableEncryption.CUSTOMER_MANAGED, }); // You can access the CMK that was added to the stack on your behalf by the Table construct via: @@ -145,15 +138,14 @@ const tableEncryptionKey = table.encryptionKey; You can also supply your own key: ```ts -import dynamodb = require('@aws-cdk/aws-dynamodb'); -import kms = require('@aws-cdk/aws-kms'); +import * as kms from '@aws-cdk/aws-kms'; -const encryptionKey = new kms.Key(stack, 'Key', { - enableKeyRotation: true +const encryptionKey = new kms.Key(this, 'Key', { + enableKeyRotation: true, }); -const table = new dynamodb.Table(stack, 'MyTable', { +const table = new dynamodb.Table(this, 'MyTable', { partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, - encryption: TableEncryption.CUSTOMER_MANAGED, + encryption: dynamodb.TableEncryption.CUSTOMER_MANAGED, encryptionKey, // This will be exposed as table.encryptionKey }); ``` @@ -161,11 +153,9 @@ const table = new dynamodb.Table(stack, 'MyTable', { In order to use the AWS managed CMK instead, change the code to: ```ts -import dynamodb = require('@aws-cdk/aws-dynamodb'); - -const table = new dynamodb.Table(stack, 'MyTable', { +const table = new dynamodb.Table(this, 'MyTable', { partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, - encryption: TableEncryption.AWS_MANAGED, + encryption: dynamodb.TableEncryption.AWS_MANAGED, }); // In this case, the CMK _cannot_ be accessed through table.encryptionKey. @@ -176,11 +166,13 @@ const table = new dynamodb.Table(stack, 'MyTable', { To get the partition key and sort key of the table or indexes you have configured: ```ts -const { partitionKey, sortKey } = table.schema(); +declare const table: dynamodb.Table; +const schema = table.schema(); +const partitionKey = schema.partitionKey; +const sortKey = schema.sortKey; // In case you want to get schema details for any secondary index - -const { partitionKey, sortKey } = table.schema(INDEX_NAME); +// const { partitionKey, sortKey } = table.schema(INDEX_NAME); ``` ## Kinesis Stream @@ -188,7 +180,6 @@ const { partitionKey, sortKey } = table.schema(INDEX_NAME); A Kinesis Data Stream can be configured on the DynamoDB table to capture item-level changes. ```ts -import * as dynamodb from '@aws-cdk/aws-dynamodb'; import * as kinesis from '@aws-cdk/aws-kinesis'; const stream = new kinesis.Stream(this, 'Stream'); diff --git a/packages/@aws-cdk/aws-dynamodb/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-dynamodb/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..1f9bb33819183 --- /dev/null +++ b/packages/@aws-cdk/aws-dynamodb/rosetta/default.ts-fixture @@ -0,0 +1,13 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { Duration, Stack } from '@aws-cdk/core'; +import dynamodb = require('@aws-cdk/aws-dynamodb'); +import iam = require('@aws-cdk/aws-iam'); + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} From bc00427fa6540d10ef994ace152ea4b85ccf81d5 Mon Sep 17 00:00:00 2001 From: Otavio Macedo Date: Thu, 4 Nov 2021 18:18:45 +0000 Subject: [PATCH 42/70] chore: stripping stability banners for Cfn constructs on alpha modules (#17327) Alpha modules don't have Cfn constructs, so it doesn't make sense to have a stability banner for them on the README. Fixes #17038. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../individual-pkg-gen/transform-packages.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tools/@aws-cdk/individual-pkg-gen/transform-packages.ts b/tools/@aws-cdk/individual-pkg-gen/transform-packages.ts index b56e39c788f2b..a2855fb2fa1b3 100644 --- a/tools/@aws-cdk/individual-pkg-gen/transform-packages.ts +++ b/tools/@aws-cdk/individual-pkg-gen/transform-packages.ts @@ -6,6 +6,21 @@ const lerna_project = require('@lerna/project'); // eslint-disable-next-line @typescript-eslint/no-require-imports const ver = require('../../../scripts/resolve-version'); +const CFN_STABILITY_BANNER = [ + '![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge)', + '', + '> All classes with the `Cfn` prefix in this module ([CFN Resources]) are always stable and safe to use.', + '>', + '> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib', +].join('\n'); + +const FEATURE_CFN_STABILITY_BANNER = `> **CFN Resources:** All classes with the \`Cfn\` prefix in this module ([CFN Resources]) are always +> stable and safe to use. +> +> [CFN Resources]: https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_lib`; + +const FEATURE_CFN_STABILITY_LINE = /CFN Resources\s+\| !\[Stable]\(https:\/\/img\.shields\.io\/badge\/stable-success\.svg\?style=for-the-badge\)\n/gm; + /** * @aws-cdk/ scoped packages that may be present in devDependencies and need to * be retained (or else pkglint might declare the package unworthy). @@ -109,6 +124,13 @@ function transformPackages(): void { packageUnscopedName: `${pkg.name.substring('@aws-cdk/'.length)}`, }); fs.outputFileSync(destination, sourceCodeOutput); + } else if (sourceFileName === 'README.md') { + // Remove the stability banner for Cfn constructs, since they don't exist in the alpha modules + let sourceCode = fs.readFileSync(source).toString(); + [CFN_STABILITY_BANNER, FEATURE_CFN_STABILITY_BANNER, FEATURE_CFN_STABILITY_LINE].forEach(pattern => { + sourceCode = sourceCode.replace(pattern, ''); + }); + fs.outputFileSync(destination, sourceCode); } else { const stat = fs.statSync(source); if (stat.isDirectory()) { From 57ad1e087edef653d672c1426b920b12962f0f0f Mon Sep 17 00:00:00 2001 From: Calvin Combs <66279577+comcalvi@users.noreply.github.com> Date: Thu, 4 Nov 2021 12:15:06 -0700 Subject: [PATCH 43/70] feat(cli): added `build` field to cdk.json (#17176) Adds a `build` field to `cdk.json`. The command specified in the `build` will be executed before synthesis. This can be used to build any code that needs to be built before synthesis (for example, CDK App code or Lambda Function code). This is part of the changes needed for the `cdk watch` command (https://github.com/aws/aws-cdk-rfcs/pull/383). ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/README.md | 7 ++++ packages/aws-cdk/lib/api/cxapp/exec.ts | 11 +++-- packages/aws-cdk/lib/settings.ts | 4 ++ packages/aws-cdk/test/api/exec.test.ts | 40 ++++++++++++++++--- packages/aws-cdk/test/usersettings.test.ts | 20 ++++++++++ .../aws-cdk/test/util/mock-child_process.ts | 21 +++------- 6 files changed, 79 insertions(+), 24 deletions(-) diff --git a/packages/aws-cdk/README.md b/packages/aws-cdk/README.md index e4566b7bbb690..0a2270b08fc90 100644 --- a/packages/aws-cdk/README.md +++ b/packages/aws-cdk/README.md @@ -464,6 +464,7 @@ Some of the interesting keys that can be used in the JSON configuration files: ```json5 { "app": "node bin/main.js", // Command to start the CDK app (--app='node bin/main.js') + "build": "mvn package", // Specify pre-synth build (no command line option) "context": { // Context entries (--context=key=value) "key": "value" }, @@ -473,6 +474,12 @@ Some of the interesting keys that can be used in the JSON configuration files: } ``` +If specified, the command in the `build` key will be executed immediately before synthesis. +This can be used to build Lambda Functions, CDK Application code, or other assets. +`build` cannot be specified on the command line or in the User configuration, +and must be specified in the Project configuration. The command specified +in `build` will be executed by the "watch" process before deployment. + ### Environment The following environment variables affect aws-cdk: diff --git a/packages/aws-cdk/lib/api/cxapp/exec.ts b/packages/aws-cdk/lib/api/cxapp/exec.ts index facaf24a3bfe0..bcc298deaeea2 100644 --- a/packages/aws-cdk/lib/api/cxapp/exec.ts +++ b/packages/aws-cdk/lib/api/cxapp/exec.ts @@ -46,6 +46,11 @@ export async function execProgram(aws: SdkProvider, config: Configuration): Prom debug('context:', context); env[cxapi.CONTEXT_ENV] = JSON.stringify(context); + const build = config.settings.get(['build']); + if (build) { + await exec(build); + } + const app = config.settings.get(['app']); if (!app) { throw new Error(`--app is required either in command-line, in ${PROJECT_CONFIG} or in ${USER_DEFAULTS}`); @@ -74,7 +79,7 @@ export async function execProgram(aws: SdkProvider, config: Configuration): Prom debug('env:', env); - await exec(); + await exec(commandLine.join(' ')); return createAssembly(outdir); @@ -91,7 +96,7 @@ export async function execProgram(aws: SdkProvider, config: Configuration): Prom } } - async function exec() { + async function exec(commandAndArgs: string) { return new Promise((ok, fail) => { // We use a slightly lower-level interface to: // @@ -103,7 +108,7 @@ export async function execProgram(aws: SdkProvider, config: Configuration): Prom // anyway, and if the subprocess is printing to it for debugging purposes the // user gets to see it sooner. Plus, capturing doesn't interact nicely with some // processes like Maven. - const proc = childProcess.spawn(commandLine[0], commandLine.slice(1), { + const proc = childProcess.spawn(commandAndArgs, { stdio: ['ignore', 'inherit', 'inherit'], detached: false, shell: true, diff --git a/packages/aws-cdk/lib/settings.ts b/packages/aws-cdk/lib/settings.ts index 4bfafd447d607..6182ecc26e0c3 100644 --- a/packages/aws-cdk/lib/settings.ts +++ b/packages/aws-cdk/lib/settings.ts @@ -113,6 +113,10 @@ export class Configuration { const readUserContext = this.props.readUserContext ?? true; + if (userConfig.get(['build'])) { + throw new Error('The `build` key cannot be specified in the user config (~/.cdk.json), specify it in the project config (cdk.json) instead'); + } + const contextSources = [ this.commandLineContext, this.projectConfig.subSettings([CONTEXT_KEY]).makeReadOnly(), diff --git a/packages/aws-cdk/test/api/exec.test.ts b/packages/aws-cdk/test/api/exec.test.ts index d2e65907527fa..b9c5637acce1a 100644 --- a/packages/aws-cdk/test/api/exec.test.ts +++ b/packages/aws-cdk/test/api/exec.test.ts @@ -137,7 +137,7 @@ test('the application set in --app is executed', async () => { // GIVEN config.settings.set(['app'], 'cloud-executable'); mockSpawn({ - commandLine: ['cloud-executable'], + commandLine: 'cloud-executable', sideEffect: () => writeOutputAssembly(), }); @@ -149,7 +149,7 @@ test('the application set in --app is executed as-is if it contains a filename t // GIVEN config.settings.set(['app'], 'does-not-exist'); mockSpawn({ - commandLine: ['does-not-exist'], + commandLine: 'does-not-exist', sideEffect: () => writeOutputAssembly(), }); @@ -161,7 +161,7 @@ test('the application set in --app is executed with arguments', async () => { // GIVEN config.settings.set(['app'], 'cloud-executable an-arg'); mockSpawn({ - commandLine: ['cloud-executable', 'an-arg'], + commandLine: 'cloud-executable an-arg', sideEffect: () => writeOutputAssembly(), }); @@ -174,7 +174,7 @@ test('application set in --app as `*.js` always uses handler on windows', async sinon.stub(process, 'platform').value('win32'); config.settings.set(['app'], 'windows.js'); mockSpawn({ - commandLine: [process.execPath, 'windows.js'], + commandLine: process.execPath + ' windows.js', sideEffect: () => writeOutputAssembly(), }); @@ -186,7 +186,7 @@ test('application set in --app is `*.js` and executable', async () => { // GIVEN config.settings.set(['app'], 'executable-app.js'); mockSpawn({ - commandLine: ['executable-app.js'], + commandLine: 'executable-app.js', sideEffect: () => writeOutputAssembly(), }); @@ -194,6 +194,36 @@ test('application set in --app is `*.js` and executable', async () => { await execProgram(sdkProvider, config); }); +test('cli throws when the `build` script fails', async () => { + // GIVEN + config.settings.set(['build'], 'fake-command'); + mockSpawn({ + commandLine: 'fake-command', + exitCode: 127, + }); + + // WHEN + await expect(execProgram(sdkProvider, config)).rejects.toEqual(new Error('Subprocess exited with error 127')); +}, TEN_SECOND_TIMEOUT); + +test('cli does not throw when the `build` script succeeds', async () => { + // GIVEN + config.settings.set(['build'], 'real command'); + config.settings.set(['app'], 'executable-app.js'); + mockSpawn({ + commandLine: 'real command', // `build` key is not split on whitespace + exitCode: 0, + }, + { + commandLine: 'executable-app.js', + sideEffect: () => writeOutputAssembly(), + }); + + // WHEN + await execProgram(sdkProvider, config); +}, TEN_SECOND_TIMEOUT); + + function writeOutputAssembly() { const asm = testAssembly({ stacks: [], diff --git a/packages/aws-cdk/test/usersettings.test.ts b/packages/aws-cdk/test/usersettings.test.ts index 948b3b3f907bc..92d7db4a44025 100644 --- a/packages/aws-cdk/test/usersettings.test.ts +++ b/packages/aws-cdk/test/usersettings.test.ts @@ -69,4 +69,24 @@ test('load context from all 3 files if available', async () => { expect(config.context.get('project')).toBe('foobar'); expect(config.context.get('foo')).toBe('bar'); expect(config.context.get('test')).toBe('bar'); +}); + +test('throws an error if the `build` key is specified in the user config', async () => { + // GIVEN + const GIVEN_CONFIG: Map = new Map([ + [USER_CONFIG, { + build: 'foobar', + }], + ]); + + // WHEN + mockedFs.pathExists.mockImplementation(path => { + return GIVEN_CONFIG.has(path); + }); + mockedFs.readJSON.mockImplementation(path => { + return GIVEN_CONFIG.get(path); + }); + + // THEN + await expect(new Configuration().load()).rejects.toEqual(new Error('The `build` key cannot be specified in the user config (~/.cdk.json), specify it in the project config (cdk.json) instead')); }); \ No newline at end of file diff --git a/packages/aws-cdk/test/util/mock-child_process.ts b/packages/aws-cdk/test/util/mock-child_process.ts index 539fd06273399..d7645b4c2ce1a 100644 --- a/packages/aws-cdk/test/util/mock-child_process.ts +++ b/packages/aws-cdk/test/util/mock-child_process.ts @@ -6,16 +6,11 @@ if (!(child_process as any).spawn.mockImplementationOnce) { } export interface Invocation { - commandLine: string[]; + commandLine: string; cwd?: string; exitCode?: number; stdout?: string; - /** - * Only match a prefix of the command (don't care about the details of the arguments) - */ - prefix?: boolean; - /** * Run this function as a side effect, if present */ @@ -26,14 +21,8 @@ export function mockSpawn(...invocations: Invocation[]) { let mock = (child_process.spawn as any); for (const _invocation of invocations) { const invocation = _invocation; // Mirror into variable for closure - mock = mock.mockImplementationOnce((binary: string, args: string[], options: child_process.SpawnOptions) => { - if (invocation.prefix) { - // Match command line prefix - expect([binary, ...args].slice(0, invocation.commandLine.length)).toEqual(invocation.commandLine); - } else { - // Match full command line - expect([binary, ...args]).toEqual(invocation.commandLine); - } + mock = mock.mockImplementationOnce((binary: string, options: child_process.SpawnOptions) => { + expect(binary).toEqual(invocation.commandLine); if (invocation.cwd != null) { expect(options.cwd).toBe(invocation.cwd); @@ -60,8 +49,8 @@ export function mockSpawn(...invocations: Invocation[]) { }); } - mock.mockImplementation((binary: string, args: string[], _options: any) => { - throw new Error(`Did not expect call of ${JSON.stringify([binary, ...args])}`); + mock.mockImplementation((binary: string, _options: any) => { + throw new Error(`Did not expect call of ${binary}`); }); } From ea56e6925422ebb987dbd87952511f23832ac7b6 Mon Sep 17 00:00:00 2001 From: suds-sky <85171367+suds-sky@users.noreply.github.com> Date: Thu, 4 Nov 2021 20:09:13 +0000 Subject: [PATCH 44/70] feat(lambda-nodejs): add sourcesContent in BundlingOptions (#17280) Support excluding sourcesContent from `esbuild` generated source map Closes #17256 ---- *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/README.md | 1 + packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts | 2 ++ packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts | 9 +++++++++ .../@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts | 5 +++-- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-lambda-nodejs/README.md b/packages/@aws-cdk/aws-lambda-nodejs/README.md index 9bf47f0631d57..1d3eaa66a2a4a 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/README.md +++ b/packages/@aws-cdk/aws-lambda-nodejs/README.md @@ -174,6 +174,7 @@ new lambda.NodejsFunction(this, 'my-handler', { minify: true, // minify code, defaults to false sourceMap: true, // include source map, defaults to false sourceMapMode: SourceMapMode.INLINE, // defaults to SourceMapMode.DEFAULT + sourcesContent: false, // do not include original source into source map, defaults to true target: 'es2020', // target environment for the generated JavaScript code loader: { // Use the 'dataurl' loader for '.png' files '.png': 'dataurl', diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts index 3bd05a7ccb39d..5b7c6ce416b2c 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/bundling.ts @@ -182,6 +182,7 @@ export class Bundling implements cdk.BundlingOptions { const sourceMapEnabled = this.props.sourceMapMode ?? this.props.sourceMap; const sourceMapMode = this.props.sourceMapMode ?? SourceMapMode.DEFAULT; const sourceMapValue = sourceMapMode === SourceMapMode.DEFAULT ? '' : `=${this.props.sourceMapMode}`; + const sourcesContent = this.props.sourcesContent ?? true; const esbuildCommand: string[] = [ options.esbuildRunner, @@ -191,6 +192,7 @@ export class Bundling implements cdk.BundlingOptions { `--outfile="${pathJoin(options.outputDir, 'index.js')}"`, ...this.props.minify ? ['--minify'] : [], ...sourceMapEnabled ? [`--sourcemap${sourceMapValue}`] : [], + ...sourcesContent ? [] : [`--sources-content=${sourcesContent}`], ...this.externals.map(external => `--external:${external}`), ...loaders.map(([ext, name]) => `--loader:${ext}=${name}`), ...defines.map(([key, value]) => `--define:${key}=${JSON.stringify(value)}`), diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts index 55606f66b2507..87d3de0eec1fc 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/types.ts @@ -26,6 +26,15 @@ export interface BundlingOptions { */ readonly sourceMapMode?: SourceMapMode; + /** + * Whether to include original source code in source maps when bundling. + * + * @see https://esbuild.github.io/api/#sources-content + * + * @default true + */ + readonly sourcesContent?: boolean; + /** * Target environment for the generated JavaScript code. * 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 f4e974c08fdce..ae871b67cb69f 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts @@ -188,6 +188,7 @@ test('esbuild bundling with esbuild options', () => { architecture: Architecture.X86_64, minify: true, sourceMap: true, + sourcesContent: false, target: 'es2020', loader: { '.png': 'dataurl', @@ -218,7 +219,7 @@ test('esbuild bundling with esbuild options', () => { [ 'esbuild --bundle "/asset-input/lib/handler.ts"', '--target=es2020 --platform=node --outfile="/asset-output/index.js"', - '--minify --sourcemap --external:aws-sdk --loader:.png=dataurl', + '--minify --sourcemap --sources-content=false --external:aws-sdk --loader:.png=dataurl', defineInstructions, '--log-level=silent --keep-names --tsconfig=/asset-input/lib/custom-tsconfig.ts', '--metafile=/asset-output/index.meta.json --banner:js="/* comments */" --footer:js="/* comments */"', @@ -656,4 +657,4 @@ test('esbuild bundling with pre compilations and undefined tsconfig ( Should thr }); }).toThrow('Cannot find a tsconfig.json, please specify the prop: tsconfig'); -}); \ No newline at end of file +}); From b9c00f09d7f489e2dc53618bbc1e481b48e36533 Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Thu, 4 Nov 2021 23:28:01 +0200 Subject: [PATCH 45/70] chore: remove invalid test (#17337) --- .../test/integ/cli/bootstrapping.integtest.ts | 24 +------------------ 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts b/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts index d7716a2ac3e70..1298c77a5fca8 100644 --- a/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts +++ b/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts @@ -1,6 +1,6 @@ import * as fs from 'fs'; import * as path from 'path'; -import { MAJOR_VERSION, randomString, withDefaultFixture } from '../helpers/cdk'; +import { randomString, withDefaultFixture } from '../helpers/cdk'; import { integTest } from '../helpers/test-helpers'; const timeout = process.env.CODEBUILD_BUILD_ID ? // if the process is running in CodeBuild @@ -129,28 +129,6 @@ integTest('deploy old style synthesis to new style bootstrap', withDefaultFixtur }); })); -if (MAJOR_VERSION === '1') { - // For v2, the default bootstrap is the modern bootstrap, so this test is predicated on invalid - // assumptions. - - integTest('deploying new style synthesis to old style bootstrap fails', withDefaultFixture(async (fixture) => { - const bootstrapStackName = fixture.bootstrapStackName; - - await fixture.cdkBootstrapLegacy({ - toolkitStackName: bootstrapStackName, - }); - - // Deploy stack that uses file assets, this fails because the bootstrap stack - // is version checked. - await expect(fixture.cdkDeploy('lambda', { - options: [ - '--toolkit-stack-name', bootstrapStackName, - '--context', '@aws-cdk/core:newStyleStackSynthesis=1', - ], - })).rejects.toThrow('exited with error'); - })); -} - integTest('can create a legacy bootstrap stack with --public-access-block-configuration=false', withDefaultFixture(async (fixture) => { const bootstrapStackName = fixture.bootstrapStackName; From e412308bc81ede16b079077cfa4774ceaa2fadeb Mon Sep 17 00:00:00 2001 From: Tatsuya Yamamoto Date: Fri, 5 Nov 2021 07:51:11 +0900 Subject: [PATCH 46/70] feat(iot): allow setting `errorAction` of TopicRule (#17287) I'm trying to implement aws-iot L2 Constructs. This PR is one of steps after following PR: - https://github.com/aws/aws-cdk/pull/16681#issuecomment-942233029 ---- *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-iot/README.md | 18 +++++++++++++ packages/@aws-cdk/aws-iot/lib/topic-rule.ts | 8 ++++++ .../@aws-cdk/aws-iot/test/topic-rule.test.ts | 25 +++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/packages/@aws-cdk/aws-iot/README.md b/packages/@aws-cdk/aws-iot/README.md index 42ab651f26f81..402036b531dfc 100644 --- a/packages/@aws-cdk/aws-iot/README.md +++ b/packages/@aws-cdk/aws-iot/README.md @@ -75,6 +75,22 @@ const topicRule = new iot.TopicRule(this, 'TopicRule', { topicRule.addAction(new actions.LambdaFunctionAction(func)) ``` +You can also supply `errorAction` as following, +and the IoT Rule will trigger it if a rule's action is unable to perform: + +```ts +import * as iot from '@aws-cdk/aws-iot'; +import * as actions from '@aws-cdk/aws-iot-actions'; +import * as logs from '@aws-cdk/aws-logs'; + +const logGroup = new logs.LogGroup(this, 'MyLogGroup'); + +new iot.TopicRule(this, 'TopicRule', { + sql: iot.IotSql.fromStringAsVer20160323("SELECT topic(2) as device_id, timestamp() as timestamp FROM 'device/+/data'"), + errorAction: new actions.CloudWatchLogsAction(logGroup), +}); +``` + If you wanna make the topic rule disable, add property `enabled: false` as following: ```ts @@ -83,3 +99,5 @@ new iot.TopicRule(this, 'TopicRule', { enabled: false, }); ``` + +See also [@aws-cdk/aws-iot-actions](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-iot-actions-readme.html) for other actions. diff --git a/packages/@aws-cdk/aws-iot/lib/topic-rule.ts b/packages/@aws-cdk/aws-iot/lib/topic-rule.ts index 8860a611e4af3..89f40c3797d97 100644 --- a/packages/@aws-cdk/aws-iot/lib/topic-rule.ts +++ b/packages/@aws-cdk/aws-iot/lib/topic-rule.ts @@ -48,6 +48,13 @@ export interface TopicRuleProps { */ readonly description?: string; + /** + * The action AWS IoT performs when it is unable to perform a rule's action. + * + * @default - no action will be performed + */ + readonly errorAction?: IAction; + /** * Specifies whether the rule is enabled. * @@ -117,6 +124,7 @@ export class TopicRule extends Resource implements ITopicRule { actions: Lazy.any({ produce: () => this.actions }), awsIotSqlVersion: sqlConfig.awsIotSqlVersion, description: props.description, + errorAction: props.errorAction?.bind(this).configuration, ruleDisabled: props.enabled === undefined ? undefined : !props.enabled, sql: sqlConfig.sql, }, diff --git a/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts b/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts index 6e4a49c234e60..5f84201a37e5d 100644 --- a/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts +++ b/packages/@aws-cdk/aws-iot/test/topic-rule.test.ts @@ -233,6 +233,31 @@ test('cannot add an action that have multiple keys', () => { }).toThrow('An action property cannot have multiple keys, received: http,lambda'); }); +test('can set errorAction', () => { + const stack = new cdk.Stack(); + + const action: iot.IAction = { + bind: () => ({ + configuration: { + http: { url: 'http://example.com' }, + }, + }), + }; + + new iot.TopicRule(stack, 'MyTopicRule', { + errorAction: action, + sql: iot.IotSql.fromStringAsVer20151008("SELECT topic(2) as device_id, temperature FROM 'device/+/data'"), + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IoT::TopicRule', { + TopicRulePayload: { + ErrorAction: { + Http: { Url: 'http://example.com' }, + }, + }, + }); +}); + test('can import a TopicRule by ARN', () => { const stack = new cdk.Stack(); From c66ac89f43d3d2cee2b5842c54dc00e14ccdd2f4 Mon Sep 17 00:00:00 2001 From: Rayjan Wilson Date: Thu, 4 Nov 2021 19:46:39 -0400 Subject: [PATCH 47/70] feat(codepipeline): add construct for registering custom Actions (#17041) fixes #17039 all it does is add `./common` and `./custom-action-registration` to the modules `index.ts` ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-codepipeline-actions/lib/index.ts | 1 + .../lib/jenkins/jenkins-provider.ts | 3 +- packages/@aws-cdk/aws-codepipeline/README.md | 34 ++++++++++++++ .../lib/custom-action-registration.ts | 45 ++++++++++--------- .../@aws-cdk/aws-codepipeline/lib/index.ts | 1 + 5 files changed, 62 insertions(+), 22 deletions(-) rename packages/@aws-cdk/{aws-codepipeline-actions => aws-codepipeline}/lib/custom-action-registration.ts (76%) diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/index.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/index.ts index 254b2764f2684..e861161ab39c1 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/index.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/index.ts @@ -18,3 +18,4 @@ export * from './s3/source-action'; export * from './stepfunctions/invoke-action'; export * from './servicecatalog/deploy-action-beta1'; export * from './action'; + diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-provider.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-provider.ts index 923b1a1e39e7c..6e0d179859916 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-provider.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/jenkins/jenkins-provider.ts @@ -1,7 +1,6 @@ import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as cdk from '@aws-cdk/core'; import { Construct } from 'constructs'; -import { CustomActionRegistration } from '../custom-action-registration'; // 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 @@ -190,7 +189,7 @@ export class JenkinsProvider extends BaseJenkinsProvider { } private registerJenkinsCustomAction(id: string, category: codepipeline.ActionCategory) { - new CustomActionRegistration(this, id, { + new codepipeline.CustomActionRegistration(this, id, { category, artifactBounds: jenkinsArtifactsBounds, provider: this.providerName, diff --git a/packages/@aws-cdk/aws-codepipeline/README.md b/packages/@aws-cdk/aws-codepipeline/README.md index 23f86b9293e92..976c9932ca210 100644 --- a/packages/@aws-cdk/aws-codepipeline/README.md +++ b/packages/@aws-cdk/aws-codepipeline/README.md @@ -109,6 +109,40 @@ or you can use the `IStage.addAction()` method to mutate an existing Stage: sourceStage.addAction(someAction); ``` +## Custom Action Registration + +To make your own custom CodePipeline Action requires registering the action provider. Look to the `JenkinsProvider` in `@aws-cdk/aws-codepipeline-actions` for an implementation example. + +```ts +new codepipeline.CustomActionRegistration(this, 'GenericGitSourceProviderResource', { + category: codepipeline.ActionCategory.SOURCE, + artifactBounds: { minInputs: 0, maxInputs: 0, minOutputs: 1, maxOutputs: 1 }, + provider: 'GenericGitSource', + version: '1', + entityUrl: 'https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-create-custom-action.html', + executionUrl: 'https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-create-custom-action.html', + actionProperties: [ + { + name: 'Branch', + required: true, + key: false, + secret: false, + queryable: false, + description: 'Git branch to pull', + type: 'String', + }, + { + name: 'GitUrl', + required: true, + key: false, + secret: false, + queryable: false, + description: 'SSH git clone URL', + type: 'String', + }, + ] +``` + ## Cross-account CodePipelines > Cross-account Pipeline actions require that the Pipeline has *not* been diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/custom-action-registration.ts b/packages/@aws-cdk/aws-codepipeline/lib/custom-action-registration.ts similarity index 76% rename from packages/@aws-cdk/aws-codepipeline-actions/lib/custom-action-registration.ts rename to packages/@aws-cdk/aws-codepipeline/lib/custom-action-registration.ts index dad9e84a47094..f32a952a24d83 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/custom-action-registration.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/custom-action-registration.ts @@ -1,8 +1,10 @@ -import * as codepipeline from '@aws-cdk/aws-codepipeline'; +import { Construct } from 'constructs'; +import { ActionCategory, ActionArtifactBounds } from './action'; +import { CfnCustomActionType } from './codepipeline.generated'; // 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 -import { Construct } from '@aws-cdk/core'; +import { Construct as CoreConstruct } from '@aws-cdk/core'; /** * The creation attributes used for defining a configuration property @@ -13,14 +15,14 @@ export interface CustomActionProperty { * The name of the property. * You use this name in the `configuration` attribute when defining your custom Action class. */ - name: string; + readonly name: string; /** * The description of the property. * * @default the description will be empty */ - description?: string; + readonly description?: string; /** * Whether this property is a key. @@ -28,7 +30,7 @@ export interface CustomActionProperty { * @default false * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codepipeline-customactiontype-configurationproperties.html#cfn-codepipeline-customactiontype-configurationproperties-key */ - key?: boolean; + readonly key?: boolean; /** * Whether this property is queryable. @@ -37,12 +39,12 @@ export interface CustomActionProperty { * @default false * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codepipeline-customactiontype-configurationproperties.html#cfn-codepipeline-customactiontype-configurationproperties-queryable */ - queryable?: boolean; + readonly queryable?: boolean; /** * Whether this property is required. */ - required: boolean; + readonly required: boolean; /** * Whether this property is secret, @@ -50,7 +52,7 @@ export interface CustomActionProperty { * * @default false */ - secret?: boolean; + readonly secret?: boolean; /** * The type of the property, @@ -58,7 +60,7 @@ export interface CustomActionProperty { * * @default 'String' */ - type?: string; + readonly type?: string; } /** @@ -68,41 +70,44 @@ export interface CustomActionRegistrationProps { /** * The category of the Action. */ - category: codepipeline.ActionCategory; + readonly category: ActionCategory; /** * The artifact bounds of the Action. */ - artifactBounds: codepipeline.ActionArtifactBounds; + readonly artifactBounds: ActionArtifactBounds; /** * The provider of the Action. + * @example 'MyCustomActionProvider' */ - provider: string; + readonly provider: string; /** * The version of your Action. * * @default '1' */ - version?: string; + readonly version?: string; /** * The URL shown for the entire Action in the Pipeline UI. + * @default none */ - entityUrl?: string; + readonly entityUrl?: string; /** * The URL shown for a particular execution of an Action in the Pipeline UI. + * @default none */ - executionUrl?: string; + readonly executionUrl?: string; /** * The properties used for customizing the instance of your Action. * * @default [] */ - actionProperties?: CustomActionProperty[]; + readonly actionProperties?: CustomActionProperty[]; } /** @@ -112,11 +117,11 @@ export interface CustomActionRegistrationProps { * representing your custom Action, extending the Action class, * and taking the `actionProperties` as properly typed, construction properties. */ -export class CustomActionRegistration extends Construct { - constructor(parent: Construct, id: string, props: CustomActionRegistrationProps) { - super(parent, id); +export class CustomActionRegistration extends CoreConstruct { + constructor(scope: Construct, id: string, props: CustomActionRegistrationProps) { + super(scope, id); - new codepipeline.CfnCustomActionType(this, 'Resource', { + new CfnCustomActionType(this, 'Resource', { category: props.category, inputArtifactDetails: { minimumCount: props.artifactBounds.minInputs, diff --git a/packages/@aws-cdk/aws-codepipeline/lib/index.ts b/packages/@aws-cdk/aws-codepipeline/lib/index.ts index c62d8dda6b33f..81b855f904184 100644 --- a/packages/@aws-cdk/aws-codepipeline/lib/index.ts +++ b/packages/@aws-cdk/aws-codepipeline/lib/index.ts @@ -1,6 +1,7 @@ export * from './action'; export * from './artifact'; export * from './pipeline'; +export * from './custom-action-registration'; // AWS::CodePipeline CloudFormation Resources: export * from './codepipeline.generated'; From 7bbd10deb322daf8ef1504ceb84ad3c895f291ae Mon Sep 17 00:00:00 2001 From: Ryan Parker Date: Thu, 4 Nov 2021 17:42:07 -0700 Subject: [PATCH 48/70] fix(aws-eks): proxy support and allow assigning a security group to all cluster handler functions (#17200) ## Summary This PR is intended for CDK EKS users who require all traffic to be routed through a proxy. Currently if a user does not allow internet connections to the VPC without going through a proxy, then deploying an EKS cluster will result in a timeout error: ```sh Received response status [FAILED] from custom resource. Message returned: Error: 2021-10-20T14:20:47.028Z d86e3ef4-45ce-4130-988f-c4663f7f8c80 Task timed out after 60.06 seconds ``` Fixes: https://github.com/aws/aws-cdk/issues/12469, SIM D29159517 Related to but does not resolve: `https://github.com/aws/aws-cdk/issues/12171` ## :gear: Changes _Expand each list item for additional details._
Corrected "Cluster Handler" docs to clarify that 2 lambdas are created (onEventHandler, isCompleteHandler)
Our docs [currently describe the "Cluster Handler" as one Lambda function that interacts with the EKS API](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-eks-readme.html#cluster-handler). However this is not accurate. The "Cluster Handler" actually creates [two Lambdas](https://github.com/aws/aws-cdk/blob/0cabb9f2d2f50c03337cd6f35bf47fc54ada3a21/packages/%40aws-cdk/aws-eks/lib/cluster-resource-provider.ts#L69-L96) for the Custom Resource, `onEventHandler` and `isCompleteHandler`, both interact with the AWS API.
Passes the clusterHandlerEnvironment to both Cluster Handler Lambdas
The `clusterHandlerEnvironment` is the [recommended method](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-eks-readme.html#cluster-handler) of passing a proxy url (i.g. `http_proxy: 'http://my-proxy.com:3128'`) to the Cluster Handler. Currently the `clusterHandlerEnvironment` is only passed to the Cluster Handler's `onEventHandler` Lambda. [The `onEventHandler` was believed to be the only Cluster Handler Lambda that interacts with the AWS EKS API](https://github.com/aws/aws-cdk/issues/12469#issuecomment-758674418), however this is not entirely true. Both the `onEventHandler` and `isCompleteHandler` call the AWS EKS API. Following the execution process of `isCompleteHandler` when creating an EKS cluster: 1. [`index.isComplete()` (this is the Lambda handler)](https://github.com/aws/aws-cdk/blob/0cabb9f2d2f50c03337cd6f35bf47fc54ada3a21/packages/%40aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts#L48) 2. [`common.isComplete()`](https://github.com/aws/aws-cdk/blob/0cabb9f2d2f50c03337cd6f35bf47fc54ada3a21/packages/%40aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts#L59) 3. [`cluster.isCreateComplete()`](https://github.com/aws/aws-cdk/blob/0cabb9f2d2f50c03337cd6f35bf47fc54ada3a21/packages/%40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L56) 4. [`cluster.isActive()`](https://github.com/aws/aws-cdk/blob/0cabb9f2d2f50c03337cd6f35bf47fc54ada3a21/packages/%40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L196) 5. [Request to EKS API](https://github.com/aws/aws-cdk/blob/0cabb9f2d2f50c03337cd6f35bf47fc54ada3a21/packages/%40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L198) (results in timeout because proxy is not used) This change allows the user to pass proxy urls as environment variables to **both** Lambdas using `clusterHandlerEnvironment`.
Renames the prop onEventLayer -> proxyAgentLayer, and provides the layer to both Cluster Handler Lambdas
The proxy-agent layer is now used in both `onEventHandler` and `isCompleteHandler` lambdas in order to support proxy configurations. Because of this change, i've deprecated the original `onEventLayer` and created a new prop `proxyAgentLayer` since we will now be passing this prop into more than just the `onEventHandler` Lambda. The `onEventLayer` prop was introduced [a few weeks ago (sept 24)](https://github.com/aws/aws-cdk/pull/16657) so it should not impact many users (if any). The prop would only be used if the user wishes to bundle the layer themselves with a custom proxy agent. This prop follows the [same user customization we allow with the kubectl handler](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-eks.Cluster.html#kubectllayer). Another suitable name for this prop could have been `clusterHandlerLayer` but I chose `proxyAgentLayer` because it represents **what** the layer is used for, instead of describing **where** it's used. This also follows the convention of the pre-existing [`kubectlLayer` prop](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-eks.Cluster.html#kubectllayer).
Adds the EKS cluster prop clusterHandlerSecurityGroup
If a proxy address is provided to the Cluster Handler Lambdas, but the proxy instance is not open to the world, then the dynamic IPs of the Cluster Handler Lambdas will be denied access. To solve this, i've implemented a new Cluster prop `clusterHandlerSecurityGroup`. This `clusterHandlerSecurityGroup` prop will allow the user to pass a Security Group to both Lambda functions and the Custom Resource provider. This is very similar to how we [already allow users to pass Security Groups to the Kubectl Handler](https://github.com/aws/aws-cdk/blob/7f194000697b85deb410ae0d7f7d4ac3c2654bcc/packages/%40aws-cdk/aws-eks/lib/kubectl-provider.ts#L83)
---- *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-eks/README.md | 17 ++-- .../lib/cluster-resource-handler/common.ts | 6 -- .../lib/cluster-resource-handler/index.ts | 6 ++ .../aws-eks/lib/cluster-resource-provider.ts | 33 ++++--- .../@aws-cdk/aws-eks/lib/cluster-resource.ts | 2 + packages/@aws-cdk/aws-eks/lib/cluster.ts | 96 ++++++++++++++----- packages/@aws-cdk/aws-eks/package.json | 2 - .../@aws-cdk/aws-eks/test/cluster.test.ts | 34 +++++++ 8 files changed, 145 insertions(+), 51 deletions(-) diff --git a/packages/@aws-cdk/aws-eks/README.md b/packages/@aws-cdk/aws-eks/README.md index cd6e324ecf788..e1d78b774450d 100644 --- a/packages/@aws-cdk/aws-eks/README.md +++ b/packages/@aws-cdk/aws-eks/README.md @@ -102,8 +102,8 @@ The following is a qualitative diagram of the various possible components involv ```text +-----------------------------------------------+ +-----------------+ - | EKS Cluster | kubectl | | - |-----------------------------------------------|<-------------+| Kubectl Handler | + | EKS Cluster | kubectl | | + | ----------- |<-------------+| Kubectl Handler | | | | | | | +-----------------+ | +--------------------+ +-----------------+ | @@ -539,16 +539,21 @@ If the endpoint does not expose private access (via `EndpointAccess.PUBLIC`) **o #### Cluster Handler -The `ClusterHandler` is a Lambda function responsible to interact with the EKS API in order to control the cluster lifecycle. To provision this function inside the VPC, set the `placeClusterHandlerInVpc` property to `true`. This will place the function inside the private subnets of the VPC based on the selection strategy specified in the [`vpcSubnets`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-eks.Cluster.html#vpcsubnetsspan-classapi-icon-api-icon-experimental-titlethis-api-element-is-experimental-it-may-change-without-noticespan) property. +The `ClusterHandler` is a set of Lambda functions (`onEventHandler`, `isCompleteHandler`) responsible for interacting with the EKS API in order to control the cluster lifecycle. To provision these functions inside the VPC, set the `placeClusterHandlerInVpc` property to `true`. This will place the functions inside the private subnets of the VPC based on the selection strategy specified in the [`vpcSubnets`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-eks.Cluster.html#vpcsubnetsspan-classapi-icon-api-icon-experimental-titlethis-api-element-is-experimental-it-may-change-without-noticespan) property. -You can configure the environment of this function by specifying it at cluster instantiation. For example, this can be useful in order to configure an http proxy: +You can configure the environment of the Cluster Handler functions by specifying it at cluster instantiation. For example, this can be useful in order to configure an http proxy: ```ts const cluster = new eks.Cluster(this, 'hello-eks', { version: eks.KubernetesVersion.V1_21, clusterHandlerEnvironment: { - 'http_proxy': 'http://proxy.myproxy.com' - } + https_proxy: 'http://proxy.myproxy.com' + }, + /** + * If the proxy is not open publicly, you can pass a security group to the + * Cluster Handler Lambdas so that it can reach the proxy. + */ + clusterHandlerSecurityGroup: proxyInstanceSecurityGroup }); ``` diff --git a/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts b/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts index 8f563de833bf6..21cf958df5a68 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts @@ -41,12 +41,6 @@ export abstract class ResourceHandler { } public onEvent() { - // eslint-disable-next-line @typescript-eslint/no-require-imports, import/no-extraneous-dependencies - const ProxyAgent: any = require('proxy-agent'); - aws.config.update({ - httpOptions: { agent: new ProxyAgent() }, - }); - switch (this.requestType) { case 'Create': return this.onCreate(); case 'Update': return this.onUpdate(); diff --git a/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts b/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts index e7fc357846259..258f5d8b04545 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts @@ -8,7 +8,13 @@ import { EksClient } from './common'; import * as consts from './consts'; import { FargateProfileResourceHandler } from './fargate'; +// eslint-disable-next-line @typescript-eslint/no-require-imports, import/no-extraneous-dependencies +const ProxyAgent = require('proxy-agent'); + aws.config.logger = console; +aws.config.update({ + httpOptions: { agent: new ProxyAgent() }, +}); let eks: aws.EKS | undefined; diff --git a/packages/@aws-cdk/aws-eks/lib/cluster-resource-provider.ts b/packages/@aws-cdk/aws-eks/lib/cluster-resource-provider.ts index f425b0a1eaba6..9bb65be4f56b2 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster-resource-provider.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster-resource-provider.ts @@ -36,11 +36,18 @@ export interface ClusterResourceProviderProps { readonly environment?: { [key: string]: string }; /** - * An AWS Lambda layer that includes the NPM dependency `proxy-agent`. - * - * If not defined, a default layer will be used. - */ + * An AWS Lambda layer that includes the NPM dependency `proxy-agent`. + * + * If not defined, a default layer will be used. + */ readonly onEventLayer?: lambda.ILayerVersion; + + /** + * The security group to associate with the functions. + * + * @default - No security group. + */ + readonly securityGroup?: ec2.ISecurityGroup; } /** @@ -66,6 +73,9 @@ export class ClusterResourceProvider extends NestedStack { private constructor(scope: Construct, id: string, props: ClusterResourceProviderProps) { super(scope as CoreConstruct, id); + // The NPM dependency proxy-agent is required in order to support proxy routing with the AWS JS SDK. + const nodeProxyAgentLayer = new NodeProxyAgentLayer(this, 'NodeProxyAgentLayer'); + const onEvent = new lambda.Function(this, 'OnEventHandler', { code: lambda.Code.fromAsset(HANDLER_DIR), description: 'onEvent handler for EKS cluster resource provider', @@ -75,24 +85,22 @@ export class ClusterResourceProvider extends NestedStack { timeout: Duration.minutes(1), vpc: props.subnets ? props.vpc : undefined, vpcSubnets: props.subnets ? { subnets: props.subnets } : undefined, + securityGroups: props.securityGroup ? [props.securityGroup] : undefined, + // Allow user to override the layer. + layers: props.onEventLayer ? [props.onEventLayer] : [nodeProxyAgentLayer], }); - // Allow user to customize the layer - if (!props.onEventLayer) { - // `NodeProxyAgentLayer` provides `proxy-agent` which is needed to configure `aws-sdk-js` with a user provided proxy. - onEvent.addLayers(new NodeProxyAgentLayer(this, 'NodeProxyAgentLayer')); - } else { - onEvent.addLayers(props.onEventLayer); - } - const isComplete = new lambda.Function(this, 'IsCompleteHandler', { code: lambda.Code.fromAsset(HANDLER_DIR), description: 'isComplete handler for EKS cluster resource provider', runtime: HANDLER_RUNTIME, + environment: props.environment, handler: 'index.isComplete', timeout: Duration.minutes(1), vpc: props.subnets ? props.vpc : undefined, vpcSubnets: props.subnets ? { subnets: props.subnets } : undefined, + securityGroups: props.securityGroup ? [props.securityGroup] : undefined, + layers: [nodeProxyAgentLayer], }); this.provider = new cr.Provider(this, 'Provider', { @@ -102,6 +110,7 @@ export class ClusterResourceProvider extends NestedStack { queryInterval: Duration.minutes(1), vpc: props.subnets ? props.vpc : undefined, vpcSubnets: props.subnets ? { subnets: props.subnets } : undefined, + securityGroups: props.securityGroup ? [props.securityGroup] : undefined, }); props.adminRole.grant(onEvent.role!, 'sts:AssumeRole'); diff --git a/packages/@aws-cdk/aws-eks/lib/cluster-resource.ts b/packages/@aws-cdk/aws-eks/lib/cluster-resource.ts index 88f3cd0138344..ed0852338a527 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster-resource.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster-resource.ts @@ -27,6 +27,7 @@ export interface ClusterResourceProps { readonly subnets?: ec2.ISubnet[]; readonly secretsEncryptionKey?: kms.IKey; readonly onEventLayer?: lambda.ILayerVersion; + readonly clusterHandlerSecurityGroup?: ec2.ISecurityGroup; } /** @@ -66,6 +67,7 @@ export class ClusterResource extends CoreConstruct { vpc: props.vpc, environment: props.environment, onEventLayer: props.onEventLayer, + securityGroup: props.clusterHandlerSecurityGroup, }); const resource = new CustomResource(this, 'Resource', { diff --git a/packages/@aws-cdk/aws-eks/lib/cluster.ts b/packages/@aws-cdk/aws-eks/lib/cluster.ts index c1d00a9dcd767..2c762ab666327 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster.ts @@ -130,10 +130,21 @@ export interface ICluster extends IResource, ec2.IConnectable { readonly kubectlMemory?: Size; /** - * An AWS Lambda layer that includes the NPM dependency `proxy-agent`. - * - * If not defined, a default layer will be used. - */ + * A security group to associate with the Cluster Handler's Lambdas. + * The Cluster Handler's Lambdas are responsible for calling AWS's EKS API. + * + * Requires `placeClusterHandlerInVpc` to be set to true. + * + * @default - No security group. + * @attribute + */ + readonly clusterHandlerSecurityGroup?: ec2.ISecurityGroup; + + /** + * An AWS Lambda layer that includes the NPM dependency `proxy-agent`. + * + * If not defined, a default layer will be used. + */ readonly onEventLayer?: lambda.ILayerVersion; /** @@ -309,6 +320,14 @@ export interface ClusterAttributes { */ readonly kubectlMemory?: Size; + /** + * A security group id to associate with the Cluster Handler's Lambdas. + * The Cluster Handler's Lambdas are responsible for calling AWS's EKS API. + * + * @default - No security group. + */ + readonly clusterHandlerSecurityGroupId?: string; + /** * An AWS Lambda Layer which includes the NPM dependency `proxy-agent`. This layer * is used by the onEvent handler to route AWS SDK requests through a proxy. @@ -452,13 +471,6 @@ export interface ClusterOptions extends CommonClusterOptions { */ readonly kubectlEnvironment?: { [key: string]: string }; - /** - * Custom environment variables when interacting with the EKS endpoint to manage the cluster lifecycle. - * - * @default - No environment variables. - */ - readonly clusterHandlerEnvironment?: { [key: string]: string }; - /** * An AWS Lambda Layer which includes `kubectl`, Helm and the AWS CLI. * @@ -491,26 +503,40 @@ export interface ClusterOptions extends CommonClusterOptions { readonly kubectlMemory?: Size; /** - * An AWS Lambda Layer which includes the NPM dependency `proxy-agent`. + * Custom environment variables when interacting with the EKS endpoint to manage the cluster lifecycle. + * + * @default - No environment variables. + */ + readonly clusterHandlerEnvironment?: { [key: string]: string }; + + /** + * A security group to associate with the Cluster Handler's Lambdas. + * The Cluster Handler's Lambdas are responsible for calling AWS's EKS API. + * + * Requires `placeClusterHandlerInVpc` to be set to true. + * + * @default - No security group. + */ + readonly clusterHandlerSecurityGroup?: ec2.ISecurityGroup; + + /** + * An AWS Lambda Layer which includes the NPM dependency `proxy-agent`. This layer + * is used by the onEvent handler to route AWS SDK requests through a proxy. * * By default, the provider will use the layer included in the * "aws-lambda-layer-node-proxy-agent" SAR application which is available in all * commercial regions. * - * To deploy the layer locally, visit - * https://github.com/aws-samples/aws-lambda-layer-node-proxy-agent/blob/master/cdk/README.md - * for instructions on how to prepare the .zip file and then define it in your - * app as follows: + * To deploy the layer locally define it in your app as follows: * * ```ts - * const layer = new lambda.LayerVersion(this, 'node-proxy-agent-layer', { + * const layer = new lambda.LayerVersion(this, 'proxy-agent-layer', { * code: lambda.Code.fromAsset(`${__dirname}/layer.zip`)), - * compatibleRuntimes: [lambda.Runtime.NODEJS_14_X] + * compatibleRuntimes: [lambda.Runtime.NODEJS_12_X] * }) * ``` * - * @default - the layer provided by the `aws-lambda-layer-node-proxy-agent` SAR app. - * @see https://github.com/aws-samples/aws-lambda-layer-node-proxy-agent + * @default - a layer bundled with this module. */ readonly onEventLayer?: lambda.ILayerVersion; @@ -749,6 +775,7 @@ abstract class ClusterBase extends Resource implements ICluster { public abstract readonly kubectlSecurityGroup?: ec2.ISecurityGroup; public abstract readonly kubectlPrivateSubnets?: ec2.ISubnet[]; public abstract readonly kubectlMemory?: Size; + public abstract readonly clusterHandlerSecurityGroup?: ec2.ISecurityGroup; public abstract readonly prune: boolean; public abstract readonly openIdConnectProvider: iam.IOpenIdConnectProvider; public abstract readonly awsAuth: AwsAuth; @@ -902,7 +929,7 @@ abstract class ClusterBase extends Resource implements ICluster { // cluster or if `mapRole` is set to false. By default this should happen. let mapRole = options.mapRole ?? true; if (mapRole && !(this instanceof Cluster)) { - // do the mapping... + // do the mapping... Annotations.of(autoScalingGroup).addWarning('Auto-mapping aws-auth role for imported cluster is not supported, please map role manually'); mapRole = false; } @@ -1099,11 +1126,21 @@ export class Cluster extends ClusterBase { */ public readonly kubectlMemory?: Size; + /** + * A security group to associate with the Cluster Handler's Lambdas. + * The Cluster Handler's Lambdas are responsible for calling AWS's EKS API. + * + * Requires `placeClusterHandlerInVpc` to be set to true. + * + * @default - No security group. + */ + public readonly clusterHandlerSecurityGroup?: ec2.ISecurityGroup; + /** * The AWS Lambda layer that contains the NPM dependency `proxy-agent`. If * undefined, a SAR app that contains this layer will be used. */ - public readonly onEventLayer?: lambda.ILayerVersion; + readonly onEventLayer?: lambda.ILayerVersion; /** * Determines if Kubernetes resources can be pruned automatically. @@ -1188,9 +1225,11 @@ export class Cluster extends ClusterBase { this.endpointAccess = props.endpointAccess ?? EndpointAccess.PUBLIC_AND_PRIVATE; this.kubectlEnvironment = props.kubectlEnvironment; this.kubectlLayer = props.kubectlLayer; - this.onEventLayer = props.onEventLayer; this.kubectlMemory = props.kubectlMemory; + this.onEventLayer = props.onEventLayer; + this.clusterHandlerSecurityGroup = props.clusterHandlerSecurityGroup; + const privateSubnets = this.selectPrivateSubnets().slice(0, 16); const publicAccessDisabled = !this.endpointAccess._config.publicAccess; const publicAccessRestricted = !publicAccessDisabled @@ -1215,6 +1254,10 @@ export class Cluster extends ClusterBase { throw new Error('Cannot place cluster handler in the VPC since no private subnets could be selected'); } + if (props.clusterHandlerSecurityGroup && !placeClusterHandlerInVpc) { + throw new Error('Cannot specify clusterHandlerSecurityGroup without placeClusterHandlerInVpc set to true'); + } + const resource = this._clusterResource = new ClusterResource(this, 'Resource', { name: this.physicalName, environment: props.clusterHandlerEnvironment, @@ -1241,6 +1284,7 @@ export class Cluster extends ClusterBase { secretsEncryptionKey: props.secretsEncryptionKey, vpc: this.vpc, subnets: placeClusterHandlerInVpc ? privateSubnets : undefined, + clusterHandlerSecurityGroup: this.clusterHandlerSecurityGroup, onEventLayer: this.onEventLayer, }); @@ -1827,8 +1871,9 @@ class ImportedCluster extends ClusterBase { public readonly kubectlSecurityGroup?: ec2.ISecurityGroup | undefined; public readonly kubectlPrivateSubnets?: ec2.ISubnet[] | undefined; public readonly kubectlLayer?: lambda.ILayerVersion; - public readonly onEventLayer?: lambda.ILayerVersion; public readonly kubectlMemory?: Size; + public readonly clusterHandlerSecurityGroup?: ec2.ISecurityGroup | undefined; + public readonly onEventLayer?: lambda.ILayerVersion; public readonly prune: boolean; // so that `clusterSecurityGroup` on `ICluster` can be configured without optionality, avoiding users from having @@ -1845,8 +1890,9 @@ class ImportedCluster extends ClusterBase { this.kubectlEnvironment = props.kubectlEnvironment; this.kubectlPrivateSubnets = props.kubectlPrivateSubnetIds ? props.kubectlPrivateSubnetIds.map((subnetid, index) => ec2.Subnet.fromSubnetId(this, `KubectlSubnet${index}`, subnetid)) : undefined; this.kubectlLayer = props.kubectlLayer; - this.onEventLayer = props.onEventLayer; this.kubectlMemory = props.kubectlMemory; + this.clusterHandlerSecurityGroup = props.clusterHandlerSecurityGroupId ? ec2.SecurityGroup.fromSecurityGroupId(this, 'ClusterHandlerSecurityGroup', props.clusterHandlerSecurityGroupId) : undefined; + this.onEventLayer = props.onEventLayer; this.prune = props.prune ?? true; let i = 1; diff --git a/packages/@aws-cdk/aws-eks/package.json b/packages/@aws-cdk/aws-eks/package.json index e5c7869f9bc13..35db07123cae8 100644 --- a/packages/@aws-cdk/aws-eks/package.json +++ b/packages/@aws-cdk/aws-eks/package.json @@ -93,7 +93,6 @@ "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kms": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", - "@aws-cdk/aws-lambda-nodejs": "0.0.0", "@aws-cdk/aws-ssm": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/custom-resources": "0.0.0", @@ -113,7 +112,6 @@ "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kms": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", - "@aws-cdk/aws-lambda-nodejs": "0.0.0", "@aws-cdk/aws-ssm": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/custom-resources": "0.0.0", diff --git a/packages/@aws-cdk/aws-eks/test/cluster.test.ts b/packages/@aws-cdk/aws-eks/test/cluster.test.ts index 295092509ffd2..63a17d9c5d64d 100644 --- a/packages/@aws-cdk/aws-eks/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-eks/test/cluster.test.ts @@ -38,6 +38,25 @@ describe('cluster', () => { expect(template.Resources.OnEventHandler42BEBAE0.Properties.Environment).toEqual({ Variables: { foo: 'bar' } }); }); + test('can specify security group to cluster resource handler', () => { + const { stack, vpc } = testFixture(); + const securityGroup = new ec2.SecurityGroup(stack, 'ProxyInstanceSG', { + vpc, + allowAllOutbound: false, + }); + + new eks.Cluster(stack, 'Cluster', { + version: CLUSTER_VERSION, + placeClusterHandlerInVpc: true, + clusterHandlerSecurityGroup: securityGroup, + }); + + const nested = stack.node.tryFindChild('@aws-cdk/aws-eks.ClusterResourceProvider') as cdk.NestedStack; + + const template = SynthUtils.toCloudFormation(nested); + expect(template.Resources.OnEventHandler42BEBAE0.Properties.VpcConfig.SecurityGroupIds).toEqual([{ Ref: 'referencetoStackProxyInstanceSG80B79D87GroupId' }]); + }); + test('throws when trying to place cluster handlers in a vpc with no private subnets', () => { const { stack } = testFixture(); @@ -55,6 +74,21 @@ describe('cluster', () => { }); + test('throws when provided `clusterHandlerSecurityGroup` without `placeClusterHandlerInVpc: true`', () => { + const { stack, vpc } = testFixture(); + const securityGroup = new ec2.SecurityGroup(stack, 'ProxyInstanceSG', { + vpc, + allowAllOutbound: false, + }); + + expect(() => { + new eks.Cluster(stack, 'Cluster', { + version: CLUSTER_VERSION, + clusterHandlerSecurityGroup: securityGroup, + }); + }).toThrow(/Cannot specify clusterHandlerSecurityGroup without placeClusterHandlerInVpc set to true/); + }); + describe('imported Vpc from unparseable list tokens', () => { let stack: cdk.Stack; let vpc: ec2.IVpc; From 0adc8b7e13011956929fc945e083f75edec16698 Mon Sep 17 00:00:00 2001 From: Adam Ruka Date: Thu, 4 Nov 2021 19:33:59 -0700 Subject: [PATCH 49/70] feat(cli): introduce the 'watch' command (#17240) This PR introduces the "watch" command, in two variants: as a separate new `cdk watch` command, and as an argument to the existing `cdk deploy` command. The "watch" process will observe the project files, defined by the new `"include"` and `"exclude"` settings in `cdk.json` (see https://github.com/aws/aws-cdk-rfcs/pull/383 for details), and will trigger a `cdk deploy` when it detects any changes. The deployment will by default use the new "hotswap" deployments for maximum speed. Since `cdk deploy` is a relatively slow process for a "watch" command, there is some logic to perform intelligent queuing of any file events that happen while `cdk deploy` is running. We will batch all of those events, and trigger a single `cdk deploy` after the current one finishes. This ensures only a single `cdk deploy` command ever executes at a time. The observing of the files, and reacting to their changes, is accomplished using the [`chokidar` library](https://www.npmjs.com/package/chokidar). ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/README.md | 63 ++++++ packages/aws-cdk/bin/cdk.ts | 59 +++++ .../lib/api/cloudformation-deployments.ts | 2 +- .../aws-cdk/lib/api/cxapp/cloud-executable.ts | 10 +- packages/aws-cdk/lib/api/deploy-stack.ts | 2 +- packages/aws-cdk/lib/cdk-toolkit.ts | 214 ++++++++++++++---- packages/aws-cdk/package.json | 1 + packages/aws-cdk/test/cdk-toolkit.test.ts | 190 ++++++++++++++++ yarn.lock | 48 +++- 9 files changed, 535 insertions(+), 54 deletions(-) diff --git a/packages/aws-cdk/README.md b/packages/aws-cdk/README.md index 0a2270b08fc90..1bd9e491e34e4 100644 --- a/packages/aws-cdk/README.md +++ b/packages/aws-cdk/README.md @@ -372,6 +372,69 @@ For this reason, only use it for development purposes. **⚠ Note #2**: This command is considered experimental, and might have breaking changes in the future. +### `cdk watch` + +The `watch` command is similar to `deploy`, +but instead of being a one-shot operation, +the command continuously monitors the files of the project, +and triggers a deployment whenever it detects any changes: + +```console +$ cdk watch DevelopmentStack +Detected change to 'lambda-code/index.js' (type: change). Triggering 'cdk deploy' +DevelopmentStack: deploying... + + ✅ DevelopmentStack + +^C +``` + +To end a `cdk watch` session, interrupt the process by pressing Ctrl+C. + +What files are observed is determined by the `"watch"` setting in your `cdk.json` file. +It has two sub-keys, `"include"` and `"exclude"`, each of which can be either a single string, or an array of strings. +Each entry is interpreted as a path relative to the location of the `cdk.json` file. +Globs, both `*` and `**`, are allowed to be used. +Example: + +```json +{ + "app": "mvn -e -q compile exec:java", + "watch": { + "include": "src/main/**", + "exclude": "target/*" + } +} +``` + +The default for `"include"` is `"**/*"` +(which means all files and directories in the root of the project), +and `"exclude"` is optional +(note that we always ignore files and directories starting with `.`, +the CDK output directory, and the `node_modules` directory), +so the minimal settings to enable `watch` are `"watch": {}`. + +If either your CDK code, or application code, needs a build step before being deployed, +`watch` works with the `"build"` key in the `cdk.json` file, +for example: + +```json +{ + "app": "mvn -e -q exec:java", + "build": "mvn package", + "watch": { + "include": "src/main/**", + "exclude": "target/*" + } +} +``` + +Note that `watch` by default uses hotswap deployments (see above for details) -- +to turn them off, pass the `--no-hotswap` option when invoking it. + +**Note**: This command is considered experimental, +and might have breaking changes in the future. + ### `cdk destroy` Deletes a stack from it's environment. This will cause the resources in the stack to be destroyed (unless they were diff --git a/packages/aws-cdk/bin/cdk.ts b/packages/aws-cdk/bin/cdk.ts index b5b60f895c8ca..a938b00f3c02f 100644 --- a/packages/aws-cdk/bin/cdk.ts +++ b/packages/aws-cdk/bin/cdk.ts @@ -118,6 +118,45 @@ async function parseCommandLineArguments() { 'which skips CloudFormation and updates the resources directly, ' + 'and falls back to a full deployment if that is not possible. ' + 'Do not use this in production environments', + }) + .option('watch', { + type: 'boolean', + desc: 'Continuously observe the project files, ' + + 'and deploy the given stack(s) automatically when changes are detected. ' + + 'Implies --hotswap by default', + }), + ) + .command('watch [STACKS..]', "Shortcut for 'deploy --watch'", yargs => yargs + // I'm fairly certain none of these options, present for 'deploy', make sense for 'watch': + // .option('all', { type: 'boolean', default: false, desc: 'Deploy all available stacks' }) + // .option('ci', { type: 'boolean', desc: 'Force CI detection', default: process.env.CI !== undefined }) + // @deprecated(v2) -- tags are part of the Cloud Assembly and tags specified here will be overwritten on the next deployment + // .option('tags', { type: 'array', alias: 't', desc: 'Tags to add to the stack (KEY=VALUE), overrides tags from Cloud Assembly (deprecated)', nargs: 1, requiresArg: true }) + // .option('execute', { type: 'boolean', desc: 'Whether to execute ChangeSet (--no-execute will NOT execute the ChangeSet)', default: true }) + // These options, however, are more subtle - I could be convinced some of these should also be available for 'watch': + // .option('require-approval', { type: 'string', choices: [RequireApproval.Never, RequireApproval.AnyChange, RequireApproval.Broadening], desc: 'What security-sensitive changes need manual approval' }) + // .option('parameters', { type: 'array', desc: 'Additional parameters passed to CloudFormation at deploy time (STACK:KEY=VALUE)', nargs: 1, requiresArg: true, default: {} }) + // .option('previous-parameters', { type: 'boolean', default: true, desc: 'Use previous values for existing parameters (you must specify all parameters on every deployment if this is disabled)' }) + // .option('outputs-file', { type: 'string', alias: 'O', desc: 'Path to file where stack outputs will be written as JSON', requiresArg: true }) + // .option('notification-arns', { type: 'array', desc: 'ARNs of SNS topics that CloudFormation will notify with stack related events', nargs: 1, requiresArg: true }) + .option('build-exclude', { type: 'array', alias: 'E', nargs: 1, desc: 'Do not rebuild asset with the given ID. Can be specified multiple times', default: [] }) + .option('exclusively', { type: 'boolean', alias: 'e', desc: 'Only deploy requested stacks, don\'t include dependencies' }) + .option('change-set-name', { type: 'string', desc: 'Name of the CloudFormation change set to create' }) + .option('force', { alias: 'f', type: 'boolean', desc: 'Always deploy stack even if templates are identical', default: false }) + .option('progress', { type: 'string', choices: [StackActivityProgress.BAR, StackActivityProgress.EVENTS], desc: 'Display mode for stack activity events' }) + .option('rollback', { + type: 'boolean', + desc: "Rollback stack to stable state on failure. Defaults to 'true', iterate more rapidly with --no-rollback or -R. " + + 'Note: do **not** disable this flag for deployments with resource replacements, as that will always fail', + }) + // same hack for -R as above in 'deploy' + .option('R', { type: 'boolean', hidden: true }).middleware(yargsNegativeAlias('R', 'rollback'), true) + .option('hotswap', { + type: 'boolean', + desc: "Attempts to perform a 'hotswap' deployment, " + + 'which skips CloudFormation and updates the resources directly, ' + + 'and falls back to a full deployment if that is not possible. ' + + "'true' by default, use --no-hotswap to turn off", }), ) .command('destroy [STACKS..]', 'Destroy the stack(s) named STACKS', yargs => yargs @@ -335,6 +374,26 @@ async function initCommandLine() { ci: args.ci, rollback: configuration.settings.get(['rollback']), hotswap: args.hotswap, + watch: args.watch, + }); + + case 'watch': + return cli.watch({ + selector, + // parameters: parameterMap, + // usePreviousParameters: args['previous-parameters'], + // outputsFile: configuration.settings.get(['outputsFile']), + // requireApproval: configuration.settings.get(['requireApproval']), + // notificationArns: args.notificationArns, + exclusively: args.exclusively, + toolkitStackName, + roleArn: args.roleArn, + reuseAssets: args['build-exclude'], + changeSetName: args.changeSetName, + force: args.force, + progress: configuration.settings.get(['progress']), + rollback: configuration.settings.get(['rollback']), + hotswap: args.hotswap, }); case 'destroy': diff --git a/packages/aws-cdk/lib/api/cloudformation-deployments.ts b/packages/aws-cdk/lib/api/cloudformation-deployments.ts index 914efd51cd574..da8db43ae8005 100644 --- a/packages/aws-cdk/lib/api/cloudformation-deployments.ts +++ b/packages/aws-cdk/lib/api/cloudformation-deployments.ts @@ -142,7 +142,7 @@ export interface DeployStackOptions { * A 'hotswap' deployment will attempt to short-circuit CloudFormation * and update the affected resources like Lambda functions directly. * - * @default - false (do not perform a 'hotswap' deployment) + * @default - false for regular deployments, true for 'watch' deployments */ readonly hotswap?: boolean; } diff --git a/packages/aws-cdk/lib/api/cxapp/cloud-executable.ts b/packages/aws-cdk/lib/api/cxapp/cloud-executable.ts index eeebec8e90f44..9bbb607de44fb 100644 --- a/packages/aws-cdk/lib/api/cxapp/cloud-executable.ts +++ b/packages/aws-cdk/lib/api/cxapp/cloud-executable.ts @@ -46,10 +46,14 @@ export class CloudExecutable { } /** - * Synthesize a set of stacks + * Synthesize a set of stacks. + * + * @param cacheCloudAssembly whether to cache the Cloud Assembly after it has been first synthesized. + * This is 'true' by default, and only set to 'false' for 'cdk watch', + * which needs to re-synthesize the Assembly each time it detects a change to the project files */ - public async synthesize(): Promise { - if (!this._cloudAssembly) { + public async synthesize(cacheCloudAssembly: boolean = true): Promise { + if (!this._cloudAssembly || !cacheCloudAssembly) { this._cloudAssembly = await this.doSynthesize(); } return this._cloudAssembly; diff --git a/packages/aws-cdk/lib/api/deploy-stack.ts b/packages/aws-cdk/lib/api/deploy-stack.ts index 2d35a3a01aea0..f73eebed57f54 100644 --- a/packages/aws-cdk/lib/api/deploy-stack.ts +++ b/packages/aws-cdk/lib/api/deploy-stack.ts @@ -179,7 +179,7 @@ export interface DeployStackOptions { * A 'hotswap' deployment will attempt to short-circuit CloudFormation * and update the affected resources like Lambda functions directly. * - * @default - false (do not perform a 'hotswap' deployment) + * @default - false for regular deployments, true for 'watch' deployments */ readonly hotswap?: boolean; } diff --git a/packages/aws-cdk/lib/cdk-toolkit.ts b/packages/aws-cdk/lib/cdk-toolkit.ts index cd5e591dce866..95da6dd39e139 100644 --- a/packages/aws-cdk/lib/cdk-toolkit.ts +++ b/packages/aws-cdk/lib/cdk-toolkit.ts @@ -1,6 +1,7 @@ import * as path from 'path'; import { format } from 'util'; import * as cxapi from '@aws-cdk/cx-api'; +import * as chokidar from 'chokidar'; import * as colors from 'colors/safe'; import * as fs from 'fs-extra'; import * as promptly from 'promptly'; @@ -12,9 +13,9 @@ import { CloudAssembly, DefaultSelection, ExtendedStackSelection, StackCollectio import { CloudExecutable } from './api/cxapp/cloud-executable'; import { StackActivityProgress } from './api/util/cloudformation/stack-activity-monitor'; import { printSecurityDiff, printStackDiff, RequireApproval } from './diff'; -import { data, error, highlight, print, success, warning } from './logging'; +import { data, debug, error, highlight, print, success, warning } from './logging'; import { deserializeStructure } from './serialize'; -import { Configuration } from './settings'; +import { Configuration, PROJECT_CONFIG } from './settings'; import { numberFromBool, partition } from './util'; export interface CdkToolkitProps { @@ -112,7 +113,11 @@ export class CdkToolkit { } public async deploy(options: DeployOptions) { - const stacks = await this.selectStacksForDeploy(options.selector, options.exclusively); + if (options.watch) { + return this.watch(options); + } + + const stacks = await this.selectStacksForDeploy(options.selector, options.exclusively, options.cacheCloudAssembly); const requireApproval = options.requireApproval ?? RequireApproval.Broadening; @@ -243,6 +248,85 @@ export class CdkToolkit { } } + public async watch(options: WatchOptions) { + const rootDir = path.dirname(path.resolve(PROJECT_CONFIG)); + debug("root directory used for 'watch' is: %s", rootDir); + + const watchSettings: { include?: string | string[], exclude: string | string [] } | undefined = + this.props.configuration.settings.get(['watch']); + if (!watchSettings) { + throw new Error("Cannot use the 'watch' command without specifying at least one directory to monitor. " + + 'Make sure to add a "watch" key to your cdk.json'); + } + + // For the "include" subkey under the "watch" key, the behavior is: + // 1. No "watch" setting? We error out. + // 2. "watch" setting without an "include" key? We default to observing "./**". + // 3. "watch" setting with an empty "include" key? We default to observing "./**". + // 4. Non-empty "include" key? Just use the "include" key. + const watchIncludes = this.patternsArrayForWatch(watchSettings.include, { rootDir, returnRootDirIfEmpty: true }); + debug("'include' patterns for 'watch': %s", watchIncludes); + + // For the "exclude" subkey under the "watch" key, + // the behavior is to add some default excludes in addition to the ones specified by the user: + // 1. The CDK output directory. + // 2. Any file whose name starts with a dot. + // 3. Any directory's content whose name starts with a dot. + // 4. Any node_modules and its content (even if it's not a JS/TS project, you might be using a local aws-cli package) + const outputDir = this.props.configuration.settings.get(['output']); + const watchExcludes = this.patternsArrayForWatch(watchSettings.exclude, { rootDir, returnRootDirIfEmpty: false }).concat( + `${outputDir}/**`, + '**/.*', + '**/.*/**', + '**/node_modules/**', + ); + debug("'exclude' patterns for 'watch': %s", watchExcludes); + + // Since 'cdk deploy' is a relatively slow operation for a 'watch' process, + // introduce a concurrency latch that tracks the state. + // This way, if file change events arrive when a 'cdk deploy' is still executing, + // we will batch them, and trigger another 'cdk deploy' after the current one finishes, + // making sure 'cdk deploy's always execute one at a time. + // Here's a diagram showing the state transitions: + // -------------- -------- file changed -------------- file changed -------------- file changed + // | | ready event | | ------------------> | | ------------------> | | --------------| + // | pre-ready | -------------> | open | | deploying | | queued | | + // | | | | <------------------ | | <------------------ | | <-------------| + // -------------- -------- 'cdk deploy' done -------------- 'cdk deploy' done -------------- + let latch: 'pre-ready' | 'open' | 'deploying' | 'queued' = 'pre-ready'; + chokidar.watch(watchIncludes, { + ignored: watchExcludes, + cwd: rootDir, + // ignoreInitial: true, + }).on('ready', () => { + latch = 'open'; + debug("'watch' received the 'ready' event. From now on, all file changes will trigger a deployment"); + }).on('all', async (event, filePath) => { + if (latch === 'pre-ready') { + print(`'watch' is observing ${event === 'addDir' ? 'directory' : 'the file'} '%s' for changes`, filePath); + } else if (latch === 'open') { + latch = 'deploying'; + print("Detected change to '%s' (type: %s). Triggering 'cdk deploy'", filePath, event); + await this.invokeDeployFromWatch(options); + + // If latch is still 'deploying' after the 'await', that's fine, + // but if it's 'queued', that means we need to deploy again + while ((latch as 'deploying' | 'queued') === 'queued') { + // TypeScript doesn't realize latch can change between 'awaits', + // and thinks the above 'while' condition is always 'false' without the cast + latch = 'deploying'; + print("Detected file changes during deployment. Invoking 'cdk deploy' again"); + await this.invokeDeployFromWatch(options); + } + latch = 'open'; + } else { // this means latch is either 'deploying' or 'queued' + latch = 'queued'; + print("Detected change to '%s' (type: %s) while 'cdk deploy' is still running. " + + 'Will queue for another deployment after this one finishes', filePath, event); + } + }); + } + public async destroy(options: DestroyOptions) { let stacks = await this.selectStacksForDestroy(options.selector, options.exclusively); @@ -397,8 +481,8 @@ export class CdkToolkit { return stacks; } - private async selectStacksForDeploy(selector: StackSelector, exclusively?: boolean): Promise { - const assembly = await this.assembly(); + private async selectStacksForDeploy(selector: StackSelector, exclusively?: boolean, cacheCloudAssembly?: boolean): Promise { + const assembly = await this.assembly(cacheCloudAssembly); const stacks = await assembly.selectStacks(selector, { extend: exclusively ? ExtendedStackSelection.None : ExtendedStackSelection.Upstream, defaultBehavior: DefaultSelection.OnlySingle, @@ -480,10 +564,38 @@ export class CdkToolkit { return assembly.stackById(stacks.firstStack.id); } - private assembly(): Promise { - return this.props.cloudExecutable.synthesize(); + private assembly(cacheCloudAssembly?: boolean): Promise { + return this.props.cloudExecutable.synthesize(cacheCloudAssembly); } + private patternsArrayForWatch(patterns: string | string[] | undefined, options: { rootDir: string, returnRootDirIfEmpty: boolean }): string[] { + const patternsArray: string[] = patterns !== undefined + ? (Array.isArray(patterns) ? patterns : [patterns]) + : []; + return patternsArray.length > 0 + ? patternsArray + : (options.returnRootDirIfEmpty ? [options.rootDir] : []); + } + + private async invokeDeployFromWatch(options: WatchOptions): Promise { + // 'watch' has different defaults than regular 'deploy' + const deployOptions: DeployOptions = { + ...options, + requireApproval: RequireApproval.Never, + // if 'watch' is called by invoking 'cdk deploy --watch', + // we need to make sure to not call 'deploy' with 'watch' again, + // as that would lead to a cycle + watch: false, + cacheCloudAssembly: false, + hotswap: options.hotswap === undefined ? true : options.hotswap, + }; + + try { + await this.deploy(deployOptions); + } catch (e) { + // just continue - deploy will show the error + } + } } export interface DiffOptions { @@ -542,7 +654,7 @@ export interface DiffOptions { securityOnly?: boolean; } -export interface DeployOptions { +interface WatchOptions { /** * Criteria for selecting stacks to deploy */ @@ -567,6 +679,49 @@ export interface DeployOptions { */ roleArn?: string; + /** + * Reuse the assets with the given asset IDs + */ + reuseAssets?: string[]; + + /** + * Optional name to use for the CloudFormation change set. + * If not provided, a name will be generated automatically. + */ + changeSetName?: string; + + /** + * Always deploy, even if templates are identical. + * @default false + */ + force?: boolean; + + /** + * Display mode for stack deployment progress. + * + * @default - StackActivityProgress.Bar - stack events will be displayed for + * the resource currently being deployed. + */ + progress?: StackActivityProgress; + + /** + * Rollback failed deployments + * + * @default true + */ + readonly rollback?: boolean; + + /** + * Whether to perform a 'hotswap' deployment. + * A 'hotswap' deployment will attempt to short-circuit CloudFormation + * and update the affected resources like Lambda functions directly. + * + * @default - false for regular deployments, true for 'watch' deployments + */ + readonly hotswap?: boolean; +} + +export interface DeployOptions extends WatchOptions { /** * ARNs of SNS topics that CloudFormation will notify with stack related events */ @@ -579,11 +734,6 @@ export interface DeployOptions { */ requireApproval?: RequireApproval; - /** - * Reuse the assets with the given asset IDs - */ - reuseAssets?: string[]; - /** * Tags to pass to CloudFormation for deployment */ @@ -596,18 +746,6 @@ export interface DeployOptions { */ execute?: boolean; - /** - * Optional name to use for the CloudFormation change set. - * If not provided, a name will be generated automatically. - */ - changeSetName?: string; - - /** - * Always deploy, even if templates are identical. - * @default false - */ - force?: boolean; - /** * Additional parameters for CloudFormation at deploy time * @default {} @@ -623,14 +761,6 @@ export interface DeployOptions { */ usePreviousParameters?: boolean; - /** - * Display mode for stack deployment progress. - * - * @default - StackActivityProgress.Bar - stack events will be displayed for - * the resource currently being deployed. - */ - progress?: StackActivityProgress; - /** * Path to file where stack outputs will be written after a successful deploy as JSON * @default - Outputs are not written to any file @@ -645,20 +775,20 @@ export interface DeployOptions { readonly ci?: boolean; /** - * Rollback failed deployments + * Whether this 'deploy' command should actually delegate to the 'watch' command. * - * @default true + * @default false */ - readonly rollback?: boolean; + readonly watch?: boolean; - /* - * Whether to perform a 'hotswap' deployment. - * A 'hotswap' deployment will attempt to short-circuit CloudFormation - * and update the affected resources like Lambda functions directly. + /** + * Whether we should cache the Cloud Assembly after the first time it has been synthesized. + * The default is 'true', we only don't want to do it in case the deployment is triggered by + * 'cdk watch'. * - * @default - false (do not perform a 'hotswap' deployment) + * @default true */ - readonly hotswap?: boolean; + readonly cacheCloudAssembly?: boolean; } export interface DestroyOptions { diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index c71dddbf206f4..40fa126a94cb4 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -76,6 +76,7 @@ "aws-sdk": "^2.979.0", "camelcase": "^6.2.0", "cdk-assets": "0.0.0", + "chokidar": "^3.5.2", "colors": "^1.4.0", "decamelize": "^5.0.1", "fs-extra": "^9.1.0", diff --git a/packages/aws-cdk/test/cdk-toolkit.test.ts b/packages/aws-cdk/test/cdk-toolkit.test.ts index 19276b15b7b7b..e8445da68a6b6 100644 --- a/packages/aws-cdk/test/cdk-toolkit.test.ts +++ b/packages/aws-cdk/test/cdk-toolkit.test.ts @@ -1,3 +1,52 @@ +// We need to mock the chokidar library, used by 'cdk watch' +const mockChokidarWatcherOn = jest.fn(); +const fakeChokidarWatcher = { + on: mockChokidarWatcherOn, +}; +const fakeChokidarWatcherOn = { + get readyCallback(): () => void { + expect(mockChokidarWatcherOn.mock.calls.length).toBeGreaterThanOrEqual(1); + // The call to the first 'watcher.on()' in the production code is the one we actually want here. + // This is a pretty fragile, but at least with this helper class, + // we would have to change it only in one place if it ever breaks + const firstCall = mockChokidarWatcherOn.mock.calls[0]; + // let's make sure the first argument is the 'ready' event, + // just to be double safe + expect(firstCall[0]).toBe('ready'); + // the second argument is the callback + return firstCall[1]; + }, + + get fileEventCallback(): (event: 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir', path: string) => Promise { + expect(mockChokidarWatcherOn.mock.calls.length).toBeGreaterThanOrEqual(2); + const secondCall = mockChokidarWatcherOn.mock.calls[1]; + // let's make sure the first argument is not the 'ready' event, + // just to be double safe + expect(secondCall[0]).not.toBe('ready'); + // the second argument is the callback + return secondCall[1]; + }, +}; + +const mockChokidarWatch = jest.fn(); +jest.mock('chokidar', () => ({ + watch: mockChokidarWatch, +})); +const fakeChokidarWatch = { + get includeArgs(): string[] { + expect(mockChokidarWatch.mock.calls.length).toBe(1); + // the include args are the first parameter to the 'watch()' call + return mockChokidarWatch.mock.calls[0][0]; + }, + + get excludeArgs(): string[] { + expect(mockChokidarWatch.mock.calls.length).toBe(1); + // the ignore args are a property of the second parameter to the 'watch()' call + const chokidarWatchOpts = mockChokidarWatch.mock.calls[0][1]; + return chokidarWatchOpts.ignored; + }, +}; + import * as cxschema from '@aws-cdk/cloud-assembly-schema'; import * as cxapi from '@aws-cdk/cx-api'; import { Bootstrapper } from '../lib/api/bootstrap'; @@ -11,6 +60,12 @@ import { instanceMockFrom, MockCloudExecutable, TestStackArtifact } from './util let cloudExecutable: MockCloudExecutable; let bootstrapper: jest.Mocked; beforeEach(() => { + jest.resetAllMocks(); + + mockChokidarWatch.mockReturnValue(fakeChokidarWatcher); + // on() in chokidar's Watcher returns 'this' + mockChokidarWatcherOn.mockReturnValue(fakeChokidarWatcher); + bootstrapper = instanceMockFrom(Bootstrapper); bootstrapper.bootstrapEnvironment.mockResolvedValue({ noOp: false, outputs: {} } as any); @@ -191,6 +246,141 @@ describe('deploy', () => { }); }); +describe('watch', () => { + test("fails when no 'watch' settings are found", async () => { + const toolkit = defaultToolkitSetup(); + + await expect(() => { + return toolkit.watch({ selector: { patterns: [] } }); + }).rejects.toThrow("Cannot use the 'watch' command without specifying at least one directory to monitor. " + + 'Make sure to add a "watch" key to your cdk.json'); + }); + + test('observes only the root directory by default', async () => { + cloudExecutable.configuration.settings.set(['watch'], {}); + const toolkit = defaultToolkitSetup(); + + await toolkit.watch({ selector: { patterns: [] } }); + + const includeArgs = fakeChokidarWatch.includeArgs; + expect(includeArgs.length).toBe(1); + }); + + test("allows providing a single string in 'watch.include'", async () => { + cloudExecutable.configuration.settings.set(['watch'], { + include: 'my-dir', + }); + const toolkit = defaultToolkitSetup(); + + await toolkit.watch({ selector: { patterns: [] } }); + + expect(fakeChokidarWatch.includeArgs).toStrictEqual(['my-dir']); + }); + + test("allows providing an array of strings in 'watch.include'", async () => { + cloudExecutable.configuration.settings.set(['watch'], { + include: ['my-dir1', '**/my-dir2/*'], + }); + const toolkit = defaultToolkitSetup(); + + await toolkit.watch({ selector: { patterns: [] } }); + + expect(fakeChokidarWatch.includeArgs).toStrictEqual(['my-dir1', '**/my-dir2/*']); + }); + + test('ignores the output dir, dot files, dot directories, and node_modules by default', async () => { + cloudExecutable.configuration.settings.set(['watch'], {}); + cloudExecutable.configuration.settings.set(['output'], 'cdk.out'); + const toolkit = defaultToolkitSetup(); + + await toolkit.watch({ selector: { patterns: [] } }); + + expect(fakeChokidarWatch.excludeArgs).toStrictEqual([ + 'cdk.out/**', + '**/.*', + '**/.*/**', + '**/node_modules/**', + ]); + }); + + test("allows providing a single string in 'watch.exclude'", async () => { + cloudExecutable.configuration.settings.set(['watch'], { + exclude: 'my-dir', + }); + const toolkit = defaultToolkitSetup(); + + await toolkit.watch({ selector: { patterns: [] } }); + + const excludeArgs = fakeChokidarWatch.excludeArgs; + expect(excludeArgs.length).toBe(5); + expect(excludeArgs[0]).toBe('my-dir'); + }); + + test("allows providing an array of strings in 'watch.exclude'", async () => { + cloudExecutable.configuration.settings.set(['watch'], { + exclude: ['my-dir1', '**/my-dir2'], + }); + const toolkit = defaultToolkitSetup(); + + await toolkit.watch({ selector: { patterns: [] } }); + + const excludeArgs = fakeChokidarWatch.excludeArgs; + expect(excludeArgs.length).toBe(6); + expect(excludeArgs[0]).toBe('my-dir1'); + expect(excludeArgs[1]).toBe('**/my-dir2'); + }); + + describe('with file change events', () => { + let toolkit: CdkToolkit; + let cdkDeployMock: jest.Mock; + + beforeEach(async () => { + cloudExecutable.configuration.settings.set(['watch'], {}); + toolkit = defaultToolkitSetup(); + cdkDeployMock = jest.fn(); + toolkit.deploy = cdkDeployMock; + await toolkit.watch({ selector: { patterns: [] } }); + }); + + test("does not trigger a 'deploy' before the 'ready' event has fired", async () => { + await fakeChokidarWatcherOn.fileEventCallback('add', 'my-file'); + + expect(cdkDeployMock).not.toHaveBeenCalled(); + }); + + describe("when the 'ready' event has already fired", () => { + beforeEach(() => { + fakeChokidarWatcherOn.readyCallback(); + }); + + test("does trigger a 'deploy' for a file change", async () => { + await fakeChokidarWatcherOn.fileEventCallback('add', 'my-file'); + + expect(cdkDeployMock).toHaveBeenCalled(); + }); + + test("triggers a 'deploy' twice for two file changes", async () => { + await Promise.all([ + fakeChokidarWatcherOn.fileEventCallback('add', 'my-file1'), + fakeChokidarWatcherOn.fileEventCallback('change', 'my-file2'), + ]); + + expect(cdkDeployMock).toHaveBeenCalledTimes(2); + }); + + test("batches file changes that happen during 'deploy'", async () => { + await Promise.all([ + fakeChokidarWatcherOn.fileEventCallback('add', 'my-file1'), + fakeChokidarWatcherOn.fileEventCallback('change', 'my-file2'), + fakeChokidarWatcherOn.fileEventCallback('unlink', 'my-file3'), + ]); + + expect(cdkDeployMock).toHaveBeenCalledTimes(2); + }); + }); + }); +}); + describe('synth', () => { test('with no stdout option', async () => { // GIVE diff --git a/yarn.lock b/yarn.lock index 026281159396d..b98b3ecdb6050 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2287,7 +2287,7 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@^3.0.3: +anymatch@^3.0.3, anymatch@~3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== @@ -2674,6 +2674,11 @@ before-after-hook@^2.0.0, before-after-hook@^2.2.0: resolved "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e" integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ== +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + bl@^4.0.3: version "4.1.0" resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" @@ -2712,7 +2717,7 @@ braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.1: +braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -2960,6 +2965,21 @@ charenc@0.0.2: resolved "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= +chokidar@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + chownr@^1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" @@ -4801,7 +4821,7 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^2.1.2, fsevents@^2.3.2: +fsevents@^2.1.2, fsevents@^2.3.2, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -4992,7 +5012,7 @@ github-api@^3.4.0: js-base64 "^2.1.9" utf8 "^2.1.1" -glob-parent@^5.1.1, glob-parent@^5.1.2: +glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -5421,6 +5441,13 @@ is-bigint@^1.0.1: dependencies: has-bigints "^1.0.1" +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-boolean-object@^1.1.0: version "1.1.2" resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" @@ -5524,7 +5551,7 @@ is-generator-fn@^2.0.0: resolved "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1, is-glob@^4.0.3: version "4.0.3" resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -7824,7 +7851,7 @@ normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" -normalize-path@^3.0.0: +normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== @@ -8467,7 +8494,7 @@ picocolors@^1.0.0: resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.3: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: version "2.3.0" resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== @@ -8877,6 +8904,13 @@ readdir-scoped-modules@^1.0.0: graceful-fs "^4.1.2" once "^1.3.0" +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + redent@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" From ea71b4ed7466d8799bde4fdd5adfed9fc8febb9c Mon Sep 17 00:00:00 2001 From: Ayush Goyal Date: Fri, 5 Nov 2021 14:35:44 +0530 Subject: [PATCH 50/70] feat(cfnspec): cloudformation spec v47.0.0 (#17350) Generated by running `scripts/bump-cfnspec.sh`. Wanted to speed up the additions required for #17290 . Feel free to close if this is supposed to be created by a bot like #17223 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/@aws-cdk/cfnspec/CHANGELOG.md | 273 +++ packages/@aws-cdk/cfnspec/cfn.version | 2 +- ...0_CloudFormationResourceSpecification.json | 1623 ++++++++++++++++- 3 files changed, 1821 insertions(+), 77 deletions(-) diff --git a/packages/@aws-cdk/cfnspec/CHANGELOG.md b/packages/@aws-cdk/cfnspec/CHANGELOG.md index 51d94432f3293..913546215a38d 100644 --- a/packages/@aws-cdk/cfnspec/CHANGELOG.md +++ b/packages/@aws-cdk/cfnspec/CHANGELOG.md @@ -1,3 +1,276 @@ +# CloudFormation Resource Specification v47.0.0 + +## New Resource Types + +* AWS::CloudFront::ResponseHeadersPolicy +* AWS::DataSync::LocationHDFS +* AWS::IoT::Logging +* AWS::IoT::ResourceSpecificLogging +* AWS::Pinpoint::InAppTemplate +* AWS::Redshift::EndpointAccess +* AWS::Redshift::EndpointAuthorization +* AWS::Redshift::EventSubscription +* AWS::Redshift::ScheduledAction + +## Attribute Changes + +* AWS::EC2::InternetGateway InternetGatewayId (__added__) +* AWS::EC2::NetworkInterface Id (__added__) +* AWS::EC2::NetworkInterface SecondaryPrivateIpAddresses.DuplicatesAllowed (__added__) +* AWS::EC2::NetworkInterface Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html +* AWS::IoTAnalytics::Channel Id (__added__) +* AWS::IoTAnalytics::Dataset Id (__added__) +* AWS::IoTAnalytics::Datastore Id (__added__) +* AWS::IoTAnalytics::Pipeline Id (__added__) + +## Property Changes + +* AWS::DMS::Endpoint RedisSettings (__added__) +* AWS::EC2::NetworkInterface Description.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-description + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-description +* AWS::EC2::NetworkInterface GroupSet.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-groupset + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-groupset +* AWS::EC2::NetworkInterface GroupSet.DuplicatesAllowed (__changed__) + * Old: false + * New: true +* AWS::EC2::NetworkInterface InterfaceType.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-interfacetype + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-interfacetype +* AWS::EC2::NetworkInterface Ipv6AddressCount.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-ipv6addresscount + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-ipv6addresscount +* AWS::EC2::NetworkInterface Ipv6Addresses.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-ipv6addresses + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-ipv6addresses +* AWS::EC2::NetworkInterface PrivateIpAddress.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-privateipaddress + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-privateipaddress +* AWS::EC2::NetworkInterface PrivateIpAddresses.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-privateipaddresses + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-privateipaddresses +* AWS::EC2::NetworkInterface PrivateIpAddresses.DuplicatesAllowed (__changed__) + * Old: false + * New: true +* AWS::EC2::NetworkInterface PrivateIpAddresses.UpdateType (__changed__) + * Old: Conditional + * New: Mutable +* AWS::EC2::NetworkInterface SecondaryPrivateIpAddressCount.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-secondaryprivateipcount + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-secondaryprivateipaddresscount +* AWS::EC2::NetworkInterface SourceDestCheck.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-sourcedestcheck + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-sourcedestcheck +* AWS::EC2::NetworkInterface SubnetId.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-subnetid + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-subnetid +* AWS::EC2::NetworkInterface Tags.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-tags + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-tags +* AWS::EC2::TransitGatewayPeeringAttachment Options (__added__) +* AWS::EC2::VPCEndpointService PayerResponsibility (__added__) +* AWS::EKS::Cluster Logging (__added__) +* AWS::EKS::Cluster Tags (__added__) +* AWS::EKS::Cluster ResourcesVpcConfig.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::IoTAnalytics::Channel ChannelName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Channel Tags.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Dataset Actions.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Dataset ContentDeliveryRules.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Dataset DatasetName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Dataset LateDataRules.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Dataset Tags.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Dataset Triggers.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Datastore Tags.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Pipeline PipelineActivities.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Pipeline PipelineName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline Tags.DuplicatesAllowed (__added__) +* AWS::S3ObjectLambda::AccessPoint Name.Required (__changed__) + * Old: true + * New: false +* AWS::SageMaker::Endpoint RetainDeploymentConfig (__added__) + +## Property Type Changes + +* AWS::EKS::Cluster.Provider (__removed__) +* AWS::DMS::Endpoint.RedisSettings (__added__) +* AWS::EC2::EC2Fleet.CapacityRebalance (__added__) +* AWS::EC2::EC2Fleet.MaintenanceStrategies (__added__) +* AWS::EC2::TransitGatewayPeeringAttachment.TransitGatewayPeeringAttachmentOptions (__added__) +* AWS::EKS::Cluster.ClusterLogging (__added__) +* AWS::EKS::Cluster.Logging (__added__) +* AWS::EKS::Cluster.LoggingTypeConfig (__added__) +* AWS::NetworkFirewall::FirewallPolicy.StatefulEngineOptions (__added__) +* AWS::NetworkFirewall::RuleGroup.StatefulRuleOptions (__added__) +* AWS::DMS::Endpoint.KafkaSettings IncludeControlDetails (__added__) +* AWS::DMS::Endpoint.KafkaSettings IncludeNullAndEmpty (__added__) +* AWS::DMS::Endpoint.KafkaSettings IncludeTableAlterOperations (__added__) +* AWS::DMS::Endpoint.KafkaSettings IncludeTransactionDetails (__added__) +* AWS::DMS::Endpoint.KafkaSettings NoHexPrefix (__added__) +* AWS::DMS::Endpoint.KafkaSettings PartitionIncludeSchemaTable (__added__) +* AWS::DMS::Endpoint.KafkaSettings SaslPassword (__added__) +* AWS::DMS::Endpoint.KafkaSettings SaslUserName (__added__) +* AWS::DMS::Endpoint.KafkaSettings SecurityProtocol (__added__) +* AWS::DMS::Endpoint.KafkaSettings SslCaCertificateArn (__added__) +* AWS::DMS::Endpoint.KafkaSettings SslClientCertificateArn (__added__) +* AWS::DMS::Endpoint.KafkaSettings SslClientKeyArn (__added__) +* AWS::DMS::Endpoint.KafkaSettings SslClientKeyPassword (__added__) +* AWS::DMS::Endpoint.KinesisSettings IncludeControlDetails (__added__) +* AWS::DMS::Endpoint.KinesisSettings IncludeNullAndEmpty (__added__) +* AWS::DMS::Endpoint.KinesisSettings IncludeTableAlterOperations (__added__) +* AWS::DMS::Endpoint.KinesisSettings IncludeTransactionDetails (__added__) +* AWS::DMS::Endpoint.KinesisSettings NoHexPrefix (__added__) +* AWS::DMS::Endpoint.KinesisSettings PartitionIncludeSchemaTable (__added__) +* AWS::EC2::EC2Fleet.SpotOptionsRequest MaintenanceStrategies.PrimitiveType (__deleted__) +* AWS::EC2::EC2Fleet.SpotOptionsRequest MaintenanceStrategies.Type (__added__) +* AWS::EC2::NetworkInterface.PrivateIpAddressSpecification Primary.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html#cfn-ec2-networkinterface-privateipspecification-primary + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinterface-privateipaddressspecification.html#cfn-ec2-networkinterface-privateipaddressspecification-primary +* AWS::EC2::NetworkInterface.PrivateIpAddressSpecification PrivateIpAddress.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html#cfn-ec2-networkinterface-privateipspecification-privateipaddress + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinterface-privateipaddressspecification.html#cfn-ec2-networkinterface-privateipaddressspecification-privateipaddress +* AWS::EKS::Cluster.EncryptionConfig Provider.Type (__deleted__) +* AWS::EKS::Cluster.EncryptionConfig Provider.PrimitiveType (__added__) +* AWS::EKS::Cluster.EncryptionConfig Provider.UpdateType (__changed__) + * Old: Mutable + * New: Immutable +* AWS::EKS::Cluster.EncryptionConfig Resources.UpdateType (__changed__) + * Old: Mutable + * New: Immutable +* AWS::EKS::Cluster.KubernetesNetworkConfig ServiceIpv4Cidr.UpdateType (__changed__) + * Old: Mutable + * New: Immutable +* AWS::EKS::Cluster.ResourcesVpcConfig EndpointPrivateAccess (__added__) +* AWS::EKS::Cluster.ResourcesVpcConfig EndpointPublicAccess (__added__) +* AWS::EKS::Cluster.ResourcesVpcConfig PublicAccessCidrs (__added__) +* AWS::EKS::Cluster.ResourcesVpcConfig SecurityGroupIds.UpdateType (__changed__) + * Old: Mutable + * New: Immutable +* AWS::EKS::Cluster.ResourcesVpcConfig SubnetIds.UpdateType (__changed__) + * Old: Mutable + * New: Immutable +* AWS::IoTAnalytics::Dataset.ContainerAction Variables.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Dataset.DatasetContentVersionValue DatasetName.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-variable-datasetcontentversionvalue.html#cfn-iotanalytics-dataset-variable-datasetcontentversionvalue-datasetname + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-datasetcontentversionvalue.html#cfn-iotanalytics-dataset-datasetcontentversionvalue-datasetname +* AWS::IoTAnalytics::Dataset.DatasetContentVersionValue DatasetName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Dataset.OutputFileUriValue FileName.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-variable-outputfileurivalue.html#cfn-iotanalytics-dataset-variable-outputfileurivalue-filename + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-outputfileurivalue.html#cfn-iotanalytics-dataset-outputfileurivalue-filename +* AWS::IoTAnalytics::Dataset.OutputFileUriValue FileName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Dataset.QueryAction Filters.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Dataset.Schedule ScheduleExpression.Documentation (__changed__) + * Old: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-trigger-schedule.html#cfn-iotanalytics-dataset-trigger-schedule-scheduleexpression + * New: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-schedule.html#cfn-iotanalytics-dataset-schedule-scheduleexpression +* AWS::IoTAnalytics::Datastore.DatastorePartitions Partitions.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Datastore.IotSiteWiseMultiLayerStorage CustomerManagedS3Storage.Required (__changed__) + * Old: true + * New: false +* AWS::IoTAnalytics::Datastore.SchemaDefinition Columns.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Pipeline.AddAttributes Attributes.PrimitiveType (__deleted__) +* AWS::IoTAnalytics::Pipeline.AddAttributes Attributes.PrimitiveItemType (__added__) +* AWS::IoTAnalytics::Pipeline.AddAttributes Attributes.Type (__added__) +* AWS::IoTAnalytics::Pipeline.AddAttributes Attributes.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.AddAttributes Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Channel ChannelName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Channel Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Datastore DatastoreName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Datastore Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceRegistryEnrich Attribute.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceRegistryEnrich Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceRegistryEnrich RoleArn.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceRegistryEnrich ThingName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceShadowEnrich Attribute.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceShadowEnrich Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceShadowEnrich RoleArn.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.DeviceShadowEnrich ThingName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Filter Filter.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Filter Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Lambda BatchSize.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Lambda LambdaName.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Lambda Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Math Attribute.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Math Math.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.Math Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.RemoveAttributes Attributes.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Pipeline.RemoveAttributes Attributes.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.RemoveAttributes Name.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.SelectAttributes Attributes.DuplicatesAllowed (__added__) +* AWS::IoTAnalytics::Pipeline.SelectAttributes Attributes.Required (__changed__) + * Old: false + * New: true +* AWS::IoTAnalytics::Pipeline.SelectAttributes Name.Required (__changed__) + * Old: false + * New: true +* AWS::NetworkFirewall::FirewallPolicy.FirewallPolicy StatefulDefaultActions (__added__) +* AWS::NetworkFirewall::FirewallPolicy.FirewallPolicy StatefulEngineOptions (__added__) +* AWS::NetworkFirewall::FirewallPolicy.StatefulRuleGroupReference Priority (__added__) +* AWS::NetworkFirewall::RuleGroup.RuleGroup StatefulRuleOptions (__added__) +* AWS::SageMaker::Endpoint.TrafficRoutingConfig LinearStepSize (__added__) + + # CloudFormation Resource Specification v46.0.0 ## New Resource Types diff --git a/packages/@aws-cdk/cfnspec/cfn.version b/packages/@aws-cdk/cfnspec/cfn.version index 783c5bb1ce5c2..645a41f3b46f7 100644 --- a/packages/@aws-cdk/cfnspec/cfn.version +++ b/packages/@aws-cdk/cfnspec/cfn.version @@ -1 +1 @@ -46.0.0 +47.0.0 diff --git a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json index 2db5051c26ccf..5d8a7aab62e63 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json +++ b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json @@ -12537,6 +12537,333 @@ } } }, + "AWS::CloudFront::ResponseHeadersPolicy.AccessControlAllowHeaders": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolallowheaders.html", + "Properties": { + "Items": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolallowheaders.html#cfn-cloudfront-responseheaderspolicy-accesscontrolallowheaders-items", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.AccessControlAllowMethods": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolallowmethods.html", + "Properties": { + "Items": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolallowmethods.html#cfn-cloudfront-responseheaderspolicy-accesscontrolallowmethods-items", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.AccessControlAllowOrigins": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolalloworigins.html", + "Properties": { + "Items": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolalloworigins.html#cfn-cloudfront-responseheaderspolicy-accesscontrolalloworigins-items", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.AccessControlExposeHeaders": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolexposeheaders.html", + "Properties": { + "Items": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-accesscontrolexposeheaders.html#cfn-cloudfront-responseheaderspolicy-accesscontrolexposeheaders-items", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.ContentSecurityPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-contentsecuritypolicy.html", + "Properties": { + "ContentSecurityPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-contentsecuritypolicy.html#cfn-cloudfront-responseheaderspolicy-contentsecuritypolicy-contentsecuritypolicy", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Override": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-contentsecuritypolicy.html#cfn-cloudfront-responseheaderspolicy-contentsecuritypolicy-override", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.ContentTypeOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-contenttypeoptions.html", + "Properties": { + "Override": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-contenttypeoptions.html#cfn-cloudfront-responseheaderspolicy-contenttypeoptions-override", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.CorsConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html", + "Properties": { + "AccessControlAllowCredentials": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html#cfn-cloudfront-responseheaderspolicy-corsconfig-accesscontrolallowcredentials", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + }, + "AccessControlAllowHeaders": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html#cfn-cloudfront-responseheaderspolicy-corsconfig-accesscontrolallowheaders", + "Required": true, + "Type": "AccessControlAllowHeaders", + "UpdateType": "Mutable" + }, + "AccessControlAllowMethods": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html#cfn-cloudfront-responseheaderspolicy-corsconfig-accesscontrolallowmethods", + "Required": true, + "Type": "AccessControlAllowMethods", + "UpdateType": "Mutable" + }, + "AccessControlAllowOrigins": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html#cfn-cloudfront-responseheaderspolicy-corsconfig-accesscontrolalloworigins", + "Required": true, + "Type": "AccessControlAllowOrigins", + "UpdateType": "Mutable" + }, + "AccessControlExposeHeaders": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html#cfn-cloudfront-responseheaderspolicy-corsconfig-accesscontrolexposeheaders", + "Required": false, + "Type": "AccessControlExposeHeaders", + "UpdateType": "Mutable" + }, + "AccessControlMaxAgeSec": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html#cfn-cloudfront-responseheaderspolicy-corsconfig-accesscontrolmaxagesec", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "OriginOverride": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-corsconfig.html#cfn-cloudfront-responseheaderspolicy-corsconfig-originoverride", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.CustomHeader": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-customheader.html", + "Properties": { + "Header": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-customheader.html#cfn-cloudfront-responseheaderspolicy-customheader-header", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Override": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-customheader.html#cfn-cloudfront-responseheaderspolicy-customheader-override", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + }, + "Value": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-customheader.html#cfn-cloudfront-responseheaderspolicy-customheader-value", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.CustomHeadersConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-customheadersconfig.html", + "Properties": { + "Items": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-customheadersconfig.html#cfn-cloudfront-responseheaderspolicy-customheadersconfig-items", + "DuplicatesAllowed": true, + "ItemType": "CustomHeader", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.FrameOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-frameoptions.html", + "Properties": { + "FrameOption": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-frameoptions.html#cfn-cloudfront-responseheaderspolicy-frameoptions-frameoption", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Override": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-frameoptions.html#cfn-cloudfront-responseheaderspolicy-frameoptions-override", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.ReferrerPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-referrerpolicy.html", + "Properties": { + "Override": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-referrerpolicy.html#cfn-cloudfront-responseheaderspolicy-referrerpolicy-override", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + }, + "ReferrerPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-referrerpolicy.html#cfn-cloudfront-responseheaderspolicy-referrerpolicy-referrerpolicy", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.ResponseHeadersPolicyConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-responseheaderspolicyconfig.html", + "Properties": { + "Comment": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-responseheaderspolicyconfig.html#cfn-cloudfront-responseheaderspolicy-responseheaderspolicyconfig-comment", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "CorsConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-responseheaderspolicyconfig.html#cfn-cloudfront-responseheaderspolicy-responseheaderspolicyconfig-corsconfig", + "Required": false, + "Type": "CorsConfig", + "UpdateType": "Mutable" + }, + "CustomHeadersConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-responseheaderspolicyconfig.html#cfn-cloudfront-responseheaderspolicy-responseheaderspolicyconfig-customheadersconfig", + "Required": false, + "Type": "CustomHeadersConfig", + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-responseheaderspolicyconfig.html#cfn-cloudfront-responseheaderspolicy-responseheaderspolicyconfig-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "SecurityHeadersConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-responseheaderspolicyconfig.html#cfn-cloudfront-responseheaderspolicy-responseheaderspolicyconfig-securityheadersconfig", + "Required": false, + "Type": "SecurityHeadersConfig", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.SecurityHeadersConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-securityheadersconfig.html", + "Properties": { + "ContentSecurityPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-securityheadersconfig.html#cfn-cloudfront-responseheaderspolicy-securityheadersconfig-contentsecuritypolicy", + "Required": false, + "Type": "ContentSecurityPolicy", + "UpdateType": "Mutable" + }, + "ContentTypeOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-securityheadersconfig.html#cfn-cloudfront-responseheaderspolicy-securityheadersconfig-contenttypeoptions", + "Required": false, + "Type": "ContentTypeOptions", + "UpdateType": "Mutable" + }, + "FrameOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-securityheadersconfig.html#cfn-cloudfront-responseheaderspolicy-securityheadersconfig-frameoptions", + "Required": false, + "Type": "FrameOptions", + "UpdateType": "Mutable" + }, + "ReferrerPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-securityheadersconfig.html#cfn-cloudfront-responseheaderspolicy-securityheadersconfig-referrerpolicy", + "Required": false, + "Type": "ReferrerPolicy", + "UpdateType": "Mutable" + }, + "StrictTransportSecurity": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-securityheadersconfig.html#cfn-cloudfront-responseheaderspolicy-securityheadersconfig-stricttransportsecurity", + "Required": false, + "Type": "StrictTransportSecurity", + "UpdateType": "Mutable" + }, + "XSSProtection": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-securityheadersconfig.html#cfn-cloudfront-responseheaderspolicy-securityheadersconfig-xssprotection", + "Required": false, + "Type": "XSSProtection", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.StrictTransportSecurity": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-stricttransportsecurity.html", + "Properties": { + "AccessControlMaxAgeSec": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-stricttransportsecurity.html#cfn-cloudfront-responseheaderspolicy-stricttransportsecurity-accesscontrolmaxagesec", + "PrimitiveType": "Integer", + "Required": true, + "UpdateType": "Mutable" + }, + "IncludeSubdomains": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-stricttransportsecurity.html#cfn-cloudfront-responseheaderspolicy-stricttransportsecurity-includesubdomains", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "Override": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-stricttransportsecurity.html#cfn-cloudfront-responseheaderspolicy-stricttransportsecurity-override", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + }, + "Preload": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-stricttransportsecurity.html#cfn-cloudfront-responseheaderspolicy-stricttransportsecurity-preload", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::ResponseHeadersPolicy.XSSProtection": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-xssprotection.html", + "Properties": { + "ModeBlock": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-xssprotection.html#cfn-cloudfront-responseheaderspolicy-xssprotection-modeblock", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "Override": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-xssprotection.html#cfn-cloudfront-responseheaderspolicy-xssprotection-override", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + }, + "Protection": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-xssprotection.html#cfn-cloudfront-responseheaderspolicy-xssprotection-protection", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Mutable" + }, + "ReportUri": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-responseheaderspolicy-xssprotection.html#cfn-cloudfront-responseheaderspolicy-xssprotection-reporturi", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::CloudFront::StreamingDistribution.Logging": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-logging.html", "Properties": { @@ -16883,6 +17210,84 @@ "Required": false, "UpdateType": "Mutable" }, + "IncludeControlDetails": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-includecontroldetails", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "IncludeNullAndEmpty": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-includenullandempty", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "IncludeTableAlterOperations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-includetablealteroperations", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "IncludeTransactionDetails": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-includetransactiondetails", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "NoHexPrefix": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-nohexprefix", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "PartitionIncludeSchemaTable": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-partitionincludeschematable", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "SaslPassword": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-saslpassword", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SaslUserName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-saslusername", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SecurityProtocol": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-securityprotocol", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SslCaCertificateArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-sslcacertificatearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SslClientCertificateArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-sslclientcertificatearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SslClientKeyArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-sslclientkeyarn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SslClientKeyPassword": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-sslclientkeypassword", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "Topic": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kafkasettings.html#cfn-dms-endpoint-kafkasettings-topic", "PrimitiveType": "String", @@ -16894,12 +17299,48 @@ "AWS::DMS::Endpoint.KinesisSettings": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html", "Properties": { + "IncludeControlDetails": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-includecontroldetails", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "IncludeNullAndEmpty": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-includenullandempty", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "IncludeTableAlterOperations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-includetablealteroperations", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "IncludeTransactionDetails": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-includetransactiondetails", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, "MessageFormat": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-messageformat", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" }, + "NoHexPrefix": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-nohexprefix", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "PartitionIncludeSchemaTable": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-partitionincludeschematable", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, "ServiceAccessRoleArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-kinesissettings.html#cfn-dms-endpoint-kinesissettings-serviceaccessrolearn", "PrimitiveType": "String", @@ -17124,6 +17565,53 @@ } } }, + "AWS::DMS::Endpoint.RedisSettings": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html", + "Properties": { + "AuthPassword": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html#cfn-dms-endpoint-redissettings-authpassword", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "AuthType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html#cfn-dms-endpoint-redissettings-authtype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "AuthUserName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html#cfn-dms-endpoint-redissettings-authusername", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Port": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html#cfn-dms-endpoint-redissettings-port", + "PrimitiveType": "Double", + "Required": false, + "UpdateType": "Mutable" + }, + "ServerName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html#cfn-dms-endpoint-redissettings-servername", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SslCaCertificateArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html#cfn-dms-endpoint-redissettings-sslcacertificatearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SslSecurityProtocol": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redissettings.html#cfn-dms-endpoint-redissettings-sslsecurityprotocol", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::DMS::Endpoint.RedshiftSettings": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dms-endpoint-redshiftsettings.html", "Properties": { @@ -18746,6 +19234,40 @@ } } }, + "AWS::DataSync::LocationHDFS.NameNode": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationhdfs-namenode.html", + "Properties": { + "Hostname": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationhdfs-namenode.html#cfn-datasync-locationhdfs-namenode-hostname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Port": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationhdfs-namenode.html#cfn-datasync-locationhdfs-namenode-port", + "PrimitiveType": "Integer", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::DataSync::LocationHDFS.QopConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationhdfs-qopconfiguration.html", + "Properties": { + "DataTransferProtection": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationhdfs-qopconfiguration.html#cfn-datasync-locationhdfs-qopconfiguration-datatransferprotection", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "RpcProtection": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationhdfs-qopconfiguration.html#cfn-datasync-locationhdfs-qopconfiguration-rpcprotection", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::DataSync::LocationNFS.MountOptions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationnfs-mountoptions.html", "Properties": { @@ -19815,6 +20337,23 @@ } } }, + "AWS::EC2::EC2Fleet.CapacityRebalance": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-capacityrebalance.html", + "Properties": { + "ReplacementStrategy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-capacityrebalance.html#cfn-ec2-ec2fleet-capacityrebalance-replacementstrategy", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "TerminationDelay": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-capacityrebalance.html#cfn-ec2-ec2fleet-capacityrebalance-terminationdelay", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Immutable" + } + } + }, "AWS::EC2::EC2Fleet.CapacityReservationOptionsRequest": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-capacityreservationoptionsrequest.html", "Properties": { @@ -20066,6 +20605,17 @@ } } }, + "AWS::EC2::EC2Fleet.MaintenanceStrategies": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-maintenancestrategies.html", + "Properties": { + "CapacityRebalance": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-maintenancestrategies.html#cfn-ec2-ec2fleet-maintenancestrategies-capacityrebalance", + "Required": false, + "Type": "CapacityRebalance", + "UpdateType": "Immutable" + } + } + }, "AWS::EC2::EC2Fleet.MemoryGiBPerVCpuRequest": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-memorygibpervcpurequest.html", "Properties": { @@ -20234,8 +20784,8 @@ }, "MaintenanceStrategies": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-ec2fleet-spotoptionsrequest.html#cfn-ec2-ec2fleet-spotoptionsrequest-maintenancestrategies", - "PrimitiveType": "Json", "Required": false, + "Type": "MaintenanceStrategies", "UpdateType": "Immutable" }, "MaxTotalPrice": { @@ -22232,16 +22782,16 @@ } }, "AWS::EC2::NetworkInterface.PrivateIpAddressSpecification": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinterface-privateipaddressspecification.html", "Properties": { "Primary": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html#cfn-ec2-networkinterface-privateipspecification-primary", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinterface-privateipaddressspecification.html#cfn-ec2-networkinterface-privateipaddressspecification-primary", "PrimitiveType": "Boolean", "Required": true, "UpdateType": "Mutable" }, "PrivateIpAddress": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-network-interface-privateipspec.html#cfn-ec2-networkinterface-privateipspecification-privateipaddress", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-networkinterface-privateipaddressspecification.html#cfn-ec2-networkinterface-privateipaddressspecification-privateipaddress", "PrimitiveType": "String", "Required": true, "UpdateType": "Mutable" @@ -23380,6 +23930,17 @@ } } }, + "AWS::EC2::TransitGatewayPeeringAttachment.TransitGatewayPeeringAttachmentOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-transitgatewaypeeringattachment-transitgatewaypeeringattachmentoptions.html", + "Properties": { + "DynamicRouting": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-transitgatewaypeeringattachment-transitgatewaypeeringattachmentoptions.html#cfn-ec2-transitgatewaypeeringattachment-transitgatewaypeeringattachmentoptions-dynamicrouting", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::EC2::VPNConnection.VpnTunnelOptionsSpecification": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-vpnconnection-vpntunneloptionsspecification.html", "Properties": { @@ -25027,21 +25588,33 @@ } } }, + "AWS::EKS::Cluster.ClusterLogging": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-clusterlogging.html", + "Properties": { + "EnabledTypes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-clusterlogging.html#cfn-eks-cluster-clusterlogging-enabledtypes", + "ItemType": "LoggingTypeConfig", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "AWS::EKS::Cluster.EncryptionConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-encryptionconfig.html", "Properties": { "Provider": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-encryptionconfig.html#cfn-eks-cluster-encryptionconfig-provider", + "PrimitiveType": "Json", "Required": false, - "Type": "Provider", - "UpdateType": "Mutable" + "UpdateType": "Immutable" }, "Resources": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-encryptionconfig.html#cfn-eks-cluster-encryptionconfig-resources", "PrimitiveItemType": "String", "Required": false, "Type": "List", - "UpdateType": "Mutable" + "UpdateType": "Immutable" } } }, @@ -25052,15 +25625,26 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-kubernetesnetworkconfig.html#cfn-eks-cluster-kubernetesnetworkconfig-serviceipv4cidr", "PrimitiveType": "String", "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::EKS::Cluster.Logging": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-logging.html", + "Properties": { + "ClusterLogging": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-logging.html#cfn-eks-cluster-logging-clusterlogging", + "Required": false, + "Type": "ClusterLogging", "UpdateType": "Mutable" } } }, - "AWS::EKS::Cluster.Provider": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-provider.html", + "AWS::EKS::Cluster.LoggingTypeConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-loggingtypeconfig.html", "Properties": { - "KeyArn": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-provider.html#cfn-eks-cluster-provider-keyarn", + "Type": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-loggingtypeconfig.html#cfn-eks-cluster-loggingtypeconfig-type", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" @@ -25070,19 +25654,38 @@ "AWS::EKS::Cluster.ResourcesVpcConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-resourcesvpcconfig.html", "Properties": { + "EndpointPrivateAccess": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-resourcesvpcconfig.html#cfn-eks-cluster-resourcesvpcconfig-endpointprivateaccess", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "EndpointPublicAccess": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-resourcesvpcconfig.html#cfn-eks-cluster-resourcesvpcconfig-endpointpublicaccess", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "PublicAccessCidrs": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-resourcesvpcconfig.html#cfn-eks-cluster-resourcesvpcconfig-publicaccesscidrs", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "SecurityGroupIds": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-resourcesvpcconfig.html#cfn-eks-cluster-resourcesvpcconfig-securitygroupids", "PrimitiveItemType": "String", "Required": false, "Type": "List", - "UpdateType": "Mutable" + "UpdateType": "Immutable" }, "SubnetIds": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-cluster-resourcesvpcconfig.html#cfn-eks-cluster-resourcesvpcconfig-subnetids", "PrimitiveItemType": "String", "Required": true, "Type": "List", - "UpdateType": "Mutable" + "UpdateType": "Immutable" } } }, @@ -35964,8 +36567,7 @@ } }, "AWS::IoTAnalytics::Channel.ServiceManagedS3": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-channel-servicemanageds3.html", - "Properties": {} + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-channel-servicemanageds3.html" }, "AWS::IoTAnalytics::Dataset.Action": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-action.html", @@ -36013,6 +36615,7 @@ }, "Variables": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-containeraction.html#cfn-iotanalytics-dataset-containeraction-variables", + "DuplicatesAllowed": true, "ItemType": "Variable", "Required": false, "Type": "List", @@ -36055,12 +36658,12 @@ } }, "AWS::IoTAnalytics::Dataset.DatasetContentVersionValue": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-variable-datasetcontentversionvalue.html", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-datasetcontentversionvalue.html", "Properties": { "DatasetName": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-variable-datasetcontentversionvalue.html#cfn-iotanalytics-dataset-variable-datasetcontentversionvalue-datasetname", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-datasetcontentversionvalue.html#cfn-iotanalytics-dataset-datasetcontentversionvalue-datasetname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" } } @@ -36167,12 +36770,12 @@ } }, "AWS::IoTAnalytics::Dataset.OutputFileUriValue": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-variable-outputfileurivalue.html", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-outputfileurivalue.html", "Properties": { "FileName": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-variable-outputfileurivalue.html#cfn-iotanalytics-dataset-variable-outputfileurivalue-filename", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-outputfileurivalue.html#cfn-iotanalytics-dataset-outputfileurivalue-filename", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" } } @@ -36182,6 +36785,7 @@ "Properties": { "Filters": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-queryaction.html#cfn-iotanalytics-dataset-queryaction-filters", + "DuplicatesAllowed": true, "ItemType": "Filter", "Required": false, "Type": "List", @@ -36259,10 +36863,10 @@ } }, "AWS::IoTAnalytics::Dataset.Schedule": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-trigger-schedule.html", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-schedule.html", "Properties": { "ScheduleExpression": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-trigger-schedule.html#cfn-iotanalytics-dataset-trigger-schedule-scheduleexpression", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-dataset-schedule.html#cfn-iotanalytics-dataset-schedule-scheduleexpression", "PrimitiveType": "String", "Required": true, "UpdateType": "Mutable" @@ -36428,6 +37032,7 @@ "Properties": { "Partitions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-datastorepartitions.html#cfn-iotanalytics-datastore-datastorepartitions-partitions", + "DuplicatesAllowed": true, "ItemType": "DatastorePartition", "Required": false, "Type": "List", @@ -36480,15 +37085,14 @@ "Properties": { "CustomerManagedS3Storage": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-iotsitewisemultilayerstorage.html#cfn-iotanalytics-datastore-iotsitewisemultilayerstorage-customermanageds3storage", - "Required": true, + "Required": false, "Type": "CustomerManagedS3Storage", "UpdateType": "Mutable" } } }, "AWS::IoTAnalytics::Datastore.JsonConfiguration": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-jsonconfiguration.html", - "Properties": {} + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-jsonconfiguration.html" }, "AWS::IoTAnalytics::Datastore.ParquetConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-parquetconfiguration.html", @@ -36534,6 +37138,7 @@ "Properties": { "Columns": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-schemadefinition.html#cfn-iotanalytics-datastore-schemadefinition-columns", + "DuplicatesAllowed": true, "ItemType": "Column", "Required": false, "Type": "List", @@ -36542,8 +37147,7 @@ } }, "AWS::IoTAnalytics::Datastore.ServiceManagedS3": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-servicemanageds3.html", - "Properties": {} + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-servicemanageds3.html" }, "AWS::IoTAnalytics::Datastore.TimestampPartition": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-datastore-timestamppartition.html", @@ -36632,14 +37236,15 @@ "Properties": { "Attributes": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-addattributes.html#cfn-iotanalytics-pipeline-addattributes-attributes", - "PrimitiveType": "Json", - "Required": false, + "PrimitiveItemType": "String", + "Required": true, + "Type": "Map", "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-addattributes.html#cfn-iotanalytics-pipeline-addattributes-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36656,13 +37261,13 @@ "ChannelName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-channel.html#cfn-iotanalytics-pipeline-channel-channelname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-channel.html#cfn-iotanalytics-pipeline-channel-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36679,13 +37284,13 @@ "DatastoreName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-datastore.html#cfn-iotanalytics-pipeline-datastore-datastorename", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-datastore.html#cfn-iotanalytics-pipeline-datastore-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" } } @@ -36696,13 +37301,13 @@ "Attribute": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceregistryenrich.html#cfn-iotanalytics-pipeline-deviceregistryenrich-attribute", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceregistryenrich.html#cfn-iotanalytics-pipeline-deviceregistryenrich-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36714,13 +37319,13 @@ "RoleArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceregistryenrich.html#cfn-iotanalytics-pipeline-deviceregistryenrich-rolearn", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "ThingName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceregistryenrich.html#cfn-iotanalytics-pipeline-deviceregistryenrich-thingname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" } } @@ -36731,13 +37336,13 @@ "Attribute": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceshadowenrich.html#cfn-iotanalytics-pipeline-deviceshadowenrich-attribute", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceshadowenrich.html#cfn-iotanalytics-pipeline-deviceshadowenrich-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36749,13 +37354,13 @@ "RoleArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceshadowenrich.html#cfn-iotanalytics-pipeline-deviceshadowenrich-rolearn", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "ThingName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-deviceshadowenrich.html#cfn-iotanalytics-pipeline-deviceshadowenrich-thingname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" } } @@ -36766,13 +37371,13 @@ "Filter": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-filter.html#cfn-iotanalytics-pipeline-filter-filter", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-filter.html#cfn-iotanalytics-pipeline-filter-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36789,19 +37394,19 @@ "BatchSize": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-lambda.html#cfn-iotanalytics-pipeline-lambda-batchsize", "PrimitiveType": "Integer", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "LambdaName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-lambda.html#cfn-iotanalytics-pipeline-lambda-lambdaname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-lambda.html#cfn-iotanalytics-pipeline-lambda-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36818,19 +37423,19 @@ "Attribute": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-math.html#cfn-iotanalytics-pipeline-math-attribute", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Math": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-math.html#cfn-iotanalytics-pipeline-math-math", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-math.html#cfn-iotanalytics-pipeline-math-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36846,15 +37451,16 @@ "Properties": { "Attributes": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-removeattributes.html#cfn-iotanalytics-pipeline-removeattributes-attributes", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", - "Required": false, + "Required": true, "Type": "List", "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-removeattributes.html#cfn-iotanalytics-pipeline-removeattributes-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -36870,15 +37476,16 @@ "Properties": { "Attributes": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-selectattributes.html#cfn-iotanalytics-pipeline-selectattributes-attributes", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", - "Required": false, + "Required": true, "Type": "List", "UpdateType": "Mutable" }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iotanalytics-pipeline-selectattributes.html#cfn-iotanalytics-pipeline-selectattributes-name", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "Next": { @@ -50593,6 +51200,20 @@ "AWS::NetworkFirewall::FirewallPolicy.FirewallPolicy": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-firewallpolicy.html", "Properties": { + "StatefulDefaultActions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-firewallpolicy.html#cfn-networkfirewall-firewallpolicy-firewallpolicy-statefuldefaultactions", + "DuplicatesAllowed": false, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "StatefulEngineOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-firewallpolicy.html#cfn-networkfirewall-firewallpolicy-firewallpolicy-statefulengineoptions", + "Required": false, + "Type": "StatefulEngineOptions", + "UpdateType": "Mutable" + }, "StatefulRuleGroupReferences": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-firewallpolicy.html#cfn-networkfirewall-firewallpolicy-firewallpolicy-statefulrulegroupreferences", "DuplicatesAllowed": false, @@ -50648,9 +51269,26 @@ } } }, + "AWS::NetworkFirewall::FirewallPolicy.StatefulEngineOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-statefulengineoptions.html", + "Properties": { + "RuleOrder": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-statefulengineoptions.html#cfn-networkfirewall-firewallpolicy-statefulengineoptions-ruleorder", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::NetworkFirewall::FirewallPolicy.StatefulRuleGroupReference": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-statefulrulegroupreference.html", "Properties": { + "Priority": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-statefulrulegroupreference.html#cfn-networkfirewall-firewallpolicy-statefulrulegroupreference-priority", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, "ResourceArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-firewallpolicy-statefulrulegroupreference.html#cfn-networkfirewall-firewallpolicy-statefulrulegroupreference-resourcearn", "PrimitiveType": "String", @@ -50945,6 +51583,12 @@ "Required": true, "Type": "RulesSource", "UpdateType": "Mutable" + }, + "StatefulRuleOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-rulegroup.html#cfn-networkfirewall-rulegroup-rulegroup-statefulruleoptions", + "Required": false, + "Type": "StatefulRuleOptions", + "UpdateType": "Mutable" } } }, @@ -51069,6 +51713,17 @@ } } }, + "AWS::NetworkFirewall::RuleGroup.StatefulRuleOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-statefulruleoptions.html", + "Properties": { + "RuleOrder": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-statefulruleoptions.html#cfn-networkfirewall-rulegroup-statefulruleoptions-ruleorder", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::NetworkFirewall::RuleGroup.StatelessRule": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-networkfirewall-rulegroup-statelessrule.html", "Properties": { @@ -53000,6 +53655,180 @@ } } }, + "AWS::Pinpoint::InAppTemplate.BodyConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-bodyconfig.html", + "Properties": { + "Alignment": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-bodyconfig.html#cfn-pinpoint-inapptemplate-bodyconfig-alignment", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Body": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-bodyconfig.html#cfn-pinpoint-inapptemplate-bodyconfig-body", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "TextColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-bodyconfig.html#cfn-pinpoint-inapptemplate-bodyconfig-textcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Pinpoint::InAppTemplate.ButtonConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-buttonconfig.html", + "Properties": { + "Android": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-buttonconfig.html#cfn-pinpoint-inapptemplate-buttonconfig-android", + "Required": false, + "Type": "OverrideButtonConfiguration", + "UpdateType": "Mutable" + }, + "DefaultConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-buttonconfig.html#cfn-pinpoint-inapptemplate-buttonconfig-defaultconfig", + "Required": false, + "Type": "DefaultButtonConfiguration", + "UpdateType": "Mutable" + }, + "IOS": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-buttonconfig.html#cfn-pinpoint-inapptemplate-buttonconfig-ios", + "Required": false, + "Type": "OverrideButtonConfiguration", + "UpdateType": "Mutable" + }, + "Web": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-buttonconfig.html#cfn-pinpoint-inapptemplate-buttonconfig-web", + "Required": false, + "Type": "OverrideButtonConfiguration", + "UpdateType": "Mutable" + } + } + }, + "AWS::Pinpoint::InAppTemplate.DefaultButtonConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-defaultbuttonconfiguration.html", + "Properties": { + "BackgroundColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-defaultbuttonconfiguration.html#cfn-pinpoint-inapptemplate-defaultbuttonconfiguration-backgroundcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "BorderRadius": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-defaultbuttonconfiguration.html#cfn-pinpoint-inapptemplate-defaultbuttonconfiguration-borderradius", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "ButtonAction": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-defaultbuttonconfiguration.html#cfn-pinpoint-inapptemplate-defaultbuttonconfiguration-buttonaction", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Link": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-defaultbuttonconfiguration.html#cfn-pinpoint-inapptemplate-defaultbuttonconfiguration-link", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Text": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-defaultbuttonconfiguration.html#cfn-pinpoint-inapptemplate-defaultbuttonconfiguration-text", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "TextColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-defaultbuttonconfiguration.html#cfn-pinpoint-inapptemplate-defaultbuttonconfiguration-textcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Pinpoint::InAppTemplate.HeaderConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-headerconfig.html", + "Properties": { + "Alignment": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-headerconfig.html#cfn-pinpoint-inapptemplate-headerconfig-alignment", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Header": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-headerconfig.html#cfn-pinpoint-inapptemplate-headerconfig-header", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "TextColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-headerconfig.html#cfn-pinpoint-inapptemplate-headerconfig-textcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Pinpoint::InAppTemplate.InAppMessageContent": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-inappmessagecontent.html", + "Properties": { + "BackgroundColor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-inappmessagecontent.html#cfn-pinpoint-inapptemplate-inappmessagecontent-backgroundcolor", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "BodyConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-inappmessagecontent.html#cfn-pinpoint-inapptemplate-inappmessagecontent-bodyconfig", + "Required": false, + "Type": "BodyConfig", + "UpdateType": "Mutable" + }, + "HeaderConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-inappmessagecontent.html#cfn-pinpoint-inapptemplate-inappmessagecontent-headerconfig", + "Required": false, + "Type": "HeaderConfig", + "UpdateType": "Mutable" + }, + "ImageUrl": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-inappmessagecontent.html#cfn-pinpoint-inapptemplate-inappmessagecontent-imageurl", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "PrimaryBtn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-inappmessagecontent.html#cfn-pinpoint-inapptemplate-inappmessagecontent-primarybtn", + "Required": false, + "Type": "ButtonConfig", + "UpdateType": "Mutable" + }, + "SecondaryBtn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-inappmessagecontent.html#cfn-pinpoint-inapptemplate-inappmessagecontent-secondarybtn", + "Required": false, + "Type": "ButtonConfig", + "UpdateType": "Mutable" + } + } + }, + "AWS::Pinpoint::InAppTemplate.OverrideButtonConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-overridebuttonconfiguration.html", + "Properties": { + "ButtonAction": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-overridebuttonconfiguration.html#cfn-pinpoint-inapptemplate-overridebuttonconfiguration-buttonaction", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Link": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-inapptemplate-overridebuttonconfiguration.html#cfn-pinpoint-inapptemplate-overridebuttonconfiguration-link", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::Pinpoint::PushTemplate.APNSPushNotificationTemplate": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-pinpoint-pushtemplate-apnspushnotificationtemplate.html", "Properties": { @@ -55910,6 +56739,103 @@ } } }, + "AWS::Redshift::EndpointAccess.VpcSecurityGroup": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-endpointaccess-vpcsecuritygroup.html", + "Properties": { + "Status": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-endpointaccess-vpcsecuritygroup.html#cfn-redshift-endpointaccess-vpcsecuritygroup-status", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "VpcSecurityGroupId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-endpointaccess-vpcsecuritygroup.html#cfn-redshift-endpointaccess-vpcsecuritygroup-vpcsecuritygroupid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Redshift::ScheduledAction.PauseClusterMessage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-pauseclustermessage.html", + "Properties": { + "ClusterIdentifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-pauseclustermessage.html#cfn-redshift-scheduledaction-pauseclustermessage-clusteridentifier", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::Redshift::ScheduledAction.ResizeClusterMessage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html", + "Properties": { + "Classic": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-classic", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "ClusterIdentifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-clusteridentifier", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "ClusterType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-clustertype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "NodeType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-nodetype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "NumberOfNodes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resizeclustermessage.html#cfn-redshift-scheduledaction-resizeclustermessage-numberofnodes", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Redshift::ScheduledAction.ResumeClusterMessage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resumeclustermessage.html", + "Properties": { + "ClusterIdentifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-resumeclustermessage.html#cfn-redshift-scheduledaction-resumeclustermessage-clusteridentifier", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::Redshift::ScheduledAction.ScheduledActionType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-scheduledactiontype.html", + "Properties": { + "PauseCluster": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-scheduledactiontype.html#cfn-redshift-scheduledaction-scheduledactiontype-pausecluster", + "Required": false, + "Type": "PauseClusterMessage", + "UpdateType": "Mutable" + }, + "ResizeCluster": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-scheduledactiontype.html#cfn-redshift-scheduledaction-scheduledactiontype-resizecluster", + "Required": false, + "Type": "ResizeClusterMessage", + "UpdateType": "Mutable" + }, + "ResumeCluster": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-redshift-scheduledaction-scheduledactiontype.html#cfn-redshift-scheduledaction-scheduledactiontype-resumecluster", + "Required": false, + "Type": "ResumeClusterMessage", + "UpdateType": "Mutable" + } + } + }, "AWS::ResourceGroups::Group.ConfigurationItem": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-resourcegroups-group-configurationitem.html", "Properties": { @@ -60138,6 +61064,12 @@ "Type": "CapacitySize", "UpdateType": "Mutable" }, + "LinearStepSize": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-endpoint-trafficroutingconfig.html#cfn-sagemaker-endpoint-trafficroutingconfig-linearstepsize", + "Required": false, + "Type": "CapacitySize", + "UpdateType": "Mutable" + }, "Type": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sagemaker-endpoint-trafficroutingconfig.html#cfn-sagemaker-endpoint-trafficroutingconfig-type", "PrimitiveType": "String", @@ -65160,7 +66092,7 @@ } } }, - "ResourceSpecificationVersion": "46.0.0", + "ResourceSpecificationVersion": "47.0.0", "ResourceTypes": { "AWS::ACMPCA::Certificate": { "Attributes": { @@ -71860,6 +72792,25 @@ } } }, + "AWS::CloudFront::ResponseHeadersPolicy": { + "Attributes": { + "Id": { + "PrimitiveType": "String" + }, + "LastModifiedTime": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-responseheaderspolicy.html", + "Properties": { + "ResponseHeadersPolicyConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-responseheaderspolicy.html#cfn-cloudfront-responseheaderspolicy-responseheaderspolicyconfig", + "Required": true, + "Type": "ResponseHeadersPolicyConfig", + "UpdateType": "Mutable" + } + } + }, "AWS::CloudFront::StreamingDistribution": { "Attributes": { "DomainName": { @@ -75133,6 +76084,12 @@ "Type": "PostgreSqlSettings", "UpdateType": "Mutable" }, + "RedisSettings": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dms-endpoint.html#cfn-dms-endpoint-redissettings", + "Required": false, + "Type": "RedisSettings", + "UpdateType": "Mutable" + }, "RedshiftSettings": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dms-endpoint.html#cfn-dms-endpoint-redshiftsettings", "Required": false, @@ -75937,6 +76894,101 @@ } } }, + "AWS::DataSync::LocationHDFS": { + "Attributes": { + "LocationArn": { + "PrimitiveType": "String" + }, + "LocationUri": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html", + "Properties": { + "AgentArns": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-agentarns", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "AuthenticationType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-authenticationtype", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "BlockSize": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-blocksize", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "KerberosKeytab": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-kerberoskeytab", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "KerberosKrb5Conf": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-kerberoskrb5conf", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "KerberosPrincipal": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-kerberosprincipal", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "KmsKeyProviderUri": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-kmskeyprovideruri", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "NameNodes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-namenodes", + "ItemType": "NameNode", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "QopConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-qopconfiguration", + "Required": false, + "Type": "QopConfiguration", + "UpdateType": "Mutable" + }, + "ReplicationFactor": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-replicationfactor", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "SimpleUser": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-simpleuser", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Subdirectory": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-subdirectory", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationhdfs.html#cfn-datasync-locationhdfs-tags", + "DuplicatesAllowed": false, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "AWS::DataSync::LocationNFS": { "Attributes": { "LocationArn": { @@ -77944,6 +78996,11 @@ } }, "AWS::EC2::InternetGateway": { + "Attributes": { + "InternetGatewayId": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-internetgateway.html", "Properties": { "Tags": { @@ -78296,44 +79353,48 @@ }, "AWS::EC2::NetworkInterface": { "Attributes": { + "Id": { + "PrimitiveType": "String" + }, "PrimaryPrivateIpAddress": { "PrimitiveType": "String" }, "SecondaryPrivateIpAddresses": { + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Type": "List" } }, - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html", "Properties": { "Description": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-description", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-description", "PrimitiveType": "String", "Required": false, "UpdateType": "Mutable" }, "GroupSet": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-groupset", - "DuplicatesAllowed": false, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-groupset", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", "UpdateType": "Mutable" }, "InterfaceType": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-interfacetype", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-interfacetype", "PrimitiveType": "String", "Required": false, "UpdateType": "Immutable" }, "Ipv6AddressCount": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-ipv6addresscount", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-ipv6addresscount", "PrimitiveType": "Integer", "Required": false, "UpdateType": "Mutable" }, "Ipv6Addresses": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-ec2-networkinterface-ipv6addresses", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-ipv6addresses", "DuplicatesAllowed": false, "ItemType": "InstanceIpv6Address", "Required": false, @@ -78341,39 +79402,39 @@ "UpdateType": "Mutable" }, "PrivateIpAddress": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-privateipaddress", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-privateipaddress", "PrimitiveType": "String", "Required": false, "UpdateType": "Immutable" }, "PrivateIpAddresses": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-privateipaddresses", - "DuplicatesAllowed": false, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-privateipaddresses", + "DuplicatesAllowed": true, "ItemType": "PrivateIpAddressSpecification", "Required": false, "Type": "List", - "UpdateType": "Conditional" + "UpdateType": "Mutable" }, "SecondaryPrivateIpAddressCount": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-secondaryprivateipcount", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-secondaryprivateipaddresscount", "PrimitiveType": "Integer", "Required": false, "UpdateType": "Mutable" }, "SourceDestCheck": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-sourcedestcheck", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-sourcedestcheck", "PrimitiveType": "Boolean", "Required": false, "UpdateType": "Mutable" }, "SubnetId": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-subnetid", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-subnetid", "PrimitiveType": "String", "Required": true, "UpdateType": "Immutable" }, "Tags": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-network-interface.html#cfn-awsec2networkinterface-tags", + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-networkinterface.html#cfn-ec2-networkinterface-tags", "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, @@ -79451,6 +80512,12 @@ }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaypeeringattachment.html", "Properties": { + "Options": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaypeeringattachment.html#cfn-ec2-transitgatewaypeeringattachment-options", + "Required": false, + "Type": "TransitGatewayPeeringAttachmentOptions", + "UpdateType": "Mutable" + }, "PeerAccountId": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-transitgatewaypeeringattachment.html#cfn-ec2-transitgatewaypeeringattachment-peeraccountid", "PrimitiveType": "String", @@ -79857,6 +80924,12 @@ "Required": false, "Type": "List", "UpdateType": "Mutable" + }, + "PayerResponsibility": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpcendpointservice.html#cfn-ec2-vpcendpointservice-payerresponsibility", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" } } }, @@ -80997,6 +82070,12 @@ "Type": "KubernetesNetworkConfig", "UpdateType": "Immutable" }, + "Logging": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-logging", + "Required": false, + "Type": "Logging", + "UpdateType": "Mutable" + }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-name", "PrimitiveType": "String", @@ -81007,7 +82086,7 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-resourcesvpcconfig", "Required": true, "Type": "ResourcesVpcConfig", - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "RoleArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-rolearn", @@ -81015,6 +82094,14 @@ "Required": true, "UpdateType": "Immutable" }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-tags", + "DuplicatesAllowed": false, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "Version": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-cluster.html#cfn-eks-cluster-version", "PrimitiveType": "String", @@ -88225,6 +89312,29 @@ } } }, + "AWS::IoT::Logging": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-logging.html", + "Properties": { + "AccountId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-logging.html#cfn-iot-logging-accountid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "DefaultLogLevel": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-logging.html#cfn-iot-logging-defaultloglevel", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "RoleArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-logging.html#cfn-iot-logging-rolearn", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, "AWS::IoT::MitigationAction": { "Attributes": { "MitigationActionArn": { @@ -88356,6 +89466,34 @@ } } }, + "AWS::IoT::ResourceSpecificLogging": { + "Attributes": { + "TargetId": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-resourcespecificlogging.html", + "Properties": { + "LogLevel": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-resourcespecificlogging.html#cfn-iot-resourcespecificlogging-loglevel", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "TargetName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-resourcespecificlogging.html#cfn-iot-resourcespecificlogging-targetname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "TargetType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iot-resourcespecificlogging.html#cfn-iot-resourcespecificlogging-targettype", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, "AWS::IoT::ScheduledAudit": { "Attributes": { "ScheduledAuditArn": { @@ -88562,12 +89700,17 @@ } }, "AWS::IoTAnalytics::Channel": { + "Attributes": { + "Id": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-channel.html", "Properties": { "ChannelName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-channel.html#cfn-iotanalytics-channel-channelname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Immutable" }, "ChannelStorage": { @@ -88584,6 +89727,7 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-channel.html#cfn-iotanalytics-channel-tags", + "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, "Type": "List", @@ -88592,10 +89736,16 @@ } }, "AWS::IoTAnalytics::Dataset": { + "Attributes": { + "Id": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-dataset.html", "Properties": { "Actions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-dataset.html#cfn-iotanalytics-dataset-actions", + "DuplicatesAllowed": true, "ItemType": "Action", "Required": true, "Type": "List", @@ -88603,6 +89753,7 @@ }, "ContentDeliveryRules": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-dataset.html#cfn-iotanalytics-dataset-contentdeliveryrules", + "DuplicatesAllowed": true, "ItemType": "DatasetContentDeliveryRule", "Required": false, "Type": "List", @@ -88611,11 +89762,12 @@ "DatasetName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-dataset.html#cfn-iotanalytics-dataset-datasetname", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Immutable" }, "LateDataRules": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-dataset.html#cfn-iotanalytics-dataset-latedatarules", + "DuplicatesAllowed": true, "ItemType": "LateDataRule", "Required": false, "Type": "List", @@ -88629,6 +89781,7 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-dataset.html#cfn-iotanalytics-dataset-tags", + "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, "Type": "List", @@ -88636,6 +89789,7 @@ }, "Triggers": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-dataset.html#cfn-iotanalytics-dataset-triggers", + "DuplicatesAllowed": true, "ItemType": "Trigger", "Required": false, "Type": "List", @@ -88650,6 +89804,11 @@ } }, "AWS::IoTAnalytics::Datastore": { + "Attributes": { + "Id": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-datastore.html", "Properties": { "DatastoreName": { @@ -88684,6 +89843,7 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-datastore.html#cfn-iotanalytics-datastore-tags", + "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, "Type": "List", @@ -88692,10 +89852,16 @@ } }, "AWS::IoTAnalytics::Pipeline": { + "Attributes": { + "Id": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-pipeline.html", "Properties": { "PipelineActivities": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-pipeline.html#cfn-iotanalytics-pipeline-pipelineactivities", + "DuplicatesAllowed": true, "ItemType": "Activity", "Required": true, "Type": "List", @@ -88704,11 +89870,12 @@ "PipelineName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-pipeline.html#cfn-iotanalytics-pipeline-pipelinename", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Immutable" }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iotanalytics-pipeline.html#cfn-iotanalytics-pipeline-tags", + "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, "Type": "List", @@ -96373,6 +97540,53 @@ } } }, + "AWS::Pinpoint::InAppTemplate": { + "Attributes": { + "Arn": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-inapptemplate.html", + "Properties": { + "Content": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-inapptemplate.html#cfn-pinpoint-inapptemplate-content", + "ItemType": "InAppMessageContent", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "CustomConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-inapptemplate.html#cfn-pinpoint-inapptemplate-customconfig", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Mutable" + }, + "Layout": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-inapptemplate.html#cfn-pinpoint-inapptemplate-layout", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-inapptemplate.html#cfn-pinpoint-inapptemplate-tags", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Mutable" + }, + "TemplateDescription": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-inapptemplate.html#cfn-pinpoint-inapptemplate-templatedescription", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "TemplateName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-pinpoint-inapptemplate.html#cfn-pinpoint-inapptemplate-templatename", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, "AWS::Pinpoint::PushTemplate": { "Attributes": { "Arn": { @@ -98792,6 +100006,257 @@ } } }, + "AWS::Redshift::EndpointAccess": { + "Attributes": { + "Address": { + "PrimitiveType": "String" + }, + "EndpointCreateTime": { + "PrimitiveType": "String" + }, + "EndpointStatus": { + "PrimitiveType": "String" + }, + "Port": { + "PrimitiveType": "Integer" + }, + "VpcSecurityGroups": { + "ItemType": "VpcSecurityGroup", + "Type": "List" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html", + "Properties": { + "ClusterIdentifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-clusteridentifier", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "EndpointName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-endpointname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "ResourceOwner": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-resourceowner", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "SubnetGroupName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-subnetgroupname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "VpcSecurityGroupIds": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointaccess.html#cfn-redshift-endpointaccess-vpcsecuritygroupids", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::Redshift::EndpointAuthorization": { + "Attributes": { + "AllowedAllVPCs": { + "PrimitiveType": "Boolean" + }, + "AllowedVPCs": { + "PrimitiveItemType": "String", + "Type": "List" + }, + "AuthorizeTime": { + "PrimitiveType": "String" + }, + "ClusterStatus": { + "PrimitiveType": "String" + }, + "EndpointCount": { + "PrimitiveType": "Integer" + }, + "Grantee": { + "PrimitiveType": "String" + }, + "Grantor": { + "PrimitiveType": "String" + }, + "Status": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html", + "Properties": { + "Account": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-account", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "ClusterIdentifier": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-clusteridentifier", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Force": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-force", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "VpcIds": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-endpointauthorization.html#cfn-redshift-endpointauthorization-vpcids", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::Redshift::EventSubscription": { + "Attributes": { + "CustSubscriptionId": { + "PrimitiveType": "String" + }, + "CustomerAwsId": { + "PrimitiveType": "String" + }, + "EventCategoriesList": { + "PrimitiveItemType": "String", + "Type": "List" + }, + "SourceIdsList": { + "PrimitiveItemType": "String", + "Type": "List" + }, + "Status": { + "PrimitiveType": "String" + }, + "SubscriptionCreationTime": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html", + "Properties": { + "Enabled": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-enabled", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "EventCategories": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-eventcategories", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "Severity": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-severity", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SnsTopicArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-snstopicarn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SourceIds": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-sourceids", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "SourceType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-sourcetype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SubscriptionName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-subscriptionname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-eventsubscription.html#cfn-redshift-eventsubscription-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::Redshift::ScheduledAction": { + "Attributes": { + "NextInvocations": { + "PrimitiveItemType": "String", + "Type": "List" + }, + "State": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html", + "Properties": { + "Enable": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-enable", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "EndTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-endtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "IamRole": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-iamrole", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Schedule": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-schedule", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ScheduledActionDescription": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-scheduledactiondescription", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ScheduledActionName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-scheduledactionname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "StartTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-starttime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "TargetAction": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-redshift-scheduledaction.html#cfn-redshift-scheduledaction-targetaction", + "Required": false, + "Type": "ScheduledActionType", + "UpdateType": "Mutable" + } + } + }, "AWS::Rekognition::Project": { "Attributes": { "Arn": { @@ -100388,7 +101853,7 @@ "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3objectlambda-accesspoint.html#cfn-s3objectlambda-accesspoint-name", "PrimitiveType": "String", - "Required": true, + "Required": false, "UpdateType": "Immutable" }, "ObjectLambdaConfiguration": { @@ -102174,6 +103639,12 @@ "Required": false, "UpdateType": "Mutable" }, + "RetainDeploymentConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-endpoint.html#cfn-sagemaker-endpoint-retaindeploymentconfig", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sagemaker-endpoint.html#cfn-sagemaker-endpoint-tags", "ItemType": "Tag", From 7886607528b0cb005fa1176803b2a45d3e948f48 Mon Sep 17 00:00:00 2001 From: AWS CDK Automation <43080478+aws-cdk-automation@users.noreply.github.com> Date: Fri, 5 Nov 2021 16:31:22 +0530 Subject: [PATCH 51/70] feat(cfnspec): cloudformation spec v47.0.0 (#17353) Co-authored-by: AWS CDK Team Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> From 332ce4d9ae995bd1336fef13e2c7f9fc0c12f34d Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Fri, 5 Nov 2021 12:58:12 +0100 Subject: [PATCH 52/70] fix(cli): `wmic not found` on modern Windows systems (#17070) Apparently Microsoft stopped shipping `wmic.exe` in certain situations (modern systems?). We rely on this to detect whether we are on an EC2 instance, so that we do or do not configure the IMDS credential provider (we try to avoid the IMDS credential provider if unnecessary, because in certain network setups it may hang for a long time failing to connect to `169.254.169.254`). If calling `wmic` fails, just assume we're not on an EC2 instance and proceed. Fixes #16419. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../lib/api/aws-auth/awscli-compatible.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/aws-cdk/lib/api/aws-auth/awscli-compatible.ts b/packages/aws-cdk/lib/api/aws-auth/awscli-compatible.ts index b409274efa59c..eb141768b9644 100644 --- a/packages/aws-cdk/lib/api/aws-auth/awscli-compatible.ts +++ b/packages/aws-cdk/lib/api/aws-auth/awscli-compatible.ts @@ -177,12 +177,18 @@ async function isEc2Instance() { let instance = false; if (process.platform === 'win32') { // https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/identify_ec2_instances.html - const result = await util.promisify(child_process.exec)('wmic path win32_computersystemproduct get uuid', { encoding: 'utf-8' }); - // output looks like - // UUID - // EC2AE145-D1DC-13B2-94ED-01234ABCDEF - const lines = result.stdout.toString().split('\n'); - instance = lines.some(x => matchesRegex(/^ec2/i, x)); + try { + const result = await util.promisify(child_process.exec)('wmic path win32_computersystemproduct get uuid', { encoding: 'utf-8' }); + // output looks like + // UUID + // EC2AE145-D1DC-13B2-94ED-01234ABCDEF + const lines = result.stdout.toString().split('\n'); + instance = lines.some(x => matchesRegex(/^ec2/i, x)); + } catch (e) { + // Modern machines may not have wmic.exe installed. No reason to fail, just assume it's not an EC2 instance. + debug(`Checking using WMIC failed, assuming NOT an EC2 instance: ${e.message} (pass --ec2creds to force)`); + instance = false; + } } else { // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/identify_ec2_instances.html const files: Array<[string, RegExp]> = [ From 9e81dc731993a55fbc05c642ce96151f12ed69da Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Fri, 5 Nov 2021 13:54:00 +0100 Subject: [PATCH 53/70] fix(pipelines): `additionalInputs` not working (#17279) The rendering of `additionalInputs` was using a bashism that is not supported by CodeBuild by default. Turn ``` [[ ! -d "directory" ]] ``` into ``` [ ! -d "directory" ] ``` Fixes #17224 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.ts | 2 +- .../pipelines/test/codepipeline/codebuild-step.test.ts | 2 +- packages/@aws-cdk/pipelines/test/compliance/synths.test.ts | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.ts b/packages/@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.ts index fb523cf7d6818..7534aba9cb840 100644 --- a/packages/@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.ts +++ b/packages/@aws-cdk/pipelines/lib/codepipeline/_codebuild-factory.ts @@ -333,7 +333,7 @@ function generateInputArtifactLinkCommands(artifacts: ArtifactMap, inputs: FileS return inputs.map(input => { const fragments = []; - fragments.push(`[[ ! -d "${input.directory}" ]] || { echo 'additionalInputs: "${input.directory}" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.'; exit 1; }`); + fragments.push(`[ ! -d "${input.directory}" ] || { echo 'additionalInputs: "${input.directory}" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.'; exit 1; }`); const parentDirectory = path.dirname(input.directory); if (!['.', '..'].includes(parentDirectory)) { diff --git a/packages/@aws-cdk/pipelines/test/codepipeline/codebuild-step.test.ts b/packages/@aws-cdk/pipelines/test/codepipeline/codebuild-step.test.ts index 78f1e0f471655..166e6c9336dd1 100644 --- a/packages/@aws-cdk/pipelines/test/codepipeline/codebuild-step.test.ts +++ b/packages/@aws-cdk/pipelines/test/codepipeline/codebuild-step.test.ts @@ -34,7 +34,7 @@ test('additionalinputs creates the right commands', () => { phases: { install: { commands: [ - '[[ ! -d "some/deep/directory" ]] || { echo \'additionalInputs: "some/deep/directory" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.\'; exit 1; } && mkdir -p -- "some/deep" && ln -s -- "$CODEBUILD_SRC_DIR_test2_test2_Source" "some/deep/directory"', + '[ ! -d "some/deep/directory" ] || { echo \'additionalInputs: "some/deep/directory" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.\'; exit 1; } && mkdir -p -- "some/deep" && ln -s -- "$CODEBUILD_SRC_DIR_test2_test2_Source" "some/deep/directory"', ], }, }, diff --git a/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts b/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts index acbce1d765f36..03ee0686f1807 100644 --- a/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts +++ b/packages/@aws-cdk/pipelines/test/compliance/synths.test.ts @@ -947,8 +947,8 @@ behavior('Multiple input sources in side-by-side directories', (suite) => { phases: { install: { commands: [ - '[[ ! -d "../sibling" ]] || { echo \'additionalInputs: "../sibling" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.\'; exit 1; } && ln -s -- "$CODEBUILD_SRC_DIR_foo_bar_Source" "../sibling"', - '[[ ! -d "sub" ]] || { echo \'additionalInputs: "sub" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.\'; exit 1; } && ln -s -- "$CODEBUILD_SRC_DIR_Prebuild_Output" "sub"', + '[ ! -d "../sibling" ] || { echo \'additionalInputs: "../sibling" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.\'; exit 1; } && ln -s -- "$CODEBUILD_SRC_DIR_foo_bar_Source" "../sibling"', + '[ ! -d "sub" ] || { echo \'additionalInputs: "sub" must not exist yet. If you want to merge multiple artifacts, use a "cp" command.\'; exit 1; } && ln -s -- "$CODEBUILD_SRC_DIR_Prebuild_Output" "sub"', ], }, build: { From 1aa1588640b34be1dc027f79e3b9dd90e9b8b26f Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Fri, 5 Nov 2021 16:06:15 +0200 Subject: [PATCH 54/70] chore: remove invalid test from regression suite (#17345) Follow up on https://github.com/aws/aws-cdk/pull/17337 to fix regression suites. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../cli-regression-patches/v1.130.0/NOTES.md | 10 +- .../v1.130.0/bootstrapping.integtest.js | 220 ++++++++++++++++++ 2 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/bootstrapping.integtest.js diff --git a/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md index 9a9338f4d04fb..5e17983dd23b4 100644 --- a/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md +++ b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/NOTES.md @@ -1,4 +1,12 @@ +--------------------------------------- + On november 2nd 2021, lambda started deprecating the nodejs10.x runtime. This meant we can no longer create functions with this runtime. Our integration tests use this runtime for one of its stacks. -This patch brings https://github.com/aws/aws-cdk/pull/17282 into the regression suite. \ No newline at end of file +This patch brings https://github.com/aws/aws-cdk/pull/17282 into the regression suite. + +---------------------------------------- + +Needs to disable an existing test due to change in bootstrap of integration tests. + +This patch brings https://github.com/aws/aws-cdk/pull/17337 into the regression suite. \ No newline at end of file diff --git a/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/bootstrapping.integtest.js b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/bootstrapping.integtest.js new file mode 100644 index 0000000000000..5895d49ff1ad9 --- /dev/null +++ b/packages/aws-cdk/test/integ/cli-regression-patches/v1.130.0/bootstrapping.integtest.js @@ -0,0 +1,220 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const fs = require("fs"); +const path = require("path"); +const cdk_1 = require("../helpers/cdk"); +const test_helpers_1 = require("../helpers/test-helpers"); +const timeout = process.env.CODEBUILD_BUILD_ID ? // if the process is running in CodeBuild + 3600000 : // 1 hour + 600000; // 10 minutes +jest.setTimeout(timeout); +process.stdout.write(`bootstrapping.integtest.ts: Setting jest time out to ${timeout} ms`); +test_helpers_1.integTest('can bootstrap without execution', cdk_1.withDefaultFixture(async (fixture) => { + var _a; + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapLegacy({ + toolkitStackName: bootstrapStackName, + noExecute: true, + }); + const resp = await fixture.aws.cloudFormation('describeStacks', { + StackName: bootstrapStackName, + }); + expect((_a = resp.Stacks) === null || _a === void 0 ? void 0 : _a[0].StackStatus).toEqual('REVIEW_IN_PROGRESS'); +})); +test_helpers_1.integTest('upgrade legacy bootstrap stack to new bootstrap stack while in use', cdk_1.withDefaultFixture(async (fixture) => { + const bootstrapStackName = fixture.bootstrapStackName; + const legacyBootstrapBucketName = `aws-cdk-bootstrap-integ-test-legacy-bckt-${cdk_1.randomString()}`; + const newBootstrapBucketName = `aws-cdk-bootstrap-integ-test-v2-bckt-${cdk_1.randomString()}`; + fixture.rememberToDeleteBucket(legacyBootstrapBucketName); // This one will leak + fixture.rememberToDeleteBucket(newBootstrapBucketName); // This one shouldn't leak if the test succeeds, but let's be safe in case it doesn't + // Legacy bootstrap + await fixture.cdkBootstrapLegacy({ + toolkitStackName: bootstrapStackName, + bootstrapBucketName: legacyBootstrapBucketName, + }); + // Deploy stack that uses file assets + await fixture.cdkDeploy('lambda', { + options: ['--toolkit-stack-name', bootstrapStackName], + }); + // Upgrade bootstrap stack to "new" style + await fixture.cdkBootstrapModern({ + toolkitStackName: bootstrapStackName, + bootstrapBucketName: newBootstrapBucketName, + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); + // (Force) deploy stack again + // --force to bypass the check which says that the template hasn't changed. + await fixture.cdkDeploy('lambda', { + options: [ + '--toolkit-stack-name', bootstrapStackName, + '--force', + ], + }); +})); +test_helpers_1.integTest('can and deploy if omitting execution policies', cdk_1.withDefaultFixture(async (fixture) => { + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapModern({ + toolkitStackName: bootstrapStackName, + }); + // Deploy stack that uses file assets + await fixture.cdkDeploy('lambda', { + options: [ + '--toolkit-stack-name', bootstrapStackName, + '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`, + '--context', '@aws-cdk/core:newStyleStackSynthesis=1', + ], + }); +})); +test_helpers_1.integTest('deploy new style synthesis to new style bootstrap', cdk_1.withDefaultFixture(async (fixture) => { + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapModern({ + toolkitStackName: bootstrapStackName, + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); + // Deploy stack that uses file assets + await fixture.cdkDeploy('lambda', { + options: [ + '--toolkit-stack-name', bootstrapStackName, + '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`, + '--context', '@aws-cdk/core:newStyleStackSynthesis=1', + ], + }); +})); +test_helpers_1.integTest('deploy new style synthesis to new style bootstrap (with docker image)', cdk_1.withDefaultFixture(async (fixture) => { + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapModern({ + toolkitStackName: bootstrapStackName, + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); + // Deploy stack that uses file assets + await fixture.cdkDeploy('docker', { + options: [ + '--toolkit-stack-name', bootstrapStackName, + '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`, + '--context', '@aws-cdk/core:newStyleStackSynthesis=1', + ], + }); +})); +test_helpers_1.integTest('deploy old style synthesis to new style bootstrap', cdk_1.withDefaultFixture(async (fixture) => { + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapModern({ + toolkitStackName: bootstrapStackName, + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); + // Deploy stack that uses file assets + await fixture.cdkDeploy('lambda', { + options: [ + '--toolkit-stack-name', bootstrapStackName, + ], + }); +})); +test_helpers_1.integTest('can create a legacy bootstrap stack with --public-access-block-configuration=false', cdk_1.withDefaultFixture(async (fixture) => { + var _a; + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapLegacy({ + verbose: true, + toolkitStackName: bootstrapStackName, + publicAccessBlockConfiguration: false, + tags: 'Foo=Bar', + }); + const response = await fixture.aws.cloudFormation('describeStacks', { StackName: bootstrapStackName }); + expect((_a = response.Stacks) === null || _a === void 0 ? void 0 : _a[0].Tags).toEqual([ + { Key: 'Foo', Value: 'Bar' }, + ]); +})); +test_helpers_1.integTest('can create multiple legacy bootstrap stacks', cdk_1.withDefaultFixture(async (fixture) => { + var _a; + const bootstrapStackName1 = `${fixture.bootstrapStackName}-1`; + const bootstrapStackName2 = `${fixture.bootstrapStackName}-2`; + // deploy two toolkit stacks into the same environment (see #1416) + // one with tags + await fixture.cdkBootstrapLegacy({ + verbose: true, + toolkitStackName: bootstrapStackName1, + tags: 'Foo=Bar', + }); + await fixture.cdkBootstrapLegacy({ + verbose: true, + toolkitStackName: bootstrapStackName2, + }); + const response = await fixture.aws.cloudFormation('describeStacks', { StackName: bootstrapStackName1 }); + expect((_a = response.Stacks) === null || _a === void 0 ? void 0 : _a[0].Tags).toEqual([ + { Key: 'Foo', Value: 'Bar' }, + ]); +})); +test_helpers_1.integTest('can dump the template, modify and use it to deploy a custom bootstrap stack', cdk_1.withDefaultFixture(async (fixture) => { + let template = await fixture.cdkBootstrapModern({ + // toolkitStackName doesn't matter for this particular invocation + toolkitStackName: fixture.bootstrapStackName, + showTemplate: true, + cliOptions: { + captureStderr: false, + }, + }); + expect(template).toContain('BootstrapVersion:'); + template += '\n' + [ + ' TwiddleDee:', + ' Value: Template got twiddled', + ].join('\n'); + const filename = path.join(fixture.integTestDir, `${fixture.qualifier}-template.yaml`); + fs.writeFileSync(filename, template, { encoding: 'utf-8' }); + await fixture.cdkBootstrapModern({ + toolkitStackName: fixture.bootstrapStackName, + template: filename, + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); +})); +test_helpers_1.integTest('switch on termination protection, switch is left alone on re-bootstrap', cdk_1.withDefaultFixture(async (fixture) => { + var _a; + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapModern({ + verbose: true, + toolkitStackName: bootstrapStackName, + terminationProtection: true, + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); + await fixture.cdkBootstrapModern({ + verbose: true, + toolkitStackName: bootstrapStackName, + force: true, + }); + const response = await fixture.aws.cloudFormation('describeStacks', { StackName: bootstrapStackName }); + expect((_a = response.Stacks) === null || _a === void 0 ? void 0 : _a[0].EnableTerminationProtection).toEqual(true); +})); +test_helpers_1.integTest('add tags, left alone on re-bootstrap', cdk_1.withDefaultFixture(async (fixture) => { + var _a; + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapModern({ + verbose: true, + toolkitStackName: bootstrapStackName, + tags: 'Foo=Bar', + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); + await fixture.cdkBootstrapModern({ + verbose: true, + toolkitStackName: bootstrapStackName, + force: true, + }); + const response = await fixture.aws.cloudFormation('describeStacks', { StackName: bootstrapStackName }); + expect((_a = response.Stacks) === null || _a === void 0 ? void 0 : _a[0].Tags).toEqual([ + { Key: 'Foo', Value: 'Bar' }, + ]); +})); +test_helpers_1.integTest('can deploy modern-synthesized stack even if bootstrap stack name is unknown', cdk_1.withDefaultFixture(async (fixture) => { + const bootstrapStackName = fixture.bootstrapStackName; + await fixture.cdkBootstrapModern({ + toolkitStackName: bootstrapStackName, + cfnExecutionPolicy: 'arn:aws:iam::aws:policy/AdministratorAccess', + }); + // Deploy stack that uses file assets + await fixture.cdkDeploy('lambda', { + options: [ + // Explicity pass a name that's sure to not exist, otherwise the CLI might accidentally find a + // default bootstracp stack if that happens to be in the account already. + '--toolkit-stack-name', 'DefinitelyDoesNotExist', + '--context', `@aws-cdk/core:bootstrapQualifier=${fixture.qualifier}`, + '--context', '@aws-cdk/core:newStyleStackSynthesis=1', + ], + }); +})); +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm9vdHN0cmFwcGluZy5pbnRlZ3Rlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJib290c3RyYXBwaW5nLmludGVndGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLHlCQUF5QjtBQUN6Qiw2QkFBNkI7QUFDN0Isd0NBQWtFO0FBQ2xFLDBEQUFvRDtBQUVwRCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyx5Q0FBeUM7SUFDeEYsT0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTO0lBQ3JCLE1BQU8sQ0FBQyxDQUFDLGFBQWE7QUFDeEIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUN6QixPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyx3REFBd0QsT0FBTyxLQUFLLENBQUMsQ0FBQztBQUUzRix3QkFBUyxDQUFDLGlDQUFpQyxFQUFFLHdCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTs7SUFDaEYsTUFBTSxrQkFBa0IsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUM7SUFFdEQsTUFBTSxPQUFPLENBQUMsa0JBQWtCLENBQUM7UUFDL0IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLFNBQVMsRUFBRSxJQUFJO0tBQ2hCLENBQUMsQ0FBQztJQUVILE1BQU0sSUFBSSxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLEVBQUU7UUFDOUQsU0FBUyxFQUFFLGtCQUFrQjtLQUM5QixDQUFDLENBQUM7SUFFSCxNQUFNLE9BQUMsSUFBSSxDQUFDLE1BQU0sMENBQUcsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBQ3JFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFSix3QkFBUyxDQUFDLG9FQUFvRSxFQUFFLHdCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUNuSCxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztJQUV0RCxNQUFNLHlCQUF5QixHQUFHLDRDQUE0QyxrQkFBWSxFQUFFLEVBQUUsQ0FBQztJQUMvRixNQUFNLHNCQUFzQixHQUFHLHdDQUF3QyxrQkFBWSxFQUFFLEVBQUUsQ0FBQztJQUN4RixPQUFPLENBQUMsc0JBQXNCLENBQUMseUJBQXlCLENBQUMsQ0FBQyxDQUFDLHFCQUFxQjtJQUNoRixPQUFPLENBQUMsc0JBQXNCLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLHFGQUFxRjtJQUU3SSxtQkFBbUI7SUFDbkIsTUFBTSxPQUFPLENBQUMsa0JBQWtCLENBQUM7UUFDL0IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLG1CQUFtQixFQUFFLHlCQUF5QjtLQUMvQyxDQUFDLENBQUM7SUFFSCxxQ0FBcUM7SUFDckMsTUFBTSxPQUFPLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRTtRQUNoQyxPQUFPLEVBQUUsQ0FBQyxzQkFBc0IsRUFBRSxrQkFBa0IsQ0FBQztLQUN0RCxDQUFDLENBQUM7SUFFSCx5Q0FBeUM7SUFDekMsTUFBTSxPQUFPLENBQUMsa0JBQWtCLENBQUM7UUFDL0IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLG1CQUFtQixFQUFFLHNCQUFzQjtRQUMzQyxrQkFBa0IsRUFBRSw2Q0FBNkM7S0FDbEUsQ0FBQyxDQUFDO0lBRUgsNkJBQTZCO0lBQzdCLDJFQUEyRTtJQUMzRSxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFO1FBQ2hDLE9BQU8sRUFBRTtZQUNQLHNCQUFzQixFQUFFLGtCQUFrQjtZQUMxQyxTQUFTO1NBQ1Y7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRUosd0JBQVMsQ0FBQywrQ0FBK0MsRUFBRSx3QkFBa0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7SUFDOUYsTUFBTSxrQkFBa0IsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUM7SUFFdEQsTUFBTSxPQUFPLENBQUMsa0JBQWtCLENBQUM7UUFDL0IsZ0JBQWdCLEVBQUUsa0JBQWtCO0tBQ3JDLENBQUMsQ0FBQztJQUVILHFDQUFxQztJQUNyQyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFO1FBQ2hDLE9BQU8sRUFBRTtZQUNQLHNCQUFzQixFQUFFLGtCQUFrQjtZQUMxQyxXQUFXLEVBQUUsb0NBQW9DLE9BQU8sQ0FBQyxTQUFTLEVBQUU7WUFDcEUsV0FBVyxFQUFFLHdDQUF3QztTQUN0RDtLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFSix3QkFBUyxDQUFDLG1EQUFtRCxFQUFFLHdCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUNsRyxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztJQUV0RCxNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQixnQkFBZ0IsRUFBRSxrQkFBa0I7UUFDcEMsa0JBQWtCLEVBQUUsNkNBQTZDO0tBQ2xFLENBQUMsQ0FBQztJQUVILHFDQUFxQztJQUNyQyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFO1FBQ2hDLE9BQU8sRUFBRTtZQUNQLHNCQUFzQixFQUFFLGtCQUFrQjtZQUMxQyxXQUFXLEVBQUUsb0NBQW9DLE9BQU8sQ0FBQyxTQUFTLEVBQUU7WUFDcEUsV0FBVyxFQUFFLHdDQUF3QztTQUN0RDtLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFSix3QkFBUyxDQUFDLHVFQUF1RSxFQUFFLHdCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUN0SCxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztJQUV0RCxNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQixnQkFBZ0IsRUFBRSxrQkFBa0I7UUFDcEMsa0JBQWtCLEVBQUUsNkNBQTZDO0tBQ2xFLENBQUMsQ0FBQztJQUVILHFDQUFxQztJQUNyQyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFO1FBQ2hDLE9BQU8sRUFBRTtZQUNQLHNCQUFzQixFQUFFLGtCQUFrQjtZQUMxQyxXQUFXLEVBQUUsb0NBQW9DLE9BQU8sQ0FBQyxTQUFTLEVBQUU7WUFDcEUsV0FBVyxFQUFFLHdDQUF3QztTQUN0RDtLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFSix3QkFBUyxDQUFDLG1EQUFtRCxFQUFFLHdCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUNsRyxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztJQUV0RCxNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQixnQkFBZ0IsRUFBRSxrQkFBa0I7UUFDcEMsa0JBQWtCLEVBQUUsNkNBQTZDO0tBQ2xFLENBQUMsQ0FBQztJQUVILHFDQUFxQztJQUNyQyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFO1FBQ2hDLE9BQU8sRUFBRTtZQUNQLHNCQUFzQixFQUFFLGtCQUFrQjtTQUMzQztLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFFSix3QkFBUyxDQUFDLG9GQUFvRixFQUFFLHdCQUFrQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTs7SUFDbkksTUFBTSxrQkFBa0IsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUM7SUFFdEQsTUFBTSxPQUFPLENBQUMsa0JBQWtCLENBQUM7UUFDL0IsT0FBTyxFQUFFLElBQUk7UUFDYixnQkFBZ0IsRUFBRSxrQkFBa0I7UUFDcEMsOEJBQThCLEVBQUUsS0FBSztRQUNyQyxJQUFJLEVBQUUsU0FBUztLQUNoQixDQUFDLENBQUM7SUFFSCxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLGdCQUFnQixFQUFFLEVBQUUsU0FBUyxFQUFFLGtCQUFrQixFQUFFLENBQUMsQ0FBQztJQUN2RyxNQUFNLE9BQUMsUUFBUSxDQUFDLE1BQU0sMENBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4QyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRTtLQUM3QixDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRUosd0JBQVMsQ0FBQyw2Q0FBNkMsRUFBRSx3QkFBa0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7O0lBQzVGLE1BQU0sbUJBQW1CLEdBQUcsR0FBRyxPQUFPLENBQUMsa0JBQWtCLElBQUksQ0FBQztJQUM5RCxNQUFNLG1CQUFtQixHQUFHLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixJQUFJLENBQUM7SUFFOUQsa0VBQWtFO0lBQ2xFLGdCQUFnQjtJQUNoQixNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQixPQUFPLEVBQUUsSUFBSTtRQUNiLGdCQUFnQixFQUFFLG1CQUFtQjtRQUNyQyxJQUFJLEVBQUUsU0FBUztLQUNoQixDQUFDLENBQUM7SUFDSCxNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQixPQUFPLEVBQUUsSUFBSTtRQUNiLGdCQUFnQixFQUFFLG1CQUFtQjtLQUN0QyxDQUFDLENBQUM7SUFFSCxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLGdCQUFnQixFQUFFLEVBQUUsU0FBUyxFQUFFLG1CQUFtQixFQUFFLENBQUMsQ0FBQztJQUN4RyxNQUFNLE9BQUMsUUFBUSxDQUFDLE1BQU0sMENBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUN4QyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRTtLQUM3QixDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRUosd0JBQVMsQ0FBQyw2RUFBNkUsRUFBRSx3QkFBa0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7SUFDNUgsSUFBSSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsa0JBQWtCLENBQUM7UUFDOUMsaUVBQWlFO1FBQ2pFLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxrQkFBa0I7UUFDNUMsWUFBWSxFQUFFLElBQUk7UUFDbEIsVUFBVSxFQUFFO1lBQ1YsYUFBYSxFQUFFLEtBQUs7U0FDckI7S0FDRixDQUFDLENBQUM7SUFFSCxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsU0FBUyxDQUFDLG1CQUFtQixDQUFDLENBQUM7SUFFaEQsUUFBUSxJQUFJLElBQUksR0FBRztRQUNqQixlQUFlO1FBQ2Ysa0NBQWtDO0tBQ25DLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBRWIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEdBQUcsT0FBTyxDQUFDLFNBQVMsZ0JBQWdCLENBQUMsQ0FBQztJQUN2RixFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUM1RCxNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQixnQkFBZ0IsRUFBRSxPQUFPLENBQUMsa0JBQWtCO1FBQzVDLFFBQVEsRUFBRSxRQUFRO1FBQ2xCLGtCQUFrQixFQUFFLDZDQUE2QztLQUNsRSxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRUosd0JBQVMsQ0FBQyx3RUFBd0UsRUFBRSx3QkFBa0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7O0lBQ3ZILE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDO0lBRXRELE1BQU0sT0FBTyxDQUFDLGtCQUFrQixDQUFDO1FBQy9CLE9BQU8sRUFBRSxJQUFJO1FBQ2IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLHFCQUFxQixFQUFFLElBQUk7UUFDM0Isa0JBQWtCLEVBQUUsNkNBQTZDO0tBQ2xFLENBQUMsQ0FBQztJQUNILE1BQU0sT0FBTyxDQUFDLGtCQUFrQixDQUFDO1FBQy9CLE9BQU8sRUFBRSxJQUFJO1FBQ2IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLEtBQUssRUFBRSxJQUFJO0tBQ1osQ0FBQyxDQUFDO0lBRUgsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLFNBQVMsRUFBRSxrQkFBa0IsRUFBRSxDQUFDLENBQUM7SUFDdkcsTUFBTSxPQUFDLFFBQVEsQ0FBQyxNQUFNLDBDQUFHLENBQUMsRUFBRSwyQkFBMkIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUN6RSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBRUosd0JBQVMsQ0FBQyxzQ0FBc0MsRUFBRSx3QkFBa0IsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7O0lBQ3JGLE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDO0lBRXRELE1BQU0sT0FBTyxDQUFDLGtCQUFrQixDQUFDO1FBQy9CLE9BQU8sRUFBRSxJQUFJO1FBQ2IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLElBQUksRUFBRSxTQUFTO1FBQ2Ysa0JBQWtCLEVBQUUsNkNBQTZDO0tBQ2xFLENBQUMsQ0FBQztJQUNILE1BQU0sT0FBTyxDQUFDLGtCQUFrQixDQUFDO1FBQy9CLE9BQU8sRUFBRSxJQUFJO1FBQ2IsZ0JBQWdCLEVBQUUsa0JBQWtCO1FBQ3BDLEtBQUssRUFBRSxJQUFJO0tBQ1osQ0FBQyxDQUFDO0lBRUgsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLFNBQVMsRUFBRSxrQkFBa0IsRUFBRSxDQUFDLENBQUM7SUFDdkcsTUFBTSxPQUFDLFFBQVEsQ0FBQyxNQUFNLDBDQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDeEMsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUU7S0FDN0IsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUVKLHdCQUFTLENBQUMsNkVBQTZFLEVBQUUsd0JBQWtCLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO0lBQzVILE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDO0lBRXRELE1BQU0sT0FBTyxDQUFDLGtCQUFrQixDQUFDO1FBQy9CLGdCQUFnQixFQUFFLGtCQUFrQjtRQUNwQyxrQkFBa0IsRUFBRSw2Q0FBNkM7S0FDbEUsQ0FBQyxDQUFDO0lBRUgscUNBQXFDO0lBQ3JDLE1BQU0sT0FBTyxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUU7UUFDaEMsT0FBTyxFQUFFO1lBQ1AsOEZBQThGO1lBQzlGLHlFQUF5RTtZQUN6RSxzQkFBc0IsRUFBRSx3QkFBd0I7WUFDaEQsV0FBVyxFQUFFLG9DQUFvQyxPQUFPLENBQUMsU0FBUyxFQUFFO1lBQ3BFLFdBQVcsRUFBRSx3Q0FBd0M7U0FDdEQ7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IHJhbmRvbVN0cmluZywgd2l0aERlZmF1bHRGaXh0dXJlIH0gZnJvbSAnLi4vaGVscGVycy9jZGsnO1xuaW1wb3J0IHsgaW50ZWdUZXN0IH0gZnJvbSAnLi4vaGVscGVycy90ZXN0LWhlbHBlcnMnO1xuXG5jb25zdCB0aW1lb3V0ID0gcHJvY2Vzcy5lbnYuQ09ERUJVSUxEX0JVSUxEX0lEID8gLy8gaWYgdGhlIHByb2Nlc3MgaXMgcnVubmluZyBpbiBDb2RlQnVpbGRcbiAgM182MDBfMDAwIDogLy8gMSBob3VyXG4gIDYwMF8wMDA7IC8vIDEwIG1pbnV0ZXNcbmplc3Quc2V0VGltZW91dCh0aW1lb3V0KTtcbnByb2Nlc3Muc3Rkb3V0LndyaXRlKGBib290c3RyYXBwaW5nLmludGVndGVzdC50czogU2V0dGluZyBqZXN0IHRpbWUgb3V0IHRvICR7dGltZW91dH0gbXNgKTtcblxuaW50ZWdUZXN0KCdjYW4gYm9vdHN0cmFwIHdpdGhvdXQgZXhlY3V0aW9uJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZSA9IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lO1xuXG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTGVnYWN5KHtcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUsXG4gICAgbm9FeGVjdXRlOiB0cnVlLFxuICB9KTtcblxuICBjb25zdCByZXNwID0gYXdhaXQgZml4dHVyZS5hd3MuY2xvdWRGb3JtYXRpb24oJ2Rlc2NyaWJlU3RhY2tzJywge1xuICAgIFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICB9KTtcblxuICBleHBlY3QocmVzcC5TdGFja3M/LlswXS5TdGFja1N0YXR1cykudG9FcXVhbCgnUkVWSUVXX0lOX1BST0dSRVNTJyk7XG59KSk7XG5cbmludGVnVGVzdCgndXBncmFkZSBsZWdhY3kgYm9vdHN0cmFwIHN0YWNrIHRvIG5ldyBib290c3RyYXAgc3RhY2sgd2hpbGUgaW4gdXNlJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZSA9IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lO1xuXG4gIGNvbnN0IGxlZ2FjeUJvb3RzdHJhcEJ1Y2tldE5hbWUgPSBgYXdzLWNkay1ib290c3RyYXAtaW50ZWctdGVzdC1sZWdhY3ktYmNrdC0ke3JhbmRvbVN0cmluZygpfWA7XG4gIGNvbnN0IG5ld0Jvb3RzdHJhcEJ1Y2tldE5hbWUgPSBgYXdzLWNkay1ib290c3RyYXAtaW50ZWctdGVzdC12Mi1iY2t0LSR7cmFuZG9tU3RyaW5nKCl9YDtcbiAgZml4dHVyZS5yZW1lbWJlclRvRGVsZXRlQnVja2V0KGxlZ2FjeUJvb3RzdHJhcEJ1Y2tldE5hbWUpOyAvLyBUaGlzIG9uZSB3aWxsIGxlYWtcbiAgZml4dHVyZS5yZW1lbWJlclRvRGVsZXRlQnVja2V0KG5ld0Jvb3RzdHJhcEJ1Y2tldE5hbWUpOyAvLyBUaGlzIG9uZSBzaG91bGRuJ3QgbGVhayBpZiB0aGUgdGVzdCBzdWNjZWVkcywgYnV0IGxldCdzIGJlIHNhZmUgaW4gY2FzZSBpdCBkb2Vzbid0XG5cbiAgLy8gTGVnYWN5IGJvb3RzdHJhcFxuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcExlZ2FjeSh7XG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIGJvb3RzdHJhcEJ1Y2tldE5hbWU6IGxlZ2FjeUJvb3RzdHJhcEJ1Y2tldE5hbWUsXG4gIH0pO1xuXG4gIC8vIERlcGxveSBzdGFjayB0aGF0IHVzZXMgZmlsZSBhc3NldHNcbiAgYXdhaXQgZml4dHVyZS5jZGtEZXBsb3koJ2xhbWJkYScsIHtcbiAgICBvcHRpb25zOiBbJy0tdG9vbGtpdC1zdGFjay1uYW1lJywgYm9vdHN0cmFwU3RhY2tOYW1lXSxcbiAgfSk7XG5cbiAgLy8gVXBncmFkZSBib290c3RyYXAgc3RhY2sgdG8gXCJuZXdcIiBzdHlsZVxuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcE1vZGVybih7XG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIGJvb3RzdHJhcEJ1Y2tldE5hbWU6IG5ld0Jvb3RzdHJhcEJ1Y2tldE5hbWUsXG4gICAgY2ZuRXhlY3V0aW9uUG9saWN5OiAnYXJuOmF3czppYW06OmF3czpwb2xpY3kvQWRtaW5pc3RyYXRvckFjY2VzcycsXG4gIH0pO1xuXG4gIC8vIChGb3JjZSkgZGVwbG95IHN0YWNrIGFnYWluXG4gIC8vIC0tZm9yY2UgdG8gYnlwYXNzIHRoZSBjaGVjayB3aGljaCBzYXlzIHRoYXQgdGhlIHRlbXBsYXRlIGhhc24ndCBjaGFuZ2VkLlxuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnbGFtYmRhJywge1xuICAgIG9wdGlvbnM6IFtcbiAgICAgICctLXRvb2xraXQtc3RhY2stbmFtZScsIGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICAgICctLWZvcmNlJyxcbiAgICBdLFxuICB9KTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjYW4gYW5kIGRlcGxveSBpZiBvbWl0dGluZyBleGVjdXRpb24gcG9saWNpZXMnLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lID0gZml4dHVyZS5ib290c3RyYXBTdGFja05hbWU7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHRvb2xraXRTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgfSk7XG5cbiAgLy8gRGVwbG95IHN0YWNrIHRoYXQgdXNlcyBmaWxlIGFzc2V0c1xuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnbGFtYmRhJywge1xuICAgIG9wdGlvbnM6IFtcbiAgICAgICctLXRvb2xraXQtc3RhY2stbmFtZScsIGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICAgICctLWNvbnRleHQnLCBgQGF3cy1jZGsvY29yZTpib290c3RyYXBRdWFsaWZpZXI9JHtmaXh0dXJlLnF1YWxpZmllcn1gLFxuICAgICAgJy0tY29udGV4dCcsICdAYXdzLWNkay9jb3JlOm5ld1N0eWxlU3RhY2tTeW50aGVzaXM9MScsXG4gICAgXSxcbiAgfSk7XG59KSk7XG5cbmludGVnVGVzdCgnZGVwbG95IG5ldyBzdHlsZSBzeW50aGVzaXMgdG8gbmV3IHN0eWxlIGJvb3RzdHJhcCcsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBib290c3RyYXBTdGFja05hbWUgPSBmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZTtcblxuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcE1vZGVybih7XG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIGNmbkV4ZWN1dGlvblBvbGljeTogJ2Fybjphd3M6aWFtOjphd3M6cG9saWN5L0FkbWluaXN0cmF0b3JBY2Nlc3MnLFxuICB9KTtcblxuICAvLyBEZXBsb3kgc3RhY2sgdGhhdCB1c2VzIGZpbGUgYXNzZXRzXG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdsYW1iZGEnLCB7XG4gICAgb3B0aW9uczogW1xuICAgICAgJy0tdG9vbGtpdC1zdGFjay1uYW1lJywgYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgICAgJy0tY29udGV4dCcsIGBAYXdzLWNkay9jb3JlOmJvb3RzdHJhcFF1YWxpZmllcj0ke2ZpeHR1cmUucXVhbGlmaWVyfWAsXG4gICAgICAnLS1jb250ZXh0JywgJ0Bhd3MtY2RrL2NvcmU6bmV3U3R5bGVTdGFja1N5bnRoZXNpcz0xJyxcbiAgICBdLFxuICB9KTtcbn0pKTtcblxuaW50ZWdUZXN0KCdkZXBsb3kgbmV3IHN0eWxlIHN5bnRoZXNpcyB0byBuZXcgc3R5bGUgYm9vdHN0cmFwICh3aXRoIGRvY2tlciBpbWFnZSknLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lID0gZml4dHVyZS5ib290c3RyYXBTdGFja05hbWU7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHRvb2xraXRTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICBjZm5FeGVjdXRpb25Qb2xpY3k6ICdhcm46YXdzOmlhbTo6YXdzOnBvbGljeS9BZG1pbmlzdHJhdG9yQWNjZXNzJyxcbiAgfSk7XG5cbiAgLy8gRGVwbG95IHN0YWNrIHRoYXQgdXNlcyBmaWxlIGFzc2V0c1xuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnZG9ja2VyJywge1xuICAgIG9wdGlvbnM6IFtcbiAgICAgICctLXRvb2xraXQtc3RhY2stbmFtZScsIGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICAgICctLWNvbnRleHQnLCBgQGF3cy1jZGsvY29yZTpib290c3RyYXBRdWFsaWZpZXI9JHtmaXh0dXJlLnF1YWxpZmllcn1gLFxuICAgICAgJy0tY29udGV4dCcsICdAYXdzLWNkay9jb3JlOm5ld1N0eWxlU3RhY2tTeW50aGVzaXM9MScsXG4gICAgXSxcbiAgfSk7XG59KSk7XG5cbmludGVnVGVzdCgnZGVwbG95IG9sZCBzdHlsZSBzeW50aGVzaXMgdG8gbmV3IHN0eWxlIGJvb3RzdHJhcCcsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBib290c3RyYXBTdGFja05hbWUgPSBmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZTtcblxuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcE1vZGVybih7XG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIGNmbkV4ZWN1dGlvblBvbGljeTogJ2Fybjphd3M6aWFtOjphd3M6cG9saWN5L0FkbWluaXN0cmF0b3JBY2Nlc3MnLFxuICB9KTtcblxuICAvLyBEZXBsb3kgc3RhY2sgdGhhdCB1c2VzIGZpbGUgYXNzZXRzXG4gIGF3YWl0IGZpeHR1cmUuY2RrRGVwbG95KCdsYW1iZGEnLCB7XG4gICAgb3B0aW9uczogW1xuICAgICAgJy0tdG9vbGtpdC1zdGFjay1uYW1lJywgYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIF0sXG4gIH0pO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2NhbiBjcmVhdGUgYSBsZWdhY3kgYm9vdHN0cmFwIHN0YWNrIHdpdGggLS1wdWJsaWMtYWNjZXNzLWJsb2NrLWNvbmZpZ3VyYXRpb249ZmFsc2UnLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lID0gZml4dHVyZS5ib290c3RyYXBTdGFja05hbWU7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBMZWdhY3koe1xuICAgIHZlcmJvc2U6IHRydWUsXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIHB1YmxpY0FjY2Vzc0Jsb2NrQ29uZmlndXJhdGlvbjogZmFsc2UsXG4gICAgdGFnczogJ0Zvbz1CYXInLFxuICB9KTtcblxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmNsb3VkRm9ybWF0aW9uKCdkZXNjcmliZVN0YWNrcycsIHsgU3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUgfSk7XG4gIGV4cGVjdChyZXNwb25zZS5TdGFja3M/LlswXS5UYWdzKS50b0VxdWFsKFtcbiAgICB7IEtleTogJ0ZvbycsIFZhbHVlOiAnQmFyJyB9LFxuICBdKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjYW4gY3JlYXRlIG11bHRpcGxlIGxlZ2FjeSBib290c3RyYXAgc3RhY2tzJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZTEgPSBgJHtmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZX0tMWA7XG4gIGNvbnN0IGJvb3RzdHJhcFN0YWNrTmFtZTIgPSBgJHtmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZX0tMmA7XG5cbiAgLy8gZGVwbG95IHR3byB0b29sa2l0IHN0YWNrcyBpbnRvIHRoZSBzYW1lIGVudmlyb25tZW50IChzZWUgIzE0MTYpXG4gIC8vIG9uZSB3aXRoIHRhZ3NcbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBMZWdhY3koe1xuICAgIHZlcmJvc2U6IHRydWUsXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lMSxcbiAgICB0YWdzOiAnRm9vPUJhcicsXG4gIH0pO1xuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcExlZ2FjeSh7XG4gICAgdmVyYm9zZTogdHJ1ZSxcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUyLFxuICB9KTtcblxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmNsb3VkRm9ybWF0aW9uKCdkZXNjcmliZVN0YWNrcycsIHsgU3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUxIH0pO1xuICBleHBlY3QocmVzcG9uc2UuU3RhY2tzPy5bMF0uVGFncykudG9FcXVhbChbXG4gICAgeyBLZXk6ICdGb28nLCBWYWx1ZTogJ0JhcicgfSxcbiAgXSk7XG59KSk7XG5cbmludGVnVGVzdCgnY2FuIGR1bXAgdGhlIHRlbXBsYXRlLCBtb2RpZnkgYW5kIHVzZSBpdCB0byBkZXBsb3kgYSBjdXN0b20gYm9vdHN0cmFwIHN0YWNrJywgd2l0aERlZmF1bHRGaXh0dXJlKGFzeW5jIChmaXh0dXJlKSA9PiB7XG4gIGxldCB0ZW1wbGF0ZSA9IGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICAvLyB0b29sa2l0U3RhY2tOYW1lIGRvZXNuJ3QgbWF0dGVyIGZvciB0aGlzIHBhcnRpY3VsYXIgaW52b2NhdGlvblxuICAgIHRvb2xraXRTdGFja05hbWU6IGZpeHR1cmUuYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIHNob3dUZW1wbGF0ZTogdHJ1ZSxcbiAgICBjbGlPcHRpb25zOiB7XG4gICAgICBjYXB0dXJlU3RkZXJyOiBmYWxzZSxcbiAgICB9LFxuICB9KTtcblxuICBleHBlY3QodGVtcGxhdGUpLnRvQ29udGFpbignQm9vdHN0cmFwVmVyc2lvbjonKTtcblxuICB0ZW1wbGF0ZSArPSAnXFxuJyArIFtcbiAgICAnICBUd2lkZGxlRGVlOicsXG4gICAgJyAgICBWYWx1ZTogVGVtcGxhdGUgZ290IHR3aWRkbGVkJyxcbiAgXS5qb2luKCdcXG4nKTtcblxuICBjb25zdCBmaWxlbmFtZSA9IHBhdGguam9pbihmaXh0dXJlLmludGVnVGVzdERpciwgYCR7Zml4dHVyZS5xdWFsaWZpZXJ9LXRlbXBsYXRlLnlhbWxgKTtcbiAgZnMud3JpdGVGaWxlU3luYyhmaWxlbmFtZSwgdGVtcGxhdGUsIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSk7XG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICB0ZW1wbGF0ZTogZmlsZW5hbWUsXG4gICAgY2ZuRXhlY3V0aW9uUG9saWN5OiAnYXJuOmF3czppYW06OmF3czpwb2xpY3kvQWRtaW5pc3RyYXRvckFjY2VzcycsXG4gIH0pO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ3N3aXRjaCBvbiB0ZXJtaW5hdGlvbiBwcm90ZWN0aW9uLCBzd2l0Y2ggaXMgbGVmdCBhbG9uZSBvbiByZS1ib290c3RyYXAnLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lID0gZml4dHVyZS5ib290c3RyYXBTdGFja05hbWU7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHZlcmJvc2U6IHRydWUsXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIHRlcm1pbmF0aW9uUHJvdGVjdGlvbjogdHJ1ZSxcbiAgICBjZm5FeGVjdXRpb25Qb2xpY3k6ICdhcm46YXdzOmlhbTo6YXdzOnBvbGljeS9BZG1pbmlzdHJhdG9yQWNjZXNzJyxcbiAgfSk7XG4gIGF3YWl0IGZpeHR1cmUuY2RrQm9vdHN0cmFwTW9kZXJuKHtcbiAgICB2ZXJib3NlOiB0cnVlLFxuICAgIHRvb2xraXRTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICBmb3JjZTogdHJ1ZSxcbiAgfSk7XG5cbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmaXh0dXJlLmF3cy5jbG91ZEZvcm1hdGlvbignZGVzY3JpYmVTdGFja3MnLCB7IFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lIH0pO1xuICBleHBlY3QocmVzcG9uc2UuU3RhY2tzPy5bMF0uRW5hYmxlVGVybWluYXRpb25Qcm90ZWN0aW9uKS50b0VxdWFsKHRydWUpO1xufSkpO1xuXG5pbnRlZ1Rlc3QoJ2FkZCB0YWdzLCBsZWZ0IGFsb25lIG9uIHJlLWJvb3RzdHJhcCcsIHdpdGhEZWZhdWx0Rml4dHVyZShhc3luYyAoZml4dHVyZSkgPT4ge1xuICBjb25zdCBib290c3RyYXBTdGFja05hbWUgPSBmaXh0dXJlLmJvb3RzdHJhcFN0YWNrTmFtZTtcblxuICBhd2FpdCBmaXh0dXJlLmNka0Jvb3RzdHJhcE1vZGVybih7XG4gICAgdmVyYm9zZTogdHJ1ZSxcbiAgICB0b29sa2l0U3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUsXG4gICAgdGFnczogJ0Zvbz1CYXInLFxuICAgIGNmbkV4ZWN1dGlvblBvbGljeTogJ2Fybjphd3M6aWFtOjphd3M6cG9saWN5L0FkbWluaXN0cmF0b3JBY2Nlc3MnLFxuICB9KTtcbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHZlcmJvc2U6IHRydWUsXG4gICAgdG9vbGtpdFN0YWNrTmFtZTogYm9vdHN0cmFwU3RhY2tOYW1lLFxuICAgIGZvcmNlOiB0cnVlLFxuICB9KTtcblxuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZpeHR1cmUuYXdzLmNsb3VkRm9ybWF0aW9uKCdkZXNjcmliZVN0YWNrcycsIHsgU3RhY2tOYW1lOiBib290c3RyYXBTdGFja05hbWUgfSk7XG4gIGV4cGVjdChyZXNwb25zZS5TdGFja3M/LlswXS5UYWdzKS50b0VxdWFsKFtcbiAgICB7IEtleTogJ0ZvbycsIFZhbHVlOiAnQmFyJyB9LFxuICBdKTtcbn0pKTtcblxuaW50ZWdUZXN0KCdjYW4gZGVwbG95IG1vZGVybi1zeW50aGVzaXplZCBzdGFjayBldmVuIGlmIGJvb3RzdHJhcCBzdGFjayBuYW1lIGlzIHVua25vd24nLCB3aXRoRGVmYXVsdEZpeHR1cmUoYXN5bmMgKGZpeHR1cmUpID0+IHtcbiAgY29uc3QgYm9vdHN0cmFwU3RhY2tOYW1lID0gZml4dHVyZS5ib290c3RyYXBTdGFja05hbWU7XG5cbiAgYXdhaXQgZml4dHVyZS5jZGtCb290c3RyYXBNb2Rlcm4oe1xuICAgIHRvb2xraXRTdGFja05hbWU6IGJvb3RzdHJhcFN0YWNrTmFtZSxcbiAgICBjZm5FeGVjdXRpb25Qb2xpY3k6ICdhcm46YXdzOmlhbTo6YXdzOnBvbGljeS9BZG1pbmlzdHJhdG9yQWNjZXNzJyxcbiAgfSk7XG5cbiAgLy8gRGVwbG95IHN0YWNrIHRoYXQgdXNlcyBmaWxlIGFzc2V0c1xuICBhd2FpdCBmaXh0dXJlLmNka0RlcGxveSgnbGFtYmRhJywge1xuICAgIG9wdGlvbnM6IFtcbiAgICAgIC8vIEV4cGxpY2l0eSBwYXNzIGEgbmFtZSB0aGF0J3Mgc3VyZSB0byBub3QgZXhpc3QsIG90aGVyd2lzZSB0aGUgQ0xJIG1pZ2h0IGFjY2lkZW50YWxseSBmaW5kIGFcbiAgICAgIC8vIGRlZmF1bHQgYm9vdHN0cmFjcCBzdGFjayBpZiB0aGF0IGhhcHBlbnMgdG8gYmUgaW4gdGhlIGFjY291bnQgYWxyZWFkeS5cbiAgICAgICctLXRvb2xraXQtc3RhY2stbmFtZScsICdEZWZpbml0ZWx5RG9lc05vdEV4aXN0JyxcbiAgICAgICctLWNvbnRleHQnLCBgQGF3cy1jZGsvY29yZTpib290c3RyYXBRdWFsaWZpZXI9JHtmaXh0dXJlLnF1YWxpZmllcn1gLFxuICAgICAgJy0tY29udGV4dCcsICdAYXdzLWNkay9jb3JlOm5ld1N0eWxlU3RhY2tTeW50aGVzaXM9MScsXG4gICAgXSxcbiAgfSk7XG59KSk7XG4iXX0= \ No newline at end of file From 4ae78b07af20ea3ef049079ac5b892f9ee8476e5 Mon Sep 17 00:00:00 2001 From: nom3ad <19239479+nom3ad@users.noreply.github.com> Date: Fri, 5 Nov 2021 22:55:16 +0530 Subject: [PATCH 55/70] fix(cognito): ambiguous error message when same trigger is added twice (#16917) when the same trigger is added twice to the Cognito userpool, ```ts const fn = lambda.Function.fromFunctionArn(stack, 'Trigger', 'arn:aws:lambda:us-east-1:123456789012:function:CognitoFunction') const userpool = new cognito.UserPool(stack, 'Userpool', { lambdaTriggers: { customMessage: fn } }) userpool.addTrigger(cognito.UserPoolOperation.CUSTOM_MESSAGE, fn) ``` throws error message: `Error: A trigger for the operation [object Object] already exists.` This PR fixes it as: ` Error: A trigger for the operation customMessage already exists.` ---- *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-cognito/lib/user-pool.ts | 2 +- packages/@aws-cdk/aws-cognito/test/user-pool.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-cognito/lib/user-pool.ts b/packages/@aws-cdk/aws-cognito/lib/user-pool.ts index 6277ee0f467ee..adc3f51bf37a2 100644 --- a/packages/@aws-cdk/aws-cognito/lib/user-pool.ts +++ b/packages/@aws-cdk/aws-cognito/lib/user-pool.ts @@ -830,7 +830,7 @@ export class UserPool extends UserPoolBase { */ public addTrigger(operation: UserPoolOperation, fn: lambda.IFunction): void { if (operation.operationName in this.triggers) { - throw new Error(`A trigger for the operation ${operation} already exists.`); + throw new Error(`A trigger for the operation ${operation.operationName} already exists.`); } this.addLambdaPermission(fn, operation.operationName); diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts index 7b132803da2d6..5aa6c48ee99fc 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts @@ -403,7 +403,7 @@ describe('User Pool', () => { // WHEN userpool.addTrigger(UserPoolOperation.CREATE_AUTH_CHALLENGE, fn1); - expect(() => userpool.addTrigger(UserPoolOperation.CREATE_AUTH_CHALLENGE, fn2)).toThrow(/already exists/); + expect(() => userpool.addTrigger(UserPoolOperation.CREATE_AUTH_CHALLENGE, fn2)).toThrow(/createAuthChallenge already exists/); }); test('no username aliases specified', () => { From 8c7eab5ca99de85bdff5b861bf596e4811ef92d2 Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Fri, 5 Nov 2021 12:21:45 -0600 Subject: [PATCH 56/70] chore(lambda-nodejs): improve spawnSync error message (#16986) This PR improves the error message when a lambda-nodejs function fails to bundle. I'm working on moving a client's repository from a "makeshift monorepo" to a real `yarn`/`lerna` driven monorepo. They make heavy use of `NodejsFunction`, so I'm moving them to the newer [reference project architecture](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-lambda-nodejs-readme.html#reference-project-architecture) with a single lockfile at the root of the repository. While working through this issue, I kept running into this error message: ``` > yarn cdk diff Bundling asset SomeLambdaHandler/SomeSubLambda/Lambda/Code/Stage... Usage Error: Couldn't find a script named "esbuild". $ yarn run [--inspect] [--inspect-brk] ... Failed to bundle asset SomeLambdaHandler/SomeSubLambda/Lambda/Code/Stage, bundle output is located at /Users/blimmer/code/client/project/packages/some-workspace/cdk.out/bundling-temp-2f3ffba54d828547eb851ebe672a601943e153ec31fdc5e45f8e80ed976da6d3-error: Error: bash exited with status 1 Subprocess exited with error 1 ``` This was confusing to me because I have `esbuild` installed in both sub-packages that require it. The error message just tells me that `bash` failed to run, which isn't very helpful. However, when I set an interactive breakpoint, I got a lot more information about the failure. By digging into these arguments https://github.com/aws/aws-cdk/blob/507769aa034ba3d8daa497953be629408072baed/packages/%40aws-cdk/aws-lambda-nodejs/lib/util.ts#L56-L57 I can actually see what's being run and which directory it's run in. | argument | contents | comments | | -------- | -------- | -------- | | `cmd` | `bash` | this doesn't really tell me anything about what's happening | | `args` | [ `-c`, `"yarn run esbuild --bundle \"/Users/blimmer/code/client/project/packages/some-workspace/lib/some-sub-lambda/lambda/index.ts\" --target=node14 --platform=node --outfile=\"/Users/blimmer/code/client/project/packages/some-workspace/cdk.out/bundling-temp-2f3ffba54d828547eb851ebe672a601943e153ec31fdc5e45f8e80ed976da6d3/index.js\" --external:aws-sdk"` ] | the second argument of this array actually represents the command being run - this is way more useful than just `bash` | | `options` | `{ ...lotsOfOtherStuff, cwd: '/Users/blimmer/code/client/project' }` | `cwd` was actually crucial for me to fix this problem. because I see this is running in the root of the monorepo, it shows that I need to install `esbuild` there, instead of in the workspaces. | ---- *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/util.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/util.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/util.ts index 5ead91793e93b..af24d3b4ae371 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/util.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/util.ts @@ -64,7 +64,7 @@ export function exec(cmd: string, args: string[], options?: SpawnSyncOptions) { if (proc.stdout || proc.stderr) { throw new Error(`[Status ${proc.status}] stdout: ${proc.stdout?.toString().trim()}\n\n\nstderr: ${proc.stderr?.toString().trim()}`); } - throw new Error(`${cmd} exited with status ${proc.status}`); + throw new Error(`${cmd} ${args.join(' ')} ${options?.cwd ? `run in directory ${options.cwd}` : ''} exited with status ${proc.status}`); } return proc; From 37f8a9f0620b41a3ce9e6e1ca42611ad35ad586a Mon Sep 17 00:00:00 2001 From: Madeline Kusters <80541297+madeline-k@users.noreply.github.com> Date: Fri, 5 Nov 2021 12:16:30 -0700 Subject: [PATCH 57/70] docs(ecs): update docs to accurately reflect that a new security group is created if one is not provided. (#17364) Closes #15365 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../lib/fargate/application-load-balanced-fargate-service.ts | 2 +- .../lib/fargate/queue-processing-fargate-service.ts | 2 +- packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts | 4 ++-- packages/@aws-cdk/aws-ecs/lib/external/external-service.ts | 2 +- packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-load-balanced-fargate-service.ts b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-load-balanced-fargate-service.ts index 19a2501355223..81f243f4a6fa6 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-load-balanced-fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/application-load-balanced-fargate-service.ts @@ -86,7 +86,7 @@ export interface ApplicationLoadBalancedFargateServiceProps extends ApplicationL readonly platformVersion?: FargatePlatformVersion; /** - * The security groups to associate with the service. If you do not specify a security group, the default security group for the VPC is used. + * The security groups to associate with the service. If you do not specify a security group, a new security group is created. * * @default - A new security group is created. */ diff --git a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/queue-processing-fargate-service.ts b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/queue-processing-fargate-service.ts index e6f8b89c736b3..033d19dc39612 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/queue-processing-fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/lib/fargate/queue-processing-fargate-service.ts @@ -77,7 +77,7 @@ export interface QueueProcessingFargateServiceProps extends QueueProcessingServi readonly taskSubnets?: ec2.SubnetSelection; /** - * The security groups to associate with the service. If you do not specify a security group, the default security group for the VPC is used. + * The security groups to associate with the service. If you do not specify a security group, a new security group is created. * * @default - A new security group is created. */ diff --git a/packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts b/packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts index df2ad7819543c..0a98809dff403 100644 --- a/packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts +++ b/packages/@aws-cdk/aws-ecs/lib/ec2/ec2-service.ts @@ -39,7 +39,7 @@ export interface Ec2ServiceProps extends BaseServiceOptions { readonly vpcSubnets?: ec2.SubnetSelection; /** - * The security groups to associate with the service. If you do not specify a security group, the default security group for the VPC is used. + * The security groups to associate with the service. If you do not specify a security group, a new security group is created. * * This property is only used for tasks that use the awsvpc network mode. * @@ -49,7 +49,7 @@ export interface Ec2ServiceProps extends BaseServiceOptions { readonly securityGroup?: ec2.ISecurityGroup; /** - * The security groups to associate with the service. If you do not specify a security group, the default security group for the VPC is used. + * The security groups to associate with the service. If you do not specify a security group, a new security group is created. * * This property is only used for tasks that use the awsvpc network mode. * diff --git a/packages/@aws-cdk/aws-ecs/lib/external/external-service.ts b/packages/@aws-cdk/aws-ecs/lib/external/external-service.ts index 741ba0a7b2b29..2c1c6c9f59534 100644 --- a/packages/@aws-cdk/aws-ecs/lib/external/external-service.ts +++ b/packages/@aws-cdk/aws-ecs/lib/external/external-service.ts @@ -21,7 +21,7 @@ export interface ExternalServiceProps extends BaseServiceOptions { readonly taskDefinition: TaskDefinition; /** - * The security groups to associate with the service. If you do not specify a security group, the default security group for the VPC is used. + * The security groups to associate with the service. If you do not specify a security group, a new security group is created. * * * @default - A new security group is created. diff --git a/packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts b/packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts index 7979b98f0b0fa..a996aca37cc23 100644 --- a/packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs/lib/fargate/fargate-service.ts @@ -34,7 +34,7 @@ export interface FargateServiceProps extends BaseServiceOptions { readonly vpcSubnets?: ec2.SubnetSelection; /** - * The security groups to associate with the service. If you do not specify a security group, the default security group for the VPC is used. + * The security groups to associate with the service. If you do not specify a security group, a new security group is created. * * @default - A new security group is created. * @deprecated use securityGroups instead. @@ -42,7 +42,7 @@ export interface FargateServiceProps extends BaseServiceOptions { readonly securityGroup?: ec2.ISecurityGroup; /** - * The security groups to associate with the service. If you do not specify a security group, the default security group for the VPC is used. + * The security groups to associate with the service. If you do not specify a security group, a new security group is created. * * @default - A new security group is created. */ From cc8dd694e6746b9c6fc4663775aaa3b68d19ef61 Mon Sep 17 00:00:00 2001 From: Jonathan Goldwasser Date: Fri, 5 Nov 2021 21:11:37 +0100 Subject: [PATCH 58/70] fix(lambda-nodejs): yarn berry goes into immutable mode in CI (#17086) Add the `--no-immutable` flag when running `yarn`. Closes #17082 ---- *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/package-manager.ts | 2 +- packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/package-manager.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/package-manager.ts index 0f18c92cbde20..f0206bbd19a99 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/package-manager.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/package-manager.ts @@ -20,7 +20,7 @@ export class PackageManager { public static YARN = new PackageManager({ lockFile: 'yarn.lock', - installCommand: ['yarn', 'install'], + installCommand: ['yarn', 'install', '--no-immutable'], runCommand: ['yarn', 'run'], }); 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 ae871b67cb69f..e79ddc2aca150 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/bundling.test.ts @@ -342,7 +342,7 @@ test('Detects yarn.lock', () => { assetHashType: AssetHashType.OUTPUT, bundling: expect.objectContaining({ command: expect.arrayContaining([ - expect.stringMatching(/yarn\.lock.+yarn install/), + expect.stringMatching(/yarn\.lock.+yarn install --no-immutable/), ]), }), }); From 14da458e0bf44d3e2516870ca99a331ba492817c Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Fri, 5 Nov 2021 22:03:49 +0100 Subject: [PATCH 59/70] chore: enable rosetta cache for builds (#17336) Avail ourselves of the new build cache feature in cdklabs/cdk-ops#1776. Adds two new things: **A persistently cached directory** The directory `$HOME/.s3buildcache` will be stored and restored in the S3 bucket, if configured. The build can assume that files it puts in there will be availble on the next build (and on the corresponding PR build). **Cache rosetta tablet** If there is a file in the persistent cache directory for Rosetta, pass it to `jsii-rosetta` as an input. Afterwards, store whatever tablet the build produced back into the cache directory. The latter will only impact the persistent cache if done on a build that is actually configured to store the cache back, which is only the main pipeline build. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- build.sh | 9 +-------- buildspec-pr.yaml | 10 ++++++++-- buildspec.yaml | 4 ++++ pack.sh | 6 +----- scripts/cache-load.sh | 23 +++++++++++++++++++++++ scripts/cache-store.sh | 21 +++++++++++++++++++++ scripts/list-packages | 4 +++- scripts/run-rosetta.sh | 40 ++++++++++++++++++++++++++++++++++++++++ scripts/transform.sh | 9 +-------- 9 files changed, 102 insertions(+), 24 deletions(-) create mode 100755 scripts/cache-load.sh create mode 100644 scripts/cache-store.sh create mode 100644 scripts/run-rosetta.sh diff --git a/build.sh b/build.sh index aae39e94ea730..64ecc043faf45 100755 --- a/build.sh +++ b/build.sh @@ -6,11 +6,10 @@ runtarget="build" run_tests="true" check_prereqs="true" check_compat="true" -extract_snippets="false" while [[ "${1:-}" != "" ]]; do case $1 in -h|--help) - echo "Usage: build.sh [--no-bail] [--force|-f] [--skip-test] [--skip-prereqs] [--skip-compat] [--extract]" + echo "Usage: build.sh [--no-bail] [--force|-f] [--skip-test] [--skip-prereqs] [--skip-compat]" exit 1 ;; --no-bail) @@ -28,9 +27,6 @@ while [[ "${1:-}" != "" ]]; do --skip-compat) check_compat="false" ;; - --extract) - extract_snippets="true" - ;; *) echo "Unrecognized parameter: $1" exit 1 @@ -81,9 +77,6 @@ trap "rm -rf $MERKLE_BUILD_CACHE" EXIT if [ "$run_tests" == "true" ]; then runtarget="$runtarget+test" fi -if [ "$extract_snippets" == "true" ]; then - runtarget="$runtarget+extract" -fi echo "=============================================================================================" echo "building..." diff --git a/buildspec-pr.yaml b/buildspec-pr.yaml index 647b78849b3e8..ade1f4a9be0c6 100644 --- a/buildspec-pr.yaml +++ b/buildspec-pr.yaml @@ -16,8 +16,14 @@ phases: # Packing the mono-libraries (monocdk & aws-cdk-lib) can cause # memory errors. Increasing this value allows our build to more consistently succeed - (command -v sysctl || yum install -y procps-ng) && /sbin/sysctl -w vm.max_map_count=2251954 + pre_build: + commands: + - /bin/bash ./scripts/cache-load.sh build: commands: - - /bin/bash ./build.sh --extract - - /bin/bash ./scripts/transform.sh --extract + - /bin/bash ./build.sh + - /bin/bash ./scripts/transform.sh + # After compilation, run Rosetta (using the cache if available). + # This will print errors, and fail the build if there are compilation errors in any packages marked as 'strict'. + - /bin/bash ./scripts/run-rosetta.sh - git diff-index --exit-code --ignore-space-at-eol --stat HEAD diff --git a/buildspec.yaml b/buildspec.yaml index 0fc990a17c805..94a75e2357f78 100644 --- a/buildspec.yaml +++ b/buildspec.yaml @@ -16,6 +16,9 @@ phases: # Packing the mono-libraries (monocdk & aws-cdk-lib) can cause # memory errors. Increasing this value allows our build to more consistently succeed - /sbin/sysctl -w vm.max_map_count=2251954 + pre_build: + commands: + - /bin/bash ./scripts/cache-load.sh build: commands: - 'if ${BUMP_CANDIDATE:-false}; then /bin/bash ./scripts/bump-candidate.sh; fi' @@ -25,6 +28,7 @@ phases: post_build: commands: - "[ -f .BUILD_COMPLETED ] && /bin/bash ./pack.sh" + - /bin/bash ./scripts/cache-store.sh artifacts: files: - "**/*" diff --git a/pack.sh b/pack.sh index 168a17f972406..81eecafabe187 100755 --- a/pack.sh +++ b/pack.sh @@ -39,11 +39,7 @@ function lerna_scopes() { # Compile examples with respect to "decdk" directory, as all packages will # be symlinked there so they can all be included. echo "Extracting code samples" >&2 -node --experimental-worker $(which $ROSETTA) \ - --compile \ - --output samples.tabl.json \ - --directory packages/decdk \ - $(cat $TMPDIR/jsii.txt) +scripts/run-rosetta.sh $TMPDIR/jsii.txt # Jsii packaging (all at once using jsii-pacmak) echo "Packaging jsii modules" >&2 diff --git a/scripts/cache-load.sh b/scripts/cache-load.sh new file mode 100755 index 0000000000000..23aff254f4f1f --- /dev/null +++ b/scripts/cache-load.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# If the environment variable S3_BUILD_CACHE is set, download and extract the +# tarball it points to into the directory $HOME/.s3buildcache. +# +set -eu + +cachedir=$HOME/.s3buildcache +mkdir -p $cachedir + +if [[ "${S3_BUILD_CACHE:-}" = "" ]]; then + exit 0 +fi + +echo "🧳 Build cache enabled: ${S3_BUILD_CACHE}" +if ! aws s3 ls ${S3_BUILD_CACHE} > /dev/null; then + echo "🧳⚠️ Cache not found." + exit 0 +fi + +if ! (cd $cachedir && aws s3 cp ${S3_BUILD_CACHE} - | tar xzv); then + echo "🧳⚠️ Something went wrong fetching the cache. Continuing anyway." +fi diff --git a/scripts/cache-store.sh b/scripts/cache-store.sh new file mode 100644 index 0000000000000..aaf99cbca4f0f --- /dev/null +++ b/scripts/cache-store.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# If the environment variable S3_BUILD_CACHE is set, compress and upload the +# contents of $HOME/.s3buildcache to it. +# +set -eu + +cachedir=$HOME/.s3buildcache +mkdir -p $cachedir + +if [[ "${S3_BUILD_CACHE:-}" = "" ]]; then + exit 0 +fi + +echo "🧳 Storing build cache at: ${S3_BUILD_CACHE}" + +if ! (cd $cachedir && tar czv . | aws s3 cp - ${S3_BUILD_CACHE}); then + echo "🧳⚠️ Something went wrong storing the cache." +fi + +echo "🧳 Finished." diff --git a/scripts/list-packages b/scripts/list-packages index 95a2c5ecc0379..fe89f84db9410 100755 --- a/scripts/list-packages +++ b/scripts/list-packages @@ -12,7 +12,9 @@ if (process.argv.length < 4) { process.exit(1); } -child_process.exec('lerna ls --toposort --json', { shell: true }, (error, stdout) => { +const lerna = path.resolve(__dirname, '..', 'node_modules', '.bin', 'lerna'); + +child_process.exec(`${lerna} ls --toposort --json`, { shell: true }, (error, stdout) => { if (error) { console.error('Error: ', error); process.exit(-1); diff --git a/scripts/run-rosetta.sh b/scripts/run-rosetta.sh new file mode 100644 index 0000000000000..0148eeccc3630 --- /dev/null +++ b/scripts/run-rosetta.sh @@ -0,0 +1,40 @@ +#!/bin/bash +# +# Run jsii-rosetta on all jsii packages, using the S3 build cache if available. +# +# Usage: run-rosetta [PKGSFILE] +# +# If you already have a file with a list of all the JSII package directories +# in it, pass it as the first argument. Otherwise, this script will run +# 'list-packages' to determine a list itself. +set -eu +scriptdir=$(cd $(dirname $0) && pwd) + +ROSETTA=${ROSETTA:-npx jsii-rosetta} + +if [[ "${1:-}" = "" ]]; then + echo "Collecting package list..." >&2 + TMPDIR=${TMPDIR:-$(dirname $(mktemp -u))} + node $scriptdir/list-packages $TMPDIR/jsii.txt $TMPDIR/nonjsii.txt + jsii_pkgs_file=$TMPDIR/jsii.txt +else + jsii_pkgs_file=$1 +fi + +rosetta_cache_file=$HOME/.s3buildcache/rosetta-cache.tabl.json +rosetta_cache_opts="" +if [[ -f $rosetta_cache_file ]]; then + rosetta_cache_opts="--cache-from ${rosetta_cache_file}" +fi + +$ROSETTA \ + --compile \ + --output samples.tabl.json \ + $rosetta_cache_opts \ + --directory packages/decdk \ + $(cat $jsii_pkgs_file) + +if [[ -d $(dirname $rosetta_cache_file) ]]; then + # If the cache directory is available, copy the current tablet into it + cp samples.tabl.json $rosetta_cache_file +fi diff --git a/scripts/transform.sh b/scripts/transform.sh index da780c3df49ff..c0bb83b3a6edf 100755 --- a/scripts/transform.sh +++ b/scripts/transform.sh @@ -25,12 +25,11 @@ createSymlinks() { runtarget="build" run_tests="true" -extract_snippets="false" skip_build="" while [[ "${1:-}" != "" ]]; do case $1 in -h|--help) - echo "Usage: transform.sh [--skip-test/build] [--extract]" + echo "Usage: transform.sh [--skip-test/build]" exit 1 ;; --skip-test|--skip-tests) @@ -39,9 +38,6 @@ while [[ "${1:-}" != "" ]]; do --skip-build) skip_build="true" ;; - --extract) - extract_snippets="true" - ;; *) echo "Unrecognized options: $1" exit 1 @@ -52,9 +48,6 @@ done if [ "$run_tests" == "true" ]; then runtarget="$runtarget+test" fi -if [ "$extract_snippets" == "true" ]; then - runtarget="$runtarget+extract" -fi export NODE_OPTIONS="--max-old-space-size=4096 --experimental-worker ${NODE_OPTIONS:-}" From 96a816058634d028c9b7ec615e1c42f32b61c5f0 Mon Sep 17 00:00:00 2001 From: Jonathan Goldwasser Date: Fri, 5 Nov 2021 22:55:25 +0100 Subject: [PATCH 60/70] chore(lambda-go): fix integ test (#17365) The test was still using the old `lambci` image and this makes the integ test fail apparently. **This currently blocks the build of the repo**. Adapted Dockerfile now that go is not installed in `/go` anymore. ---- *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-go/lib/Dockerfile | 6 ++++-- .../@aws-cdk/aws-lambda-go/test/docker.test.ts | 2 +- .../test/integ.function.expected.json | 18 +++++++++--------- .../aws-lambda-go/test/integ.function.ts | 7 +------ 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/packages/@aws-cdk/aws-lambda-go/lib/Dockerfile b/packages/@aws-cdk/aws-lambda-go/lib/Dockerfile index ffa102c84803c..e832110399bea 100644 --- a/packages/@aws-cdk/aws-lambda-go/lib/Dockerfile +++ b/packages/@aws-cdk/aws-lambda-go/lib/Dockerfile @@ -1,13 +1,15 @@ # The correct AWS SAM build image based on the runtime of the function will be # passed as build arg. The default allows to do `docker build .` when testing. -ARG IMAGE=lambci/lambda:build-go1.x +ARG IMAGE=public.ecr.aws/sam/build-go1.x FROM $IMAGE # set the GOCACHE +ENV GOPATH=/go ENV GOCACHE=$GOPATH/.cache/go-build ENV GOPROXY=direct # Ensure all users can write to GOPATH -RUN chmod -R 777 $GOPATH +RUN mkdir $GOPATH && \ + chmod -R 777 $GOPATH CMD [ "go" ] diff --git a/packages/@aws-cdk/aws-lambda-go/test/docker.test.ts b/packages/@aws-cdk/aws-lambda-go/test/docker.test.ts index d619d9f0fb91d..cd335d834358f 100644 --- a/packages/@aws-cdk/aws-lambda-go/test/docker.test.ts +++ b/packages/@aws-cdk/aws-lambda-go/test/docker.test.ts @@ -2,7 +2,7 @@ import { spawnSync } from 'child_process'; import * as path from 'path'; beforeAll(() => { - spawnSync('docker', ['build', '--build-arg', 'IMAGE=public.ecr.aws/bitnami/golang:1.15', '-t', 'golang', path.join(__dirname, '../lib')]); + spawnSync('docker', ['build', '-t', 'golang', path.join(__dirname, '../lib')]); }); test('golang is available', async () => { diff --git a/packages/@aws-cdk/aws-lambda-go/test/integ.function.expected.json b/packages/@aws-cdk/aws-lambda-go/test/integ.function.expected.json index 9ae6cc08830e8..9ad2aa2afce94 100644 --- a/packages/@aws-cdk/aws-lambda-go/test/integ.function.expected.json +++ b/packages/@aws-cdk/aws-lambda-go/test/integ.function.expected.json @@ -36,7 +36,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParameters4702fc8f2fac1855e6700e59222ef0ebbeaf11eba75c66af9f2e216e312b16b1S3Bucket62A8237E" + "Ref": "AssetParameterse04b349f3d0535498861679603e52edaa01d01ee442f4f665c16e22e5bc81820S3Bucket854EE9A9" }, "S3Key": { "Fn::Join": [ @@ -49,7 +49,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters4702fc8f2fac1855e6700e59222ef0ebbeaf11eba75c66af9f2e216e312b16b1S3VersionKey1C4F3B50" + "Ref": "AssetParameterse04b349f3d0535498861679603e52edaa01d01ee442f4f665c16e22e5bc81820S3VersionKey2AD7C6E5" } ] } @@ -62,7 +62,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters4702fc8f2fac1855e6700e59222ef0ebbeaf11eba75c66af9f2e216e312b16b1S3VersionKey1C4F3B50" + "Ref": "AssetParameterse04b349f3d0535498861679603e52edaa01d01ee442f4f665c16e22e5bc81820S3VersionKey2AD7C6E5" } ] } @@ -87,17 +87,17 @@ } }, "Parameters": { - "AssetParameters4702fc8f2fac1855e6700e59222ef0ebbeaf11eba75c66af9f2e216e312b16b1S3Bucket62A8237E": { + "AssetParameterse04b349f3d0535498861679603e52edaa01d01ee442f4f665c16e22e5bc81820S3Bucket854EE9A9": { "Type": "String", - "Description": "S3 bucket for asset \"4702fc8f2fac1855e6700e59222ef0ebbeaf11eba75c66af9f2e216e312b16b1\"" + "Description": "S3 bucket for asset \"e04b349f3d0535498861679603e52edaa01d01ee442f4f665c16e22e5bc81820\"" }, - "AssetParameters4702fc8f2fac1855e6700e59222ef0ebbeaf11eba75c66af9f2e216e312b16b1S3VersionKey1C4F3B50": { + "AssetParameterse04b349f3d0535498861679603e52edaa01d01ee442f4f665c16e22e5bc81820S3VersionKey2AD7C6E5": { "Type": "String", - "Description": "S3 key for asset version \"4702fc8f2fac1855e6700e59222ef0ebbeaf11eba75c66af9f2e216e312b16b1\"" + "Description": "S3 key for asset version \"e04b349f3d0535498861679603e52edaa01d01ee442f4f665c16e22e5bc81820\"" }, - "AssetParameters4702fc8f2fac1855e6700e59222ef0ebbeaf11eba75c66af9f2e216e312b16b1ArtifactHashBE683488": { + "AssetParameterse04b349f3d0535498861679603e52edaa01d01ee442f4f665c16e22e5bc81820ArtifactHash245320AE": { "Type": "String", - "Description": "Artifact hash for asset \"4702fc8f2fac1855e6700e59222ef0ebbeaf11eba75c66af9f2e216e312b16b1\"" + "Description": "Artifact hash for asset \"e04b349f3d0535498861679603e52edaa01d01ee442f4f665c16e22e5bc81820\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda-go/test/integ.function.ts b/packages/@aws-cdk/aws-lambda-go/test/integ.function.ts index 093597339e8b5..84a30bff352e3 100644 --- a/packages/@aws-cdk/aws-lambda-go/test/integ.function.ts +++ b/packages/@aws-cdk/aws-lambda-go/test/integ.function.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import { App, DockerImage, Stack, StackProps } from '@aws-cdk/core'; +import { App, Stack, StackProps } from '@aws-cdk/core'; import { Construct } from 'constructs'; import * as lambda from '../lib'; @@ -15,11 +15,6 @@ class TestStack extends Stack { new lambda.GoFunction(this, 'go-handler-docker', { entry: path.join(__dirname, 'lambda-handler-vendor/cmd/api'), bundling: { - dockerImage: DockerImage.fromBuild(path.join(__dirname, '../lib'), { - buildArgs: { - IMAGE: 'public.ecr.aws/bitnami/golang:1.16.3-debian-10-r16', - }, - }), forcedDockerBundling: true, goBuildFlags: ['-mod=readonly', '-ldflags "-s -w"'], }, From 42902626efa22165df8e657449ed4bacc962cd68 Mon Sep 17 00:00:00 2001 From: kaizen3031593 <36202692+kaizen3031593@users.noreply.github.com> Date: Fri, 5 Nov 2021 18:45:55 -0400 Subject: [PATCH 61/70] chore: make examples compile (#17360) Included in this PR: - chore(ssm): make examples compile - chore(synthetics): make examples compile ---- *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-ssm/README.md | 4 ++-- .../aws-ssm/rosetta/default.ts-fixture | 12 +++++++++++ packages/@aws-cdk/aws-synthetics/README.md | 16 +++++++------- .../aws-synthetics/rosetta/canary.ts-fixture | 21 ------------------- .../aws-synthetics/rosetta/default.ts-fixture | 3 ++- 5 files changed, 23 insertions(+), 33 deletions(-) create mode 100644 packages/@aws-cdk/aws-ssm/rosetta/default.ts-fixture delete mode 100644 packages/@aws-cdk/aws-synthetics/rosetta/canary.ts-fixture diff --git a/packages/@aws-cdk/aws-ssm/README.md b/packages/@aws-cdk/aws-ssm/README.md index 54e7acab8cec0..23fea31765525 100644 --- a/packages/@aws-cdk/aws-ssm/README.md +++ b/packages/@aws-cdk/aws-ssm/README.md @@ -23,7 +23,7 @@ $ npm i @aws-cdk/aws-ssm Import it into your code: -```ts +```ts nofixture import * as ssm from '@aws-cdk/aws-ssm'; ``` @@ -43,7 +43,7 @@ to provision secrets automatically, use Secrets Manager Secrets (see the `@aws-cdk/aws-secretsmanager` package). ```ts -new ssm.StringParameter(stack, 'Parameter', { +new ssm.StringParameter(this, 'Parameter', { allowedPattern: '.*', description: 'The value Foo', parameterName: 'FooParameter', diff --git a/packages/@aws-cdk/aws-ssm/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-ssm/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..66143d00d0bff --- /dev/null +++ b/packages/@aws-cdk/aws-ssm/rosetta/default.ts-fixture @@ -0,0 +1,12 @@ +// Fixture with packages imported, but nothing else +import { Construct } from 'constructs'; +import { Stack } from '@aws-cdk/core'; +import * as ssm from '@aws-cdk/aws-ssm'; + +class Fixture extends Stack { + constructor(scope: Construct, id: string) { + super(scope, id); + + /// here + } +} diff --git a/packages/@aws-cdk/aws-synthetics/README.md b/packages/@aws-cdk/aws-synthetics/README.md index 013205a4ce3e4..cdb5aaa6dff47 100644 --- a/packages/@aws-cdk/aws-synthetics/README.md +++ b/packages/@aws-cdk/aws-synthetics/README.md @@ -97,15 +97,15 @@ object to the `schedule` property. Configure a run rate of up to 60 minutes with `Schedule.rate`: ```ts -Schedule.rate(Duration.minutes(5)) // Runs every 5 minutes. +const schedule = synthetics.Schedule.rate(Duration.minutes(5)); // Runs every 5 minutes. ``` You can also specify a [cron expression](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Synthetics_Canaries_cron.html) with `Schedule.cron`: ```ts -Schedule.cron({ - hour: '0,8,16' // Run at 12am, 8am, 4pm UTC every day -}) +const schedule = synthetics.Schedule.cron({ + hour: '0,8,16', // Run at 12am, 8am, 4pm UTC every day +}); ``` If you want the canary to run just once upon deployment, you can use `Schedule.once()`. @@ -183,8 +183,10 @@ You can configure a CloudWatch Alarm on a canary metric. Metrics are emitted by Create an alarm that tracks the canary metric: -```ts fixture=canary +```ts import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; + +declare const canary: synthetics.Canary; new cloudwatch.Alarm(this, 'CanaryAlarm', { metric: canary.metricSuccessPercent(), evaluationPeriods: 2, @@ -192,7 +194,3 @@ new cloudwatch.Alarm(this, 'CanaryAlarm', { comparisonOperator: cloudwatch.ComparisonOperator.LESS_THAN_THRESHOLD, }); ``` - -### Future Work - -- Add blueprints to the Test class [#9613](https://github.com/aws/aws-cdk/issues/9613#issue-677134857). diff --git a/packages/@aws-cdk/aws-synthetics/rosetta/canary.ts-fixture b/packages/@aws-cdk/aws-synthetics/rosetta/canary.ts-fixture deleted file mode 100644 index d1950f9d9bcbe..0000000000000 --- a/packages/@aws-cdk/aws-synthetics/rosetta/canary.ts-fixture +++ /dev/null @@ -1,21 +0,0 @@ -// Fixture with a canary already created, named `canary` -import { Construct, Duration, Stack } from '@aws-cdk/core'; -import * as synthetics from '@aws-cdk/aws-synthetics'; -import * as path from 'path'; - -class Fixture extends Stack { - constructor(scope: Construct, id: string) { - super(scope, id); - - const canary = new synthetics.Canary(this, 'MyCanary', { - schedule: synthetics.Schedule.rate(Duration.minutes(5)), - test: synthetics.Test.custom({ - code: synthetics.Code.fromAsset(path.join(__dirname, 'canary')), - handler: 'index.handler', - }), - runtime: synthetics.Runtime.SYNTHETICS_NODEJS_PUPPETEER_3_1, - }); - - /// here - } -} diff --git a/packages/@aws-cdk/aws-synthetics/rosetta/default.ts-fixture b/packages/@aws-cdk/aws-synthetics/rosetta/default.ts-fixture index 0af6c54c30689..a0a9d5c2a596e 100644 --- a/packages/@aws-cdk/aws-synthetics/rosetta/default.ts-fixture +++ b/packages/@aws-cdk/aws-synthetics/rosetta/default.ts-fixture @@ -1,5 +1,6 @@ // Fixture with packages imported, but nothing else -import { Construct, Duration, Stack } from '@aws-cdk/core'; +import { Construct } from 'constructs'; +import { Duration, Stack } from '@aws-cdk/core'; import * as synthetics from '@aws-cdk/aws-synthetics'; import * as path from 'path'; From d5e98ac91497c2fa52b89240c68537a8bd676bbd Mon Sep 17 00:00:00 2001 From: Jonathan Goldwasser Date: Sat, 6 Nov 2021 00:37:01 +0100 Subject: [PATCH 62/70] feat(rds,secretsmanager): subnets and endpoint configuration for secret rotation (#17363) Add options to configure vpc subnet placement and Secrets Manager API endpoint for the rotation Lambda function. This is required in some VPC configurations where the database is placed in subnets without internet connectivity. Closes #17265 ---- *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/README.md | 15 ++ packages/@aws-cdk/aws-rds/lib/props.ts | 19 ++ .../@aws-cdk/aws-rds/test/cluster.test.ts | 191 ++++++++++++++++++ .../@aws-cdk/aws-rds/test/instance.test.ts | 178 ++++++++++++++++ .../aws-secretsmanager/lib/secret-rotation.ts | 14 +- .../test/secret-rotation.test.ts | 34 ++++ 6 files changed, 450 insertions(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-rds/README.md b/packages/@aws-cdk/aws-rds/README.md index 42283697f6181..9f350d3dd1f5b 100644 --- a/packages/@aws-cdk/aws-rds/README.md +++ b/packages/@aws-cdk/aws-rds/README.md @@ -299,6 +299,21 @@ instance.addRotationMultiUser('MyUser', { // Add rotation using the multi user s **Note**: This user must be created manually in the database using the master credentials. The rotation will start as soon as this user exists. +Access to the Secrets Manager API is required for the secret rotation. This can be achieved either with +internet connectivity (through NAT) or with a VPC interface endpoint. By default, the rotation Lambda function +is deployed in the same subnets as the instance/cluster. If access to the Secrets Manager API is not possible from +those subnets or using the default API endpoint, use the `vpcSubnets` and/or `endpoint` options: + +```ts +declare const instance: rds.DatabaseInstance; +declare const myEndpoint: ec2.InterfaceVpcEndpoint; + +instance.addRotationSingleUser({ + vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_NAT }, // Place rotation Lambda in private subnets + endpoint: myEndpoint, // Use VPC interface endpoint +}); +``` + See also [@aws-cdk/aws-secretsmanager](https://github.com/aws/aws-cdk/blob/master/packages/%40aws-cdk/aws-secretsmanager/README.md) for credentials rotation of existing clusters/instances. ## IAM Authentication diff --git a/packages/@aws-cdk/aws-rds/lib/props.ts b/packages/@aws-cdk/aws-rds/lib/props.ts index e9ed3c126cd65..50577cf4dde29 100644 --- a/packages/@aws-cdk/aws-rds/lib/props.ts +++ b/packages/@aws-cdk/aws-rds/lib/props.ts @@ -468,6 +468,25 @@ interface CommonRotationUserOptions { * @default " %+~`#$&*()|[]{}:;<>?!'/@\"\\" */ readonly excludeCharacters?: string; + + /** + * Where to place the rotation Lambda function + * + * @default - same placement as instance or cluster + */ + readonly vpcSubnets?: ec2.SubnetSelection; + + /** + * The VPC interface endpoint to use for the Secrets Manager API + * + * If you enable private DNS hostnames for your VPC private endpoint (the default), you don't + * need to specify an endpoint. The standard Secrets Manager DNS hostname the Secrets Manager + * CLI and SDKs use by default (https://secretsmanager..amazonaws.com) automatically + * resolves to your VPC endpoint. + * + * @default https://secretsmanager..amazonaws.com + */ + readonly endpoint?: ec2.IInterfaceVpcEndpoint; } /** diff --git a/packages/@aws-cdk/aws-rds/test/cluster.test.ts b/packages/@aws-cdk/aws-rds/test/cluster.test.ts index 5adc3d4906643..35fe439c57857 100644 --- a/packages/@aws-cdk/aws-rds/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-rds/test/cluster.test.ts @@ -722,6 +722,197 @@ describe('cluster', () => { }); + test('addRotationSingleUser()', () => { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + const cluster = new DatabaseCluster(stack, 'Database', { + engine: DatabaseClusterEngine.AURORA_MYSQL, + instanceProps: { + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + vpc, + }, + }); + + // WHEN + cluster.addRotationSingleUser(); + + expect(stack).toHaveResource('AWS::SecretsManager::RotationSchedule', { + SecretId: { + Ref: 'DatabaseSecretAttachmentE5D1B020', + }, + RotationLambdaARN: { + 'Fn::GetAtt': [ + 'DatabaseRotationSingleUser65F55654', + 'Outputs.RotationLambdaARN', + ], + }, + RotationRules: { + AutomaticallyAfterDays: 30, + }, + }); + }); + + test('addRotationMultiUser()', () => { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + const cluster = new DatabaseCluster(stack, 'Database', { + engine: DatabaseClusterEngine.AURORA_MYSQL, + instanceProps: { + instanceType: ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.SMALL), + vpc, + }, + }); + + const userSecret = new DatabaseSecret(stack, 'UserSecret', { username: 'user' }); + cluster.addRotationMultiUser('user', { secret: userSecret.attach(cluster) }); + + expect(stack).toHaveResource('AWS::SecretsManager::RotationSchedule', { + SecretId: { + Ref: 'UserSecretAttachment16ACBE6D', + }, + RotationLambdaARN: { + 'Fn::GetAtt': [ + 'DatabaseuserECD1FB0C', + 'Outputs.RotationLambdaARN', + ], + }, + RotationRules: { + AutomaticallyAfterDays: 30, + }, + }); + + expect(stack).toHaveResourceLike('AWS::Serverless::Application', { + Parameters: { + masterSecretArn: { + Ref: 'DatabaseSecretAttachmentE5D1B020', + }, + }, + }); + }); + + test('addRotationSingleUser() with options', () => { + // 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 }, + ], + }); + + // 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.addRotationSingleUser({ + automaticallyAfter: cdk.Duration.days(15), + excludeCharacters: '°_@', + vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_NAT }, + }); + + // THEN + expect(stack).toHaveResource('AWS::SecretsManager::RotationSchedule', { + RotationRules: { + AutomaticallyAfterDays: 15, + }, + }); + + expect(stack).toHaveResource('AWS::Serverless::Application', { + Parameters: { + endpoint: { + 'Fn::Join': ['', [ + 'https://secretsmanager.', + { Ref: 'AWS::Region' }, + '.', + { Ref: 'AWS::URLSuffix' }, + ]], + }, + functionName: 'DatabaseRotationSingleUser458A45BE', + vpcSubnetIds: { + 'Fn::Join': ['', [ + { Ref: 'VpcprivateSubnet1SubnetCEAD3716' }, + ',', + { Ref: 'VpcprivateSubnet2Subnet2DE7549C' }, + ]], + }, + vpcSecurityGroupIds: { + 'Fn::GetAtt': [ + 'DatabaseRotationSingleUserSecurityGroupAC6E0E73', + 'GroupId', + ], + }, + excludeCharacters: '°_@', + }, + }); + }); + + + test('addRotationSingleUser() with VPC interface endpoint', () => { + // GIVEN + const stack = new cdk.Stack(); + const vpcIsolatedOnly = new ec2.Vpc(stack, 'Vpc', { natGateways: 0 }); + + const endpoint = new ec2.InterfaceVpcEndpoint(stack, 'Endpoint', { + service: ec2.InterfaceVpcEndpointAwsService.SECRETS_MANAGER, + vpc: vpcIsolatedOnly, + subnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED }, + }); + + // 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: vpcIsolatedOnly, + vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED }, + }, + }); + + // Rotation in isolated subnet with access to Secrets Manager API via endpoint + cluster.addRotationSingleUser({ endpoint }); + + expect(stack).toHaveResource('AWS::Serverless::Application', { + Parameters: { + endpoint: { + 'Fn::Join': ['', [ + 'https://', + { Ref: 'EndpointEEF1FD8F' }, + '.secretsmanager.', + { Ref: 'AWS::Region' }, + '.', + { Ref: 'AWS::URLSuffix' }, + ]], + }, + functionName: 'DatabaseRotationSingleUser458A45BE', + vpcSubnetIds: { + 'Fn::Join': ['', [ + { Ref: 'VpcIsolatedSubnet1SubnetE48C5737' }, + ',', + { Ref: 'VpcIsolatedSubnet2Subnet16364B91' }, + ]], + }, + vpcSecurityGroupIds: { + 'Fn::GetAtt': [ + 'DatabaseRotationSingleUserSecurityGroupAC6E0E73', + 'GroupId', + ], + }, + excludeCharacters: " %+~`#$&*()|[]{}:;<>?!'/@\"\\", + }, + }); + }); + test('throws when trying to add rotation to a cluster without secret', () => { // GIVEN const stack = new cdk.Stack(); diff --git a/packages/@aws-cdk/aws-rds/test/instance.test.ts b/packages/@aws-cdk/aws-rds/test/instance.test.ts index 7364599e4ed25..9f94607eda8ad 100644 --- a/packages/@aws-cdk/aws-rds/test/instance.test.ts +++ b/packages/@aws-cdk/aws-rds/test/instance.test.ts @@ -738,6 +738,184 @@ describe('instance', () => { }); + test('addRotationSingleUser()', () => { + // GIVEN + const instance = new rds.DatabaseInstance(stack, 'Database', { + engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_10 }), + vpc, + }); + + // WHEN + instance.addRotationSingleUser(); + + // THEN + expect(stack).toHaveResource('AWS::SecretsManager::RotationSchedule', { + SecretId: { + Ref: 'DatabaseSecretAttachmentE5D1B020', + }, + RotationLambdaARN: { + 'Fn::GetAtt': [ + 'DatabaseRotationSingleUser65F55654', + 'Outputs.RotationLambdaARN', + ], + }, + RotationRules: { + AutomaticallyAfterDays: 30, + }, + }); + }); + + test('addRotationMultiUser()', () => { + // GIVEN + const instance = new rds.DatabaseInstance(stack, 'Database', { + engine: rds.DatabaseInstanceEngine.postgres({ version: rds.PostgresEngineVersion.VER_10 }), + vpc, + }); + + // WHEN + const userSecret = new rds.DatabaseSecret(stack, 'UserSecret', { username: 'user' }); + instance.addRotationMultiUser('user', { secret: userSecret.attach(instance) }); + + // THEN + expect(stack).toHaveResource('AWS::SecretsManager::RotationSchedule', { + SecretId: { + Ref: 'UserSecretAttachment16ACBE6D', + }, + RotationLambdaARN: { + 'Fn::GetAtt': [ + 'DatabaseuserECD1FB0C', + 'Outputs.RotationLambdaARN', + ], + }, + RotationRules: { + AutomaticallyAfterDays: 30, + }, + }); + + expect(stack).toHaveResourceLike('AWS::Serverless::Application', { + Parameters: { + masterSecretArn: { + Ref: 'DatabaseSecretAttachmentE5D1B020', + }, + }, + }); + }); + + test('addRotationSingleUser() with options', () => { + // 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 }, + ], + }); + + // 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.addRotationSingleUser({ + automaticallyAfter: cdk.Duration.days(15), + excludeCharacters: '°_@', + vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_WITH_NAT }, + }); + + // THEN + expect(stack).toHaveResource('AWS::SecretsManager::RotationSchedule', { + RotationRules: { + AutomaticallyAfterDays: 15, + }, + }); + + expect(stack).toHaveResource('AWS::Serverless::Application', { + Parameters: { + endpoint: { + 'Fn::Join': ['', [ + 'https://secretsmanager.', + { Ref: 'AWS::Region' }, + '.', + { Ref: 'AWS::URLSuffix' }, + ]], + }, + functionName: 'DatabaseRotationSingleUser458A45BE', + vpcSubnetIds: { + 'Fn::Join': ['', [ + { Ref: 'VpcprivateSubnet1SubnetCEAD3716' }, + ',', + { Ref: 'VpcprivateSubnet2Subnet2DE7549C' }, + ]], + }, + vpcSecurityGroupIds: { + 'Fn::GetAtt': [ + 'DatabaseRotationSingleUserSecurityGroupAC6E0E73', + 'GroupId', + ], + }, + excludeCharacters: '°_@', + }, + }); + }); + + + test('addRotationSingleUser() with VPC interface endpoint', () => { + // GIVEN + const vpcIsolatedOnly = new ec2.Vpc(stack, 'Vpc', { natGateways: 0 }); + + const endpoint = new ec2.InterfaceVpcEndpoint(stack, 'Endpoint', { + service: ec2.InterfaceVpcEndpointAwsService.SECRETS_MANAGER, + vpc: vpcIsolatedOnly, + subnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED }, + }); + + // 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: vpcIsolatedOnly, + vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED }, + }); + + // Rotation in isolated subnet with access to Secrets Manager API via endpoint + instance.addRotationSingleUser({ endpoint }); + + // THEN + expect(stack).toHaveResource('AWS::Serverless::Application', { + Parameters: { + endpoint: { + 'Fn::Join': ['', [ + 'https://', + { Ref: 'EndpointEEF1FD8F' }, + '.secretsmanager.', + { Ref: 'AWS::Region' }, + '.', + { Ref: 'AWS::URLSuffix' }, + ]], + }, + functionName: 'DatabaseRotationSingleUser458A45BE', + vpcSubnetIds: { + 'Fn::Join': ['', [ + { Ref: 'VpcIsolatedSubnet1SubnetE48C5737' }, + ',', + { Ref: 'VpcIsolatedSubnet2Subnet16364B91' }, + ]], + }, + vpcSecurityGroupIds: { + 'Fn::GetAtt': [ + 'DatabaseRotationSingleUserSecurityGroupAC6E0E73', + 'GroupId', + ], + }, + excludeCharacters: " %+~`#$&*()|[]{}:;<>?!'/@\"\\", + }, + }); + }); + test('throws when trying to add rotation to an instance without secret', () => { const instance = new rds.DatabaseInstance(stack, 'Database', { engine: rds.DatabaseInstanceEngine.SQL_SERVER_EE, diff --git a/packages/@aws-cdk/aws-secretsmanager/lib/secret-rotation.ts b/packages/@aws-cdk/aws-secretsmanager/lib/secret-rotation.ts index fb52821c88729..7311288279a51 100644 --- a/packages/@aws-cdk/aws-secretsmanager/lib/secret-rotation.ts +++ b/packages/@aws-cdk/aws-secretsmanager/lib/secret-rotation.ts @@ -245,6 +245,18 @@ export interface SecretRotationProps { * @default - no additional characters are explicitly excluded */ readonly excludeCharacters?: string; + + /** + * The VPC interface endpoint to use for the Secrets Manager API + * + * If you enable private DNS hostnames for your VPC private endpoint (the default), you don't + * need to specify an endpoint. The standard Secrets Manager DNS hostname the Secrets Manager + * CLI and SDKs use by default (https://secretsmanager..amazonaws.com) automatically + * resolves to your VPC endpoint. + * + * @default https://secretsmanager..amazonaws.com + */ + readonly endpoint?: ec2.IInterfaceVpcEndpoint; } /** @@ -272,7 +284,7 @@ export class SecretRotation extends CoreConstruct { props.target.connections.allowDefaultPortFrom(securityGroup); const parameters: { [key: string]: string } = { - endpoint: `https://secretsmanager.${Stack.of(this).region}.${Stack.of(this).urlSuffix}`, + endpoint: `https://${props.endpoint ? `${props.endpoint.vpcEndpointId}.` : ''}secretsmanager.${Stack.of(this).region}.${Stack.of(this).urlSuffix}`, functionName: rotationFunctionName, vpcSubnetIds: props.vpc.selectSubnets(props.vpcSubnets).subnetIds.join(','), vpcSecurityGroupIds: securityGroup.securityGroupId, diff --git a/packages/@aws-cdk/aws-secretsmanager/test/secret-rotation.test.ts b/packages/@aws-cdk/aws-secretsmanager/test/secret-rotation.test.ts index 55c7388393619..974aa0c611c4d 100644 --- a/packages/@aws-cdk/aws-secretsmanager/test/secret-rotation.test.ts +++ b/packages/@aws-cdk/aws-secretsmanager/test/secret-rotation.test.ts @@ -345,3 +345,37 @@ test('rotation function name does not exceed 64 chars', () => { }, }); }); + + +test('with interface vpc endpoint', () => { + // GIVEN + const endpoint = new ec2.InterfaceVpcEndpoint(stack, 'SecretsManagerEndpoint', { + service: ec2.InterfaceVpcEndpointAwsService.SECRETS_MANAGER, + vpc, + }); + + // WHEN + new secretsmanager.SecretRotation(stack, 'SecretRotation', { + application: secretsmanager.SecretRotationApplication.MYSQL_ROTATION_SINGLE_USER, + secret, + target, + vpc, + endpoint, + }); + + // THEN + expect(stack).toHaveResourceLike('AWS::Serverless::Application', { + Parameters: { + endpoint: { + 'Fn::Join': ['', [ + 'https://', + { Ref: 'SecretsManagerEndpoint5E83C66B' }, + '.secretsmanager.', + { Ref: 'AWS::Region' }, + '.', + { Ref: 'AWS::URLSuffix' }, + ]], + }, + }, + }); +}); From 5f6d550677d1998a5a2720aabbff1ed2c3815aeb Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Sat, 6 Nov 2021 02:26:07 +0200 Subject: [PATCH 63/70] fix: java and python templates are broken (#17357) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are two problems. ### Python The `app` template doesn't define any tests (it does, but they are commented out), this makes `pytest` fail during our integ tests: ```console ============================= test session starts ============================== 970 | platform linux -- Python 3.7.3, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 971 | rootdir: /tmp/cdk-init-test 972 | collected 0 items 973 |   974 | ============================ no tests ran in 0.01s ============================= 975 | + run_traps 976 | + for cmd in "${TRAPS[@]}" 977 | + echo 'cleanup: kill 121' 978 | cleanup: kill 121 979 | + eval 'kill 121' 980 | ++ kill 121 981 | + for cmd in "${TRAPS[@]}" 982 | + echo 'cleanup: clean_up_nuget_config' 983 | cleanup: clean_up_nuget_config 984 | + eval clean_up_nuget_config 985 | ++ clean_up_nuget_config 986 | ++ log 'Restoring NuGet configuration' 987 | ++ echo '\| Restoring NuGet configuration' 988 | \| Restoring NuGet configuration 989 | ++ '[' -f /root/.nuget/NuGet/NuGet.Config.bak ']' 990 | ++ log '-> Removing /root/.nuget/NuGet/NuGet.Config' 991 | ++ echo '\| -> Removing /root/.nuget/NuGet/NuGet.Config' 992 | \| -> Removing /root/.nuget/NuGet/NuGet.Config 993 | ++ rm -f /root/.nuget/NuGet/NuGet.Config 994 |   995 | [Container] 2021/11/05 05:05:43 Command did not exit successfully /bin/bash /tmp/scriptdir/cdk/init-templates/dispatch.sh exit status 5 996 | [Container] 2021/11/05 05:05:43 Phase complete: BUILD State: FAILED 997 | [Container] 2021/11/05 05:05:43 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: /bin/bash /tmp/scriptdir/cdk/init-templates/dispatch.sh. Reason: exit status 5 998 | [Container] 2021/11/05 05:05:43 Entering phase POST_BUILD 999 | [Container] 2021/11/05 05:05:43 Phase complete: POST_BUILD State: SUCCEEDED 1000 | [Container] 2021/11/05 05:05:43 Phase context status code: Message: 1001
``` Solution is to uncomment the test method signature and making it an empty test, just like we do with typescript. ### Java `Map.of` doesn't exist in Java 8 and we are getting complication errors during `mvn package`: ```console [INFO] ------------------------------------------------------------- -- 1018 | [ERROR] COMPILATION ERROR : 1019 | [INFO] ------------------------------------------------------------- 1020 | [ERROR] /tmp/cdk-init-test/src/test/java/com/myorg/CdkInitTestStackTest.java:[21,62] cannot find symbol 1021 | symbol: method of(java.lang.String,int) 1022 | location: interface java.util.Map 1023 | [INFO] 1 error ``` Solution is to replace `Map.of` with `new HashMap` that is supported everywhere. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- CONTRIBUTING.md | 1 + .../java/com/myorg/%name.PascalCased%Test.template.java | 8 ++++---- .../v1/app/python/requirements.template.txt | 4 ++-- .../tests/unit/test_%name.PythonModule%_stack.template.py | 3 ++- .../com/myorg/%name.PascalCased%StackTest.template.java | 8 ++++---- .../java/com/myorg/%name.PascalCased%Test.template.java | 8 ++++---- .../com/myorg/%name.PascalCased%StackTest.template.java | 8 ++++---- 7 files changed, 21 insertions(+), 19 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5af7da4ecc25a..dca9ebdce5f06 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -978,3 +978,4 @@ $ node --inspect-brk /path/to/aws-cdk/node_modules/.bin/jest -i -t 'TESTNAME' * [Workshop](https://github.com/aws-samples/aws-cdk-intro-workshop): source for https://cdkworkshop.com * [Developer Guide](https://github.com/awsdocs/aws-cdk-guide): markdown source for developer guide * [jsii](https://github.com/aws/jsii): the technology we use for multi-language support. If you are looking to help us support new languages, start there. + diff --git a/packages/aws-cdk/lib/init-templates/v1/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java b/packages/aws-cdk/lib/init-templates/v1/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java index f96ca04987f31..e095565be7920 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java +++ b/packages/aws-cdk/lib/init-templates/v1/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java @@ -4,7 +4,7 @@ // import software.amazon.awscdk.assertions.Template; // import java.io.IOException; -// import java.util.Map; +// import java.util.HashMap; // import org.junit.jupiter.api.Test; @@ -19,8 +19,8 @@ // Template template = Template.fromStack(stack); -// template.hasResourceProperties("AWS::SQS::Queue", Map.of( -// "VisibilityTimeout", 300 -// )); +// template.hasResourceProperties("AWS::SQS::Queue", new HashMap() {{ +// put("VisibilityTimeout", 300); +// }}); // } // } diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.template.txt b/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.template.txt index e14ce6e77e499..87cbb00cfac55 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.template.txt +++ b/packages/aws-cdk/lib/init-templates/v1/app/python/requirements.template.txt @@ -1,2 +1,2 @@ -aws-cdk.core>=%cdk-version%, -aws-cdk.assertions>=%cdk-version%, +aws-cdk.core>=%cdk-version% +aws-cdk.assertions>=%cdk-version% diff --git a/packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/test_%name.PythonModule%_stack.template.py b/packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/test_%name.PythonModule%_stack.template.py index 94f2234e02aa6..1b0e4b66e9aaa 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/test_%name.PythonModule%_stack.template.py +++ b/packages/aws-cdk/lib/init-templates/v1/app/python/tests/unit/test_%name.PythonModule%_stack.template.py @@ -8,7 +8,7 @@ # example tests. To run these tests, uncomment this file along with the example # resource in %name.PythonModule%/%name.PythonModule%_stack.py -# def test_sqs_queue_created(): +def test_sqs_queue_created(): # app = core.App() # stack = %name.PascalCased%Stack(app, "%name.StackName%") # template = assertions.Template.from_stack(stack) @@ -16,3 +16,4 @@ # template.has_resource_properties("AWS::SQS::Queue", { # "VisibilityTimeout": 300 # }) + pass diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java b/packages/aws-cdk/lib/init-templates/v1/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java index b648a3a72dc46..5cbbe8a127e4f 100644 --- a/packages/aws-cdk/lib/init-templates/v1/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java @@ -5,7 +5,7 @@ import software.amazon.awscdk.assertions.Match; import java.io.IOException; -import java.util.Map; +import java.util.HashMap; import org.junit.jupiter.api.Test; @@ -18,9 +18,9 @@ public void testStack() throws IOException { Template template = Template.fromStack(stack); - template.hasResourceProperties("AWS::SQS::Queue", Map.of( - "VisibilityTimeout", 300 - )); + template.hasResourceProperties("AWS::SQS::Queue", new HashMap() {{ + put("VisibilityTimeout", 300); + }}); template.resourceCountIs("AWS::SNS::Topic", 1); } } diff --git a/packages/aws-cdk/lib/init-templates/v2/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java b/packages/aws-cdk/lib/init-templates/v2/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java index 5e9d7806654d0..564b1682848ca 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java +++ b/packages/aws-cdk/lib/init-templates/v2/app/java/src/test/java/com/myorg/%name.PascalCased%Test.template.java @@ -4,7 +4,7 @@ // import software.amazon.awscdk.assertions.alpha.Template; // import java.io.IOException; -// import java.util.Map; +// import java.util.HashMap; // import org.junit.jupiter.api.Test; @@ -19,8 +19,8 @@ // Template template = Template.fromStack(stack); -// template.hasResourceProperties("AWS::SQS::Queue", Map.of( -// "VisibilityTimeout", 300 -// )); +// template.hasResourceProperties("AWS::SQS::Queue", new HashMap() {{ +// put("VisibilityTimeout", 300); +// }}); // } // } diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java b/packages/aws-cdk/lib/init-templates/v2/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java index c728c6eb6323c..1cd39ad8da3bb 100644 --- a/packages/aws-cdk/lib/init-templates/v2/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/java/src/test/java/com/myorg/%name.PascalCased%StackTest.template.java @@ -5,7 +5,7 @@ import software.amazon.awscdk.assertions.alpha.Match; import java.io.IOException; -import java.util.Map; +import java.util.HashMap; import org.junit.jupiter.api.Test; @@ -18,9 +18,9 @@ public void testStack() throws IOException { Template template = Template.fromStack(stack); - template.hasResourceProperties("AWS::SQS::Queue", Map.of( - "VisibilityTimeout", 300 - )); + template.hasResourceProperties("AWS::SQS::Queue", new HashMap() {{ + put("VisibilityTimeout", 300); + }}); template.resourceCountIs("AWS::SNS::Topic", 1); } From 6420b1817d4319924d11cfccb8b6a29d4a2d5008 Mon Sep 17 00:00:00 2001 From: Unnati Parekh <80710604+upparekh@users.noreply.github.com> Date: Fri, 5 Nov 2021 18:17:11 -0700 Subject: [PATCH 64/70] feat(ecs-service-extensions): Target tracking policies for Service Extensions (#17101) ---- This PR adds `desiredCount`, `targetCpuUtilization` and `targetMemoryUtilization` to the service construct. It also adds `requestsPerTarget` to the `HttpLoadBalancerExtension` props to allow adding target tracking policy based on the ALB request count. It will be followed by another PR to configure queue auto scaling for the SQS Queues in the `QueueExtension`. *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../ecs-service-extensions/README.md | 67 ++++++---- .../lib/extensions/http-load-balancer.ts | 23 +++- .../ecs-service-extensions/lib/service.ts | 90 +++++++++++++- .../test/http-load-balancer.test.ts | 68 +++++++++++ .../test/service.test.ts | 114 ++++++++++++++++++ 5 files changed, 338 insertions(+), 24 deletions(-) diff --git a/packages/@aws-cdk-containers/ecs-service-extensions/README.md b/packages/@aws-cdk-containers/ecs-service-extensions/README.md index 0556debfc705f..b80f1539f4447 100644 --- a/packages/@aws-cdk-containers/ecs-service-extensions/README.md +++ b/packages/@aws-cdk-containers/ecs-service-extensions/README.md @@ -154,43 +154,68 @@ const nameService = new Service(stack, 'name', { }); ``` +## Task Auto-Scaling + +You can configure the task count of a service to match demand. The recommended way of achieving this is to configure target tracking policies for your service which scales in and out in order to keep metrics around target values. + +You need to configure an auto scaling target for the service by setting the `minTaskCount` (defaults to 1) and `maxTaskCount` in the `Service` construct. Then you can specify target values for "CPU Utilization" or "Memory Utilization" across all tasks in your service. Note that the `desiredCount` value will be set to `undefined` if the auto scaling target is configured. + +If you want to configure auto-scaling policies based on resources like Application Load Balancer or SQS Queues, you can set the corresponding resource-specific fields in the extension. For example, you can enable target tracking scaling based on Application Load Balancer request count as follows: + +```ts +const stack = new cdk.Stack(); +const environment = new Environment(stack, 'production'); +const serviceDescription = new ServiceDescription(); + +serviceDescription.add(new Container({ + cpu: 256, + memoryMiB: 512, + trafficPort: 80, + image: ecs.ContainerImage.fromRegistry('my-alb'), +})); + +// Add the extension with target `requestsPerTarget` value set +serviceDescription.add(new HttpLoadBalancerExtension({ requestsPerTarget: 10 })); + +// Configure the auto scaling target +new Service(stack, 'my-service', { + environment, + serviceDescription, + desiredCount: 5, + // Task auto-scaling constuct for the service + autoScaleTaskCount: { + maxTaskCount: 10, + targetCpuUtilization: 70, + targetMemoryUtilization: 50, + }, +}); +``` + +You can also define your own service extensions for [other auto-scaling policies](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-auto-scaling.html) for your service by making use of the `scalableTaskCount` attribute of the `Service` class. + ## Creating your own custom `ServiceExtension` In addition to using the default service extensions that come with this module, you can choose to implement your own custom service extensions. The `ServiceExtension` class is an abstract class you can implement yourself. The following example implements a custom service extension that could be added to a service in order to -autoscale it based on CPU: +autoscale it based on scaling intervals of SQS Queue size: ```ts export class MyCustomAutoscaling extends ServiceExtension { constructor() { super('my-custom-autoscaling'); - } - - // This function modifies properties of the service prior - // to construct creation. - public modifyServiceProps(props: ServiceBuild) { - return { - ...props, - - // Initially launch 10 copies of the service - desiredCount: 10 - } as ServiceBuild; + // Scaling intervals for the step scaling policy + this.scalingSteps = [{ upper: 0, change: -1 }, { lower: 100, change: +1 }, { lower: 500, change: +5 }]; + this.sqsQueue = new sqs.Queue(this.scope, 'my-queue'); } // This hook utilizes the resulting service construct // once it is created public useService(service: ecs.Ec2Service | ecs.FargateService) { - const scalingTarget = service.autoScaleTaskCount({ - minCapacity: 5, // Min 5 tasks - maxCapacity: 20 // Max 20 tasks - }); - - scalingTarget.scaleOnCpuUtilization('TargetCpuUtilization50', { - targetUtilizationPercent: 50, - scaleInCooldown: cdk.Duration.seconds(60), - scaleOutCooldown: cdk.Duration.seconds(60), + this.parentService.scalableTaskCount.scaleOnMetric('QueueMessagesVisibleScaling', { + metric: this.sqsQueue.metricApproximateNumberOfMessagesVisible(), + scalingSteps: this.scalingSteps, }); } } diff --git a/packages/@aws-cdk-containers/ecs-service-extensions/lib/extensions/http-load-balancer.ts b/packages/@aws-cdk-containers/ecs-service-extensions/lib/extensions/http-load-balancer.ts index e0390c0ab617c..6db6a6c9616d4 100644 --- a/packages/@aws-cdk-containers/ecs-service-extensions/lib/extensions/http-load-balancer.ts +++ b/packages/@aws-cdk-containers/ecs-service-extensions/lib/extensions/http-load-balancer.ts @@ -8,6 +8,12 @@ import { ServiceExtension, ServiceBuild } from './extension-interfaces'; // eslint-disable-next-line no-duplicate-imports, import/order import { Construct } from '@aws-cdk/core'; +export interface HttpLoadBalancerProps { + /** + * The number of ALB requests per target. + */ + readonly requestsPerTarget?: number; +} /** * This extension add a public facing load balancer for sending traffic * to one or more replicas of the application container. @@ -15,9 +21,11 @@ import { Construct } from '@aws-cdk/core'; export class HttpLoadBalancerExtension extends ServiceExtension { private loadBalancer!: alb.IApplicationLoadBalancer; private listener!: alb.IApplicationListener; + private requestsPerTarget?: number; - constructor() { + constructor(props: HttpLoadBalancerProps = {}) { super('load-balancer'); + this.requestsPerTarget = props.requestsPerTarget; } // Before the service is created, go ahead and create the load balancer itself. @@ -55,10 +63,21 @@ export class HttpLoadBalancerExtension extends ServiceExtension { // After the service is created add the service to the load balancer's listener public useService(service: ecs.Ec2Service | ecs.FargateService) { - this.listener.addTargets(this.parentService.id, { + const targetGroup = this.listener.addTargets(this.parentService.id, { deregistrationDelay: cdk.Duration.seconds(10), port: 80, targets: [service], }); + + if (this.requestsPerTarget) { + if (!this.parentService.scalableTaskCount) { + throw Error(`Auto scaling target for the service '${this.parentService.id}' hasn't been configured. Please use Service construct to configure 'minTaskCount' and 'maxTaskCount'.`); + } + this.parentService.scalableTaskCount.scaleOnRequestCount(`${this.parentService.id}-target-request-count-${this.requestsPerTarget}`, { + requestsPerTarget: this.requestsPerTarget, + targetGroup, + }); + this.parentService.enableAutoScalingPolicy(); + } } } diff --git a/packages/@aws-cdk-containers/ecs-service-extensions/lib/service.ts b/packages/@aws-cdk-containers/ecs-service-extensions/lib/service.ts index 4fdc8590c1dc0..957dcef280cd7 100644 --- a/packages/@aws-cdk-containers/ecs-service-extensions/lib/service.ts +++ b/packages/@aws-cdk-containers/ecs-service-extensions/lib/service.ts @@ -30,6 +30,43 @@ export interface ServiceProps { * @default - A task role is automatically created for you. */ readonly taskRole?: iam.IRole; + + /** + * The desired number of instantiations of the task definition to keep running on the service. + * + * @default - When creating the service, default is 1; when updating the service, default uses + * the current task number. + */ + readonly desiredCount?: number; + + /** + * The options for configuring the auto scaling target. + */ + readonly autoScaleTaskCount?: AutoScalingOptions; +} + +export interface AutoScalingOptions { + /** + * The minimum number of tasks when scaling in. + * + * @default - 1 + */ + readonly minTaskCount?: number; + + /** + * The maximum number of tasks when scaling out. + */ + readonly maxTaskCount: number; + + /** + * The target value for CPU utilization across all tasks in the service. + */ + readonly targetCpuUtilization?: number; + + /** + * The target value for memory utilization across all tasks in the service. + */ + readonly targetMemoryUtilization?: number; } /** @@ -75,6 +112,17 @@ export class Service extends Construct { */ public readonly environment: IEnvironment; + /** + * The scalable attribute representing task count. + */ + public readonly scalableTaskCount?: ecs.ScalableTaskCount; + + /** + * The flag to track if auto scaling policies have been configured + * for the service. + */ + private autoScalingPoliciesEnabled: boolean = false; + /** * The generated task definition for this service. It is only * generated after .prepare() has been executed. @@ -160,6 +208,9 @@ export class Service extends Construct { } } + // Set desiredCount to `undefined` if auto scaling is configured for the service + const desiredCount = props.autoScaleTaskCount ? undefined : (props.desiredCount || 1); + // Give each extension a chance to mutate the service props before // service creation let serviceProps = { @@ -167,7 +218,7 @@ export class Service extends Construct { taskDefinition: this.taskDefinition, minHealthyPercent: 100, maxHealthyPercent: 200, - desiredCount: 1, + desiredCount, } as ServiceBuild; for (const extensions in this.serviceDescription.extensions) { @@ -219,12 +270,41 @@ export class Service extends Construct { throw new Error(`Unknown capacity type for service ${this.id}`); } + // Create the auto scaling target and configure target tracking policies after the service is created + if (props.autoScaleTaskCount) { + this.scalableTaskCount = this.ecsService.autoScaleTaskCount({ + maxCapacity: props.autoScaleTaskCount.maxTaskCount, + minCapacity: props.autoScaleTaskCount.minTaskCount, + }); + + if (props.autoScaleTaskCount.targetCpuUtilization) { + const targetUtilizationPercent = props.autoScaleTaskCount.targetCpuUtilization; + this.scalableTaskCount.scaleOnCpuUtilization(`${this.id}-target-cpu-utilization-${targetUtilizationPercent}`, { + targetUtilizationPercent, + }); + this.enableAutoScalingPolicy(); + } + + if (props.autoScaleTaskCount.targetMemoryUtilization) { + const targetUtilizationPercent = props.autoScaleTaskCount.targetMemoryUtilization; + this.scalableTaskCount.scaleOnMemoryUtilization(`${this.id}-target-memory-utilization-${targetUtilizationPercent}`, { + targetUtilizationPercent, + }); + this.enableAutoScalingPolicy(); + } + } + // Now give all extensions a chance to use the service for (const extensions in this.serviceDescription.extensions) { if (this.serviceDescription.extensions[extensions]) { this.serviceDescription.extensions[extensions].useService(this.ecsService); } } + + // Error out if the auto scaling target is created but no scaling policies have been configured + if (this.scalableTaskCount && !this.autoScalingPoliciesEnabled) { + throw Error(`The auto scaling target for the service '${this.id}' has been created but no auto scaling policies have been configured.`); + } } /** @@ -266,4 +346,12 @@ export class Service extends Construct { return this.urls[urlName]; } + + /** + * This helper method is used to set the `autoScalingPoliciesEnabled` attribute + * whenever an auto scaling policy is configured for the service. + */ + public enableAutoScalingPolicy() { + this.autoScalingPoliciesEnabled = true; + } } diff --git a/packages/@aws-cdk-containers/ecs-service-extensions/test/http-load-balancer.test.ts b/packages/@aws-cdk-containers/ecs-service-extensions/test/http-load-balancer.test.ts index 5e0d0e36ff554..e06c1632d93b5 100644 --- a/packages/@aws-cdk-containers/ecs-service-extensions/test/http-load-balancer.test.ts +++ b/packages/@aws-cdk-containers/ecs-service-extensions/test/http-load-balancer.test.ts @@ -72,4 +72,72 @@ describe('http load balancer', () => { }); + test('allows scaling on request count for the HTTP load balancer', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + const environment = new Environment(stack, 'production'); + const serviceDescription = new ServiceDescription(); + + serviceDescription.add(new Container({ + cpu: 256, + memoryMiB: 512, + trafficPort: 80, + image: ecs.ContainerImage.fromRegistry('nathanpeck/name'), + })); + + serviceDescription.add(new HttpLoadBalancerExtension({ requestsPerTarget: 100 })); + + new Service(stack, 'my-service', { + environment, + serviceDescription, + autoScaleTaskCount: { + maxTaskCount: 5, + }, + }); + + // THEN + expect(stack).toHaveResourceLike('AWS::ApplicationAutoScaling::ScalableTarget', { + MaxCapacity: 5, + MinCapacity: 1, + }); + + expect(stack).toHaveResourceLike('AWS::ApplicationAutoScaling::ScalingPolicy', { + PolicyType: 'TargetTrackingScaling', + TargetTrackingScalingPolicyConfiguration: { + PredefinedMetricSpecification: { + PredefinedMetricType: 'ALBRequestCountPerTarget', + }, + TargetValue: 100, + }, + }); + }); + + test('should error when adding scaling policy if scaling target has not been configured', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + const environment = new Environment(stack, 'production'); + const serviceDescription = new ServiceDescription(); + + serviceDescription.add(new Container({ + cpu: 256, + memoryMiB: 512, + trafficPort: 80, + image: ecs.ContainerImage.fromRegistry('nathanpeck/name'), + })); + + serviceDescription.add(new HttpLoadBalancerExtension({ requestsPerTarget: 100 })); + + // THEN + expect(() => { + new Service(stack, 'my-service', { + environment, + serviceDescription, + }); + }).toThrow(/Auto scaling target for the service 'my-service' hasn't been configured. Please use Service construct to configure 'minTaskCount' and 'maxTaskCount'./); + }); + }); \ No newline at end of file diff --git a/packages/@aws-cdk-containers/ecs-service-extensions/test/service.test.ts b/packages/@aws-cdk-containers/ecs-service-extensions/test/service.test.ts index eb21eec01b5f5..65807231679b7 100644 --- a/packages/@aws-cdk-containers/ecs-service-extensions/test/service.test.ts +++ b/packages/@aws-cdk-containers/ecs-service-extensions/test/service.test.ts @@ -1,3 +1,4 @@ +import { ABSENT } from '@aws-cdk/assert-internal'; import '@aws-cdk/assert-internal/jest'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as ecs from '@aws-cdk/aws-ecs'; @@ -102,4 +103,117 @@ describe('service', () => { }); + test('allows scaling on a target CPU utilization', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + const environment = new Environment(stack, 'production'); + const serviceDescription = new ServiceDescription(); + serviceDescription.add(new Container({ + cpu: 256, + memoryMiB: 512, + trafficPort: 80, + image: ecs.ContainerImage.fromRegistry('nathanpeck/name'), + })); + + new Service(stack, 'my-service', { + environment, + serviceDescription, + desiredCount: 3, + autoScaleTaskCount: { + maxTaskCount: 5, + targetCpuUtilization: 70, + }, + }); + + // THEN + expect(stack).toHaveResourceLike('AWS::ECS::Service', { + DesiredCount: ABSENT, + }); + + expect(stack).toHaveResourceLike('AWS::ApplicationAutoScaling::ScalableTarget', { + MaxCapacity: 5, + MinCapacity: 1, + }); + + expect(stack).toHaveResource('AWS::ApplicationAutoScaling::ScalingPolicy', { + PolicyType: 'TargetTrackingScaling', + TargetTrackingScalingPolicyConfiguration: { + PredefinedMetricSpecification: { PredefinedMetricType: 'ECSServiceAverageCPUUtilization' }, + TargetValue: 70, + }, + }); + }); + + test('allows scaling on a target memory utilization', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + const environment = new Environment(stack, 'production'); + const serviceDescription = new ServiceDescription(); + serviceDescription.add(new Container({ + cpu: 256, + memoryMiB: 512, + trafficPort: 80, + image: ecs.ContainerImage.fromRegistry('nathanpeck/name'), + })); + + new Service(stack, 'my-service', { + environment, + serviceDescription, + desiredCount: 3, + autoScaleTaskCount: { + maxTaskCount: 5, + targetMemoryUtilization: 70, + }, + }); + + // THEN + expect(stack).toHaveResourceLike('AWS::ECS::Service', { + DesiredCount: ABSENT, + }); + + expect(stack).toHaveResourceLike('AWS::ApplicationAutoScaling::ScalableTarget', { + MaxCapacity: 5, + MinCapacity: 1, + }); + + expect(stack).toHaveResource('AWS::ApplicationAutoScaling::ScalingPolicy', { + PolicyType: 'TargetTrackingScaling', + TargetTrackingScalingPolicyConfiguration: { + PredefinedMetricSpecification: { PredefinedMetricType: 'ECSServiceAverageMemoryUtilization' }, + TargetValue: 70, + }, + }); + }); + + test('should error when no auto scaling policies have been configured after creating the auto scaling target', () => { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + const environment = new Environment(stack, 'production'); + const serviceDescription = new ServiceDescription(); + + serviceDescription.add(new Container({ + cpu: 256, + memoryMiB: 512, + trafficPort: 80, + image: ecs.ContainerImage.fromRegistry('nathanpeck/name'), + })); + + // THEN + expect(() => { + new Service(stack, 'my-service', { + environment, + serviceDescription, + autoScaleTaskCount: { + maxTaskCount: 5, + }, + }); + }).toThrow(/The auto scaling target for the service 'my-service' has been created but no auto scaling policies have been configured./); + }); + }); \ No newline at end of file From 9f9fe8ad6857c4a21f71af437964e8c3a20c63ef Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Sat, 6 Nov 2021 12:23:53 +0200 Subject: [PATCH 65/70] chore: make new scripts executable (#17373) --- scripts/cache-store.sh | 0 scripts/run-rosetta.sh | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 scripts/cache-store.sh mode change 100644 => 100755 scripts/run-rosetta.sh diff --git a/scripts/cache-store.sh b/scripts/cache-store.sh old mode 100644 new mode 100755 diff --git a/scripts/run-rosetta.sh b/scripts/run-rosetta.sh old mode 100644 new mode 100755 From 747eb7cf5dba4514241103ffebc49e03261d25a9 Mon Sep 17 00:00:00 2001 From: tmokmss Date: Sun, 7 Nov 2021 03:29:49 +0900 Subject: [PATCH 66/70] feat(apigatewayv2-authorizers): http api - allow multiple user pool clients per HttpUserPoolAuthorizer (#16903) closes #15431 BREAKING CHANGE: `userPoolClient` property in `UserPoolAuthorizerProps` is now renamed to `userPoolClients`. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-apigatewayv2-authorizers/README.md | 2 +- .../lib/http/user-pool.ts | 10 ++--- .../test/http/integ.user-pool.ts | 2 +- .../test/http/user-pool.test.ts | 44 ++++++++++++++++++- 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/README.md b/packages/@aws-cdk/aws-apigatewayv2-authorizers/README.md index 7dd9c2f5e61bd..a7da95a29c682 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/README.md +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/README.md @@ -150,7 +150,7 @@ const userPoolClient = userPool.addClient('UserPoolClient'); const authorizer = new HttpUserPoolAuthorizer({ userPool, - userPoolClient, + userPoolClients: [userPoolClient], }); const api = new HttpApi(stack, 'HttpApi'); diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/lib/http/user-pool.ts b/packages/@aws-cdk/aws-apigatewayv2-authorizers/lib/http/user-pool.ts index 702a3a05576ec..21cef2e478756 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/lib/http/user-pool.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/lib/http/user-pool.ts @@ -7,9 +7,9 @@ import { Stack, Token } from '@aws-cdk/core'; */ export interface UserPoolAuthorizerProps { /** - * The user pool client that should be used to authorize requests with the user pool. + * The user pool clients that should be used to authorize requests with the user pool. */ - readonly userPoolClient: IUserPoolClient; + readonly userPoolClients: IUserPoolClient[]; /** * The associated user pool @@ -33,7 +33,7 @@ export interface UserPoolAuthorizerProps { * * @default ['$request.header.Authorization'] */ - readonly identitySource?: string[], + readonly identitySource?: string[]; } /** @@ -56,7 +56,7 @@ export class HttpUserPoolAuthorizer implements IHttpRouteAuthorizer { identitySource: this.props.identitySource ?? ['$request.header.Authorization'], type: HttpAuthorizerType.JWT, authorizerName: this.props.authorizerName, - jwtAudience: [this.props.userPoolClient.userPoolClientId], + jwtAudience: this.props.userPoolClients.map((c) => c.userPoolClientId), jwtIssuer: `https://cognito-idp.${region}.amazonaws.com/${this.props.userPool.userPoolId}`, }); } @@ -66,4 +66,4 @@ export class HttpUserPoolAuthorizer implements IHttpRouteAuthorizer { authorizationType: 'JWT', }; } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.user-pool.ts b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.user-pool.ts index edf455f4a787c..3e607b4474365 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.user-pool.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/integ.user-pool.ts @@ -25,7 +25,7 @@ const userPoolClient = userPool.addClient('my-client'); const authorizer = new HttpUserPoolAuthorizer({ userPool, - userPoolClient, + userPoolClients: [userPoolClient], }); const handler = new lambda.Function(stack, 'lambda', { diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/user-pool.test.ts b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/user-pool.test.ts index 0e3c339e7f744..127b389b8b0f2 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/user-pool.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/user-pool.test.ts @@ -13,7 +13,7 @@ describe('HttpUserPoolAuthorizer', () => { const userPoolClient = userPool.addClient('UserPoolClient'); const authorizer = new HttpUserPoolAuthorizer({ userPool, - userPoolClient, + userPoolClients: [userPoolClient], }); // WHEN @@ -52,7 +52,7 @@ describe('HttpUserPoolAuthorizer', () => { const userPoolClient = userPool.addClient('UserPoolClient'); const authorizer = new HttpUserPoolAuthorizer({ userPool, - userPoolClient, + userPoolClients: [userPoolClient], }); // WHEN @@ -70,6 +70,46 @@ describe('HttpUserPoolAuthorizer', () => { // THEN Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::Authorizer', 1); }); + + test('multiple userPoolClients are attached', () => { + // GIVEN + const stack = new Stack(); + const api = new HttpApi(stack, 'HttpApi'); + const userPool = new UserPool(stack, 'UserPool'); + const userPoolClient1 = userPool.addClient('UserPoolClient1'); + const userPoolClient2 = userPool.addClient('UserPoolClient2'); + const authorizer = new HttpUserPoolAuthorizer({ + userPool, + userPoolClients: [userPoolClient1, userPoolClient2], + }); + + // WHEN + api.addRoutes({ + integration: new DummyRouteIntegration(), + path: '/books', + authorizer, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Authorizer', { + AuthorizerType: 'JWT', + IdentitySource: ['$request.header.Authorization'], + JwtConfiguration: { + Audience: [stack.resolve(userPoolClient1.userPoolClientId), stack.resolve(userPoolClient2.userPoolClientId)], + Issuer: { + 'Fn::Join': [ + '', + [ + 'https://cognito-idp.', + { Ref: 'AWS::Region' }, + '.amazonaws.com/', + stack.resolve(userPool.userPoolId), + ], + ], + }, + }, + }); + }); }); class DummyRouteIntegration implements IHttpRouteIntegration { From 9fc42c49a359bde0c0452e300496c368e6d0095d Mon Sep 17 00:00:00 2001 From: AWS CDK Team Date: Sun, 7 Nov 2021 09:30:17 +0000 Subject: [PATCH 67/70] chore(release): 1.131.0 --- CHANGELOG.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ version.v1.json | 2 +- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c9ab93b5e534..fdfa6efdaad59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,56 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [1.131.0](https://github.com/aws/aws-cdk/compare/v1.130.0...v1.131.0) (2021-11-07) + + +### ⚠ BREAKING CHANGES TO EXPERIMENTAL FEATURES + +* **apigatewayv2-authorizers:** `userPoolClient` property in `UserPoolAuthorizerProps` +is now renamed to `userPoolClients`. + +### Features + +* **apigatewayv2-authorizers:** http api - allow multiple user pool clients per HttpUserPoolAuthorizer ([#16903](https://github.com/aws/aws-cdk/issues/16903)) ([747eb7c](https://github.com/aws/aws-cdk/commit/747eb7cf5dba4514241103ffebc49e03261d25a9)), closes [#15431](https://github.com/aws/aws-cdk/issues/15431) +* **certificatemanager:** requesting private certificates issued by Private Certificate Authority ([#16315](https://github.com/aws/aws-cdk/issues/16315)) ([e26f5be](https://github.com/aws/aws-cdk/commit/e26f5befc2adedeb524fd263424c7920989b2288)), closes [#10076](https://github.com/aws/aws-cdk/issues/10076) +* **cfnspec:** cloudformation spec v46.0.0 ([#17223](https://github.com/aws/aws-cdk/issues/17223)) ([d9f7b58](https://github.com/aws/aws-cdk/commit/d9f7b58a91a625ffd9bc366767794a3101b0afeb)) +* **cfnspec:** cloudformation spec v46.0.0 ([#17334](https://github.com/aws/aws-cdk/issues/17334)) ([e0f1180](https://github.com/aws/aws-cdk/commit/e0f118046c4a0350bdd614fbff4b96ba7772402e)) +* **cfnspec:** cloudformation spec v47.0.0 ([#17350](https://github.com/aws/aws-cdk/issues/17350)) ([ea71b4e](https://github.com/aws/aws-cdk/commit/ea71b4ed7466d8799bde4fdd5adfed9fc8febb9c)), closes [#17290](https://github.com/aws/aws-cdk/issues/17290) [#17223](https://github.com/aws/aws-cdk/issues/17223) +* **cfnspec:** cloudformation spec v47.0.0 ([#17353](https://github.com/aws/aws-cdk/issues/17353)) ([7886607](https://github.com/aws/aws-cdk/commit/7886607528b0cb005fa1176803b2a45d3e948f48)) +* **cli:** added `build` field to cdk.json ([#17176](https://github.com/aws/aws-cdk/issues/17176)) ([57ad1e0](https://github.com/aws/aws-cdk/commit/57ad1e087edef653d672c1426b920b12962f0f0f)) +* **cli:** introduce the 'watch' command ([#17240](https://github.com/aws/aws-cdk/issues/17240)) ([0adc8b7](https://github.com/aws/aws-cdk/commit/0adc8b7e13011956929fc945e083f75edec16698)) +* **codepipeline:** add construct for registering custom Actions ([#17041](https://github.com/aws/aws-cdk/issues/17041)) ([c66ac89](https://github.com/aws/aws-cdk/commit/c66ac89f43d3d2cee2b5842c54dc00e14ccdd2f4)), closes [#17039](https://github.com/aws/aws-cdk/issues/17039) +* **docdb:** add the ability to exclude characters when generating passwords ([#17262](https://github.com/aws/aws-cdk/issues/17262)) ([135f7d3](https://github.com/aws/aws-cdk/commit/135f7d33db5e96c3af4a8691c13b419e7b14ceae)), closes [#15732](https://github.com/aws/aws-cdk/issues/15732) +* **ec2:** add c6i instances ([#17237](https://github.com/aws/aws-cdk/issues/17237)) ([25cea18](https://github.com/aws/aws-cdk/commit/25cea1807539a8d45f3f4ff8b775b3417387d6fe)), closes [/docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2](https://github.com/aws//docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html/issues/cfn-ec2) +* **ecs-service-extensions:** Target tracking policies for Service Extensions ([#17101](https://github.com/aws/aws-cdk/issues/17101)) ([6420b18](https://github.com/aws/aws-cdk/commit/6420b1817d4319924d11cfccb8b6a29d4a2d5008)) +* **eks:** expose FargateCluster's defaultProfile ([#17130](https://github.com/aws/aws-cdk/issues/17130)) ([e461601](https://github.com/aws/aws-cdk/commit/e4616010c1915206758be3bf4cd6da9f14d2101a)), closes [#16149](https://github.com/aws/aws-cdk/issues/16149) +* **iot:** allow setting `description` and `enabled` of TopicRule ([#17225](https://github.com/aws/aws-cdk/issues/17225)) ([a9aae09](https://github.com/aws/aws-cdk/commit/a9aae097daad475dd57bbf4842956327a6d5a220)), closes [/github.com/aws/aws-cdk/pull/16681#issuecomment-942233029](https://github.com/aws//github.com/aws/aws-cdk/pull/16681/issues/issuecomment-942233029) +* **iot:** allow setting `errorAction` of TopicRule ([#17287](https://github.com/aws/aws-cdk/issues/17287)) ([e412308](https://github.com/aws/aws-cdk/commit/e412308bc81ede16b079077cfa4774ceaa2fadeb)), closes [/github.com/aws/aws-cdk/pull/16681#issuecomment-942233029](https://github.com/aws//github.com/aws/aws-cdk/pull/16681/issues/issuecomment-942233029) +* **iot-actions:** Add the action to put CloudWatch Logs ([#17228](https://github.com/aws/aws-cdk/issues/17228)) ([a7c869e](https://github.com/aws/aws-cdk/commit/a7c869e6d57932389df572cd7f104a4c9ea8f8a5)), closes [/github.com/aws/aws-cdk/pull/16681#issuecomment-942233029](https://github.com/aws//github.com/aws/aws-cdk/pull/16681/issues/issuecomment-942233029) +* **lambda-nodejs:** add sourcesContent in BundlingOptions ([#17280](https://github.com/aws/aws-cdk/issues/17280)) ([ea56e69](https://github.com/aws/aws-cdk/commit/ea56e6925422ebb987dbd87952511f23832ac7b6)), closes [#17256](https://github.com/aws/aws-cdk/issues/17256) +* **logs:** add support for cloudwatch logs resource policy ([#17015](https://github.com/aws/aws-cdk/issues/17015)) ([e9a461d](https://github.com/aws/aws-cdk/commit/e9a461d6dcbad933fcb9d671a8c5b5ad8f5ece8d)), closes [#5343](https://github.com/aws/aws-cdk/issues/5343) [aws-cdk/aws-elasticsearch/lib/log-group-resource-policy.ts#L25](https://github.com/aws-cdk/aws-elasticsearch/lib/log-group-resource-policy.ts/issues/L25) [aws-cdk/aws-events-targets/lib/log-group-resource-policy.ts#L26](https://github.com/aws-cdk/aws-events-targets/lib/log-group-resource-policy.ts/issues/L26) [aws-cdk/aws-events-targets/lib/log-group-resource-policy.ts#L26](https://github.com/aws-cdk/aws-events-targets/lib/log-group-resource-policy.ts/issues/L26) [#5343](https://github.com/aws/aws-cdk/issues/5343) +* **servicecatalog:** allow creating a CFN Product Version with CDK code ([#17144](https://github.com/aws/aws-cdk/issues/17144)) ([f8d0ef5](https://github.com/aws/aws-cdk/commit/f8d0ef550df07e43aeab35dde4406c92f7551ed0)) +* **synthetics:** add static cron method to schedule class ([#17250](https://github.com/aws/aws-cdk/issues/17250)) ([1ab9b26](https://github.com/aws/aws-cdk/commit/1ab9b265e9899ffcd093b3600d658c8a6519cc69)), closes [#16402](https://github.com/aws/aws-cdk/issues/16402) + + +### Bug Fixes + +* java and python templates are broken ([#17357](https://github.com/aws/aws-cdk/issues/17357)) ([5f6d550](https://github.com/aws/aws-cdk/commit/5f6d550677d1998a5a2720aabbff1ed2c3815aeb)) +* **aws-eks:** proxy support and allow assigning a security group to all cluster handler functions ([#17200](https://github.com/aws/aws-cdk/issues/17200)) ([7bbd10d](https://github.com/aws/aws-cdk/commit/7bbd10deb322daf8ef1504ceb84ad3c895f291ae)), closes [40aws-cdk/aws-eks/lib/cluster-resource-provider.ts#L69-L96](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-provider.ts/issues/L69-L96) [/github.com/aws/aws-cdk/issues/12469#issuecomment-758674418](https://github.com/aws//github.com/aws/aws-cdk/issues/12469/issues/issuecomment-758674418) [40aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts#L48](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts/issues/L48) [40aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts#L59](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts/issues/L59) [40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L56](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts/issues/L56) [40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L196](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts/issues/L196) [40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L198](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts/issues/L198) [40aws-cdk/aws-eks/lib/kubectl-provider.ts#L83](https://github.com/40aws-cdk/aws-eks/lib/kubectl-provider.ts/issues/L83) +* **cli:** `wmic not found` on modern Windows systems ([#17070](https://github.com/aws/aws-cdk/issues/17070)) ([332ce4d](https://github.com/aws/aws-cdk/commit/332ce4d9ae995bd1336fef13e2c7f9fc0c12f34d)), closes [#16419](https://github.com/aws/aws-cdk/issues/16419) +* **cli:** cdk ls --long outputs less-friendly stack IDs for nested assemblies ([#17263](https://github.com/aws/aws-cdk/issues/17263)) ([864c50e](https://github.com/aws/aws-cdk/commit/864c50ed2f3ae133af0cffd17ed77a6cf32ac6f4)), closes [#14379](https://github.com/aws/aws-cdk/issues/14379) +* **cli:** no longer disable rollback by default for hotswap deployments ([#17317](https://github.com/aws/aws-cdk/issues/17317)) ([e32b616](https://github.com/aws/aws-cdk/commit/e32b61652b5d01c44b05c2ac6d5fb1e99b50e059)), closes [#17267](https://github.com/aws/aws-cdk/issues/17267) +* **cognito:** ambiguous error message when same trigger is added twice ([#16917](https://github.com/aws/aws-cdk/issues/16917)) ([4ae78b0](https://github.com/aws/aws-cdk/commit/4ae78b07af20ea3ef049079ac5b892f9ee8476e5)) +* **ec2:** functions addIngressRule and addEgressRule detect unresolved tokens as duplicates ([#17221](https://github.com/aws/aws-cdk/issues/17221)) ([d4952c3](https://github.com/aws/aws-cdk/commit/d4952c3cbe12e7c8c27e1bca7f9d8536d93fd3cb)), closes [#17201](https://github.com/aws/aws-cdk/issues/17201) +* **lambda-nodejs:** yarn berry goes into immutable mode in CI ([#17086](https://github.com/aws/aws-cdk/issues/17086)) ([cc8dd69](https://github.com/aws/aws-cdk/commit/cc8dd694e6746b9c6fc4663775aaa3b68d19ef61)), closes [#17082](https://github.com/aws/aws-cdk/issues/17082) +* **pipelines:** `additionalInputs` not working ([#17279](https://github.com/aws/aws-cdk/issues/17279)) ([9e81dc7](https://github.com/aws/aws-cdk/commit/9e81dc731993a55fbc05c642ce96151f12ed69da)), closes [#17224](https://github.com/aws/aws-cdk/issues/17224) +* **s3:** enforce that fromBucketAttributes supplies a valid bucket name ([#16915](https://github.com/aws/aws-cdk/issues/16915)) ([30ac0cc](https://github.com/aws/aws-cdk/commit/30ac0cc2d95ef3fd79d0658428975ea675b6916f)) + + +### Reverts + +* "chore: activate 'rosetta infuse' feature ([#17191](https://github.com/aws/aws-cdk/issues/17191))" ([#17329](https://github.com/aws/aws-cdk/issues/17329)) ([c8cd515](https://github.com/aws/aws-cdk/commit/c8cd515b3984ce0d8bfbe2d19cd56d299785e78b)) + ## [1.130.0](https://github.com/aws/aws-cdk/compare/v1.129.0...v1.130.0) (2021-10-29) diff --git a/version.v1.json b/version.v1.json index cf3002b8d98b8..1d5c1405e9991 100644 --- a/version.v1.json +++ b/version.v1.json @@ -1,3 +1,3 @@ { - "version": "1.130.0" + "version": "1.131.0" } \ No newline at end of file From 89ab13e8b1e9db7366676bbbe42b9f1306b07e7f Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Sun, 7 Nov 2021 11:35:13 +0200 Subject: [PATCH 68/70] remove templates fix since it was never visible It was never visible to customers --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fdfa6efdaad59..2818a63573dea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,6 @@ is now renamed to `userPoolClients`. ### Bug Fixes -* java and python templates are broken ([#17357](https://github.com/aws/aws-cdk/issues/17357)) ([5f6d550](https://github.com/aws/aws-cdk/commit/5f6d550677d1998a5a2720aabbff1ed2c3815aeb)) * **aws-eks:** proxy support and allow assigning a security group to all cluster handler functions ([#17200](https://github.com/aws/aws-cdk/issues/17200)) ([7bbd10d](https://github.com/aws/aws-cdk/commit/7bbd10deb322daf8ef1504ceb84ad3c895f291ae)), closes [40aws-cdk/aws-eks/lib/cluster-resource-provider.ts#L69-L96](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-provider.ts/issues/L69-L96) [/github.com/aws/aws-cdk/issues/12469#issuecomment-758674418](https://github.com/aws//github.com/aws/aws-cdk/issues/12469/issues/issuecomment-758674418) [40aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts#L48](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts/issues/L48) [40aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts#L59](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts/issues/L59) [40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L56](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts/issues/L56) [40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L196](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts/issues/L196) [40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L198](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts/issues/L198) [40aws-cdk/aws-eks/lib/kubectl-provider.ts#L83](https://github.com/40aws-cdk/aws-eks/lib/kubectl-provider.ts/issues/L83) * **cli:** `wmic not found` on modern Windows systems ([#17070](https://github.com/aws/aws-cdk/issues/17070)) ([332ce4d](https://github.com/aws/aws-cdk/commit/332ce4d9ae995bd1336fef13e2c7f9fc0c12f34d)), closes [#16419](https://github.com/aws/aws-cdk/issues/16419) * **cli:** cdk ls --long outputs less-friendly stack IDs for nested assemblies ([#17263](https://github.com/aws/aws-cdk/issues/17263)) ([864c50e](https://github.com/aws/aws-cdk/commit/864c50ed2f3ae133af0cffd17ed77a6cf32ac6f4)), closes [#14379](https://github.com/aws/aws-cdk/issues/14379) From c736651bf9cf542e2925b71f68f46a18d9abe21f Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Sun, 7 Nov 2021 11:37:35 +0200 Subject: [PATCH 69/70] corrupted eks fix in CL --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2818a63573dea..d9987a1831cb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,7 @@ is now renamed to `userPoolClients`. ### Bug Fixes -* **aws-eks:** proxy support and allow assigning a security group to all cluster handler functions ([#17200](https://github.com/aws/aws-cdk/issues/17200)) ([7bbd10d](https://github.com/aws/aws-cdk/commit/7bbd10deb322daf8ef1504ceb84ad3c895f291ae)), closes [40aws-cdk/aws-eks/lib/cluster-resource-provider.ts#L69-L96](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-provider.ts/issues/L69-L96) [/github.com/aws/aws-cdk/issues/12469#issuecomment-758674418](https://github.com/aws//github.com/aws/aws-cdk/issues/12469/issues/issuecomment-758674418) [40aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts#L48](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/index.ts/issues/L48) [40aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts#L59](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/common.ts/issues/L59) [40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L56](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts/issues/L56) [40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L196](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts/issues/L196) [40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts#L198](https://github.com/40aws-cdk/aws-eks/lib/cluster-resource-handler/cluster.ts/issues/L198) [40aws-cdk/aws-eks/lib/kubectl-provider.ts#L83](https://github.com/40aws-cdk/aws-eks/lib/kubectl-provider.ts/issues/L83) +* **aws-eks:** proxy support and allow assigning a security group to all cluster handler functions ([#17200](https://github.com/aws/aws-cdk/issues/17200)) ([7bbd10d](https://github.com/aws/aws-cdk/commit/7bbd10deb322daf8ef1504ceb84ad3c895f291ae)), closes [#12469](https://github.com/aws/aws-cdk/issues/12469) * **cli:** `wmic not found` on modern Windows systems ([#17070](https://github.com/aws/aws-cdk/issues/17070)) ([332ce4d](https://github.com/aws/aws-cdk/commit/332ce4d9ae995bd1336fef13e2c7f9fc0c12f34d)), closes [#16419](https://github.com/aws/aws-cdk/issues/16419) * **cli:** cdk ls --long outputs less-friendly stack IDs for nested assemblies ([#17263](https://github.com/aws/aws-cdk/issues/17263)) ([864c50e](https://github.com/aws/aws-cdk/commit/864c50ed2f3ae133af0cffd17ed77a6cf32ac6f4)), closes [#14379](https://github.com/aws/aws-cdk/issues/14379) * **cli:** no longer disable rollback by default for hotswap deployments ([#17317](https://github.com/aws/aws-cdk/issues/17317)) ([e32b616](https://github.com/aws/aws-cdk/commit/e32b61652b5d01c44b05c2ac6d5fb1e99b50e059)), closes [#17267](https://github.com/aws/aws-cdk/issues/17267) From 596ce04c707538d141457ab437a11cbd0421b9f0 Mon Sep 17 00:00:00 2001 From: Eli Polonsky Date: Sun, 7 Nov 2021 11:43:07 +0200 Subject: [PATCH 70/70] CL corruptions --- CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9987a1831cb0..780107f78c21a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,14 +22,14 @@ is now renamed to `userPoolClients`. * **cli:** introduce the 'watch' command ([#17240](https://github.com/aws/aws-cdk/issues/17240)) ([0adc8b7](https://github.com/aws/aws-cdk/commit/0adc8b7e13011956929fc945e083f75edec16698)) * **codepipeline:** add construct for registering custom Actions ([#17041](https://github.com/aws/aws-cdk/issues/17041)) ([c66ac89](https://github.com/aws/aws-cdk/commit/c66ac89f43d3d2cee2b5842c54dc00e14ccdd2f4)), closes [#17039](https://github.com/aws/aws-cdk/issues/17039) * **docdb:** add the ability to exclude characters when generating passwords ([#17262](https://github.com/aws/aws-cdk/issues/17262)) ([135f7d3](https://github.com/aws/aws-cdk/commit/135f7d33db5e96c3af4a8691c13b419e7b14ceae)), closes [#15732](https://github.com/aws/aws-cdk/issues/15732) -* **ec2:** add c6i instances ([#17237](https://github.com/aws/aws-cdk/issues/17237)) ([25cea18](https://github.com/aws/aws-cdk/commit/25cea1807539a8d45f3f4ff8b775b3417387d6fe)), closes [/docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2](https://github.com/aws//docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html/issues/cfn-ec2) +* **ec2:** add c6i instances ([#17237](https://github.com/aws/aws-cdk/issues/17237)) ([25cea18](https://github.com/aws/aws-cdk/commit/25cea1807539a8d45f3f4ff8b775b3417387d6fe)) * **ecs-service-extensions:** Target tracking policies for Service Extensions ([#17101](https://github.com/aws/aws-cdk/issues/17101)) ([6420b18](https://github.com/aws/aws-cdk/commit/6420b1817d4319924d11cfccb8b6a29d4a2d5008)) * **eks:** expose FargateCluster's defaultProfile ([#17130](https://github.com/aws/aws-cdk/issues/17130)) ([e461601](https://github.com/aws/aws-cdk/commit/e4616010c1915206758be3bf4cd6da9f14d2101a)), closes [#16149](https://github.com/aws/aws-cdk/issues/16149) -* **iot:** allow setting `description` and `enabled` of TopicRule ([#17225](https://github.com/aws/aws-cdk/issues/17225)) ([a9aae09](https://github.com/aws/aws-cdk/commit/a9aae097daad475dd57bbf4842956327a6d5a220)), closes [/github.com/aws/aws-cdk/pull/16681#issuecomment-942233029](https://github.com/aws//github.com/aws/aws-cdk/pull/16681/issues/issuecomment-942233029) -* **iot:** allow setting `errorAction` of TopicRule ([#17287](https://github.com/aws/aws-cdk/issues/17287)) ([e412308](https://github.com/aws/aws-cdk/commit/e412308bc81ede16b079077cfa4774ceaa2fadeb)), closes [/github.com/aws/aws-cdk/pull/16681#issuecomment-942233029](https://github.com/aws//github.com/aws/aws-cdk/pull/16681/issues/issuecomment-942233029) -* **iot-actions:** Add the action to put CloudWatch Logs ([#17228](https://github.com/aws/aws-cdk/issues/17228)) ([a7c869e](https://github.com/aws/aws-cdk/commit/a7c869e6d57932389df572cd7f104a4c9ea8f8a5)), closes [/github.com/aws/aws-cdk/pull/16681#issuecomment-942233029](https://github.com/aws//github.com/aws/aws-cdk/pull/16681/issues/issuecomment-942233029) +* **iot:** allow setting `description` and `enabled` of TopicRule ([#17225](https://github.com/aws/aws-cdk/issues/17225)) ([a9aae09](https://github.com/aws/aws-cdk/commit/a9aae097daad475dd57bbf4842956327a6d5a220)) +* **iot:** allow setting `errorAction` of TopicRule ([#17287](https://github.com/aws/aws-cdk/issues/17287)) ([e412308](https://github.com/aws/aws-cdk/commit/e412308bc81ede16b079077cfa4774ceaa2fadeb)) +* **iot-actions:** Add the action to put CloudWatch Logs ([#17228](https://github.com/aws/aws-cdk/issues/17228)) ([a7c869e](https://github.com/aws/aws-cdk/commit/a7c869e6d57932389df572cd7f104a4c9ea8f8a5)) * **lambda-nodejs:** add sourcesContent in BundlingOptions ([#17280](https://github.com/aws/aws-cdk/issues/17280)) ([ea56e69](https://github.com/aws/aws-cdk/commit/ea56e6925422ebb987dbd87952511f23832ac7b6)), closes [#17256](https://github.com/aws/aws-cdk/issues/17256) -* **logs:** add support for cloudwatch logs resource policy ([#17015](https://github.com/aws/aws-cdk/issues/17015)) ([e9a461d](https://github.com/aws/aws-cdk/commit/e9a461d6dcbad933fcb9d671a8c5b5ad8f5ece8d)), closes [#5343](https://github.com/aws/aws-cdk/issues/5343) [aws-cdk/aws-elasticsearch/lib/log-group-resource-policy.ts#L25](https://github.com/aws-cdk/aws-elasticsearch/lib/log-group-resource-policy.ts/issues/L25) [aws-cdk/aws-events-targets/lib/log-group-resource-policy.ts#L26](https://github.com/aws-cdk/aws-events-targets/lib/log-group-resource-policy.ts/issues/L26) [aws-cdk/aws-events-targets/lib/log-group-resource-policy.ts#L26](https://github.com/aws-cdk/aws-events-targets/lib/log-group-resource-policy.ts/issues/L26) [#5343](https://github.com/aws/aws-cdk/issues/5343) +* **logs:** add support for cloudwatch logs resource policy ([#17015](https://github.com/aws/aws-cdk/issues/17015)) ([e9a461d](https://github.com/aws/aws-cdk/commit/e9a461d6dcbad933fcb9d671a8c5b5ad8f5ece8d)), closes [#5343](https://github.com/aws/aws-cdk/issues/5343) * **servicecatalog:** allow creating a CFN Product Version with CDK code ([#17144](https://github.com/aws/aws-cdk/issues/17144)) ([f8d0ef5](https://github.com/aws/aws-cdk/commit/f8d0ef550df07e43aeab35dde4406c92f7551ed0)) * **synthetics:** add static cron method to schedule class ([#17250](https://github.com/aws/aws-cdk/issues/17250)) ([1ab9b26](https://github.com/aws/aws-cdk/commit/1ab9b265e9899ffcd093b3600d658c8a6519cc69)), closes [#16402](https://github.com/aws/aws-cdk/issues/16402)