diff --git a/.mergify.yml b/.mergify.yml index 358575303ca74..81cce822cc2b6 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -6,7 +6,7 @@ pull_request_rules: label: add: [ contribution/core ] conditions: - - author~=^(eladb|RomainMuller|garnaat|nija-at|skinny85|rix0rrr|NGL321|Jerry-AWS|MrArnoldPalmer|NetaNir|iliapolo|njlynch|ericzbeard|ccfife|fulghum|pkandasamy91|SoManyHs|uttarasridhar)$ + - author~=^(eladb|RomainMuller|garnaat|nija-at|skinny85|rix0rrr|NGL321|Jerry-AWS|MrArnoldPalmer|NetaNir|iliapolo|njlynch|ericzbeard|ccfife|fulghum|pkandasamy91|SoManyHs|uttarasridhar|otaviomacedo|BenChaimberg|madeline-k)$ - -label~="contribution/core" - name: automatic merge actions: diff --git a/CHANGELOG.md b/CHANGELOG.md index 63aa4c3bf3be9..30f83c5d5d399 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,32 @@ 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.104.0](https://github.com/aws/aws-cdk/compare/v1.103.0...v1.104.0) (2021-05-14) + + +### ⚠ BREAKING CHANGES TO EXPERIMENTAL FEATURES + +* **apigatewayv2:** setting the authorizer of an API route to HttpNoneAuthorizer will now remove any existing authorizer on the route + +### Features + +* **appsync:** elasticsearch data source for graphql api ([#14651](https://github.com/aws/aws-cdk/issues/14651)) ([2337b5d](https://github.com/aws/aws-cdk/commit/2337b5d965028ba06d6ff72f991c0b8e46433a8f)), closes [#6063](https://github.com/aws/aws-cdk/issues/6063) +* **cfnspec:** cloudformation spec v35.2.0 ([#14610](https://github.com/aws/aws-cdk/issues/14610)) ([799ce1a](https://github.com/aws/aws-cdk/commit/799ce1a7d5fb261cae92d514b4f7e315d8f0e589)) +* **cloudwatch:** GraphWidget supports period and statistic ([#14679](https://github.com/aws/aws-cdk/issues/14679)) ([b240f6e](https://github.com/aws/aws-cdk/commit/b240f6ece74d129e5f43b210e8ad12f95c4a2971)) +* **cloudwatch:** time range support for GraphWidget ([#14659](https://github.com/aws/aws-cdk/issues/14659)) ([010a6b1](https://github.com/aws/aws-cdk/commit/010a6b1a14f14be5001779644df3d3a2e27d4e71)), closes [#4649](https://github.com/aws/aws-cdk/issues/4649) +* **ecs:** add support for EC2 Capacity Providers ([#14386](https://github.com/aws/aws-cdk/issues/14386)) ([114f7cc](https://github.com/aws/aws-cdk/commit/114f7ccdaf736988834fe2be487363a992a31369)) +* **secretsmanager:** Automatically grant permissions to rotation Lambda ([#14471](https://github.com/aws/aws-cdk/issues/14471)) ([85e00fa](https://github.com/aws/aws-cdk/commit/85e00faf1e3bcc32c2f7aa881d42c6d1f6c17f63)) + + +### Bug Fixes + +* **apigatewayv2:** authorizer is not removed when HttpNoneAuthorizer is used ([#14424](https://github.com/aws/aws-cdk/issues/14424)) ([3698a91](https://github.com/aws/aws-cdk/commit/3698a91ac81a31f763c55487f200458d5b5eaf0f)) +* **ecs:** Classes FargateService and Ec2Service have no defaultChild ([#14691](https://github.com/aws/aws-cdk/issues/14691)) ([348e11e](https://github.com/aws/aws-cdk/commit/348e11e26edc0ff90b623b7cec778f4935e61e6d)), closes [#14665](https://github.com/aws/aws-cdk/issues/14665) +* **events-targets:** circular dependency when adding a KMS-encrypted SQS queue ([#14638](https://github.com/aws/aws-cdk/issues/14638)) ([3063818](https://github.com/aws/aws-cdk/commit/3063818aa7c3c3ff56cf55254b0f6561db190a3e)), closes [#11158](https://github.com/aws/aws-cdk/issues/11158) +* **lambda:** custom resource fails to connect to efs filesystem ([#14431](https://github.com/aws/aws-cdk/issues/14431)) ([10a633c](https://github.com/aws/aws-cdk/commit/10a633c8cda9f21b85c82f911d88641f3a362c4d)) +* **lambda-event-sources:** incorrect documented defaults for stream types ([#14562](https://github.com/aws/aws-cdk/issues/14562)) ([0ea24e9](https://github.com/aws/aws-cdk/commit/0ea24e95939412765c0e09133a7793557f779c76)), closes [#13908](https://github.com/aws/aws-cdk/issues/13908) +* **lambda-nodejs:** handler filename missing from error message ([#14564](https://github.com/aws/aws-cdk/issues/14564)) ([256fd4c](https://github.com/aws/aws-cdk/commit/256fd4c6fcdbe6519bc70f62415557dbeae950a1)) + ## [1.103.0](https://github.com/aws/aws-cdk/compare/v1.102.0...v1.103.0) (2021-05-10) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0762461d541d5..6a7065377b28e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -56,6 +56,8 @@ The following tools need to be installed on your system prior to installing the - [Yarn >= 1.19.1, < 2](https://yarnpkg.com/lang/en/docs/install) - [.NET Core SDK 3.1.x](https://www.microsoft.com/net/download) - [Python >= 3.6.5, < 4.0](https://www.python.org/downloads/release/python-365/) +- [Docker >= 19.03](https://docs.docker.com/get-docker/) + - the Docker daemon must also be running First fork the repository, and then run the following commands to clone the repository locally. @@ -113,8 +115,9 @@ However, if you wish to build the the entire repository, the following command w ```console cd -yarn build +scripts/foreach.sh yarn build ``` +Note: The `foreach` command is resumable by default; you must supply `-r` or `--reset` to start a new session. You are now ready to start contributing to the CDK. See the [Pull Requests](#pull-requests) section on how to make your changes and submit it as a pull request. diff --git a/packages/@aws-cdk-containers/ecs-service-extensions/README.md b/packages/@aws-cdk-containers/ecs-service-extensions/README.md index da884a7aa85bd..1bf5a63a39fc5 100644 --- a/packages/@aws-cdk-containers/ecs-service-extensions/README.md +++ b/packages/@aws-cdk-containers/ecs-service-extensions/README.md @@ -61,19 +61,19 @@ const nameService = new Service(stack, 'name', { ## Creating an `Environment` An `Environment` is a place to deploy your services. You can have multiple environments -on a single AWS account. For example you could create a `test` environment as well -as a `production` environment so you have a place to verify that you application +on a single AWS account. For example, you could create a `test` environment as well +as a `production` environment so you have a place to verify that your application works as intended before you deploy it to a live environment. -Each environment is isolated from other environments. In specific -by default when you create an environment the construct supplies its own VPC, +Each environment is isolated from other environments. In other words, +when you create an environment, by default the construct supplies its own VPC, ECS Cluster, and any other required resources for the environment: ```ts const environment = new Environment(stack, 'production'); ``` -However, you can also choose to build an environment out of a pre-existing VPC, +However, you can also choose to build an environment out of a pre-existing VPC or ECS Cluster: ```ts @@ -89,7 +89,7 @@ const environment = new Environment(stack, 'production', { ## Defining your `ServiceDescription` The `ServiceDescription` defines what application you want the service to run and -what optional extensions you want to add to the service. The most basic form of a `ServiceExtension` looks like this: +what optional extensions you want to add to the service. The most basic form of a `ServiceDescription` looks like this: ```ts const nameDescription = new ServiceDescription(); @@ -105,9 +105,9 @@ nameDescription.add(new Container({ ``` Every `ServiceDescription` requires at minimum that you add a `Container` extension -which defines the main application container to run for the service. +which defines the main application (essential) container to run for the service. -After that you can optionally enable additional features for the service using the `ServiceDescription.add()` method: +After that, you can optionally enable additional features for the service using the `ServiceDescription.add()` method: ```ts nameDescription.add(new AppMeshExtension({ mesh })); @@ -238,7 +238,7 @@ frontend.connectTo(backend); The address that a service will use to talk to another service depends on the type of ingress that has been created by the extension that did the connecting. -For example if an App Mesh extension has been used then the service is accessible +For example, if an App Mesh extension has been used, then the service is accessible at a DNS address of `.`. For example: ```ts @@ -280,7 +280,7 @@ const backend = new Service(stack, 'backend', { frontend.connectTo(backend); ``` -The above code uses the well known service discovery name for each +The above code uses the well-known service discovery name for each service, and passes it as an environment variable to the container so that the container knows what address to use when communicating to the other service. diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.expected.json b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.expected.json index ae65d49847d54..b9f5d96ff4656 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.expected.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.alb.expected.json @@ -633,6 +633,7 @@ "Ref": "HttpProxyPrivateApiA55E154D" }, "RouteKey": "$default", + "AuthorizationType": "NONE", "Target": { "Fn::Join": [ "", diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.http-proxy.expected.json b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.http-proxy.expected.json index 378e7b2395f03..0e53d0a223e42 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.http-proxy.expected.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.http-proxy.expected.json @@ -117,6 +117,7 @@ "Ref": "LambdaProxyApi67594471" }, "RouteKey": "$default", + "AuthorizationType": "NONE", "Target": { "Fn::Join": [ "", @@ -185,6 +186,7 @@ "Ref": "HttpProxyApiD0217C67" }, "RouteKey": "$default", + "AuthorizationType": "NONE", "Target": { "Fn::Join": [ "", diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.lambda-proxy.expected.json b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.lambda-proxy.expected.json index 58e37b0f64e0a..7963d3534e099 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.lambda-proxy.expected.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.lambda-proxy.expected.json @@ -117,6 +117,7 @@ "Ref": "LambdaProxyApi67594471" }, "RouteKey": "$default", + "AuthorizationType": "NONE", "Target": { "Fn::Join": [ "", diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.nlb.expected.json b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.nlb.expected.json index aed54a5a8395c..0a3241cdc8139 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.nlb.expected.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.nlb.expected.json @@ -598,6 +598,7 @@ "Ref": "HttpProxyPrivateApiA55E154D" }, "RouteKey": "$default", + "AuthorizationType": "NONE", "Target": { "Fn::Join": [ "", diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.service-discovery.expected.json b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.service-discovery.expected.json index 1aaf644336b8c..00e587f8ac85f 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.service-discovery.expected.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/integ.service-discovery.expected.json @@ -602,6 +602,7 @@ "Ref": "HttpProxyPrivateApiA55E154D" }, "RouteKey": "$default", + "AuthorizationType": "NONE", "Target": { "Fn::Join": [ "", diff --git a/packages/@aws-cdk/aws-apigatewayv2/lib/http/route.ts b/packages/@aws-cdk/aws-apigatewayv2/lib/http/route.ts index 2252630930c27..5178281d08953 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/lib/http/route.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/lib/http/route.ts @@ -156,8 +156,6 @@ export class HttpRoute extends Resource implements IHttpRoute { ])); } - const authorizationType = authBindResult?.authorizationType === HttpAuthorizerType.NONE ? undefined : authBindResult?.authorizationType; - if (authorizationScopes?.length === 0) { authorizationScopes = undefined; } @@ -167,7 +165,7 @@ export class HttpRoute extends Resource implements IHttpRoute { routeKey: props.routeKey.key, target: `integrations/${integration.integrationId}`, authorizerId: authBindResult?.authorizerId, - authorizationType, + authorizationType: authBindResult?.authorizationType ?? HttpAuthorizerType.NONE, // must be explicitly NONE (not undefined) for stack updates to work correctly authorizationScopes, }; diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/http/api.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/http/api.test.ts index 25b0a5bca3189..12d2c68aa0ecb 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/http/api.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/http/api.test.ts @@ -429,6 +429,7 @@ describe('HttpApi', () => { expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { RouteKey: 'GET /chickens', + AuthorizationType: 'NONE', AuthorizerId: ABSENT, }); }); diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/http/route.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/http/route.test.ts index 044d278e086e4..8de7d2ae7f1d6 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/http/route.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/http/route.test.ts @@ -30,6 +30,7 @@ describe('HttpRoute', () => { ], ], }, + AuthorizationType: 'NONE', }); expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { diff --git a/packages/@aws-cdk/aws-appmesh/README.md b/packages/@aws-cdk/aws-appmesh/README.md index 067575fb73ec0..46c568fc3eb8c 100644 --- a/packages/@aws-cdk/aws-appmesh/README.md +++ b/packages/@aws-cdk/aws-appmesh/README.md @@ -27,7 +27,7 @@ App Mesh gives you consistent visibility and network traffic controls for every App Mesh supports microservice applications that use service discovery naming for their components. To use App Mesh, you must have an existing application running on AWS Fargate, Amazon ECS, Amazon EKS, Kubernetes on AWS, or Amazon EC2. -For futher information on **AWS AppMesh** visit the [AWS Docs for AppMesh](https://docs.aws.amazon.com/app-mesh/index.html). +For further information on **AWS AppMesh** visit the [AWS Docs for AppMesh](https://docs.aws.amazon.com/app-mesh/index.html). ## Create the App and Stack diff --git a/packages/@aws-cdk/aws-appsync/README.md b/packages/@aws-cdk/aws-appsync/README.md index e0a636217f38b..32e0558ccd4f8 100644 --- a/packages/@aws-cdk/aws-appsync/README.md +++ b/packages/@aws-cdk/aws-appsync/README.md @@ -240,6 +240,47 @@ httpDs.createResolver({ }); ``` +### Elasticsearch + +AppSync has builtin support for Elasticsearch from domains that are provisioned +through your AWS account. You can use AppSync resolvers to perform GraphQL operations +such as queries, mutations, and subscriptions. + +```ts +const user = new User(stack, 'User'); +const domain = new es.Domain(stack, 'Domain', { + version: es.ElasticsearchVersion.V7_1, + removalPolicy: cdk.RemovalPolicy.DESTROY, + fineGrainedAccessControl: { masterUserArn: user.userArn }, + encryptionAtRest: { enabled: true }, + nodeToNodeEncryption: true, + enforceHttps: true, +}); + +const ds = api.addElasticsearchDataSource('ds', domain); + +ds.createResolver({ + typeName: 'Query', + fieldName: 'getTests', + requestMappingTemplate: appsync.MappingTemplate.fromString(JSON.stringify({ + version: '2017-02-28', + operation: 'GET', + path: '/id/post/_search', + params: { + headers: {}, + queryString: {}, + body: { from: 0, size: 50 }, + }, + })), + responseMappingTemplate: appsync.MappingTemplate.fromString(`[ + #foreach($entry in $context.result.hits.hits) + #if( $velocityCount > 1 ) , #end + $utils.toJson($entry.get("_source")) + #end + ]`), +}); +``` + ## Schema Every GraphQL Api needs a schema to define the Api. CDK offers `appsync.Schema` @@ -718,7 +759,7 @@ You can create Object Types in three ways: name: 'demo', }); const demo = new appsync.ObjectType('Demo', { - defintion: { + definition: { id: appsync.GraphqlType.string({ isRequired: true }), version: appsync.GraphqlType.string({ isRequired: true }), }, @@ -741,7 +782,7 @@ You can create Object Types in three ways: ```ts import { required_string } from './scalar-types'; export const demo = new appsync.ObjectType('Demo', { - defintion: { + definition: { id: required_string, version: required_string, }, @@ -765,7 +806,7 @@ You can create Object Types in three ways: }); const demo = new appsync.ObjectType('Demo', { interfaceTypes: [ node ], - defintion: { + definition: { version: appsync.GraphqlType.string({ isRequired: true }), }, }); diff --git a/packages/@aws-cdk/aws-appsync/lib/data-source.ts b/packages/@aws-cdk/aws-appsync/lib/data-source.ts index ac22771916400..b7570be255fac 100644 --- a/packages/@aws-cdk/aws-appsync/lib/data-source.ts +++ b/packages/@aws-cdk/aws-appsync/lib/data-source.ts @@ -1,4 +1,5 @@ import { ITable } from '@aws-cdk/aws-dynamodb'; +import { IDomain } from '@aws-cdk/aws-elasticsearch'; import { Grant, IGrantable, IPrincipal, IRole, Role, ServicePrincipal } from '@aws-cdk/aws-iam'; import { IFunction } from '@aws-cdk/aws-lambda'; import { IServerlessCluster } from '@aws-cdk/aws-rds'; @@ -349,12 +350,14 @@ export class RdsDataSource extends BackedDataSource { props.secretStore.grantRead(this); // Change to grant with RDS grant becomes implemented + + props.serverlessCluster.grantDataApiAccess(this); + Grant.addToPrincipal({ grantee: this, actions: [ 'rds-data:DeleteItems', 'rds-data:ExecuteSql', - 'rds-data:ExecuteStatement', 'rds-data:GetItems', 'rds-data:InsertItems', 'rds-data:UpdateItems', @@ -363,4 +366,31 @@ export class RdsDataSource extends BackedDataSource { scope: this, }); } +} + +/** + * Properities for the Elasticsearch Data Source + */ +export interface ElasticsearchDataSourceProps extends BackedDataSourceProps { + /** + * The elasticsearch domain containing the endpoint for the data source + */ + readonly domain: IDomain; +} + +/** + * An Appsync datasource backed by Elasticsearch + */ +export class ElasticsearchDataSource extends BackedDataSource { + constructor(scope: Construct, id: string, props: ElasticsearchDataSourceProps) { + super(scope, id, props, { + type: 'AMAZON_ELASTICSEARCH', + elasticsearchConfig: { + awsRegion: props.domain.stack.region, + endpoint: `https://${props.domain.domainEndpoint}`, + }, + }); + + props.domain.grantReadWrite(this); + } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-appsync/lib/graphqlapi-base.ts b/packages/@aws-cdk/aws-appsync/lib/graphqlapi-base.ts index 060d57a34c276..dfd596b929903 100644 --- a/packages/@aws-cdk/aws-appsync/lib/graphqlapi-base.ts +++ b/packages/@aws-cdk/aws-appsync/lib/graphqlapi-base.ts @@ -1,9 +1,10 @@ import { ITable } from '@aws-cdk/aws-dynamodb'; +import { IDomain } from '@aws-cdk/aws-elasticsearch'; import { IFunction } from '@aws-cdk/aws-lambda'; import { IServerlessCluster } from '@aws-cdk/aws-rds'; import { ISecret } from '@aws-cdk/aws-secretsmanager'; import { CfnResource, IResource, Resource } from '@aws-cdk/core'; -import { DynamoDbDataSource, HttpDataSource, LambdaDataSource, NoneDataSource, RdsDataSource, AwsIamConfig } from './data-source'; +import { DynamoDbDataSource, HttpDataSource, LambdaDataSource, NoneDataSource, RdsDataSource, AwsIamConfig, ElasticsearchDataSource } from './data-source'; import { Resolver, ExtendedResolverProps } from './resolver'; /** @@ -110,6 +111,15 @@ export interface IGraphqlApi extends IResource { options?: DataSourceOptions ): RdsDataSource; + /** + * add a new elasticsearch data source to this API + * + * @param id The data source's id + * @param domain The elasticsearch domain for this data source + * @param options The optional configuration for this data source + */ + addElasticsearchDataSource(id: string, domain: IDomain, options?: DataSourceOptions): ElasticsearchDataSource; + /** * creates a new resolver for this datasource and API using the given properties */ @@ -228,6 +238,22 @@ export abstract class GraphqlApiBase extends Resource implements IGraphqlApi { }); } + /** + * add a new elasticsearch data source to this API + * + * @param id The data source's id + * @param domain The elasticsearch domain for this data source + * @param options The optional configuration for this data source + */ + public addElasticsearchDataSource(id: string, domain: IDomain, options?: DataSourceOptions): ElasticsearchDataSource { + return new ElasticsearchDataSource(this, id, { + api: this, + name: options?.name, + description: options?.description, + domain, + }); + } + /** * creates a new resolver for this datasource and API using the given properties */ diff --git a/packages/@aws-cdk/aws-appsync/package.json b/packages/@aws-cdk/aws-appsync/package.json index 61ac81e9d385c..bb3d07854903f 100644 --- a/packages/@aws-cdk/aws-appsync/package.json +++ b/packages/@aws-cdk/aws-appsync/package.json @@ -84,6 +84,7 @@ "@aws-cdk/aws-cognito": "0.0.0", "@aws-cdk/aws-dynamodb": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", + "@aws-cdk/aws-elasticsearch": "0.0.0", "@aws-cdk/aws-rds": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-secretsmanager": "0.0.0", @@ -97,6 +98,7 @@ "@aws-cdk/aws-cognito": "0.0.0", "@aws-cdk/aws-dynamodb": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", + "@aws-cdk/aws-elasticsearch": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/aws-s3-assets": "0.0.0", diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-elasticsearch.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-elasticsearch.test.ts new file mode 100644 index 0000000000000..1a974f982b61f --- /dev/null +++ b/packages/@aws-cdk/aws-appsync/test/appsync-elasticsearch.test.ts @@ -0,0 +1,150 @@ +import '@aws-cdk/assert-internal/jest'; +import * as path from 'path'; +import * as es from '@aws-cdk/aws-elasticsearch'; +import * as cdk from '@aws-cdk/core'; +import * as appsync from '../lib'; + +// GLOBAL GIVEN +let stack: cdk.Stack; +let api: appsync.GraphqlApi; +let domain: es.Domain; +beforeEach(() => { + stack = new cdk.Stack(); + api = new appsync.GraphqlApi(stack, 'baseApi', { + name: 'api', + schema: appsync.Schema.fromAsset(path.join(__dirname, 'appsync.test.graphql')), + }); + domain = new es.Domain(stack, 'EsDomain', { + version: es.ElasticsearchVersion.V7_10, + }); +}); + +describe('Elasticsearch Data Source Configuration', () => { + test('Elasticsearch configure properly', () => { + // WHEN + api.addElasticsearchDataSource('ds', domain); + + // THEN + expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [{ + Action: [ + 'es:ESHttpGet', + 'es:ESHttpHead', + 'es:ESHttpDelete', + 'es:ESHttpPost', + 'es:ESHttpPut', + 'es:ESHttpPatch', + ], + Effect: 'Allow', + Resource: [{ + 'Fn::GetAtt': ['EsDomain1213C634', 'Arn'], + }, + { + 'Fn::Join': ['', [{ + 'Fn::GetAtt': ['EsDomain1213C634', 'Arn'], + }, '/*']], + }], + }], + }, + }); + }); + + test('Elastic search configuration contains fully qualified url', () => { + // WHEN + api.addElasticsearchDataSource('ds', domain); + + // THEN + expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + ElasticsearchConfig: { + Endpoint: { + 'Fn::Join': ['', ['https://', { + 'Fn::GetAtt': ['EsDomain1213C634', 'DomainEndpoint'], + }]], + }, + }, + }); + }); + + test('default configuration produces name identical to the id', () => { + // WHEN + api.addElasticsearchDataSource('ds', domain); + + // THEN + expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Type: 'AMAZON_ELASTICSEARCH', + Name: 'ds', + }); + }); + + test('appsync configures name correctly', () => { + // WHEN + api.addElasticsearchDataSource('ds', domain, { + name: 'custom', + }); + + // THEN + expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Type: 'AMAZON_ELASTICSEARCH', + Name: 'custom', + }); + }); + + test('appsync configures name and description correctly', () => { + // WHEN + api.addElasticsearchDataSource('ds', domain, { + name: 'custom', + description: 'custom description', + }); + + // THEN + expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Type: 'AMAZON_ELASTICSEARCH', + Name: 'custom', + Description: 'custom description', + }); + }); + + test('appsync errors when creating multiple elasticsearch data sources with no configuration', () => { + // WHEN + const when = () => { + api.addElasticsearchDataSource('ds', domain); + api.addElasticsearchDataSource('ds', domain); + }; + + // THEN + expect(when).toThrow('There is already a Construct with name \'ds\' in GraphqlApi [baseApi]'); + }); +}); + +describe('adding elasticsearch data source from imported api', () => { + test('imported api can add ElasticsearchDataSource from id', () => { + // WHEN + const importedApi = appsync.GraphqlApi.fromGraphqlApiAttributes(stack, 'importedApi', { + graphqlApiId: api.apiId, + }); + importedApi.addElasticsearchDataSource('ds', domain); + + // THEN + expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Type: 'AMAZON_ELASTICSEARCH', + ApiId: { 'Fn::GetAtt': ['baseApiCDA4D43A', 'ApiId'] }, + }); + }); + + test('imported api can add ElasticsearchDataSource from attributes', () => { + // WHEN + const importedApi = appsync.GraphqlApi.fromGraphqlApiAttributes(stack, 'importedApi', { + graphqlApiId: api.apiId, + graphqlApiArn: api.arn, + }); + importedApi.addElasticsearchDataSource('ds', domain); + + // THEN + expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Type: 'AMAZON_ELASTICSEARCH', + ApiId: { 'Fn::GetAtt': ['baseApiCDA4D43A', 'ApiId'] }, + }); + }); +}); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-rds.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-rds.test.ts index 1f7c942811791..9a328b0fe65a0 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-rds.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-rds.test.ts @@ -58,11 +58,29 @@ describe('Rds Data Source configuration', () => { Effect: 'Allow', Resource: { Ref: 'AuroraSecret41E6E877' }, }, + { + Action: [ + 'rds-data:BatchExecuteStatement', + 'rds-data:BeginTransaction', + 'rds-data:CommitTransaction', + 'rds-data:ExecuteStatement', + 'rds-data:RollbackTransaction', + ], + Effect: 'Allow', + Resource: '*', + }, + { + Action: [ + 'secretsmanager:GetSecretValue', + 'secretsmanager:DescribeSecret', + ], + Effect: 'Allow', + Resource: { Ref: 'AuroraClusterSecretAttachmentDB8032DA' }, + }, { Action: [ 'rds-data:DeleteItems', 'rds-data:ExecuteSql', - 'rds-data:ExecuteStatement', 'rds-data:GetItems', 'rds-data:InsertItems', 'rds-data:UpdateItems', diff --git a/packages/@aws-cdk/aws-appsync/test/integ.graphql-elasticsearch.expected.json b/packages/@aws-cdk/aws-appsync/test/integ.graphql-elasticsearch.expected.json new file mode 100644 index 0000000000000..22e64957700e9 --- /dev/null +++ b/packages/@aws-cdk/aws-appsync/test/integ.graphql-elasticsearch.expected.json @@ -0,0 +1,210 @@ +{ + "Resources": { + "User00B015A1": { + "Type": "AWS::IAM::User" + }, + "Domain66AC69E0": { + "Type": "AWS::Elasticsearch::Domain", + "Properties": { + "AdvancedSecurityOptions": { + "Enabled": true, + "InternalUserDatabaseEnabled": false, + "MasterUserOptions": { + "MasterUserARN": { + "Fn::GetAtt": [ + "User00B015A1", + "Arn" + ] + } + } + }, + "CognitoOptions": { + "Enabled": false + }, + "DomainEndpointOptions": { + "EnforceHTTPS": true, + "TLSSecurityPolicy": "Policy-Min-TLS-1-0-2019-07" + }, + "EBSOptions": { + "EBSEnabled": true, + "VolumeSize": 10, + "VolumeType": "gp2" + }, + "ElasticsearchClusterConfig": { + "DedicatedMasterEnabled": false, + "InstanceCount": 1, + "InstanceType": "r5.large.elasticsearch", + "ZoneAwarenessEnabled": false + }, + "ElasticsearchVersion": "7.1", + "EncryptionAtRestOptions": { + "Enabled": true + }, + "LogPublishingOptions": {}, + "NodeToNodeEncryptionOptions": { + "Enabled": true + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "apiC8550315": { + "Type": "AWS::AppSync::GraphQLApi", + "Properties": { + "AuthenticationType": "API_KEY", + "Name": "api" + } + }, + "apiSchema0EA92056": { + "Type": "AWS::AppSync::GraphQLSchema", + "Properties": { + "ApiId": { + "Fn::GetAtt": [ + "apiC8550315", + "ApiId" + ] + }, + "Definition": "type test {\n version: String!\n}\ntype Query {\n getTests: [test]!\n}\ntype Mutation {\n addTest(version: String!): test\n}\n" + } + }, + "apiDefaultApiKey6AB8D7C4": { + "Type": "AWS::AppSync::ApiKey", + "Properties": { + "ApiId": { + "Fn::GetAtt": [ + "apiC8550315", + "ApiId" + ] + } + }, + "DependsOn": [ + "apiSchema0EA92056" + ] + }, + "apidsServiceRoleBDB08107": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "appsync.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "apidsServiceRoleDefaultPolicy5634EFD0": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "es:ESHttpGet", + "es:ESHttpHead", + "es:ESHttpDelete", + "es:ESHttpPost", + "es:ESHttpPut", + "es:ESHttpPatch" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Domain66AC69E0", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Domain66AC69E0", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "apidsServiceRoleDefaultPolicy5634EFD0", + "Roles": [ + { + "Ref": "apidsServiceRoleBDB08107" + } + ] + } + }, + "apids4328272F": { + "Type": "AWS::AppSync::DataSource", + "Properties": { + "ApiId": { + "Fn::GetAtt": [ + "apiC8550315", + "ApiId" + ] + }, + "Name": "ds", + "Type": "AMAZON_ELASTICSEARCH", + "ElasticsearchConfig": { + "AwsRegion": { + "Ref": "AWS::Region" + }, + "Endpoint": { + "Fn::Join": [ + "", + [ + "https://", + { + "Fn::GetAtt": [ + "Domain66AC69E0", + "DomainEndpoint" + ] + } + ] + ] + } + }, + "ServiceRoleArn": { + "Fn::GetAtt": [ + "apidsServiceRoleBDB08107", + "Arn" + ] + } + } + }, + "apidsQuerygetTestsResolver5C6FBB59": { + "Type": "AWS::AppSync::Resolver", + "Properties": { + "ApiId": { + "Fn::GetAtt": [ + "apiC8550315", + "ApiId" + ] + }, + "FieldName": "getTests", + "TypeName": "Query", + "DataSourceName": "ds", + "Kind": "UNIT", + "RequestMappingTemplate": "{\"version\":\"2017-02-28\",\"operation\":\"GET\",\"path\":\"/id/post/_search\",\"params\":{\"headers\":{},\"queryString\":{},\"body\":{\"from\":0,\"size\":50}}}", + "ResponseMappingTemplate": "{\"version\":\"2017-02-28\",\"operation\":\"GET\",\"path\":\"/id/post/_search\",\"params\":{\"headers\":{},\"queryString\":{},\"body\":{\"from\":0,\"size\":50,\"query\":{\"term\":{\"author\":\"$util.toJson($context.arguments.author)\"}}}}}" + }, + "DependsOn": [ + "apids4328272F", + "apiSchema0EA92056" + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-appsync/test/integ.graphql-elasticsearch.ts b/packages/@aws-cdk/aws-appsync/test/integ.graphql-elasticsearch.ts new file mode 100644 index 0000000000000..933572da29eca --- /dev/null +++ b/packages/@aws-cdk/aws-appsync/test/integ.graphql-elasticsearch.ts @@ -0,0 +1,66 @@ +import * as path from 'path'; +import * as es from '@aws-cdk/aws-elasticsearch'; +import { User } from '@aws-cdk/aws-iam'; +import * as cdk from '@aws-cdk/core'; +import * as appsync from '../lib'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'appsync-elasticsearch'); +const user = new User(stack, 'User'); +const domain = new es.Domain(stack, 'Domain', { + version: es.ElasticsearchVersion.V7_1, + removalPolicy: cdk.RemovalPolicy.DESTROY, + fineGrainedAccessControl: { + masterUserArn: user.userArn, + }, + encryptionAtRest: { + enabled: true, + }, + nodeToNodeEncryption: true, + enforceHttps: true, +}); + +const api = new appsync.GraphqlApi(stack, 'api', { + name: 'api', + schema: appsync.Schema.fromAsset(path.join(__dirname, 'appsync.test.graphql')), +}); + +const ds = api.addElasticsearchDataSource('ds', domain); + +ds.createResolver({ + typeName: 'Query', + fieldName: 'getTests', + requestMappingTemplate: appsync.MappingTemplate.fromString(JSON.stringify({ + version: '2017-02-28', + operation: 'GET', + path: '/id/post/_search', + params: { + headers: {}, + queryString: {}, + body: { + from: 0, + size: 50, + }, + }, + })), + responseMappingTemplate: appsync.MappingTemplate.fromString(JSON.stringify({ + version: '2017-02-28', + operation: 'GET', + path: '/id/post/_search', + params: { + headers: {}, + queryString: {}, + body: { + from: 0, + size: 50, + query: { + term: { + author: '$util.toJson($context.arguments.author)', + }, + }, + }, + }, + })), +}); + +app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudwatch/lib/graph.ts b/packages/@aws-cdk/aws-cloudwatch/lib/graph.ts index 98f8980db4f4b..709baba719109 100644 --- a/packages/@aws-cdk/aws-cloudwatch/lib/graph.ts +++ b/packages/@aws-cdk/aws-cloudwatch/lib/graph.ts @@ -206,13 +206,39 @@ export interface GraphWidgetProps extends MetricWidgetProps { */ readonly liveData?: boolean; - /** * Display this metric * * @default TimeSeries */ readonly view?: GraphWidgetView; + + /** + * Whether to show the value from the entire time range. Only applicable for Bar and Pie charts. + * + * If false, values will be from the most recent period of your chosen time range; + * if true, shows the value from the entire time range. + * + * @default false + */ + readonly setPeriodToTimeRange?: boolean; + + /** + * The default period for all metrics in this widget. + * The period is the length of time represented by one data point on the graph. + * This default can be overridden within each metric definition. + * + * @default cdk.Duration.seconds(300) + */ + readonly period?: cdk.Duration; + + /** + * The default statistic to be displayed for each metric. + * This default can be overridden within the definition of each individual metric + * + * @default - The statistic for each metric is used + */ + readonly statistic?: string; } /** @@ -276,6 +302,9 @@ export class GraphWidget extends ConcreteWidget { }, legend: this.props.legendPosition !== undefined ? { position: this.props.legendPosition } : undefined, liveData: this.props.liveData, + setPeriodToTimeRange: this.props.setPeriodToTimeRange, + period: this.props.period?.toSeconds(), + stat: this.props.statistic, }, }]; } @@ -447,4 +476,4 @@ function mapAnnotation(yAxis: string): ((x: HorizontalAnnotation) => any) { return (a: HorizontalAnnotation) => { return { ...a, yAxis }; }; -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.math-alarm-and-dashboard.expected.json b/packages/@aws-cdk/aws-cloudwatch/test/integ.math-alarm-and-dashboard.expected.json index 8e9b235bb2b65..9d6d0b5b1c4bc 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.math-alarm-and-dashboard.expected.json +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.math-alarm-and-dashboard.expected.json @@ -116,7 +116,25 @@ "QueueName" ] }, - "\",{\"label\":\"NotVisible Messages\",\"period\":30,\"yAxis\":\"right\"}]],\"annotations\":{\"horizontal\":[{\"label\":\"Total Messages >= 100 for 3 datapoints within 3 minutes\",\"value\":100,\"yAxis\":\"left\"}]},\"yAxis\":{}}},{\"type\":\"metric\",\"width\":6,\"height\":3,\"x\":0,\"y\":12,\"properties\":{\"view\":\"singleValue\",\"title\":\"Current total messages in queue\",\"region\":\"", + "\",{\"label\":\"NotVisible Messages\",\"period\":30,\"yAxis\":\"right\"}]],\"annotations\":{\"horizontal\":[{\"label\":\"Total Messages >= 100 for 3 datapoints within 3 minutes\",\"value\":100,\"yAxis\":\"left\"}]},\"yAxis\":{}}},{\"type\":\"metric\",\"width\":6,\"height\":6,\"x\":0,\"y\":12,\"properties\":{\"view\":\"pie\",\"title\":\"Percentage of messages in each queue as pie chart\",\"region\":\"", + { + "Ref": "AWS::Region" + }, + "\",\"metrics\":[[\"AWS/SQS\",\"ApproximateNumberOfMessagesVisible\",\"QueueName\",\"", + { + "Fn::GetAtt": [ + "queue", + "QueueName" + ] + }, + "\",{\"label\":\"Visible Messages\",\"period\":10}],[\"AWS/SQS\",\"ApproximateNumberOfMessagesNotVisible\",\"QueueName\",\"", + { + "Fn::GetAtt": [ + "queue", + "QueueName" + ] + }, + "\",{\"label\":\"NotVisible Messages\",\"period\":30}]],\"yAxis\":{},\"setPeriodToTimeRange\":true}},{\"type\":\"metric\",\"width\":6,\"height\":3,\"x\":0,\"y\":18,\"properties\":{\"view\":\"singleValue\",\"title\":\"Current total messages in queue\",\"region\":\"", { "Ref": "AWS::Region" }, diff --git a/packages/@aws-cdk/aws-cloudwatch/test/integ.math-alarm-and-dashboard.ts b/packages/@aws-cdk/aws-cloudwatch/test/integ.math-alarm-and-dashboard.ts index 9de88e6bc729a..5a3285d873fe8 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/integ.math-alarm-and-dashboard.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/integ.math-alarm-and-dashboard.ts @@ -59,6 +59,13 @@ dashboard.addWidgets(new cloudwatch.GraphWidget({ leftAnnotations: [alarm.toAnnotation()], })); +dashboard.addWidgets(new cloudwatch.GraphWidget({ + title: 'Percentage of messages in each queue as pie chart', + left: [metricA, metricB], + view: cloudwatch.GraphWidgetView.PIE, + setPeriodToTimeRange: true, +})); + dashboard.addWidgets(new cloudwatch.SingleValueWidget({ title: 'Current total messages in queue', metrics: [sumExpression], diff --git a/packages/@aws-cdk/aws-cloudwatch/test/test.graphs.ts b/packages/@aws-cdk/aws-cloudwatch/test/test.graphs.ts index 7e306e2bf0691..e5cc11781393d 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/test.graphs.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/test.graphs.ts @@ -1,4 +1,4 @@ -import { Stack } from '@aws-cdk/core'; +import { Duration, Stack } from '@aws-cdk/core'; import { Test } from 'nodeunit'; import { Alarm, AlarmWidget, Color, GraphWidget, GraphWidgetView, LegendPosition, LogQueryWidget, Metric, Shading, SingleValueWidget, LogQueryVisualizationType } from '../lib'; @@ -660,4 +660,61 @@ export = { test.done(); }, -}; \ No newline at end of file + + 'add setPeriodToTimeRange to GraphWidget'(test: Test) { + // GIVEN + const stack = new Stack(); + const widget = new GraphWidget({ + left: [new Metric({ namespace: 'CDK', metricName: 'Test' })], + view: GraphWidgetView.PIE, + setPeriodToTimeRange: true, + }); + + // THEN + test.deepEqual(stack.resolve(widget.toJson()), [{ + type: 'metric', + width: 6, + height: 6, + properties: { + view: 'pie', + region: { Ref: 'AWS::Region' }, + metrics: [ + ['CDK', 'Test'], + ], + yAxis: {}, + setPeriodToTimeRange: true, + }, + }]); + + test.done(); + }, + + 'GraphWidget supports stat and period'(test: Test) { + // GIVEN + const stack = new Stack(); + const widget = new GraphWidget({ + left: [new Metric({ namespace: 'CDK', metricName: 'Test' })], + statistic: 'Average', + period: Duration.days(2), + }); + + // THEN + test.deepEqual(stack.resolve(widget.toJson()), [{ + type: 'metric', + width: 6, + height: 6, + properties: { + view: 'timeSeries', + region: { Ref: 'AWS::Region' }, + metrics: [ + ['CDK', 'Test'], + ], + yAxis: {}, + stat: 'Average', + period: 172800, + }, + }]); + + test.done(); + }, +}; diff --git a/packages/@aws-cdk/aws-codepipeline-actions/package.json b/packages/@aws-cdk/aws-codepipeline-actions/package.json index 48b7c111f56f6..281edb052d5a6 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/package.json +++ b/packages/@aws-cdk/aws-codepipeline-actions/package.json @@ -69,7 +69,7 @@ "@types/jest": "^26.0.23", "@aws-cdk/aws-cloudtrail": "0.0.0", "@aws-cdk/cx-api": "0.0.0", - "@types/lodash": "^4.14.168", + "@types/lodash": "^4.14.169", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "lodash": "^4.17.21", diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.load-balanced-fargate-service.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https.expected.json similarity index 92% rename from packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.load-balanced-fargate-service.expected.json rename to packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https.expected.json index 1d670f79f58a6..5a67a969707c8 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.load-balanced-fargate-service.expected.json +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https.expected.json @@ -10,7 +10,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc" + "Value": "aws-ecs-integ-alb-fg-https/Vpc" } ] } @@ -35,7 +35,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-alb-fg-https/Vpc/PublicSubnet1" } ] } @@ -49,7 +49,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-alb-fg-https/Vpc/PublicSubnet1" } ] } @@ -87,7 +87,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-alb-fg-https/Vpc/PublicSubnet1" } ] } @@ -107,7 +107,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-alb-fg-https/Vpc/PublicSubnet1" } ] } @@ -132,7 +132,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-alb-fg-https/Vpc/PublicSubnet2" } ] } @@ -146,7 +146,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-alb-fg-https/Vpc/PublicSubnet2" } ] } @@ -184,7 +184,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-alb-fg-https/Vpc/PublicSubnet2" } ] } @@ -204,7 +204,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-alb-fg-https/Vpc/PublicSubnet2" } ] } @@ -229,7 +229,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PrivateSubnet1" + "Value": "aws-ecs-integ-alb-fg-https/Vpc/PrivateSubnet1" } ] } @@ -243,7 +243,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PrivateSubnet1" + "Value": "aws-ecs-integ-alb-fg-https/Vpc/PrivateSubnet1" } ] } @@ -291,7 +291,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PrivateSubnet2" + "Value": "aws-ecs-integ-alb-fg-https/Vpc/PrivateSubnet2" } ] } @@ -305,7 +305,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PrivateSubnet2" + "Value": "aws-ecs-integ-alb-fg-https/Vpc/PrivateSubnet2" } ] } @@ -339,7 +339,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc" + "Value": "aws-ecs-integ-alb-fg-https/Vpc" } ] } @@ -394,7 +394,7 @@ "myServiceLBSecurityGroupFE0ED608": { "Type": "AWS::EC2::SecurityGroup", "Properties": { - "GroupDescription": "Automatically created Security Group for ELB awsecsintegmyServiceLB1F7A535D", + "GroupDescription": "Automatically created Security Group for ELB awsecsintegalbfghttpsmyServiceLB8BEE3C49", "SecurityGroupIngress": [ { "CidrIp": "0.0.0.0/0", @@ -416,7 +416,7 @@ } } }, - "myServiceLBSecurityGrouptoawsecsintegmyServiceSecurityGroup8DAB521180B6703B07": { + "myServiceLBSecurityGrouptoawsecsintegalbfghttpsmyServiceSecurityGroup49C558AD803FB613FF": { "Type": "AWS::EC2::SecurityGroupEgress", "Properties": { "GroupId": { @@ -451,15 +451,15 @@ "LoadBalancerArn": { "Ref": "myServiceLB168895E1" }, - "Port": 443, - "Protocol": "HTTPS", "Certificates": [ { "CertificateArn": { "Ref": "myServiceCertificate152F9DDA" } } - ] + ], + "Port": 443, + "Protocol": "HTTPS" } }, "myServiceLBPublicListenerECSGroup17E9BBC1": { @@ -513,8 +513,7 @@ "Type": "A", "AliasTarget": { "DNSName": { - "Fn::Join": - [ + "Fn::Join": [ "", [ "dualstack.", @@ -589,7 +588,7 @@ "Arn" ] }, - "Family": "awsecsintegmyServiceTaskDefA3A33D18", + "Family": "awsecsintegalbfghttpsmyServiceTaskDefD8ABFBF2", "Memory": "512", "NetworkMode": "awsvpc", "RequiresCompatibilities": [ @@ -709,7 +708,7 @@ "myServiceSecurityGroupC3B9D4E0": { "Type": "AWS::EC2::SecurityGroup", "Properties": { - "GroupDescription": "aws-ecs-integ/myService/Service/SecurityGroup", + "GroupDescription": "aws-ecs-integ-alb-fg-https/myService/Service/SecurityGroup", "SecurityGroupEgress": [ { "CidrIp": "0.0.0.0/0", @@ -722,7 +721,7 @@ } } }, - "myServiceSecurityGroupfromawsecsintegmyServiceLBSecurityGroupFA544FE5800A81885C": { + "myServiceSecurityGroupfromawsecsintegalbfghttpsmyServiceLBSecurityGroupA934AF89808E9FB7A3": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "IpProtocol": "tcp", @@ -767,4 +766,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.load-balanced-fargate-service.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https.ts similarity index 94% rename from packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.load-balanced-fargate-service.ts rename to packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https.ts index b78ff8da2304f..fe6940d272cc9 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.load-balanced-fargate-service.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.alb-fargate-service-https.ts @@ -7,7 +7,7 @@ import { App, Stack } from '@aws-cdk/core'; import { ApplicationLoadBalancedFargateService } from '../../lib'; const app = new App(); -const stack = new Stack(app, 'aws-ecs-integ'); +const stack = new Stack(app, 'aws-ecs-integ-alb-fg-https'); const vpc = new Vpc(stack, 'Vpc', { maxAzs: 2 }); const cluster = new Cluster(stack, 'Cluster', { vpc }); diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-autocreate.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-autocreate.expected.json index 5813cd78e41f3..778523d6bc6df 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-autocreate.expected.json +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-autocreate.expected.json @@ -1,6 +1,6 @@ { "Resources": { - "L3LB212FC0E0": { + "ALBFargateServiceLB64A0074E": { "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", "Properties": { "LoadBalancerAttributes": [ @@ -13,7 +13,7 @@ "SecurityGroups": [ { "Fn::GetAtt": [ - "L3LBSecurityGroupEDE61198", + "ALBFargateServiceLBSecurityGroup5DC3060E", "GroupId" ] } @@ -33,10 +33,10 @@ "EcsDefaultClusterMnL3mNNYNVpcPublicSubnet2DefaultRouteB1375520" ] }, - "L3LBSecurityGroupEDE61198": { + "ALBFargateServiceLBSecurityGroup5DC3060E": { "Type": "AWS::EC2::SecurityGroup", "Properties": { - "GroupDescription": "Automatically created Security Group for ELB awsecsintegL3LB6453BA0A", + "GroupDescription": "Automatically created Security Group for ELB awsecsintegl3autocreateALBFargateServiceLB31EA4AB6", "SecurityGroupIngress": [ { "CidrIp": "0.0.0.0/0", @@ -51,12 +51,12 @@ } } }, - "L3LBSecurityGrouptoawsecsintegL3ServiceSecurityGroup7B96C87F8094933E0A": { + "ALBFargateServiceLBSecurityGrouptoawsecsintegl3autocreateALBFargateServiceSecurityGroup6F9400B580770A6C60": { "Type": "AWS::EC2::SecurityGroupEgress", "Properties": { "GroupId": { "Fn::GetAtt": [ - "L3LBSecurityGroupEDE61198", + "ALBFargateServiceLBSecurityGroup5DC3060E", "GroupId" ] }, @@ -64,7 +64,7 @@ "Description": "Load balancer to target", "DestinationSecurityGroupId": { "Fn::GetAtt": [ - "L3ServiceSecurityGroup677B0897", + "ALBFargateServiceSecurityGroup82F7A67E", "GroupId" ] }, @@ -72,25 +72,25 @@ "ToPort": 80 } }, - "L3LBPublicListener156FFC0F": { + "ALBFargateServiceLBPublicListener3489002A": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "Properties": { "DefaultActions": [ { "TargetGroupArn": { - "Ref": "L3LBPublicListenerECSGroup648EEA11" + "Ref": "ALBFargateServiceLBPublicListenerECSGroup6871FB8C" }, "Type": "forward" } ], "LoadBalancerArn": { - "Ref": "L3LB212FC0E0" + "Ref": "ALBFargateServiceLB64A0074E" }, "Port": 80, "Protocol": "HTTP" } }, - "L3LBPublicListenerECSGroup648EEA11": { + "ALBFargateServiceLBPublicListenerECSGroup6871FB8C": { "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", "Properties": { "Port": 80, @@ -101,7 +101,7 @@ } } }, - "L3TaskDefTaskRole21C75D10": { + "ALBFargateServiceTaskDefTaskRole11408723": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -118,7 +118,7 @@ } } }, - "L3TaskDef48D8ACB8": { + "ALBFargateServiceTaskDefF69F17D6": { "Type": "AWS::ECS::TaskDefinition", "Properties": { "ContainerDefinitions": [ @@ -129,9 +129,9 @@ "LogDriver": "awslogs", "Options": { "awslogs-group": { - "Ref": "L3TaskDefwebLogGroupC6E4A38A" + "Ref": "ALBFargateServiceTaskDefwebLogGroup7073A41D" }, - "awslogs-stream-prefix": "L3", + "awslogs-stream-prefix": "ALBFargateService", "awslogs-region": { "Ref": "AWS::Region" } @@ -149,11 +149,11 @@ "Cpu": "512", "ExecutionRoleArn": { "Fn::GetAtt": [ - "L3TaskDefExecutionRole49AF0996", + "ALBFargateServiceTaskDefExecutionRole9E885E7B", "Arn" ] }, - "Family": "awsecsintegL3TaskDefAA25240E", + "Family": "awsecsintegl3autocreateALBFargateServiceTaskDefDA905826", "Memory": "1024", "NetworkMode": "awsvpc", "RequiresCompatibilities": [ @@ -161,18 +161,18 @@ ], "TaskRoleArn": { "Fn::GetAtt": [ - "L3TaskDefTaskRole21C75D10", + "ALBFargateServiceTaskDefTaskRole11408723", "Arn" ] } } }, - "L3TaskDefwebLogGroupC6E4A38A": { + "ALBFargateServiceTaskDefwebLogGroup7073A41D": { "Type": "AWS::Logs::LogGroup", "UpdateReplacePolicy": "Retain", "DeletionPolicy": "Retain" }, - "L3TaskDefExecutionRole49AF0996": { + "ALBFargateServiceTaskDefExecutionRole9E885E7B": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -189,7 +189,7 @@ } } }, - "L3TaskDefExecutionRoleDefaultPolicy4656E642": { + "ALBFargateServiceTaskDefExecutionRoleDefaultPolicy574B9EAD": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { @@ -202,7 +202,7 @@ "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "L3TaskDefwebLogGroupC6E4A38A", + "ALBFargateServiceTaskDefwebLogGroup7073A41D", "Arn" ] } @@ -210,15 +210,15 @@ ], "Version": "2012-10-17" }, - "PolicyName": "L3TaskDefExecutionRoleDefaultPolicy4656E642", + "PolicyName": "ALBFargateServiceTaskDefExecutionRoleDefaultPolicy574B9EAD", "Roles": [ { - "Ref": "L3TaskDefExecutionRole49AF0996" + "Ref": "ALBFargateServiceTaskDefExecutionRole9E885E7B" } ] } }, - "L3Service616D5A93": { + "ALBFargateService90FDCE10": { "Type": "AWS::ECS::Service", "Properties": { "Cluster": { @@ -236,7 +236,7 @@ "ContainerName": "web", "ContainerPort": 80, "TargetGroupArn": { - "Ref": "L3LBPublicListenerECSGroup648EEA11" + "Ref": "ALBFargateServiceLBPublicListenerECSGroup6871FB8C" } } ], @@ -246,7 +246,7 @@ "SecurityGroups": [ { "Fn::GetAtt": [ - "L3ServiceSecurityGroup677B0897", + "ALBFargateServiceSecurityGroup82F7A67E", "GroupId" ] } @@ -262,18 +262,18 @@ } }, "TaskDefinition": { - "Ref": "L3TaskDef48D8ACB8" + "Ref": "ALBFargateServiceTaskDefF69F17D6" } }, "DependsOn": [ - "L3LBPublicListenerECSGroup648EEA11", - "L3LBPublicListener156FFC0F" + "ALBFargateServiceLBPublicListenerECSGroup6871FB8C", + "ALBFargateServiceLBPublicListener3489002A" ] }, - "L3ServiceSecurityGroup677B0897": { + "ALBFargateServiceSecurityGroup82F7A67E": { "Type": "AWS::EC2::SecurityGroup", "Properties": { - "GroupDescription": "aws-ecs-integ/L3/Service/SecurityGroup", + "GroupDescription": "aws-ecs-integ-l3-autocreate/ALBFargateService/Service/SecurityGroup", "SecurityGroupEgress": [ { "CidrIp": "0.0.0.0/0", @@ -286,7 +286,7 @@ } } }, - "L3ServiceSecurityGroupfromawsecsintegL3LBSecurityGroupA70DA46C80DBDFBCD6": { + "ALBFargateServiceSecurityGroupfromawsecsintegl3autocreateALBFargateServiceLBSecurityGroupD565E0BF802E7B8344": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "IpProtocol": "tcp", @@ -294,13 +294,13 @@ "FromPort": 80, "GroupId": { "Fn::GetAtt": [ - "L3ServiceSecurityGroup677B0897", + "ALBFargateServiceSecurityGroup82F7A67E", "GroupId" ] }, "SourceSecurityGroupId": { "Fn::GetAtt": [ - "L3LBSecurityGroupEDE61198", + "ALBFargateServiceLBSecurityGroup5DC3060E", "GroupId" ] }, @@ -320,7 +320,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/EcsDefaultClusterMnL3mNNYN/Vpc" + "Value": "aws-ecs-integ-l3-autocreate/EcsDefaultClusterMnL3mNNYN/Vpc" } ] } @@ -345,7 +345,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-l3-autocreate/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet1" } ] } @@ -359,7 +359,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-l3-autocreate/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet1" } ] } @@ -397,7 +397,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-l3-autocreate/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet1" } ] } @@ -417,7 +417,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-l3-autocreate/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet1" } ] } @@ -442,7 +442,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-l3-autocreate/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet2" } ] } @@ -456,7 +456,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-l3-autocreate/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet2" } ] } @@ -494,7 +494,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-l3-autocreate/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet2" } ] } @@ -514,7 +514,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-l3-autocreate/EcsDefaultClusterMnL3mNNYN/Vpc/PublicSubnet2" } ] } @@ -539,7 +539,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/EcsDefaultClusterMnL3mNNYN/Vpc/PrivateSubnet1" + "Value": "aws-ecs-integ-l3-autocreate/EcsDefaultClusterMnL3mNNYN/Vpc/PrivateSubnet1" } ] } @@ -553,7 +553,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/EcsDefaultClusterMnL3mNNYN/Vpc/PrivateSubnet1" + "Value": "aws-ecs-integ-l3-autocreate/EcsDefaultClusterMnL3mNNYN/Vpc/PrivateSubnet1" } ] } @@ -601,7 +601,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/EcsDefaultClusterMnL3mNNYN/Vpc/PrivateSubnet2" + "Value": "aws-ecs-integ-l3-autocreate/EcsDefaultClusterMnL3mNNYN/Vpc/PrivateSubnet2" } ] } @@ -615,7 +615,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/EcsDefaultClusterMnL3mNNYN/Vpc/PrivateSubnet2" + "Value": "aws-ecs-integ-l3-autocreate/EcsDefaultClusterMnL3mNNYN/Vpc/PrivateSubnet2" } ] } @@ -649,7 +649,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/EcsDefaultClusterMnL3mNNYN/Vpc" + "Value": "aws-ecs-integ-l3-autocreate/EcsDefaultClusterMnL3mNNYN/Vpc" } ] } @@ -665,7 +665,7 @@ } } }, - "L3bLBB8FADA4E": { + "NLBFargateServiceLB659EC17C": { "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", "Properties": { "LoadBalancerAttributes": [ @@ -675,14 +675,6 @@ } ], "Scheme": "internet-facing", - "SecurityGroups": [ - { - "Fn::GetAtt": [ - "L3bLBSecurityGroup7A2B0AA0", - "GroupId" - ] - } - ], "Subnets": [ { "Ref": "EcsDefaultClusterMnL3mNNYNVpcPublicSubnet1Subnet3C273B99" @@ -691,82 +683,43 @@ "Ref": "EcsDefaultClusterMnL3mNNYNVpcPublicSubnet2Subnet95FF715A" } ], - "Type": "application" + "Type": "network" }, "DependsOn": [ "EcsDefaultClusterMnL3mNNYNVpcPublicSubnet1DefaultRouteFF4E2178", "EcsDefaultClusterMnL3mNNYNVpcPublicSubnet2DefaultRouteB1375520" ] }, - "L3bLBSecurityGroup7A2B0AA0": { - "Type": "AWS::EC2::SecurityGroup", - "Properties": { - "GroupDescription": "Automatically created Security Group for ELB awsecsintegL3bLB9C1497A7", - "SecurityGroupIngress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow from anyone on port 80", - "FromPort": 80, - "IpProtocol": "tcp", - "ToPort": 80 - } - ], - "VpcId": { - "Ref": "EcsDefaultClusterMnL3mNNYNVpc7788A521" - } - } - }, - "L3bLBSecurityGrouptoawsecsintegL3bServiceSecurityGroupC2BD1A598019C4C37D": { - "Type": "AWS::EC2::SecurityGroupEgress", - "Properties": { - "GroupId": { - "Fn::GetAtt": [ - "L3bLBSecurityGroup7A2B0AA0", - "GroupId" - ] - }, - "IpProtocol": "tcp", - "Description": "Load balancer to target", - "DestinationSecurityGroupId": { - "Fn::GetAtt": [ - "L3bServiceSecurityGroupA8DA736E", - "GroupId" - ] - }, - "FromPort": 80, - "ToPort": 80 - } - }, - "L3bLBPublicListenerA825925B": { + "NLBFargateServiceLBPublicListenerB0DCA73C": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "Properties": { "DefaultActions": [ { "TargetGroupArn": { - "Ref": "L3bLBPublicListenerECSGroup0070C5CA" + "Ref": "NLBFargateServiceLBPublicListenerECSGroupC469CAA2" }, "Type": "forward" } ], "LoadBalancerArn": { - "Ref": "L3bLBB8FADA4E" + "Ref": "NLBFargateServiceLB659EC17C" }, "Port": 80, - "Protocol": "HTTP" + "Protocol": "TCP" } }, - "L3bLBPublicListenerECSGroup0070C5CA": { + "NLBFargateServiceLBPublicListenerECSGroupC469CAA2": { "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", "Properties": { "Port": 80, - "Protocol": "HTTP", + "Protocol": "TCP", "TargetType": "ip", "VpcId": { "Ref": "EcsDefaultClusterMnL3mNNYNVpc7788A521" } } }, - "L3bTaskDefTaskRoleADAB80C8": { + "NLBFargateServiceTaskDefTaskRole6C88F40B": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -783,7 +736,7 @@ } } }, - "L3bTaskDef5506864D": { + "NLBFargateServiceTaskDefB836FA89": { "Type": "AWS::ECS::TaskDefinition", "Properties": { "ContainerDefinitions": [ @@ -794,9 +747,9 @@ "LogDriver": "awslogs", "Options": { "awslogs-group": { - "Ref": "L3bTaskDefwebLogGroup8E5F1183" + "Ref": "NLBFargateServiceTaskDefwebLogGroupC4A42FE2" }, - "awslogs-stream-prefix": "L3b", + "awslogs-stream-prefix": "NLBFargateService", "awslogs-region": { "Ref": "AWS::Region" } @@ -814,11 +767,11 @@ "Cpu": "512", "ExecutionRoleArn": { "Fn::GetAtt": [ - "L3bTaskDefExecutionRole9A3E2688", + "NLBFargateServiceTaskDefExecutionRoleF6D642D5", "Arn" ] }, - "Family": "awsecsintegL3bTaskDef24D7E4F1", + "Family": "awsecsintegl3autocreateNLBFargateServiceTaskDef7AC6C114", "Memory": "1024", "NetworkMode": "awsvpc", "RequiresCompatibilities": [ @@ -826,18 +779,18 @@ ], "TaskRoleArn": { "Fn::GetAtt": [ - "L3bTaskDefTaskRoleADAB80C8", + "NLBFargateServiceTaskDefTaskRole6C88F40B", "Arn" ] } } }, - "L3bTaskDefwebLogGroup8E5F1183": { + "NLBFargateServiceTaskDefwebLogGroupC4A42FE2": { "Type": "AWS::Logs::LogGroup", "UpdateReplacePolicy": "Retain", "DeletionPolicy": "Retain" }, - "L3bTaskDefExecutionRole9A3E2688": { + "NLBFargateServiceTaskDefExecutionRoleF6D642D5": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -854,7 +807,7 @@ } } }, - "L3bTaskDefExecutionRoleDefaultPolicy0CEA0ED2": { + "NLBFargateServiceTaskDefExecutionRoleDefaultPolicy90080805": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { @@ -867,7 +820,7 @@ "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "L3bTaskDefwebLogGroup8E5F1183", + "NLBFargateServiceTaskDefwebLogGroupC4A42FE2", "Arn" ] } @@ -875,15 +828,15 @@ ], "Version": "2012-10-17" }, - "PolicyName": "L3bTaskDefExecutionRoleDefaultPolicy0CEA0ED2", + "PolicyName": "NLBFargateServiceTaskDefExecutionRoleDefaultPolicy90080805", "Roles": [ { - "Ref": "L3bTaskDefExecutionRole9A3E2688" + "Ref": "NLBFargateServiceTaskDefExecutionRoleF6D642D5" } ] } }, - "L3bServiceF9D33D5A": { + "NLBFargateServiceB92AC095": { "Type": "AWS::ECS::Service", "Properties": { "Cluster": { @@ -901,7 +854,7 @@ "ContainerName": "web", "ContainerPort": 80, "TargetGroupArn": { - "Ref": "L3bLBPublicListenerECSGroup0070C5CA" + "Ref": "NLBFargateServiceLBPublicListenerECSGroupC469CAA2" } } ], @@ -911,7 +864,7 @@ "SecurityGroups": [ { "Fn::GetAtt": [ - "L3bServiceSecurityGroupA8DA736E", + "NLBFargateServiceSecurityGroup9D81388B", "GroupId" ] } @@ -927,18 +880,18 @@ } }, "TaskDefinition": { - "Ref": "L3bTaskDef5506864D" + "Ref": "NLBFargateServiceTaskDefB836FA89" } }, "DependsOn": [ - "L3bLBPublicListenerECSGroup0070C5CA", - "L3bLBPublicListenerA825925B" + "NLBFargateServiceLBPublicListenerECSGroupC469CAA2", + "NLBFargateServiceLBPublicListenerB0DCA73C" ] }, - "L3bServiceSecurityGroupA8DA736E": { + "NLBFargateServiceSecurityGroup9D81388B": { "Type": "AWS::EC2::SecurityGroup", "Properties": { - "GroupDescription": "aws-ecs-integ/L3b/Service/SecurityGroup", + "GroupDescription": "aws-ecs-integ-l3-autocreate/NLBFargateService/Service/SecurityGroup", "SecurityGroupEgress": [ { "CidrIp": "0.0.0.0/0", @@ -950,39 +903,18 @@ "Ref": "EcsDefaultClusterMnL3mNNYNVpc7788A521" } } - }, - "L3bServiceSecurityGroupfromawsecsintegL3bLBSecurityGroupA7B79A628034042CE5": { - "Type": "AWS::EC2::SecurityGroupIngress", - "Properties": { - "IpProtocol": "tcp", - "Description": "Load balancer to target", - "FromPort": 80, - "GroupId": { - "Fn::GetAtt": [ - "L3bServiceSecurityGroupA8DA736E", - "GroupId" - ] - }, - "SourceSecurityGroupId": { - "Fn::GetAtt": [ - "L3bLBSecurityGroup7A2B0AA0", - "GroupId" - ] - }, - "ToPort": 80 - } } }, "Outputs": { - "L3LoadBalancerDNSC6CB4A70": { + "ALBFargateServiceLoadBalancerDNSAFB2EDDB": { "Value": { "Fn::GetAtt": [ - "L3LB212FC0E0", + "ALBFargateServiceLB64A0074E", "DNSName" ] } }, - "L3ServiceURL0F065F2D": { + "ALBFargateServiceServiceURL4A19CF25": { "Value": { "Fn::Join": [ "", @@ -990,7 +922,7 @@ "http://", { "Fn::GetAtt": [ - "L3LB212FC0E0", + "ALBFargateServiceLB64A0074E", "DNSName" ] } @@ -998,29 +930,13 @@ ] } }, - "L3bLoadBalancerDNSED096132": { + "NLBFargateServiceLoadBalancerDNSC2B2922F": { "Value": { "Fn::GetAtt": [ - "L3bLBB8FADA4E", + "NLBFargateServiceLB659EC17C", "DNSName" ] } - }, - "L3bServiceURL0EDED888": { - "Value": { - "Fn::Join": [ - "", - [ - "http://", - { - "Fn::GetAtt": [ - "L3bLBB8FADA4E", - "DNSName" - ] - } - ] - ] - } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-autocreate.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-autocreate.ts index aae9efc969bac..3644cbbe8ec9f 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-autocreate.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-autocreate.ts @@ -3,9 +3,12 @@ import * as cdk from '@aws-cdk/core'; import * as ecsPatterns from '../../lib'; const app = new cdk.App(); -const stack = new cdk.Stack(app, 'aws-ecs-integ'); +const stack = new cdk.Stack(app, 'aws-ecs-integ-l3-autocreate'); -new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'L3', { +// No VPC or Cluster specified + +// Create ALB service +new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'ALBFargateService', { memoryLimitMiB: 1024, cpu: 512, taskImageOptions: { @@ -13,7 +16,8 @@ new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'L3', { }, }); -new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'L3b', { +// Create NLB service +new ecsPatterns.NetworkLoadBalancedFargateService(stack, 'NLBFargateService', { memoryLimitMiB: 1024, cpu: 512, taskImageOptions: { diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-vpconly.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-vpconly.expected.json index 5556df70a59b7..f221c99ccf4fc 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-vpconly.expected.json +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-vpconly.expected.json @@ -10,7 +10,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc" + "Value": "aws-ecs-integ-l3-vpconly/Vpc" } ] } @@ -35,7 +35,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-l3-vpconly/Vpc/PublicSubnet1" } ] } @@ -49,7 +49,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-l3-vpconly/Vpc/PublicSubnet1" } ] } @@ -87,7 +87,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-l3-vpconly/Vpc/PublicSubnet1" } ] } @@ -107,7 +107,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-l3-vpconly/Vpc/PublicSubnet1" } ] } @@ -132,7 +132,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-l3-vpconly/Vpc/PublicSubnet2" } ] } @@ -146,7 +146,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-l3-vpconly/Vpc/PublicSubnet2" } ] } @@ -184,7 +184,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-l3-vpconly/Vpc/PublicSubnet2" } ] } @@ -204,7 +204,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-l3-vpconly/Vpc/PublicSubnet2" } ] } @@ -229,7 +229,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PrivateSubnet1" + "Value": "aws-ecs-integ-l3-vpconly/Vpc/PrivateSubnet1" } ] } @@ -243,7 +243,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PrivateSubnet1" + "Value": "aws-ecs-integ-l3-vpconly/Vpc/PrivateSubnet1" } ] } @@ -291,7 +291,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PrivateSubnet2" + "Value": "aws-ecs-integ-l3-vpconly/Vpc/PrivateSubnet2" } ] } @@ -305,7 +305,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PrivateSubnet2" + "Value": "aws-ecs-integ-l3-vpconly/Vpc/PrivateSubnet2" } ] } @@ -339,7 +339,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc" + "Value": "aws-ecs-integ-l3-vpconly/Vpc" } ] } @@ -355,7 +355,7 @@ } } }, - "L3LB212FC0E0": { + "ALBFargateServiceLB64A0074E": { "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", "Properties": { "LoadBalancerAttributes": [ @@ -368,7 +368,7 @@ "SecurityGroups": [ { "Fn::GetAtt": [ - "L3LBSecurityGroupEDE61198", + "ALBFargateServiceLBSecurityGroup5DC3060E", "GroupId" ] } @@ -388,10 +388,10 @@ "VpcPublicSubnet2DefaultRoute97F91067" ] }, - "L3LBSecurityGroupEDE61198": { + "ALBFargateServiceLBSecurityGroup5DC3060E": { "Type": "AWS::EC2::SecurityGroup", "Properties": { - "GroupDescription": "Automatically created Security Group for ELB awsecsintegL3LB6453BA0A", + "GroupDescription": "Automatically created Security Group for ELB awsecsintegl3vpconlyALBFargateServiceLBE08492C1", "SecurityGroupIngress": [ { "CidrIp": "0.0.0.0/0", @@ -406,12 +406,12 @@ } } }, - "L3LBSecurityGrouptoawsecsintegL3ServiceSecurityGroup7B96C87F8094933E0A": { + "ALBFargateServiceLBSecurityGrouptoawsecsintegl3vpconlyALBFargateServiceSecurityGroup3700A42180D1AB9DBC": { "Type": "AWS::EC2::SecurityGroupEgress", "Properties": { "GroupId": { "Fn::GetAtt": [ - "L3LBSecurityGroupEDE61198", + "ALBFargateServiceLBSecurityGroup5DC3060E", "GroupId" ] }, @@ -419,7 +419,7 @@ "Description": "Load balancer to target", "DestinationSecurityGroupId": { "Fn::GetAtt": [ - "L3ServiceSecurityGroup677B0897", + "ALBFargateServiceSecurityGroup82F7A67E", "GroupId" ] }, @@ -427,25 +427,25 @@ "ToPort": 80 } }, - "L3LBPublicListener156FFC0F": { + "ALBFargateServiceLBPublicListener3489002A": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "Properties": { "DefaultActions": [ { "TargetGroupArn": { - "Ref": "L3LBPublicListenerECSGroup648EEA11" + "Ref": "ALBFargateServiceLBPublicListenerECSGroup6871FB8C" }, "Type": "forward" } ], "LoadBalancerArn": { - "Ref": "L3LB212FC0E0" + "Ref": "ALBFargateServiceLB64A0074E" }, "Port": 80, "Protocol": "HTTP" } }, - "L3LBPublicListenerECSGroup648EEA11": { + "ALBFargateServiceLBPublicListenerECSGroup6871FB8C": { "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", "Properties": { "Port": 80, @@ -456,7 +456,7 @@ } } }, - "L3TaskDefTaskRole21C75D10": { + "ALBFargateServiceTaskDefTaskRole11408723": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -473,7 +473,7 @@ } } }, - "L3TaskDef48D8ACB8": { + "ALBFargateServiceTaskDefF69F17D6": { "Type": "AWS::ECS::TaskDefinition", "Properties": { "ContainerDefinitions": [ @@ -484,9 +484,9 @@ "LogDriver": "awslogs", "Options": { "awslogs-group": { - "Ref": "L3TaskDefwebLogGroupC6E4A38A" + "Ref": "ALBFargateServiceTaskDefwebLogGroup7073A41D" }, - "awslogs-stream-prefix": "L3", + "awslogs-stream-prefix": "ALBFargateService", "awslogs-region": { "Ref": "AWS::Region" } @@ -504,11 +504,11 @@ "Cpu": "512", "ExecutionRoleArn": { "Fn::GetAtt": [ - "L3TaskDefExecutionRole49AF0996", + "ALBFargateServiceTaskDefExecutionRole9E885E7B", "Arn" ] }, - "Family": "awsecsintegL3TaskDefAA25240E", + "Family": "awsecsintegl3vpconlyALBFargateServiceTaskDef846555AE", "Memory": "1024", "NetworkMode": "awsvpc", "RequiresCompatibilities": [ @@ -516,18 +516,18 @@ ], "TaskRoleArn": { "Fn::GetAtt": [ - "L3TaskDefTaskRole21C75D10", + "ALBFargateServiceTaskDefTaskRole11408723", "Arn" ] } } }, - "L3TaskDefwebLogGroupC6E4A38A": { + "ALBFargateServiceTaskDefwebLogGroup7073A41D": { "Type": "AWS::Logs::LogGroup", "UpdateReplacePolicy": "Retain", "DeletionPolicy": "Retain" }, - "L3TaskDefExecutionRole49AF0996": { + "ALBFargateServiceTaskDefExecutionRole9E885E7B": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -544,7 +544,7 @@ } } }, - "L3TaskDefExecutionRoleDefaultPolicy4656E642": { + "ALBFargateServiceTaskDefExecutionRoleDefaultPolicy574B9EAD": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { @@ -557,7 +557,7 @@ "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "L3TaskDefwebLogGroupC6E4A38A", + "ALBFargateServiceTaskDefwebLogGroup7073A41D", "Arn" ] } @@ -565,15 +565,15 @@ ], "Version": "2012-10-17" }, - "PolicyName": "L3TaskDefExecutionRoleDefaultPolicy4656E642", + "PolicyName": "ALBFargateServiceTaskDefExecutionRoleDefaultPolicy574B9EAD", "Roles": [ { - "Ref": "L3TaskDefExecutionRole49AF0996" + "Ref": "ALBFargateServiceTaskDefExecutionRole9E885E7B" } ] } }, - "L3Service616D5A93": { + "ALBFargateService90FDCE10": { "Type": "AWS::ECS::Service", "Properties": { "Cluster": { @@ -591,7 +591,7 @@ "ContainerName": "web", "ContainerPort": 80, "TargetGroupArn": { - "Ref": "L3LBPublicListenerECSGroup648EEA11" + "Ref": "ALBFargateServiceLBPublicListenerECSGroup6871FB8C" } } ], @@ -601,7 +601,7 @@ "SecurityGroups": [ { "Fn::GetAtt": [ - "L3ServiceSecurityGroup677B0897", + "ALBFargateServiceSecurityGroup82F7A67E", "GroupId" ] } @@ -617,18 +617,18 @@ } }, "TaskDefinition": { - "Ref": "L3TaskDef48D8ACB8" + "Ref": "ALBFargateServiceTaskDefF69F17D6" } }, "DependsOn": [ - "L3LBPublicListenerECSGroup648EEA11", - "L3LBPublicListener156FFC0F" + "ALBFargateServiceLBPublicListenerECSGroup6871FB8C", + "ALBFargateServiceLBPublicListener3489002A" ] }, - "L3ServiceSecurityGroup677B0897": { + "ALBFargateServiceSecurityGroup82F7A67E": { "Type": "AWS::EC2::SecurityGroup", "Properties": { - "GroupDescription": "aws-ecs-integ/L3/Service/SecurityGroup", + "GroupDescription": "aws-ecs-integ-l3-vpconly/ALBFargateService/Service/SecurityGroup", "SecurityGroupEgress": [ { "CidrIp": "0.0.0.0/0", @@ -641,7 +641,7 @@ } } }, - "L3ServiceSecurityGroupfromawsecsintegL3LBSecurityGroupA70DA46C80DBDFBCD6": { + "ALBFargateServiceSecurityGroupfromawsecsintegl3vpconlyALBFargateServiceLBSecurityGroup96E9BBBD8073FB670D": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "IpProtocol": "tcp", @@ -649,13 +649,13 @@ "FromPort": 80, "GroupId": { "Fn::GetAtt": [ - "L3ServiceSecurityGroup677B0897", + "ALBFargateServiceSecurityGroup82F7A67E", "GroupId" ] }, "SourceSecurityGroupId": { "Fn::GetAtt": [ - "L3LBSecurityGroupEDE61198", + "ALBFargateServiceLBSecurityGroup5DC3060E", "GroupId" ] }, @@ -665,672 +665,7 @@ "EcsDefaultClusterMnL3mNNYNVpc18E0451A": { "Type": "AWS::ECS::Cluster" }, - "Vpc299FDBC5F": { - "Type": "AWS::EC2::VPC", - "Properties": { - "CidrBlock": "10.0.0.0/16", - "EnableDnsHostnames": true, - "EnableDnsSupport": true, - "InstanceTenancy": "default", - "Tags": [ - { - "Key": "Name", - "Value": "aws-ecs-integ/Vpc2" - } - ] - } - }, - "Vpc2PublicSubnet1Subnet758D49A9": { - "Type": "AWS::EC2::Subnet", - "Properties": { - "CidrBlock": "10.0.0.0/18", - "VpcId": { - "Ref": "Vpc299FDBC5F" - }, - "AvailabilityZone": "test-region-1a", - "MapPublicIpOnLaunch": true, - "Tags": [ - { - "Key": "aws-cdk:subnet-name", - "Value": "Public" - }, - { - "Key": "aws-cdk:subnet-type", - "Value": "Public" - }, - { - "Key": "Name", - "Value": "aws-ecs-integ/Vpc2/PublicSubnet1" - } - ] - } - }, - "Vpc2PublicSubnet1RouteTable424A19D4": { - "Type": "AWS::EC2::RouteTable", - "Properties": { - "VpcId": { - "Ref": "Vpc299FDBC5F" - }, - "Tags": [ - { - "Key": "Name", - "Value": "aws-ecs-integ/Vpc2/PublicSubnet1" - } - ] - } - }, - "Vpc2PublicSubnet1RouteTableAssociationA1651F3A": { - "Type": "AWS::EC2::SubnetRouteTableAssociation", - "Properties": { - "RouteTableId": { - "Ref": "Vpc2PublicSubnet1RouteTable424A19D4" - }, - "SubnetId": { - "Ref": "Vpc2PublicSubnet1Subnet758D49A9" - } - } - }, - "Vpc2PublicSubnet1DefaultRoute64172CA2": { - "Type": "AWS::EC2::Route", - "Properties": { - "RouteTableId": { - "Ref": "Vpc2PublicSubnet1RouteTable424A19D4" - }, - "DestinationCidrBlock": "0.0.0.0/0", - "GatewayId": { - "Ref": "Vpc2IGWB10A76EB" - } - }, - "DependsOn": [ - "Vpc2VPCGW62C338EF" - ] - }, - "Vpc2PublicSubnet1EIP42DB8E45": { - "Type": "AWS::EC2::EIP", - "Properties": { - "Domain": "vpc", - "Tags": [ - { - "Key": "Name", - "Value": "aws-ecs-integ/Vpc2/PublicSubnet1" - } - ] - } - }, - "Vpc2PublicSubnet1NATGateway26016506": { - "Type": "AWS::EC2::NatGateway", - "Properties": { - "AllocationId": { - "Fn::GetAtt": [ - "Vpc2PublicSubnet1EIP42DB8E45", - "AllocationId" - ] - }, - "SubnetId": { - "Ref": "Vpc2PublicSubnet1Subnet758D49A9" - }, - "Tags": [ - { - "Key": "Name", - "Value": "aws-ecs-integ/Vpc2/PublicSubnet1" - } - ] - } - }, - "Vpc2PublicSubnet2Subnet0BF8C291": { - "Type": "AWS::EC2::Subnet", - "Properties": { - "CidrBlock": "10.0.64.0/18", - "VpcId": { - "Ref": "Vpc299FDBC5F" - }, - "AvailabilityZone": "test-region-1b", - "MapPublicIpOnLaunch": true, - "Tags": [ - { - "Key": "aws-cdk:subnet-name", - "Value": "Public" - }, - { - "Key": "aws-cdk:subnet-type", - "Value": "Public" - }, - { - "Key": "Name", - "Value": "aws-ecs-integ/Vpc2/PublicSubnet2" - } - ] - } - }, - "Vpc2PublicSubnet2RouteTableF9AE47B1": { - "Type": "AWS::EC2::RouteTable", - "Properties": { - "VpcId": { - "Ref": "Vpc299FDBC5F" - }, - "Tags": [ - { - "Key": "Name", - "Value": "aws-ecs-integ/Vpc2/PublicSubnet2" - } - ] - } - }, - "Vpc2PublicSubnet2RouteTableAssociation361E1341": { - "Type": "AWS::EC2::SubnetRouteTableAssociation", - "Properties": { - "RouteTableId": { - "Ref": "Vpc2PublicSubnet2RouteTableF9AE47B1" - }, - "SubnetId": { - "Ref": "Vpc2PublicSubnet2Subnet0BF8C291" - } - } - }, - "Vpc2PublicSubnet2DefaultRouteBAB514C1": { - "Type": "AWS::EC2::Route", - "Properties": { - "RouteTableId": { - "Ref": "Vpc2PublicSubnet2RouteTableF9AE47B1" - }, - "DestinationCidrBlock": "0.0.0.0/0", - "GatewayId": { - "Ref": "Vpc2IGWB10A76EB" - } - }, - "DependsOn": [ - "Vpc2VPCGW62C338EF" - ] - }, - "Vpc2PublicSubnet2EIP66DD26A4": { - "Type": "AWS::EC2::EIP", - "Properties": { - "Domain": "vpc", - "Tags": [ - { - "Key": "Name", - "Value": "aws-ecs-integ/Vpc2/PublicSubnet2" - } - ] - } - }, - "Vpc2PublicSubnet2NATGateway6CBF7FA6": { - "Type": "AWS::EC2::NatGateway", - "Properties": { - "AllocationId": { - "Fn::GetAtt": [ - "Vpc2PublicSubnet2EIP66DD26A4", - "AllocationId" - ] - }, - "SubnetId": { - "Ref": "Vpc2PublicSubnet2Subnet0BF8C291" - }, - "Tags": [ - { - "Key": "Name", - "Value": "aws-ecs-integ/Vpc2/PublicSubnet2" - } - ] - } - }, - "Vpc2PrivateSubnet1Subnet34902000": { - "Type": "AWS::EC2::Subnet", - "Properties": { - "CidrBlock": "10.0.128.0/18", - "VpcId": { - "Ref": "Vpc299FDBC5F" - }, - "AvailabilityZone": "test-region-1a", - "MapPublicIpOnLaunch": false, - "Tags": [ - { - "Key": "aws-cdk:subnet-name", - "Value": "Private" - }, - { - "Key": "aws-cdk:subnet-type", - "Value": "Private" - }, - { - "Key": "Name", - "Value": "aws-ecs-integ/Vpc2/PrivateSubnet1" - } - ] - } - }, - "Vpc2PrivateSubnet1RouteTableF8A2430B": { - "Type": "AWS::EC2::RouteTable", - "Properties": { - "VpcId": { - "Ref": "Vpc299FDBC5F" - }, - "Tags": [ - { - "Key": "Name", - "Value": "aws-ecs-integ/Vpc2/PrivateSubnet1" - } - ] - } - }, - "Vpc2PrivateSubnet1RouteTableAssociation74320528": { - "Type": "AWS::EC2::SubnetRouteTableAssociation", - "Properties": { - "RouteTableId": { - "Ref": "Vpc2PrivateSubnet1RouteTableF8A2430B" - }, - "SubnetId": { - "Ref": "Vpc2PrivateSubnet1Subnet34902000" - } - } - }, - "Vpc2PrivateSubnet1DefaultRoute24717F54": { - "Type": "AWS::EC2::Route", - "Properties": { - "RouteTableId": { - "Ref": "Vpc2PrivateSubnet1RouteTableF8A2430B" - }, - "DestinationCidrBlock": "0.0.0.0/0", - "NatGatewayId": { - "Ref": "Vpc2PublicSubnet1NATGateway26016506" - } - } - }, - "Vpc2PrivateSubnet2Subnet3BA0F39B": { - "Type": "AWS::EC2::Subnet", - "Properties": { - "CidrBlock": "10.0.192.0/18", - "VpcId": { - "Ref": "Vpc299FDBC5F" - }, - "AvailabilityZone": "test-region-1b", - "MapPublicIpOnLaunch": false, - "Tags": [ - { - "Key": "aws-cdk:subnet-name", - "Value": "Private" - }, - { - "Key": "aws-cdk:subnet-type", - "Value": "Private" - }, - { - "Key": "Name", - "Value": "aws-ecs-integ/Vpc2/PrivateSubnet2" - } - ] - } - }, - "Vpc2PrivateSubnet2RouteTableB4F37E84": { - "Type": "AWS::EC2::RouteTable", - "Properties": { - "VpcId": { - "Ref": "Vpc299FDBC5F" - }, - "Tags": [ - { - "Key": "Name", - "Value": "aws-ecs-integ/Vpc2/PrivateSubnet2" - } - ] - } - }, - "Vpc2PrivateSubnet2RouteTableAssociation19A1B68F": { - "Type": "AWS::EC2::SubnetRouteTableAssociation", - "Properties": { - "RouteTableId": { - "Ref": "Vpc2PrivateSubnet2RouteTableB4F37E84" - }, - "SubnetId": { - "Ref": "Vpc2PrivateSubnet2Subnet3BA0F39B" - } - } - }, - "Vpc2PrivateSubnet2DefaultRouteA55B1734": { - "Type": "AWS::EC2::Route", - "Properties": { - "RouteTableId": { - "Ref": "Vpc2PrivateSubnet2RouteTableB4F37E84" - }, - "DestinationCidrBlock": "0.0.0.0/0", - "NatGatewayId": { - "Ref": "Vpc2PublicSubnet2NATGateway6CBF7FA6" - } - } - }, - "Vpc2IGWB10A76EB": { - "Type": "AWS::EC2::InternetGateway", - "Properties": { - "Tags": [ - { - "Key": "Name", - "Value": "aws-ecs-integ/Vpc2" - } - ] - } - }, - "Vpc2VPCGW62C338EF": { - "Type": "AWS::EC2::VPCGatewayAttachment", - "Properties": { - "VpcId": { - "Ref": "Vpc299FDBC5F" - }, - "InternetGatewayId": { - "Ref": "Vpc2IGWB10A76EB" - } - } - }, - "L3bLBB8FADA4E": { - "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", - "Properties": { - "LoadBalancerAttributes": [ - { - "Key": "deletion_protection.enabled", - "Value": "false" - } - ], - "Scheme": "internet-facing", - "SecurityGroups": [ - { - "Fn::GetAtt": [ - "L3bLBSecurityGroup7A2B0AA0", - "GroupId" - ] - } - ], - "Subnets": [ - { - "Ref": "Vpc2PublicSubnet1Subnet758D49A9" - }, - { - "Ref": "Vpc2PublicSubnet2Subnet0BF8C291" - } - ], - "Type": "application" - }, - "DependsOn": [ - "Vpc2PublicSubnet1DefaultRoute64172CA2", - "Vpc2PublicSubnet2DefaultRouteBAB514C1" - ] - }, - "L3bLBSecurityGroup7A2B0AA0": { - "Type": "AWS::EC2::SecurityGroup", - "Properties": { - "GroupDescription": "Automatically created Security Group for ELB awsecsintegL3bLB9C1497A7", - "SecurityGroupIngress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow from anyone on port 80", - "FromPort": 80, - "IpProtocol": "tcp", - "ToPort": 80 - } - ], - "VpcId": { - "Ref": "Vpc299FDBC5F" - } - } - }, - "L3bLBSecurityGrouptoawsecsintegL3bServiceSecurityGroupC2BD1A598019C4C37D": { - "Type": "AWS::EC2::SecurityGroupEgress", - "Properties": { - "GroupId": { - "Fn::GetAtt": [ - "L3bLBSecurityGroup7A2B0AA0", - "GroupId" - ] - }, - "IpProtocol": "tcp", - "Description": "Load balancer to target", - "DestinationSecurityGroupId": { - "Fn::GetAtt": [ - "L3bServiceSecurityGroupA8DA736E", - "GroupId" - ] - }, - "FromPort": 80, - "ToPort": 80 - } - }, - "L3bLBPublicListenerA825925B": { - "Type": "AWS::ElasticLoadBalancingV2::Listener", - "Properties": { - "DefaultActions": [ - { - "TargetGroupArn": { - "Ref": "L3bLBPublicListenerECSGroup0070C5CA" - }, - "Type": "forward" - } - ], - "LoadBalancerArn": { - "Ref": "L3bLBB8FADA4E" - }, - "Port": 80, - "Protocol": "HTTP" - } - }, - "L3bLBPublicListenerECSGroup0070C5CA": { - "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", - "Properties": { - "Port": 80, - "Protocol": "HTTP", - "TargetType": "ip", - "VpcId": { - "Ref": "Vpc299FDBC5F" - } - } - }, - "L3bTaskDefTaskRoleADAB80C8": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "ecs-tasks.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - } - } - }, - "L3bTaskDef5506864D": { - "Type": "AWS::ECS::TaskDefinition", - "Properties": { - "ContainerDefinitions": [ - { - "Essential": true, - "Image": "amazon/amazon-ecs-sample", - "LogConfiguration": { - "LogDriver": "awslogs", - "Options": { - "awslogs-group": { - "Ref": "L3bTaskDefwebLogGroup8E5F1183" - }, - "awslogs-stream-prefix": "L3b", - "awslogs-region": { - "Ref": "AWS::Region" - } - } - }, - "Name": "web", - "PortMappings": [ - { - "ContainerPort": 80, - "Protocol": "tcp" - } - ] - } - ], - "Cpu": "512", - "ExecutionRoleArn": { - "Fn::GetAtt": [ - "L3bTaskDefExecutionRole9A3E2688", - "Arn" - ] - }, - "Family": "awsecsintegL3bTaskDef24D7E4F1", - "Memory": "1024", - "NetworkMode": "awsvpc", - "RequiresCompatibilities": [ - "FARGATE" - ], - "TaskRoleArn": { - "Fn::GetAtt": [ - "L3bTaskDefTaskRoleADAB80C8", - "Arn" - ] - } - } - }, - "L3bTaskDefwebLogGroup8E5F1183": { - "Type": "AWS::Logs::LogGroup", - "UpdateReplacePolicy": "Retain", - "DeletionPolicy": "Retain" - }, - "L3bTaskDefExecutionRole9A3E2688": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "ecs-tasks.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - } - } - }, - "L3bTaskDefExecutionRoleDefaultPolicy0CEA0ED2": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "logs:CreateLogStream", - "logs:PutLogEvents" - ], - "Effect": "Allow", - "Resource": { - "Fn::GetAtt": [ - "L3bTaskDefwebLogGroup8E5F1183", - "Arn" - ] - } - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "L3bTaskDefExecutionRoleDefaultPolicy0CEA0ED2", - "Roles": [ - { - "Ref": "L3bTaskDefExecutionRole9A3E2688" - } - ] - } - }, - "L3bServiceF9D33D5A": { - "Type": "AWS::ECS::Service", - "Properties": { - "Cluster": { - "Ref": "EcsDefaultClusterMnL3mNNYNVpc2B5DB011D" - }, - "DeploymentConfiguration": { - "MaximumPercent": 200, - "MinimumHealthyPercent": 50 - }, - "EnableECSManagedTags": false, - "HealthCheckGracePeriodSeconds": 60, - "LaunchType": "FARGATE", - "LoadBalancers": [ - { - "ContainerName": "web", - "ContainerPort": 80, - "TargetGroupArn": { - "Ref": "L3bLBPublicListenerECSGroup0070C5CA" - } - } - ], - "NetworkConfiguration": { - "AwsvpcConfiguration": { - "AssignPublicIp": "DISABLED", - "SecurityGroups": [ - { - "Fn::GetAtt": [ - "L3bServiceSecurityGroupA8DA736E", - "GroupId" - ] - } - ], - "Subnets": [ - { - "Ref": "Vpc2PrivateSubnet1Subnet34902000" - }, - { - "Ref": "Vpc2PrivateSubnet2Subnet3BA0F39B" - } - ] - } - }, - "TaskDefinition": { - "Ref": "L3bTaskDef5506864D" - } - }, - "DependsOn": [ - "L3bLBPublicListenerECSGroup0070C5CA", - "L3bLBPublicListenerA825925B" - ] - }, - "L3bServiceSecurityGroupA8DA736E": { - "Type": "AWS::EC2::SecurityGroup", - "Properties": { - "GroupDescription": "aws-ecs-integ/L3b/Service/SecurityGroup", - "SecurityGroupEgress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow all outbound traffic by default", - "IpProtocol": "-1" - } - ], - "VpcId": { - "Ref": "Vpc299FDBC5F" - } - } - }, - "L3bServiceSecurityGroupfromawsecsintegL3bLBSecurityGroupA7B79A628034042CE5": { - "Type": "AWS::EC2::SecurityGroupIngress", - "Properties": { - "IpProtocol": "tcp", - "Description": "Load balancer to target", - "FromPort": 80, - "GroupId": { - "Fn::GetAtt": [ - "L3bServiceSecurityGroupA8DA736E", - "GroupId" - ] - }, - "SourceSecurityGroupId": { - "Fn::GetAtt": [ - "L3bLBSecurityGroup7A2B0AA0", - "GroupId" - ] - }, - "ToPort": 80 - } - }, - "EcsDefaultClusterMnL3mNNYNVpc2B5DB011D": { - "Type": "AWS::ECS::Cluster" - }, - "L3cLB041B1E8C": { + "NLBFargateServiceLB659EC17C": { "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", "Properties": { "LoadBalancerAttributes": [ @@ -1340,98 +675,51 @@ } ], "Scheme": "internet-facing", - "SecurityGroups": [ - { - "Fn::GetAtt": [ - "L3cLBSecurityGroup818CBDE1", - "GroupId" - ] - } - ], "Subnets": [ { - "Ref": "Vpc2PublicSubnet1Subnet758D49A9" + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" }, { - "Ref": "Vpc2PublicSubnet2Subnet0BF8C291" + "Ref": "VpcPublicSubnet2Subnet691E08A3" } ], - "Type": "application" + "Type": "network" }, "DependsOn": [ - "Vpc2PublicSubnet1DefaultRoute64172CA2", - "Vpc2PublicSubnet2DefaultRouteBAB514C1" + "VpcPublicSubnet1DefaultRoute3DA9E72A", + "VpcPublicSubnet2DefaultRoute97F91067" ] }, - "L3cLBSecurityGroup818CBDE1": { - "Type": "AWS::EC2::SecurityGroup", - "Properties": { - "GroupDescription": "Automatically created Security Group for ELB awsecsintegL3cLB16505710", - "SecurityGroupIngress": [ - { - "CidrIp": "0.0.0.0/0", - "Description": "Allow from anyone on port 80", - "FromPort": 80, - "IpProtocol": "tcp", - "ToPort": 80 - } - ], - "VpcId": { - "Ref": "Vpc299FDBC5F" - } - } - }, - "L3cLBSecurityGrouptoawsecsintegL3cServiceSecurityGroupA4254E838029E3B246": { - "Type": "AWS::EC2::SecurityGroupEgress", - "Properties": { - "GroupId": { - "Fn::GetAtt": [ - "L3cLBSecurityGroup818CBDE1", - "GroupId" - ] - }, - "IpProtocol": "tcp", - "Description": "Load balancer to target", - "DestinationSecurityGroupId": { - "Fn::GetAtt": [ - "L3cServiceSecurityGroup94AFACED", - "GroupId" - ] - }, - "FromPort": 80, - "ToPort": 80 - } - }, - "L3cLBPublicListener1D4B3F11": { + "NLBFargateServiceLBPublicListenerB0DCA73C": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "Properties": { "DefaultActions": [ { "TargetGroupArn": { - "Ref": "L3cLBPublicListenerECSGroup62D7B705" + "Ref": "NLBFargateServiceLBPublicListenerECSGroupC469CAA2" }, "Type": "forward" } ], "LoadBalancerArn": { - "Ref": "L3cLB041B1E8C" + "Ref": "NLBFargateServiceLB659EC17C" }, "Port": 80, - "Protocol": "HTTP" + "Protocol": "TCP" } }, - "L3cLBPublicListenerECSGroup62D7B705": { + "NLBFargateServiceLBPublicListenerECSGroupC469CAA2": { "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", "Properties": { "Port": 80, - "Protocol": "HTTP", + "Protocol": "TCP", "TargetType": "ip", "VpcId": { - "Ref": "Vpc299FDBC5F" + "Ref": "Vpc8378EB38" } } }, - "L3cTaskDefTaskRole3C3C6124": { + "NLBFargateServiceTaskDefTaskRole6C88F40B": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -1448,7 +736,7 @@ } } }, - "L3cTaskDefA575AF8A": { + "NLBFargateServiceTaskDefB836FA89": { "Type": "AWS::ECS::TaskDefinition", "Properties": { "ContainerDefinitions": [ @@ -1459,9 +747,9 @@ "LogDriver": "awslogs", "Options": { "awslogs-group": { - "Ref": "L3cTaskDefwebLogGroupE4BDEC1B" + "Ref": "NLBFargateServiceTaskDefwebLogGroupC4A42FE2" }, - "awslogs-stream-prefix": "L3c", + "awslogs-stream-prefix": "NLBFargateService", "awslogs-region": { "Ref": "AWS::Region" } @@ -1479,11 +767,11 @@ "Cpu": "512", "ExecutionRoleArn": { "Fn::GetAtt": [ - "L3cTaskDefExecutionRoleF366B4B2", + "NLBFargateServiceTaskDefExecutionRoleF6D642D5", "Arn" ] }, - "Family": "awsecsintegL3cTaskDefF83D4A1D", + "Family": "awsecsintegl3vpconlyNLBFargateServiceTaskDef1E6E41A6", "Memory": "1024", "NetworkMode": "awsvpc", "RequiresCompatibilities": [ @@ -1491,18 +779,18 @@ ], "TaskRoleArn": { "Fn::GetAtt": [ - "L3cTaskDefTaskRole3C3C6124", + "NLBFargateServiceTaskDefTaskRole6C88F40B", "Arn" ] } } }, - "L3cTaskDefwebLogGroupE4BDEC1B": { + "NLBFargateServiceTaskDefwebLogGroupC4A42FE2": { "Type": "AWS::Logs::LogGroup", "UpdateReplacePolicy": "Retain", "DeletionPolicy": "Retain" }, - "L3cTaskDefExecutionRoleF366B4B2": { + "NLBFargateServiceTaskDefExecutionRoleF6D642D5": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -1519,7 +807,7 @@ } } }, - "L3cTaskDefExecutionRoleDefaultPolicy364B8E8C": { + "NLBFargateServiceTaskDefExecutionRoleDefaultPolicy90080805": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { @@ -1532,7 +820,7 @@ "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "L3cTaskDefwebLogGroupE4BDEC1B", + "NLBFargateServiceTaskDefwebLogGroupC4A42FE2", "Arn" ] } @@ -1540,19 +828,19 @@ ], "Version": "2012-10-17" }, - "PolicyName": "L3cTaskDefExecutionRoleDefaultPolicy364B8E8C", + "PolicyName": "NLBFargateServiceTaskDefExecutionRoleDefaultPolicy90080805", "Roles": [ { - "Ref": "L3cTaskDefExecutionRoleF366B4B2" + "Ref": "NLBFargateServiceTaskDefExecutionRoleF6D642D5" } ] } }, - "L3cServiceADA1E573": { + "NLBFargateServiceB92AC095": { "Type": "AWS::ECS::Service", "Properties": { "Cluster": { - "Ref": "EcsDefaultClusterMnL3mNNYNVpc2B5DB011D" + "Ref": "EcsDefaultClusterMnL3mNNYNVpc18E0451A" }, "DeploymentConfiguration": { "MaximumPercent": 200, @@ -1566,7 +854,7 @@ "ContainerName": "web", "ContainerPort": 80, "TargetGroupArn": { - "Ref": "L3cLBPublicListenerECSGroup62D7B705" + "Ref": "NLBFargateServiceLBPublicListenerECSGroupC469CAA2" } } ], @@ -1576,34 +864,34 @@ "SecurityGroups": [ { "Fn::GetAtt": [ - "L3cServiceSecurityGroup94AFACED", + "NLBFargateServiceSecurityGroup9D81388B", "GroupId" ] } ], "Subnets": [ { - "Ref": "Vpc2PrivateSubnet1Subnet34902000" + "Ref": "VpcPrivateSubnet1Subnet536B997A" }, { - "Ref": "Vpc2PrivateSubnet2Subnet3BA0F39B" + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" } ] } }, "TaskDefinition": { - "Ref": "L3cTaskDefA575AF8A" + "Ref": "NLBFargateServiceTaskDefB836FA89" } }, "DependsOn": [ - "L3cLBPublicListenerECSGroup62D7B705", - "L3cLBPublicListener1D4B3F11" + "NLBFargateServiceLBPublicListenerECSGroupC469CAA2", + "NLBFargateServiceLBPublicListenerB0DCA73C" ] }, - "L3cServiceSecurityGroup94AFACED": { + "NLBFargateServiceSecurityGroup9D81388B": { "Type": "AWS::EC2::SecurityGroup", "Properties": { - "GroupDescription": "aws-ecs-integ/L3c/Service/SecurityGroup", + "GroupDescription": "aws-ecs-integ-l3-vpconly/NLBFargateService/Service/SecurityGroup", "SecurityGroupEgress": [ { "CidrIp": "0.0.0.0/0", @@ -1612,66 +900,21 @@ } ], "VpcId": { - "Ref": "Vpc299FDBC5F" + "Ref": "Vpc8378EB38" } } - }, - "L3cServiceSecurityGroupfromawsecsintegL3cLBSecurityGroup7820B0B28070DB6447": { - "Type": "AWS::EC2::SecurityGroupIngress", - "Properties": { - "IpProtocol": "tcp", - "Description": "Load balancer to target", - "FromPort": 80, - "GroupId": { - "Fn::GetAtt": [ - "L3cServiceSecurityGroup94AFACED", - "GroupId" - ] - }, - "SourceSecurityGroupId": { - "Fn::GetAtt": [ - "L3cLBSecurityGroup818CBDE1", - "GroupId" - ] - }, - "ToPort": 80 - } } }, "Outputs": { - "L3LoadBalancerDNSC6CB4A70": { - "Value": { - "Fn::GetAtt": [ - "L3LB212FC0E0", - "DNSName" - ] - } - }, - "L3ServiceURL0F065F2D": { - "Value": { - "Fn::Join": [ - "", - [ - "http://", - { - "Fn::GetAtt": [ - "L3LB212FC0E0", - "DNSName" - ] - } - ] - ] - } - }, - "L3bLoadBalancerDNSED096132": { + "ALBFargateServiceLoadBalancerDNSAFB2EDDB": { "Value": { "Fn::GetAtt": [ - "L3bLBB8FADA4E", + "ALBFargateServiceLB64A0074E", "DNSName" ] } }, - "L3bServiceURL0EDED888": { + "ALBFargateServiceServiceURL4A19CF25": { "Value": { "Fn::Join": [ "", @@ -1679,7 +922,7 @@ "http://", { "Fn::GetAtt": [ - "L3bLBB8FADA4E", + "ALBFargateServiceLB64A0074E", "DNSName" ] } @@ -1687,29 +930,13 @@ ] } }, - "L3cLoadBalancerDNS9409202E": { + "NLBFargateServiceLoadBalancerDNSC2B2922F": { "Value": { "Fn::GetAtt": [ - "L3cLB041B1E8C", + "NLBFargateServiceLB659EC17C", "DNSName" ] } - }, - "L3cServiceURL2E1758C7": { - "Value": { - "Fn::Join": [ - "", - [ - "http://", - { - "Fn::GetAtt": [ - "L3cLB041B1E8C", - "DNSName" - ] - } - ] - ] - } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-vpconly.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-vpconly.ts index e3e7fedceda97..f0f76f754639e 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-vpconly.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3-vpconly.ts @@ -4,21 +4,14 @@ import * as cdk from '@aws-cdk/core'; import * as ecsPatterns from '../../lib'; const app = new cdk.App(); -const stack = new cdk.Stack(app, 'aws-ecs-integ'); +const stack = new cdk.Stack(app, 'aws-ecs-integ-l3-vpconly'); +// Create VPC only const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 2 }); -new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'L3', { - vpc, - memoryLimitMiB: 1024, - cpu: 512, - taskImageOptions: { - image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), - }, -}); -const vpc2 = new ec2.Vpc(stack, 'Vpc2', { maxAzs: 2 }); -new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'L3b', { - vpc: vpc2, +// Create ALB service +new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'ALBFargateService', { + vpc, memoryLimitMiB: 1024, cpu: 512, taskImageOptions: { @@ -26,8 +19,9 @@ new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'L3b', { }, }); -new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'L3c', { - vpc: vpc2, +// Create NLB service +new ecsPatterns.NetworkLoadBalancedFargateService(stack, 'NLBFargateService', { + vpc, memoryLimitMiB: 1024, cpu: 512, taskImageOptions: { diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.expected.json index 40d86be5d331b..efd340e79b5cf 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.expected.json +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.expected.json @@ -10,7 +10,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc" + "Value": "aws-ecs-integ-lb-fargate/Vpc" } ] } @@ -35,7 +35,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1" } ] } @@ -49,7 +49,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1" } ] } @@ -87,7 +87,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1" } ] } @@ -107,7 +107,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet1" + "Value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet1" } ] } @@ -132,7 +132,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2" } ] } @@ -146,7 +146,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2" } ] } @@ -184,7 +184,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2" } ] } @@ -204,7 +204,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PublicSubnet2" + "Value": "aws-ecs-integ-lb-fargate/Vpc/PublicSubnet2" } ] } @@ -229,7 +229,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PrivateSubnet1" + "Value": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1" } ] } @@ -243,7 +243,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PrivateSubnet1" + "Value": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet1" } ] } @@ -291,7 +291,7 @@ }, { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PrivateSubnet2" + "Value": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2" } ] } @@ -305,7 +305,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc/PrivateSubnet2" + "Value": "aws-ecs-integ-lb-fargate/Vpc/PrivateSubnet2" } ] } @@ -339,7 +339,7 @@ "Tags": [ { "Key": "Name", - "Value": "aws-ecs-integ/Vpc" + "Value": "aws-ecs-integ-lb-fargate/Vpc" } ] } @@ -358,7 +358,7 @@ "FargateCluster7CCD5F93": { "Type": "AWS::ECS::Cluster" }, - "L3LB212FC0E0": { + "ALBFargateServiceLB64A0074E": { "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", "Properties": { "LoadBalancerAttributes": [ @@ -371,7 +371,7 @@ "SecurityGroups": [ { "Fn::GetAtt": [ - "L3LBSecurityGroupEDE61198", + "ALBFargateServiceLBSecurityGroup5DC3060E", "GroupId" ] } @@ -391,10 +391,10 @@ "VpcPublicSubnet2DefaultRoute97F91067" ] }, - "L3LBSecurityGroupEDE61198": { + "ALBFargateServiceLBSecurityGroup5DC3060E": { "Type": "AWS::EC2::SecurityGroup", "Properties": { - "GroupDescription": "Automatically created Security Group for ELB awsecsintegL3LB6453BA0A", + "GroupDescription": "Automatically created Security Group for ELB awsecsinteglbfargateALBFargateServiceLBF93E98F2", "SecurityGroupIngress": [ { "CidrIp": "0.0.0.0/0", @@ -409,12 +409,12 @@ } } }, - "L3LBSecurityGrouptoawsecsintegL3ServiceSecurityGroup7B96C87F8094933E0A": { + "ALBFargateServiceLBSecurityGrouptoawsecsinteglbfargateALBFargateServiceSecurityGroup0D9B5AEB80C5CFCE6C": { "Type": "AWS::EC2::SecurityGroupEgress", "Properties": { "GroupId": { "Fn::GetAtt": [ - "L3LBSecurityGroupEDE61198", + "ALBFargateServiceLBSecurityGroup5DC3060E", "GroupId" ] }, @@ -422,7 +422,7 @@ "Description": "Load balancer to target", "DestinationSecurityGroupId": { "Fn::GetAtt": [ - "L3ServiceSecurityGroup677B0897", + "ALBFargateServiceSecurityGroup82F7A67E", "GroupId" ] }, @@ -430,25 +430,25 @@ "ToPort": 80 } }, - "L3LBPublicListener156FFC0F": { + "ALBFargateServiceLBPublicListener3489002A": { "Type": "AWS::ElasticLoadBalancingV2::Listener", "Properties": { "DefaultActions": [ { "TargetGroupArn": { - "Ref": "L3LBPublicListenerECSGroup648EEA11" + "Ref": "ALBFargateServiceLBPublicListenerECSGroup6871FB8C" }, "Type": "forward" } ], "LoadBalancerArn": { - "Ref": "L3LB212FC0E0" + "Ref": "ALBFargateServiceLB64A0074E" }, "Port": 80, "Protocol": "HTTP" } }, - "L3LBPublicListenerECSGroup648EEA11": { + "ALBFargateServiceLBPublicListenerECSGroup6871FB8C": { "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", "Properties": { "Port": 80, @@ -459,7 +459,7 @@ } } }, - "L3TaskDefTaskRole21C75D10": { + "ALBFargateServiceTaskDefTaskRole11408723": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -476,7 +476,7 @@ } } }, - "L3TaskDef48D8ACB8": { + "ALBFargateServiceTaskDefF69F17D6": { "Type": "AWS::ECS::TaskDefinition", "Properties": { "ContainerDefinitions": [ @@ -487,9 +487,9 @@ "LogDriver": "awslogs", "Options": { "awslogs-group": { - "Ref": "L3TaskDefwebLogGroupC6E4A38A" + "Ref": "ALBFargateServiceTaskDefwebLogGroup7073A41D" }, - "awslogs-stream-prefix": "L3", + "awslogs-stream-prefix": "ALBFargateService", "awslogs-region": { "Ref": "AWS::Region" } @@ -507,11 +507,11 @@ "Cpu": "512", "ExecutionRoleArn": { "Fn::GetAtt": [ - "L3TaskDefExecutionRole49AF0996", + "ALBFargateServiceTaskDefExecutionRole9E885E7B", "Arn" ] }, - "Family": "awsecsintegL3TaskDefAA25240E", + "Family": "awsecsinteglbfargateALBFargateServiceTaskDef26FE75C0", "Memory": "1024", "NetworkMode": "awsvpc", "RequiresCompatibilities": [ @@ -519,18 +519,18 @@ ], "TaskRoleArn": { "Fn::GetAtt": [ - "L3TaskDefTaskRole21C75D10", + "ALBFargateServiceTaskDefTaskRole11408723", "Arn" ] } } }, - "L3TaskDefwebLogGroupC6E4A38A": { + "ALBFargateServiceTaskDefwebLogGroup7073A41D": { "Type": "AWS::Logs::LogGroup", "UpdateReplacePolicy": "Retain", "DeletionPolicy": "Retain" }, - "L3TaskDefExecutionRole49AF0996": { + "ALBFargateServiceTaskDefExecutionRole9E885E7B": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { @@ -547,7 +547,7 @@ } } }, - "L3TaskDefExecutionRoleDefaultPolicy4656E642": { + "ALBFargateServiceTaskDefExecutionRoleDefaultPolicy574B9EAD": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyDocument": { @@ -560,7 +560,7 @@ "Effect": "Allow", "Resource": { "Fn::GetAtt": [ - "L3TaskDefwebLogGroupC6E4A38A", + "ALBFargateServiceTaskDefwebLogGroup7073A41D", "Arn" ] } @@ -568,15 +568,15 @@ ], "Version": "2012-10-17" }, - "PolicyName": "L3TaskDefExecutionRoleDefaultPolicy4656E642", + "PolicyName": "ALBFargateServiceTaskDefExecutionRoleDefaultPolicy574B9EAD", "Roles": [ { - "Ref": "L3TaskDefExecutionRole49AF0996" + "Ref": "ALBFargateServiceTaskDefExecutionRole9E885E7B" } ] } }, - "L3Service616D5A93": { + "ALBFargateService90FDCE10": { "Type": "AWS::ECS::Service", "Properties": { "Cluster": { @@ -594,7 +594,7 @@ "ContainerName": "web", "ContainerPort": 80, "TargetGroupArn": { - "Ref": "L3LBPublicListenerECSGroup648EEA11" + "Ref": "ALBFargateServiceLBPublicListenerECSGroup6871FB8C" } } ], @@ -604,7 +604,7 @@ "SecurityGroups": [ { "Fn::GetAtt": [ - "L3ServiceSecurityGroup677B0897", + "ALBFargateServiceSecurityGroup82F7A67E", "GroupId" ] } @@ -620,18 +620,18 @@ } }, "TaskDefinition": { - "Ref": "L3TaskDef48D8ACB8" + "Ref": "ALBFargateServiceTaskDefF69F17D6" } }, "DependsOn": [ - "L3LBPublicListenerECSGroup648EEA11", - "L3LBPublicListener156FFC0F" + "ALBFargateServiceLBPublicListenerECSGroup6871FB8C", + "ALBFargateServiceLBPublicListener3489002A" ] }, - "L3ServiceSecurityGroup677B0897": { + "ALBFargateServiceSecurityGroup82F7A67E": { "Type": "AWS::EC2::SecurityGroup", "Properties": { - "GroupDescription": "aws-ecs-integ/L3/Service/SecurityGroup", + "GroupDescription": "aws-ecs-integ-lb-fargate/ALBFargateService/Service/SecurityGroup", "SecurityGroupEgress": [ { "CidrIp": "0.0.0.0/0", @@ -644,7 +644,7 @@ } } }, - "L3ServiceSecurityGroupfromawsecsintegL3LBSecurityGroupA70DA46C80DBDFBCD6": { + "ALBFargateServiceSecurityGroupfromawsecsinteglbfargateALBFargateServiceLBSecurityGroupCD911D2880462ECC11": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "IpProtocol": "tcp", @@ -652,30 +652,269 @@ "FromPort": 80, "GroupId": { "Fn::GetAtt": [ - "L3ServiceSecurityGroup677B0897", + "ALBFargateServiceSecurityGroup82F7A67E", "GroupId" ] }, "SourceSecurityGroupId": { "Fn::GetAtt": [ - "L3LBSecurityGroupEDE61198", + "ALBFargateServiceLBSecurityGroup5DC3060E", "GroupId" ] }, "ToPort": 80 } + }, + "NLBFargateServiceLB659EC17C": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "LoadBalancerAttributes": [ + { + "Key": "deletion_protection.enabled", + "Value": "false" + } + ], + "Scheme": "internet-facing", + "Subnets": [ + { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + ], + "Type": "network" + }, + "DependsOn": [ + "VpcPublicSubnet1DefaultRoute3DA9E72A", + "VpcPublicSubnet2DefaultRoute97F91067" + ] + }, + "NLBFargateServiceLBPublicListenerB0DCA73C": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "NLBFargateServiceLBPublicListenerECSGroupC469CAA2" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "NLBFargateServiceLB659EC17C" + }, + "Port": 80, + "Protocol": "TCP" + } + }, + "NLBFargateServiceLBPublicListenerECSGroupC469CAA2": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "Port": 80, + "Protocol": "TCP", + "TargetType": "ip", + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "NLBFargateServiceTaskDefTaskRole6C88F40B": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "NLBFargateServiceTaskDefB836FA89": { + "Type": "AWS::ECS::TaskDefinition", + "Properties": { + "ContainerDefinitions": [ + { + "Essential": true, + "Image": "amazon/amazon-ecs-sample", + "LogConfiguration": { + "LogDriver": "awslogs", + "Options": { + "awslogs-group": { + "Ref": "NLBFargateServiceTaskDefwebLogGroupC4A42FE2" + }, + "awslogs-stream-prefix": "NLBFargateService", + "awslogs-region": { + "Ref": "AWS::Region" + } + } + }, + "Name": "web", + "PortMappings": [ + { + "ContainerPort": 80, + "Protocol": "tcp" + } + ] + } + ], + "Cpu": "512", + "ExecutionRoleArn": { + "Fn::GetAtt": [ + "NLBFargateServiceTaskDefExecutionRoleF6D642D5", + "Arn" + ] + }, + "Family": "awsecsinteglbfargateNLBFargateServiceTaskDef1265FF34", + "Memory": "1024", + "NetworkMode": "awsvpc", + "RequiresCompatibilities": [ + "FARGATE" + ], + "TaskRoleArn": { + "Fn::GetAtt": [ + "NLBFargateServiceTaskDefTaskRole6C88F40B", + "Arn" + ] + } + } + }, + "NLBFargateServiceTaskDefwebLogGroupC4A42FE2": { + "Type": "AWS::Logs::LogGroup", + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "NLBFargateServiceTaskDefExecutionRoleF6D642D5": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "NLBFargateServiceTaskDefExecutionRoleDefaultPolicy90080805": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "NLBFargateServiceTaskDefwebLogGroupC4A42FE2", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "NLBFargateServiceTaskDefExecutionRoleDefaultPolicy90080805", + "Roles": [ + { + "Ref": "NLBFargateServiceTaskDefExecutionRoleF6D642D5" + } + ] + } + }, + "NLBFargateServiceB92AC095": { + "Type": "AWS::ECS::Service", + "Properties": { + "Cluster": { + "Ref": "FargateCluster7CCD5F93" + }, + "DeploymentConfiguration": { + "MaximumPercent": 200, + "MinimumHealthyPercent": 50 + }, + "EnableECSManagedTags": false, + "HealthCheckGracePeriodSeconds": 60, + "LaunchType": "FARGATE", + "LoadBalancers": [ + { + "ContainerName": "web", + "ContainerPort": 80, + "TargetGroupArn": { + "Ref": "NLBFargateServiceLBPublicListenerECSGroupC469CAA2" + } + } + ], + "NetworkConfiguration": { + "AwsvpcConfiguration": { + "AssignPublicIp": "DISABLED", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "NLBFargateServiceSecurityGroup9D81388B", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + }, + { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + } + ] + } + }, + "TaskDefinition": { + "Ref": "NLBFargateServiceTaskDefB836FA89" + } + }, + "DependsOn": [ + "NLBFargateServiceLBPublicListenerECSGroupC469CAA2", + "NLBFargateServiceLBPublicListenerB0DCA73C" + ] + }, + "NLBFargateServiceSecurityGroup9D81388B": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-ecs-integ-lb-fargate/NLBFargateService/Service/SecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } } }, "Outputs": { - "L3LoadBalancerDNSC6CB4A70": { + "ALBFargateServiceLoadBalancerDNSAFB2EDDB": { "Value": { "Fn::GetAtt": [ - "L3LB212FC0E0", + "ALBFargateServiceLB64A0074E", "DNSName" ] } }, - "L3ServiceURL0F065F2D": { + "ALBFargateServiceServiceURL4A19CF25": { "Value": { "Fn::Join": [ "", @@ -683,13 +922,21 @@ "http://", { "Fn::GetAtt": [ - "L3LB212FC0E0", + "ALBFargateServiceLB64A0074E", "DNSName" ] } ] ] } + }, + "NLBFargateServiceLoadBalancerDNSC2B2922F": { + "Value": { + "Fn::GetAtt": [ + "NLBFargateServiceLB659EC17C", + "DNSName" + ] + } } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.ts b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.ts index 5819bb3955190..b7cca5925e67c 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.ts +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.l3.ts @@ -4,13 +4,24 @@ import * as cdk from '@aws-cdk/core'; import * as ecsPatterns from '../../lib'; const app = new cdk.App(); -const stack = new cdk.Stack(app, 'aws-ecs-integ'); +const stack = new cdk.Stack(app, 'aws-ecs-integ-lb-fargate'); +// Create VPC and cluster const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 2 }); - const cluster = new ecs.Cluster(stack, 'FargateCluster', { vpc }); -new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'L3', { +// Create ALB service +new ecsPatterns.ApplicationLoadBalancedFargateService(stack, 'ALBFargateService', { + cluster, + memoryLimitMiB: 1024, + cpu: 512, + taskImageOptions: { + image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), + }, +}); + +// Create NLB service +new ecsPatterns.NetworkLoadBalancedFargateService(stack, 'NLBFargateService', { cluster, memoryLimitMiB: 1024, cpu: 512, diff --git a/packages/@aws-cdk/aws-ecs/README.md b/packages/@aws-cdk/aws-ecs/README.md index 7f0338ed3ff18..5e63747de137f 100644 --- a/packages/@aws-cdk/aws-ecs/README.md +++ b/packages/@aws-cdk/aws-ecs/README.md @@ -14,16 +14,13 @@ This package contains constructs for working with **Amazon Elastic Container Service** (Amazon ECS). -Amazon ECS is a highly scalable, fast, container management service -that makes it easy to run, stop, -and manage Docker containers on a cluster of Amazon EC2 instances. +Amazon Elastic Container Service (Amazon ECS) is a fully managed container orchestration service. For further information on Amazon ECS, see the [Amazon ECS documentation](https://docs.aws.amazon.com/ecs) -The following example creates an Amazon ECS cluster, -adds capacity to it, -and instantiates the Amazon ECS Service with an automatic load balancer. +The following example creates an Amazon ECS cluster, adds capacity to it, and +runs a service on it: ```ts import * as ecs from '@aws-cdk/aws-ecs'; @@ -496,38 +493,6 @@ scaling.scaleOnRequestCount('RequestScaling', { Task auto-scaling is powered by *Application Auto-Scaling*. See that section for details. -## Instance Auto-Scaling - -If you're running on AWS Fargate, AWS manages the physical machines that your -containers are running on for you. If you're running an Amazon ECS cluster however, -your Amazon EC2 instances might fill up as your number of Tasks goes up. - -To avoid placement errors, configure auto-scaling for your -Amazon EC2 instance group so that your instance count scales with demand. To keep -your Amazon EC2 instances halfway loaded, scaling up to a maximum of 30 instances -if required: - -```ts -const autoScalingGroup = cluster.addCapacity('DefaultAutoScalingGroup', { - instanceType: new ec2.InstanceType("t2.xlarge"), - minCapacity: 3, - maxCapacity: 30, - desiredCapacity: 3, - - // Give instances 5 minutes to drain running tasks when an instance is - // terminated. This is the default, turn this off by specifying 0 or - // change the timeout up to 900 seconds. - taskDrainTime: Duration.seconds(300) -}); - -autoScalingGroup.scaleOnCpuUtilization('KeepCpuHalfwayLoaded', { - targetUtilizationPercent: 50 -}); -``` - -See the `@aws-cdk/aws-autoscaling` library for more autoscaling options -you can configure on your instances. - ## Integration with CloudWatch Events To start an Amazon ECS task on an Amazon EC2-backed Cluster, instantiate an @@ -760,25 +725,24 @@ ecsService.associateCloudMapService({ ## Capacity Providers -Currently, only `FARGATE` and `FARGATE_SPOT` capacity providers are supported. - -To enable capacity providers on your cluster, set the `capacityProviders` field -to [`FARGATE`, `FARGATE_SPOT`]. Then, specify capacity provider strategies on -the `capacityProviderStrategies` field for your Fargate Service. - -```ts -import * as cdk from '@aws-cdk/core'; -import * as ec2 from '@aws-cdk/aws-ec2'; -import * as ecs from '../../lib'; +There are two major families of Capacity Providers: [AWS +Fargate](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/fargate-capacity-providers.html) +(including Fargate Spot) and EC2 [Auto Scaling +Group](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/asg-capacity-providers.html) +Capacity Providers. Both are supported. -const app = new cdk.App(); -const stack = new cdk.Stack(app, 'aws-ecs-integ-capacity-provider'); +### Fargate Capacity Providers -const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 2 }); +To enable Fargate capacity providers, you can either set +`enableFargateCapacityProviders` to `true` when creating your cluster, or by +invoking the `enableFargateCapacityProviders()` method after creating your +cluster. This will add both `FARGATE` and `FARGATE_SPOT` as available capacity +providers on your cluster. +```ts const cluster = new ecs.Cluster(stack, 'FargateCPCluster', { vpc, - capacityProviders: ['FARGATE', 'FARGATE_SPOT'], + enableFargateCapacityProviders: true, }); const taskDefinition = new ecs.FargateTaskDefinition(stack, 'TaskDef'); @@ -801,8 +765,57 @@ new ecs.FargateService(stack, 'FargateService', { } ], }); +``` + +### Auto Scaling Group Capacity Providers + +To add an Auto Scaling Group Capacity Provider, first create an EC2 Auto Scaling +Group. Then, create an `AsgCapacityProvider` and pass the Auto Scaling Group to +it in the constructor. Then add the Capacity Provider to the cluster. Finally, +you can refer to the Provider by its name in your service's or task's Capacity +Provider strategy. + +By default, an Auto Scaling Group Capacity Provider will manage the Auto Scaling +Group's size for you. It will also enable managed termination protection, in +order to prevent EC2 Auto Scaling from terminating EC2 instances that have tasks +running on them. If you want to disable this behavior, set both +`enableManagedScaling` to and `enableManagedTerminationProtection` to `false`. -app.synth(); +```ts +const cluster = new ecs.Cluster(stack, 'Cluster', { + vpc, +}); + +const autoScalingGroup = new autoscaling.AutoScalingGroup(stack, 'ASG', { + vpc, + instanceType: new ec2.InstanceType('t2.micro'), + machineImage: ecs.EcsOptimizedImage.amazonLinux2(), + minCapacity: 0, + maxCapacity: 100, +}); + +const capacityProvider = new ecs.AsgCapacityProvider(stack, 'AsgCapacityProvider', { + autoScalingGroup, +}); +cluster.addAsgCapacityProvider(capacityProvider); + +const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); + +taskDefinition.addContainer('web', { + image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample', + memoryReservationMiB: 256, +}); + +new ecs.Ec2Service(stack, 'EC2Service', { + cluster, + taskDefinition, + capacityProviderStrategies: [ + { + capacityProvider: capacityProvider.capacityProviderName, + weight: 1, + } + ], +}); ``` ## Elastic Inference Accelerators @@ -810,7 +823,7 @@ app.synth(); Currently, this feature is only supported for services with EC2 launch types. To add elastic inference accelerators to your EC2 instance, first add -`inferenceAccelerators` field to the EC2TaskDefinition and set the `deviceName` +`inferenceAccelerators` field to the Ec2TaskDefinition and set the `deviceName` and `deviceType` properties. ```ts diff --git a/packages/@aws-cdk/aws-ecs/lib/base/base-service.ts b/packages/@aws-cdk/aws-ecs/lib/base/base-service.ts index e51756cf7fa91..8d46952bf1baa 100644 --- a/packages/@aws-cdk/aws-ecs/lib/base/base-service.ts +++ b/packages/@aws-cdk/aws-ecs/lib/base/base-service.ts @@ -415,6 +415,8 @@ export abstract class BaseService extends Resource if (props.cloudMapOptions) { this.enableCloudMap(props.cloudMapOptions); } + + this.node.defaultChild = this.resource; } /** diff --git a/packages/@aws-cdk/aws-ecs/lib/cluster.ts b/packages/@aws-cdk/aws-ecs/lib/cluster.ts index a65efaa83e17e..294a88fcb1858 100644 --- a/packages/@aws-cdk/aws-ecs/lib/cluster.ts +++ b/packages/@aws-cdk/aws-ecs/lib/cluster.ts @@ -5,11 +5,11 @@ import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; import * as cloudmap from '@aws-cdk/aws-servicediscovery'; import * as ssm from '@aws-cdk/aws-ssm'; -import { Duration, Lazy, IResource, Resource, Stack } from '@aws-cdk/core'; +import { Duration, Lazy, IResource, Resource, Stack, Aspects, IAspect, IConstruct } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { InstanceDrainHook } from './drain-hook/instance-drain-hook'; import { ECSMetrics } from './ecs-canned-metrics.generated'; -import { CfnCluster } from './ecs.generated'; +import { CfnCluster, CfnCapacityProvider, CfnClusterCapacityProviderAssociations } from './ecs.generated'; // v2 - keep this import as a separate section to reduce merge conflict when forward merging with the v2 branch. // eslint-disable-next-line @@ -52,9 +52,17 @@ export interface ClusterProps { * The capacity providers to add to the cluster * * @default - None. Currently only FARGATE and FARGATE_SPOT are supported. + * @deprecated Use {@link ClusterProps.enableFargateCapacityProviders} instead. */ readonly capacityProviders?: string[]; + /** + * Whether to enable Fargate Capacity Providers + * + * @default false + */ + readonly enableFargateCapacityProviders?: boolean; + /** * If true CloudWatch Container Insights will be enabled for the cluster * @@ -109,11 +117,14 @@ export class Cluster extends Resource implements ICluster { public readonly clusterName: string; /** - * The capacity providers associated with the cluster. - * - * Currently only FARGATE and FARGATE_SPOT are supported. + * The cluster-level (FARGATE, FARGATE_SPOT) capacity providers. */ - private _capacityProviders: string[] = []; + private _fargateCapacityProviders: string[] = []; + + /** + * The EC2 Auto Scaling Group capacity providers associated with the cluster. + */ + private _asgCapacityProviders: AsgCapacityProvider[] = []; /** * The AWS Cloud Map namespace to associate with the cluster. @@ -148,12 +159,15 @@ export class Cluster extends Resource implements ICluster { clusterSettings = [{ name: 'containerInsights', value: props.containerInsights ? ContainerInsights.ENABLED : ContainerInsights.DISABLED }]; } - this._capacityProviders = props.capacityProviders ?? []; + this._fargateCapacityProviders = props.capacityProviders ?? []; + if (props.enableFargateCapacityProviders) { + this.enableFargateCapacityProviders(); + } const cluster = new CfnCluster(this, 'Resource', { clusterName: this.physicalName, clusterSettings, - capacityProviders: Lazy.list({ produce: () => this._capacityProviders }, { omitEmpty: true }), + capacityProviders: Lazy.list({ produce: () => this._fargateCapacityProviders }, { omitEmpty: true }), }); this.clusterArn = this.getResourceArnAttribute(cluster.attrArn, { @@ -173,6 +187,24 @@ export class Cluster extends Resource implements ICluster { this._autoscalingGroup = props.capacity !== undefined ? this.addCapacity('DefaultAutoScalingGroup', props.capacity) : undefined; + + // Only create cluster capacity provider associations if there are any EC2 + // capacity providers. Ordinarily we'd just add the construct to the tree + // since it's harmless, but we'd prefer not to add unexpected new + // resources to the stack which could surprise users working with + // brown-field CDK apps and stacks. + Aspects.of(this).add(new MaybeCreateCapacityProviderAssociations(this, id, this._asgCapacityProviders)); + } + + /** + * Enable the Fargate capacity providers for this cluster. + */ + public enableFargateCapacityProviders() { + for (const provider of ['FARGATE', 'FARGATE_SPOT']) { + if (!this._fargateCapacityProviders.includes(provider)) { + this._fargateCapacityProviders.push(provider); + } + } } /** @@ -214,6 +246,8 @@ export class Cluster extends Resource implements ICluster { * This method adds compute capacity to a cluster by creating an AutoScalingGroup with the specified options. * * Returns the AutoScalingGroup so you can add autoscaling settings to it. + * + * @deprecated Use {@link Cluster.addAsgCapacityProvider} instead. */ public addCapacity(id: string, options: AddCapacityOptions): autoscaling.AutoScalingGroup { if (options.machineImage && options.machineImageType) { @@ -238,9 +272,31 @@ export class Cluster extends Resource implements ICluster { return autoScalingGroup; } + /** + * This method adds an Auto Scaling Group Capacity Provider to a cluster. + * + * @param provider the capacity provider to add to this cluster. + */ + public addAsgCapacityProvider(provider: AsgCapacityProvider, options: AddAutoScalingGroupCapacityOptions = {}) { + // Don't add the same capacity provider more than once. + if (this._asgCapacityProviders.includes(provider)) { + return; + } + + this._hasEc2Capacity = true; + this.configureAutoScalingGroup(provider.autoScalingGroup, { + ...options, + // Don't enable the instance-draining lifecycle hook if managed termination protection is enabled + taskDrainTime: provider.enableManagedTerminationProtection ? Duration.seconds(0) : options.taskDrainTime, + }); + + this._asgCapacityProviders.push(provider); + } + /** * This method adds compute capacity to a cluster using the specified AutoScalingGroup. * + * @deprecated Use {@link Cluster.addAsgCapacityProvider} instead. * @param autoScalingGroup the ASG to add to this cluster. * [disable-awslint:ref-via-interface] is needed in order to install the ECS * agent by updating the ASGs user data. @@ -248,8 +304,11 @@ export class Cluster extends Resource implements ICluster { public addAutoScalingGroup(autoScalingGroup: autoscaling.AutoScalingGroup, options: AddAutoScalingGroupCapacityOptions = {}) { this._hasEc2Capacity = true; this.connections.connections.addSecurityGroup(...autoScalingGroup.connections.securityGroups); + this.configureAutoScalingGroup(autoScalingGroup, options); + } - if ( autoScalingGroup.osType === ec2.OperatingSystemType.WINDOWS ) { + private configureAutoScalingGroup(autoScalingGroup: autoscaling.AutoScalingGroup, options: AddAutoScalingGroupCapacityOptions = {}) { + if (autoScalingGroup.osType === ec2.OperatingSystemType.WINDOWS) { this.configureWindowsAutoScalingGroup(autoScalingGroup, options); } else { // Tie instances to cluster @@ -342,17 +401,19 @@ export class Cluster extends Resource implements ICluster { } /** - * addCapacityProvider adds the name of a capacityProvider to the list of supproted capacityProviders for a cluster. + * This method enables the Fargate or Fargate Spot capacity providers on the cluster. * * @param provider the capacity provider to add to this cluster. + * @deprecated Use {@link enableFargateCapacityProviders} instead. + * @see {@link addAsgCapacityProvider} to add an Auto Scaling Group capacity provider to the cluster. */ public addCapacityProvider(provider: string) { if (!(provider === 'FARGATE' || provider === 'FARGATE_SPOT')) { throw new Error('CapacityProvider not supported'); } - if (!this._capacityProviders.includes(provider)) { - this._capacityProviders.push(provider); + if (!this._fargateCapacityProviders.includes(provider)) { + this._fargateCapacityProviders.push(provider); } } @@ -859,6 +920,7 @@ export interface AddAutoScalingGroupCapacityOptions { * * Set to 0 to disable task draining. * + * @deprecated The lifecycle draining hook is not configured if using the EC2 Capacity Provider. Enable managed termination protection instead. * @default Duration.minutes(5) */ readonly taskDrainTime?: Duration; @@ -975,7 +1037,7 @@ enum ContainerInsights { */ export interface CapacityProviderStrategy { /** - * The name of the Capacity Provider. Currently only FARGATE and FARGATE_SPOT are supported. + * The name of the capacity provider. */ readonly capacityProvider: string; @@ -997,3 +1059,137 @@ capacity provider. The weight value is taken into consideration after the base v */ readonly weight?: number; } + +/** + * The options for creating an Auto Scaling Group Capacity Provider. + */ +export interface AsgCapacityProviderProps extends AddAutoScalingGroupCapacityOptions { + /** + * The name for the capacity provider. + * + * @default CloudFormation-generated name + */ + readonly capacityProviderName?: string; + + /** + * The autoscaling group to add as a Capacity Provider. + */ + readonly autoScalingGroup: autoscaling.IAutoScalingGroup; + + /** + * Whether to enable managed scaling + * + * @default true + */ + readonly enableManagedScaling?: boolean; + + /** + * Whether to enable managed termination protection + * + * @default true + */ + readonly enableManagedTerminationProtection?: boolean; + + /** + * Maximum scaling step size. In most cases this should be left alone. + * + * @default 1000 + */ + readonly maximumScalingStepSize?: number; + + /** + * Minimum scaling step size. In most cases this should be left alone. + * + * @default 1 + */ + readonly minimumScalingStepSize?: number; + + /** + * Target capacity percent. In most cases this should be left alone. + * + * @default 100 + */ + readonly targetCapacityPercent?: number; +} + +/** + * An Auto Scaling Group Capacity Provider. This allows an ECS cluster to target + * a specific EC2 Auto Scaling Group for the placement of tasks. Optionally (and + * recommended), ECS can manage the number of instances in the ASG to fit the + * tasks, and can ensure that instances are not prematurely terminated while + * there are still tasks running on them. + */ +export class AsgCapacityProvider extends CoreConstruct { + /** + * Capacity provider name + * @default Chosen by CloudFormation + */ + readonly capacityProviderName: string; + + /** + * Auto Scaling Group + */ + readonly autoScalingGroup: autoscaling.AutoScalingGroup; + + /** + * Whether managed termination protection is enabled + */ + readonly enableManagedTerminationProtection?: boolean; + + constructor(scope: Construct, id: string, props: AsgCapacityProviderProps) { + super(scope, id); + + this.autoScalingGroup = props.autoScalingGroup as autoscaling.AutoScalingGroup; + + this.enableManagedTerminationProtection = + props.enableManagedTerminationProtection === undefined ? true : props.enableManagedTerminationProtection; + + if (this.enableManagedTerminationProtection) { + this.autoScalingGroup.protectNewInstancesFromScaleIn(); + } + + const capacityProvider = new CfnCapacityProvider(this, id, { + name: props.capacityProviderName, + autoScalingGroupProvider: { + autoScalingGroupArn: this.autoScalingGroup.autoScalingGroupName, + managedScaling: props.enableManagedScaling === false ? undefined : { + status: 'ENABLED', + targetCapacity: props.targetCapacityPercent || 100, + maximumScalingStepSize: props.maximumScalingStepSize, + minimumScalingStepSize: props.minimumScalingStepSize, + }, + managedTerminationProtection: this.enableManagedTerminationProtection ? 'ENABLED' : 'DISABLED', + }, + }); + + this.capacityProviderName = capacityProvider.ref; + } +} + +/** + * A visitor that adds a capacity provider association to a Cluster only if + * the caller created any EC2 Capacity Providers. + */ +class MaybeCreateCapacityProviderAssociations implements IAspect { + private scope: CoreConstruct; + private id: string; + private capacityProviders: AsgCapacityProvider[] + + constructor(scope: CoreConstruct, id: string, capacityProviders: AsgCapacityProvider[]) { + this.scope = scope; + this.id = id; + this.capacityProviders = capacityProviders; + } + public visit(node: IConstruct): void { + if (node instanceof Cluster) { + const providers = this.capacityProviders.map(p => p.capacityProviderName).filter(p => p !== 'FARGATE' && p !== 'FARGATE_SPOT'); + if (providers.length > 0) { + new CfnClusterCapacityProviderAssociations(this.scope, this.id, { + cluster: node.clusterName, + defaultCapacityProviderStrategy: [], + capacityProviders: Lazy.list({ produce: () => providers }), + }); + } + } + } +} diff --git a/packages/@aws-cdk/aws-ecs/test/cluster.test.ts b/packages/@aws-cdk/aws-ecs/test/cluster.test.ts index 713338284e57b..a76c98377c1db 100644 --- a/packages/@aws-cdk/aws-ecs/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-ecs/test/cluster.test.ts @@ -4,7 +4,9 @@ import { haveResource, haveResourceLike, ResourcePart, + ABSENT, } from '@aws-cdk/assert-internal'; +import * as autoscaling from '@aws-cdk/aws-autoscaling'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as kms from '@aws-cdk/aws-kms'; import * as cloudmap from '@aws-cdk/aws-servicediscovery'; @@ -1695,7 +1697,7 @@ nodeunitShim({ test.done(); }, - 'allows specifying capacityProviders'(test: Test) { + 'allows specifying capacityProviders (deprecated)'(test: Test) { // GIVEN const app = new cdk.App(); const stack = new cdk.Stack(app, 'test'); @@ -1711,6 +1713,59 @@ nodeunitShim({ test.done(); }, + 'allows specifying Fargate capacityProviders'(test: Test) { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'test'); + + // WHEN + new ecs.Cluster(stack, 'EcsCluster', { + enableFargateCapacityProviders: true, + }); + + // THEN + expect(stack).to(haveResource('AWS::ECS::Cluster', { + CapacityProviders: ['FARGATE', 'FARGATE_SPOT'], + })); + + test.done(); + }, + + 'allows specifying capacityProviders (alternate method)'(test: Test) { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'test'); + + // WHEN + const cluster = new ecs.Cluster(stack, 'EcsCluster'); + cluster.enableFargateCapacityProviders(); + + // THEN + expect(stack).to(haveResource('AWS::ECS::Cluster', { + CapacityProviders: ['FARGATE', 'FARGATE_SPOT'], + })); + + test.done(); + }, + + 'allows adding capacityProviders post-construction (deprecated)'(test: Test) { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'test'); + const cluster = new ecs.Cluster(stack, 'EcsCluster'); + + // WHEN + cluster.addCapacityProvider('FARGATE'); + cluster.addCapacityProvider('FARGATE'); // does not add twice + + // THEN + expect(stack).to(haveResource('AWS::ECS::Cluster', { + CapacityProviders: ['FARGATE'], + })); + + test.done(); + }, + 'allows adding capacityProviders post-construction'(test: Test) { // GIVEN const app = new cdk.App(); @@ -1742,4 +1797,154 @@ nodeunitShim({ test.done(); }, + + 'creates ASG capacity providers with expected defaults'(test: Test) { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'test'); + const vpc = new ec2.Vpc(stack, 'Vpc'); + const autoScalingGroup = new autoscaling.AutoScalingGroup(stack, 'asg', { + vpc, + instanceType: new ec2.InstanceType('bogus'), + machineImage: ecs.EcsOptimizedImage.amazonLinux2(), + }); + + // WHEN + new ecs.AsgCapacityProvider(stack, 'provider', { + autoScalingGroup, + }); + + // THEN + expect(stack).to(haveResource('AWS::ECS::CapacityProvider', { + AutoScalingGroupProvider: { + AutoScalingGroupArn: { + Ref: 'asgASG4D014670', + }, + ManagedScaling: { + Status: 'ENABLED', + TargetCapacity: 100, + }, + ManagedTerminationProtection: 'ENABLED', + }, + })); + test.done(); + }, + + 'can disable managed scaling for ASG capacity provider'(test: Test) { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'test'); + const vpc = new ec2.Vpc(stack, 'Vpc'); + const autoScalingGroup = new autoscaling.AutoScalingGroup(stack, 'asg', { + vpc, + instanceType: new ec2.InstanceType('bogus'), + machineImage: ecs.EcsOptimizedImage.amazonLinux2(), + }); + + // WHEN + new ecs.AsgCapacityProvider(stack, 'provider', { + autoScalingGroup, + enableManagedScaling: false, + }); + + // THEN + expect(stack).to(haveResource('AWS::ECS::CapacityProvider', { + AutoScalingGroupProvider: { + AutoScalingGroupArn: { + Ref: 'asgASG4D014670', + }, + ManagedScaling: ABSENT, + ManagedTerminationProtection: 'ENABLED', + }, + })); + test.done(); + }, + + 'capacity provider enables ASG new instance scale-in protection by default'(test: Test) { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'test'); + const vpc = new ec2.Vpc(stack, 'Vpc'); + const autoScalingGroup = new autoscaling.AutoScalingGroup(stack, 'asg', { + vpc, + instanceType: new ec2.InstanceType('bogus'), + machineImage: ecs.EcsOptimizedImage.amazonLinux2(), + }); + + // WHEN + new ecs.AsgCapacityProvider(stack, 'provider', { + autoScalingGroup, + }); + + // THEN + expect(stack).to(haveResource('AWS::AutoScaling::AutoScalingGroup', { + NewInstancesProtectedFromScaleIn: true, + })); + test.done(); + }, + + 'capacity provider disables ASG new instance scale-in protection'(test: Test) { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'test'); + const vpc = new ec2.Vpc(stack, 'Vpc'); + const autoScalingGroup = new autoscaling.AutoScalingGroup(stack, 'asg', { + vpc, + instanceType: new ec2.InstanceType('bogus'), + machineImage: ecs.EcsOptimizedImage.amazonLinux2(), + }); + + // WHEN + new ecs.AsgCapacityProvider(stack, 'provider', { + autoScalingGroup, + enableManagedTerminationProtection: false, + }); + + // THEN + expect(stack).notTo(haveResource('AWS::AutoScaling::AutoScalingGroup', { + NewInstancesProtectedFromScaleIn: true, + })); + test.done(); + }, + + 'can add ASG capacity via Capacity Provider'(test: Test) { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'test'); + const vpc = new ec2.Vpc(stack, 'Vpc'); + const cluster = new ecs.Cluster(stack, 'EcsCluster'); + + const autoScalingGroup = new autoscaling.AutoScalingGroup(stack, 'asg', { + vpc, + instanceType: new ec2.InstanceType('bogus'), + machineImage: ecs.EcsOptimizedImage.amazonLinux2(), + }); + + // WHEN + const capacityProvider = new ecs.AsgCapacityProvider(stack, 'provider', { + autoScalingGroup, + enableManagedTerminationProtection: false, + }); + + // These should not be added at the association level + cluster.enableFargateCapacityProviders(); + + // Ensure not added twice + cluster.addAsgCapacityProvider(capacityProvider); + cluster.addAsgCapacityProvider(capacityProvider); + + // THEN + expect(stack).to(haveResource('AWS::ECS::ClusterCapacityProviderAssociations', { + Cluster: { + Ref: 'EcsCluster97242B84', + }, + CapacityProviders: [ + { + Ref: 'providerD3FF4D3A', + }, + ], + DefaultCapacityProviderStrategy: [], + })); + test.done(); + }, }); diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/ec2-service.test.ts b/packages/@aws-cdk/aws-ecs/test/ec2/ec2-service.test.ts index f6d6a47efc6c3..036604d079c71 100644 --- a/packages/@aws-cdk/aws-ecs/test/ec2/ec2-service.test.ts +++ b/packages/@aws-cdk/aws-ecs/test/ec2/ec2-service.test.ts @@ -1,4 +1,5 @@ import { expect, haveResource, haveResourceLike } from '@aws-cdk/assert-internal'; +import * as autoscaling from '@aws-cdk/aws-autoscaling'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as elb from '@aws-cdk/aws-elasticloadbalancing'; import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2'; @@ -24,7 +25,7 @@ nodeunitShim({ memoryLimitMiB: 512, }); - new ecs.Ec2Service(stack, 'Ec2Service', { + const service = new ecs.Ec2Service(stack, 'Ec2Service', { cluster, taskDefinition, }); @@ -46,6 +47,8 @@ nodeunitShim({ EnableECSManagedTags: false, })); + test.notEqual(service.node.defaultChild, undefined); + test.done(); }, @@ -236,6 +239,58 @@ nodeunitShim({ test.done(); }, + 'with autoscaling group capacity provider'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'Vpc'); + const cluster = new ecs.Cluster(stack, 'EcsCluster'); + + const autoScalingGroup = new autoscaling.AutoScalingGroup(stack, 'asg', { + vpc, + instanceType: new ec2.InstanceType('bogus'), + machineImage: ecs.EcsOptimizedImage.amazonLinux2(), + }); + + // WHEN + const capacityProvider = new ecs.AsgCapacityProvider(stack, 'provider', { + autoScalingGroup, + enableManagedTerminationProtection: false, + }); + cluster.addAsgCapacityProvider(capacityProvider); + + const taskDefinition = new ecs.TaskDefinition(stack, 'ServerTask', { + compatibility: ecs.Compatibility.EC2, + }); + taskDefinition.addContainer('app', { + image: new ecs.RepositoryImage('bogus'), + cpu: 1024, + memoryReservationMiB: 900, + portMappings: [{ + containerPort: 80, + }], + }); + new ecs.Ec2Service(stack, 'Service', { + cluster, + taskDefinition, + desiredCount: 0, + capacityProviderStrategies: [{ + capacityProvider: capacityProvider.capacityProviderName, + }], + }); + + // THEN + expect(stack).to(haveResource('AWS::ECS::Service', { + CapacityProviderStrategy: [ + { + CapacityProvider: { + Ref: 'providerD3FF4D3A', + }, + }, + ], + })); + test.done(); + }, + 'with multiple security groups, it correctly updates the cfn template'(test: Test) { // GIVEN const stack = new cdk.Stack(); diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.capacity-provider.expected.json b/packages/@aws-cdk/aws-ecs/test/ec2/integ.capacity-provider.expected.json new file mode 100644 index 0000000000000..d4e008750fe93 --- /dev/null +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.capacity-provider.expected.json @@ -0,0 +1,655 @@ +{ + "Resources": { + "Vpc8378EB38": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/Vpc" + } + ] + } + }, + "VpcPublicSubnet1Subnet5C2D37C4": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.0.0/18", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1RouteTable6C95E38E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1RouteTableAssociation97140677": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + } + } + }, + "VpcPublicSubnet1DefaultRoute3DA9E72A": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet1RouteTable6C95E38E" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": [ + "VpcVPCGWBF912B6E" + ] + }, + "VpcPublicSubnet1EIPD7E02669": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet1NATGateway4D7517AA": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet1EIPD7E02669", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/Vpc/PublicSubnet1" + } + ] + } + }, + "VpcPublicSubnet2Subnet691E08A3": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.64.0/18", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1b", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPublicSubnet2RouteTable94F7E489": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPublicSubnet2RouteTableAssociationDD5762D8": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + } + } + }, + "VpcPublicSubnet2DefaultRoute97F91067": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPublicSubnet2RouteTable94F7E489" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VpcIGWD7BA715C" + } + }, + "DependsOn": [ + "VpcVPCGWBF912B6E" + ] + }, + "VpcPublicSubnet2EIP3C605A87": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPublicSubnet2NATGateway9182C01D": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VpcPublicSubnet2EIP3C605A87", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VpcPublicSubnet2Subnet691E08A3" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/Vpc/PublicSubnet2" + } + ] + } + }, + "VpcPrivateSubnet1Subnet536B997A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.128.0/18", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1a", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/Vpc/PrivateSubnet1" + } + ] + } + }, + "VpcPrivateSubnet1RouteTableB2C5B500": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/Vpc/PrivateSubnet1" + } + ] + } + }, + "VpcPrivateSubnet1RouteTableAssociation70C59FA6": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + } + } + }, + "VpcPrivateSubnet1DefaultRouteBE02A9ED": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet1RouteTableB2C5B500" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet1NATGateway4D7517AA" + } + } + }, + "VpcPrivateSubnet2Subnet3788AAA1": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "CidrBlock": "10.0.192.0/18", + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "AvailabilityZone": "test-region-1b", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/Vpc/PrivateSubnet2" + } + ] + } + }, + "VpcPrivateSubnet2RouteTableA678073B": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/Vpc/PrivateSubnet2" + } + ] + } + }, + "VpcPrivateSubnet2RouteTableAssociationA89CAD56": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet2RouteTableA678073B" + }, + "SubnetId": { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + } + } + }, + "VpcPrivateSubnet2DefaultRoute060D2087": { + "Type": "AWS::EC2::Route", + "Properties": { + "RouteTableId": { + "Ref": "VpcPrivateSubnet2RouteTableA678073B" + }, + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VpcPublicSubnet2NATGateway9182C01D" + } + } + }, + "VpcIGWD7BA715C": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/Vpc" + } + ] + } + }, + "VpcVPCGWBF912B6E": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "VpcId": { + "Ref": "Vpc8378EB38" + }, + "InternetGatewayId": { + "Ref": "VpcIGWD7BA715C" + } + } + }, + "EC2CPClusterD5F0FD32": { + "Type": "AWS::ECS::Cluster" + }, + "EC2CPCluster4CFED4DD": { + "Type": "AWS::ECS::ClusterCapacityProviderAssociations", + "Properties": { + "CapacityProviders": [ + { + "Ref": "EC2CapacityProvider5A2E35CD" + } + ], + "Cluster": { + "Ref": "EC2CPClusterD5F0FD32" + }, + "DefaultCapacityProviderStrategy": [] + } + }, + "TaskDefTaskRole1EDB4A67": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "TaskDef54694570": { + "Type": "AWS::ECS::TaskDefinition", + "Properties": { + "ContainerDefinitions": [ + { + "Essential": true, + "Image": "amazon/amazon-ecs-sample", + "MemoryReservation": 256, + "Name": "web" + } + ], + "Family": "integec2capacityproviderTaskDefA6140A6B", + "NetworkMode": "bridge", + "RequiresCompatibilities": [ + "EC2" + ], + "TaskRoleArn": { + "Fn::GetAtt": [ + "TaskDefTaskRole1EDB4A67", + "Arn" + ] + } + } + }, + "ASGInstanceSecurityGroup0525485D": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "integ-ec2-capacity-provider/ASG/InstanceSecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "Tags": [ + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/ASG" + } + ], + "VpcId": { + "Ref": "Vpc8378EB38" + } + } + }, + "ASGInstanceRoleE263A41B": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "ec2.", + { + "Ref": "AWS::URLSuffix" + } + ] + ] + } + } + } + ], + "Version": "2012-10-17" + }, + "Tags": [ + { + "Key": "Name", + "Value": "integ-ec2-capacity-provider/ASG" + } + ] + } + }, + "ASGInstanceRoleDefaultPolicy7636D8BF": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "ecs:DeregisterContainerInstance", + "ecs:RegisterContainerInstance", + "ecs:Submit*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "EC2CPClusterD5F0FD32", + "Arn" + ] + } + }, + { + "Action": [ + "ecs:Poll", + "ecs:StartTelemetrySession" + ], + "Condition": { + "ArnEquals": { + "ecs:cluster": { + "Fn::GetAtt": [ + "EC2CPClusterD5F0FD32", + "Arn" + ] + } + } + }, + "Effect": "Allow", + "Resource": "*" + }, + { + "Action": [ + "ecs:DiscoverPollEndpoint", + "ecr:GetAuthorizationToken", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ASGInstanceRoleDefaultPolicy7636D8BF", + "Roles": [ + { + "Ref": "ASGInstanceRoleE263A41B" + } + ] + } + }, + "ASGInstanceProfile0A2834D7": { + "Type": "AWS::IAM::InstanceProfile", + "Properties": { + "Roles": [ + { + "Ref": "ASGInstanceRoleE263A41B" + } + ] + } + }, + "ASGLaunchConfigC00AF12B": { + "Type": "AWS::AutoScaling::LaunchConfiguration", + "Properties": { + "ImageId": { + "Ref": "SsmParameterValueawsserviceecsoptimizedamiamazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter" + }, + "InstanceType": "t2.micro", + "IamInstanceProfile": { + "Ref": "ASGInstanceProfile0A2834D7" + }, + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "ASGInstanceSecurityGroup0525485D", + "GroupId" + ] + } + ], + "UserData": { + "Fn::Base64": { + "Fn::Join": [ + "", + [ + "#!/bin/bash\necho ECS_CLUSTER=", + { + "Ref": "EC2CPClusterD5F0FD32" + }, + " >> /etc/ecs/ecs.config\nsudo iptables --insert FORWARD 1 --in-interface docker+ --destination 169.254.169.254/32 --jump DROP\nsudo service iptables save\necho ECS_AWSVPC_BLOCK_IMDS=true >> /etc/ecs/ecs.config" + ] + ] + } + } + }, + "DependsOn": [ + "ASGInstanceRoleDefaultPolicy7636D8BF", + "ASGInstanceRoleE263A41B" + ] + }, + "ASG46ED3070": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "MaxSize": "1", + "MinSize": "1", + "LaunchConfigurationName": { + "Ref": "ASGLaunchConfigC00AF12B" + }, + "NewInstancesProtectedFromScaleIn": true, + "Tags": [ + { + "Key": "Name", + "PropagateAtLaunch": true, + "Value": "integ-ec2-capacity-provider/ASG" + } + ], + "VPCZoneIdentifier": [ + { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + }, + { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + } + ] + }, + "UpdatePolicy": { + "AutoScalingScheduledAction": { + "IgnoreUnmodifiedGroupSizeProperties": true + } + } + }, + "EC2CapacityProvider5A2E35CD": { + "Type": "AWS::ECS::CapacityProvider", + "Properties": { + "AutoScalingGroupProvider": { + "AutoScalingGroupArn": { + "Ref": "ASG46ED3070" + }, + "ManagedScaling": { + "Status": "ENABLED", + "TargetCapacity": 100 + }, + "ManagedTerminationProtection": "ENABLED" + } + } + }, + "EC2Service5392EF94": { + "Type": "AWS::ECS::Service", + "Properties": { + "CapacityProviderStrategy": [ + { + "CapacityProvider": { + "Ref": "EC2CapacityProvider5A2E35CD" + }, + "Weight": 1 + } + ], + "Cluster": { + "Ref": "EC2CPClusterD5F0FD32" + }, + "DeploymentConfiguration": { + "MaximumPercent": 200, + "MinimumHealthyPercent": 50 + }, + "EnableECSManagedTags": false, + "SchedulingStrategy": "REPLICA", + "TaskDefinition": { + "Ref": "TaskDef54694570" + } + } + } + }, + "Parameters": { + "SsmParameterValueawsserviceecsoptimizedamiamazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-ecs/test/ec2/integ.capacity-provider.ts b/packages/@aws-cdk/aws-ecs/test/ec2/integ.capacity-provider.ts new file mode 100644 index 0000000000000..f82ce6a9f9f56 --- /dev/null +++ b/packages/@aws-cdk/aws-ecs/test/ec2/integ.capacity-provider.ts @@ -0,0 +1,46 @@ +import * as autoscaling from '@aws-cdk/aws-autoscaling'; +import * as ec2 from '@aws-cdk/aws-ec2'; +import * as cdk from '@aws-cdk/core'; +import * as ecs from '../../lib'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'integ-ec2-capacity-provider'); + +const vpc = new ec2.Vpc(stack, 'Vpc', { maxAzs: 2 }); + +const cluster = new ecs.Cluster(stack, 'EC2CPCluster', { + vpc, +}); + +const taskDefinition = new ecs.Ec2TaskDefinition(stack, 'TaskDef'); + +taskDefinition.addContainer('web', { + image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), + memoryReservationMiB: 256, +}); + +const autoScalingGroup = new autoscaling.AutoScalingGroup(stack, 'ASG', { + vpc, + instanceType: new ec2.InstanceType('t2.micro'), + machineImage: ecs.EcsOptimizedImage.amazonLinux2(), +}); + +const cp = new ecs.AsgCapacityProvider(stack, 'EC2CapacityProvider', { + autoScalingGroup, +}); + +cluster.addAsgCapacityProvider(cp); + +new ecs.Ec2Service(stack, 'EC2Service', { + cluster, + taskDefinition, + capacityProviderStrategies: [ + { + capacityProvider: cp.capacityProviderName, + weight: 1, + }, + ], +}); + +app.synth(); + diff --git a/packages/@aws-cdk/aws-ecs/test/fargate/fargate-service.test.ts b/packages/@aws-cdk/aws-ecs/test/fargate/fargate-service.test.ts index 0bdbeac0c04d5..af4b92370726d 100644 --- a/packages/@aws-cdk/aws-ecs/test/fargate/fargate-service.test.ts +++ b/packages/@aws-cdk/aws-ecs/test/fargate/fargate-service.test.ts @@ -1,4 +1,4 @@ -import { expect, haveResource, haveResourceLike } from '@aws-cdk/assert-internal'; +import { expect, haveResource, haveResourceLike, ABSENT } from '@aws-cdk/assert-internal'; import * as appscaling from '@aws-cdk/aws-applicationautoscaling'; import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; @@ -23,7 +23,7 @@ nodeunitShim({ image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), }); - new ecs.FargateService(stack, 'FargateService', { + const service = new ecs.FargateService(stack, 'FargateService', { cluster, taskDefinition, }); @@ -79,6 +79,8 @@ nodeunitShim({ }, })); + test.notEqual(service.node.defaultChild, undefined); + test.done(); }, @@ -110,7 +112,7 @@ nodeunitShim({ test.done(); }, - 'does not set launchType when capacity provider strategies specified'(test: Test) { + 'does not set launchType when capacity provider strategies specified (deprecated)'(test: Test) { // GIVEN const stack = new cdk.Stack(); const vpc = new ec2.Vpc(stack, 'MyVpc', {}); @@ -195,6 +197,93 @@ nodeunitShim({ test.done(); }, + 'does not set launchType when capacity provider strategies specified'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'MyVpc', {}); + const cluster = new ecs.Cluster(stack, 'EcsCluster', { + vpc, + }); + cluster.enableFargateCapacityProviders(); + + const taskDefinition = new ecs.FargateTaskDefinition(stack, 'FargateTaskDef'); + + const container = taskDefinition.addContainer('web', { + image: ecs.ContainerImage.fromRegistry('amazon/amazon-ecs-sample'), + memoryLimitMiB: 512, + }); + container.addPortMappings({ containerPort: 8000 }); + + new ecs.FargateService(stack, 'FargateService', { + cluster, + taskDefinition, + capacityProviderStrategies: [ + { + capacityProvider: 'FARGATE_SPOT', + weight: 2, + }, + { + capacityProvider: 'FARGATE', + weight: 1, + }, + ], + }); + + // THEN + expect(stack).to(haveResource('AWS::ECS::Cluster', { + CapacityProviders: ['FARGATE', 'FARGATE_SPOT'], + })); + + expect(stack).to(haveResource('AWS::ECS::Service', { + TaskDefinition: { + Ref: 'FargateTaskDefC6FB60B4', + }, + Cluster: { + Ref: 'EcsCluster97242B84', + }, + DeploymentConfiguration: { + MaximumPercent: 200, + MinimumHealthyPercent: 50, + }, + // no launch type + LaunchType: ABSENT, + CapacityProviderStrategy: [ + { + CapacityProvider: 'FARGATE_SPOT', + Weight: 2, + }, + { + CapacityProvider: 'FARGATE', + Weight: 1, + }, + ], + EnableECSManagedTags: false, + NetworkConfiguration: { + AwsvpcConfiguration: { + AssignPublicIp: 'DISABLED', + SecurityGroups: [ + { + 'Fn::GetAtt': [ + 'FargateServiceSecurityGroup0A0E79CB', + 'GroupId', + ], + }, + ], + Subnets: [ + { + Ref: 'MyVpcPrivateSubnet1Subnet5057CF7E', + }, + { + Ref: 'MyVpcPrivateSubnet2Subnet0040C983', + }, + ], + }, + }, + })); + + test.done(); + }, + 'with custom cloudmap namespace'(test: Test) { // GIVEN const stack = new cdk.Stack(); diff --git a/packages/@aws-cdk/aws-eks/README.md b/packages/@aws-cdk/aws-eks/README.md index bb64c62070a0e..2eae725b53873 100644 --- a/packages/@aws-cdk/aws-eks/README.md +++ b/packages/@aws-cdk/aws-eks/README.md @@ -654,7 +654,7 @@ const cluster = new eks.Cluster(this, 'MyCluster', { }); ``` -You can also use a similiar configuration for running a cluster built using the FargateCluster construct. +You can also use a similar configuration for running a cluster built using the FargateCluster construct. ```ts const secretsKey = new kms.Key(this, 'SecretsKey'); diff --git a/packages/@aws-cdk/aws-events-targets/lib/sqs.ts b/packages/@aws-cdk/aws-events-targets/lib/sqs.ts index 8d711b4b9f5be..501414ecee348 100644 --- a/packages/@aws-cdk/aws-events-targets/lib/sqs.ts +++ b/packages/@aws-cdk/aws-events-targets/lib/sqs.ts @@ -52,14 +52,15 @@ export class SqsQueue implements events.IRuleTarget { * @see https://docs.aws.amazon.com/eventbridge/latest/userguide/resource-based-policies-eventbridge.html#sqs-permissions */ public bind(rule: events.IRule, _id?: string): events.RuleTargetConfig { + // Only add the rule as a condition if the queue is not encrypted, to avoid circular dependency. See issue #11158. + const principalOpts = this.queue.encryptionMasterKey ? {} : { + conditions: { + ArnEquals: { 'aws:SourceArn': rule.ruleArn }, + }, + }; + // deduplicated automatically - this.queue.grantSendMessages(new iam.ServicePrincipal('events.amazonaws.com', - { - conditions: { - ArnEquals: { 'aws:SourceArn': rule.ruleArn }, - }, - }), - ); + this.queue.grantSendMessages(new iam.ServicePrincipal('events.amazonaws.com', principalOpts)); return { arn: this.queue.queueArn, diff --git a/packages/@aws-cdk/aws-events-targets/package.json b/packages/@aws-cdk/aws-events-targets/package.json index e36df0baf5c71..f262d5897aa5a 100644 --- a/packages/@aws-cdk/aws-events-targets/package.json +++ b/packages/@aws-cdk/aws-events-targets/package.json @@ -93,6 +93,7 @@ "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kinesis": "0.0.0", "@aws-cdk/aws-kinesisfirehose": "0.0.0", + "@aws-cdk/aws-kms": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-sns": "0.0.0", @@ -114,6 +115,7 @@ "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kinesis": "0.0.0", "@aws-cdk/aws-kinesisfirehose": "0.0.0", + "@aws-cdk/aws-kms": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-sns": "0.0.0", diff --git a/packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.expected.json b/packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.expected.json index eebbc3a996344..eb2a7dd26ef5f 100644 --- a/packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.expected.json +++ b/packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.expected.json @@ -1,5 +1,53 @@ { "Resources": { + "MyKey6AB29FA6": { + "Type": "AWS::KMS::Key", + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + }, + { + "Action": [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Principal": { + "Service": "events.amazonaws.com" + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, "MyRuleA44AB831": { "Type": "AWS::Events::Rule", "Properties": { @@ -20,6 +68,14 @@ }, "MyQueueE6CA6235": { "Type": "AWS::SQS::Queue", + "Properties": { + "KmsMasterKeyId": { + "Fn::GetAtt": [ + "MyKey6AB29FA6", + "Arn" + ] + } + }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, @@ -34,16 +90,6 @@ "sqs:GetQueueAttributes", "sqs:GetQueueUrl" ], - "Condition": { - "ArnEquals": { - "aws:SourceArn": { - "Fn::GetAtt": [ - "MyRuleA44AB831", - "Arn" - ] - } - } - }, "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com" diff --git a/packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.ts b/packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.ts index b58641f727d03..b2b8fb334bff6 100644 --- a/packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.ts +++ b/packages/@aws-cdk/aws-events-targets/test/sqs/integ.sqs-event-rule-target.ts @@ -1,4 +1,5 @@ import * as events from '@aws-cdk/aws-events'; +import * as kms from '@aws-cdk/aws-kms'; import * as sqs from '@aws-cdk/aws-sqs'; import * as cdk from '@aws-cdk/core'; import * as targets from '../../lib'; @@ -12,11 +13,17 @@ const app = new cdk.App(); const stack = new cdk.Stack(app, 'aws-cdk-sqs-event-target'); +const key = new kms.Key(stack, 'MyKey'); + const event = new events.Rule(stack, 'MyRule', { schedule: events.Schedule.rate(cdk.Duration.minutes(1)), }); -const queue = new sqs.Queue(stack, 'MyQueue'); +const queue = new sqs.Queue(stack, 'MyQueue', { + encryption: sqs.QueueEncryption.KMS, + encryptionMasterKey: key, +}); + event.addTarget(new targets.SqsQueue(queue)); app.synth(); diff --git a/packages/@aws-cdk/aws-finspace/.eslintrc.js b/packages/@aws-cdk/aws-finspace/.eslintrc.js new file mode 100644 index 0000000000000..61dd8dd001f63 --- /dev/null +++ b/packages/@aws-cdk/aws-finspace/.eslintrc.js @@ -0,0 +1,3 @@ +const baseConfig = require('cdk-build-tools/config/eslintrc'); +baseConfig.parserOptions.project = __dirname + '/tsconfig.json'; +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-finspace/.gitignore b/packages/@aws-cdk/aws-finspace/.gitignore new file mode 100644 index 0000000000000..62ebc95d75ce6 --- /dev/null +++ b/packages/@aws-cdk/aws-finspace/.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-finspace/.npmignore b/packages/@aws-cdk/aws-finspace/.npmignore new file mode 100644 index 0000000000000..e4486030fcb17 --- /dev/null +++ b/packages/@aws-cdk/aws-finspace/.npmignore @@ -0,0 +1,28 @@ +# 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/ diff --git a/packages/@aws-cdk/aws-finspace/LICENSE b/packages/@aws-cdk/aws-finspace/LICENSE new file mode 100644 index 0000000000000..28e4bdcec77ec --- /dev/null +++ b/packages/@aws-cdk/aws-finspace/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-finspace/NOTICE b/packages/@aws-cdk/aws-finspace/NOTICE new file mode 100644 index 0000000000000..5fc3826926b5b --- /dev/null +++ b/packages/@aws-cdk/aws-finspace/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-finspace/README.md b/packages/@aws-cdk/aws-finspace/README.md new file mode 100644 index 0000000000000..686a32758ad3e --- /dev/null +++ b/packages/@aws-cdk/aws-finspace/README.md @@ -0,0 +1,20 @@ +# AWS::FinSpace 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 finspace = require('@aws-cdk/aws-finspace'); +``` diff --git a/packages/@aws-cdk/aws-finspace/jest.config.js b/packages/@aws-cdk/aws-finspace/jest.config.js new file mode 100644 index 0000000000000..54e28beb9798b --- /dev/null +++ b/packages/@aws-cdk/aws-finspace/jest.config.js @@ -0,0 +1,2 @@ +const baseConfig = require('cdk-build-tools/config/jest.config'); +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-finspace/lib/index.ts b/packages/@aws-cdk/aws-finspace/lib/index.ts new file mode 100644 index 0000000000000..c3d3bf207c329 --- /dev/null +++ b/packages/@aws-cdk/aws-finspace/lib/index.ts @@ -0,0 +1,2 @@ +// AWS::FinSpace CloudFormation Resources: +export * from './finspace.generated'; diff --git a/packages/@aws-cdk/aws-finspace/package.json b/packages/@aws-cdk/aws-finspace/package.json new file mode 100644 index 0000000000000..4c3c6f007e64b --- /dev/null +++ b/packages/@aws-cdk/aws-finspace/package.json @@ -0,0 +1,101 @@ +{ + "name": "@aws-cdk/aws-finspace", + "version": "0.0.0", + "description": "The CDK Construct Library for AWS::FinSpace", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "jsii": { + "outdir": "dist", + "projectReferences": true, + "targets": { + "dotnet": { + "namespace": "Amazon.CDK.AWS.FinSpace", + "packageId": "Amazon.CDK.AWS.FinSpace", + "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.finspace", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "finspace" + } + }, + "python": { + "classifiers": [ + "Framework :: AWS CDK", + "Framework :: AWS CDK :: 1" + ], + "distName": "aws-cdk.aws-finspace", + "module": "aws_cdk.aws_finspace" + } + } + }, + "repository": { + "type": "git", + "url": "https://github.com/aws/aws-cdk.git", + "directory": "packages/@aws-cdk/aws-finspace" + }, + "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" + }, + "cdk-build": { + "cloudformation": "AWS::FinSpace", + "jest": true, + "env": { + "AWSLINT_BASE_CONSTRUCT": "true" + } + }, + "keywords": [ + "aws", + "cdk", + "constructs", + "AWS::FinSpace", + "aws-finspace" + ], + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "organization": true + }, + "license": "Apache-2.0", + "devDependencies": { + "@types/jest": "^26.0.23", + "@aws-cdk/assert-internal": "0.0.0", + "cdk-build-tools": "0.0.0", + "cfn2ts": "0.0.0", + "pkglint": "0.0.0" + }, + "dependencies": { + "@aws-cdk/core": "0.0.0" + }, + "peerDependencies": { + "@aws-cdk/core": "0.0.0" + }, + "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-finspace/test/finspace.test.ts b/packages/@aws-cdk/aws-finspace/test/finspace.test.ts new file mode 100644 index 0000000000000..c4505ad966984 --- /dev/null +++ b/packages/@aws-cdk/aws-finspace/test/finspace.test.ts @@ -0,0 +1,6 @@ +import '@aws-cdk/assert-internal/jest'; +import {} from '../lib'; + +test('No tests are specified for this package', () => { + expect(true).toBe(true); +}); diff --git a/packages/@aws-cdk/aws-frauddetector/.eslintrc.js b/packages/@aws-cdk/aws-frauddetector/.eslintrc.js new file mode 100644 index 0000000000000..61dd8dd001f63 --- /dev/null +++ b/packages/@aws-cdk/aws-frauddetector/.eslintrc.js @@ -0,0 +1,3 @@ +const baseConfig = require('cdk-build-tools/config/eslintrc'); +baseConfig.parserOptions.project = __dirname + '/tsconfig.json'; +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-frauddetector/.gitignore b/packages/@aws-cdk/aws-frauddetector/.gitignore new file mode 100644 index 0000000000000..62ebc95d75ce6 --- /dev/null +++ b/packages/@aws-cdk/aws-frauddetector/.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-frauddetector/.npmignore b/packages/@aws-cdk/aws-frauddetector/.npmignore new file mode 100644 index 0000000000000..e4486030fcb17 --- /dev/null +++ b/packages/@aws-cdk/aws-frauddetector/.npmignore @@ -0,0 +1,28 @@ +# 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/ diff --git a/packages/@aws-cdk/aws-frauddetector/LICENSE b/packages/@aws-cdk/aws-frauddetector/LICENSE new file mode 100644 index 0000000000000..28e4bdcec77ec --- /dev/null +++ b/packages/@aws-cdk/aws-frauddetector/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-frauddetector/NOTICE b/packages/@aws-cdk/aws-frauddetector/NOTICE new file mode 100644 index 0000000000000..5fc3826926b5b --- /dev/null +++ b/packages/@aws-cdk/aws-frauddetector/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-frauddetector/README.md b/packages/@aws-cdk/aws-frauddetector/README.md new file mode 100644 index 0000000000000..2805d63c38fb7 --- /dev/null +++ b/packages/@aws-cdk/aws-frauddetector/README.md @@ -0,0 +1,20 @@ +# AWS::FraudDetector 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 frauddetector = require('@aws-cdk/aws-frauddetector'); +``` diff --git a/packages/@aws-cdk/aws-frauddetector/jest.config.js b/packages/@aws-cdk/aws-frauddetector/jest.config.js new file mode 100644 index 0000000000000..54e28beb9798b --- /dev/null +++ b/packages/@aws-cdk/aws-frauddetector/jest.config.js @@ -0,0 +1,2 @@ +const baseConfig = require('cdk-build-tools/config/jest.config'); +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-frauddetector/lib/index.ts b/packages/@aws-cdk/aws-frauddetector/lib/index.ts new file mode 100644 index 0000000000000..ed9953ee506e8 --- /dev/null +++ b/packages/@aws-cdk/aws-frauddetector/lib/index.ts @@ -0,0 +1,2 @@ +// AWS::FraudDetector CloudFormation Resources: +export * from './frauddetector.generated'; diff --git a/packages/@aws-cdk/aws-frauddetector/package.json b/packages/@aws-cdk/aws-frauddetector/package.json new file mode 100644 index 0000000000000..58b9f0393e614 --- /dev/null +++ b/packages/@aws-cdk/aws-frauddetector/package.json @@ -0,0 +1,101 @@ +{ + "name": "@aws-cdk/aws-frauddetector", + "version": "0.0.0", + "description": "The CDK Construct Library for AWS::FraudDetector", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "jsii": { + "outdir": "dist", + "projectReferences": true, + "targets": { + "dotnet": { + "namespace": "Amazon.CDK.AWS.FraudDetector", + "packageId": "Amazon.CDK.AWS.FraudDetector", + "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.frauddetector", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "frauddetector" + } + }, + "python": { + "classifiers": [ + "Framework :: AWS CDK", + "Framework :: AWS CDK :: 1" + ], + "distName": "aws-cdk.aws-frauddetector", + "module": "aws_cdk.aws_frauddetector" + } + } + }, + "repository": { + "type": "git", + "url": "https://github.com/aws/aws-cdk.git", + "directory": "packages/@aws-cdk/aws-frauddetector" + }, + "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" + }, + "cdk-build": { + "cloudformation": "AWS::FraudDetector", + "jest": true, + "env": { + "AWSLINT_BASE_CONSTRUCT": "true" + } + }, + "keywords": [ + "aws", + "cdk", + "constructs", + "AWS::FraudDetector", + "aws-frauddetector" + ], + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "organization": true + }, + "license": "Apache-2.0", + "devDependencies": { + "@types/jest": "^26.0.23", + "@aws-cdk/assert-internal": "0.0.0", + "cdk-build-tools": "0.0.0", + "cfn2ts": "0.0.0", + "pkglint": "0.0.0" + }, + "dependencies": { + "@aws-cdk/core": "0.0.0" + }, + "peerDependencies": { + "@aws-cdk/core": "0.0.0" + }, + "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-frauddetector/test/frauddetector.test.ts b/packages/@aws-cdk/aws-frauddetector/test/frauddetector.test.ts new file mode 100644 index 0000000000000..c4505ad966984 --- /dev/null +++ b/packages/@aws-cdk/aws-frauddetector/test/frauddetector.test.ts @@ -0,0 +1,6 @@ +import '@aws-cdk/assert-internal/jest'; +import {} from '../lib'; + +test('No tests are specified for this package', () => { + expect(true).toBe(true); +}); diff --git a/packages/@aws-cdk/aws-lambda-event-sources/lib/stream.ts b/packages/@aws-cdk/aws-lambda-event-sources/lib/stream.ts index c9de62653a93e..85b9728fafbc2 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/lib/stream.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/lib/stream.ts @@ -41,7 +41,7 @@ export interface StreamEventSourceProps { * * Minimum value of 60 seconds * * Maximum value of 7 days * - * @default Duration.days(7) + * @default - the retention period configured on the stream */ readonly maxRecordAge?: Duration; @@ -51,7 +51,7 @@ export interface StreamEventSourceProps { * * Minimum value of 0 * * Maximum value of 10000 * - * @default 10000 + * @default - retry until the record expires */ readonly retryAttempts?: number; diff --git a/packages/@aws-cdk/aws-lambda-nodejs/README.md b/packages/@aws-cdk/aws-lambda-nodejs/README.md index 7a1662dc26fb2..c52b0fe2570c9 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/README.md +++ b/packages/@aws-cdk/aws-lambda-nodejs/README.md @@ -142,7 +142,7 @@ new lambda.NodejsFunction(this, 'my-handler', { }, logLevel: LogLevel.SILENT, // defaults to LogLevel.WARNING keepNames: true, // defaults to false - tsconfig: 'custom-tsconfig.json' // use custom-tsconfig.json instead of default, + tsconfig: 'custom-tsconfig.json', // use custom-tsconfig.json instead of default, metafile: true, // include meta file, defaults to false banner : '/* comments */', // by default no comments are passed footer : '/* comments */', // by default no comments are passed diff --git a/packages/@aws-cdk/aws-lambda-nodejs/lib/function.ts b/packages/@aws-cdk/aws-lambda-nodejs/lib/function.ts index 49e9b40b5cd5d..00e5315654796 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/lib/function.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/lib/function.ts @@ -155,7 +155,7 @@ function findEntry(id: string, entry?: string): string { return jsHandlerFile; } - throw new Error('Cannot find entry file.'); + throw new Error(`Cannot find handler file ${tsHandlerFile} or ${jsHandlerFile}`); } /** diff --git a/packages/@aws-cdk/aws-lambda-nodejs/test/function.test.ts b/packages/@aws-cdk/aws-lambda-nodejs/test/function.test.ts index cc4544ec6e732..83ea2131c043a 100644 --- a/packages/@aws-cdk/aws-lambda-nodejs/test/function.test.ts +++ b/packages/@aws-cdk/aws-lambda-nodejs/test/function.test.ts @@ -98,7 +98,7 @@ test('throws when entry does not exist', () => { }); test('throws when entry cannot be automatically found', () => { - expect(() => new NodejsFunction(stack, 'Fn')).toThrow(/Cannot find entry file./); + expect(() => new NodejsFunction(stack, 'Fn')).toThrow(/Cannot find handler file .*function.test.Fn.ts or .*function.test.Fn.js/); }); test('throws with the wrong runtime family', () => { diff --git a/packages/@aws-cdk/aws-lambda/lib/function.ts b/packages/@aws-cdk/aws-lambda/lib/function.ts index 4a0fc2d916ec0..0565ba2a98b1e 100644 --- a/packages/@aws-cdk/aws-lambda/lib/function.ts +++ b/packages/@aws-cdk/aws-lambda/lib/function.ts @@ -701,10 +701,30 @@ export class Function extends FunctionBase { this.currentVersionOptions = props.currentVersionOptions; if (props.filesystem) { + if (!props.vpc) { + throw new Error('Cannot configure \'filesystem\' without configuring a VPC.'); + } const config = props.filesystem.config; if (config.dependency) { this.node.addDependency(...config.dependency); } + // There could be a race if the Lambda is used in a CustomResource. It is possible for the Lambda to + // fail to attach to a given FileSystem if we do not have a dependency on the SecurityGroup ingress/egress + // rules that were created between this Lambda's SG & the Filesystem SG. + this.connections.securityGroups.forEach(sg => { + sg.node.findAll().forEach(child => { + if (child instanceof CfnResource && child.cfnResourceType === 'AWS::EC2::SecurityGroupEgress') { + resource.node.addDependency(child); + } + }); + }); + config.connections?.securityGroups.forEach(sg => { + sg.node.findAll().forEach(child => { + if (child instanceof CfnResource && child.cfnResourceType === 'AWS::EC2::SecurityGroupIngress') { + resource.node.addDependency(child); + } + }); + }); } } diff --git a/packages/@aws-cdk/aws-lambda/package.json b/packages/@aws-cdk/aws-lambda/package.json index 3fdc26ada0d5e..6279fa92e0518 100644 --- a/packages/@aws-cdk/aws-lambda/package.json +++ b/packages/@aws-cdk/aws-lambda/package.json @@ -77,7 +77,7 @@ "devDependencies": { "@types/jest": "^26.0.23", "@types/aws-lambda": "^8.10.76", - "@types/lodash": "^4.14.168", + "@types/lodash": "^4.14.169", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-lambda/test/function.test.ts b/packages/@aws-cdk/aws-lambda/test/function.test.ts index e4ac71c25c8d1..26a27ca76aad2 100644 --- a/packages/@aws-cdk/aws-lambda/test/function.test.ts +++ b/packages/@aws-cdk/aws-lambda/test/function.test.ts @@ -1841,6 +1841,7 @@ describe('function', () => { const accessPoint = fs.addAccessPoint('AccessPoint'); // WHEN new lambda.Function(stack, 'MyFunction', { + vpc, handler: 'foo', runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset(path.join(__dirname, 'handler.zip')), @@ -1879,6 +1880,69 @@ describe('function', () => { ], }); }); + + test('throw error mounting efs with no vpc', () => { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'Vpc', { + maxAzs: 3, + natGateways: 1, + }); + + const fs = new efs.FileSystem(stack, 'Efs', { + vpc, + }); + const accessPoint = fs.addAccessPoint('AccessPoint'); + + // THEN + expect(() => { + new lambda.Function(stack, 'MyFunction', { + handler: 'foo', + runtime: lambda.Runtime.NODEJS_12_X, + code: lambda.Code.fromAsset(path.join(__dirname, 'handler.zip')), + filesystem: lambda.FileSystem.fromEfsAccessPoint(accessPoint, '/mnt/msg'), + }); + }).toThrow(); + }); + + test('verify deps when mounting efs', () => { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'Vpc', { + maxAzs: 3, + natGateways: 1, + }); + const securityGroup = new ec2.SecurityGroup(stack, 'LambdaSG', { + vpc, + allowAllOutbound: false, + }); + + const fs = new efs.FileSystem(stack, 'Efs', { + vpc, + }); + const accessPoint = fs.addAccessPoint('AccessPoint'); + // WHEN + new lambda.Function(stack, 'MyFunction', { + vpc, + handler: 'foo', + securityGroups: [securityGroup], + runtime: lambda.Runtime.NODEJS_12_X, + code: lambda.Code.fromAsset(path.join(__dirname, 'handler.zip')), + filesystem: lambda.FileSystem.fromEfsAccessPoint(accessPoint, '/mnt/msg'), + }); + + // THEN + expect(stack).toHaveResource('AWS::Lambda::Function', { + DependsOn: [ + 'EfsEfsMountTarget195B2DD2E', + 'EfsEfsMountTarget2315C927F', + 'EfsEfsSecurityGroupfromLambdaSG20491B2F751D', + 'LambdaSGtoEfsEfsSecurityGroupFCE2954020499719694A', + 'MyFunctionServiceRoleDefaultPolicyB705ABD4', + 'MyFunctionServiceRole3C357FF2', + ], + }, ResourcePart.CompleteDefinition); + }); }); describe('code config', () => { diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda.filesystem.expected.json b/packages/@aws-cdk/aws-lambda/test/integ.lambda.filesystem.expected.json index 6d9334ab8999f..abb79b5123377 100644 --- a/packages/@aws-cdk/aws-lambda/test/integ.lambda.filesystem.expected.json +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda.filesystem.expected.json @@ -801,6 +801,7 @@ "EfsEfsMountTarget195B2DD2E", "EfsEfsMountTarget2315C927F", "EfsEfsMountTarget36646B9A0", + "EfsEfsSecurityGroupfromawscdklambda1MyLambdaSecurityGroup86B085EE20490D9864A8", "MyLambdaServiceRoleDefaultPolicy5BBC6F68", "MyLambdaServiceRole4539ECB6" ] @@ -1048,7 +1049,8 @@ "MyLambdaServiceRoleDefaultPolicy5BBC6F68", "MyLambdaServiceRole4539ECB6", "MyLambda2ServiceRoleDefaultPolicy2BECE79D", - "MyLambda2ServiceRoleD09B370C" + "MyLambda2ServiceRoleD09B370C", + "securityGroupfromawscdklambda1MyLambda2SecurityGroup7492F70D20498301D9D2" ] } } diff --git a/packages/@aws-cdk/aws-msk/test/integ.cluster.expected.json b/packages/@aws-cdk/aws-msk/test/integ.cluster.expected.json index 43769c1b25ac8..769c0533269cd 100644 --- a/packages/@aws-cdk/aws-msk/test/integ.cluster.expected.json +++ b/packages/@aws-cdk/aws-msk/test/integ.cluster.expected.json @@ -524,7 +524,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParametersb965ea3084ec95e24846d4975623e62a02c21883c3ddea9366b2ae42d21cef98S3Bucket4DD075F7" + "Ref": "AssetParametersf56a9c742f3e99b26237d5d0912c69f9db8289c13656fdcb490fd017d801c483S3Bucket9DEDD0AB" }, "S3Key": { "Fn::Join": [ @@ -537,7 +537,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersb965ea3084ec95e24846d4975623e62a02c21883c3ddea9366b2ae42d21cef98S3VersionKeyBD0E03B7" + "Ref": "AssetParametersf56a9c742f3e99b26237d5d0912c69f9db8289c13656fdcb490fd017d801c483S3VersionKeyA54743D3" } ] } @@ -550,7 +550,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersb965ea3084ec95e24846d4975623e62a02c21883c3ddea9366b2ae42d21cef98S3VersionKeyBD0E03B7" + "Ref": "AssetParametersf56a9c742f3e99b26237d5d0912c69f9db8289c13656fdcb490fd017d801c483S3VersionKeyA54743D3" } ] } @@ -576,17 +576,17 @@ } }, "Parameters": { - "AssetParametersb965ea3084ec95e24846d4975623e62a02c21883c3ddea9366b2ae42d21cef98S3Bucket4DD075F7": { + "AssetParametersf56a9c742f3e99b26237d5d0912c69f9db8289c13656fdcb490fd017d801c483S3Bucket9DEDD0AB": { "Type": "String", - "Description": "S3 bucket for asset \"b965ea3084ec95e24846d4975623e62a02c21883c3ddea9366b2ae42d21cef98\"" + "Description": "S3 bucket for asset \"f56a9c742f3e99b26237d5d0912c69f9db8289c13656fdcb490fd017d801c483\"" }, - "AssetParametersb965ea3084ec95e24846d4975623e62a02c21883c3ddea9366b2ae42d21cef98S3VersionKeyBD0E03B7": { + "AssetParametersf56a9c742f3e99b26237d5d0912c69f9db8289c13656fdcb490fd017d801c483S3VersionKeyA54743D3": { "Type": "String", - "Description": "S3 key for asset version \"b965ea3084ec95e24846d4975623e62a02c21883c3ddea9366b2ae42d21cef98\"" + "Description": "S3 key for asset version \"f56a9c742f3e99b26237d5d0912c69f9db8289c13656fdcb490fd017d801c483\"" }, - "AssetParametersb965ea3084ec95e24846d4975623e62a02c21883c3ddea9366b2ae42d21cef98ArtifactHash35A756EB": { + "AssetParametersf56a9c742f3e99b26237d5d0912c69f9db8289c13656fdcb490fd017d801c483ArtifactHash228F5AF4": { "Type": "String", - "Description": "Artifact hash for asset \"b965ea3084ec95e24846d4975623e62a02c21883c3ddea9366b2ae42d21cef98\"" + "Description": "Artifact hash for asset \"f56a9c742f3e99b26237d5d0912c69f9db8289c13656fdcb490fd017d801c483\"" } }, "Outputs": { diff --git a/packages/@aws-cdk/aws-s3-deployment/README.md b/packages/@aws-cdk/aws-s3-deployment/README.md index 64c3872c59f74..84af913dcaccd 100644 --- a/packages/@aws-cdk/aws-s3-deployment/README.md +++ b/packages/@aws-cdk/aws-s3-deployment/README.md @@ -77,7 +77,7 @@ Configuring this has a few implications you should be aware of: - **Destination Changes** When the destination bucket or prefix is changed, all files in the previous destination will **first** be - deleted and then uploaded to the new destination location. This could have availablity implications + deleted and then uploaded to the new destination location. This could have availability implications on your users. ### General Recommendations diff --git a/packages/@aws-cdk/aws-secretsmanager/README.md b/packages/@aws-cdk/aws-secretsmanager/README.md index 0c0f45828e9ef..81c8e3c5e8e24 100644 --- a/packages/@aws-cdk/aws-secretsmanager/README.md +++ b/packages/@aws-cdk/aws-secretsmanager/README.md @@ -87,6 +87,8 @@ secret.addRotationSchedule('RotationSchedule', { }); ``` +Note: The required permissions for Lambda to call SecretsManager and the other way round are automatically granted based on [AWS Documentation](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets-required-permissions.html) as long as the Lambda is not imported. + See [Overview of the Lambda Rotation Function](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets-lambda-function-overview.html) on how to implement a Lambda Rotation Function. ### Using a Hosted Lambda Function diff --git a/packages/@aws-cdk/aws-secretsmanager/lib/rotation-schedule.ts b/packages/@aws-cdk/aws-secretsmanager/lib/rotation-schedule.ts index 1243976963386..7e00492f2cb2f 100644 --- a/packages/@aws-cdk/aws-secretsmanager/lib/rotation-schedule.ts +++ b/packages/@aws-cdk/aws-secretsmanager/lib/rotation-schedule.ts @@ -1,4 +1,5 @@ import * as ec2 from '@aws-cdk/aws-ec2'; +import * as iam from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; import { Duration, Resource, Stack } from '@aws-cdk/core'; import { Construct } from 'constructs'; @@ -70,6 +71,35 @@ export class RotationSchedule extends Resource { throw new Error('One of `rotationLambda` or `hostedRotation` must be specified.'); } + if (props.rotationLambda?.permissionsNode.defaultChild) { + props.rotationLambda.grantInvoke(new iam.ServicePrincipal('secretsmanager.amazonaws.com')); + + props.rotationLambda.addToRolePolicy( + new iam.PolicyStatement({ + actions: [ + 'secretsmanager:DescribeSecret', + 'secretsmanager:GetSecretValue', + 'secretsmanager:PutSecretValue', + 'secretsmanager:UpdateSecretVersionStage', + ], + resources: [props.secret.secretArn], + conditions: { + StringEquals: { + 'secretsmanager:resource/AllowRotationLambdaArn': props.rotationLambda.functionArn, + }, + }, + }), + ); + props.rotationLambda.addToRolePolicy( + new iam.PolicyStatement({ + actions: [ + 'secretsmanager:GetRandomPassword', + ], + resources: ['*'], + }), + ); + } + new CfnRotationSchedule(this, 'Resource', { secretId: props.secret.secretArn, rotationLambdaArn: props.rotationLambda?.functionArn, diff --git a/packages/@aws-cdk/aws-secretsmanager/test/rotation-schedule.test.ts b/packages/@aws-cdk/aws-secretsmanager/test/rotation-schedule.test.ts index e77336732d51b..3ab3422cd265b 100644 --- a/packages/@aws-cdk/aws-secretsmanager/test/rotation-schedule.test.ts +++ b/packages/@aws-cdk/aws-secretsmanager/test/rotation-schedule.test.ts @@ -41,6 +41,75 @@ test('create a rotation schedule with a rotation Lambda', () => { }); }); +test('assign permissions for rotation schedule with a rotation Lambda', () => { + // GIVEN + const secret = new secretsmanager.Secret(stack, 'Secret'); + const rotationLambda = new lambda.Function(stack, 'Lambda', { + runtime: lambda.Runtime.NODEJS_10_X, + code: lambda.Code.fromInline('export.handler = event => event;'), + handler: 'index.handler', + }); + + // WHEN + new secretsmanager.RotationSchedule(stack, 'RotationSchedule', { + secret, + rotationLambda, + }); + + // THEN + expect(stack).toHaveResource('AWS::Lambda::Permission', { + Action: 'lambda:InvokeFunction', + FunctionName: { + 'Fn::GetAtt': [ + 'LambdaD247545B', + 'Arn', + ], + }, + Principal: 'secretsmanager.amazonaws.com', + }); + + expect(stack).toHaveResource('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: [ + 'secretsmanager:DescribeSecret', + 'secretsmanager:GetSecretValue', + 'secretsmanager:PutSecretValue', + 'secretsmanager:UpdateSecretVersionStage', + ], + Effect: 'Allow', + Resource: { + Ref: 'SecretA720EF05', + }, + Condition: { + StringEquals: { + 'secretsmanager:resource/AllowRotationLambdaArn': { + 'Fn::GetAtt': [ + 'LambdaD247545B', + 'Arn', + ], + }, + }, + }, + }, + { + Action: 'secretsmanager:GetRandomPassword', + Effect: 'Allow', + Resource: '*', + }, + ], + Version: '2012-10-17', + }, + PolicyName: 'LambdaServiceRoleDefaultPolicyDAE46E21', + Roles: [ + { + Ref: 'LambdaServiceRoleA8ED4D3B', + }, + ], + }); +}); + describe('hosted rotation', () => { test('single user not in a vpc', () => { // GIVEN diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/integ.call-http-api.expected.json b/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/integ.call-http-api.expected.json index 56d4889af3d55..c6a6abaa89273 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/integ.call-http-api.expected.json +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/integ.call-http-api.expected.json @@ -77,6 +77,7 @@ "Ref": "MyHttpApi8AEAAC21" }, "RouteKey": "ANY /", + "AuthorizationType": "NONE", "Target": { "Fn::Join": [ "", diff --git a/packages/@aws-cdk/aws-xray/.eslintrc.js b/packages/@aws-cdk/aws-xray/.eslintrc.js new file mode 100644 index 0000000000000..61dd8dd001f63 --- /dev/null +++ b/packages/@aws-cdk/aws-xray/.eslintrc.js @@ -0,0 +1,3 @@ +const baseConfig = require('cdk-build-tools/config/eslintrc'); +baseConfig.parserOptions.project = __dirname + '/tsconfig.json'; +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-xray/.gitignore b/packages/@aws-cdk/aws-xray/.gitignore new file mode 100644 index 0000000000000..62ebc95d75ce6 --- /dev/null +++ b/packages/@aws-cdk/aws-xray/.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-xray/.npmignore b/packages/@aws-cdk/aws-xray/.npmignore new file mode 100644 index 0000000000000..e4486030fcb17 --- /dev/null +++ b/packages/@aws-cdk/aws-xray/.npmignore @@ -0,0 +1,28 @@ +# 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/ diff --git a/packages/@aws-cdk/aws-xray/LICENSE b/packages/@aws-cdk/aws-xray/LICENSE new file mode 100644 index 0000000000000..28e4bdcec77ec --- /dev/null +++ b/packages/@aws-cdk/aws-xray/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-xray/NOTICE b/packages/@aws-cdk/aws-xray/NOTICE new file mode 100644 index 0000000000000..5fc3826926b5b --- /dev/null +++ b/packages/@aws-cdk/aws-xray/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-xray/README.md b/packages/@aws-cdk/aws-xray/README.md new file mode 100644 index 0000000000000..77a0090e7f659 --- /dev/null +++ b/packages/@aws-cdk/aws-xray/README.md @@ -0,0 +1,20 @@ +# AWS::XRay 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 xray = require('@aws-cdk/aws-xray'); +``` diff --git a/packages/@aws-cdk/aws-xray/jest.config.js b/packages/@aws-cdk/aws-xray/jest.config.js new file mode 100644 index 0000000000000..54e28beb9798b --- /dev/null +++ b/packages/@aws-cdk/aws-xray/jest.config.js @@ -0,0 +1,2 @@ +const baseConfig = require('cdk-build-tools/config/jest.config'); +module.exports = baseConfig; diff --git a/packages/@aws-cdk/aws-xray/lib/index.ts b/packages/@aws-cdk/aws-xray/lib/index.ts new file mode 100644 index 0000000000000..9912dab6f0e95 --- /dev/null +++ b/packages/@aws-cdk/aws-xray/lib/index.ts @@ -0,0 +1,2 @@ +// AWS::XRay CloudFormation Resources: +export * from './xray.generated'; diff --git a/packages/@aws-cdk/aws-xray/package.json b/packages/@aws-cdk/aws-xray/package.json new file mode 100644 index 0000000000000..baaafffc7e70e --- /dev/null +++ b/packages/@aws-cdk/aws-xray/package.json @@ -0,0 +1,101 @@ +{ + "name": "@aws-cdk/aws-xray", + "version": "0.0.0", + "description": "The CDK Construct Library for AWS::XRay", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "jsii": { + "outdir": "dist", + "projectReferences": true, + "targets": { + "dotnet": { + "namespace": "Amazon.CDK.AWS.XRay", + "packageId": "Amazon.CDK.AWS.XRay", + "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.xray", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "xray" + } + }, + "python": { + "classifiers": [ + "Framework :: AWS CDK", + "Framework :: AWS CDK :: 1" + ], + "distName": "aws-cdk.aws-xray", + "module": "aws_cdk.aws_xray" + } + } + }, + "repository": { + "type": "git", + "url": "https://github.com/aws/aws-cdk.git", + "directory": "packages/@aws-cdk/aws-xray" + }, + "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" + }, + "cdk-build": { + "cloudformation": "AWS::XRay", + "jest": true, + "env": { + "AWSLINT_BASE_CONSTRUCT": "true" + } + }, + "keywords": [ + "aws", + "cdk", + "constructs", + "AWS::XRay", + "aws-xray" + ], + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "organization": true + }, + "license": "Apache-2.0", + "devDependencies": { + "@types/jest": "^26.0.23", + "@aws-cdk/assert-internal": "0.0.0", + "cdk-build-tools": "0.0.0", + "cfn2ts": "0.0.0", + "pkglint": "0.0.0" + }, + "dependencies": { + "@aws-cdk/core": "0.0.0" + }, + "peerDependencies": { + "@aws-cdk/core": "0.0.0" + }, + "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-xray/test/xray.test.ts b/packages/@aws-cdk/aws-xray/test/xray.test.ts new file mode 100644 index 0000000000000..c4505ad966984 --- /dev/null +++ b/packages/@aws-cdk/aws-xray/test/xray.test.ts @@ -0,0 +1,6 @@ +import '@aws-cdk/assert-internal/jest'; +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 4f49d0b63908e..df0747a8e2705 100644 --- a/packages/@aws-cdk/cfnspec/CHANGELOG.md +++ b/packages/@aws-cdk/cfnspec/CHANGELOG.md @@ -1,3 +1,145 @@ +# CloudFormation Resource Specification v35.2.0 + +## New Resource Types + +* AWS::CloudFront::Function +* AWS::FinSpace::Environment +* AWS::FraudDetector::Detector +* AWS::FraudDetector::EntityType +* AWS::FraudDetector::EventType +* AWS::FraudDetector::Label +* AWS::FraudDetector::Outcome +* AWS::FraudDetector::Variable +* AWS::XRay::Group +* AWS::XRay::SamplingRule + +## Attribute Changes + +* AWS::CloudFront::Distribution Id (__added__) +* AWS::Config::ConfigurationAggregator ConfigurationAggregatorArn (__added__) +* AWS::ECR::Repository RepositoryUri (__added__) +* AWS::ECS::Service ServiceArn (__added__) + +## Property Changes + +* AWS::ACMPCA::CertificateAuthority KeyStorageSecurityStandard (__added__) +* AWS::CloudFront::Distribution Tags.DuplicatesAllowed (__added__) +* AWS::CloudWatch::MetricStream OutputFormat.Required (__changed__) + * Old: false + * New: true +* AWS::Config::ConfigurationAggregator AccountAggregationSources.DuplicatesAllowed (__added__) +* AWS::Config::ConfigurationAggregator ConfigurationAggregatorName.Required (__changed__) + * Old: true + * New: false +* AWS::Config::ConfigurationAggregator Tags.DuplicatesAllowed (__added__) +* AWS::DataBrew::Job JobSample.PrimitiveType (__deleted__) +* AWS::DataBrew::Job JobSample.Type (__added__) +* AWS::DataBrew::Job OutputLocation.PrimitiveType (__deleted__) +* AWS::DataBrew::Job OutputLocation.Type (__added__) +* AWS::DataBrew::Job Recipe.Type (__added__) +* AWS::DataBrew::Project Sample.PrimitiveType (__deleted__) +* AWS::DataBrew::Project Sample.Type (__added__) +* AWS::ECR::Repository EncryptionConfiguration (__added__) +* AWS::ECS::Service ServiceArn (__deleted__) +* AWS::ECS::TaskDefinition EphemeralStorage (__added__) +* AWS::EKS::Nodegroup Taints (__added__) +* AWS::GameLift::Fleet Locations (__added__) +* AWS::GameLift::GameSessionQueue FilterConfiguration (__added__) +* AWS::GameLift::GameSessionQueue PriorityConfiguration (__added__) +* AWS::Lambda::Function Id (__added__) +* AWS::Lambda::Function FileSystemConfigs.DuplicatesAllowed (__deleted__) +* AWS::Lambda::Function Layers.DuplicatesAllowed (__changed__) + * Old: false + * New: true +* AWS::Lambda::Function Tags.DuplicatesAllowed (__changed__) + * Old: true + * New: false + +## Property Type Changes + +* AWS::FIS::ExperimentTemplate.ExperimentTemplateActionItemParameterMap (__removed__) +* AWS::FIS::ExperimentTemplate.ExperimentTemplateActionItemTargetMap (__removed__) +* AWS::FIS::ExperimentTemplate.TagMap (__removed__) +* AWS::CloudFront::Distribution.FunctionAssociation (__added__) +* AWS::CloudFront::Distribution.LegacyCustomOrigin (__added__) +* AWS::CloudFront::Distribution.LegacyS3Origin (__added__) +* AWS::DataBrew::Job.JobSample (__added__) +* AWS::DataBrew::Job.OutputLocation (__added__) +* AWS::DataBrew::Job.Recipe (__added__) +* AWS::DataBrew::Project.Sample (__added__) +* AWS::ECS::TaskDefinition.EphemeralStorage (__added__) +* AWS::EKS::Nodegroup.Taint (__added__) +* AWS::GameLift::Fleet.LocationCapacity (__added__) +* AWS::GameLift::Fleet.LocationConfiguration (__added__) +* AWS::GameLift::GameSessionQueue.FilterConfiguration (__added__) +* AWS::GameLift::GameSessionQueue.PriorityConfiguration (__added__) +* AWS::MSK::Cluster.Iam (__added__) +* AWS::CloudFront::Distribution.CacheBehavior FunctionAssociations (__added__) +* AWS::CloudFront::Distribution.CacheBehavior AllowedMethods.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.CacheBehavior CachedMethods.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.CacheBehavior LambdaFunctionAssociations.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.CacheBehavior TrustedKeyGroups.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.CacheBehavior TrustedSigners.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.Cookies WhitelistedNames.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.CustomOriginConfig OriginSSLProtocols.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.DefaultCacheBehavior FunctionAssociations (__added__) +* AWS::CloudFront::Distribution.DefaultCacheBehavior AllowedMethods.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.DefaultCacheBehavior CachedMethods.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.DefaultCacheBehavior LambdaFunctionAssociations.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.DefaultCacheBehavior TrustedKeyGroups.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.DefaultCacheBehavior TrustedSigners.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.DistributionConfig CNAMEs (__added__) +* AWS::CloudFront::Distribution.DistributionConfig CustomOrigin (__added__) +* AWS::CloudFront::Distribution.DistributionConfig S3Origin (__added__) +* AWS::CloudFront::Distribution.DistributionConfig Aliases.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.DistributionConfig CacheBehaviors.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.DistributionConfig CustomErrorResponses.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.DistributionConfig Origins.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.ForwardedValues Headers.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.ForwardedValues QueryStringCacheKeys.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.GeoRestriction Locations.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.Origin OriginCustomHeaders.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.Origin OriginShield.Type (__deleted__) +* AWS::CloudFront::Distribution.OriginGroupMembers Items.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.OriginGroups Items.DuplicatesAllowed (__added__) +* AWS::CloudFront::Distribution.OriginShield Enabled.Required (__changed__) + * Old: true + * New: false +* AWS::CloudFront::Distribution.StatusCodes Items.DuplicatesAllowed (__added__) +* AWS::Config::ConfigurationAggregator.AccountAggregationSource AccountIds.DuplicatesAllowed (__added__) +* AWS::Config::ConfigurationAggregator.AccountAggregationSource AwsRegions.DuplicatesAllowed (__added__) +* AWS::Config::ConfigurationAggregator.OrganizationAggregationSource AwsRegions.DuplicatesAllowed (__added__) +* AWS::FIS::ExperimentTemplate.ExperimentTemplateAction Parameters.PrimitiveItemType (__added__) +* AWS::FIS::ExperimentTemplate.ExperimentTemplateAction Parameters.Type (__changed__) + * Old: ExperimentTemplateActionItemParameterMap + * New: Map +* AWS::FIS::ExperimentTemplate.ExperimentTemplateAction Targets.PrimitiveItemType (__added__) +* AWS::FIS::ExperimentTemplate.ExperimentTemplateAction Targets.Type (__changed__) + * Old: ExperimentTemplateActionItemTargetMap + * New: Map +* AWS::FIS::ExperimentTemplate.ExperimentTemplateTarget ResourceTags.PrimitiveItemType (__added__) +* AWS::FIS::ExperimentTemplate.ExperimentTemplateTarget ResourceTags.Type (__changed__) + * Old: TagMap + * New: Map +* AWS::Lambda::Function.Environment Variables.DuplicatesAllowed (__deleted__) +* AWS::Lambda::Function.VpcConfig SecurityGroupIds.DuplicatesAllowed (__changed__) + * Old: false + * New: true +* AWS::Lambda::Function.VpcConfig SecurityGroupIds.Required (__changed__) + * Old: true + * New: false +* AWS::Lambda::Function.VpcConfig SubnetIds.DuplicatesAllowed (__changed__) + * Old: false + * New: true +* AWS::Lambda::Function.VpcConfig SubnetIds.Required (__changed__) + * Old: true + * New: false +* AWS::MSK::Cluster.Sasl Iam (__added__) +* AWS::MSK::Cluster.Sasl Scram.Required (__changed__) + * Old: true + * New: false + + # CloudFormation Resource Specification v35.1.0 ## New Resource Types diff --git a/packages/@aws-cdk/cfnspec/cfn.version b/packages/@aws-cdk/cfnspec/cfn.version index 4710c8eb98fcd..6ee5ed10b7ff5 100644 --- a/packages/@aws-cdk/cfnspec/cfn.version +++ b/packages/@aws-cdk/cfnspec/cfn.version @@ -1 +1 @@ -35.1.0 +35.2.0 diff --git a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json index 43816f779cc2c..61926760268cd 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json +++ b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json @@ -9950,6 +9950,7 @@ "Properties": { "AllowedMethods": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-allowedmethods", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -9963,6 +9964,7 @@ }, "CachedMethods": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-cachedmethods", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -9992,8 +9994,17 @@ "Type": "ForwardedValues", "UpdateType": "Mutable" }, + "FunctionAssociations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-functionassociations", + "DuplicatesAllowed": true, + "ItemType": "FunctionAssociation", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "LambdaFunctionAssociations": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-lambdafunctionassociations", + "DuplicatesAllowed": true, "ItemType": "LambdaFunctionAssociation", "Required": false, "Type": "List", @@ -10043,6 +10054,7 @@ }, "TrustedKeyGroups": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-trustedkeygroups", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -10050,6 +10062,7 @@ }, "TrustedSigners": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-trustedsigners", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -10074,6 +10087,7 @@ }, "WhitelistedNames": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cookies.html#cfn-cloudfront-distribution-cookies-whitelistednames", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -10145,6 +10159,7 @@ }, "OriginSSLProtocols": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-customoriginconfig.html#cfn-cloudfront-distribution-customoriginconfig-originsslprotocols", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -10157,6 +10172,7 @@ "Properties": { "AllowedMethods": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-allowedmethods", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -10170,6 +10186,7 @@ }, "CachedMethods": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-cachedmethods", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -10199,8 +10216,17 @@ "Type": "ForwardedValues", "UpdateType": "Mutable" }, + "FunctionAssociations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-functionassociations", + "DuplicatesAllowed": true, + "ItemType": "FunctionAssociation", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "LambdaFunctionAssociations": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-lambdafunctionassociations", + "DuplicatesAllowed": true, "ItemType": "LambdaFunctionAssociation", "Required": false, "Type": "List", @@ -10244,6 +10270,7 @@ }, "TrustedKeyGroups": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-trustedkeygroups", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -10251,6 +10278,7 @@ }, "TrustedSigners": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-trustedsigners", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -10269,6 +10297,15 @@ "Properties": { "Aliases": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-aliases", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "CNAMEs": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-cnames", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -10276,6 +10313,7 @@ }, "CacheBehaviors": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-cachebehaviors", + "DuplicatesAllowed": true, "ItemType": "CacheBehavior", "Required": false, "Type": "List", @@ -10289,11 +10327,18 @@ }, "CustomErrorResponses": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-customerrorresponses", + "DuplicatesAllowed": true, "ItemType": "CustomErrorResponse", "Required": false, "Type": "List", "UpdateType": "Mutable" }, + "CustomOrigin": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-customorigin", + "Required": false, + "Type": "LegacyCustomOrigin", + "UpdateType": "Mutable" + }, "DefaultCacheBehavior": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-defaultcachebehavior", "Required": false, @@ -10338,6 +10383,7 @@ }, "Origins": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-origins", + "DuplicatesAllowed": true, "ItemType": "Origin", "Required": false, "Type": "List", @@ -10355,6 +10401,12 @@ "Type": "Restrictions", "UpdateType": "Mutable" }, + "S3Origin": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-s3origin", + "Required": false, + "Type": "LegacyS3Origin", + "UpdateType": "Mutable" + }, "ViewerCertificate": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-viewercertificate", "Required": false, @@ -10380,6 +10432,7 @@ }, "Headers": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-forwardedvalues.html#cfn-cloudfront-distribution-forwardedvalues-headers", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -10393,6 +10446,7 @@ }, "QueryStringCacheKeys": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-forwardedvalues.html#cfn-cloudfront-distribution-forwardedvalues-querystringcachekeys", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -10400,11 +10454,29 @@ } } }, + "AWS::CloudFront::Distribution.FunctionAssociation": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-functionassociation.html", + "Properties": { + "EventType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-functionassociation.html#cfn-cloudfront-distribution-functionassociation-eventtype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "FunctionARN": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-functionassociation.html#cfn-cloudfront-distribution-functionassociation-functionarn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::CloudFront::Distribution.GeoRestriction": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-georestriction.html", "Properties": { "Locations": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-georestriction.html#cfn-cloudfront-distribution-georestriction-locations", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -10441,6 +10513,60 @@ } } }, + "AWS::CloudFront::Distribution.LegacyCustomOrigin": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacycustomorigin.html", + "Properties": { + "DNSName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacycustomorigin.html#cfn-cloudfront-distribution-legacycustomorigin-dnsname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "HTTPPort": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacycustomorigin.html#cfn-cloudfront-distribution-legacycustomorigin-httpport", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "HTTPSPort": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacycustomorigin.html#cfn-cloudfront-distribution-legacycustomorigin-httpsport", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "OriginProtocolPolicy": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacycustomorigin.html#cfn-cloudfront-distribution-legacycustomorigin-originprotocolpolicy", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "OriginSSLProtocols": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacycustomorigin.html#cfn-cloudfront-distribution-legacycustomorigin-originsslprotocols", + "DuplicatesAllowed": true, + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::Distribution.LegacyS3Origin": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacys3origin.html", + "Properties": { + "DNSName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacys3origin.html#cfn-cloudfront-distribution-legacys3origin-dnsname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "OriginAccessIdentity": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacys3origin.html#cfn-cloudfront-distribution-legacys3origin-originaccessidentity", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::CloudFront::Distribution.Logging": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-logging.html", "Properties": { @@ -10499,6 +10625,7 @@ }, "OriginCustomHeaders": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origin.html#cfn-cloudfront-distribution-origin-origincustomheaders", + "DuplicatesAllowed": true, "ItemType": "OriginCustomHeader", "Required": false, "Type": "List", @@ -10513,7 +10640,6 @@ "OriginShield": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origin.html#cfn-cloudfront-distribution-origin-originshield", "Required": false, - "Type": "OriginShield", "UpdateType": "Mutable" }, "S3OriginConfig": { @@ -10591,6 +10717,7 @@ "Properties": { "Items": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroupmembers.html#cfn-cloudfront-distribution-origingroupmembers-items", + "DuplicatesAllowed": true, "ItemType": "OriginGroupMember", "Required": true, "Type": "List", @@ -10609,6 +10736,7 @@ "Properties": { "Items": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroups.html#cfn-cloudfront-distribution-origingroups-items", + "DuplicatesAllowed": true, "ItemType": "OriginGroup", "Required": false, "Type": "List", @@ -10628,7 +10756,7 @@ "Enabled": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-originshield.html#cfn-cloudfront-distribution-originshield-enabled", "PrimitiveType": "Boolean", - "Required": true, + "Required": false, "UpdateType": "Mutable" }, "OriginShieldRegion": { @@ -10666,6 +10794,7 @@ "Properties": { "Items": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-statuscodes.html#cfn-cloudfront-distribution-statuscodes-items", + "DuplicatesAllowed": true, "PrimitiveItemType": "Integer", "Required": true, "Type": "List", @@ -10714,6 +10843,34 @@ } } }, + "AWS::CloudFront::Function.FunctionConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-function-functionconfig.html", + "Properties": { + "Comment": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-function-functionconfig.html#cfn-cloudfront-function-functionconfig-comment", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Runtime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-function-functionconfig.html#cfn-cloudfront-function-functionconfig-runtime", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::CloudFront::Function.FunctionMetadata": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-function-functionmetadata.html", + "Properties": { + "FunctionARN": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-function-functionmetadata.html#cfn-cloudfront-function-functionmetadata-functionarn", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, "AWS::CloudFront::KeyGroup.KeyGroupConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-keygroup-keygroupconfig.html", "Properties": { @@ -13616,6 +13773,7 @@ "Properties": { "AccountIds": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-config-configurationaggregator-accountaggregationsource.html#cfn-config-configurationaggregator-accountaggregationsource-accountids", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": true, "Type": "List", @@ -13629,6 +13787,7 @@ }, "AwsRegions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-config-configurationaggregator-accountaggregationsource.html#cfn-config-configurationaggregator-accountaggregationsource-awsregions", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -13647,6 +13806,7 @@ }, "AwsRegions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-config-configurationaggregator-organizationaggregationsource.html#cfn-config-configurationaggregator-organizationaggregationsource-awsregions", + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -15150,6 +15310,23 @@ } } }, + "AWS::DataBrew::Job.JobSample": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-jobsample.html", + "Properties": { + "Mode": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-jobsample.html#cfn-databrew-job-jobsample-mode", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Size": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-jobsample.html#cfn-databrew-job-jobsample-size", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::DataBrew::Job.Output": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-output.html", "Properties": { @@ -15204,6 +15381,40 @@ } } }, + "AWS::DataBrew::Job.OutputLocation": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-outputlocation.html", + "Properties": { + "Bucket": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-outputlocation.html#cfn-databrew-job-outputlocation-bucket", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Key": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-outputlocation.html#cfn-databrew-job-outputlocation-key", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::DataBrew::Job.Recipe": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-recipe.html", + "Properties": { + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-recipe.html#cfn-databrew-job-recipe-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Version": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-recipe.html#cfn-databrew-job-recipe-version", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::DataBrew::Job.S3Location": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-s3location.html", "Properties": { @@ -15221,6 +15432,23 @@ } } }, + "AWS::DataBrew::Project.Sample": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-project-sample.html", + "Properties": { + "Size": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-project-sample.html#cfn-databrew-project-sample-size", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "Type": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-project-sample.html#cfn-databrew-project-sample-type", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, "AWS::DataBrew::Recipe.Action": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-recipe-action.html", "Properties": { @@ -20431,6 +20659,17 @@ } } }, + "AWS::ECS::TaskDefinition.EphemeralStorage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-ephemeralstorage.html", + "Properties": { + "SizeInGiB": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-ephemeralstorage.html#cfn-ecs-taskdefinition-ephemeralstorage-sizeingib", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::ECS::TaskDefinition.FirelensConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-firelensconfiguration.html", "Properties": { @@ -21272,6 +21511,29 @@ } } }, + "AWS::EKS::Nodegroup.Taint": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-nodegroup-taint.html", + "Properties": { + "Effect": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-nodegroup-taint.html#cfn-eks-nodegroup-taint-effect", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Key": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-nodegroup-taint.html#cfn-eks-nodegroup-taint-key", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Value": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-eks-nodegroup-taint.html#cfn-eks-nodegroup-taint-value", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::EMR::Cluster.Application": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-elasticmapreduce-cluster-application.html", "Properties": { @@ -24949,8 +25211,9 @@ }, "Parameters": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fis-experimenttemplate-experimenttemplateaction.html#cfn-fis-experimenttemplate-experimenttemplateaction-parameters", + "PrimitiveItemType": "String", "Required": false, - "Type": "ExperimentTemplateActionItemParameterMap", + "Type": "Map", "UpdateType": "Mutable" }, "StartAfter": { @@ -24962,18 +25225,13 @@ }, "Targets": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fis-experimenttemplate-experimenttemplateaction.html#cfn-fis-experimenttemplate-experimenttemplateaction-targets", + "PrimitiveItemType": "String", "Required": false, - "Type": "ExperimentTemplateActionItemTargetMap", + "Type": "Map", "UpdateType": "Mutable" } } }, - "AWS::FIS::ExperimentTemplate.ExperimentTemplateActionItemParameterMap": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fis-experimenttemplate-experimenttemplateactionitemparametermap.html" - }, - "AWS::FIS::ExperimentTemplate.ExperimentTemplateActionItemTargetMap": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fis-experimenttemplate-experimenttemplateactionitemtargetmap.html" - }, "AWS::FIS::ExperimentTemplate.ExperimentTemplateStopCondition": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fis-experimenttemplate-experimenttemplatestopcondition.html", "Properties": { @@ -25010,8 +25268,9 @@ }, "ResourceTags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fis-experimenttemplate-experimenttemplatetarget.html#cfn-fis-experimenttemplate-experimenttemplatetarget-resourcetags", + "PrimitiveItemType": "String", "Required": false, - "Type": "TagMap", + "Type": "Map", "UpdateType": "Mutable" }, "ResourceType": { @@ -25046,9 +25305,6 @@ } } }, - "AWS::FIS::ExperimentTemplate.TagMap": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fis-experimenttemplate-tagmap.html" - }, "AWS::FMS::Policy.IEMap": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fms-policy-iemap.html", "Properties": { @@ -25281,6 +25537,586 @@ } } }, + "AWS::FinSpace::Environment.FederationParameters": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-finspace-environment-federationparameters.html", + "Properties": { + "ApplicationCallBackURL": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-finspace-environment-federationparameters.html#cfn-finspace-environment-federationparameters-applicationcallbackurl", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "AttributeMap": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-finspace-environment-federationparameters.html#cfn-finspace-environment-federationparameters-attributemap", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Mutable" + }, + "FederationProviderName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-finspace-environment-federationparameters.html#cfn-finspace-environment-federationparameters-federationprovidername", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "FederationURN": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-finspace-environment-federationparameters.html#cfn-finspace-environment-federationparameters-federationurn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SamlMetadataDocument": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-finspace-environment-federationparameters.html#cfn-finspace-environment-federationparameters-samlmetadatadocument", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SamlMetadataURL": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-finspace-environment-federationparameters.html#cfn-finspace-environment-federationparameters-samlmetadataurl", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::Detector.EntityType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-entitytype.html", + "Properties": { + "Arn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-entitytype.html#cfn-frauddetector-detector-entitytype-arn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "CreatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-entitytype.html#cfn-frauddetector-detector-entitytype-createdtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-entitytype.html#cfn-frauddetector-detector-entitytype-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Inline": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-entitytype.html#cfn-frauddetector-detector-entitytype-inline", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "LastUpdatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-entitytype.html#cfn-frauddetector-detector-entitytype-lastupdatedtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-entitytype.html#cfn-frauddetector-detector-entitytype-name", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-entitytype.html#cfn-frauddetector-detector-entitytype-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::Detector.EventType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventtype.html", + "Properties": { + "Arn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventtype.html#cfn-frauddetector-detector-eventtype-arn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "CreatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventtype.html#cfn-frauddetector-detector-eventtype-createdtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventtype.html#cfn-frauddetector-detector-eventtype-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "EntityTypes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventtype.html#cfn-frauddetector-detector-eventtype-entitytypes", + "DuplicatesAllowed": true, + "ItemType": "EntityType", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "EventVariables": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventtype.html#cfn-frauddetector-detector-eventtype-eventvariables", + "DuplicatesAllowed": true, + "ItemType": "EventVariable", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "Inline": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventtype.html#cfn-frauddetector-detector-eventtype-inline", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "Labels": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventtype.html#cfn-frauddetector-detector-eventtype-labels", + "DuplicatesAllowed": true, + "ItemType": "Label", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "LastUpdatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventtype.html#cfn-frauddetector-detector-eventtype-lastupdatedtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventtype.html#cfn-frauddetector-detector-eventtype-name", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventtype.html#cfn-frauddetector-detector-eventtype-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::Detector.EventVariable": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventvariable.html", + "Properties": { + "Arn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventvariable.html#cfn-frauddetector-detector-eventvariable-arn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "CreatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventvariable.html#cfn-frauddetector-detector-eventvariable-createdtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "DataSource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventvariable.html#cfn-frauddetector-detector-eventvariable-datasource", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "DataType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventvariable.html#cfn-frauddetector-detector-eventvariable-datatype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "DefaultValue": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventvariable.html#cfn-frauddetector-detector-eventvariable-defaultvalue", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventvariable.html#cfn-frauddetector-detector-eventvariable-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Inline": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventvariable.html#cfn-frauddetector-detector-eventvariable-inline", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "LastUpdatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventvariable.html#cfn-frauddetector-detector-eventvariable-lastupdatedtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventvariable.html#cfn-frauddetector-detector-eventvariable-name", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventvariable.html#cfn-frauddetector-detector-eventvariable-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "VariableType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-eventvariable.html#cfn-frauddetector-detector-eventvariable-variabletype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::Detector.Label": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-label.html", + "Properties": { + "Arn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-label.html#cfn-frauddetector-detector-label-arn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "CreatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-label.html#cfn-frauddetector-detector-label-createdtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-label.html#cfn-frauddetector-detector-label-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Inline": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-label.html#cfn-frauddetector-detector-label-inline", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "LastUpdatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-label.html#cfn-frauddetector-detector-label-lastupdatedtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-label.html#cfn-frauddetector-detector-label-name", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-label.html#cfn-frauddetector-detector-label-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::Detector.Outcome": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-outcome.html", + "Properties": { + "Arn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-outcome.html#cfn-frauddetector-detector-outcome-arn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "CreatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-outcome.html#cfn-frauddetector-detector-outcome-createdtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-outcome.html#cfn-frauddetector-detector-outcome-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Inline": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-outcome.html#cfn-frauddetector-detector-outcome-inline", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "LastUpdatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-outcome.html#cfn-frauddetector-detector-outcome-lastupdatedtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-outcome.html#cfn-frauddetector-detector-outcome-name", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-outcome.html#cfn-frauddetector-detector-outcome-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::Detector.Rule": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-rule.html", + "Properties": { + "Arn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-rule.html#cfn-frauddetector-detector-rule-arn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "CreatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-rule.html#cfn-frauddetector-detector-rule-createdtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-rule.html#cfn-frauddetector-detector-rule-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "DetectorId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-rule.html#cfn-frauddetector-detector-rule-detectorid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Expression": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-rule.html#cfn-frauddetector-detector-rule-expression", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Language": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-rule.html#cfn-frauddetector-detector-rule-language", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "LastUpdatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-rule.html#cfn-frauddetector-detector-rule-lastupdatedtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Outcomes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-rule.html#cfn-frauddetector-detector-rule-outcomes", + "DuplicatesAllowed": true, + "ItemType": "Outcome", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "RuleId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-rule.html#cfn-frauddetector-detector-rule-ruleid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "RuleVersion": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-rule.html#cfn-frauddetector-detector-rule-ruleversion", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-detector-rule.html#cfn-frauddetector-detector-rule-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::EventType.EntityType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-entitytype.html", + "Properties": { + "Arn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-entitytype.html#cfn-frauddetector-eventtype-entitytype-arn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "CreatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-entitytype.html#cfn-frauddetector-eventtype-entitytype-createdtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-entitytype.html#cfn-frauddetector-eventtype-entitytype-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Inline": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-entitytype.html#cfn-frauddetector-eventtype-entitytype-inline", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "LastUpdatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-entitytype.html#cfn-frauddetector-eventtype-entitytype-lastupdatedtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-entitytype.html#cfn-frauddetector-eventtype-entitytype-name", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-entitytype.html#cfn-frauddetector-eventtype-entitytype-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::EventType.EventVariable": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-eventvariable.html", + "Properties": { + "Arn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-eventvariable.html#cfn-frauddetector-eventtype-eventvariable-arn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "CreatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-eventvariable.html#cfn-frauddetector-eventtype-eventvariable-createdtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "DataSource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-eventvariable.html#cfn-frauddetector-eventtype-eventvariable-datasource", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "DataType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-eventvariable.html#cfn-frauddetector-eventtype-eventvariable-datatype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "DefaultValue": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-eventvariable.html#cfn-frauddetector-eventtype-eventvariable-defaultvalue", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-eventvariable.html#cfn-frauddetector-eventtype-eventvariable-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Inline": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-eventvariable.html#cfn-frauddetector-eventtype-eventvariable-inline", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "LastUpdatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-eventvariable.html#cfn-frauddetector-eventtype-eventvariable-lastupdatedtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-eventvariable.html#cfn-frauddetector-eventtype-eventvariable-name", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-eventvariable.html#cfn-frauddetector-eventtype-eventvariable-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "VariableType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-eventvariable.html#cfn-frauddetector-eventtype-eventvariable-variabletype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::EventType.Label": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-label.html", + "Properties": { + "Arn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-label.html#cfn-frauddetector-eventtype-label-arn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "CreatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-label.html#cfn-frauddetector-eventtype-label-createdtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-label.html#cfn-frauddetector-eventtype-label-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Inline": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-label.html#cfn-frauddetector-eventtype-label-inline", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "LastUpdatedTime": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-label.html#cfn-frauddetector-eventtype-label-lastupdatedtime", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-label.html#cfn-frauddetector-eventtype-label-name", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-frauddetector-eventtype-label.html#cfn-frauddetector-eventtype-label-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "AWS::GameLift::Alias.RoutingStrategy": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-alias-routingstrategy.html", "Properties": { @@ -25373,6 +26209,46 @@ } } }, + "AWS::GameLift::Fleet.LocationCapacity": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-fleet-locationcapacity.html", + "Properties": { + "DesiredEC2Instances": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-fleet-locationcapacity.html#cfn-gamelift-fleet-locationcapacity-desiredec2instances", + "PrimitiveType": "Integer", + "Required": true, + "UpdateType": "Mutable" + }, + "MaxSize": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-fleet-locationcapacity.html#cfn-gamelift-fleet-locationcapacity-maxsize", + "PrimitiveType": "Integer", + "Required": true, + "UpdateType": "Mutable" + }, + "MinSize": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-fleet-locationcapacity.html#cfn-gamelift-fleet-locationcapacity-minsize", + "PrimitiveType": "Integer", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::GameLift::Fleet.LocationConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-fleet-locationconfiguration.html", + "Properties": { + "Location": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-fleet-locationconfiguration.html#cfn-gamelift-fleet-locationconfiguration-location", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "LocationCapacity": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-fleet-locationconfiguration.html#cfn-gamelift-fleet-locationconfiguration-locationcapacity", + "Required": false, + "Type": "LocationCapacity", + "UpdateType": "Mutable" + } + } + }, "AWS::GameLift::Fleet.ResourceCreationLimitPolicy": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-fleet-resourcecreationlimitpolicy.html", "Properties": { @@ -25516,6 +26392,18 @@ } } }, + "AWS::GameLift::GameSessionQueue.FilterConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-gamesessionqueue-filterconfiguration.html", + "Properties": { + "AllowedLocations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-gamesessionqueue-filterconfiguration.html#cfn-gamelift-gamesessionqueue-filterconfiguration-allowedlocations", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "AWS::GameLift::GameSessionQueue.PlayerLatencyPolicy": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-gamesessionqueue-playerlatencypolicy.html", "Properties": { @@ -25533,6 +26421,25 @@ } } }, + "AWS::GameLift::GameSessionQueue.PriorityConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-gamesessionqueue-priorityconfiguration.html", + "Properties": { + "LocationOrder": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-gamesessionqueue-priorityconfiguration.html#cfn-gamelift-gamesessionqueue-priorityconfiguration-locationorder", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "PriorityOrder": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-gamesessionqueue-priorityconfiguration.html#cfn-gamelift-gamesessionqueue-priorityconfiguration-priorityorder", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "AWS::GameLift::MatchmakingConfiguration.GameProperty": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-gamelift-matchmakingconfiguration-gameproperty.html", "Properties": { @@ -37248,7 +38155,6 @@ "Properties": { "Variables": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-environment.html#cfn-lambda-function-environment-variables", - "DuplicatesAllowed": false, "PrimitiveItemType": "String", "Required": false, "Type": "Map", @@ -37316,17 +38222,17 @@ "Properties": { "SecurityGroupIds": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-vpcconfig.html#cfn-lambda-function-vpcconfig-securitygroupids", - "DuplicatesAllowed": false, + "DuplicatesAllowed": true, "PrimitiveItemType": "String", - "Required": true, + "Required": false, "Type": "List", "UpdateType": "Mutable" }, "SubnetIds": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-vpcconfig.html#cfn-lambda-function-vpcconfig-subnetids", - "DuplicatesAllowed": false, + "DuplicatesAllowed": true, "PrimitiveItemType": "String", - "Required": true, + "Required": false, "Type": "List", "UpdateType": "Mutable" } @@ -38118,6 +39024,17 @@ } } }, + "AWS::MSK::Cluster.Iam": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-msk-cluster-iam.html", + "Properties": { + "Enabled": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-msk-cluster-iam.html#cfn-msk-cluster-iam-enabled", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Immutable" + } + } + }, "AWS::MSK::Cluster.JmxExporter": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-msk-cluster-jmxexporter.html", "Properties": { @@ -38205,9 +39122,15 @@ "AWS::MSK::Cluster.Sasl": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-msk-cluster-sasl.html", "Properties": { + "Iam": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-msk-cluster-sasl.html#cfn-msk-cluster-sasl-iam", + "Required": false, + "Type": "Iam", + "UpdateType": "Immutable" + }, "Scram": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-msk-cluster-sasl.html#cfn-msk-cluster-sasl-scram", - "Required": true, + "Required": false, "Type": "Scram", "UpdateType": "Immutable" } @@ -57304,6 +58227,208 @@ } } }, + "AWS::XRay::Group.InsightsConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-group-insightsconfiguration.html", + "Properties": { + "InsightsEnabled": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-group-insightsconfiguration.html#cfn-xray-group-insightsconfiguration-insightsenabled", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "NotificationsEnabled": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-group-insightsconfiguration.html#cfn-xray-group-insightsconfiguration-notificationsenabled", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::XRay::SamplingRule.SamplingRule": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrule.html", + "Properties": { + "Attributes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrule.html#cfn-xray-samplingrule-samplingrule-attributes", + "PrimitiveItemType": "String", + "Required": false, + "Type": "Map", + "UpdateType": "Mutable" + }, + "FixedRate": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrule.html#cfn-xray-samplingrule-samplingrule-fixedrate", + "PrimitiveType": "Double", + "Required": false, + "UpdateType": "Mutable" + }, + "HTTPMethod": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrule.html#cfn-xray-samplingrule-samplingrule-httpmethod", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Host": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrule.html#cfn-xray-samplingrule-samplingrule-host", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Priority": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrule.html#cfn-xray-samplingrule-samplingrule-priority", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "ReservoirSize": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrule.html#cfn-xray-samplingrule-samplingrule-reservoirsize", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "ResourceARN": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrule.html#cfn-xray-samplingrule-samplingrule-resourcearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "RuleARN": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrule.html#cfn-xray-samplingrule-samplingrule-rulearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "RuleName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrule.html#cfn-xray-samplingrule-samplingrule-rulename", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ServiceName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrule.html#cfn-xray-samplingrule-samplingrule-servicename", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ServiceType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrule.html#cfn-xray-samplingrule-samplingrule-servicetype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "URLPath": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrule.html#cfn-xray-samplingrule-samplingrule-urlpath", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Version": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrule.html#cfn-xray-samplingrule-samplingrule-version", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::XRay::SamplingRule.SamplingRuleRecord": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrulerecord.html", + "Properties": { + "CreatedAt": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrulerecord.html#cfn-xray-samplingrule-samplingrulerecord-createdat", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ModifiedAt": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrulerecord.html#cfn-xray-samplingrule-samplingrulerecord-modifiedat", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SamplingRule": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingrulerecord.html#cfn-xray-samplingrule-samplingrulerecord-samplingrule", + "Required": false, + "Type": "SamplingRule", + "UpdateType": "Mutable" + } + } + }, + "AWS::XRay::SamplingRule.SamplingRuleUpdate": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingruleupdate.html", + "Properties": { + "Attributes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingruleupdate.html#cfn-xray-samplingrule-samplingruleupdate-attributes", + "PrimitiveItemType": "String", + "Required": false, + "Type": "Map", + "UpdateType": "Mutable" + }, + "FixedRate": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingruleupdate.html#cfn-xray-samplingrule-samplingruleupdate-fixedrate", + "PrimitiveType": "Double", + "Required": false, + "UpdateType": "Mutable" + }, + "HTTPMethod": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingruleupdate.html#cfn-xray-samplingrule-samplingruleupdate-httpmethod", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Host": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingruleupdate.html#cfn-xray-samplingrule-samplingruleupdate-host", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Priority": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingruleupdate.html#cfn-xray-samplingrule-samplingruleupdate-priority", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "ReservoirSize": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingruleupdate.html#cfn-xray-samplingrule-samplingruleupdate-reservoirsize", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "ResourceARN": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingruleupdate.html#cfn-xray-samplingrule-samplingruleupdate-resourcearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "RuleARN": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingruleupdate.html#cfn-xray-samplingrule-samplingruleupdate-rulearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "RuleName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingruleupdate.html#cfn-xray-samplingrule-samplingruleupdate-rulename", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ServiceName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingruleupdate.html#cfn-xray-samplingrule-samplingruleupdate-servicename", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "ServiceType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingruleupdate.html#cfn-xray-samplingrule-samplingruleupdate-servicetype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "URLPath": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-xray-samplingrule-samplingruleupdate.html#cfn-xray-samplingrule-samplingruleupdate-urlpath", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "Alexa::ASK::Skill.AuthenticationConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ask-skill-authenticationconfiguration.html", "Properties": { @@ -57391,7 +58516,7 @@ } } }, - "ResourceSpecificationVersion": "35.1.0", + "ResourceSpecificationVersion": "35.2.0", "ResourceTypes": { "AWS::ACMPCA::Certificate": { "Attributes": { @@ -57471,6 +58596,12 @@ "Required": true, "UpdateType": "Immutable" }, + "KeyStorageSecurityStandard": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-acmpca-certificateauthority.html#cfn-acmpca-certificateauthority-keystoragesecuritystandard", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, "RevocationConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-acmpca-certificateauthority.html#cfn-acmpca-certificateauthority-revocationconfiguration", "Required": false, @@ -63271,6 +64402,9 @@ "Attributes": { "DomainName": { "PrimitiveType": "String" + }, + "Id": { + "PrimitiveType": "String" } }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-distribution.html", @@ -63283,6 +64417,7 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-distribution.html#cfn-cloudfront-distribution-tags", + "DuplicatesAllowed": true, "ItemType": "Tag", "Required": false, "Type": "List", @@ -63290,6 +64425,49 @@ } } }, + "AWS::CloudFront::Function": { + "Attributes": { + "FunctionARN": { + "PrimitiveType": "String" + }, + "Stage": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html", + "Properties": { + "AutoPublish": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-autopublish", + "PrimitiveType": "Boolean", + "Required": false, + "UpdateType": "Mutable" + }, + "FunctionCode": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-functioncode", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "FunctionConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-functionconfig", + "Required": false, + "Type": "FunctionConfig", + "UpdateType": "Mutable" + }, + "FunctionMetadata": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-functionmetadata", + "Required": false, + "Type": "FunctionMetadata", + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, "AWS::CloudFront::KeyGroup": { "Attributes": { "Id": { @@ -63842,7 +65020,7 @@ "OutputFormat": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudwatch-metricstream.html#cfn-cloudwatch-metricstream-outputformat", "PrimitiveType": "String", - "Required": false, + "Required": true, "UpdateType": "Mutable" }, "RoleArn": { @@ -65524,10 +66702,16 @@ } }, "AWS::Config::ConfigurationAggregator": { + "Attributes": { + "ConfigurationAggregatorArn": { + "PrimitiveType": "String" + } + }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-config-configurationaggregator.html", "Properties": { "AccountAggregationSources": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-config-configurationaggregator.html#cfn-config-configurationaggregator-accountaggregationsources", + "DuplicatesAllowed": true, "ItemType": "AccountAggregationSource", "Required": false, "Type": "List", @@ -65536,7 +66720,7 @@ "ConfigurationAggregatorName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-config-configurationaggregator.html#cfn-config-configurationaggregator-configurationaggregatorname", "PrimitiveType": "String", - "Required": true, + "Required": false, "UpdateType": "Immutable" }, "OrganizationAggregationSource": { @@ -65547,6 +66731,7 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-config-configurationaggregator.html#cfn-config-configurationaggregator-tags", + "DuplicatesAllowed": false, "ItemType": "Tag", "Required": false, "Type": "List", @@ -66728,8 +67913,8 @@ }, "JobSample": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-databrew-job.html#cfn-databrew-job-jobsample", - "PrimitiveType": "Json", "Required": false, + "Type": "JobSample", "UpdateType": "Mutable" }, "LogSubscription": { @@ -66758,8 +67943,8 @@ }, "OutputLocation": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-databrew-job.html#cfn-databrew-job-outputlocation", - "PrimitiveType": "Json", "Required": false, + "Type": "OutputLocation", "UpdateType": "Mutable" }, "Outputs": { @@ -66779,6 +67964,7 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-databrew-job.html#cfn-databrew-job-recipe", "PrimitiveType": "Json", "Required": false, + "Type": "Recipe", "UpdateType": "Mutable" }, "RoleArn": { @@ -66838,8 +68024,8 @@ }, "Sample": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-databrew-project.html#cfn-databrew-project-sample", - "PrimitiveType": "Json", "Required": false, + "Type": "Sample", "UpdateType": "Mutable" }, "Tags": { @@ -71055,10 +72241,19 @@ "Attributes": { "Arn": { "PrimitiveType": "String" + }, + "RepositoryUri": { + "PrimitiveType": "String" } }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecr-repository.html", "Properties": { + "EncryptionConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecr-repository.html#cfn-ecr-repository-encryptionconfiguration", + "PrimitiveType": "Json", + "Required": false, + "UpdateType": "Immutable" + }, "ImageScanningConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecr-repository.html#cfn-ecr-repository-imagescanningconfiguration", "PrimitiveType": "Json", @@ -71226,6 +72421,9 @@ "Attributes": { "Name": { "PrimitiveType": "String" + }, + "ServiceArn": { + "PrimitiveType": "String" } }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-service.html", @@ -71336,12 +72534,6 @@ "Required": false, "UpdateType": "Immutable" }, - "ServiceArn": { - "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-service.html#cfn-ecs-service-servicearn", - "PrimitiveType": "String", - "Required": false, - "UpdateType": "Mutable" - }, "ServiceName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-service.html#cfn-ecs-service-servicename", "PrimitiveType": "String", @@ -71392,6 +72584,12 @@ "Required": false, "UpdateType": "Immutable" }, + "EphemeralStorage": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html#cfn-ecs-taskdefinition-ephemeralstorage", + "Required": false, + "Type": "EphemeralStorage", + "UpdateType": "Mutable" + }, "ExecutionRoleArn": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html#cfn-ecs-taskdefinition-executionrolearn", "PrimitiveType": "String", @@ -71983,6 +73181,13 @@ "Required": false, "UpdateType": "Mutable" }, + "Taints": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-nodegroup.html#cfn-eks-nodegroup-taints", + "ItemType": "Taint", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "Version": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-eks-nodegroup.html#cfn-eks-nodegroup-version", "PrimitiveType": "String", @@ -74523,6 +75728,357 @@ } } }, + "AWS::FinSpace::Environment": { + "Attributes": { + "AwsAccountId": { + "PrimitiveType": "String" + }, + "DedicatedServiceAccountId": { + "PrimitiveType": "String" + }, + "EnvironmentArn": { + "PrimitiveType": "String" + }, + "EnvironmentId": { + "PrimitiveType": "String" + }, + "EnvironmentUrl": { + "PrimitiveType": "String" + }, + "SageMakerStudioDomainUrl": { + "PrimitiveType": "String" + }, + "Status": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-finspace-environment.html", + "Properties": { + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-finspace-environment.html#cfn-finspace-environment-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "FederationMode": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-finspace-environment.html#cfn-finspace-environment-federationmode", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "FederationParameters": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-finspace-environment.html#cfn-finspace-environment-federationparameters", + "Required": false, + "Type": "FederationParameters", + "UpdateType": "Mutable" + }, + "KmsKeyId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-finspace-environment.html#cfn-finspace-environment-kmskeyid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-finspace-environment.html#cfn-finspace-environment-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::Detector": { + "Attributes": { + "Arn": { + "PrimitiveType": "String" + }, + "CreatedTime": { + "PrimitiveType": "String" + }, + "DetectorVersionId": { + "PrimitiveType": "String" + }, + "LastUpdatedTime": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-detector.html", + "Properties": { + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-detector.html#cfn-frauddetector-detector-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "DetectorId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-detector.html#cfn-frauddetector-detector-detectorid", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "DetectorVersionStatus": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-detector.html#cfn-frauddetector-detector-detectorversionstatus", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "EventType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-detector.html#cfn-frauddetector-detector-eventtype", + "Required": true, + "Type": "EventType", + "UpdateType": "Mutable" + }, + "RuleExecutionMode": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-detector.html#cfn-frauddetector-detector-ruleexecutionmode", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Rules": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-detector.html#cfn-frauddetector-detector-rules", + "DuplicatesAllowed": true, + "ItemType": "Rule", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-detector.html#cfn-frauddetector-detector-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::EntityType": { + "Attributes": { + "Arn": { + "PrimitiveType": "String" + }, + "CreatedTime": { + "PrimitiveType": "String" + }, + "LastUpdatedTime": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-entitytype.html", + "Properties": { + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-entitytype.html#cfn-frauddetector-entitytype-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-entitytype.html#cfn-frauddetector-entitytype-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-entitytype.html#cfn-frauddetector-entitytype-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::EventType": { + "Attributes": { + "Arn": { + "PrimitiveType": "String" + }, + "CreatedTime": { + "PrimitiveType": "String" + }, + "LastUpdatedTime": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-eventtype.html", + "Properties": { + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-eventtype.html#cfn-frauddetector-eventtype-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "EntityTypes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-eventtype.html#cfn-frauddetector-eventtype-entitytypes", + "DuplicatesAllowed": true, + "ItemType": "EntityType", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "EventVariables": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-eventtype.html#cfn-frauddetector-eventtype-eventvariables", + "DuplicatesAllowed": true, + "ItemType": "EventVariable", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "Labels": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-eventtype.html#cfn-frauddetector-eventtype-labels", + "DuplicatesAllowed": true, + "ItemType": "Label", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-eventtype.html#cfn-frauddetector-eventtype-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-eventtype.html#cfn-frauddetector-eventtype-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::Label": { + "Attributes": { + "Arn": { + "PrimitiveType": "String" + }, + "CreatedTime": { + "PrimitiveType": "String" + }, + "LastUpdatedTime": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-label.html", + "Properties": { + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-label.html#cfn-frauddetector-label-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-label.html#cfn-frauddetector-label-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-label.html#cfn-frauddetector-label-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::Outcome": { + "Attributes": { + "Arn": { + "PrimitiveType": "String" + }, + "CreatedTime": { + "PrimitiveType": "String" + }, + "LastUpdatedTime": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-outcome.html", + "Properties": { + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-outcome.html#cfn-frauddetector-outcome-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-outcome.html#cfn-frauddetector-outcome-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-outcome.html#cfn-frauddetector-outcome-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::FraudDetector::Variable": { + "Attributes": { + "Arn": { + "PrimitiveType": "String" + }, + "CreatedTime": { + "PrimitiveType": "String" + }, + "LastUpdatedTime": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-variable.html", + "Properties": { + "DataSource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-variable.html#cfn-frauddetector-variable-datasource", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "DataType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-variable.html#cfn-frauddetector-variable-datatype", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "DefaultValue": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-variable.html#cfn-frauddetector-variable-defaultvalue", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "Description": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-variable.html#cfn-frauddetector-variable-description", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-variable.html#cfn-frauddetector-variable-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-variable.html#cfn-frauddetector-variable-tags", + "DuplicatesAllowed": true, + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "VariableType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-frauddetector-variable.html#cfn-frauddetector-variable-variabletype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::GameLift::Alias": { "Attributes": { "AliasId": { @@ -74637,6 +76193,13 @@ "Required": false, "UpdateType": "Immutable" }, + "Locations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-gamelift-fleet.html#cfn-gamelift-fleet-locations", + "ItemType": "LocationConfiguration", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "MaxSize": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-gamelift-fleet.html#cfn-gamelift-fleet-maxsize", "PrimitiveType": "Integer", @@ -74812,6 +76375,12 @@ "Type": "List", "UpdateType": "Mutable" }, + "FilterConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-gamelift-gamesessionqueue.html#cfn-gamelift-gamesessionqueue-filterconfiguration", + "Required": false, + "Type": "FilterConfiguration", + "UpdateType": "Mutable" + }, "Name": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-gamelift-gamesessionqueue.html#cfn-gamelift-gamesessionqueue-name", "PrimitiveType": "String", @@ -74831,6 +76400,12 @@ "Type": "List", "UpdateType": "Mutable" }, + "PriorityConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-gamelift-gamesessionqueue.html#cfn-gamelift-gamesessionqueue-priorityconfiguration", + "Required": false, + "Type": "PriorityConfiguration", + "UpdateType": "Mutable" + }, "TimeoutInSeconds": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-gamelift-gamesessionqueue.html#cfn-gamelift-gamesessionqueue-timeoutinseconds", "PrimitiveType": "Integer", @@ -80645,7 +82220,6 @@ }, "FileSystemConfigs": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-filesystemconfigs", - "DuplicatesAllowed": false, "ItemType": "FileSystemConfig", "Required": false, "Type": "List", @@ -80663,6 +82237,12 @@ "Required": false, "UpdateType": "Mutable" }, + "Id": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-id", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "ImageConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-imageconfig", "Required": false, @@ -80677,7 +82257,7 @@ }, "Layers": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-layers", - "DuplicatesAllowed": false, + "DuplicatesAllowed": true, "PrimitiveItemType": "String", "Required": false, "Type": "List", @@ -80715,7 +82295,7 @@ }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-tags", - "DuplicatesAllowed": true, + "DuplicatesAllowed": false, "ItemType": "Tag", "Required": false, "Type": "List", @@ -93249,6 +94829,82 @@ } } }, + "AWS::XRay::Group": { + "Attributes": { + "GroupARN": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-xray-group.html", + "Properties": { + "FilterExpression": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-xray-group.html#cfn-xray-group-filterexpression", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "GroupName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-xray-group.html#cfn-xray-group-groupname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "InsightsConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-xray-group.html#cfn-xray-group-insightsconfiguration", + "Required": false, + "Type": "InsightsConfiguration", + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-xray-group.html#cfn-xray-group-tags", + "ItemType": "Json", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::XRay::SamplingRule": { + "Attributes": { + "RuleARN": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-xray-samplingrule.html", + "Properties": { + "RuleName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-xray-samplingrule.html#cfn-xray-samplingrule-rulename", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "SamplingRule": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-xray-samplingrule.html#cfn-xray-samplingrule-samplingrule", + "Required": false, + "Type": "SamplingRule", + "UpdateType": "Mutable" + }, + "SamplingRuleRecord": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-xray-samplingrule.html#cfn-xray-samplingrule-samplingrulerecord", + "Required": false, + "Type": "SamplingRuleRecord", + "UpdateType": "Mutable" + }, + "SamplingRuleUpdate": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-xray-samplingrule.html#cfn-xray-samplingrule-samplingruleupdate", + "Required": false, + "Type": "SamplingRuleUpdate", + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-xray-samplingrule.html#cfn-xray-samplingrule-tags", + "ItemType": "Json", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "Alexa::ASK::Skill": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ask-skill.html", "Properties": { diff --git a/packages/@aws-cdk/cfnspec/spec-source/900_CloudFront_OriginShield_patch.json b/packages/@aws-cdk/cfnspec/spec-source/900_CloudFront_OriginShield_patch.json new file mode 100644 index 0000000000000..44c5c8eb33400 --- /dev/null +++ b/packages/@aws-cdk/cfnspec/spec-source/900_CloudFront_OriginShield_patch.json @@ -0,0 +1,16 @@ +{ + "PropertyTypes": { + "AWS::CloudFront::Distribution.Origin": { + "patch": { + "description": "Add Type to OriginShield property of AWS::CloudFront::Distribution.Origin", + "operations": [ + { + "op": "add", + "path": "/Properties/OriginShield/Type", + "value": "OriginShield" + } + ] + } + } + } +} diff --git a/packages/@aws-cdk/cfnspec/spec-source/900_XRay_Tags_ItemType_patch.json b/packages/@aws-cdk/cfnspec/spec-source/900_XRay_Tags_ItemType_patch.json new file mode 100644 index 0000000000000..c504e20b59c24 --- /dev/null +++ b/packages/@aws-cdk/cfnspec/spec-source/900_XRay_Tags_ItemType_patch.json @@ -0,0 +1,27 @@ +{ + "ResourceTypes": { + "patch": { + "description": "Rename ItemType to PrimitiveItemType for Tags property of AWS::XRay Group and SamplingRule resources", + "operations": [ + { + "op": "remove", + "path": "/AWS::XRay::Group/Properties/Tags/ItemType" + }, + { + "op": "add", + "path": "/AWS::XRay::Group/Properties/Tags/PrimitiveItemType", + "value": "Json" + }, + { + "op": "remove", + "path": "/AWS::XRay::SamplingRule/Properties/Tags/ItemType" + }, + { + "op": "add", + "path": "/AWS::XRay::SamplingRule/Properties/Tags/PrimitiveItemType", + "value": "Json" + } + ] + } + } +} diff --git a/packages/@aws-cdk/cloudformation-include/package.json b/packages/@aws-cdk/cloudformation-include/package.json index 218742424f03e..36fd0bfd649a5 100644 --- a/packages/@aws-cdk/cloudformation-include/package.json +++ b/packages/@aws-cdk/cloudformation-include/package.json @@ -133,8 +133,10 @@ "@aws-cdk/aws-emrcontainers": "0.0.0", "@aws-cdk/aws-events": "0.0.0", "@aws-cdk/aws-eventschemas": "0.0.0", + "@aws-cdk/aws-finspace": "0.0.0", "@aws-cdk/aws-fis": "0.0.0", "@aws-cdk/aws-fms": "0.0.0", + "@aws-cdk/aws-frauddetector": "0.0.0", "@aws-cdk/aws-fsx": "0.0.0", "@aws-cdk/aws-gamelift": "0.0.0", "@aws-cdk/aws-globalaccelerator": "0.0.0", @@ -217,6 +219,7 @@ "@aws-cdk/aws-wafregional": "0.0.0", "@aws-cdk/aws-wafv2": "0.0.0", "@aws-cdk/aws-workspaces": "0.0.0", + "@aws-cdk/aws-xray": "0.0.0", "@aws-cdk/core": "0.0.0", "constructs": "^3.3.69", "yaml": "1.10.2" @@ -290,8 +293,10 @@ "@aws-cdk/aws-emrcontainers": "0.0.0", "@aws-cdk/aws-events": "0.0.0", "@aws-cdk/aws-eventschemas": "0.0.0", + "@aws-cdk/aws-finspace": "0.0.0", "@aws-cdk/aws-fis": "0.0.0", "@aws-cdk/aws-fms": "0.0.0", + "@aws-cdk/aws-frauddetector": "0.0.0", "@aws-cdk/aws-fsx": "0.0.0", "@aws-cdk/aws-gamelift": "0.0.0", "@aws-cdk/aws-globalaccelerator": "0.0.0", @@ -374,6 +379,7 @@ "@aws-cdk/aws-wafregional": "0.0.0", "@aws-cdk/aws-wafv2": "0.0.0", "@aws-cdk/aws-workspaces": "0.0.0", + "@aws-cdk/aws-xray": "0.0.0", "@aws-cdk/core": "0.0.0", "constructs": "^3.3.69" }, diff --git a/packages/@aws-cdk/core/lib/assets.ts b/packages/@aws-cdk/core/lib/assets.ts index d9bd02d4d91a9..289ef925189fe 100644 --- a/packages/@aws-cdk/core/lib/assets.ts +++ b/packages/@aws-cdk/core/lib/assets.ts @@ -117,7 +117,7 @@ export interface FileAssetSource { /** * The path, relative to the root of the cloud assembly, in which this asset - * source resides. This can be a path to a file or a directory, dependning on the + * source resides. This can be a path to a file or a directory, depending on the * packaging type. * * @default - Exactly one of `directory` and `executable` is required diff --git a/packages/@aws-cdk/core/package.json b/packages/@aws-cdk/core/package.json index af2e803a1f7f8..c926741368a48 100644 --- a/packages/@aws-cdk/core/package.json +++ b/packages/@aws-cdk/core/package.json @@ -177,7 +177,7 @@ "@types/aws-lambda": "^8.10.76", "@types/fs-extra": "^8.1.1", "@types/jest": "^26.0.23", - "@types/lodash": "^4.14.168", + "@types/lodash": "^4.14.169", "@types/minimatch": "^3.0.4", "@types/node": "^10.17.59", "@types/sinon": "^9.0.11", diff --git a/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts b/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts index 56d485e83d4fa..807dc7e78fec5 100644 --- a/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts +++ b/packages/@aws-cdk/custom-resources/lib/aws-custom-resource/runtime/index.ts @@ -1,5 +1,11 @@ /* eslint-disable no-console */ import { execSync } from 'child_process'; +// import the AWSLambda package explicitly, +// which is globally available in the Lambda runtime, +// as otherwise linking this repository with link-all.sh +// fails in the CDK app executed with ts-node +/* eslint-disable-next-line import/no-extraneous-dependencies,import/no-unresolved */ +import * as AWSLambda from 'aws-lambda'; import { AwsSdkCall } from '../aws-custom-resource'; /** @@ -204,4 +210,4 @@ export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent function decodeCall(call: string | undefined) { if (!call) { return undefined; } return JSON.parse(call); -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/pipelines/README.md b/packages/@aws-cdk/pipelines/README.md index 6097c87c16426..074c1b331ee41 100644 --- a/packages/@aws-cdk/pipelines/README.md +++ b/packages/@aws-cdk/pipelines/README.md @@ -596,7 +596,7 @@ to create it in. If you are deploying your application to different environments also have to bootstrap those and be sure to add a *trust* relationship. > This library requires a newer version of the bootstrapping stack which has -> been updated specifically to support cross-account continous delivery. In the future, +> been updated specifically to support cross-account continuous delivery. In the future, > this new bootstrapping stack will become the default, but for now it is still > opt-in. > diff --git a/packages/aws-cdk-lib/package.json b/packages/aws-cdk-lib/package.json index ecc5f73614f4b..22ba72ab4eafd 100644 --- a/packages/aws-cdk-lib/package.json +++ b/packages/aws-cdk-lib/package.json @@ -192,8 +192,10 @@ "@aws-cdk/aws-events": "0.0.0", "@aws-cdk/aws-events-targets": "0.0.0", "@aws-cdk/aws-eventschemas": "0.0.0", + "@aws-cdk/aws-finspace": "0.0.0", "@aws-cdk/aws-fis": "0.0.0", "@aws-cdk/aws-fms": "0.0.0", + "@aws-cdk/aws-frauddetector": "0.0.0", "@aws-cdk/aws-fsx": "0.0.0", "@aws-cdk/aws-gamelift": "0.0.0", "@aws-cdk/aws-globalaccelerator": "0.0.0", @@ -225,8 +227,8 @@ "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/aws-lambda-destinations": "0.0.0", "@aws-cdk/aws-lambda-event-sources": "0.0.0", - "@aws-cdk/aws-lambda-nodejs": "0.0.0", "@aws-cdk/aws-lambda-go": "0.0.0", + "@aws-cdk/aws-lambda-nodejs": "0.0.0", "@aws-cdk/aws-lambda-python": "0.0.0", "@aws-cdk/aws-licensemanager": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", @@ -292,6 +294,7 @@ "@aws-cdk/aws-wafregional": "0.0.0", "@aws-cdk/aws-wafv2": "0.0.0", "@aws-cdk/aws-workspaces": "0.0.0", + "@aws-cdk/aws-xray": "0.0.0", "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/cloudformation-include": "0.0.0", "@aws-cdk/core": "0.0.0", diff --git a/packages/aws-cdk/lib/init-templates/v1/app/javascript/jest.config.js b/packages/aws-cdk/lib/init-templates/v1/app/javascript/jest.config.js new file mode 100644 index 0000000000000..668e089fb02b3 --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v1/app/javascript/jest.config.js @@ -0,0 +1,3 @@ +module.exports = { + testEnvironment: "node" +} diff --git a/packages/aws-cdk/lib/init-templates/v1/app/typescript/jest.config.js b/packages/aws-cdk/lib/init-templates/v1/app/typescript/jest.config.js index 772f974903b79..08263b8954a42 100644 --- a/packages/aws-cdk/lib/init-templates/v1/app/typescript/jest.config.js +++ b/packages/aws-cdk/lib/init-templates/v1/app/typescript/jest.config.js @@ -1,4 +1,5 @@ module.exports = { + testEnvironment: 'node', roots: ['/test'], testMatch: ['**/*.test.ts'], transform: { diff --git a/packages/aws-cdk/lib/init-templates/v1/lib/typescript/jest.config.js b/packages/aws-cdk/lib/init-templates/v1/lib/typescript/jest.config.js index 772f974903b79..08263b8954a42 100644 --- a/packages/aws-cdk/lib/init-templates/v1/lib/typescript/jest.config.js +++ b/packages/aws-cdk/lib/init-templates/v1/lib/typescript/jest.config.js @@ -1,4 +1,5 @@ module.exports = { + testEnvironment: 'node', roots: ['/test'], testMatch: ['**/*.test.ts'], transform: { diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/jest.config.js b/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/jest.config.js new file mode 100644 index 0000000000000..95495de92eb8c --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/javascript/jest.config.js @@ -0,0 +1,3 @@ +module.exports = { + testEnvironment: 'node' +} diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/app.template.py b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/app.template.py index 580bbee9e069c..808bc22af32e4 100644 --- a/packages/aws-cdk/lib/init-templates/v1/sample-app/python/app.template.py +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/python/app.template.py @@ -6,6 +6,6 @@ app = core.App() -%name.PascalCased%Stack(app, "%name.StackName%", env={'region': 'us-west-2'}) +%name.PascalCased%Stack(app, "%name.StackName%") app.synth() diff --git a/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/jest.config.js b/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/jest.config.js index 772f974903b79..08263b8954a42 100644 --- a/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/jest.config.js +++ b/packages/aws-cdk/lib/init-templates/v1/sample-app/typescript/jest.config.js @@ -1,4 +1,5 @@ module.exports = { + testEnvironment: 'node', roots: ['/test'], testMatch: ['**/*.test.ts'], transform: { diff --git a/packages/aws-cdk/lib/init-templates/v2/app/javascript/jest.config.js b/packages/aws-cdk/lib/init-templates/v2/app/javascript/jest.config.js new file mode 100644 index 0000000000000..95495de92eb8c --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v2/app/javascript/jest.config.js @@ -0,0 +1,3 @@ +module.exports = { + testEnvironment: 'node' +} diff --git a/packages/aws-cdk/lib/init-templates/v2/app/typescript/jest.config.js b/packages/aws-cdk/lib/init-templates/v2/app/typescript/jest.config.js index 772f974903b79..08263b8954a42 100644 --- a/packages/aws-cdk/lib/init-templates/v2/app/typescript/jest.config.js +++ b/packages/aws-cdk/lib/init-templates/v2/app/typescript/jest.config.js @@ -1,4 +1,5 @@ module.exports = { + testEnvironment: 'node', roots: ['/test'], testMatch: ['**/*.test.ts'], transform: { diff --git a/packages/aws-cdk/lib/init-templates/v2/lib/typescript/jest.config.js b/packages/aws-cdk/lib/init-templates/v2/lib/typescript/jest.config.js index 772f974903b79..08263b8954a42 100644 --- a/packages/aws-cdk/lib/init-templates/v2/lib/typescript/jest.config.js +++ b/packages/aws-cdk/lib/init-templates/v2/lib/typescript/jest.config.js @@ -1,4 +1,5 @@ module.exports = { + testEnvironment: 'node', roots: ['/test'], testMatch: ['**/*.test.ts'], transform: { diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/jest.config.js b/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/jest.config.js new file mode 100644 index 0000000000000..95495de92eb8c --- /dev/null +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/javascript/jest.config.js @@ -0,0 +1,3 @@ +module.exports = { + testEnvironment: 'node' +} diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/app.template.py b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/app.template.py index 1f64e6a67bc56..49094e6711cbf 100644 --- a/packages/aws-cdk/lib/init-templates/v2/sample-app/python/app.template.py +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/python/app.template.py @@ -6,6 +6,6 @@ app = cdk.App() -%name.PascalCased%Stack(app, "%name.StackName%", env={'region': 'us-west-2'}) +%name.PascalCased%Stack(app, "%name.StackName%") app.synth() diff --git a/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/jest.config.js b/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/jest.config.js index 772f974903b79..08263b8954a42 100644 --- a/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/jest.config.js +++ b/packages/aws-cdk/lib/init-templates/v2/sample-app/typescript/jest.config.js @@ -1,4 +1,5 @@ module.exports = { + testEnvironment: 'node', roots: ['/test'], testMatch: ['**/*.test.ts'], transform: { diff --git a/packages/aws-cdk/lib/version.ts b/packages/aws-cdk/lib/version.ts index 19bec86549c2e..e407935ce2bfa 100644 --- a/packages/aws-cdk/lib/version.ts +++ b/packages/aws-cdk/lib/version.ts @@ -108,7 +108,7 @@ export async function displayVersionMessage(): Promise { if (laterVersion) { const bannerMsg = formatAsBanner([ `Newer version of CDK is available [${colors.green(laterVersion as string)}]`, - 'Upgrade recommended', + 'Upgrade recommended (npm install -g aws-cdk)', ]); bannerMsg.forEach((e) => print(e)); } diff --git a/packages/awslint/package.json b/packages/awslint/package.json index dab312dc46ea0..6b91a94c8349d 100644 --- a/packages/awslint/package.json +++ b/packages/awslint/package.json @@ -29,8 +29,8 @@ "@types/yargs": "^15.0.13", "pkglint": "0.0.0", "typescript": "~3.9.9", - "@typescript-eslint/eslint-plugin": "^4.22.1", - "@typescript-eslint/parser": "^4.22.1", + "@typescript-eslint/eslint-plugin": "^4.23.0", + "@typescript-eslint/parser": "^4.23.0", "eslint": "^7.26.0", "eslint-import-resolver-node": "^0.3.4", "eslint-import-resolver-typescript": "^2.4.0", diff --git a/packages/decdk/package.json b/packages/decdk/package.json index 210bc6ee109db..f72bb5df7e89b 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -109,8 +109,10 @@ "@aws-cdk/aws-events": "0.0.0", "@aws-cdk/aws-events-targets": "0.0.0", "@aws-cdk/aws-eventschemas": "0.0.0", + "@aws-cdk/aws-finspace": "0.0.0", "@aws-cdk/aws-fis": "0.0.0", "@aws-cdk/aws-fms": "0.0.0", + "@aws-cdk/aws-frauddetector": "0.0.0", "@aws-cdk/aws-fsx": "0.0.0", "@aws-cdk/aws-gamelift": "0.0.0", "@aws-cdk/aws-globalaccelerator": "0.0.0", @@ -142,10 +144,10 @@ "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/aws-lambda-destinations": "0.0.0", "@aws-cdk/aws-lambda-event-sources": "0.0.0", + "@aws-cdk/aws-lambda-go": "0.0.0", "@aws-cdk/aws-lambda-nodejs": "0.0.0", "@aws-cdk/aws-lambda-python": "0.0.0", "@aws-cdk/aws-licensemanager": "0.0.0", - "@aws-cdk/aws-lambda-go": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-logs-destinations": "0.0.0", "@aws-cdk/aws-lookoutmetrics": "0.0.0", @@ -209,6 +211,7 @@ "@aws-cdk/aws-wafregional": "0.0.0", "@aws-cdk/aws-wafv2": "0.0.0", "@aws-cdk/aws-workspaces": "0.0.0", + "@aws-cdk/aws-xray": "0.0.0", "@aws-cdk/cfnspec": "0.0.0", "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/core": "0.0.0", diff --git a/packages/monocdk/package.json b/packages/monocdk/package.json index 0a5750d59db78..06b2c423cfc45 100644 --- a/packages/monocdk/package.json +++ b/packages/monocdk/package.json @@ -193,8 +193,10 @@ "@aws-cdk/aws-events": "0.0.0", "@aws-cdk/aws-events-targets": "0.0.0", "@aws-cdk/aws-eventschemas": "0.0.0", + "@aws-cdk/aws-finspace": "0.0.0", "@aws-cdk/aws-fis": "0.0.0", "@aws-cdk/aws-fms": "0.0.0", + "@aws-cdk/aws-frauddetector": "0.0.0", "@aws-cdk/aws-fsx": "0.0.0", "@aws-cdk/aws-gamelift": "0.0.0", "@aws-cdk/aws-globalaccelerator": "0.0.0", @@ -226,8 +228,8 @@ "@aws-cdk/aws-lambda": "0.0.0", "@aws-cdk/aws-lambda-destinations": "0.0.0", "@aws-cdk/aws-lambda-event-sources": "0.0.0", - "@aws-cdk/aws-lambda-nodejs": "0.0.0", "@aws-cdk/aws-lambda-go": "0.0.0", + "@aws-cdk/aws-lambda-nodejs": "0.0.0", "@aws-cdk/aws-lambda-python": "0.0.0", "@aws-cdk/aws-licensemanager": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", @@ -293,6 +295,7 @@ "@aws-cdk/aws-wafregional": "0.0.0", "@aws-cdk/aws-wafv2": "0.0.0", "@aws-cdk/aws-workspaces": "0.0.0", + "@aws-cdk/aws-xray": "0.0.0", "@aws-cdk/cloud-assembly-schema": "0.0.0", "@aws-cdk/cloudformation-include": "0.0.0", "@aws-cdk/core": "0.0.0", diff --git a/scripts/check-build-prerequisites.sh b/scripts/check-build-prerequisites.sh old mode 100644 new mode 100755 index c703d9f3e94e7..4414ff378a48d --- a/scripts/check-build-prerequisites.sh +++ b/scripts/check-build-prerequisites.sh @@ -42,7 +42,7 @@ app_v=$(node --version) # Check for version 10.*.* - 29.*.* echo -e "Checking node version... \c" if [ $(echo $app_v | grep -c -E "v[12][0-9]\.[0-9]+\.[0-9]+") -eq 1 ] -then +then # Check for version 13.0 to 13.6 if [ $(echo $app_v | grep -c -E "v13\.[0-6]\.[0-9]+") -eq 1 ] then @@ -50,7 +50,7 @@ then else # Check for version < 10.13 if [ $(echo $app_v | grep -c -E "v10\.([0-9]|1[0-2])\.[0-9]+") -eq 1 ] - then + then wrong_version else echo "Ok" @@ -68,7 +68,7 @@ check_which $app $app_min app_v=$(${app} --version) echo -e "Checking yarn version... \c" if [ $(echo $app_v | grep -c -E "1\.(19|2[0-9])\.[0-9]+") -eq 1 ] -then +then echo "Ok" else wrong_version @@ -83,9 +83,34 @@ check_which $app $app_min echo -e "Checking if docker is running... \c" docker_running=$(docker ps) if [ $? -eq 0 ] -then +then echo "Ok" else die "Docker is not running" fi +# [.NET == 3.1.x] +app="dotnet" +app_min="3.1.0" +check_which $app $app_min +app_v=$(${app} --version) +echo -e "Checking dotnet version... \c" +if [ $(echo $app_v | grep -c -E "3\.1\.[0-9]+") -eq 1 ] +then + echo "Ok" +else + wrong_version +fi + +# [Python >= 3.6.5, < 4.0] +app="python3" +app_min="3.6.5" +check_which $app $app_min +app_v=$(${app} --version) +echo -e "Checking python3 version... \c" +if [ $(echo $app_v | grep -c -E "3\.[6-9]+\.[0-9]+") -eq 1 ] +then + echo "Ok" +else + wrong_version +fi diff --git a/scripts/check-yarn-lock.js b/scripts/check-yarn-lock.js index 285128b3b18a6..d13e4e08cf64f 100755 --- a/scripts/check-yarn-lock.js +++ b/scripts/check-yarn-lock.js @@ -45,9 +45,9 @@ async function main() { } projects.forEach((p) => { - Object.entries(p.devDependencies ?? {}).forEach(([depName, depVersion]) => errorIfNotInYarnLock(p, depName, depVersion)); - Object.entries(p.peerDependencies ?? {}).forEach(([depName, depVersion]) => errorIfNotInYarnLock(p, depName, depVersion)); - Object.entries(p.dependencies ?? {}).forEach(([depName, depVersion]) => errorIfNotInYarnLock(p, depName, depVersion)); + Object.entries(p.devDependencies || {}).forEach(([depName, depVersion]) => errorIfNotInYarnLock(p, depName, depVersion)); + Object.entries(p.peerDependencies || {}).forEach(([depName, depVersion]) => errorIfNotInYarnLock(p, depName, depVersion)); + Object.entries(p.dependencies || {}).forEach(([depName, depVersion]) => errorIfNotInYarnLock(p, depName, depVersion)); }); } diff --git a/tools/cdk-build-tools/package.json b/tools/cdk-build-tools/package.json index 994b0248e9882..8e31468544319 100644 --- a/tools/cdk-build-tools/package.json +++ b/tools/cdk-build-tools/package.json @@ -40,8 +40,8 @@ "pkglint": "0.0.0" }, "dependencies": { - "@typescript-eslint/eslint-plugin": "^4.22.1", - "@typescript-eslint/parser": "^4.22.1", + "@typescript-eslint/eslint-plugin": "^4.23.0", + "@typescript-eslint/parser": "^4.23.0", "awslint": "0.0.0", "colors": "^1.4.0", "eslint": "^7.26.0", diff --git a/tools/eslint-plugin-cdk/package.json b/tools/eslint-plugin-cdk/package.json index 0d07037e93385..562f31110ad8d 100644 --- a/tools/eslint-plugin-cdk/package.json +++ b/tools/eslint-plugin-cdk/package.json @@ -21,7 +21,7 @@ "typescript": "~3.9.9" }, "dependencies": { - "@typescript-eslint/parser": "^4.22.1", + "@typescript-eslint/parser": "^4.23.0", "eslint": "^7.26.0", "fs-extra": "^9.1.0" }, diff --git a/tools/pkglint/package.json b/tools/pkglint/package.json index 21c682d12b91d..0fd91fcb0d2a0 100644 --- a/tools/pkglint/package.json +++ b/tools/pkglint/package.json @@ -40,8 +40,8 @@ "@types/jest": "^26.0.23", "@types/semver": "^7.3.5", "@types/yargs": "^15.0.13", - "@typescript-eslint/eslint-plugin": "^4.22.1", - "@typescript-eslint/parser": "^4.22.1", + "@typescript-eslint/eslint-plugin": "^4.23.0", + "@typescript-eslint/parser": "^4.23.0", "eslint": "^7.26.0", "eslint-import-resolver-node": "^0.3.4", "eslint-import-resolver-typescript": "^2.4.0", diff --git a/version.v1.json b/version.v1.json index 60bdf592f8796..9076251f5032f 100644 --- a/version.v1.json +++ b/version.v1.json @@ -1,3 +1,3 @@ { - "version": "1.103.0" + "version": "1.104.0" } diff --git a/yarn.lock b/yarn.lock index cd9959d6a69fe..0be97e7c4e3ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1529,10 +1529,10 @@ dependencies: jszip "*" -"@types/lodash@^4.14.168": - version "4.14.168" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.168.tgz#fe24632e79b7ade3f132891afff86caa5e5ce008" - integrity sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q== +"@types/lodash@^4.14.169": + version "4.14.169" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.169.tgz#83c217688f07a4d9ef8f28a3ebd1d318f6ff4cbb" + integrity sha512-DvmZHoHTFJ8zhVYwCLWbQ7uAbYQEk52Ev2/ZiQ7Y7gQGeV9pjBqjnQpECMHfKS1rCYAhMI7LHVxwyZLZinJgdw== "@types/md5@^2.3.0": version "2.3.0" @@ -1692,13 +1692,13 @@ resolved "https://registry.yarnpkg.com/@types/yarnpkg__lockfile/-/yarnpkg__lockfile-1.1.4.tgz#445251eb00bd9c1e751f82c7c6bf4f714edfd464" integrity sha512-/emrKCfQMQmFCqRqqBJ0JueHBT06jBRM3e8OgnvDUcvuExONujIk2hFA5dNsN9Nt41ljGVDdChvCydATZ+KOZw== -"@typescript-eslint/eslint-plugin@^4.22.1": - version "4.22.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.22.1.tgz#6bcdbaa4548553ab861b4e5f34936ead1349a543" - integrity sha512-kVTAghWDDhsvQ602tHBc6WmQkdaYbkcTwZu+7l24jtJiYvm9l+/y/b2BZANEezxPDiX5MK2ZecE+9BFi/YJryw== +"@typescript-eslint/eslint-plugin@^4.23.0": + version "4.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.23.0.tgz#29d3c9c81f6200b1fd6d8454cfb007ba176cde80" + integrity sha512-tGK1y3KIvdsQEEgq6xNn1DjiFJtl+wn8JJQiETtCbdQxw1vzjXyAaIkEmO2l6Nq24iy3uZBMFQjZ6ECf1QdgGw== dependencies: - "@typescript-eslint/experimental-utils" "4.22.1" - "@typescript-eslint/scope-manager" "4.22.1" + "@typescript-eslint/experimental-utils" "4.23.0" + "@typescript-eslint/scope-manager" "4.23.0" debug "^4.1.1" functional-red-black-tree "^1.0.1" lodash "^4.17.15" @@ -1706,7 +1706,19 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@4.22.1", "@typescript-eslint/experimental-utils@^4.0.1": +"@typescript-eslint/experimental-utils@4.23.0": + version "4.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.23.0.tgz#f2059434cd6e5672bfeab2fb03b7c0a20622266f" + integrity sha512-WAFNiTDnQfrF3Z2fQ05nmCgPsO5o790vOhmWKXbbYQTO9erE1/YsFot5/LnOUizLzU2eeuz6+U/81KV5/hFTGA== + dependencies: + "@types/json-schema" "^7.0.3" + "@typescript-eslint/scope-manager" "4.23.0" + "@typescript-eslint/types" "4.23.0" + "@typescript-eslint/typescript-estree" "4.23.0" + eslint-scope "^5.0.0" + eslint-utils "^2.0.0" + +"@typescript-eslint/experimental-utils@^4.0.1": version "4.22.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.22.1.tgz#3938a5c89b27dc9a39b5de63a62ab1623ab27497" integrity sha512-svYlHecSMCQGDO2qN1v477ax/IDQwWhc7PRBiwAdAMJE7GXk5stF4Z9R/8wbRkuX/5e9dHqbIWxjeOjckK3wLQ== @@ -1718,14 +1730,14 @@ eslint-scope "^5.0.0" eslint-utils "^2.0.0" -"@typescript-eslint/parser@^4.22.1": - version "4.22.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.22.1.tgz#a95bda0fd01d994a15fc3e99dc984294f25c19cc" - integrity sha512-l+sUJFInWhuMxA6rtirzjooh8cM/AATAe3amvIkqKFeMzkn85V+eLzb1RyuXkHak4dLfYzOmF6DXPyflJvjQnw== +"@typescript-eslint/parser@^4.23.0": + version "4.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.23.0.tgz#239315d38e42e852bef43a4b0b01bef78f78911c" + integrity sha512-wsvjksHBMOqySy/Pi2Q6UuIuHYbgAMwLczRl4YanEPKW5KVxI9ZzDYh3B5DtcZPQTGRWFJrfcbJ6L01Leybwug== dependencies: - "@typescript-eslint/scope-manager" "4.22.1" - "@typescript-eslint/types" "4.22.1" - "@typescript-eslint/typescript-estree" "4.22.1" + "@typescript-eslint/scope-manager" "4.23.0" + "@typescript-eslint/types" "4.23.0" + "@typescript-eslint/typescript-estree" "4.23.0" debug "^4.1.1" "@typescript-eslint/scope-manager@4.22.1": @@ -1736,11 +1748,24 @@ "@typescript-eslint/types" "4.22.1" "@typescript-eslint/visitor-keys" "4.22.1" +"@typescript-eslint/scope-manager@4.23.0": + version "4.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.23.0.tgz#8792ef7eacac122e2ec8fa2d30a59b8d9a1f1ce4" + integrity sha512-ZZ21PCFxPhI3n0wuqEJK9omkw51wi2bmeKJvlRZPH5YFkcawKOuRMQMnI8mH6Vo0/DoHSeZJnHiIx84LmVQY+w== + dependencies: + "@typescript-eslint/types" "4.23.0" + "@typescript-eslint/visitor-keys" "4.23.0" + "@typescript-eslint/types@4.22.1": version "4.22.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.22.1.tgz#bf99c6cec0b4a23d53a61894816927f2adad856a" integrity sha512-2HTkbkdAeI3OOcWbqA8hWf/7z9c6gkmnWNGz0dKSLYLWywUlkOAQ2XcjhlKLj5xBFDf8FgAOF5aQbnLRvgNbCw== +"@typescript-eslint/types@4.23.0": + version "4.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.23.0.tgz#da1654c8a5332f4d1645b2d9a1c64193cae3aa3b" + integrity sha512-oqkNWyG2SLS7uTWLZf6Sr7Dm02gA5yxiz1RP87tvsmDsguVATdpVguHr4HoGOcFOpCvx9vtCSCyQUGfzq28YCw== + "@typescript-eslint/typescript-estree@4.22.1": version "4.22.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.22.1.tgz#dca379eead8cdfd4edc04805e83af6d148c164f9" @@ -1754,6 +1779,19 @@ semver "^7.3.2" tsutils "^3.17.1" +"@typescript-eslint/typescript-estree@4.23.0": + version "4.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.23.0.tgz#0753b292097523852428a6f5a1aa8ccc1aae6cd9" + integrity sha512-5Sty6zPEVZF5fbvrZczfmLCOcby3sfrSPu30qKoY1U3mca5/jvU5cwsPb/CO6Q3ByRjixTMIVsDkqwIxCf/dMw== + dependencies: + "@typescript-eslint/types" "4.23.0" + "@typescript-eslint/visitor-keys" "4.23.0" + debug "^4.1.1" + globby "^11.0.1" + is-glob "^4.0.1" + semver "^7.3.2" + tsutils "^3.17.1" + "@typescript-eslint/visitor-keys@4.22.1": version "4.22.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.22.1.tgz#6045ae25a11662c671f90b3a403d682dfca0b7a6" @@ -1762,6 +1800,14 @@ "@typescript-eslint/types" "4.22.1" eslint-visitor-keys "^2.0.0" +"@typescript-eslint/visitor-keys@4.23.0": + version "4.23.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.23.0.tgz#7215cc977bd3b4ef22467b9023594e32f9e4e455" + integrity sha512-5PNe5cmX9pSifit0H+nPoQBXdbNzi5tOEec+3riK+ku4e3er37pKxMKDH5Ct5Y4fhWxcD4spnlYjxi9vXbSpwg== + dependencies: + "@typescript-eslint/types" "4.23.0" + eslint-visitor-keys "^2.0.0" + "@yarnpkg/lockfile@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31"