diff --git a/.github/workflows/issue-label-assign.yml b/.github/workflows/issue-label-assign.yml index fe09e74b25e2e..bcf12f04a1ec6 100644 --- a/.github/workflows/issue-label-assign.yml +++ b/.github/workflows/issue-label-assign.yml @@ -21,23 +21,23 @@ jobs: [ {"keywords":["(cli)","(command line)"],"labels":["package/tools"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/alexa-ask)","(alexa-ask)","(alexa ask)"],"labels":["@aws-cdk/alexa-ask"],"assignees":["madeline-k"]}, - {"keywords":["(@aws-cdk/app-delivery)","(app-delivery)","(app delivery)"],"labels":["@aws-cdk/app-delivery"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/app-delivery)","(app-delivery)","(app delivery)"],"labels":["@aws-cdk/app-delivery"],"assignees":["madeline-k"]}, {"keywords":["(@aws-cdk/assert)","(assert)"],"labels":["@aws-cdk/assert"],"assignees":["nija-at"]}, {"keywords":["(@aws-cdk/assets)","(assets)"],"labels":["@aws-cdk/assets"],"assignees":["eladb"]}, - {"keywords":["(@aws-cdk/aws-accessanalyzer)","(aws-accessanalyzer)","(accessanalyzer)","(access analyzer)"],"labels":["@aws-cdk/aws-accessanalyzer"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-acmpca)","(aws-acmpca)","(acmpca)"],"labels":["@aws-cdk/aws-acmpca"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-accessanalyzer)","(aws-accessanalyzer)","(accessanalyzer)","(access analyzer)"],"labels":["@aws-cdk/aws-accessanalyzer"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-acmpca)","(aws-acmpca)","(acmpca)"],"labels":["@aws-cdk/aws-acmpca"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-amazonmq)","(aws-amazonmq)","(amazonmq)","(amazon mq)","(amazon-mq)"],"labels":["@aws-cdk/aws-amazonmq"],"assignees":["otaviomacedo"]}, - {"keywords":["(@aws-cdk/aws-amplify)","(aws-amplify)","(amplify)"],"labels":["@aws-cdk/aws-amplify"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-amplify)","(aws-amplify)","(amplify)"],"labels":["@aws-cdk/aws-amplify"],"assignees":["madeline-k"]}, {"keywords":["(@aws-cdk/aws-apigateway)","(aws-apigateway)","(apigateway)","(api gateway)","(api-gateway)"],"labels":["@aws-cdk/aws-apigateway"],"assignees":["nija-at"]}, {"keywords":["(@aws-cdk/aws-apigatewayv2)","(aws-apigatewayv2)","(apigatewayv2)","(apigateway v2)","(api-gateway-v2)"],"labels":["@aws-cdk/aws-apigatewayv2"],"assignees":["nija-at"]}, {"keywords":["(@aws-cdk/aws-apigatewayv2-authorizers)","(aws-apigatewayv2-authorizers)","(apigatewayv2-authorizers)"],"labels":["@aws-cdk/aws-apigatewayv2-authorizers"],"assignees":["nija-at"]}, {"keywords":["(@aws-cdk/aws-apigatewayv2-integrations)","(aws-apigatewayv2-integrations)","(apigatewayv2-integrations)","(apigateway v2 integrations)","(api-gateway-v2-integrations)"],"labels":["@aws-cdk/aws-apigatewayv2-integrations"],"assignees":["nija-at"]}, {"keywords":["(@aws-cdk/aws-appconfig)","(aws-appconfig)","(appconfig)","(app config)","(app-config)"],"labels":["@aws-cdk/aws-appconfig"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-appflow)","(aws-appflow)","(appflow)","(app flow)","(app-flow)"],"labels":["@aws-cdk/aws-appflow"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-appintegrations)","(aws-appintegrations)","(appintegrations)"],"labels":["@aws-cdk/aws-appintegrations"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-appflow)","(aws-appflow)","(appflow)","(app flow)","(app-flow)"],"labels":["@aws-cdk/aws-appflow"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-appintegrations)","(aws-appintegrations)","(appintegrations)"],"labels":["@aws-cdk/aws-appintegrations"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-applicationautoscaling)","(aws-applicationautoscaling)","(applicationautoscaling)","(application autoscaling)","(application-autoscaling)"],"labels":["@aws-cdk/aws-applicationautoscaling"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/aws-applicationinsights)","(aws-applicationinsights)","(applicationinsights)","(application insights)","(application-insights)"],"labels":["@aws-cdk/aws-applicationinsights"],"assignees":["njlynch"]}, - {"keywords":["(@aws-cdk/aws-appmesh)","(aws-appmesh)","(appmesh)","(app mesh)","(app-mesh)"],"labels":["@aws-cdk/aws-appmesh"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-appmesh)","(aws-appmesh)","(appmesh)","(app mesh)","(app-mesh)"],"labels":["@aws-cdk/aws-appmesh"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-appstream)","(aws-appstream)","(appstream)","(app stream)","(app-stream)"],"labels":["@aws-cdk/aws-appstream"],"assignees":["madeline-k"]}, {"keywords":["(@aws-cdk/aws-appsync)","(aws-appsync)","(appsync)","(app sync)","(app-sync)"],"labels":["@aws-cdk/aws-appsync"],"assignees":["otaviomacedo"]}, {"keywords":["(@aws-cdk/aws-athena)","(aws-athena)","(athena)"],"labels":["@aws-cdk/aws-athena"],"assignees":["BenChaimberg"]}, @@ -54,7 +54,7 @@ jobs: {"keywords":["(@aws-cdk/aws-ce)","(aws-ce)","(ce)"],"labels":["@aws-cdk/aws-ce"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-certificatemanager)","(aws-certificatemanager)","(certificatemanager)","(certificate manager)","(certificate-manager)","(acm)"],"labels":["@aws-cdk/aws-certificatemanager"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-chatbot)","(aws-chatbot)","(chatbot)"],"labels":["@aws-cdk/aws-chatbot"],"assignees":["BenChaimberg"]}, - {"keywords":["(@aws-cdk/aws-cloud9)","(aws-cloud9)","(cloud9)","(cloud 9)"],"labels":["@aws-cdk/aws-cloud9"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-cloud9)","(aws-cloud9)","(cloud9)","(cloud 9)"],"labels":["@aws-cdk/aws-cloud9"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-cloudformation)","(aws-cloudformation)","(cloudformation)","(cloud formation)"],"labels":["@aws-cdk/aws-cloudformation"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/aws-cloudfront)","(aws-cloudfront)","(cloudfront)","(cloud front)"],"labels":["@aws-cdk/aws-cloudfront"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-cloudfront-origins)","(aws-cloudfront-origins)","(cloudfront-origins)","(cloudfront origins)"],"labels":["@aws-cdk/aws-cloudfront-origins"],"assignees":["njlynch"]}, @@ -62,31 +62,31 @@ jobs: {"keywords":["(@aws-cdk/aws-cloudwatch)","(aws-cloudwatch)","(cloudwatch)","(cloud watch)"],"labels":["@aws-cdk/aws-cloudwatch"],"assignees":["madeline-k"]}, {"keywords":["(@aws-cdk/aws-cloudwatch-actions)","(aws-cloudwatch-actions)","(cloudwatch-actions)","(cloudwatch actions)"],"labels":["@aws-cdk/aws-cloudwatch-actions"],"assignees":["madeline-k"]}, {"keywords":["(@aws-cdk/aws-codeartifact)","(aws-codeartifact)","(codeartifact)","(code artifact)","(code-artifact)"],"labels":["@aws-cdk/aws-codeartifact"],"assignees":["njlynch"]}, - {"keywords":["(@aws-cdk/aws-codebuild)","(aws-codebuild)","(codebuild)","(code build)","(code-build)"],"labels":["@aws-cdk/aws-codebuild"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codecommit)","(aws-codecommit)","(codecommit)","(code commit)", "(code-commit)"],"labels":["@aws-cdk/aws-codecommit"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codedeploy)","(aws-codedeploy)","(codedeploy)","(code deploy)","(code-deploy)"],"labels":["@aws-cdk/aws-codedeploy"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codeguruprofiler)","(aws-codeguruprofiler)","(codeguruprofiler)","(codeguru profiler)","(codeguru-profiler)"],"labels":["@aws-cdk/aws-codeguruprofiler"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codegurureviewer)","(aws-codegurureviewer)","(codegurureviewer)","(codeguru reviewer)","(codeguru-reviewer)"],"labels":["@aws-cdk/aws-codegurureviewer"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codepipeline)","(aws-codepipeline)","(codepipeline)","(code pipeline)","(code-pipeline)"],"labels":["@aws-cdk/aws-codepipeline"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codepipeline-actions)","(aws-codepipeline-actions)","(codepipeline-actions)","(codepipeline actions)"],"labels":["@aws-cdk/aws-codepipeline-actions"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codestar)","(aws-codestar)","(codestar)"],"labels":["@aws-cdk/aws-codestar"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codestarconnections)","(aws-codestarconnections)","(codestarconnections)","(codestar connections)","(codestar-connections)"],"labels":["@aws-cdk/aws-codestarconnections"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-codestarnotifications)","(aws-codestarnotifications)","(codestarnotifications)","(codestar notifications)","(codestar-notifications)"],"labels":["@aws-cdk/aws-codestarnotifications"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-codebuild)","(aws-codebuild)","(codebuild)","(code build)","(code-build)"],"labels":["@aws-cdk/aws-codebuild"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-codecommit)","(aws-codecommit)","(codecommit)","(code commit)", "(code-commit)"],"labels":["@aws-cdk/aws-codecommit"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-codedeploy)","(aws-codedeploy)","(codedeploy)","(code deploy)","(code-deploy)"],"labels":["@aws-cdk/aws-codedeploy"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-codeguruprofiler)","(aws-codeguruprofiler)","(codeguruprofiler)","(codeguru profiler)","(codeguru-profiler)"],"labels":["@aws-cdk/aws-codeguruprofiler"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-codegurureviewer)","(aws-codegurureviewer)","(codegurureviewer)","(codeguru reviewer)","(codeguru-reviewer)"],"labels":["@aws-cdk/aws-codegurureviewer"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-codepipeline)","(aws-codepipeline)","(codepipeline)","(code pipeline)","(code-pipeline)"],"labels":["@aws-cdk/aws-codepipeline"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-codepipeline-actions)","(aws-codepipeline-actions)","(codepipeline-actions)","(codepipeline actions)"],"labels":["@aws-cdk/aws-codepipeline-actions"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-codestar)","(aws-codestar)","(codestar)"],"labels":["@aws-cdk/aws-codestar"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-codestarconnections)","(aws-codestarconnections)","(codestarconnections)","(codestar connections)","(codestar-connections)"],"labels":["@aws-cdk/aws-codestarconnections"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-codestarnotifications)","(aws-codestarnotifications)","(codestarnotifications)","(codestar notifications)","(codestar-notifications)"],"labels":["@aws-cdk/aws-codestarnotifications"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-cognito)","(aws-cognito)","(cognito)"],"labels":["@aws-cdk/aws-cognito"],"assignees":["nija-at"]}, {"keywords":["(@aws-cdk/aws-config)","(aws-config)","(config)"],"labels":["@aws-cdk/aws-config"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/aws-customerprofiles)","(aws-customerprofiles)","(customerprofiles)"],"labels":["@aws-cdk/aws-customerprofiles"],"assignees":["otaviomacedo"]}, {"keywords":["(@aws-cdk/aws-databrew)","(aws-databrew)","(databrew)"],"labels":["@aws-cdk/aws-databrew"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-datapipeline)","(aws-datapipeline)","(datapipeline)","(data pipeline)","(data-pipeline)"],"labels":["@aws-cdk/aws-datapipeline"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-datasync)","(aws-datasync)","(datasync)"],"labels":["@aws-cdk/aws-datasync"],"assignees":["BenChaimberg"]}, - {"keywords":["(@aws-cdk/aws-dax)","(aws-dax)","(dax)"],"labels":["@aws-cdk/aws-dax"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-detective)","(aws-detective)","(detective)"],"labels":["@aws-cdk/aws-detective"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-dax)","(aws-dax)","(dax)"],"labels":["@aws-cdk/aws-dax"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-detective)","(aws-detective)","(detective)"],"labels":["@aws-cdk/aws-detective"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-devopsguru)","(aws-devopsguru)","(devopsguru)"],"labels":["@aws-cdk/aws-devopsguru"],"assignees":["nija-at"]}, {"keywords":["(@aws-cdk/aws-directoryservice)","(aws-directoryservice)","(directoryservice)","(directory service)","(directory-service)"],"labels":["@aws-cdk/aws-directoryservice"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/aws-dlm)","(aws-dlm)","(dlm)"],"labels":["@aws-cdk/aws-dlm"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-dms)","(aws-dms)","(dms)"],"labels":["@aws-cdk/aws-dms"],"assignees":["njlynch"]}, - {"keywords":["(@aws-cdk/aws-docdb)","(aws-docdb)","(docdb)","(doc db)","(doc-db)"],"labels":["@aws-cdk/aws-docdb"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-dynamodb)","(aws-dynamodb)","(dynamodb)","(dynamo db)","(dynamo-db)"],"labels":["@aws-cdk/aws-dynamodb"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-dynamodb-global)","(aws-dynamodb-global)","(dynamodb-global)","(dynamodb global)"],"labels":["@aws-cdk/aws-dynamodb-global"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-docdb)","(aws-docdb)","(docdb)","(doc db)","(doc-db)"],"labels":["@aws-cdk/aws-docdb"],"assignees":["madeline-k"]}, + {"keywords":["(@aws-cdk/aws-dynamodb)","(aws-dynamodb)","(dynamodb)","(dynamo db)","(dynamo-db)"],"labels":["@aws-cdk/aws-dynamodb"],"assignees":["madeline-k"]}, + {"keywords":["(@aws-cdk/aws-dynamodb-global)","(aws-dynamodb-global)","(dynamodb-global)","(dynamodb global)"],"labels":["@aws-cdk/aws-dynamodb-global"],"assignees":["madeline-k"]}, {"keywords":["(@aws-cdk/aws-ec2)","(aws-ec2)","(ec2)","(vpc)"],"labels":["@aws-cdk/aws-ec2"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-ecr)","(aws-ecr)","(ecr)"],"labels":["@aws-cdk/aws-ecr"],"assignees":["madeline-k"]}, {"keywords":["(@aws-cdk/aws-ecr-assets)","(aws-ecr-assets)","(ecr-assets)","(ecr assets)","(ecrassets)"],"labels":["@aws-cdk/aws-ecr-assets"],"assignees":["eladb"]}, @@ -96,7 +96,7 @@ jobs: {"keywords":["(@aws-cdk/aws-eks)","(aws-eks)","(eks)"],"labels":["@aws-cdk/aws-eks"],"assignees":["otaviomacedo"]}, {"keywords":["(@aws-cdk/aws-eks-legacy)","(aws-eks-legacy)","(eks-legacy)"],"labels":["@aws-cdk/aws-eks-legacy"],"assignees":["otaviomacedo"]}, {"keywords":["(@aws-cdk/aws-elasticache)","(aws-elasticache)","(elasticache)","(elastic cache)","(elastic-cache)"],"labels":["@aws-cdk/aws-elasticache"],"assignees":["otaviomacedo"]}, - {"keywords":["(@aws-cdk/aws-elasticbeanstalk)","(aws-elasticbeanstalk)","(elasticbeanstalk)","(elastic beanstalk)","(elastic-beanstalk)"],"labels":["@aws-cdk/aws-elasticbeanstalk"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-elasticbeanstalk)","(aws-elasticbeanstalk)","(elasticbeanstalk)","(elastic beanstalk)","(elastic-beanstalk)"],"labels":["@aws-cdk/aws-elasticbeanstalk"],"assignees":["madeline-k"]}, {"keywords":["(@aws-cdk/aws-elasticloadbalancing)","(aws-elasticloadbalancing)","(elasticloadbalancing)","(elastic loadbalancing)","(elastic-loadbalancing)","(elb)"],"labels":["@aws-cdk/aws-elasticloadbalancing"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-elasticloadbalancingv2)","(aws-elasticloadbalancingv2)","(elasticloadbalancingv2)","(elastic-loadbalancing-v2)","(elbv2)","(elb v2)"],"labels":["@aws-cdk/aws-elasticloadbalancingv2"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-elasticloadbalancingv2-actions)","(aws-elasticloadbalancingv2-actions)","(elasticloadbalancingv2-actions)"],"labels":["@aws-cdk/aws-elasticloadbalancingv2-actions"],"assignees":["njlynch"]}, @@ -106,7 +106,7 @@ jobs: {"keywords":["(@aws-cdk/aws-emrcontainers)","(aws-emrcontainers)","(emrcontainers)"],"labels":["@aws-cdk/aws-emrcontainers"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-events)","(aws-events)","(events)","(eventbridge)","(event-bridge)"],"labels":["@aws-cdk/aws-events"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/aws-events-targets)","(aws-events-targets)","(events-targets)","(events targets)"],"labels":["@aws-cdk/aws-events-targets"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-eventschemas)","(aws-eventschemas)","(eventschemas)","(event schemas)"],"labels":["@aws-cdk/aws-eventschemas"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-eventschemas)","(aws-eventschemas)","(eventschemas)","(event schemas)"],"labels":["@aws-cdk/aws-eventschemas"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-finspace)","(aws-finspace)","(finspace)"],"labels":["@aws-cdk/aws-finspace"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-fis)","(aws-fis)","(fis)"],"labels":["@aws-cdk/aws-fis"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-fms)","(aws-fms)","(fms)"],"labels":["@aws-cdk/aws-fms"],"assignees":["rix0rrr"]}, @@ -116,23 +116,23 @@ jobs: {"keywords":["(@aws-cdk/aws-globalaccelerator)","(aws-globalaccelerator)","(globalaccelerator)","(global accelerator)","(global-accelerator)"],"labels":["@aws-cdk/aws-globalaccelerator"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/aws-globalaccelerator-endpoints)","(aws-globalaccelerator-endpoints)","(globalaccelerator-endpoints)"],"labels":["@aws-cdk/aws-globalaccelerator-endpoints"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/aws-glue)","(aws-glue)","(glue)"],"labels":["@aws-cdk/aws-glue"],"assignees":["BenChaimberg"]}, - {"keywords":["(@aws-cdk/aws-greengrass)","(aws-greengrass)","(greengrass)","(green grass)","(green-grass)"],"labels":["@aws-cdk/aws-greengrass"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-greengrassv2)","(aws-greengrassv2)","(greengrassv2)"],"labels":["@aws-cdk/aws-greengrassv2"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-greengrass)","(aws-greengrass)","(greengrass)","(green grass)","(green-grass)"],"labels":["@aws-cdk/aws-greengrass"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-greengrassv2)","(aws-greengrassv2)","(greengrassv2)"],"labels":["@aws-cdk/aws-greengrassv2"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-groundstation)","(aws-groundstation)","(groundstation)"],"labels":["@aws-cdk/aws-groundstation"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/aws-guardduty)","(aws-guardduty)","(guardduty)","(guard duty)","(guard-duty)"],"labels":["@aws-cdk/aws-guardduty"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/aws-iam)","(aws-iam)","(iam)"],"labels":["@aws-cdk/aws-iam"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/aws-imagebuilder)","(aws-imagebuilder)","(imagebuilder)","(image builder)","(image-builder)"],"labels":["@aws-cdk/aws-imagebuilder"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-inspector)","(aws-inspector)","(inspector)"],"labels":["@aws-cdk/aws-inspector"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-iot)","(aws-iot)","(iot)"],"labels":["@aws-cdk/aws-iot"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-iot1click)","(aws-iot1click)","(iot1click)","(iot 1click)"],"labels":["@aws-cdk/aws-iot1click"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-iotanalytics)","(aws-iotanalytics)","(iotanalytics)","(iot analytics)","(iot-analytics)"],"labels":["@aws-cdk/aws-iotanalytics"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-iotevents)","(aws-iotevents)","(iotevents)","(iot events)","(iot-events)"],"labels":["@aws-cdk/aws-iotevents"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-iotfleethub)","(aws-iotfleethub)","(iotfleethub)"],"labels":["@aws-cdk/aws-iotfleethub"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-iotsitewise)","(aws-iotsitewise)","(iotsitewise)","(iot sitewise)","(iot-sitewise)","(iot-site-wise)","(iot site wise)"],"labels":["@aws-cdk/aws-iotsitewise"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-iotthingsgraph)","(aws-iotthingsgraph)","(iotthingsgraph)","(iot things graph)","(iot-things-graph)"],"labels":["@aws-cdk/aws-iotthingsgraph"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-iotwireless)","(aws-iotwireless)","(iotwireless)"],"labels":["@aws-cdk/aws-iotwireless"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-ivs)","(aws-ivs)","(Interactive Video Service)","(ivs)"],"labels":["@aws-cdk/aws-ivs"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-kendra)","(aws-kendra)","(kendra)"],"labels":["@aws-cdk/aws-kendra"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-imagebuilder)","(aws-imagebuilder)","(imagebuilder)","(image builder)","(image-builder)"],"labels":["@aws-cdk/aws-imagebuilder"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-inspector)","(aws-inspector)","(inspector)"],"labels":["@aws-cdk/aws-inspector"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-iot)","(aws-iot)","(iot)"],"labels":["@aws-cdk/aws-iot"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-iot1click)","(aws-iot1click)","(iot1click)","(iot 1click)"],"labels":["@aws-cdk/aws-iot1click"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-iotanalytics)","(aws-iotanalytics)","(iotanalytics)","(iot analytics)","(iot-analytics)"],"labels":["@aws-cdk/aws-iotanalytics"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-iotevents)","(aws-iotevents)","(iotevents)","(iot events)","(iot-events)"],"labels":["@aws-cdk/aws-iotevents"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-iotfleethub)","(aws-iotfleethub)","(iotfleethub)"],"labels":["@aws-cdk/aws-iotfleethub"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-iotsitewise)","(aws-iotsitewise)","(iotsitewise)","(iot sitewise)","(iot-sitewise)","(iot-site-wise)","(iot site wise)"],"labels":["@aws-cdk/aws-iotsitewise"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-iotthingsgraph)","(aws-iotthingsgraph)","(iotthingsgraph)","(iot things graph)","(iot-things-graph)"],"labels":["@aws-cdk/aws-iotthingsgraph"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-iotwireless)","(aws-iotwireless)","(iotwireless)"],"labels":["@aws-cdk/aws-iotwireless"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-ivs)","(aws-ivs)","(Interactive Video Service)","(ivs)"],"labels":["@aws-cdk/aws-ivs"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-kendra)","(aws-kendra)","(kendra)"],"labels":["@aws-cdk/aws-kendra"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-kinesis)","(aws-kinesis)","(kinesis)"],"labels":["@aws-cdk/aws-kinesis"],"assignees":["otaviomacedo"]}, {"keywords":["(@aws-cdk/aws-kinesisanalytics)","(aws-kinesisanalytics)","(kinesisanalytics)","(kinesis analytics)","(kinesis-analytics)"],"labels":["@aws-cdk/aws-kinesisanalytics"],"assignees":["otaviomacedo"]}, {"keywords":["(@aws-cdk/aws-kinesisanalytics-flink)","(aws-kinesisanalytics-flink)","(kinesisanalytics-flink)"],"labels":["@aws-cdk/aws-kinesisanalytics-flink"],"assignees":["otaviomacedo"]}, @@ -151,27 +151,27 @@ jobs: {"keywords":["(@aws-cdk/aws-lookoutmetrics)","(aws-lookoutmetrics)","(lookoutmetrics)"],"labels":["@aws-cdk/aws-lookoutmetrics"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-lookoutvision)","(aws-lookoutvision)","(lookoutvision)"],"labels":["@aws-cdk/aws-lookoutvision"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-macie)","(aws-macie)","(macie)"],"labels":["@aws-cdk/aws-macie"],"assignees":["njlynch"]}, - {"keywords":["(@aws-cdk/aws-managedblockchain)","(aws-managedblockchain)","(managedblockchain)","(managed blockchain)","(managed-blockchain)"],"labels":["@aws-cdk/aws-managedblockchain"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-mediaconnect)","(aws-mediaconnect)","(mediaconnect)"],"labels":["@aws-cdk/aws-mediaconnect"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-mediaconvert)","(aws-mediaconvert)","(mediaconvert)","(media convert)","(media-convert)"],"labels":["@aws-cdk/aws-mediaconvert"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-medialive)","(aws-medialive)","(medialive)","(media live)","(media-live)"],"labels":["@aws-cdk/aws-medialive"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-mediastore)","(aws-mediastore)","(mediastore)","(media store)","(media-store)"],"labels":["@aws-cdk/aws-mediastore"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-mediapackage)","(aws-mediapackage)","(mediapackage)","(media package)","(media-package)"],"labels":["@aws-cdk/aws-mediapackage"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-managedblockchain)","(aws-managedblockchain)","(managedblockchain)","(managed blockchain)","(managed-blockchain)"],"labels":["@aws-cdk/aws-managedblockchain"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-mediaconnect)","(aws-mediaconnect)","(mediaconnect)"],"labels":["@aws-cdk/aws-mediaconnect"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-mediaconvert)","(aws-mediaconvert)","(mediaconvert)","(media convert)","(media-convert)"],"labels":["@aws-cdk/aws-mediaconvert"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-medialive)","(aws-medialive)","(medialive)","(media live)","(media-live)"],"labels":["@aws-cdk/aws-medialive"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-mediastore)","(aws-mediastore)","(mediastore)","(media store)","(media-store)"],"labels":["@aws-cdk/aws-mediastore"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-mediapackage)","(aws-mediapackage)","(mediapackage)","(media package)","(media-package)"],"labels":["@aws-cdk/aws-mediapackage"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-msk)","(aws-msk)","(msk)"],"labels":["@aws-cdk/aws-msk"],"assignees":["otaviomacedo"]}, {"keywords":["(@aws-cdk/aws-mwaa)","(aws-mwaa)","(mwaa)"],"labels":["@aws-cdk/aws-mwaa"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/aws-neptune)","(aws-neptune)","(neptune)"],"labels":["@aws-cdk/aws-neptune"],"assignees":["njlynch"]}, - {"keywords":["(@aws-cdk/aws-networkfirewall)","(aws-networkfirewall)","(networkfirewall)"],"labels":["@aws-cdk/aws-networkfirewall"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-networkmanager)","(aws-networkmanager)","(networkmanager)","(network manager)","(network-manager)"],"labels":["@aws-cdk/aws-networkmanager"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-networkfirewall)","(aws-networkfirewall)","(networkfirewall)"],"labels":["@aws-cdk/aws-networkfirewall"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-networkmanager)","(aws-networkmanager)","(networkmanager)","(network manager)","(network-manager)"],"labels":["@aws-cdk/aws-networkmanager"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-nimblestudio)","(aws-nimblestudio)","(nimblestudio)"],"labels":["@aws-cdk/aws-nimblestudio"],"assignees":["madeline-k"]}, {"keywords":["(@aws-cdk/aws-opsworks)","(aws-opsworks)","(opsworks)","(ops works)","(ops-works)"],"labels":["@aws-cdk/aws-opsworks"],"assignees":["madeline-k"]}, {"keywords":["(@aws-cdk/aws-opsworkscm)","(aws-opsworkscm)","(opsworkscm)","(opsworks cm)","(opsworks-cm)"],"labels":["@aws-cdk/aws-opsworkscm"],"assignees":["madeline-k"]}, {"keywords":["(@aws-cdk/aws-personalize)","(aws-personalize)","(personalize)"],"labels":["@aws-cdk/aws-personalize"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-pinpoint)","(aws-pinpoint)","(pinpoint)"],"labels":["@aws-cdk/aws-pinpoint"],"assignees":["otaviomacedo"]}, {"keywords":["(@aws-cdk/aws-pinpointemail)","(aws-pinpointemail)","(pinpointemail)","(pinpoint email)","(pinpoint-email)"],"labels":["@aws-cdk/aws-pinpointemail"],"assignees":["otaviomacedo"]}, - {"keywords":["(@aws-cdk/aws-qldb)","(aws-qldb)","(qldb)"],"labels":["@aws-cdk/aws-qldb"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-qldb)","(aws-qldb)","(qldb)"],"labels":["@aws-cdk/aws-qldb"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-quicksight)","(aws-quicksight)","(quicksight)"],"labels":["@aws-cdk/aws-quicksight"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-ram)","(aws-ram)","(ram)"],"labels":["@aws-cdk/aws-ram"],"assignees":["madeline-k"]}, - {"keywords":["(@aws-cdk/aws-rds)","(aws-rds)","(rds)"],"labels":["@aws-cdk/aws-rds"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-rds)","(aws-rds)","(rds)"],"labels":["@aws-cdk/aws-rds"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-redshift)","(aws-redshift)","(redshift)","(red shift)","(red-shift)"],"labels":["@aws-cdk/aws-redshift"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-resourcegroups)","(aws-resourcegroups)","(resourcegroups)","(resource groups)","(resource-groups)"],"labels":["@aws-cdk/aws-resourcegroups"],"assignees":["madeline-k"]}, {"keywords":["(@aws-cdk/aws-robomaker)","(aws-robomaker)","(robomaker)","(robo maker)","(robo-maker)"],"labels":["@aws-cdk/aws-robomaker"],"assignees":["njlynch"]}, @@ -189,9 +189,9 @@ jobs: {"keywords":["(@aws-cdk/aws-sam)","(aws-sam)","(sam)"],"labels":["@aws-cdk/aws-sam"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-sdb)","(aws-sdb)","(sdb)"],"labels":["@aws-cdk/aws-sdb"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-secretsmanager)","(aws-secretsmanager)","(secretsmanager)","(secrets manager)","(secrets-manager)"],"labels":["@aws-cdk/aws-secretsmanager"],"assignees":["njlynch"]}, - {"keywords":["(@aws-cdk/aws-securityhub)","(aws-securityhub)","(securityhub)","(security hub)","(security-hub)"],"labels":["@aws-cdk/aws-securityhub"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-servicecatalog)","(aws-servicecatalog)","(servicecatalog)","(service catalog)","(service-catalog)"],"labels":["@aws-cdk/aws-servicecatalog"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/aws-servicecatalogappregistry)","(aws-servicecatalogappregistry)","(servicecatalogappregistry)"],"labels":["@aws-cdk/aws-servicecatalogappregistry"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-securityhub)","(aws-securityhub)","(securityhub)","(security hub)","(security-hub)"],"labels":["@aws-cdk/aws-securityhub"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-servicecatalog)","(aws-servicecatalog)","(servicecatalog)","(service catalog)","(service-catalog)"],"labels":["@aws-cdk/aws-servicecatalog"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/aws-servicecatalogappregistry)","(aws-servicecatalogappregistry)","(servicecatalogappregistry)"],"labels":["@aws-cdk/aws-servicecatalogappregistry"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-servicediscovery)","(aws-servicediscovery)","(servicediscovery)","(service discovery)","(service-discovery)"],"labels":["@aws-cdk/aws-servicediscovery"],"assignees":["madeline-k"]}, {"keywords":["(@aws-cdk/aws-ses)","(aws-ses)","(ses)"],"labels":["@aws-cdk/aws-ses"],"assignees":["otaviomacedo"]}, {"keywords":["(@aws-cdk/aws-ses-actions)","(aws-ses-actions)","(ses-actions)","(ses actions)"],"labels":["@aws-cdk/aws-ses-actions"],"assignees":["otaviomacedo"]}, @@ -200,11 +200,11 @@ jobs: {"keywords":["(@aws-cdk/aws-sns-subscriptions)","(aws-sns-subscriptions)","(sns-subscriptions)","(sns subscriptions)"],"labels":["@aws-cdk/aws-sns-subscriptions"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-sqs)","(aws-sqs)","(sqs)"],"labels":["@aws-cdk/aws-sqs"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-ssm)","(aws-ssm)","(ssm)"],"labels":["@aws-cdk/aws-ssm"],"assignees":["njlynch"]}, - {"keywords":["(@aws-cdk/aws-sso)","(aws-sso)","(sso)"],"labels":["@aws-cdk/aws-sso"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-sso)","(aws-sso)","(sso)"],"labels":["@aws-cdk/aws-sso"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-stepfunctions)","(aws-stepfunctions)","(stepfunctions)","(step functions)","(step-functions)"],"labels":["@aws-cdk/aws-stepfunctions"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-stepfunctions-tasks)","(aws-stepfunctions-tasks)","(stepfunctions-tasks)","(stepfunctions tasks)"],"labels":["@aws-cdk/aws-stepfunctions-tasks"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-synthetics)","(aws-synthetics)","(synthetics)"],"labels":["@aws-cdk/aws-synthetics"],"assignees":["BenChaimberg"]}, - {"keywords":["(@aws-cdk/aws-timestream)","(aws-timestream)","(timestream)"],"labels":["@aws-cdk/aws-timestream"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/aws-timestream)","(aws-timestream)","(timestream)"],"labels":["@aws-cdk/aws-timestream"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/aws-transfer)","(aws-transfer)","(transfer)"],"labels":["@aws-cdk/aws-transfer"],"assignees":["otaviomacedo"]}, {"keywords":["(@aws-cdk/aws-waf)","(aws-waf)","(waf)"],"labels":["@aws-cdk/aws-waf"],"assignees":["njlynch"]}, {"keywords":["(@aws-cdk/aws-wafregional)","(aws-wafregional)","(wafregional)","(waf regional)","(waf-regional)"],"labels":["@aws-cdk/aws-wafregional"],"assignees":["njlynch"]}, @@ -213,16 +213,16 @@ jobs: {"keywords":["(@aws-cdk/aws-xray)","(aws-xray)","(xray)"],"labels":["@aws-cdk/aws-xray"],"assignees":["nija-at"]}, {"keywords":["(@aws-cdk/cfnspec)","(cfnspec)","(cfn spec)","(cfn-spec)"],"labels":["@aws-cdk/cfnspec"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/cloud-assembly-schema)","(cloud-assembly-schema)","(cloud assembly schema)"],"labels":["@aws-cdk/cloud-assembly-schema"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/cloudformation-diff)","(cloudformation-diff)","(cloudformation diff)","(cfn diff)"],"labels":["@aws-cdk/cloudformation-diff"],"assignees":["skinny85"]}, - {"keywords":["(@aws-cdk/cloudformation-include)","(cloudformation-include)","(cloudformation include)","(cfn include)","(cfn-include)"],"labels":["@aws-cdk/cloudformation-include"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/cloudformation-diff)","(cloudformation-diff)","(cloudformation diff)","(cfn diff)"],"labels":["@aws-cdk/cloudformation-diff"],"assignees":["BenChaimberg"]}, + {"keywords":["(@aws-cdk/cloudformation-include)","(cloudformation-include)","(cloudformation include)","(cfn include)","(cfn-include)"],"labels":["@aws-cdk/cloudformation-include"],"assignees":["BenChaimberg"]}, {"keywords":["(@aws-cdk/core)","(core)"],"labels":["@aws-cdk/core"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/custom-resources)","(custom-resources)","(custom resources)"],"labels":["@aws-cdk/custom-resources"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/cx-api)","(cx-api)","(cx api)"],"labels":["@aws-cdk/cx-api"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/aws-lambda-layer-awscli)","(aws-lambda-layer-awscli)","(lambda-layer-awscli)"],"labels":["@aws-cdk/aws-lambda-layer-awscli"],"assignees":["rix0rrr"]}, {"keywords":["(@aws-cdk/aws-lambda-layer-kubectl)","(aws-lambda-layer-kubectl)","(lambda-layer-kubectl)"],"labels":["@aws-cdk/aws-lambda-layer-kubectl"],"assignees":["eladb"]}, {"keywords":["(@aws-cdk/pipelines)","(pipelines)","(cdk pipelines)","(cdk-pipelines)"],"labels":["@aws-cdk/pipelines"],"assignees":["rix0rrr"]}, - {"keywords":["(@aws-cdk/region-info)","(region-info)","(region info)"],"labels":["@aws-cdk/region-info"],"assignees":["skinny85"]}, + {"keywords":["(@aws-cdk/region-info)","(region-info)","(region info)"],"labels":["@aws-cdk/region-info"],"assignees":["BenChaimberg"]}, {"keywords":["(aws-cdk-lib)","(cdk-v2)", "(v2)", "(ubergen)"],"labels":["aws-cdk-lib"],"assignees":["nija-at"]}, {"keywords":["(monocdk)","(monocdk-experiment)"],"labels":["monocdk"],"assignees":["nija-at"]}, - {"keywords":["(@aws-cdk/yaml-cfn)","(aws-yaml-cfn)","(yaml-cfn)"],"labels":["@aws-cdk/aws-yaml-cfn"],"assignees":["skinny85"]} + {"keywords":["(@aws-cdk/yaml-cfn)","(aws-yaml-cfn)","(yaml-cfn)"],"labels":["@aws-cdk/aws-yaml-cfn"],"assignees":["BenChaimberg"]} ] diff --git a/CHANGELOG.md b/CHANGELOG.md index 21264b7582645..ef046c0c53529 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,60 @@ 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.117.0](https://github.com/aws/aws-cdk/compare/v1.116.0...v1.117.0) (2021-08-05) + + +### ⚠ BREAKING CHANGES TO EXPERIMENTAL FEATURES + +* **assertions:** `Template.fromTemplate()` is now +renamed to `Template.fromJSON()` to provide clarity. +* **assertions:** `TemplateAssertions` is now renamed to +`Template`. + +### Features + +* **aws-cloudfront:** add enabled to web distribution ([#15433](https://github.com/aws/aws-cdk/issues/15433)) ([7ad9348](https://github.com/aws/aws-cdk/commit/7ad9348b49ab3b9dde1b4f1db3d888ddec423a9f)) +* **aws-ec2:** Add SubnetFilter for Id and CIDR netmask ([#15373](https://github.com/aws/aws-cdk/issues/15373)) ([407b02d](https://github.com/aws/aws-cdk/commit/407b02d62bd8b3eb77e53fc74197b64148640b5a)), closes [#15228](https://github.com/aws/aws-cdk/issues/15228) +* **aws-kinesisfirehose:** support for S3 destination encryption on DeliveryStream ([#15558](https://github.com/aws/aws-cdk/issues/15558)) ([3888773](https://github.com/aws/aws-cdk/commit/388877300e460e23cd69d67a16a00f7c57630649)), closes [#15555](https://github.com/aws/aws-cdk/issues/15555) +* **cfnspec:** cloudformation spec v39.8.0 ([#15885](https://github.com/aws/aws-cdk/issues/15885)) ([60e6b41](https://github.com/aws/aws-cdk/commit/60e6b4186680af98b538a21e82146fb0a0e84f33)) +* **cloudfront:** Origin Shield support ([#15453](https://github.com/aws/aws-cdk/issues/15453)) ([08ebbae](https://github.com/aws/aws-cdk/commit/08ebbae4cffdf85a66775f4e8f5ea9d7400bf358)), closes [#12872](https://github.com/aws/aws-cdk/issues/12872) +* **cloudfront:** use TLS_V1_2_2021 SecurityPolicy as default version (under feature flag) ([#15477](https://github.com/aws/aws-cdk/issues/15477)) ([7b64abf](https://github.com/aws/aws-cdk/commit/7b64abf51c52cd2f6f585d7fd9201030fdba8163)) +* **ec2:** Add Transcribe interface endpoint ([#15465](https://github.com/aws/aws-cdk/issues/15465)) ([929d6ae](https://github.com/aws/aws-cdk/commit/929d6aef84eb21aea0d9a4fff953a0f39246288e)) +* **eks:** support Kubernetes 1.21 ([#15774](https://github.com/aws/aws-cdk/issues/15774)) ([83dd318](https://github.com/aws/aws-cdk/commit/83dd318959b1b1e5f94b5a31030d03379638c9ad)), closes [#15758](https://github.com/aws/aws-cdk/issues/15758) +* **kinesisfirehose:** add metrics functions to IDeliveryStream ([#15618](https://github.com/aws/aws-cdk/issues/15618)) ([33909ed](https://github.com/aws/aws-cdk/commit/33909ed2144ede58e5e503f3f220f610dbd89675)), closes [#15543](https://github.com/aws/aws-cdk/issues/15543) +* **kinesisfirehose:** add support for backing up source records to S3 ([#15725](https://github.com/aws/aws-cdk/issues/15725)) ([b86062f](https://github.com/aws/aws-cdk/commit/b86062ff6215384b5def76e07586e94cc6ecc9c1)), closes [#15724](https://github.com/aws/aws-cdk/issues/15724) +* **kinesisfirehose:** add support for BufferingHints ([#15557](https://github.com/aws/aws-cdk/issues/15557)) ([099b584](https://github.com/aws/aws-cdk/commit/099b5840cc5b45bad987b7e797e6009d6383a3a7)), closes [#15554](https://github.com/aws/aws-cdk/issues/15554) +* **kinesisfirehose:** add support for Lambda data processors ([#15704](https://github.com/aws/aws-cdk/issues/15704)) ([6244a81](https://github.com/aws/aws-cdk/commit/6244a81af17ec823df409437c4a33ef5fb13a1c5)), closes [#15703](https://github.com/aws/aws-cdk/issues/15703) +* **kinesisfirehose:** add support for server-side encryption on DeliveryStream ([#15547](https://github.com/aws/aws-cdk/issues/15547)) ([74f3cda](https://github.com/aws/aws-cdk/commit/74f3cda53de7e8b5cd1d144e79cf9f5bb28e1938)), closes [#15546](https://github.com/aws/aws-cdk/issues/15546) +* **kinesisfirehose:** supports Kinesis data stream source for delivery stream ([#15836](https://github.com/aws/aws-cdk/issues/15836)) ([afd5bf7](https://github.com/aws/aws-cdk/commit/afd5bf768a280cd11b4e72db841af36df2268ccf)), closes [#15500](https://github.com/aws/aws-cdk/issues/15500) [#10783](https://github.com/aws/aws-cdk/issues/10783) +* **kinesisfirehose-destinations:** add support for compression on S3 delivery stream destinations ([#15550](https://github.com/aws/aws-cdk/issues/15550)) ([1eb56a0](https://github.com/aws/aws-cdk/commit/1eb56a025f728b7596f57b1289c2fc4c1c20e7f4)), closes [#15548](https://github.com/aws/aws-cdk/issues/15548) +* **kinesisfirehose-destinations:** add support for prefixes in the S3 destination ([#15552](https://github.com/aws/aws-cdk/issues/15552)) ([d227e48](https://github.com/aws/aws-cdk/commit/d227e48458832ff85d2d575e5462e45d29f49a6c)), closes [#15551](https://github.com/aws/aws-cdk/issues/15551) +* **lambda:** cloudwatch lambda insights ([#15439](https://github.com/aws/aws-cdk/issues/15439)) ([9efd800](https://github.com/aws/aws-cdk/commit/9efd800b4eea3a849edc5710975e4d70ec14a5cd)) +* **Route53:** add support for RemovalPolicy in CrossAccountZoneDelegationRecord ([#15782](https://github.com/aws/aws-cdk/issues/15782)) ([9eea4b8](https://github.com/aws/aws-cdk/commit/9eea4b8d454f7bc23930e6254651029b1a348a2c)), closes [#15211](https://github.com/aws/aws-cdk/issues/15211) +* **s3-deployment:** control object access ([#15730](https://github.com/aws/aws-cdk/issues/15730)) ([f58cf3c](https://github.com/aws/aws-cdk/commit/f58cf3c95eb32e9a4dc797665160e1b508ace2e1)) +* **servicecatalog:** add CloudFormation Parameter constraint ([#15770](https://github.com/aws/aws-cdk/issues/15770)) ([58fda91](https://github.com/aws/aws-cdk/commit/58fda9104ad884026d578dc0602f7d64dd533f6d)) +* **stepfunctions-tasks:** add sns publish with message attributes ([#14817](https://github.com/aws/aws-cdk/issues/14817)) ([bc99e82](https://github.com/aws/aws-cdk/commit/bc99e8271d443b10928d99437593c52efd763d7c)), closes [#4702](https://github.com/aws/aws-cdk/issues/4702) + + +### Bug Fixes + +* **assert:** module is incompatible with jest@27 ([#15666](https://github.com/aws/aws-cdk/issues/15666)) ([f446566](https://github.com/aws/aws-cdk/commit/f446566bd26ca024aed0a88da08a82a261c0dac6)) +* **appsync:** graphqlapi throws incorrect error message for authorizationConfig ([#15830](https://github.com/aws/aws-cdk/issues/15830)) ([1f23313](https://github.com/aws/aws-cdk/commit/1f23313e889a00d85e7cbc56a64242d6e7762835)), closes [#15039](https://github.com/aws/aws-cdk/issues/15039) +* **eks:** Allow desiredsize minsize and maxsize to accept CfnParameters. ([#15487](https://github.com/aws/aws-cdk/issues/15487)) ([fb43769](https://github.com/aws/aws-cdk/commit/fb437693c0f1568ddc53e9a198e54be3b9a01592)) +* **chatbot:** ARN validation in fromSlackChannelConfigurationArn fails for tokenized values ([#15849](https://github.com/aws/aws-cdk/issues/15849)) ([440ca35](https://github.com/aws/aws-cdk/commit/440ca35cf0f0e9f6f86bef445bd9aa6ef05ff9be)), closes [#15842](https://github.com/aws/aws-cdk/issues/15842) +* **cli:** move fail option into the diff command ([#15829](https://github.com/aws/aws-cdk/issues/15829)) ([473c1d8](https://github.com/aws/aws-cdk/commit/473c1d8248ae84bd8b4bb3863334e05e5328fddc)) +* **ec2:** volumename doesn't set name of volume ([#15832](https://github.com/aws/aws-cdk/issues/15832)) ([b842702](https://github.com/aws/aws-cdk/commit/b842702cbb7aa6632dd2fc4b4981abdd3a773826)), closes [#15831](https://github.com/aws/aws-cdk/issues/15831) +* **elbv2:** unresolved listener priority throws error ([#15804](https://github.com/aws/aws-cdk/issues/15804)) ([fce9ac7](https://github.com/aws/aws-cdk/commit/fce9ac73fe6da5e604f0659d9f101001dcef830a)) +* **pipelines:** Prepare stage doesn't have AUTO_EXPAND capability ([#15819](https://github.com/aws/aws-cdk/issues/15819)) ([a6fac49](https://github.com/aws/aws-cdk/commit/a6fac4974fa17949b836c72d04e1cc4504bc920a)), closes [#15711](https://github.com/aws/aws-cdk/issues/15711) +* **s3:** notifications are broken in some regions ([#15884](https://github.com/aws/aws-cdk/issues/15884)) ([ee19196](https://github.com/aws/aws-cdk/commit/ee191961a8b057a0585e731a67c15a7edd59c79e)) +* **stepfunctions-tasks:** Stage field not included in CallApiGatewayHttpApiEndpoint task definition ([#15755](https://github.com/aws/aws-cdk/issues/15755)) ([4f38fe1](https://github.com/aws/aws-cdk/commit/4f38fe1c3e5515ae22f2820712644ed763dbc248)), closes [#14242](https://github.com/aws/aws-cdk/issues/14242) + + +### Miscellaneous Chores + +* **assertions:** migrate more modules to use assertions ([#15857](https://github.com/aws/aws-cdk/issues/15857)) ([45b484c](https://github.com/aws/aws-cdk/commit/45b484cdff115a0893f7eed2b0c1d6424c2751e4)) +* **assertions:** rename TemplateAssertions to Template ([#15823](https://github.com/aws/aws-cdk/issues/15823)) ([823dfda](https://github.com/aws/aws-cdk/commit/823dfda76f39f0eff51d792b28aafcc5568f3db1)) + ## [1.116.0](https://github.com/aws/aws-cdk/compare/v1.115.0...v1.116.0) (2021-07-28) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 423fb1e897ff3..8c85b5a2ce259 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -759,17 +759,7 @@ The pattern is simple: through `cdk init`. 4. In your PR title (which goes into CHANGELOG), add a `(under feature flag)` suffix. e.g: - ``` - fix(core): impossible to use the same physical stack name for two stacks (under feature flag) - ``` -5. Under `BREAKING CHANGES` in your commit message describe this new behavior: - - ``` - BREAKING CHANGE: template file names for new projects created through "cdk init" - will use the template artifact ID instead of the physical stack name to enable - multiple stacks to use the same name. This is enabled through the flag - `@aws-cdk/core:enableStackNameDuplicates` in newly generated `cdk.json` files. - ``` + `fix(core): impossible to use the same physical stack name for two stacks (under feature flag)` In the [next major version of the CDK](https://github.com/aws/aws-cdk/issues/3398) we will either remove the diff --git a/package.json b/package.json index 66025c149aa84..a18d46e63c20d 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,8 @@ "@aws-cdk/aws-eks/yaml/**", "@aws-cdk/aws-events-targets/aws-sdk", "@aws-cdk/aws-events-targets/aws-sdk/**", + "@aws-cdk/aws-s3-deployment/case", + "@aws-cdk/aws-s3-deployment/case/**", "@aws-cdk/cloud-assembly-schema/jsonschema", "@aws-cdk/cloud-assembly-schema/jsonschema/**", "@aws-cdk/cloud-assembly-schema/semver", diff --git a/packages/@aws-cdk/alexa-ask/package.json b/packages/@aws-cdk/alexa-ask/package.json index 6462fd3fcc4ee..cf42ce0ff70cd 100644 --- a/packages/@aws-cdk/alexa-ask/package.json +++ b/packages/@aws-cdk/alexa-ask/package.json @@ -78,7 +78,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/alexa-ask/test/ask.test.ts b/packages/@aws-cdk/alexa-ask/test/ask.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/alexa-ask/test/ask.test.ts +++ b/packages/@aws-cdk/alexa-ask/test/ask.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/assert/package.json b/packages/@aws-cdk/assert/package.json index 92a9fd2f88bb8..a4366c4372345 100644 --- a/packages/@aws-cdk/assert/package.json +++ b/packages/@aws-cdk/assert/package.json @@ -53,7 +53,7 @@ "peerDependencies": { "@aws-cdk/core": "0.0.0", "constructs": "^3.3.69", - "jest": "^26.6.3" + "jest": ">=26.6.3" }, "repository": { "url": "https://github.com/aws/aws-cdk.git", diff --git a/packages/@aws-cdk/assertions/README.md b/packages/@aws-cdk/assertions/README.md index 1a79f8294cf3b..bfeb893417c31 100644 --- a/packages/@aws-cdk/assertions/README.md +++ b/packages/@aws-cdk/assertions/README.md @@ -17,24 +17,24 @@ Functions for writing test asserting against CDK applications, with focus on CloudFormation templates. -The `TemplateAssertions` class includes a set of methods for writing assertions against CloudFormation templates. Use one of the `TemplateAssertions.fromXxx()` static methods to create an instance of this class. +The `Template` class includes a set of methods for writing assertions against CloudFormation templates. Use one of the `Template.fromXxx()` static methods to create an instance of this class. -To create `TemplateAssertions` from CDK stack, start off with: +To create `Template` from CDK stack, start off with: ```ts import { Stack } from '@aws-cdk/core'; -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; const stack = new Stack(...) ... -const assert = TemplateAssertions.fromStack(stack); +const assert = Template.fromStack(stack); ``` Alternatively, assertions can be run on an existing CloudFormation template - ```ts const template = fs.readFileSync('/path/to/template/file'); -const assert = TemplateAssertions.fromString(template); +const assert = Template.fromString(template); ``` ## Full Template Match @@ -53,6 +53,17 @@ assert.templateMatches({ }); ``` +The `Template` class also supports [snapshot +testing](https://jestjs.io/docs/snapshot-testing) using jest. + +```ts +// using jest +expect(Template.fromStack(stack)).toMatchSnapshot(); +``` + +For non-javascript languages, the `toJSON()` can be called to get an in-memory object +of the template. + ## Counting Resources This module allows asserting the number of resources of a specific type found diff --git a/packages/@aws-cdk/assertions/lib/template.ts b/packages/@aws-cdk/assertions/lib/template.ts index c76f8150292a2..480290bc45b04 100644 --- a/packages/@aws-cdk/assertions/lib/template.ts +++ b/packages/@aws-cdk/assertions/lib/template.ts @@ -9,39 +9,49 @@ import * as assert from './vendored/assert'; * Typically used, as part of unit tests, to validate that the rendered * CloudFormation template has expected resources and properties. */ -export class TemplateAssertions { +export class Template { /** * Base your assertions on the CloudFormation template synthesized by a CDK `Stack`. * @param stack the CDK Stack to run assertions on */ - public static fromStack(stack: Stack): TemplateAssertions { - return new TemplateAssertions(toTemplate(stack)); + public static fromStack(stack: Stack): Template { + return new Template(toTemplate(stack)); } /** - * Base your assertions from an existing CloudFormation template formatted as a - * nested set of records. + * Base your assertions from an existing CloudFormation template formatted as an in-memory + * JSON object. * @param template the CloudFormation template formatted as a nested set of records */ - public static fromTemplate(template: { [key: string] : any }): TemplateAssertions { - return new TemplateAssertions(template); + public static fromJSON(template: { [key: string] : any }): Template { + return new Template(template); } /** - * Base your assertions from an existing CloudFormation template formatted as a string. + * Base your assertions from an existing CloudFormation template formatted as a + * JSON string. * @param template the CloudFormation template in */ - public static fromString(template: string): TemplateAssertions { - return new TemplateAssertions(JSON.parse(template)); + public static fromString(template: string): Template { + return new Template(JSON.parse(template)); } + private readonly template: { [key: string]: any }; private readonly inspector: assert.StackInspector; - private constructor(template: any) { + private constructor(template: { [key: string]: any }) { + this.template = template; this.inspector = new assert.StackInspector(template); } + /** + * The CloudFormation template deserialized into an object. + */ + public toJSON(): { [key: string]: any } { + return this.template; + } + /** * Assert that the given number of resources of the given type exist in the * template. diff --git a/packages/@aws-cdk/assertions/test/template.test.ts b/packages/@aws-cdk/assertions/test/template.test.ts index 70b09b618446c..0fe308e68e5be 100644 --- a/packages/@aws-cdk/assertions/test/template.test.ts +++ b/packages/@aws-cdk/assertions/test/template.test.ts @@ -1,11 +1,53 @@ import { CfnResource, Stack } from '@aws-cdk/core'; import { Construct } from 'constructs'; -import { Match, TemplateAssertions } from '../lib'; +import { Match, Template } from '../lib'; + +describe('Template', () => { + describe('asObject', () => { + test('fromString', () => { + const template = Template.fromString(`{ + "Resources": { + "Foo": { + "Type": "Baz::Qux", + "Properties": { "Fred": "Waldo" } + } + } + }`); + + expect(template.toJSON()).toEqual({ + Resources: { + Foo: { + Type: 'Baz::Qux', + Properties: { Fred: 'Waldo' }, + }, + }, + }); + }); + + test('fromStack', () => { + const stack = new Stack(); + new CfnResource(stack, 'Foo', { + type: 'Foo::Bar', + properties: { + Baz: 'Qux', + }, + }); + const template = Template.fromStack(stack); + + expect(template.toJSON()).toEqual({ + Resources: { + Foo: { + Type: 'Foo::Bar', + Properties: { Baz: 'Qux' }, + }, + }, + }); + }); + }); -describe('TemplateAssertions', () => { describe('fromString', () => { test('default', () => { - const assertions = TemplateAssertions.fromString(`{ + const assertions = Template.fromString(`{ "Resources": { "Foo": { "Type": "Baz::Qux", @@ -21,7 +63,7 @@ describe('TemplateAssertions', () => { test('fails when root is not a stage', () => { const c = new Construct(undefined as any, ''); const stack = new Stack(c, 'MyStack'); - expect(() => TemplateAssertions.fromStack(stack)).toThrow(/must be part of a Stage or an App/); + expect(() => Template.fromStack(stack)).toThrow(/must be part of a Stage or an App/); }); }); @@ -32,7 +74,7 @@ describe('TemplateAssertions', () => { type: 'Foo::Bar', }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); inspect.resourceCountIs('Foo::Bar', 1); expect(() => inspect.resourceCountIs('Foo::Bar', 0)).toThrow(/has 1 resource of type Foo::Bar/); @@ -44,7 +86,7 @@ describe('TemplateAssertions', () => { test('no resource', () => { const stack = new Stack(); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); inspect.resourceCountIs('Foo::Bar', 0); expect(() => inspect.resourceCountIs('Foo::Bar', 1)).toThrow(/has 0 resource of type Foo::Bar/); @@ -59,7 +101,7 @@ describe('TemplateAssertions', () => { properties: { baz: 'qux' }, }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); inspect.templateMatches({ Resources: { Foo: { @@ -77,7 +119,7 @@ describe('TemplateAssertions', () => { properties: { baz: 'qux' }, }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); expect(() => inspect.templateMatches({ Resources: { Foo: { @@ -97,7 +139,7 @@ describe('TemplateAssertions', () => { properties: { baz: 'qux' }, }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); inspect.hasResource('Foo::Bar', { Properties: { baz: 'qux' }, }); @@ -118,7 +160,7 @@ describe('TemplateAssertions', () => { properties: { baz: ['qux', 'quy'] }, }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); inspect.hasResource('Foo::Bar', { Properties: { baz: Match.arrayWith(['qux']) }, }); @@ -139,7 +181,7 @@ describe('TemplateAssertions', () => { properties: { flob: ['qux'] }, }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); expectToThrow(() => { inspect.hasResource('Foo::Bar', { @@ -157,7 +199,7 @@ describe('TemplateAssertions', () => { properties: { baz: 'qux', fred: 'waldo' }, }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); inspect.hasResource('Foo::Bar', { Properties: Match.objectLike({ baz: 'qux' }), }); @@ -181,7 +223,7 @@ describe('TemplateAssertions', () => { properties: { flob: 'waldo' }, }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); expectToThrow(() => { inspect.hasResource('Foo::Bar', { @@ -199,7 +241,7 @@ describe('TemplateAssertions', () => { properties: { baz: 'qux' }, }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); inspect.hasResource('Foo::Bar', { Properties: Match.objectLike({ foo: Match.absentProperty() }), }); @@ -215,7 +257,7 @@ describe('TemplateAssertions', () => { properties: { baz: 'qux', fred: 'waldo' }, }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); expect(() => inspect.hasResource('Foo::Baz', { Properties: Match.objectLike({ baz: 'qux' }), })).toThrow(/No resource/); @@ -230,7 +272,7 @@ describe('TemplateAssertions', () => { properties: { baz: 'qux', fred: 'waldo' }, }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); expect(inspect.findResources('Foo::Bar')).toEqual([{ Type: 'Foo::Bar', Properties: { baz: 'qux', fred: 'waldo' }, @@ -244,7 +286,7 @@ describe('TemplateAssertions', () => { properties: { baz: 'qux', fred: 'waldo' }, }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); expect(inspect.findResources('Foo::Baz')).toEqual([]); }); @@ -255,7 +297,7 @@ describe('TemplateAssertions', () => { properties: { baz: 'qux', fred: 'waldo' }, }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); expect(inspect.findResources('Foo::Bar', { Properties: { baz: 'qux' }, }).length).toEqual(1); @@ -268,7 +310,7 @@ describe('TemplateAssertions', () => { properties: { baz: 'qux', fred: 'waldo' }, }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); expect(inspect.findResources('Foo::Bar', { Properties: { baz: 'waldo' }, })).toEqual([]); @@ -279,7 +321,7 @@ describe('TemplateAssertions', () => { new CfnResource(stack, 'Foo', { type: 'Foo::Bar' }); new CfnResource(stack, 'Bar', { type: 'Foo::Bar' }); - const inspect = TemplateAssertions.fromStack(stack); + const inspect = Template.fromStack(stack); expect(inspect.findResources('Foo::Bar').length).toEqual(2); }); }); diff --git a/packages/@aws-cdk/aws-accessanalyzer/package.json b/packages/@aws-cdk/aws-accessanalyzer/package.json index dd207f1859f38..ef5d378f88205 100644 --- a/packages/@aws-cdk/aws-accessanalyzer/package.json +++ b/packages/@aws-cdk/aws-accessanalyzer/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-accessanalyzer/test/accessanalyzer.test.ts b/packages/@aws-cdk/aws-accessanalyzer/test/accessanalyzer.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-accessanalyzer/test/accessanalyzer.test.ts +++ b/packages/@aws-cdk/aws-accessanalyzer/test/accessanalyzer.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-amazonmq/package.json b/packages/@aws-cdk/aws-amazonmq/package.json index 4cdda66e3dbf4..393ef14b15326 100644 --- a/packages/@aws-cdk/aws-amazonmq/package.json +++ b/packages/@aws-cdk/aws-amazonmq/package.json @@ -78,7 +78,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-amazonmq/test/amazonmq.test.ts b/packages/@aws-cdk/aws-amazonmq/test/amazonmq.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-amazonmq/test/amazonmq.test.ts +++ b/packages/@aws-cdk/aws-amazonmq/test/amazonmq.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-amplify/package.json b/packages/@aws-cdk/aws-amplify/package.json index 35a569393b9c0..dad425ea592f2 100644 --- a/packages/@aws-cdk/aws-amplify/package.json +++ b/packages/@aws-cdk/aws-amplify/package.json @@ -75,12 +75,12 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", - "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/aws-iam": "0.0.0", diff --git a/packages/@aws-cdk/aws-amplify/test/app.test.ts b/packages/@aws-cdk/aws-amplify/test/app.test.ts index f4e4468708a76..76b6830bec1c5 100644 --- a/packages/@aws-cdk/aws-amplify/test/app.test.ts +++ b/packages/@aws-cdk/aws-amplify/test/app.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as codebuild from '@aws-cdk/aws-codebuild'; import * as codecommit from '@aws-cdk/aws-codecommit'; import { SecretValue, Stack } from '@aws-cdk/core'; @@ -32,7 +32,7 @@ test('create an app connected to a GitHub repository', () => { }); // THEN - expect(stack).toHaveResource('AWS::Amplify::App', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::App', { Name: 'App', BuildSpec: 'version: \"1.0\"\nfrontend:\n phases:\n build:\n commands:\n - npm run build\n', IAMServiceRole: { @@ -48,7 +48,7 @@ test('create an app connected to a GitHub repository', () => { }, }); - expect(stack).toHaveResource('AWS::IAM::Role', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { AssumeRolePolicyDocument: { Statement: [ { @@ -87,7 +87,7 @@ test('create an app connected to a GitLab repository', () => { }); // THEN - expect(stack).toHaveResource('AWS::Amplify::App', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::App', { Name: 'App', BuildSpec: '{\n \"version\": \"1.0\",\n \"frontend\": {\n \"phases\": {\n \"build\": {\n \"commands\": [\n \"npm run build\"\n ]\n }\n }\n }\n}', IAMServiceRole: { @@ -100,7 +100,7 @@ test('create an app connected to a GitLab repository', () => { Repository: 'https://gitlab.com/aws/aws-cdk', }); - expect(stack).toHaveResource('AWS::IAM::Role', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { AssumeRolePolicyDocument: { Statement: [ { @@ -125,7 +125,7 @@ test('create an app connected to a CodeCommit repository', () => { }); // THEN - expect(stack).toHaveResource('AWS::Amplify::App', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::App', { IAMServiceRole: { 'Fn::GetAtt': [ 'AppRole1AF9B530', @@ -150,7 +150,7 @@ test('create an app connected to a CodeCommit repository', () => { }, }); - expect(stack).toHaveResource('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -200,7 +200,7 @@ test('with basic auth from credentials', () => { }); // THEN - expect(stack).toHaveResource('AWS::Amplify::App', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::App', { BasicAuthConfig: { EnableBasicAuth: true, Password: 'password', @@ -221,7 +221,7 @@ test('with basic auth from generated password', () => { }); // THEN - expect(stack).toHaveResource('AWS::Amplify::App', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::App', { BasicAuthConfig: { EnableBasicAuth: true, Password: { @@ -240,7 +240,7 @@ test('with basic auth from generated password', () => { }, }); - expect(stack).toHaveResource('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { GenerateSecretString: { GenerateStringKey: 'password', SecretStringTemplate: '{\"username\":\"username\"}', @@ -263,7 +263,7 @@ test('with env vars', () => { app.addEnvironment('key2', 'value2'); // THEN - expect(stack).toHaveResource('AWS::Amplify::App', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::App', { EnvironmentVariables: [ { Name: 'key1', @@ -300,7 +300,7 @@ test('with custom rules', () => { }); // THEN - expect(stack).toHaveResource('AWS::Amplify::App', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::App', { CustomRules: [ { Source: '/source1', @@ -328,7 +328,7 @@ test('with SPA redirect', () => { }); // THEN - expect(stack).toHaveResource('AWS::Amplify::App', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::App', { CustomRules: [ { Source: '', @@ -356,7 +356,7 @@ test('with auto branch creation', () => { app.addAutoBranchEnvironment('key2', 'value2'); // THEN - expect(stack).toHaveResource('AWS::Amplify::App', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::App', { AutoBranchCreationConfig: { BasicAuthConfig: { EnableBasicAuth: false, @@ -390,7 +390,7 @@ test('with auto branch deletion', () => { }); // THEN - expect(stack).toHaveResource('AWS::Amplify::App', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::App', { EnableBranchAutoDeletion: true, }); }); diff --git a/packages/@aws-cdk/aws-amplify/test/branch.test.ts b/packages/@aws-cdk/aws-amplify/test/branch.test.ts index 6844d9f952d10..1638157eb4b14 100644 --- a/packages/@aws-cdk/aws-amplify/test/branch.test.ts +++ b/packages/@aws-cdk/aws-amplify/test/branch.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { SecretValue, Stack } from '@aws-cdk/core'; import * as amplify from '../lib'; @@ -20,7 +20,7 @@ test('create a branch', () => { app.addBranch('dev'); // THEN - expect(stack).toHaveResource('AWS::Amplify::Branch', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::Branch', { AppId: { 'Fn::GetAtt': [ 'AppF1B96344', @@ -40,7 +40,7 @@ test('with basic auth from credentials', () => { }); // THEN - expect(stack).toHaveResource('AWS::Amplify::Branch', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::Branch', { BasicAuthConfig: { EnableBasicAuth: true, Password: 'password', @@ -56,7 +56,7 @@ test('with basic auth from generated password', () => { }); // THEN - expect(stack).toHaveResource('AWS::Amplify::Branch', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::Branch', { BasicAuthConfig: { EnableBasicAuth: true, Password: { @@ -86,7 +86,7 @@ test('with env vars', () => { branch.addEnvironment('key2', 'value2'); // THEN - expect(stack).toHaveResource('AWS::Amplify::Branch', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::Branch', { EnvironmentVariables: [ { Name: 'key1', diff --git a/packages/@aws-cdk/aws-amplify/test/domain.test.ts b/packages/@aws-cdk/aws-amplify/test/domain.test.ts index 13311a93abaec..2188de34ef23d 100644 --- a/packages/@aws-cdk/aws-amplify/test/domain.test.ts +++ b/packages/@aws-cdk/aws-amplify/test/domain.test.ts @@ -1,5 +1,5 @@ +import { Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; -import '@aws-cdk/assert-internal/jest'; import { App, SecretValue, Stack } from '@aws-cdk/core'; import * as amplify from '../lib'; @@ -28,7 +28,7 @@ test('create a domain', () => { domain.mapSubDomain(devBranch); // THEN - expect(stack).toHaveResource('AWS::Amplify::Domain', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::Domain', { AppId: { 'Fn::GetAtt': [ 'AppF1B96344', @@ -81,7 +81,7 @@ test('map a branch to the domain root', () => { domain.mapRoot(prodBranch); // THEN - expect(stack).toHaveResource('AWS::Amplify::Domain', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::Domain', { AppId: { 'Fn::GetAtt': [ 'AppF1B96344', @@ -141,7 +141,7 @@ test('auto subdomain all branches', () => { domain.mapRoot(prodBranch); // THEN - expect(stack).toHaveResource('AWS::Amplify::Domain', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::Domain', { EnableAutoSubDomain: true, AutoSubDomainCreationPatterns: [ '*', @@ -176,7 +176,7 @@ test('auto subdomain some branches', () => { domain.mapRoot(prodBranch); // THEN - expect(stack).toHaveResource('AWS::Amplify::Domain', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::Domain', { EnableAutoSubDomain: true, AutoSubDomainCreationPatterns: ['features/**'], AutoSubDomainIAMRole: { @@ -214,7 +214,7 @@ test('auto subdomain with IAM role', () => { domain.mapRoot(prodBranch); // THEN - expect(stack).toHaveResource('AWS::Amplify::Domain', { + Template.fromStack(stack).hasResourceProperties('AWS::Amplify::Domain', { EnableAutoSubDomain: true, AutoSubDomainCreationPatterns: ['features/**'], AutoSubDomainIAMRole: { diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/package.json b/packages/@aws-cdk/aws-apigatewayv2-authorizers/package.json index 748efa7077158..8466c95ddc9da 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/package.json +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/package.json @@ -73,14 +73,14 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "@types/aws-lambda": "^8.10.79", "@aws-cdk/aws-apigatewayv2-integrations": "0.0.0", "@aws-cdk/aws-lambda": "0.0.0", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", - "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/aws-apigatewayv2": "0.0.0", diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/jwt.test.ts b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/jwt.test.ts index 469a0d6aa4ece..f97e3d4c24d74 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/jwt.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/jwt.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { HttpApi, HttpIntegrationType, HttpRouteIntegrationBindOptions, IHttpRouteIntegration, PayloadFormatVersion } from '@aws-cdk/aws-apigatewayv2'; import { Stack } from '@aws-cdk/core'; import { HttpJwtAuthorizer } from '../../lib'; @@ -22,7 +22,7 @@ describe('HttpJwtAuthorizer', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Authorizer', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Authorizer', { AuthorizerType: 'JWT', IdentitySource: ['$request.header.Authorization'], JwtConfiguration: { @@ -55,7 +55,7 @@ describe('HttpJwtAuthorizer', () => { }); // THEN - expect(stack).toCountResources('AWS::ApiGatewayV2::Authorizer', 1); + Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::Authorizer', 1); }); }); diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/lambda.test.ts b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/lambda.test.ts index a9efd500e6bf1..1f62ad76867b0 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/lambda.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/lambda.test.ts @@ -1,5 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; -import { ABSENT } from '@aws-cdk/assert-internal'; +import { Match, Template } from '@aws-cdk/assertions'; import { HttpApi, HttpIntegrationType, HttpRouteIntegrationBindOptions, IHttpRouteIntegration, PayloadFormatVersion } from '@aws-cdk/aws-apigatewayv2'; import { Code, Function, Runtime } from '@aws-cdk/aws-lambda'; import { Duration, Stack } from '@aws-cdk/core'; @@ -31,7 +30,7 @@ describe('HttpLambdaAuthorizer', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Authorizer', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Authorizer', { Name: 'default-authorizer', AuthorizerType: 'REQUEST', AuthorizerResultTtlInSeconds: 300, @@ -41,7 +40,7 @@ describe('HttpLambdaAuthorizer', () => { ], }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { AuthorizationType: 'CUSTOM', }); }); @@ -71,7 +70,7 @@ describe('HttpLambdaAuthorizer', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Authorizer', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Authorizer', { AuthorizerPayloadFormatVersion: '2.0', EnableSimpleResponses: true, }); @@ -102,9 +101,9 @@ describe('HttpLambdaAuthorizer', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Authorizer', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Authorizer', { AuthorizerPayloadFormatVersion: '1.0', - EnableSimpleResponses: ABSENT, + EnableSimpleResponses: Match.absentProperty(), }); }); @@ -133,7 +132,7 @@ describe('HttpLambdaAuthorizer', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Authorizer', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Authorizer', { AuthorizerPayloadFormatVersion: '2.0', EnableSimpleResponses: true, }); @@ -165,7 +164,7 @@ describe('HttpLambdaAuthorizer', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Authorizer', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Authorizer', { AuthorizerResultTtlInSeconds: 600, }); }); diff --git a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/user-pool.test.ts b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/user-pool.test.ts index 33086eab5ff4a..0e3c339e7f744 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/user-pool.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-authorizers/test/http/user-pool.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { HttpApi, HttpIntegrationType, HttpRouteIntegrationBindOptions, IHttpRouteIntegration, PayloadFormatVersion } from '@aws-cdk/aws-apigatewayv2'; import { UserPool } from '@aws-cdk/aws-cognito'; import { Stack } from '@aws-cdk/core'; @@ -24,7 +24,7 @@ describe('HttpUserPoolAuthorizer', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Authorizer', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Authorizer', { AuthorizerType: 'JWT', IdentitySource: ['$request.header.Authorization'], JwtConfiguration: { @@ -68,7 +68,7 @@ describe('HttpUserPoolAuthorizer', () => { }); // THEN - expect(stack).toCountResources('AWS::ApiGatewayV2::Authorizer', 1); + Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::Authorizer', 1); }); }); diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/package.json b/packages/@aws-cdk/aws-apigatewayv2-integrations/package.json index 77e37b1fd5d0d..f857a94bc93f4 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/package.json +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/package.json @@ -71,11 +71,11 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", - "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/aws-apigatewayv2": "0.0.0", diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/alb.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/alb.test.ts index 95ece74cf7e93..e5871da260bc2 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/alb.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/alb.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { HttpApi, HttpMethod, HttpRoute, HttpRouteKey, VpcLink } from '@aws-cdk/aws-apigatewayv2'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2'; @@ -25,7 +25,7 @@ describe('HttpAlbIntegration', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationType: 'HTTP_PROXY', ConnectionId: { Ref: 'HttpApiVpcLink159804837', @@ -60,7 +60,7 @@ describe('HttpAlbIntegration', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationType: 'HTTP_PROXY', ConnectionId: { Ref: 'VpcLink42ED6FF0', @@ -94,7 +94,7 @@ describe('HttpAlbIntegration', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationMethod: 'PATCH', }); }); @@ -137,7 +137,7 @@ describe('HttpAlbIntegration', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { TlsConfig: { ServerNameToVerify: 'name-to-verify', }, diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/http-proxy.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/http-proxy.test.ts index 9c3b09ddcfbd6..0c76996fe7867 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/http-proxy.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/http-proxy.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { HttpApi, HttpIntegration, HttpIntegrationType, HttpMethod, HttpRoute, HttpRouteKey, PayloadFormatVersion } from '@aws-cdk/aws-apigatewayv2'; import { Stack } from '@aws-cdk/core'; import { HttpProxyIntegration } from '../../lib'; @@ -15,7 +15,7 @@ describe('HttpProxyIntegration', () => { routeKey: HttpRouteKey.with('/pets'), }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationType: 'HTTP_PROXY', IntegrationUri: 'some-target-url', PayloadFormatVersion: '1.0', @@ -35,7 +35,7 @@ describe('HttpProxyIntegration', () => { routeKey: HttpRouteKey.with('/pets'), }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationMethod: 'PATCH', }); }); @@ -50,7 +50,7 @@ describe('HttpProxyIntegration', () => { integrationUri: 'some-target-url', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationType: 'HTTP_PROXY', IntegrationUri: 'some-target-url', PayloadFormatVersion: '99.99', @@ -66,7 +66,7 @@ describe('HttpProxyIntegration', () => { integrationUri: 'some-target-url', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationType: 'HTTP_PROXY', IntegrationUri: 'some-target-url', }); diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/lambda.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/lambda.test.ts index 6414869f66f66..d0ead43945ec4 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/lambda.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/lambda.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { HttpApi, HttpRoute, HttpRouteKey, PayloadFormatVersion } from '@aws-cdk/aws-apigatewayv2'; import { Code, Function, Runtime } from '@aws-cdk/aws-lambda'; import { App, Stack } from '@aws-cdk/core'; @@ -17,7 +17,7 @@ describe('LambdaProxyIntegration', () => { routeKey: HttpRouteKey.with('/pets'), }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationType: 'AWS_PROXY', IntegrationUri: stack.resolve(fooFn.functionArn), PayloadFormatVersion: '2.0', @@ -36,7 +36,7 @@ describe('LambdaProxyIntegration', () => { routeKey: HttpRouteKey.with('/pets'), }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { PayloadFormatVersion: '1.0', }); }); diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/nlb.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/nlb.test.ts index 2b7120ea33582..a32d448d8e448 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/nlb.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/nlb.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { HttpApi, HttpMethod, HttpRoute, HttpRouteKey, VpcLink } from '@aws-cdk/aws-apigatewayv2'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as elbv2 from '@aws-cdk/aws-elasticloadbalancingv2'; @@ -25,7 +25,7 @@ describe('HttpNlbIntegration', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationType: 'HTTP_PROXY', ConnectionId: { Ref: 'HttpApiVpcLink159804837', @@ -60,7 +60,7 @@ describe('HttpNlbIntegration', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationType: 'HTTP_PROXY', ConnectionId: { Ref: 'VpcLink42ED6FF0', @@ -94,7 +94,7 @@ describe('HttpNlbIntegration', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationMethod: 'PATCH', }); }); @@ -134,7 +134,7 @@ describe('HttpNlbIntegration', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { TlsConfig: { ServerNameToVerify: 'name-to-verify', }, diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/private/integration.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/private/integration.test.ts index fb6c4ab082b53..8cda89e3d2390 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/private/integration.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/private/integration.test.ts @@ -1,4 +1,3 @@ -import '@aws-cdk/assert-internal/jest'; import { HttpApi, HttpRoute, HttpRouteIntegrationBindOptions, HttpRouteIntegrationConfig, HttpRouteKey } from '@aws-cdk/aws-apigatewayv2'; import { Stack } from '@aws-cdk/core'; import { HttpPrivateIntegration } from '../../../lib/http/private/integration'; diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/service-discovery.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/service-discovery.test.ts index 83d2b47252598..4d3bef328a637 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/service-discovery.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/http/service-discovery.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { HttpApi, HttpMethod, HttpRoute, HttpRouteKey, VpcLink } from '@aws-cdk/aws-apigatewayv2'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as servicediscovery from '@aws-cdk/aws-servicediscovery'; @@ -29,7 +29,7 @@ describe('HttpServiceDiscoveryIntegration', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationType: 'HTTP_PROXY', ConnectionId: { Ref: 'VpcLink42ED6FF0', @@ -70,7 +70,7 @@ describe('HttpServiceDiscoveryIntegration', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationMethod: 'PATCH', }); }); @@ -119,7 +119,7 @@ describe('HttpServiceDiscoveryIntegration', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { TlsConfig: { ServerNameToVerify: 'name-to-verify', }, diff --git a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/lambda.test.ts b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/lambda.test.ts index d5d7e4079db2d..e12b09f75ed50 100644 --- a/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/lambda.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2-integrations/test/websocket/lambda.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { WebSocketApi } from '@aws-cdk/aws-apigatewayv2'; import { Code, Function, Runtime } from '@aws-cdk/aws-lambda'; import { Stack } from '@aws-cdk/core'; @@ -19,7 +19,7 @@ describe('LambdaWebSocketIntegration', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationType: 'AWS_PROXY', IntegrationUri: { 'Fn::Join': [ diff --git a/packages/@aws-cdk/aws-apigatewayv2/package.json b/packages/@aws-cdk/aws-apigatewayv2/package.json index 20d03097c4ae7..d0f2d3b6288c2 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/package.json +++ b/packages/@aws-cdk/aws-apigatewayv2/package.json @@ -78,12 +78,12 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", - "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/aws-certificatemanager": "0.0.0", diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/common/api-mapping.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/common/api-mapping.test.ts index 705f3ca6a4371..607afb5f8238f 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/common/api-mapping.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/common/api-mapping.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { Certificate } from '@aws-cdk/aws-certificatemanager'; import { Stack } from '@aws-cdk/core'; import { DomainName, HttpApi, ApiMapping, WebSocketApi } from '../../lib'; @@ -22,7 +22,7 @@ describe('ApiMapping', () => { domainName: dn, }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::ApiMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::ApiMapping', { ApiId: { Ref: 'ApiF70053CD', }, @@ -54,7 +54,7 @@ describe('ApiMapping', () => { apiMappingKey: 'beta', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::ApiMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::ApiMapping', { ApiId: { Ref: 'ApiF70053CD', }, 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 c2324412d3396..a4e880bac742d 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/http/api.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/http/api.test.ts @@ -1,5 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; -import { ABSENT } from '@aws-cdk/assert-internal'; +import { Match, Template } from '@aws-cdk/assertions'; import { Metric } from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; import { Duration, Stack } from '@aws-cdk/core'; @@ -14,19 +13,19 @@ describe('HttpApi', () => { const stack = new Stack(); const api = new HttpApi(stack, 'api'); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Api', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Api', { Name: 'api', ProtocolType: 'HTTP', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Stage', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Stage', { ApiId: stack.resolve(api.apiId), StageName: '$default', AutoDeploy: true, }); - expect(stack).not.toHaveResource('AWS::ApiGatewayV2::Route'); - expect(stack).not.toHaveResource('AWS::ApiGatewayV2::Integration'); + Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::Route', 0); + Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::Integration', 0); expect(api.url).toBeDefined(); }); @@ -45,7 +44,7 @@ describe('HttpApi', () => { createDefaultStage: false, }); - expect(stack).not.toHaveResource('AWS::ApiGatewayV2::Stage'); + Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::Stage', 0); expect(api.url).toBeUndefined(); }); @@ -55,12 +54,12 @@ describe('HttpApi', () => { defaultIntegration: new DummyRouteIntegration(), }); - expect(stack).toHaveResourceLike('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { ApiId: stack.resolve(httpApi.apiId), RouteKey: '$default', }); - expect(stack).toHaveResourceLike('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { ApiId: stack.resolve(httpApi.apiId), }); }); @@ -75,12 +74,12 @@ describe('HttpApi', () => { integration: new DummyRouteIntegration(), }); - expect(stack).toHaveResourceLike('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { ApiId: stack.resolve(httpApi.apiId), RouteKey: 'GET /pets', }); - expect(stack).toHaveResourceLike('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { ApiId: stack.resolve(httpApi.apiId), RouteKey: 'PATCH /pets', }); @@ -95,7 +94,7 @@ describe('HttpApi', () => { integration: new DummyRouteIntegration(), }); - expect(stack).toHaveResourceLike('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { ApiId: stack.resolve(httpApi.apiId), RouteKey: 'ANY /pets', }); @@ -113,7 +112,7 @@ describe('HttpApi', () => { }, }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Api', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Api', { CorsConfiguration: { AllowHeaders: ['Authorization'], AllowMethods: ['GET', 'HEAD', 'OPTIONS', 'POST', '*'], @@ -127,8 +126,8 @@ describe('HttpApi', () => { const stack = new Stack(); new HttpApi(stack, 'HttpApi'); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Api', { - CorsConfiguration: ABSENT, + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Api', { + CorsConfiguration: Match.absentProperty(), }); }); @@ -214,7 +213,7 @@ describe('HttpApi', () => { description: 'My Api', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Api', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Api', { Name: 'api', ProtocolType: 'HTTP', Description: 'My Api', @@ -227,7 +226,7 @@ describe('HttpApi', () => { disableExecuteApiEndpoint: true, }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Api', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Api', { Name: 'api', ProtocolType: 'HTTP', DisableExecuteApiEndpoint: true, @@ -246,10 +245,10 @@ describe('HttpApi', () => { api.addVpcLink({ vpc: vpc2, vpcLinkName: 'Link-2' }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::VpcLink', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::VpcLink', { Name: 'Link-1', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::VpcLink', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::VpcLink', { Name: 'Link-2', }); }); @@ -265,12 +264,12 @@ describe('HttpApi', () => { api.addVpcLink({ vpc, vpcLinkName: 'Link-2' }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::VpcLink', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::VpcLink', { Name: 'Link-1', }); - expect(stack).not.toHaveResource('AWS::ApiGatewayV2::VpcLink', { + expect(Template.fromStack(stack).findResources('AWS::ApiGatewayV2::VpcLink', { Name: 'Link-2', - }); + }).length).toEqual(0); }); test('apiEndpoint is exported', () => { @@ -292,12 +291,12 @@ describe('HttpApi', () => { authorizer, }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Api', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Api', { Name: 'api', ProtocolType: 'HTTP', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { AuthorizerId: 'auth-1234', AuthorizationType: 'JWT', }); @@ -327,7 +326,7 @@ describe('HttpApi', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { AuthorizerId: '12345', }); }); @@ -345,12 +344,12 @@ describe('HttpApi', () => { authorizationScopes: ['read:scopes'], }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Api', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Api', { Name: 'api', ProtocolType: 'HTTP', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { AuthorizerId: 'auth-1234', AuthorizationType: 'JWT', AuthorizationScopes: ['read:scopes'], @@ -393,7 +392,7 @@ describe('HttpApi', () => { integration: new DummyRouteIntegration(), }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { AuthorizerId: 'auth-1234', AuthorizationType: 'JWT', AuthorizationScopes: ['read:pets'], @@ -411,7 +410,7 @@ describe('HttpApi', () => { defaultAuthorizationScopes: ['read:pets'], }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { AuthorizerId: 'auth-1234', AuthorizationType: 'JWT', AuthorizationScopes: ['read:pets'], @@ -440,15 +439,15 @@ describe('HttpApi', () => { authorizer: new HttpNoneAuthorizer(), }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { RouteKey: 'GET /pets', AuthorizerId: 'auth-1234', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { RouteKey: 'GET /chickens', AuthorizationType: 'NONE', - AuthorizerId: ABSENT, + AuthorizerId: Match.absentProperty(), }); }); @@ -469,8 +468,8 @@ describe('HttpApi', () => { authorizationScopes: [], }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { - AuthorizationScopes: ABSENT, + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { + AuthorizationScopes: Match.absentProperty(), }); }); @@ -497,12 +496,12 @@ describe('HttpApi', () => { authorizationScopes: ['read:chickens'], }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { RouteKey: 'GET /pets', AuthorizationScopes: ['read:pets'], }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { RouteKey: 'GET /chickens', AuthorizationScopes: ['read:chickens'], }); diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/http/authorizer.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/http/authorizer.test.ts index 92c0ee0422c17..8cdca389cad00 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/http/authorizer.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/http/authorizer.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { Stack } from '@aws-cdk/core'; import { HttpApi, HttpAuthorizer, HttpAuthorizerType, @@ -17,7 +17,7 @@ describe('HttpAuthorizer', () => { jwtIssuer: 'issuer', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Authorizer', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Authorizer', { ApiId: stack.resolve(httpApi.apiId), Name: 'HttpAuthorizer', AuthorizerType: 'JWT', @@ -38,7 +38,7 @@ describe('HttpAuthorizer', () => { jwtIssuer: 'issuer', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Authorizer', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Authorizer', { Name: 'my-authorizer', }); }); @@ -56,7 +56,7 @@ describe('HttpAuthorizer', () => { jwtIssuer: 'issuer', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Authorizer', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Authorizer', { JwtConfiguration: { Audience: ['audience.1', 'audience.2'], Issuer: 'issuer', @@ -77,7 +77,7 @@ describe('HttpAuthorizer', () => { authorizerUri: 'arn:cool-lambda-arn', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Authorizer', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Authorizer', { AuthorizerType: 'REQUEST', AuthorizerPayloadFormatVersion: '2.0', AuthorizerUri: 'arn:cool-lambda-arn', diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/http/domain-name.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/http/domain-name.test.ts index c0074ac464d63..dc64fbf5bf7c9 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/http/domain-name.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/http/domain-name.test.ts @@ -1,5 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; -// import { expect, haveResource, haveResourceLike } from '@aws-cdk/assert-internal'; +import { Template } from '@aws-cdk/assertions'; import { Certificate } from '@aws-cdk/aws-certificatemanager'; import { Stack } from '@aws-cdk/core'; import { DomainName, HttpApi } from '../../lib'; @@ -19,7 +18,7 @@ describe('DomainName', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::DomainName', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::DomainName', { DomainName: 'example.com', DomainNameConfigurations: [ { @@ -74,7 +73,7 @@ describe('DomainName', () => { }, }); - expect(stack).toHaveResourceLike('AWS::ApiGatewayV2::DomainName', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::DomainName', { DomainName: 'example.com', DomainNameConfigurations: [ { @@ -83,7 +82,7 @@ describe('DomainName', () => { }, ], }); - expect(stack).toHaveResourceLike('AWS::ApiGatewayV2::ApiMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::ApiMapping', { ApiId: { Ref: 'ApiF70053CD', }, @@ -110,7 +109,7 @@ describe('DomainName', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::ApiGatewayV2::DomainName', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::DomainName', { DomainName: 'example.com', DomainNameConfigurations: [ { @@ -120,7 +119,7 @@ describe('DomainName', () => { ], }); - expect(stack).toHaveResourceLike('AWS::ApiGatewayV2::ApiMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::ApiMapping', { ApiId: { Ref: 'ApiF70053CD', }, 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 748ec8cb68d41..9f64cfdfbd123 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/http/route.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/http/route.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { Stack, App } from '@aws-cdk/core'; import { HttpApi, HttpAuthorizer, HttpAuthorizerType, HttpConnectionType, HttpIntegrationType, HttpMethod, HttpRoute, HttpRouteAuthorizerBindOptions, @@ -16,7 +16,7 @@ describe('HttpRoute', () => { routeKey: HttpRouteKey.with('/books', HttpMethod.GET), }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { ApiId: stack.resolve(httpApi.apiId), RouteKey: 'GET /books', Target: { @@ -33,7 +33,7 @@ describe('HttpRoute', () => { AuthorizationType: 'NONE', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { ApiId: stack.resolve(httpApi.apiId), }); }); @@ -48,7 +48,7 @@ describe('HttpRoute', () => { routeKey: HttpRouteKey.with('/books', HttpMethod.GET), }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { ApiId: stack.resolve(httpApi.apiId), IntegrationType: 'HTTP_PROXY', PayloadFormatVersion: '2.0', @@ -75,7 +75,7 @@ describe('HttpRoute', () => { }); // THEN - expect(stack).toCountResources('AWS::ApiGatewayV2::Integration', 1); + Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::Integration', 1); }); test('integration can be used across HttpApis', () => { @@ -112,8 +112,8 @@ describe('HttpRoute', () => { }); // THEN - expect(stack1).toCountResources('AWS::ApiGatewayV2::Integration', 1); - expect(stack2).toCountResources('AWS::ApiGatewayV2::Integration', 1); + Template.fromStack(stack1).resourceCountIs('AWS::ApiGatewayV2::Integration', 1); + Template.fromStack(stack2).resourceCountIs('AWS::ApiGatewayV2::Integration', 1); }); test('route defined in a separate stack does not create cycles', () => { @@ -133,8 +133,8 @@ describe('HttpRoute', () => { }); // THEN - expect(stack1).toCountResources('AWS::ApiGatewayV2::Integration', 0); - expect(stack2).toCountResources('AWS::ApiGatewayV2::Integration', 1); + Template.fromStack(stack1).resourceCountIs('AWS::ApiGatewayV2::Integration', 0); + Template.fromStack(stack2).resourceCountIs('AWS::ApiGatewayV2::Integration', 1); }); test('throws when path not start with /', () => { @@ -186,7 +186,7 @@ describe('HttpRoute', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { IntegrationType: 'HTTP_PROXY', ConnectionId: 'some-connection-id', ConnectionType: 'VPC_LINK', @@ -198,7 +198,7 @@ describe('HttpRoute', () => { }, }); - expect(stack).not.toHaveResource('AWS::ApiGatewayV2::VpcLink'); + Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::VpcLink', 0); }); test('can create route with an authorizer attached', () => { @@ -214,16 +214,16 @@ describe('HttpRoute', () => { authorizer, }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { ApiId: stack.resolve(httpApi.apiId), IntegrationType: 'HTTP_PROXY', PayloadFormatVersion: '2.0', IntegrationUri: 'some-uri', }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Authorizer'); + Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::Authorizer', 1); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { AuthorizerId: stack.resolve(authorizer.bind({ scope: stack, route: route }).authorizerId), AuthorizationType: 'JWT', }); @@ -243,7 +243,7 @@ describe('HttpRoute', () => { authorizationScopes: ['read:books'], }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { AuthorizationScopes: ['read:books'], }); }); diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/http/stage.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/http/stage.test.ts index e3758183c68ff..c56c2ded5d48b 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/http/stage.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/http/stage.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { Metric } from '@aws-cdk/aws-cloudwatch'; import { Stack } from '@aws-cdk/core'; import { HttpApi, HttpStage } from '../../lib'; @@ -15,7 +15,7 @@ describe('HttpStage', () => { httpApi: api, }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Stage', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Stage', { ApiId: stack.resolve(api.apiId), StageName: '$default', }); diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/http/vpc-link.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/http/vpc-link.test.ts index 134c70b653ce6..99f7d480da63b 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/http/vpc-link.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/http/vpc-link.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import { Stack } from '@aws-cdk/core'; import { VpcLink } from '../../lib'; @@ -16,7 +16,7 @@ describe('VpcLink', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::VpcLink', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::VpcLink', { Name: 'MyLink', SubnetIds: [ { @@ -56,7 +56,7 @@ describe('VpcLink', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::VpcLink', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::VpcLink', { Name: 'VpcLink', SubnetIds: [ { @@ -104,7 +104,7 @@ describe('VpcLink', () => { vpcLink.addSubnets(subnet); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::VpcLink', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::VpcLink', { Name: 'VpcLink', SubnetIds: [ { @@ -136,7 +136,7 @@ describe('VpcLink', () => { vpcLink.addSecurityGroups(sg1, sg2, sg3); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::VpcLink', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::VpcLink', { Name: 'VpcLink', SubnetIds: [ { @@ -183,6 +183,6 @@ describe('VpcLink', () => { }); // THEN - expect(stack).not.toHaveResource('AWS::ApiGatewayV2::VpcLink'); + Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::VpcLink', 0); }); }); diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/websocket/api.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/websocket/api.test.ts index 8a387941cad6f..959555a5c2b7a 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/websocket/api.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/websocket/api.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { Stack } from '@aws-cdk/core'; import { IWebSocketRouteIntegration, WebSocketApi, WebSocketIntegrationType, @@ -14,14 +14,14 @@ describe('WebSocketApi', () => { new WebSocketApi(stack, 'api'); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Api', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Api', { Name: 'api', ProtocolType: 'WEBSOCKET', }); - expect(stack).not.toHaveResource('AWS::ApiGatewayV2::Stage'); - expect(stack).not.toHaveResource('AWS::ApiGatewayV2::Route'); - expect(stack).not.toHaveResource('AWS::ApiGatewayV2::Integration'); + Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::Stage', 0); + Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::Route', 0); + Template.fromStack(stack).resourceCountIs('AWS::ApiGatewayV2::Integration', 0); }); test('addRoute: adds a route with passed key', () => { @@ -33,7 +33,7 @@ describe('WebSocketApi', () => { api.addRoute('myroute', { integration: new DummyIntegration() }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { ApiId: stack.resolve(api.apiId), RouteKey: 'myroute', }); @@ -47,7 +47,7 @@ describe('WebSocketApi', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { ApiId: stack.resolve(api.apiId), RouteKey: '$connect', }); @@ -61,7 +61,7 @@ describe('WebSocketApi', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { ApiId: stack.resolve(api.apiId), RouteKey: '$disconnect', }); @@ -75,7 +75,7 @@ describe('WebSocketApi', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { ApiId: stack.resolve(api.apiId), RouteKey: '$default', }); diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/websocket/route.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/websocket/route.test.ts index ae73fd7e6cba0..07eadc5300a85 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/websocket/route.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/websocket/route.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { Stack } from '@aws-cdk/core'; import { IWebSocketRouteIntegration, WebSocketApi, WebSocketIntegrationType, @@ -19,7 +19,7 @@ describe('WebSocketRoute', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Route', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Route', { ApiId: stack.resolve(webSocketApi.apiId), RouteKey: 'message', Target: { @@ -35,7 +35,7 @@ describe('WebSocketRoute', () => { }, }); - expect(stack).toHaveResource('AWS::ApiGatewayV2::Integration', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Integration', { ApiId: stack.resolve(webSocketApi.apiId), IntegrationType: 'AWS_PROXY', IntegrationUri: 'some-uri', diff --git a/packages/@aws-cdk/aws-apigatewayv2/test/websocket/stage.test.ts b/packages/@aws-cdk/aws-apigatewayv2/test/websocket/stage.test.ts index bec3e34e5d4fb..d942eb6dc7a4e 100644 --- a/packages/@aws-cdk/aws-apigatewayv2/test/websocket/stage.test.ts +++ b/packages/@aws-cdk/aws-apigatewayv2/test/websocket/stage.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { Stack } from '@aws-cdk/core'; import { WebSocketApi, WebSocketStage } from '../../lib'; @@ -15,7 +15,7 @@ describe('WebSocketStage', () => { }); // THEN - expect(stack).toHaveResource('AWS::ApiGatewayV2::Stage', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGatewayV2::Stage', { ApiId: stack.resolve(api.apiId), StageName: 'dev', }); diff --git a/packages/@aws-cdk/aws-appconfig/package.json b/packages/@aws-cdk/aws-appconfig/package.json index 7ae2918e7a24a..87877e48cadd7 100644 --- a/packages/@aws-cdk/aws-appconfig/package.json +++ b/packages/@aws-cdk/aws-appconfig/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-appconfig/test/appconfig.test.ts b/packages/@aws-cdk/aws-appconfig/test/appconfig.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-appconfig/test/appconfig.test.ts +++ b/packages/@aws-cdk/aws-appconfig/test/appconfig.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-appflow/package.json b/packages/@aws-cdk/aws-appflow/package.json index d3892bc22a18e..3c1164cb36e44 100644 --- a/packages/@aws-cdk/aws-appflow/package.json +++ b/packages/@aws-cdk/aws-appflow/package.json @@ -76,7 +76,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-appflow/test/appflow.test.ts b/packages/@aws-cdk/aws-appflow/test/appflow.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-appflow/test/appflow.test.ts +++ b/packages/@aws-cdk/aws-appflow/test/appflow.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-appintegrations/package.json b/packages/@aws-cdk/aws-appintegrations/package.json index cc372cc4fb1f7..df834c9675083 100644 --- a/packages/@aws-cdk/aws-appintegrations/package.json +++ b/packages/@aws-cdk/aws-appintegrations/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-appintegrations/test/appintegrations.test.ts b/packages/@aws-cdk/aws-appintegrations/test/appintegrations.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-appintegrations/test/appintegrations.test.ts +++ b/packages/@aws-cdk/aws-appintegrations/test/appintegrations.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-applicationinsights/package.json b/packages/@aws-cdk/aws-applicationinsights/package.json index 0dcc760a0ef2b..3b0b998051313 100644 --- a/packages/@aws-cdk/aws-applicationinsights/package.json +++ b/packages/@aws-cdk/aws-applicationinsights/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-applicationinsights/test/applicationinsights.test.ts b/packages/@aws-cdk/aws-applicationinsights/test/applicationinsights.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-applicationinsights/test/applicationinsights.test.ts +++ b/packages/@aws-cdk/aws-applicationinsights/test/applicationinsights.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-apprunner/package.json b/packages/@aws-cdk/aws-apprunner/package.json index 20db35c7a3264..ffbecdc004aa6 100644 --- a/packages/@aws-cdk/aws-apprunner/package.json +++ b/packages/@aws-cdk/aws-apprunner/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-apprunner/test/apprunner.test.ts b/packages/@aws-cdk/aws-apprunner/test/apprunner.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-apprunner/test/apprunner.test.ts +++ b/packages/@aws-cdk/aws-apprunner/test/apprunner.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-appstream/package.json b/packages/@aws-cdk/aws-appstream/package.json index 2bdd6def0c6f8..3605b0f0e9ccf 100644 --- a/packages/@aws-cdk/aws-appstream/package.json +++ b/packages/@aws-cdk/aws-appstream/package.json @@ -78,7 +78,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-appstream/test/appstream.test.ts b/packages/@aws-cdk/aws-appstream/test/appstream.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-appstream/test/appstream.test.ts +++ b/packages/@aws-cdk/aws-appstream/test/appstream.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-appsync/lib/graphqlapi.ts b/packages/@aws-cdk/aws-appsync/lib/graphqlapi.ts index 9dcc75719b77b..8b0252bed9eb4 100644 --- a/packages/@aws-cdk/aws-appsync/lib/graphqlapi.ts +++ b/packages/@aws-cdk/aws-appsync/lib/graphqlapi.ts @@ -492,10 +492,10 @@ export class GraphqlApi extends GraphqlApiBase { private validateAuthorizationProps(modes: AuthorizationMode[]) { modes.map((mode) => { if (mode.authorizationType === AuthorizationType.OIDC && !mode.openIdConnectConfig) { - throw new Error('Missing default OIDC Configuration'); + throw new Error('Missing OIDC Configuration'); } if (mode.authorizationType === AuthorizationType.USER_POOL && !mode.userPoolConfig) { - throw new Error('Missing default OIDC Configuration'); + throw new Error('Missing User Pool Configuration'); } }); if (modes.filter((mode) => mode.authorizationType === AuthorizationType.API_KEY).length > 1) { diff --git a/packages/@aws-cdk/aws-appsync/package.json b/packages/@aws-cdk/aws-appsync/package.json index 13267c04844cc..bc2dc7796af93 100644 --- a/packages/@aws-cdk/aws-appsync/package.json +++ b/packages/@aws-cdk/aws-appsync/package.json @@ -73,14 +73,14 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", + "@aws-cdk/aws-stepfunctions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", "jest": "^26.6.3", - "pkglint": "0.0.0", - "@aws-cdk/aws-stepfunctions": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/aws-cognito": "0.0.0", diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-auth.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-auth.test.ts index c0d7ce0ac8796..a137e54b0423f 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-auth.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-auth.test.ts @@ -1,5 +1,5 @@ -import '@aws-cdk/assert-internal/jest'; import * as path from 'path'; +import { Template } from '@aws-cdk/assertions'; import * as cognito from '@aws-cdk/aws-cognito'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; @@ -19,7 +19,7 @@ describe('AppSync API Key Authorization', () => { }); // THEN - expect(stack).toHaveResource('AWS::AppSync::ApiKey'); + Template.fromStack(stack).resourceCountIs('AWS::AppSync::ApiKey', 1); }); test('AppSync creates api key from additionalAuthorizationModes', () => { @@ -36,7 +36,7 @@ describe('AppSync API Key Authorization', () => { }); // THEN - expect(stack).toHaveResource('AWS::AppSync::ApiKey'); + Template.fromStack(stack).resourceCountIs('AWS::AppSync::ApiKey', 1); }); test('AppSync does not create unspecified api key from additionalAuthorizationModes', () => { @@ -50,7 +50,7 @@ describe('AppSync API Key Authorization', () => { }); // THEN - expect(stack).not.toHaveResource('AWS::AppSync::ApiKey'); + Template.fromStack(stack).resourceCountIs('AWS::AppSync::ApiKey', 0); }); test('appsync does not create unspecified api key with empty additionalAuthorizationModes', () => { @@ -65,7 +65,7 @@ describe('AppSync API Key Authorization', () => { }); // THEN - expect(stack).not.toHaveResource('AWS::AppSync::ApiKey'); + Template.fromStack(stack).resourceCountIs('AWS::AppSync::ApiKey', 0); }); test('appsync creates configured api key with additionalAuthorizationModes', () => { @@ -83,7 +83,7 @@ describe('AppSync API Key Authorization', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::ApiKey', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::ApiKey', { Description: 'Custom Description', }); }); @@ -105,7 +105,7 @@ describe('AppSync API Key Authorization', () => { }, }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::ApiKey', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::ApiKey', { ApiId: { 'Fn::GetAtt': ['API62EA1CFF', 'ApiId'] }, Expires: expirationDate, }); @@ -174,7 +174,7 @@ describe('AppSync API Key Authorization', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::ApiKey', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::ApiKey', { Description: 'Custom Description', }); }); @@ -240,7 +240,7 @@ describe('AppSync IAM Authorization', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { AuthenticationType: 'AWS_IAM', }); }); @@ -256,7 +256,7 @@ describe('AppSync IAM Authorization', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { AdditionalAuthenticationProviders: [{ AuthenticationType: 'AWS_IAM' }], }); }); @@ -311,7 +311,7 @@ describe('AppSync User Pool Authorization', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { AuthenticationType: 'AMAZON_COGNITO_USER_POOLS', UserPoolConfig: { AwsRegion: { Ref: 'AWS::Region' }, @@ -339,7 +339,7 @@ describe('AppSync User Pool Authorization', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { AuthenticationType: 'AMAZON_COGNITO_USER_POOLS', UserPoolConfig: { AwsRegion: { Ref: 'AWS::Region' }, @@ -364,7 +364,7 @@ describe('AppSync User Pool Authorization', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { AdditionalAuthenticationProviders: [{ AuthenticationType: 'AMAZON_COGNITO_USER_POOLS', UserPoolConfig: { @@ -393,7 +393,7 @@ describe('AppSync User Pool Authorization', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { AdditionalAuthenticationProviders: [{ AuthenticationType: 'AMAZON_COGNITO_USER_POOLS', UserPoolConfig: { @@ -433,7 +433,7 @@ describe('AppSync User Pool Authorization', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { AuthenticationType: 'AMAZON_COGNITO_USER_POOLS', UserPoolConfig: { AwsRegion: { Ref: 'AWS::Region' }, @@ -476,7 +476,7 @@ describe('AppSync OIDC Authorization', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { AuthenticationType: 'OPENID_CONNECT', OpenIDConnectConfig: { Issuer: 'test', @@ -503,7 +503,7 @@ describe('AppSync OIDC Authorization', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { AuthenticationType: 'OPENID_CONNECT', OpenIDConnectConfig: { AuthTTL: 1, @@ -528,7 +528,7 @@ describe('AppSync OIDC Authorization', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { AdditionalAuthenticationProviders: [{ AuthenticationType: 'OPENID_CONNECT', OpenIDConnectConfig: { @@ -557,7 +557,7 @@ describe('AppSync OIDC Authorization', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { AdditionalAuthenticationProviders: [{ AuthenticationType: 'OPENID_CONNECT', OpenIDConnectConfig: { @@ -604,7 +604,7 @@ describe('AppSync OIDC Authorization', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { AuthenticationType: 'OPENID_CONNECT', OpenIDConnectConfig: { Issuer: 'test' }, AdditionalAuthenticationProviders: [ diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-code-first.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-code-first.test.ts index 5abe04434496a..d904186f4f07b 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-code-first.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-code-first.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; import * as t from './scalar-type-defintions'; @@ -34,7 +34,7 @@ describe('code-first implementation through GraphQL Api functions`', () => { const out = 'interface Test {\n id: ID\n lid: [ID]\n rid: ID!\n rlid: [ID]!\n rlrid: [ID!]!\n dupid: [ID!]!\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -55,7 +55,7 @@ describe('code-first implementation through GraphQL Api functions`', () => { const out = 'type Test {\n id: ID\n lid: [ID]\n rid: ID!\n rlid: [ID]!\n rlrid: [ID!]!\n dupid: [ID!]!\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -75,7 +75,7 @@ describe('code-first implementation through GraphQL Api functions`', () => { const out = 'type Test {\n id: ID\n lid: [ID]\n rid: ID!\n rlid: [ID]!\n rlrid: [ID!]!\n dupid: [ID!]!\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -96,7 +96,7 @@ describe('code-first implementation through GraphQL Api functions`', () => { const out = 'type Test {\n id: ID\n lid: [ID]\n rid: ID!\n rlid: [ID]!\n rlrid: [ID!]!\n dupid: [ID!]!\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -116,7 +116,7 @@ describe('code-first implementation through GraphQL Api functions`', () => { const out = 'interface Test {\n id: ID\n lid: [ID]\n rid: ID!\n rlid: [ID]!\n rlrid: [ID!]!\n dupid: [ID!]!\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -137,7 +137,7 @@ describe('code-first implementation through GraphQL Api functions`', () => { const out = 'interface Test {\n id: ID\n lid: [ID]\n rid: ID!\n rlid: [ID]!\n rlrid: [ID!]!\n dupid: [ID!]!\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -171,7 +171,7 @@ describe('code-first implementation through Schema functions`', () => { const out = 'interface Test {\n id: ID\n lid: [ID]\n rid: ID!\n rlid: [ID]!\n rlrid: [ID!]!\n dupid: [ID!]!\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -197,7 +197,7 @@ describe('code-first implementation through Schema functions`', () => { const out = 'type Test {\n id: ID\n lid: [ID]\n rid: ID!\n rlid: [ID]!\n rlrid: [ID!]!\n dupid: [ID!]!\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -223,7 +223,7 @@ describe('code-first implementation through Schema functions`', () => { const out = 'type Test {\n id: ID\n lid: [ID]\n rid: ID!\n rlid: [ID]!\n rlrid: [ID!]!\n dupid: [ID!]!\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -248,7 +248,7 @@ describe('code-first implementation through Schema functions`', () => { const out = 'type Test {\n id: ID\n lid: [ID]\n rid: ID!\n rlid: [ID]!\n rlrid: [ID!]!\n dupid: [ID!]!\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -272,7 +272,7 @@ describe('code-first implementation through Schema functions`', () => { const out = 'interface Test {\n id: ID\n lid: [ID]\n rid: ID!\n rlid: [ID]!\n rlrid: [ID!]!\n dupid: [ID!]!\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -297,7 +297,7 @@ describe('code-first implementation through Schema functions`', () => { const out = 'interface Test {\n id: ID\n lid: [ID]\n rid: ID!\n rlid: [ID]!\n rlrid: [ID!]!\n dupid: [ID!]!\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-directives.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-directives.test.ts index 1d4d211ac8289..de2ce5d864813 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-directives.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-directives.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cognito from '@aws-cdk/aws-cognito'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; @@ -85,7 +85,7 @@ const testObjectType = (IApi: appsync.GraphqlApi, directives: appsync.Directive[ directives: directives, })); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `type Test ${tag} {\n field: String\n ${tag}\n rfield: String\n ${tag}\n}\n`, }); }; @@ -100,7 +100,7 @@ const testInterfaceType = (IApi: appsync.GraphqlApi, directives: appsync.Directi directives: directives, })); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `interface Test ${tag} {\n field: String\n ${tag}\n rfield: String\n ${tag}\n}\n`, }); }; diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-dynamodb.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-dynamodb.test.ts index ffc36ddabd276..657eecd9f9064 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-dynamodb.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-dynamodb.test.ts @@ -1,5 +1,5 @@ -import '@aws-cdk/assert-internal/jest'; import * as path from 'path'; +import { Template } from '@aws-cdk/assertions'; import * as db from '@aws-cdk/aws-dynamodb'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; @@ -36,7 +36,7 @@ describe('DynamoDb Data Source configuration', () => { api.addDynamoDbDataSource('ds', table); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AMAZON_DYNAMODB', Name: 'ds', }); @@ -49,7 +49,7 @@ describe('DynamoDb Data Source configuration', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AMAZON_DYNAMODB', Name: 'custom', }); @@ -63,7 +63,7 @@ describe('DynamoDb Data Source configuration', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AMAZON_DYNAMODB', Name: 'custom', Description: 'custom description', @@ -166,7 +166,7 @@ describe('adding DynamoDb data source from imported api', () => { importedApi.addDynamoDbDataSource('ds', table); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AMAZON_DYNAMODB', ApiId: { 'Fn::GetAtt': ['baseApiCDA4D43A', 'ApiId'] }, }); @@ -181,7 +181,7 @@ describe('adding DynamoDb data source from imported api', () => { importedApi.addDynamoDbDataSource('ds', table); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AMAZON_DYNAMODB', ApiId: { 'Fn::GetAtt': ['baseApiCDA4D43A', 'ApiId'] }, }); diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-elasticsearch.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-elasticsearch.test.ts index 1a974f982b61f..89199d65ca629 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-elasticsearch.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-elasticsearch.test.ts @@ -1,5 +1,5 @@ -import '@aws-cdk/assert-internal/jest'; import * as path from 'path'; +import { Template } from '@aws-cdk/assertions'; import * as es from '@aws-cdk/aws-elasticsearch'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; @@ -25,7 +25,7 @@ describe('Elasticsearch Data Source Configuration', () => { api.addElasticsearchDataSource('ds', domain); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Version: '2012-10-17', Statement: [{ @@ -56,7 +56,7 @@ describe('Elasticsearch Data Source Configuration', () => { api.addElasticsearchDataSource('ds', domain); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { ElasticsearchConfig: { Endpoint: { 'Fn::Join': ['', ['https://', { @@ -72,7 +72,7 @@ describe('Elasticsearch Data Source Configuration', () => { api.addElasticsearchDataSource('ds', domain); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AMAZON_ELASTICSEARCH', Name: 'ds', }); @@ -85,7 +85,7 @@ describe('Elasticsearch Data Source Configuration', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AMAZON_ELASTICSEARCH', Name: 'custom', }); @@ -99,7 +99,7 @@ describe('Elasticsearch Data Source Configuration', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AMAZON_ELASTICSEARCH', Name: 'custom', Description: 'custom description', @@ -127,7 +127,7 @@ describe('adding elasticsearch data source from imported api', () => { importedApi.addElasticsearchDataSource('ds', domain); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AMAZON_ELASTICSEARCH', ApiId: { 'Fn::GetAtt': ['baseApiCDA4D43A', 'ApiId'] }, }); @@ -142,7 +142,7 @@ describe('adding elasticsearch data source from imported api', () => { importedApi.addElasticsearchDataSource('ds', domain); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AMAZON_ELASTICSEARCH', ApiId: { 'Fn::GetAtt': ['baseApiCDA4D43A', 'ApiId'] }, }); diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-enum-type.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-enum-type.test.ts index 82551e354d1a0..a04e9a5c89d82 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-enum-type.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-enum-type.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; import * as t from './scalar-type-defintions'; @@ -23,10 +23,10 @@ describe('testing Enum Type properties', () => { api.addType(test); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); - expect(stack).not.toHaveResource('AWS::AppSync::Resolver'); + Template.fromStack(stack).resourceCountIs('AWS::AppSync::Resolver', 0); }); test('EnumType can addField', () => { @@ -38,7 +38,7 @@ describe('testing Enum Type properties', () => { test.addField({ fieldName: 'test3' }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -57,7 +57,7 @@ describe('testing Enum Type properties', () => { const obj = 'type Test2 {\n enum: Test\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}${obj}`, }); }); diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-grant.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-grant.test.ts index 904c19b7dafd6..fb23df6e8ec74 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-grant.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-grant.test.ts @@ -1,5 +1,5 @@ import { join } from 'path'; -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; @@ -38,11 +38,12 @@ describe('grant Permissions', () => { api.grant(role, appsync.IamResource.custom('types/Mutation/fields/addTest'), 'appsync:GraphQL'); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: { 'Fn::Join': ['', [ 'arn:', @@ -67,11 +68,12 @@ describe('grant Permissions', () => { api.grant(role, appsync.IamResource.ofType('Mutation'), 'appsync:GraphQL'); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: { 'Fn::Join': ['', [ 'arn:', @@ -96,11 +98,12 @@ describe('grant Permissions', () => { api.grant(role, appsync.IamResource.ofType('Mutation', 'addTest'), 'appsync:GraphQL'); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: { 'Fn::Join': ['', [ 'arn:', @@ -125,11 +128,12 @@ describe('grant Permissions', () => { api.grant(role, appsync.IamResource.all(), 'appsync:GraphQL'); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: { 'Fn::Join': ['', [ 'arn:', @@ -154,11 +158,12 @@ describe('grant Permissions', () => { api.grant(role, appsync.IamResource.custom('I', 'am', 'custom'), 'appsync:GraphQL'); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: [ { 'Fn::Join': ['', [ @@ -211,11 +216,12 @@ describe('grant Permissions', () => { api.grant(role, appsync.IamResource.ofType('I', 'am', 'custom'), 'appsync:GraphQL'); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: [ { 'Fn::Join': ['', [ @@ -258,11 +264,12 @@ describe('grantMutation Permissions', () => { api.grantMutation(role); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: { 'Fn::Join': ['', [ 'arn:', @@ -287,11 +294,12 @@ describe('grantMutation Permissions', () => { api.grantMutation(role, 'addTest'); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: { 'Fn::Join': ['', [ 'arn:', @@ -316,11 +324,12 @@ describe('grantMutation Permissions', () => { api.grantMutation(role, 'addTest', 'removeTest'); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: [ { 'Fn::Join': ['', [ @@ -363,11 +372,12 @@ describe('grantQuery Permissions', () => { api.grantQuery(role); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: { 'Fn::Join': ['', [ 'arn:', @@ -392,11 +402,12 @@ describe('grantQuery Permissions', () => { api.grantQuery(role, 'getTest'); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: { 'Fn::Join': ['', [ 'arn:', @@ -421,11 +432,12 @@ describe('grantQuery Permissions', () => { api.grantQuery(role, 'getTests', 'getTest'); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: [ { 'Fn::Join': ['', [ @@ -468,11 +480,12 @@ describe('grantSubscription Permissions', () => { api.grantSubscription(role); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: { 'Fn::Join': ['', [ 'arn:', @@ -496,11 +509,12 @@ describe('grantSubscription Permissions', () => { api.grantSubscription(role, 'subscribe'); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: { 'Fn::Join': ['', [ 'arn:', @@ -525,11 +539,12 @@ describe('grantSubscription Permissions', () => { api.grantSubscription(role, 'subscribe', 'custom'); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { Action: 'appsync:GraphQL', + Effect: 'Allow', Resource: [ { 'Fn::Join': ['', [ diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-http.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-http.test.ts index 8023412c78a55..2f380b028c592 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-http.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-http.test.ts @@ -1,5 +1,5 @@ -import '@aws-cdk/assert-internal/jest'; import * as path from 'path'; +import { Template } from '@aws-cdk/assertions'; import * as sfn from '@aws-cdk/aws-stepfunctions'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; @@ -24,7 +24,7 @@ describe('Http Data Source configuration', () => { api.addHttpDataSource('ds', endpoint); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'HTTP', Name: 'ds', }); @@ -37,7 +37,7 @@ describe('Http Data Source configuration', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'HTTP', Name: 'custom', }); @@ -51,7 +51,7 @@ describe('Http Data Source configuration', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'HTTP', Name: 'custom', Description: 'custom description', @@ -70,7 +70,7 @@ describe('Http Data Source configuration', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'HTTP', Name: 'custom', Description: 'custom description', @@ -103,7 +103,7 @@ describe('Http Data Source configuration', () => { // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -176,7 +176,7 @@ describe('adding http data source from imported api', () => { importedApi.addHttpDataSource('ds', endpoint); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'HTTP', ApiId: { 'Fn::GetAtt': ['baseApiCDA4D43A', 'ApiId'] }, }); @@ -191,7 +191,7 @@ describe('adding http data source from imported api', () => { importedApi.addHttpDataSource('ds', endpoint); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'HTTP', ApiId: { 'Fn::GetAtt': ['baseApiCDA4D43A', 'ApiId'] }, }); diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-input-types.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-input-types.test.ts index bfc391aeaf0f3..f58196e43cd31 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-input-types.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-input-types.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; import * as t from './scalar-type-defintions'; @@ -23,10 +23,10 @@ describe('testing Input Type properties', () => { api.addType(test); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); - expect(stack).not.toHaveResource('AWS::AppSync::Resolver'); + Template.fromStack(stack).resourceCountIs('AWS::AppSync::Resolver', 0); }); test('InputType can addField', () => { @@ -36,7 +36,7 @@ describe('testing Input Type properties', () => { test.addField({ fieldName: 'test', field: t.string }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -88,7 +88,7 @@ describe('testing Input Type properties', () => { const obj = 'type Test2 {\n input: Test\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}${obj}`, }); }); diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-interface-type.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-interface-type.test.ts index 4061a2e69a0f9..f94400fab6ea3 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-interface-type.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-interface-type.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; import * as t from './scalar-type-defintions'; @@ -28,7 +28,7 @@ describe('testing InterfaceType properties', () => { const out = 'interface baseTest {\n id: ID\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -46,7 +46,7 @@ describe('testing InterfaceType properties', () => { const out = 'interface baseTest {\n id: ID\n test(success: Int): String\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -65,10 +65,10 @@ describe('testing InterfaceType properties', () => { const out = 'interface baseTest {\n id: ID\n test(success: Int): String\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); - expect(stack).not.toHaveResource('AWS::AppSync::Resolver'); + Template.fromStack(stack).resourceCountIs('AWS::AppSync::Resolver', 0); }); test('Interface Type can be a Graphql Type', () => { @@ -84,7 +84,7 @@ describe('testing InterfaceType properties', () => { const out = 'type Test {\n test: baseTest\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -108,7 +108,7 @@ describe('testing InterfaceType properties', () => { const out = 'interface Test {\n test: String\n resolve: String\n @aws_api_key\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -133,10 +133,10 @@ describe('testing InterfaceType properties', () => { const out = 'interface Test {\n test: String\n resolve: String\n @aws_api_key\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); - expect(stack).not.toHaveResource('AWS::AppSync::Resolver'); + Template.fromStack(stack).resourceCountIs('AWS::AppSync::Resolver', 0); }); test('appsync fails addField with InterfaceType missing fieldName', () => { diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-lambda.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-lambda.test.ts index 55c2ec0f132eb..b714b0f28cef9 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-lambda.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-lambda.test.ts @@ -1,5 +1,5 @@ -import '@aws-cdk/assert-internal/jest'; import * as path from 'path'; +import { Template } from '@aws-cdk/assertions'; import * as lambda from '@aws-cdk/aws-lambda'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; @@ -31,7 +31,7 @@ describe('Lambda Data Source configuration', () => { api.addLambdaDataSource('ds', func); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AWS_LAMBDA', Name: 'ds', }); @@ -44,7 +44,7 @@ describe('Lambda Data Source configuration', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AWS_LAMBDA', Name: 'custom', }); @@ -58,7 +58,7 @@ describe('Lambda Data Source configuration', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AWS_LAMBDA', Name: 'custom', Description: 'custom description', @@ -86,7 +86,7 @@ describe('Lambda Data Source configuration', () => { }); // THEN - expect(stack).toHaveResource('AWS::AppSync::Resolver'); + Template.fromStack(stack).resourceCountIs('AWS::AppSync::Resolver', 1); }); }); @@ -108,7 +108,7 @@ describe('adding lambda data source from imported api', () => { importedApi.addLambdaDataSource('ds', func); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AWS_LAMBDA', ApiId: { 'Fn::GetAtt': ['baseApiCDA4D43A', 'ApiId'] }, }); @@ -123,7 +123,7 @@ describe('adding lambda data source from imported api', () => { importedApi.addLambdaDataSource('ds', func); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'AWS_LAMBDA', ApiId: { 'Fn::GetAtt': ['baseApiCDA4D43A', 'ApiId'] }, }); diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-mapping-template.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-mapping-template.test.ts index d19b07d196b21..2259cbb4c48df 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-mapping-template.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-mapping-template.test.ts @@ -1,5 +1,5 @@ -import '@aws-cdk/assert-internal/jest'; import * as path from 'path'; +import { Template } from '@aws-cdk/assertions'; import * as lambda from '@aws-cdk/aws-lambda'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; @@ -42,7 +42,7 @@ describe('Lambda Mapping Templates', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::Resolver', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::Resolver', { FieldName: 'allPosts', RequestMappingTemplate: invokeMT, }); @@ -60,7 +60,7 @@ describe('Lambda Mapping Templates', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::Resolver', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::Resolver', { FieldName: 'relatedPosts', RequestMappingTemplate: batchMT, }); diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-none.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-none.test.ts index 6dc1e0ad9273f..5dec58aa5b726 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-none.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-none.test.ts @@ -1,5 +1,5 @@ -import '@aws-cdk/assert-internal/jest'; import * as path from 'path'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; @@ -21,7 +21,7 @@ describe('None Data Source configuration', () => { api.addNoneDataSource('ds'); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'NONE', Name: 'ds', }); @@ -34,7 +34,7 @@ describe('None Data Source configuration', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'NONE', Name: 'custom', }); @@ -48,7 +48,7 @@ describe('None Data Source configuration', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'NONE', Name: 'custom', Description: 'custom description', @@ -81,7 +81,7 @@ describe('adding none data source from imported api', () => { importedApi.addNoneDataSource('none'); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'NONE', ApiId: { 'Fn::GetAtt': ['baseApiCDA4D43A', 'ApiId'] }, }); @@ -96,7 +96,7 @@ describe('adding none data source from imported api', () => { importedApi.addNoneDataSource('none'); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'NONE', ApiId: { 'Fn::GetAtt': ['baseApiCDA4D43A', 'ApiId'] }, }); diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-object-type.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-object-type.test.ts index 03e2bb411bbe9..4180ec9d30dad 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-object-type.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-object-type.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; import * as t from './scalar-type-defintions'; @@ -36,7 +36,7 @@ describe('testing Object Type properties', () => { const out = `${gql_interface}${gql_object}`; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -65,7 +65,7 @@ describe('testing Object Type properties', () => { const out = `${gql_interface}${gql_object}`; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -87,7 +87,7 @@ describe('testing Object Type properties', () => { const out = 'type Test {\n test: baseTest\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -112,7 +112,7 @@ describe('testing Object Type properties', () => { const out = 'type Test {\n test: String\n resolve(arg: Int): String\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -137,7 +137,7 @@ describe('testing Object Type properties', () => { const out = 'type Test {\n test: String\n resolve(arg: Int): String\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -171,7 +171,7 @@ describe('testing Object Type properties', () => { api.addType(test); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::Resolver', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::Resolver', { Kind: 'PIPELINE', PipelineConfig: { Functions: [ @@ -202,10 +202,10 @@ describe('testing Object Type properties', () => { const out = 'type Test {\n test: String\n resolve(arg: Int): String\n dynamic: String\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); - expect(stack).toHaveResource('AWS::AppSync::Resolver'); + Template.fromStack(stack).resourceCountIs('AWS::AppSync::Resolver', 1); }); test('Object Type can generate Fields with Directives', () => { @@ -227,7 +227,7 @@ describe('testing Object Type properties', () => { const out = 'type Test {\n test: String\n resolve: String\n @aws_api_key\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -254,10 +254,10 @@ describe('testing Object Type properties', () => { const out = 'type Test {\n test: String\n resolve(arg: String): String\n @aws_api_key\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); - expect(stack).toHaveResource('AWS::AppSync::Resolver'); + Template.fromStack(stack).resourceCountIs('AWS::AppSync::Resolver', 1); }); test('appsync fails addField with ObjectType missing fieldName', () => { 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 9a328b0fe65a0..cc7329344b84e 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-rds.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-rds.test.ts @@ -1,5 +1,5 @@ -import '@aws-cdk/assert-internal/jest'; import * as path from 'path'; +import { Template } from '@aws-cdk/assertions'; import { Vpc, SecurityGroup, SubnetType } from '@aws-cdk/aws-ec2'; import { DatabaseSecret, DatabaseClusterEngine, AuroraMysqlEngineVersion, ServerlessCluster } from '@aws-cdk/aws-rds'; import * as cdk from '@aws-cdk/core'; @@ -47,7 +47,7 @@ describe('Rds Data Source configuration', () => { api.addRdsDataSource('ds', cluster, secret); // THEN - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Version: '2012-10-17', Statement: [{ @@ -117,7 +117,7 @@ describe('Rds Data Source configuration', () => { api.addRdsDataSource('ds', cluster, secret); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'RELATIONAL_DATABASE', RelationalDatabaseConfig: { RdsHttpEndpointConfig: { @@ -144,7 +144,7 @@ describe('Rds Data Source configuration', () => { api.addRdsDataSource('ds', cluster, secret, testDatabaseName); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'RELATIONAL_DATABASE', RelationalDatabaseConfig: { RdsHttpEndpointConfig: { @@ -171,7 +171,7 @@ describe('Rds Data Source configuration', () => { api.addRdsDataSource('ds', cluster, secret); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'RELATIONAL_DATABASE', Name: 'ds', }); @@ -184,7 +184,7 @@ describe('Rds Data Source configuration', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'RELATIONAL_DATABASE', Name: 'custom', }); @@ -198,7 +198,7 @@ describe('Rds Data Source configuration', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'RELATIONAL_DATABASE', Name: 'custom', Description: 'custom description', @@ -249,7 +249,7 @@ describe('adding rds data source from imported api', () => { importedApi.addRdsDataSource('ds', cluster, secret); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'RELATIONAL_DATABASE', ApiId: { 'Fn::GetAtt': ['baseApiCDA4D43A', 'ApiId'] }, }); @@ -264,7 +264,7 @@ describe('adding rds data source from imported api', () => { importedApi.addRdsDataSource('ds', cluster, secret); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::DataSource', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::DataSource', { Type: 'RELATIONAL_DATABASE', ApiId: { 'Fn::GetAtt': ['baseApiCDA4D43A', 'ApiId'] }, }); diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-scalar-type.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-scalar-type.test.ts index 150b45e747006..01cf50bd8904b 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-scalar-type.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-scalar-type.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; import * as t from './scalar-type-defintions'; @@ -24,7 +24,7 @@ describe('testing all GraphQL Types', () => { const out = 'type Test {\n id: ID\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -39,7 +39,7 @@ describe('testing all GraphQL Types', () => { const out = 'type Test {\n id: String\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -54,7 +54,7 @@ describe('testing all GraphQL Types', () => { const out = 'type Test {\n id: Int\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -69,7 +69,7 @@ describe('testing all GraphQL Types', () => { const out = 'type Test {\n id: Float\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -84,7 +84,7 @@ describe('testing all GraphQL Types', () => { const out = 'type Test {\n id: Boolean\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -99,7 +99,7 @@ describe('testing all GraphQL Types', () => { const out = 'type Test {\n id: AWSDate\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -114,7 +114,7 @@ describe('testing all GraphQL Types', () => { const out = 'type Test {\n id: AWSTime\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -129,7 +129,7 @@ describe('testing all GraphQL Types', () => { const out = 'type Test {\n id: AWSDateTime\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -144,7 +144,7 @@ describe('testing all GraphQL Types', () => { const out = 'type Test {\n id: AWSTimestamp\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -159,7 +159,7 @@ describe('testing all GraphQL Types', () => { const out = 'type Test {\n id: AWSEmail\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -174,7 +174,7 @@ describe('testing all GraphQL Types', () => { const out = 'type Test {\n id: AWSJSON\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -190,7 +190,7 @@ describe('testing all GraphQL Types', () => { const out = 'type Test {\n id: AWSURL\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -205,7 +205,7 @@ describe('testing all GraphQL Types', () => { const out = 'type Test {\n id: AWSPhone\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -220,7 +220,7 @@ describe('testing all GraphQL Types', () => { const out = 'type Test {\n id: AWSIPAddress\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-schema.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-schema.test.ts index 37db685807139..9e3c5d951d807 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-schema.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-schema.test.ts @@ -1,5 +1,5 @@ import { join } from 'path'; -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; import * as t from './scalar-type-defintions'; @@ -41,7 +41,7 @@ describe('basic testing schema definition mode `code`', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: '', }); }); @@ -56,7 +56,7 @@ describe('basic testing schema definition mode `code`', () => { api.addType(mutation); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${type.toString()}\n${query.toString()}\n${mutation.toString()}\n`, }); }); @@ -71,7 +71,7 @@ describe('basic testing schema definition mode `code`', () => { })); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: 'schema {\n query: Query\n}\ntype Query {\n test: String\n}\n', }); }); @@ -88,7 +88,7 @@ describe('basic testing schema definition mode `code`', () => { })); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: 'schema {\n query: Query\n}\ntype Query {\n test: String\n}\n', }); }); @@ -103,7 +103,7 @@ describe('basic testing schema definition mode `code`', () => { })); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: 'schema {\n mutation: Mutation\n}\ntype Mutation {\n test: String\n}\n', }); }); @@ -120,7 +120,7 @@ describe('basic testing schema definition mode `code`', () => { })); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: 'schema {\n mutation: Mutation\n}\ntype Mutation {\n test: String\n}\n', }); }); @@ -135,7 +135,7 @@ describe('basic testing schema definition mode `code`', () => { })); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: 'schema {\n subscription: Subscription\n}\ntype Subscription {\n test: String\n}\n', }); }); @@ -152,7 +152,7 @@ describe('basic testing schema definition mode `code`', () => { })); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: 'schema {\n subscription: Subscription\n}\ntype Subscription {\n test: String\n}\n', }); }); @@ -170,7 +170,7 @@ describe('basic testing schema definition mode `code`', () => { const out = 'schema {\n subscription: Subscription\n}\ntype Subscription {\n test: String\n @aws_subscribe(mutations: ["test1"])\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: out, }); }); @@ -186,7 +186,7 @@ describe('testing schema definition mode `file`', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${type.toString()}\n${query.toString()}\n${mutation.toString()}\n`, }); }); diff --git a/packages/@aws-cdk/aws-appsync/test/appsync-union-types.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync-union-types.test.ts index a2f0e6f47a41a..b84099b93e68f 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync-union-types.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync-union-types.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; import * as t from './scalar-type-defintions'; @@ -30,10 +30,10 @@ describe('testing Union Type properties', () => { }); api.addType(union); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); - expect(stack).not.toHaveResource('AWS::AppSync::Resolver'); + Template.fromStack(stack).resourceCountIs('AWS::AppSync::Resolver', 0); }); test('UnionType can addField', () => { @@ -45,7 +45,7 @@ describe('testing Union Type properties', () => { union.addField({ field: test2.attribute() }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}`, }); }); @@ -90,7 +90,7 @@ describe('testing Union Type properties', () => { const obj = 'type Test2 {\n union: UnionTest\n}\n'; // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLSchema', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLSchema', { Definition: `${out}${obj}`, }); }); diff --git a/packages/@aws-cdk/aws-appsync/test/appsync.test.ts b/packages/@aws-cdk/aws-appsync/test/appsync.test.ts index 773b1142b0917..9c75c0c7a28c9 100644 --- a/packages/@aws-cdk/aws-appsync/test/appsync.test.ts +++ b/packages/@aws-cdk/aws-appsync/test/appsync.test.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; import * as appsync from '../lib'; @@ -32,7 +32,7 @@ test('appsync should configure pipeline when pipelineConfig has contents', () => }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::Resolver', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::Resolver', { Kind: 'PIPELINE', PipelineConfig: { Functions: [ @@ -74,7 +74,7 @@ test('appsync should configure resolver as unit when pipelineConfig is empty', ( }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::Resolver', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::Resolver', { Kind: 'UNIT', }); }); @@ -88,7 +88,7 @@ test('appsync should configure resolver as unit when pipelineConfig is empty arr }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::Resolver', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::Resolver', { Kind: 'UNIT', }); }); @@ -103,7 +103,7 @@ test('when xray is enabled should not throw an Error', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { XrayEnabled: true, }); }); @@ -128,7 +128,7 @@ test('appsync GraphqlApi should be configured with custom CloudWatch Logs role w }); // THEN - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { Name: 'apiWithCustomRole', LogConfig: { CloudWatchLogsRoleArn: { @@ -143,7 +143,7 @@ test('appsync GraphqlApi should be configured with custom CloudWatch Logs role w test('appsync GraphqlApi should not use custom role for CW Logs when not specified', () => { // EXPECT - expect(stack).toHaveResourceLike('AWS::AppSync::GraphQLApi', { + Template.fromStack(stack).hasResourceProperties('AWS::AppSync::GraphQLApi', { Name: 'api', LogConfig: { CloudWatchLogsRoleArn: { diff --git a/packages/@aws-cdk/aws-athena/package.json b/packages/@aws-cdk/aws-athena/package.json index 0170da3267a71..4248daf56fb68 100644 --- a/packages/@aws-cdk/aws-athena/package.json +++ b/packages/@aws-cdk/aws-athena/package.json @@ -79,7 +79,7 @@ "nodeunit-shim": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-athena/test/athena.test.ts b/packages/@aws-cdk/aws-athena/test/athena.test.ts index 3e954a5b6c39b..5e84a85f5e1cf 100644 --- a/packages/@aws-cdk/aws-athena/test/athena.test.ts +++ b/packages/@aws-cdk/aws-athena/test/athena.test.ts @@ -1,5 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; -import { expect, haveResource } from '@aws-cdk/assert-internal'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import { CfnWorkGroup } from '../lib'; @@ -28,7 +27,7 @@ describe('Athena Workgroup Tags', () => { }, }, }); - expect(stack).to(haveResource('AWS::Athena::WorkGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::Athena::WorkGroup', { Tags: [ { Key: 'key1', @@ -39,7 +38,7 @@ describe('Athena Workgroup Tags', () => { Value: 'value2', }, ], - })); + }); }); test('test tag aspect spec correction', () => { const stack = new cdk.Stack(); @@ -57,7 +56,7 @@ describe('Athena Workgroup Tags', () => { }, }, }); - expect(stack).to(haveResource('AWS::Athena::WorkGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::Athena::WorkGroup', { Tags: [ { Key: 'key1', @@ -68,6 +67,6 @@ describe('Athena Workgroup Tags', () => { Value: 'value2', }, ], - })); + }); }); }); diff --git a/packages/@aws-cdk/aws-auditmanager/package.json b/packages/@aws-cdk/aws-auditmanager/package.json index e1c4d99497507..f667b4c12c375 100644 --- a/packages/@aws-cdk/aws-auditmanager/package.json +++ b/packages/@aws-cdk/aws-auditmanager/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-auditmanager/test/auditmanager.test.ts b/packages/@aws-cdk/aws-auditmanager/test/auditmanager.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-auditmanager/test/auditmanager.test.ts +++ b/packages/@aws-cdk/aws-auditmanager/test/auditmanager.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-autoscalingplans/package.json b/packages/@aws-cdk/aws-autoscalingplans/package.json index e665150f6b980..653b5457f3c97 100644 --- a/packages/@aws-cdk/aws-autoscalingplans/package.json +++ b/packages/@aws-cdk/aws-autoscalingplans/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-autoscalingplans/test/autoscalingplans.test.ts b/packages/@aws-cdk/aws-autoscalingplans/test/autoscalingplans.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-autoscalingplans/test/autoscalingplans.test.ts +++ b/packages/@aws-cdk/aws-autoscalingplans/test/autoscalingplans.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-batch/package.json b/packages/@aws-cdk/aws-batch/package.json index 158edc9ff76ff..bc9cbf389cd8c 100644 --- a/packages/@aws-cdk/aws-batch/package.json +++ b/packages/@aws-cdk/aws-batch/package.json @@ -73,13 +73,13 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", "jest": "^26.6.3", - "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-batch/test/compute-environment.test.ts b/packages/@aws-cdk/aws-batch/test/compute-environment.test.ts index dd18be3f1496c..c7ead4cd47de8 100644 --- a/packages/@aws-cdk/aws-batch/test/compute-environment.test.ts +++ b/packages/@aws-cdk/aws-batch/test/compute-environment.test.ts @@ -1,6 +1,5 @@ import { throws } from 'assert'; -import { expect, haveResource, haveResourceLike, ResourcePart } from '@aws-cdk/assert-internal'; -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as ecs from '@aws-cdk/aws-ecs'; import * as iam from '@aws-cdk/aws-iam'; @@ -96,7 +95,7 @@ describe('Batch Compute Evironment', () => { }); // THEN - expect(stack).to(haveResourceLike('AWS::Batch::ComputeEnvironment', { + Template.fromStack(stack).hasResourceProperties('AWS::Batch::ComputeEnvironment', { Type: 'MANAGED', ...expectedManagedDefaultComputeProps({ Type: batch.ComputeResourceType.SPOT, @@ -117,7 +116,7 @@ describe('Batch Compute Evironment', () => { ], }, }), - }, ResourcePart.Properties)); + }); }); describe('with a bid percentage', () => { @@ -200,7 +199,7 @@ describe('Batch Compute Evironment', () => { new batch.ComputeEnvironment(stack, 'test-compute-env', props); // THEN - expect(stack).to(haveResourceLike('AWS::Batch::ComputeEnvironment', { + Template.fromStack(stack).hasResourceProperties('AWS::Batch::ComputeEnvironment', { ComputeEnvironmentName: 'my-test-compute-env', Type: 'MANAGED', State: 'DISABLED', @@ -251,7 +250,7 @@ describe('Batch Compute Evironment', () => { }, Type: 'EC2', }, - }, ResourcePart.Properties)); + }); }); describe('with no allocation strategy specified', () => { @@ -265,7 +264,7 @@ describe('Batch Compute Evironment', () => { }); // THEN - expect(stack).to(haveResourceLike('AWS::Batch::ComputeEnvironment', { + Template.fromStack(stack).hasResourceProperties('AWS::Batch::ComputeEnvironment', { Type: 'MANAGED', ServiceRole: { 'Fn::GetAtt': [ @@ -273,7 +272,7 @@ describe('Batch Compute Evironment', () => { 'Arn', ], }, - }, ResourcePart.Properties)); + }); }); }); @@ -317,12 +316,12 @@ describe('Batch Compute Evironment', () => { }); // THEN - expect(stack).to(haveResourceLike('AWS::Batch::ComputeEnvironment', { + Template.fromStack(stack).hasResourceProperties('AWS::Batch::ComputeEnvironment', { ...defaultServiceRole, ...expectedManagedDefaultComputeProps({ MinvCpus: 0, }), - }, ResourcePart.Properties)); + }); }); }); @@ -337,11 +336,11 @@ describe('Batch Compute Evironment', () => { }); // THEN - expect(stack).to(haveResourceLike('AWS::Batch::ComputeEnvironment', { + Template.fromStack(stack).hasResourceProperties('AWS::Batch::ComputeEnvironment', { ...expectedManagedDefaultComputeProps({ MaxvCpus: 256, }), - }, ResourcePart.Properties)); + }); }); }); @@ -356,8 +355,8 @@ describe('Batch Compute Evironment', () => { }); // THEN - expect(stack).to(haveResource('AWS::Batch::ComputeEnvironment')); - expect(stack).to(haveResource('AWS::IAM::Role')); + Template.fromStack(stack).resourceCountIs('AWS::Batch::ComputeEnvironment', 1); + Template.fromStack(stack).resourceCountIs('AWS::IAM::Role', 2); }); }); @@ -372,11 +371,11 @@ describe('Batch Compute Evironment', () => { }); // THEN - expect(stack).to(haveResourceLike('AWS::Batch::ComputeEnvironment', { + Template.fromStack(stack).hasResourceProperties('AWS::Batch::ComputeEnvironment', { ...expectedManagedDefaultComputeProps({ InstanceTypes: ['optimal'], }), - }, ResourcePart.Properties)); + }); }); }); @@ -391,11 +390,11 @@ describe('Batch Compute Evironment', () => { }); // THEN - expect(stack).to(haveResourceLike('AWS::Batch::ComputeEnvironment', { + Template.fromStack(stack).hasResourceProperties('AWS::Batch::ComputeEnvironment', { ...expectedManagedDefaultComputeProps({ Type: batch.ComputeResourceType.ON_DEMAND, }), - }, ResourcePart.Properties)); + }); }); }); }); diff --git a/packages/@aws-cdk/aws-batch/test/job-definition.test.ts b/packages/@aws-cdk/aws-batch/test/job-definition.test.ts index 2761611e063bb..ed9bffb7a90bc 100644 --- a/packages/@aws-cdk/aws-batch/test/job-definition.test.ts +++ b/packages/@aws-cdk/aws-batch/test/job-definition.test.ts @@ -1,5 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; -import { ResourcePart } from '@aws-cdk/assert-internal/lib/assertions/have-resource'; +import { Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as ecr from '@aws-cdk/aws-ecr'; import * as ecs from '@aws-cdk/aws-ecs'; @@ -70,7 +69,7 @@ describe('Batch Job Definition', () => { new batch.JobDefinition(stack, 'job-def', jobDefProps); // THEN - expect(stack).toHaveResourceLike('AWS::Batch::JobDefinition', { + Template.fromStack(stack).hasResourceProperties('AWS::Batch::JobDefinition', { JobDefinitionName: jobDefProps.jobDefinitionName, ContainerProperties: jobDefProps.container ? { Command: jobDefProps.container.command, @@ -113,7 +112,7 @@ describe('Batch Job Definition', () => { AttemptDurationSeconds: jobDefProps.timeout ? jobDefProps.timeout.toSeconds() : -1, }, Type: 'container', - }, ResourcePart.Properties); + }); }); test('can use an ecr image', () => { // WHEN @@ -126,7 +125,7 @@ describe('Batch Job Definition', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::Batch::JobDefinition', { + Template.fromStack(stack).hasResourceProperties('AWS::Batch::JobDefinition', { ContainerProperties: { Image: { 'Fn::Join': [ @@ -182,7 +181,7 @@ describe('Batch Job Definition', () => { ReadonlyRootFilesystem: false, Vcpus: 1, }, - }, ResourcePart.Properties); + }); }); test('can use a registry image', () => { @@ -194,7 +193,7 @@ describe('Batch Job Definition', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::Batch::JobDefinition', { + Template.fromStack(stack).hasResourceProperties('AWS::Batch::JobDefinition', { ContainerProperties: { Image: 'docker/whalesay', Memory: 4, @@ -202,7 +201,7 @@ describe('Batch Job Definition', () => { ReadonlyRootFilesystem: false, Vcpus: 1, }, - }, ResourcePart.Properties); + }); }); test('can be imported from an ARN', () => { @@ -247,7 +246,7 @@ describe('Batch Job Definition', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::Batch::JobDefinition', { + Template.fromStack(stack).hasResourceProperties('AWS::Batch::JobDefinition', { ContainerProperties: { LogConfiguration: { LogDriver: 'awslogs', @@ -285,6 +284,6 @@ describe('Batch Job Definition', () => { ], }, }, - }, ResourcePart.Properties); + }); }); }); diff --git a/packages/@aws-cdk/aws-batch/test/job-queue.test.ts b/packages/@aws-cdk/aws-batch/test/job-queue.test.ts index 0bec27b20899a..94fe03c5e93f0 100644 --- a/packages/@aws-cdk/aws-batch/test/job-queue.test.ts +++ b/packages/@aws-cdk/aws-batch/test/job-queue.test.ts @@ -1,5 +1,4 @@ -import { ResourcePart } from '@aws-cdk/assert-internal'; -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as batch from '../lib'; @@ -48,7 +47,7 @@ describe('Batch Job Queue', () => { new batch.JobQueue(stack, 'test-job-queue', props); // THEN - expect(stack).toHaveResourceLike('AWS::Batch::JobQueue', { + Template.fromStack(stack).hasResourceProperties('AWS::Batch::JobQueue', { JobQueueName: props.jobQueueName, State: props.enabled ? 'ENABLED' : 'DISABLED', Priority: props.priority, @@ -60,7 +59,7 @@ describe('Batch Job Queue', () => { Order: 1, }, ], - }, ResourcePart.Properties); + }); }); it('should have a default queue priority of 1', () => { @@ -76,8 +75,8 @@ describe('Batch Job Queue', () => { }); // THEN - expect(stack).toHaveResourceLike('AWS::Batch::JobQueue', { + Template.fromStack(stack).hasResourceProperties('AWS::Batch::JobQueue', { Priority: 1, - }, ResourcePart.Properties); + }); }); }); diff --git a/packages/@aws-cdk/aws-budgets/package.json b/packages/@aws-cdk/aws-budgets/package.json index b3d03d5d5d194..37c92a04ef9cc 100644 --- a/packages/@aws-cdk/aws-budgets/package.json +++ b/packages/@aws-cdk/aws-budgets/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-budgets/test/budgets.test.ts b/packages/@aws-cdk/aws-budgets/test/budgets.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-budgets/test/budgets.test.ts +++ b/packages/@aws-cdk/aws-budgets/test/budgets.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-cassandra/package.json b/packages/@aws-cdk/aws-cassandra/package.json index 94d5a49670f90..1515c0f8cbebe 100644 --- a/packages/@aws-cdk/aws-cassandra/package.json +++ b/packages/@aws-cdk/aws-cassandra/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-cassandra/test/cassandra.test.ts b/packages/@aws-cdk/aws-cassandra/test/cassandra.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-cassandra/test/cassandra.test.ts +++ b/packages/@aws-cdk/aws-cassandra/test/cassandra.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-ce/package.json b/packages/@aws-cdk/aws-ce/package.json index 1e0345dc6fb9c..8148d2c5f2dd2 100644 --- a/packages/@aws-cdk/aws-ce/package.json +++ b/packages/@aws-cdk/aws-ce/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-ce/test/ce.test.ts b/packages/@aws-cdk/aws-ce/test/ce.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-ce/test/ce.test.ts +++ b/packages/@aws-cdk/aws-ce/test/ce.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-chatbot/lib/slack-channel-configuration.ts b/packages/@aws-cdk/aws-chatbot/lib/slack-channel-configuration.ts index 69646e783ebd7..690bb95c9bffd 100644 --- a/packages/@aws-cdk/aws-chatbot/lib/slack-channel-configuration.ts +++ b/packages/@aws-cdk/aws-chatbot/lib/slack-channel-configuration.ts @@ -204,9 +204,9 @@ export class SlackChannelConfiguration extends SlackChannelConfigurationBase { */ public static fromSlackChannelConfigurationArn(scope: Construct, id: string, slackChannelConfigurationArn: string): ISlackChannelConfiguration { const re = /^slack-channel\//; - const resourceName = cdk.Stack.of(scope).parseArn(slackChannelConfigurationArn).resourceName as string; + const resourceName = cdk.Arn.extractResourceName(slackChannelConfigurationArn, 'chat-configuration'); - if (!re.test(resourceName)) { + if (!cdk.Token.isUnresolved(slackChannelConfigurationArn) && !re.test(resourceName)) { throw new Error('The ARN of a Slack integration must be in the form: arn:aws:chatbot:{region}:{account}:chat-configuration/slack-channel/{slackChannelName}'); } @@ -227,11 +227,19 @@ export class SlackChannelConfiguration extends SlackChannelConfigurationBase { * The ArnComponents API will return `slack-channel/my-slack` * It need to handle that to gets a correct name.`my-slack` */ - readonly slackChannelConfigurationName = resourceName.substring('slack-channel/'.length); + readonly slackChannelConfigurationName: string; constructor(s: Construct, i: string) { super(s, i); this.grantPrincipal = new iam.UnknownPrincipal({ resource: this }); + + // handle slackChannelConfigurationName as specified above + if (cdk.Token.isUnresolved(slackChannelConfigurationArn)) { + this.slackChannelConfigurationName = cdk.Fn.select(1, cdk.Fn.split('slack-channel/', resourceName)); + } else { + this.slackChannelConfigurationName = resourceName.substring('slack-channel/'.length); + } + } } diff --git a/packages/@aws-cdk/aws-chatbot/test/slack-channel-configuration.test.ts b/packages/@aws-cdk/aws-chatbot/test/slack-channel-configuration.test.ts index 21d530bfd839a..63bf61b46d21c 100644 --- a/packages/@aws-cdk/aws-chatbot/test/slack-channel-configuration.test.ts +++ b/packages/@aws-cdk/aws-chatbot/test/slack-channel-configuration.test.ts @@ -245,4 +245,22 @@ describe('SlackChannelConfiguration', () => { expect(imported.slackChannelConfigurationName).toEqual('my-slack'); expect(imported.slackChannelConfigurationArn).toEqual('arn:aws:chatbot::1234567890:chat-configuration/slack-channel/my-slack'); }); + + test('skip validation for tokenized values', () => { + // invalid ARN because of underscores, no error because tokenized value + expect(() => chatbot.SlackChannelConfiguration.fromSlackChannelConfigurationArn(stack, 'MySlackChannel', + cdk.Lazy.string({ produce: () => 'arn:aws:chatbot::1234567890:chat-configuration/slack_channel/my_slack' }))).not.toThrow(); + }); + + test('test name and ARN from slack channel configuration ARN', () => { + const imported = chatbot.SlackChannelConfiguration.fromSlackChannelConfigurationArn(stack, 'MySlackChannel', cdk.Token.asString({ Ref: 'ARN' })); + + // THEN + expect(stack.resolve(imported.slackChannelConfigurationName)).toStrictEqual({ + 'Fn::Select': [1, { 'Fn::Split': ['slack-channel/', { 'Fn::Select': [1, { 'Fn::Split': [':chat-configuration/', { Ref: 'ARN' }] }] }] }], + }); + expect(stack.resolve(imported.slackChannelConfigurationArn)).toStrictEqual({ + Ref: 'ARN', + }); + }); }); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloud9/package.json b/packages/@aws-cdk/aws-cloud9/package.json index 8aac346d87398..452002a0e5dde 100644 --- a/packages/@aws-cdk/aws-cloud9/package.json +++ b/packages/@aws-cdk/aws-cloud9/package.json @@ -73,13 +73,13 @@ }, "license": "Apache-2.0", "devDependencies": { - "@types/jest": "^26.0.24", + "@aws-cdk/assertions": "0.0.0", "@aws-cdk/aws-codecommit": "0.0.0", + "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", - "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-cloud9/test/cloud9.environment.test.ts b/packages/@aws-cdk/aws-cloud9/test/cloud9.environment.test.ts index 231484ea26ffb..079fe546d0a4f 100644 --- a/packages/@aws-cdk/aws-cloud9/test/cloud9.environment.test.ts +++ b/packages/@aws-cdk/aws-cloud9/test/cloud9.environment.test.ts @@ -1,4 +1,4 @@ -import { expect as expectCDK, haveResource, haveResourceLike } from '@aws-cdk/assert-internal'; +import { Template } from '@aws-cdk/assertions'; import * as codecommit from '@aws-cdk/aws-codecommit'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as cdk from '@aws-cdk/core'; @@ -16,7 +16,7 @@ test('create resource correctly with only vpc provide', () => { // WHEN new cloud9.Ec2Environment(stack, 'C9Env', { vpc }); // THEN - expectCDK(stack).to(haveResource('AWS::Cloud9::EnvironmentEC2')); + Template.fromStack(stack).resourceCountIs('AWS::Cloud9::EnvironmentEC2', 1); }); test('create resource correctly with both vpc and subnetSelectio', () => { @@ -28,7 +28,7 @@ test('create resource correctly with both vpc and subnetSelectio', () => { }, }); // THEN - expectCDK(stack).to(haveResource('AWS::Cloud9::EnvironmentEC2')); + Template.fromStack(stack).resourceCountIs('AWS::Cloud9::EnvironmentEC2', 1); }); test('import correctly from existing environment', () => { @@ -45,7 +45,7 @@ test('create correctly with instanceType specified', () => { instanceType: ec2.InstanceType.of(ec2.InstanceClass.C5, ec2.InstanceSize.LARGE), }); // THEN - expectCDK(stack).to(haveResource('AWS::Cloud9::EnvironmentEC2')); + Template.fromStack(stack).resourceCountIs('AWS::Cloud9::EnvironmentEC2', 1); }); test('throw error when subnetSelection not specified and the provided VPC has no public subnets', () => { @@ -80,7 +80,7 @@ test('can use CodeCommit repositories', () => { ], }); // THEN - expectCDK(stack).to(haveResourceLike('AWS::Cloud9::EnvironmentEC2', { + Template.fromStack(stack).hasResourceProperties('AWS::Cloud9::EnvironmentEC2', { InstanceType: 't2.micro', Repositories: [ { @@ -103,5 +103,5 @@ test('can use CodeCommit repositories', () => { }, }, ], - })); + }); }); diff --git a/packages/@aws-cdk/aws-cloudfront/README.md b/packages/@aws-cdk/aws-cloudfront/README.md index 88fc86156a2e2..10c42d68efcfd 100644 --- a/packages/@aws-cdk/aws-cloudfront/README.md +++ b/packages/@aws-cdk/aws-cloudfront/README.md @@ -95,7 +95,7 @@ your domain name, and provide one (or more) domain names from the certificate fo The certificate must be present in the AWS Certificate Manager (ACM) service in the US East (N. Virginia) region; the certificate may either be created by ACM, or created elsewhere and imported into ACM. When a certificate is used, the distribution will support HTTPS connections -from SNI only and a minimum protocol version of TLSv1.2_2019. +from SNI only and a minimum protocol version of TLSv1.2_2021 if the '@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021' feature flag is set, and TLSv1.2_2019 otherwise. ```ts const myCertificate = new acm.DnsValidatedCertificate(this, 'mySiteCert', { @@ -590,6 +590,7 @@ new CloudFrontWebDistribution(stack, 'ADistribution', { originHeaders: { 'myHeader': '42', }, + originShieldRegion: 'us-west-2' }, failoverS3OriginSource: { s3BucketSource: s3.Bucket.fromBucketName(stack, 'aBucketFallback', 'myoriginbucketfallback'), @@ -597,6 +598,7 @@ new CloudFrontWebDistribution(stack, 'ADistribution', { originHeaders: { 'myHeader2': '21', }, + originShieldRegion: 'us-east-1' }, failoverCriteriaStatusCodes: [FailoverStatusCode.INTERNAL_SERVER_ERROR], behaviors: [ diff --git a/packages/@aws-cdk/aws-cloudfront/lib/distribution.ts b/packages/@aws-cdk/aws-cloudfront/lib/distribution.ts index fb1bca2c0b278..b8926bad4c88f 100644 --- a/packages/@aws-cdk/aws-cloudfront/lib/distribution.ts +++ b/packages/@aws-cdk/aws-cloudfront/lib/distribution.ts @@ -1,7 +1,8 @@ import * as acm from '@aws-cdk/aws-certificatemanager'; import * as lambda from '@aws-cdk/aws-lambda'; import * as s3 from '@aws-cdk/aws-s3'; -import { IResource, Lazy, Resource, Stack, Token, Duration, Names } from '@aws-cdk/core'; +import { IResource, Lazy, Resource, Stack, Token, Duration, Names, FeatureFlags } from '@aws-cdk/core'; +import { CLOUDFRONT_DEFAULT_SECURITY_POLICY_TLS_V1_2_2021 } from '@aws-cdk/cx-api'; import { Construct } from 'constructs'; import { ICachePolicy } from './cache-policy'; import { CfnDistribution } from './cloudfront.generated'; @@ -215,7 +216,7 @@ export interface DistributionProps { * CloudFront serves your objects only to browsers or devices that support at * least the SSL version that you specify. * - * @default SecurityPolicyProtocol.TLS_V1_2_2019 + * @default - SecurityPolicyProtocol.TLS_V1_2_2021 if the '@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021' feature flag is set; otherwise, SecurityPolicyProtocol.TLS_V1_2_2019. */ readonly minimumProtocolVersion?: SecurityPolicyProtocol; } @@ -446,7 +447,12 @@ export class Distribution extends Resource implements IDistribution { } private renderViewerCertificate(certificate: acm.ICertificate, - minimumProtocolVersion: SecurityPolicyProtocol = SecurityPolicyProtocol.TLS_V1_2_2019): CfnDistribution.ViewerCertificateProperty { + minimumProtocolVersionProp?: SecurityPolicyProtocol): CfnDistribution.ViewerCertificateProperty { + + const defaultVersion = FeatureFlags.of(this).isEnabled(CLOUDFRONT_DEFAULT_SECURITY_POLICY_TLS_V1_2_2021) + ? SecurityPolicyProtocol.TLS_V1_2_2021 : SecurityPolicyProtocol.TLS_V1_2_2019; + const minimumProtocolVersion = minimumProtocolVersionProp ?? defaultVersion; + return { acmCertificateArn: certificate.certificateArn, sslSupportMethod: SSLMethod.SNI, @@ -531,7 +537,8 @@ export enum SecurityPolicyProtocol { TLS_V1_2016 = 'TLSv1_2016', TLS_V1_1_2016 = 'TLSv1.1_2016', TLS_V1_2_2018 = 'TLSv1.2_2018', - TLS_V1_2_2019 = 'TLSv1.2_2019' + TLS_V1_2_2019 = 'TLSv1.2_2019', + TLS_V1_2_2021 = 'TLSv1.2_2021' } /** diff --git a/packages/@aws-cdk/aws-cloudfront/lib/origin.ts b/packages/@aws-cdk/aws-cloudfront/lib/origin.ts index 6f5a42e407e01..9b841e413c405 100644 --- a/packages/@aws-cdk/aws-cloudfront/lib/origin.ts +++ b/packages/@aws-cdk/aws-cloudfront/lib/origin.ts @@ -83,6 +83,15 @@ export interface OriginProps { * @default {} */ readonly customHeaders?: Record; + + /** + * When you enable Origin Shield in the AWS Region that has the lowest latency to your origin, you can get better network performance + * + * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/origin-shield.html + * + * @default - origin shield not enabled + */ + readonly originShieldRegion?: string; } /** @@ -106,6 +115,7 @@ export abstract class OriginBase implements IOrigin { private readonly connectionTimeout?: Duration; private readonly connectionAttempts?: number; private readonly customHeaders?: Record; + private readonly originShieldRegion?: string protected constructor(domainName: string, props: OriginProps = {}) { validateIntInRangeOrUndefined('connectionTimeout', 1, 10, props.connectionTimeout?.toSeconds()); @@ -116,6 +126,7 @@ export abstract class OriginBase implements IOrigin { this.connectionTimeout = props.connectionTimeout; this.connectionAttempts = props.connectionAttempts; this.customHeaders = props.customHeaders; + this.originShieldRegion = props.originShieldRegion; } /** @@ -139,6 +150,7 @@ export abstract class OriginBase implements IOrigin { originCustomHeaders: this.renderCustomHeaders(), s3OriginConfig, customOriginConfig, + originShield: this.renderOriginShield(this.originShieldRegion), }, }; } @@ -172,6 +184,15 @@ export abstract class OriginBase implements IOrigin { if (path.endsWith('/')) { path = path.substr(0, path.length - 1); } return path; } + + /** + * Takes origin shield region and converts to CfnDistribution.OriginShieldProperty + */ + private renderOriginShield(originShieldRegion?: string): CfnDistribution.OriginShieldProperty | undefined { + return originShieldRegion + ? { enabled: true, originShieldRegion } + : undefined; + } } /** diff --git a/packages/@aws-cdk/aws-cloudfront/lib/web-distribution.ts b/packages/@aws-cdk/aws-cloudfront/lib/web-distribution.ts index db8db2b2bdeb4..29a63fd681bb3 100644 --- a/packages/@aws-cdk/aws-cloudfront/lib/web-distribution.ts +++ b/packages/@aws-cdk/aws-cloudfront/lib/web-distribution.ts @@ -123,6 +123,7 @@ interface SourceConfigurationRender { readonly customOriginSource?: CustomOriginConfig; readonly originPath?: string; readonly originHeaders?: { [key: string]: string }; + readonly originShieldRegion?: string } /** @@ -202,6 +203,15 @@ export interface SourceConfiguration { * @deprecated Use originHeaders on s3OriginSource or customOriginSource */ readonly originHeaders?: { [key: string]: string }; + + /** + * When you enable Origin Shield in the AWS Region that has the lowest latency to your origin, you can get better network performance + * + * @see https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/origin-shield.html + * + * @default - origin shield not enabled + */ + readonly originShieldRegion?: string; } /** @@ -268,6 +278,13 @@ export interface CustomOriginConfig { * @default - No additional headers are passed. */ readonly originHeaders?: { [key: string]: string }; + + /** + * When you enable Origin Shield in the AWS Region that has the lowest latency to your origin, you can get better network performance + * + * @default - origin shield not enabled + */ + readonly originShieldRegion?: string; } export enum OriginSslPolicy { @@ -306,6 +323,13 @@ export interface S3OriginConfig { * @default - No additional headers are passed. */ readonly originHeaders?: { [key: string]: string }; + + /** + * When you enable Origin Shield in the AWS Region that has the lowest latency to your origin, you can get better network performance + * + * @default - origin shield not enabled + */ + readonly originShieldRegion?: string; } /** @@ -557,6 +581,13 @@ export interface CloudFrontWebDistributionProps { */ readonly comment?: string; + /** + * Enable or disable the distribution. + * + * @default true + */ + readonly enabled?: boolean; + /** * The default object to serve. * @@ -769,7 +800,7 @@ export class CloudFrontWebDistribution extends cdk.Resource implements IDistribu [SSLMethod.SNI]: [ SecurityPolicyProtocol.TLS_V1, SecurityPolicyProtocol.TLS_V1_1_2016, SecurityPolicyProtocol.TLS_V1_2016, SecurityPolicyProtocol.TLS_V1_2_2018, - SecurityPolicyProtocol.TLS_V1_2_2019, + SecurityPolicyProtocol.TLS_V1_2_2019, SecurityPolicyProtocol.TLS_V1_2_2021, ], [SSLMethod.VIP]: [SecurityPolicyProtocol.SSL_V3, SecurityPolicyProtocol.TLS_V1], }; @@ -785,7 +816,7 @@ export class CloudFrontWebDistribution extends cdk.Resource implements IDistribu let distributionConfig: CfnDistribution.DistributionConfigProperty = { comment: trimmedComment, - enabled: true, + enabled: props.enabled ?? true, defaultRootObject: props.defaultRootObject ?? 'index.html', httpVersion: props.httpVersion || HttpVersion.HTTP2, priceClass: props.priceClass || PriceClass.PRICE_CLASS_100, @@ -814,6 +845,7 @@ export class CloudFrontWebDistribution extends cdk.Resource implements IDistribu customOriginSource: originConfig.failoverCustomOriginSource, originPath: originConfig.originPath, originHeaders: originConfig.originHeaders, + originShieldRegion: originConfig.originShieldRegion, }, originSecondaryId, ); @@ -1032,6 +1064,14 @@ export class CloudFrontWebDistribution extends cdk.Resource implements IDistribu throw new Error('Only one originPath field allowed across origin and failover origins'); } + if ([ + originConfig.originShieldRegion, + originConfig.s3OriginSource?.originShieldRegion, + originConfig.customOriginSource?.originShieldRegion, + ].filter(x => x).length > 1) { + throw new Error('Only one originShieldRegion field allowed across origin and failover origins'); + } + const headers = originConfig.originHeaders ?? originConfig.s3OriginSource?.originHeaders ?? originConfig.customOriginSource?.originHeaders; const originHeaders: CfnDistribution.OriginCustomHeaderProperty[] = []; @@ -1087,6 +1127,7 @@ export class CloudFrontWebDistribution extends cdk.Resource implements IDistribu originCustomHeaders: originHeaders.length > 0 ? originHeaders : undefined, s3OriginConfig, + originShield: this.toOriginShieldProperty(originConfig), customOriginConfig: originConfig.customOriginSource ? { httpPort: originConfig.customOriginSource.httpPort || 80, @@ -1112,4 +1153,16 @@ export class CloudFrontWebDistribution extends cdk.Resource implements IDistribu return originProperty; } + + /** + * Takes origin shield region from props and converts to CfnDistribution.OriginShieldProperty + */ + private toOriginShieldProperty(originConfig:SourceConfigurationRender): CfnDistribution.OriginShieldProperty | undefined { + const originShieldRegion = originConfig.originShieldRegion ?? + originConfig.customOriginSource?.originShieldRegion ?? + originConfig.s3OriginSource?.originShieldRegion; + return originShieldRegion + ? { enabled: true, originShieldRegion } + : undefined; + } } diff --git a/packages/@aws-cdk/aws-cloudfront/package.json b/packages/@aws-cdk/aws-cloudfront/package.json index cd8e8f17f9b5d..58a6b35ef281f 100644 --- a/packages/@aws-cdk/aws-cloudfront/package.json +++ b/packages/@aws-cdk/aws-cloudfront/package.json @@ -85,6 +85,7 @@ "dependencies": { "@aws-cdk/aws-certificatemanager": "0.0.0", "@aws-cdk/aws-cloudwatch": "0.0.0", + "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kms": "0.0.0", @@ -98,6 +99,7 @@ "peerDependencies": { "@aws-cdk/aws-certificatemanager": "0.0.0", "@aws-cdk/aws-cloudwatch": "0.0.0", + "@aws-cdk/cx-api": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kms": "0.0.0", @@ -147,6 +149,7 @@ "docs-public-apis:@aws-cdk/aws-cloudfront.SecurityPolicyProtocol.TLS_V1_1_2016", "docs-public-apis:@aws-cdk/aws-cloudfront.SecurityPolicyProtocol.TLS_V1_2_2018", "docs-public-apis:@aws-cdk/aws-cloudfront.SecurityPolicyProtocol.TLS_V1_2_2019", + "docs-public-apis:@aws-cdk/aws-cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021", "docs-public-apis:@aws-cdk/aws-cloudfront.ViewerCertificate.aliases", "docs-public-apis:@aws-cdk/aws-cloudfront.ViewerCertificate.props", "docs-public-apis:@aws-cdk/aws-cloudfront.ViewerCertificateOptions", diff --git a/packages/@aws-cdk/aws-cloudfront/test/distribution.test.ts b/packages/@aws-cdk/aws-cloudfront/test/distribution.test.ts index 52bd0a81c2c8a..930557098851c 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/distribution.test.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/distribution.test.ts @@ -4,7 +4,21 @@ import * as acm from '@aws-cdk/aws-certificatemanager'; import * as lambda from '@aws-cdk/aws-lambda'; import * as s3 from '@aws-cdk/aws-s3'; import { App, Duration, Stack } from '@aws-cdk/core'; -import { CfnDistribution, Distribution, Function, FunctionCode, FunctionEventType, GeoRestriction, HttpVersion, IOrigin, LambdaEdgeEventType, PriceClass, SecurityPolicyProtocol } from '../lib'; +import { CLOUDFRONT_DEFAULT_SECURITY_POLICY_TLS_V1_2_2021 } from '@aws-cdk/cx-api'; +import { testFutureBehavior, testLegacyBehavior } from 'cdk-build-tools/lib/feature-flag'; +import { + CfnDistribution, + Distribution, + Function, + FunctionCode, + FunctionEventType, + GeoRestriction, + HttpVersion, + IOrigin, + LambdaEdgeEventType, + PriceClass, + SecurityPolicyProtocol, +} from '../lib'; import { defaultOrigin, defaultOriginGroup } from './test-origin'; let app: App; @@ -60,6 +74,7 @@ test('exhaustive example of props renders correctly', () => { httpVersion: HttpVersion.HTTP1_1, logFilePrefix: 'logs/', logIncludesCookies: true, + minimumProtocolVersion: SecurityPolicyProtocol.TLS_V1_2_2019, priceClass: PriceClass.PRICE_CLASS_100, webAclId: '473e64fd-f30b-4765-81a0-62ad96dd167a', }); @@ -328,25 +343,61 @@ describe('certificates', () => { }).toThrow(/Must specify at least one domain name/); }); - test('adding a certificate and domain renders the correct ViewerCertificate and Aliases property', () => { - const certificate = acm.Certificate.fromCertificateArn(stack, 'Cert', 'arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012'); - - new Distribution(stack, 'Dist', { - defaultBehavior: { origin: defaultOrigin() }, - domainNames: ['example.com', 'www.example.com'], - certificate, - }); - - expect(stack).toHaveResourceLike('AWS::CloudFront::Distribution', { - DistributionConfig: { - Aliases: ['example.com', 'www.example.com'], - ViewerCertificate: { - AcmCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012', - SslSupportMethod: 'sni-only', - MinimumProtocolVersion: 'TLSv1.2_2019', - }, + describe('adding a certificate and domain renders the correct ViewerCertificate and Aliases property', () => { + testFutureBehavior( + 'when @aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021 is enabled, use the TLSv1.2_2021 security policy by default', + { [CLOUDFRONT_DEFAULT_SECURITY_POLICY_TLS_V1_2_2021]: true }, + App, + (customApp) => { + const customStack = new Stack(customApp); + + const certificate = acm.Certificate.fromCertificateArn(customStack, 'Cert', 'arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012'); + + new Distribution(customStack, 'Dist', { + defaultBehavior: { origin: defaultOrigin() }, + domainNames: ['example.com', 'www.example.com'], + certificate, + }); + + expect(customStack).toHaveResourceLike('AWS::CloudFront::Distribution', { + DistributionConfig: { + Aliases: ['example.com', 'www.example.com'], + ViewerCertificate: { + AcmCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012', + SslSupportMethod: 'sni-only', + MinimumProtocolVersion: 'TLSv1.2_2021', + }, + }, + }); + }, + ); + + testLegacyBehavior( + 'when @aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021 is disabled, use the TLSv1.2_2019 security policy by default', + App, + (customApp) => { + const customStack = new Stack(customApp); + + const certificate = acm.Certificate.fromCertificateArn(customStack, 'Cert', 'arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012'); + + new Distribution(customStack, 'Dist', { + defaultBehavior: { origin: defaultOrigin() }, + domainNames: ['example.com', 'www.example.com'], + certificate, + }); + + expect(customStack).toHaveResourceLike('AWS::CloudFront::Distribution', { + DistributionConfig: { + Aliases: ['example.com', 'www.example.com'], + ViewerCertificate: { + AcmCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012', + SslSupportMethod: 'sni-only', + MinimumProtocolVersion: 'TLSv1.2_2019', + }, + }, + }); }, - }); + ); }); test('adding a certificate with non default security policy protocol', () => { diff --git a/packages/@aws-cdk/aws-cloudfront/test/integ.distribution-extensive.expected.json b/packages/@aws-cdk/aws-cloudfront/test/integ.distribution-extensive.expected.json index 56829919d2306..4ddd5ddb8d373 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/integ.distribution-extensive.expected.json +++ b/packages/@aws-cdk/aws-cloudfront/test/integ.distribution-extensive.expected.json @@ -36,7 +36,11 @@ "OriginProtocolPolicy": "https-only" }, "DomainName": "www.example.com", - "Id": "integdistributionextensiveMyDistOrigin185F089B3" + "Id": "integdistributionextensiveMyDistOrigin185F089B3", + "OriginShield": { + "Enabled": true, + "OriginShieldRegion": "us-west-2" + } } ], "PriceClass": "PriceClass_100", diff --git a/packages/@aws-cdk/aws-cloudfront/test/integ.distribution-extensive.ts b/packages/@aws-cdk/aws-cloudfront/test/integ.distribution-extensive.ts index 6a8f949ca9b43..fa55fe571326d 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/integ.distribution-extensive.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/integ.distribution-extensive.ts @@ -6,7 +6,11 @@ const app = new cdk.App(); const stack = new cdk.Stack(app, 'integ-distribution-extensive'); new cloudfront.Distribution(stack, 'MyDist', { - defaultBehavior: { origin: new TestOrigin('www.example.com') }, + defaultBehavior: { + origin: new TestOrigin('www.example.com', { + originShieldRegion: 'us-west-2', + }), + }, comment: 'a test', defaultRootObject: 'index.html', enabled: true, diff --git a/packages/@aws-cdk/aws-cloudfront/test/origin.test.ts b/packages/@aws-cdk/aws-cloudfront/test/origin.test.ts index b2a60a2fd109d..b30362c7fe652 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/origin.test.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/origin.test.ts @@ -44,3 +44,17 @@ test.each(['api', '/api', '/api/', 'api/']) expect(originBindConfig.originProperty?.originPath).toEqual('/api'); }); + + +test.each(['us-east-1', 'ap-southeast-2', 'eu-west-3', 'me-south-1']) +('ensures that originShieldRegion is a valid aws region', (originShieldRegion) => { + const origin = new TestOrigin('www.example.com', { + originShieldRegion, + }); + const originBindConfig = origin.bind(stack, { originId: '0' }); + + expect(originBindConfig.originProperty?.originShield).toEqual({ + enabled: true, + originShieldRegion, + }); +}); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-cloudfront/test/web-distribution.test.ts b/packages/@aws-cdk/aws-cloudfront/test/web-distribution.test.ts index 517aa18b3364c..6d799b2f89cf9 100644 --- a/packages/@aws-cdk/aws-cloudfront/test/web-distribution.test.ts +++ b/packages/@aws-cdk/aws-cloudfront/test/web-distribution.test.ts @@ -47,6 +47,7 @@ nodeunitShim({ customOriginSource: { domainName: 'myorigin.com', }, + originShieldRegion: 'us-east-1', behaviors: [ { isDefaultBehavior: true, @@ -108,6 +109,10 @@ nodeunitShim({ 'HeaderValue': 'somevalue', }, ], + 'OriginShield': { + 'Enabled': true, + 'OriginShieldRegion': 'us-east-1', + }, }, ], 'PriceClass': 'PriceClass_100', @@ -201,6 +206,84 @@ nodeunitShim({ test.done(); }, + 'can disable distribution'(test: Test) { + const stack = new cdk.Stack(); + const sourceBucket = new s3.Bucket(stack, 'Bucket'); + + new CloudFrontWebDistribution(stack, 'AnAmazingWebsiteProbably', { + enabled: false, + originConfigs: [ + { + s3OriginSource: { + s3BucketSource: sourceBucket, + }, + behaviors: [ + { + isDefaultBehavior: true, + }, + ], + }, + ], + }); + + expect(stack).toMatch({ + 'Resources': { + 'Bucket83908E77': { + 'Type': 'AWS::S3::Bucket', + 'DeletionPolicy': 'Retain', + 'UpdateReplacePolicy': 'Retain', + }, + 'AnAmazingWebsiteProbablyCFDistribution47E3983B': { + 'Type': 'AWS::CloudFront::Distribution', + 'Properties': { + 'DistributionConfig': { + 'DefaultRootObject': 'index.html', + 'Origins': [ + { + 'ConnectionAttempts': 3, + 'ConnectionTimeout': 10, + 'DomainName': { + 'Fn::GetAtt': [ + 'Bucket83908E77', + 'RegionalDomainName', + ], + }, + 'Id': 'origin1', + 'S3OriginConfig': {}, + }, + ], + 'ViewerCertificate': { + 'CloudFrontDefaultCertificate': true, + }, + 'PriceClass': 'PriceClass_100', + 'DefaultCacheBehavior': { + 'AllowedMethods': [ + 'GET', + 'HEAD', + ], + 'CachedMethods': [ + 'GET', + 'HEAD', + ], + 'TargetOriginId': 'origin1', + 'ViewerProtocolPolicy': 'redirect-to-https', + 'ForwardedValues': { + 'QueryString': false, + 'Cookies': { 'Forward': 'none' }, + }, + 'Compress': true, + }, + 'Enabled': false, + 'IPV6Enabled': true, + 'HttpVersion': 'http2', + }, + }, + }, + }, + }); + test.done(); + }, + 'ensure long comments will not break the distribution'(test: Test) { const stack = new cdk.Stack(); const sourceBucket = new s3.Bucket(stack, 'Bucket'); diff --git a/packages/@aws-cdk/aws-cloudwatch/test/alarm.test.ts b/packages/@aws-cdk/aws-cloudwatch/test/alarm.test.ts index 437dbc5df4ab8..c2381d2891a86 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/alarm.test.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/alarm.test.ts @@ -1,4 +1,4 @@ -import { Match, TemplateAssertions } from '@aws-cdk/assertions'; +import { Match, Template } from '@aws-cdk/assertions'; import { Duration, Stack } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { Alarm, IAlarm, IAlarmAction, Metric, MathExpression, IMetric } from '../lib'; @@ -67,7 +67,7 @@ describe('Alarm', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { ComparisonOperator: 'GreaterThanOrEqualToThreshold', EvaluationPeriods: 3, MetricName: 'Metric', @@ -93,7 +93,7 @@ describe('Alarm', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { ComparisonOperator: 'GreaterThanOrEqualToThreshold', EvaluationPeriods: 3, MetricName: 'Metric', @@ -119,7 +119,7 @@ describe('Alarm', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { ComparisonOperator: 'GreaterThanOrEqualToThreshold', EvaluationPeriods: 3, MetricName: 'Metric', @@ -146,7 +146,7 @@ describe('Alarm', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { ComparisonOperator: 'GreaterThanOrEqualToThreshold', EvaluationPeriods: 3, MetricName: 'Metric', @@ -173,7 +173,7 @@ describe('Alarm', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { ComparisonOperator: 'GreaterThanOrEqualToThreshold', EvaluationPeriods: 3, DatapointsToAlarm: 2, @@ -203,7 +203,7 @@ describe('Alarm', () => { alarm.addOkAction(new TestAlarmAction('C')); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { AlarmActions: ['A'], InsufficientDataActions: ['B'], OKActions: ['C'], @@ -225,7 +225,7 @@ describe('Alarm', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { ComparisonOperator: 'GreaterThanOrEqualToThreshold', EvaluationPeriods: 2, MetricName: 'Metric', @@ -250,7 +250,7 @@ describe('Alarm', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { ExtendedStatistic: 'p99.9', }); @@ -269,7 +269,7 @@ describe('Alarm', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { Statistic: Match.absentProperty(), ExtendedStatistic: 'tm99.9999999999', }); diff --git a/packages/@aws-cdk/aws-cloudwatch/test/composite-alarm.test.ts b/packages/@aws-cdk/aws-cloudwatch/test/composite-alarm.test.ts index e77d33a546ca5..0633f455eadbf 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/composite-alarm.test.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/composite-alarm.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import { Stack } from '@aws-cdk/core'; import { Alarm, AlarmRule, AlarmState, CompositeAlarm, Metric } from '../lib'; @@ -59,7 +59,7 @@ describe('CompositeAlarm', () => { alarmRule, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::CompositeAlarm', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::CompositeAlarm', { AlarmName: 'CompositeAlarm', AlarmRule: { 'Fn::Join': [ diff --git a/packages/@aws-cdk/aws-cloudwatch/test/cross-environment.test.ts b/packages/@aws-cdk/aws-cloudwatch/test/cross-environment.test.ts index fc00cda0753d1..7c7ed7d04bf6f 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/cross-environment.test.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/cross-environment.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import { Stack } from '@aws-cdk/core'; import { Alarm, GraphWidget, IWidget, Metric } from '../lib'; @@ -89,7 +89,7 @@ describe('cross environment', () => { }); // THEN - TemplateAssertions.fromStack(stack1).hasResourceProperties('AWS::CloudWatch::Alarm', { + Template.fromStack(stack1).hasResourceProperties('AWS::CloudWatch::Alarm', { MetricName: 'ACount', Namespace: 'Test', Period: 300, @@ -128,4 +128,4 @@ function graphMetricsAre(stack: Stack, w: IWidget, metrics: any[]) { yAxis: {}, }, }]); -} \ No newline at end of file +} diff --git a/packages/@aws-cdk/aws-cloudwatch/test/dashboard.test.ts b/packages/@aws-cdk/aws-cloudwatch/test/dashboard.test.ts index cf3c4caa96042..6e796aa6b833b 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/dashboard.test.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/dashboard.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import { App, Stack } from '@aws-cdk/core'; import { Dashboard, GraphWidget, PeriodOverride, TextWidget } from '../lib'; @@ -26,7 +26,7 @@ describe('Dashboard', () => { })); // THEN - const resources = TemplateAssertions.fromStack(stack).findResources('AWS::CloudWatch::Dashboard'); + const resources = Template.fromStack(stack).findResources('AWS::CloudWatch::Dashboard'); expect(resources.length).toEqual(1); hasWidgets(resources[0].Properties, [ { type: 'text', width: 10, height: 2, x: 0, y: 0, properties: { markdown: 'first' } }, @@ -62,7 +62,7 @@ describe('Dashboard', () => { ); // THEN - const resources = TemplateAssertions.fromStack(stack).findResources('AWS::CloudWatch::Dashboard'); + const resources = Template.fromStack(stack).findResources('AWS::CloudWatch::Dashboard'); expect(resources.length).toEqual(1); hasWidgets(resources[0].Properties, [ { type: 'text', width: 10, height: 2, x: 0, y: 0, properties: { markdown: 'first' } }, @@ -84,7 +84,7 @@ describe('Dashboard', () => { ); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Dashboard', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Dashboard', { DashboardBody: { 'Fn::Join': ['', [ '{"widgets":[{"type":"metric","width":1,"height":1,"x":0,"y":0,"properties":{"view":"timeSeries","region":"', @@ -113,7 +113,7 @@ describe('Dashboard', () => { ); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Dashboard', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Dashboard', { DashboardBody: { 'Fn::Join': ['', [ '{"start":"-9H","end":"2018-12-17T06:00:00.000Z","periodOverride":"inherit",\ @@ -138,7 +138,7 @@ describe('Dashboard', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Dashboard', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Dashboard', { DashboardName: 'MyCustomDashboardName', }); @@ -154,7 +154,7 @@ describe('Dashboard', () => { new Dashboard(stack, 'MyDashboard'); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Dashboard', {}); + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Dashboard', {}); }); diff --git a/packages/@aws-cdk/aws-cloudwatch/test/metric-math.test.ts b/packages/@aws-cdk/aws-cloudwatch/test/metric-math.test.ts index 52e7803575d05..5f244f3b11352 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/metric-math.test.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/metric-math.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import { Duration, Stack } from '@aws-cdk/core'; import { Alarm, GraphWidget, IWidget, MathExpression, Metric } from '../lib'; @@ -638,7 +638,7 @@ function graphMetricsAre(w: IWidget, metrics: any[]) { } function alarmMetricsAre(metrics: any[]) { - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { Metrics: metrics, }); } diff --git a/packages/@aws-cdk/aws-cloudwatch/test/metrics.test.ts b/packages/@aws-cdk/aws-cloudwatch/test/metrics.test.ts index f7b5c69f8018b..d13d3a8c4e0c6 100644 --- a/packages/@aws-cdk/aws-cloudwatch/test/metrics.test.ts +++ b/packages/@aws-cdk/aws-cloudwatch/test/metrics.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; import * as cdk from '@aws-cdk/core'; import { Alarm, Metric } from '../lib'; @@ -15,7 +15,7 @@ describe('Metrics', () => { Metric.grantPutMetricData(role); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Version: '2012-10-17', Statement: [ @@ -188,7 +188,7 @@ describe('Metrics', () => { dimensionA: 'value1', dimensionB: 'value2', }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { Namespace: 'Test', MetricName: 'Metric', Dimensions: [ diff --git a/packages/@aws-cdk/aws-codeartifact/package.json b/packages/@aws-cdk/aws-codeartifact/package.json index b1d8e76ef79d4..3dc1f03908775 100644 --- a/packages/@aws-cdk/aws-codeartifact/package.json +++ b/packages/@aws-cdk/aws-codeartifact/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-codeartifact/test/codeartifact.test.ts b/packages/@aws-cdk/aws-codeartifact/test/codeartifact.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-codeartifact/test/codeartifact.test.ts +++ b/packages/@aws-cdk/aws-codeartifact/test/codeartifact.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-codegurureviewer/package.json b/packages/@aws-cdk/aws-codegurureviewer/package.json index f7a900d2aef8b..c0619789ea414 100644 --- a/packages/@aws-cdk/aws-codegurureviewer/package.json +++ b/packages/@aws-cdk/aws-codegurureviewer/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-codegurureviewer/test/codegurureviewer.test.ts b/packages/@aws-cdk/aws-codegurureviewer/test/codegurureviewer.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-codegurureviewer/test/codegurureviewer.test.ts +++ b/packages/@aws-cdk/aws-codegurureviewer/test/codegurureviewer.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-codestar/package.json b/packages/@aws-cdk/aws-codestar/package.json index 8b943f821668d..7740100ab9d29 100644 --- a/packages/@aws-cdk/aws-codestar/package.json +++ b/packages/@aws-cdk/aws-codestar/package.json @@ -75,12 +75,12 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", - "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/aws-s3": "0.0.0", diff --git a/packages/@aws-cdk/aws-codestar/test/codestar.test.ts b/packages/@aws-cdk/aws-codestar/test/codestar.test.ts index 7b142a03ac221..c1af7348d849c 100644 --- a/packages/@aws-cdk/aws-codestar/test/codestar.test.ts +++ b/packages/@aws-cdk/aws-codestar/test/codestar.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { Bucket } from '@aws-cdk/aws-s3'; import * as cdk from '@aws-cdk/core'; import { GitHubRepository, RepositoryVisibility } from '../lib'; @@ -22,7 +22,7 @@ describe('GitHub Repository', () => { contentsKey: 'import.zip', }); - expect(stack).toHaveResource('AWS::CodeStar::GitHubRepository', { + Template.fromStack(stack).hasResourceProperties('AWS::CodeStar::GitHubRepository', { RepositoryAccessToken: '{{resolve:secretsmanager:my-github-token:SecretString:token::}}', RepositoryName: 'bar', RepositoryOwner: 'foo', @@ -48,7 +48,7 @@ describe('GitHub Repository', () => { visibility: RepositoryVisibility.PRIVATE, }); - expect(stack).toHaveResourceLike('AWS::CodeStar::GitHubRepository', { + Template.fromStack(stack).hasResourceProperties('AWS::CodeStar::GitHubRepository', { EnableIssues: true, IsPrivate: true, }); diff --git a/packages/@aws-cdk/aws-codestarconnections/package.json b/packages/@aws-cdk/aws-codestarconnections/package.json index d45abecfe6ccd..76e45df893762 100644 --- a/packages/@aws-cdk/aws-codestarconnections/package.json +++ b/packages/@aws-cdk/aws-codestarconnections/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-codestarconnections/test/codestarconnections.test.ts b/packages/@aws-cdk/aws-codestarconnections/test/codestarconnections.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-codestarconnections/test/codestarconnections.test.ts +++ b/packages/@aws-cdk/aws-codestarconnections/test/codestarconnections.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool-client.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool-client.test.ts index a94eef4061bdc..dc8dde7779bbc 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool-client.test.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool-client.test.ts @@ -1,4 +1,4 @@ -import { Match, TemplateAssertions } from '@aws-cdk/assertions'; +import { Match, Template } from '@aws-cdk/assertions'; import { Stack, Duration } from '@aws-cdk/core'; import { OAuthScope, ResourceServerScope, UserPool, UserPoolClient, UserPoolClientIdentityProvider, UserPoolIdentityProvider, ClientAttributes } from '../lib'; @@ -14,7 +14,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { UserPoolId: stack.resolve(pool.userPoolId), AllowedOAuthFlows: ['implicit', 'code'], AllowedOAuthScopes: ['profile', 'phone', 'email', 'openid', 'aws.cognito.signin.user.admin'], @@ -62,7 +62,7 @@ describe('User Pool Client', () => { pool.addClient('Client'); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ExplicitAuthFlows: Match.absentProperty(), }); }); @@ -82,7 +82,7 @@ describe('User Pool Client', () => { }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ExplicitAuthFlows: [ 'ALLOW_USER_PASSWORD_AUTH', 'ALLOW_ADMIN_USER_PASSWORD_AUTH', @@ -105,7 +105,7 @@ describe('User Pool Client', () => { }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ExplicitAuthFlows: [ 'ALLOW_USER_SRP_AUTH', 'ALLOW_REFRESH_TOKEN_AUTH', @@ -138,12 +138,12 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { AllowedOAuthFlows: ['implicit', 'code'], AllowedOAuthFlowsUserPoolClient: true, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { AllowedOAuthFlows: ['client_credentials'], AllowedOAuthFlowsUserPoolClient: true, }); @@ -177,17 +177,17 @@ describe('User Pool Client', () => { }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { AllowedOAuthFlows: ['client_credentials'], CallbackURLs: Match.absentProperty(), }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { AllowedOAuthFlows: ['implicit'], CallbackURLs: ['https://example.com'], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { AllowedOAuthFlows: ['code'], CallbackURLs: ['https://example.com'], }); @@ -205,7 +205,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { CallbackURLs: Match.absentProperty(), }); }); @@ -246,7 +246,7 @@ describe('User Pool Client', () => { }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { LogoutURLs: ['https://example.com'], }); }); @@ -297,7 +297,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { AllowedOAuthScopes: [ 'phone', 'email', @@ -330,7 +330,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { AllowedOAuthScopes: [ { 'Fn::Join': [ @@ -380,19 +380,19 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'Client1', AllowedOAuthScopes: ['phone', 'openid'], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'Client2', AllowedOAuthScopes: ['email', 'openid'], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'Client3', AllowedOAuthScopes: ['profile', 'openid'], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'Client4', AllowedOAuthScopes: ['aws.cognito.signin.user.admin'], }); @@ -410,7 +410,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { UserPoolId: stack.resolve(pool.userPoolId), PreventUserExistenceErrors: 'ENABLED', }); @@ -428,7 +428,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { UserPoolId: stack.resolve(pool.userPoolId), PreventUserExistenceErrors: 'LEGACY', }); @@ -445,7 +445,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { UserPoolId: stack.resolve(pool.userPoolId), PreventUserExistenceErrors: Match.absentProperty(), }); @@ -465,7 +465,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { SupportedIdentityProviders: [ 'userpool-idp', 'COGNITO', @@ -491,7 +491,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'AllEnabled', SupportedIdentityProviders: ['COGNITO', 'Facebook', 'LoginWithAmazon', 'Google', 'SignInWithApple'], }); @@ -513,13 +513,13 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'OAuthDisabled', AllowedOAuthFlows: Match.absentProperty(), AllowedOAuthScopes: Match.absentProperty(), AllowedOAuthFlowsUserPoolClient: false, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'OAuthEnabled', AllowedOAuthFlows: ['implicit', 'code'], AllowedOAuthScopes: ['profile', 'phone', 'email', 'openid', 'aws.cognito.signin.user.admin'], @@ -571,7 +571,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'Client1', AccessTokenValidity: 60, IdTokenValidity: 60, @@ -582,7 +582,7 @@ describe('User Pool Client', () => { RefreshToken: 'minutes', }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'Client2', AccessTokenValidity: 60, IdTokenValidity: Match.absentProperty(), @@ -593,7 +593,7 @@ describe('User Pool Client', () => { RefreshToken: Match.absentProperty(), }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'Client3', AccessTokenValidity: Match.absentProperty(), IdTokenValidity: 60, @@ -604,7 +604,7 @@ describe('User Pool Client', () => { RefreshToken: Match.absentProperty(), }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'Client4', AccessTokenValidity: Match.absentProperty(), IdTokenValidity: Match.absentProperty(), @@ -615,7 +615,7 @@ describe('User Pool Client', () => { RefreshToken: 'minutes', }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'Client5', TokenValidityUnits: Match.absentProperty(), IdTokenValidity: Match.absentProperty(), @@ -719,7 +719,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'Client1', AccessTokenValidity: validity.toMinutes(), TokenValidityUnits: { @@ -743,7 +743,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'Client1', IdTokenValidity: validity.toMinutes(), TokenValidityUnits: { @@ -768,7 +768,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'Client1', RefreshTokenValidity: validity.toMinutes(), TokenValidityUnits: { @@ -793,7 +793,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'Client1', AccessTokenValidity: validity.toMinutes(), TokenValidityUnits: { @@ -818,7 +818,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'Client1', IdTokenValidity: validity.toMinutes(), TokenValidityUnits: { @@ -838,7 +838,7 @@ describe('User Pool Client', () => { pool.addClient('Client', {}); // EXPECT - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ReadAttributes: Match.absentProperty(), WriteAttributes: Match.absentProperty(), }); @@ -878,7 +878,7 @@ describe('User Pool Client', () => { }); // EXPECT - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ReadAttributes: Match.arrayWith(['address', 'birthdate', 'email', 'email_verified', 'family_name', 'gender', 'given_name', 'locale', 'middle_name', 'name', 'nickname', 'phone_number', 'phone_number_verified', 'picture', 'preferred_username', 'profile', 'updated_at', 'website', 'zoneinfo']), @@ -886,4 +886,4 @@ describe('User Pool Client', () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool-domain.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool-domain.test.ts index cc387b1f0e818..7cbc013951271 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool-domain.test.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool-domain.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import { Certificate } from '@aws-cdk/aws-certificatemanager'; import { CfnParameter, Stack } from '@aws-cdk/core'; import { UserPool, UserPoolDomain } from '../lib'; @@ -21,7 +21,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolDomain', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolDomain', { UserPoolId: stack.resolve(pool.userPoolId), Domain: 'test-domain.example.com', CustomDomainConfig: { @@ -44,7 +44,7 @@ describe('User Pool Client', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolDomain', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolDomain', { UserPoolId: stack.resolve(pool.userPoolId), Domain: 'cognito-domain-prefix', }); @@ -124,8 +124,8 @@ describe('User Pool Client', () => { ], }); - TemplateAssertions.fromStack(stack).resourceCountIs('Custom::UserPoolCloudFrontDomainName', 1); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + Template.fromStack(stack).resourceCountIs('Custom::UserPoolCloudFrontDomainName', 1); + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [{ Action: 'cognito-idp:DescribeUserPoolDomain', @@ -161,7 +161,7 @@ describe('User Pool Client', () => { // THEN expect(client.domainName).toEqual('domain-name-1'); - TemplateAssertions.fromStack(stack).resourceCountIs('AWS::Cognito::UserPoolDomain', 0); + Template.fromStack(stack).resourceCountIs('AWS::Cognito::UserPoolDomain', 0); }); describe('signInUrl', () => { @@ -226,4 +226,4 @@ describe('User Pool Client', () => { expect(signInUrl).toMatch(/amazoncognito\.com\/testsignin\?/); }); }); -}); \ No newline at end of file +}); diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool-idps/amazon.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool-idps/amazon.test.ts index d6bf3550fb924..a905e7da01730 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool-idps/amazon.test.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool-idps/amazon.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import { Stack } from '@aws-cdk/core'; import { ProviderAttribute, UserPool, UserPoolIdentityProviderAmazon } from '../../lib'; @@ -16,7 +16,7 @@ describe('UserPoolIdentityProvider', () => { clientSecret: 'amzn-client-secret', }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { ProviderName: 'LoginWithAmazon', ProviderType: 'LoginWithAmazon', ProviderDetails: { @@ -40,7 +40,7 @@ describe('UserPoolIdentityProvider', () => { scopes: ['scope1', 'scope2'], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { ProviderName: 'LoginWithAmazon', ProviderType: 'LoginWithAmazon', ProviderDetails: { @@ -88,7 +88,7 @@ describe('UserPoolIdentityProvider', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { AttributeMapping: { given_name: 'name', address: 'amzn-address', @@ -98,4 +98,4 @@ describe('UserPoolIdentityProvider', () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool-idps/apple.ts b/packages/@aws-cdk/aws-cognito/test/user-pool-idps/apple.ts index 651601e0151bb..3787f83b17391 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool-idps/apple.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool-idps/apple.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import { Stack } from '@aws-cdk/core'; import { ProviderAttribute, UserPool, UserPoolIdentityProviderApple } from '../../lib'; @@ -18,7 +18,7 @@ describe('UserPoolIdentityProvider', () => { privateKey: 'PRIV_KEY_CDK', }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { ProviderName: 'SignInWithApple', ProviderType: 'SignInWithApple', ProviderDetails: { @@ -46,7 +46,7 @@ describe('UserPoolIdentityProvider', () => { scopes: ['scope1', 'scope2'], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { ProviderName: 'SignInWithApple', ProviderType: 'SignInWithApple', ProviderDetails: { @@ -100,7 +100,7 @@ describe('UserPoolIdentityProvider', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { AttributeMapping: { family_name: 'firstName', given_name: 'lastName', @@ -110,4 +110,4 @@ describe('UserPoolIdentityProvider', () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool-idps/facebook.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool-idps/facebook.test.ts index 8a1002f4d0d05..f2ec3bf581bf6 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool-idps/facebook.test.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool-idps/facebook.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import { Stack } from '@aws-cdk/core'; import { ProviderAttribute, UserPool, UserPoolIdentityProviderFacebook } from '../../lib'; @@ -16,7 +16,7 @@ describe('UserPoolIdentityProvider', () => { clientSecret: 'fb-client-secret', }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { ProviderName: 'Facebook', ProviderType: 'Facebook', ProviderDetails: { @@ -41,7 +41,7 @@ describe('UserPoolIdentityProvider', () => { apiVersion: 'version1', }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { ProviderName: 'Facebook', ProviderType: 'Facebook', ProviderDetails: { @@ -90,7 +90,7 @@ describe('UserPoolIdentityProvider', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { AttributeMapping: { given_name: 'name', address: 'fb-address', @@ -100,4 +100,4 @@ describe('UserPoolIdentityProvider', () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool-idps/google.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool-idps/google.test.ts index 78363550ca2ab..d66cf55dcd84c 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool-idps/google.test.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool-idps/google.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import { Stack } from '@aws-cdk/core'; import { ProviderAttribute, UserPool, UserPoolIdentityProviderGoogle } from '../../lib'; @@ -16,7 +16,7 @@ describe('UserPoolIdentityProvider', () => { clientSecret: 'google-client-secret', }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { ProviderName: 'Google', ProviderType: 'Google', ProviderDetails: { @@ -40,7 +40,7 @@ describe('UserPoolIdentityProvider', () => { scopes: ['scope1', 'scope2'], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { ProviderName: 'Google', ProviderType: 'Google', ProviderDetails: { @@ -88,7 +88,7 @@ describe('UserPoolIdentityProvider', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolIdentityProvider', { AttributeMapping: { given_name: 'name', address: 'google-address', @@ -98,4 +98,4 @@ describe('UserPoolIdentityProvider', () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool-resource-server.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool-resource-server.test.ts index 84837585252f0..f8c3fc9d12d3a 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool-resource-server.test.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool-resource-server.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import { Stack } from '@aws-cdk/core'; import { UserPool, UserPoolResourceServer } from '../lib'; @@ -15,7 +15,7 @@ describe('User Pool Resource Server', () => { }); //THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolResourceServer', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolResourceServer', { Identifier: 'users', Name: 'users', UserPoolId: stack.resolve(pool.userPoolId), @@ -35,7 +35,7 @@ describe('User Pool Resource Server', () => { }); //THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolResourceServer', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolResourceServer', { Identifier: 'users', Name: 'internal-users', }); @@ -59,7 +59,7 @@ describe('User Pool Resource Server', () => { }); //THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolResourceServer', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolResourceServer', { Scopes: [ { ScopeDescription: 'read only access', diff --git a/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts b/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts index 41b15062cc426..75ed3dcfa1a2d 100644 --- a/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts +++ b/packages/@aws-cdk/aws-cognito/test/user-pool.test.ts @@ -1,4 +1,4 @@ -import { Match, TemplateAssertions } from '@aws-cdk/assertions'; +import { Match, Template } from '@aws-cdk/assertions'; import { Role, ServicePrincipal } from '@aws-cdk/aws-iam'; import * as lambda from '@aws-cdk/aws-lambda'; import { CfnParameter, Duration, Stack, Tags } from '@aws-cdk/core'; @@ -14,7 +14,7 @@ describe('User Pool', () => { new UserPool(stack, 'Pool'); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { AdminCreateUserConfig: { AllowAdminCreateUserOnly: true, InviteMessageTemplate: Match.absentProperty(), @@ -33,7 +33,7 @@ describe('User Pool', () => { lambdaTriggers: Match.absentProperty(), }); - TemplateAssertions.fromStack(stack).hasResource('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResource('AWS::Cognito::UserPool', { DeletionPolicy: 'Retain', }); }); @@ -48,7 +48,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { AdminCreateUserConfig: { AllowAdminCreateUserOnly: false, }, @@ -67,7 +67,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { EmailVerificationMessage: Match.absentProperty(), EmailVerificationSubject: Match.absentProperty(), SmsVerificationMessage: 'The verification code to your new account is {####}', @@ -91,7 +91,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { SmsAuthenticationMessage: message, }); }), @@ -202,7 +202,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { AdminCreateUserConfig: { InviteMessageTemplate: { EmailMessage: 'invitation email body', @@ -225,7 +225,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { SmsConfiguration: { ExternalId: 'test-external-id', SnsCallerArn: role.roleArn, @@ -297,7 +297,7 @@ describe('User Pool', () => { Tags.of(pool).add('PoolTag', 'PoolParty'); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UserPoolName: 'myPool', UserPoolTags: { PoolTag: 'PoolParty', @@ -318,12 +318,12 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { LambdaConfig: { PreSignUp: stack.resolve(fn.functionArn), }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { Action: 'lambda:InvokeFunction', FunctionName: stack.resolve(fn.functionArn), Principal: 'cognito-idp.amazonaws.com', @@ -359,7 +359,7 @@ describe('User Pool', () => { pool.addTrigger(UserPoolOperation.VERIFY_AUTH_CHALLENGE_RESPONSE, verifyAuthChallengeResponse); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { LambdaConfig: { CreateAuthChallenge: stack.resolve(createAuthChallenge.functionArn), CustomMessage: stack.resolve(customMessage.functionArn), @@ -377,7 +377,7 @@ describe('User Pool', () => { [createAuthChallenge, customMessage, defineAuthChallenge, postAuthentication, postConfirmation, preAuthentication, preSignUp, preTokenGeneration, userMigration, verifyAuthChallengeResponse].forEach((fn) => { - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { Action: 'lambda:InvokeFunction', FunctionName: stack.resolve(fn.functionArn), Principal: 'cognito-idp.amazonaws.com', @@ -414,7 +414,7 @@ describe('User Pool', () => { new UserPool(stack, 'Pool'); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UsernameAttributes: Match.absentProperty(), AliasAttributes: Match.absentProperty(), }); @@ -437,7 +437,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UsernameAttributes: Match.absentProperty(), AliasAttributes: ['email'], }); @@ -453,7 +453,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UsernameAttributes: ['email', 'phone_number'], AliasAttributes: Match.absentProperty(), }); @@ -474,11 +474,11 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UserPoolName: 'Pool1', AutoVerifiedAttributes: ['email'], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UserPoolName: 'Pool2', AutoVerifiedAttributes: ['email', 'phone_number'], }); @@ -495,7 +495,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { AutoVerifiedAttributes: ['email', 'phone_number'], }); }); @@ -510,7 +510,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UsernameConfiguration: { CaseSensitive: false, }, @@ -525,7 +525,7 @@ describe('User Pool', () => { new UserPool(stack, 'Pool', {}); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UsernameConfiguration: Match.absentProperty(), }); }); @@ -547,7 +547,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { Schema: [ { Name: 'name', @@ -595,7 +595,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UserPoolName: 'Pool', Schema: [ { @@ -611,7 +611,7 @@ describe('User Pool', () => { ], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UserPoolName: 'Pool1', Schema: [ { @@ -636,7 +636,7 @@ describe('User Pool', () => { new UserPool(stack, 'Pool', { userPoolName: 'Pool' }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UserPoolName: 'Pool', Schema: Match.absentProperty(), }); @@ -657,7 +657,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UserPoolName: 'Pool', Schema: [ { @@ -682,7 +682,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { Schema: [ { Name: 'custom-string-attr', @@ -713,7 +713,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { Schema: [ { AttributeDataType: 'String', @@ -757,12 +757,12 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UserPoolName: 'Pool1', MfaConfiguration: Match.absentProperty(), EnabledMfas: Match.absentProperty(), }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UserPoolName: 'Pool2', MfaConfiguration: 'OFF', EnabledMfas: Match.absentProperty(), @@ -784,12 +784,12 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UserPoolName: 'Pool1', MfaConfiguration: 'OPTIONAL', EnabledMfas: ['SMS_MFA'], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { UserPoolName: 'Pool2', MfaConfiguration: 'ON', EnabledMfas: ['SMS_MFA'], @@ -810,7 +810,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { EnabledMfas: ['SMS_MFA', 'SOFTWARE_TOKEN_MFA'], }); }); @@ -832,7 +832,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { Policies: { PasswordPolicy: { TemporaryPasswordValidityDays: 2, @@ -858,7 +858,7 @@ describe('User Pool', () => { }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { Policies: { PasswordPolicy: { MinimumLength: 8, @@ -916,7 +916,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { EmailConfiguration: { From: 'from@myawesomeapp.com', ReplyToEmailAddress: 'replyTo@myawesomeapp.com', @@ -939,11 +939,11 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'userpoolclient', UserPoolId: stack.resolve(userpool.userPoolId), }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolClient', { ClientName: 'userpoolimportedclient', UserPoolId: stack.resolve(imported.userPoolId), }); @@ -966,7 +966,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolResourceServer', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolResourceServer', { Identifier: 'users', Name: 'users', UserPoolId: stack.resolve(userpool.userPoolId), @@ -998,11 +998,11 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolDomain', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolDomain', { Domain: 'userpooldomain', UserPoolId: stack.resolve(userpool.userPoolId), }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolDomain', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPoolDomain', { Domain: 'userpoolimporteddomain', UserPoolId: stack.resolve(imported.userPoolId), }); @@ -1032,7 +1032,7 @@ describe('User Pool', () => { new UserPool(stack, 'pool', { accountRecovery: AccountRecovery.EMAIL_AND_PHONE_WITHOUT_MFA }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { AccountRecoverySetting: { RecoveryMechanisms: [ { Name: 'verified_email', Priority: 1 }, @@ -1050,7 +1050,7 @@ describe('User Pool', () => { new UserPool(stack, 'pool', { accountRecovery: AccountRecovery.PHONE_WITHOUT_MFA_AND_EMAIL }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { AccountRecoverySetting: { RecoveryMechanisms: [ { Name: 'verified_phone_number', Priority: 1 }, @@ -1068,7 +1068,7 @@ describe('User Pool', () => { new UserPool(stack, 'pool', { accountRecovery: AccountRecovery.EMAIL_ONLY }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { AccountRecoverySetting: { RecoveryMechanisms: [ { Name: 'verified_email', Priority: 1 }, @@ -1085,7 +1085,7 @@ describe('User Pool', () => { new UserPool(stack, 'pool', { accountRecovery: AccountRecovery.PHONE_ONLY_WITHOUT_MFA }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { AccountRecoverySetting: { RecoveryMechanisms: [ { Name: 'verified_phone_number', Priority: 1 }, @@ -1102,7 +1102,7 @@ describe('User Pool', () => { new UserPool(stack, 'pool', { accountRecovery: AccountRecovery.NONE }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { AccountRecoverySetting: { RecoveryMechanisms: [ { Name: 'admin_only', Priority: 1 }, @@ -1119,7 +1119,7 @@ describe('User Pool', () => { new UserPool(stack, 'pool', { accountRecovery: AccountRecovery.PHONE_AND_EMAIL }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { AccountRecoverySetting: Match.absentProperty(), }); }); @@ -1132,7 +1132,7 @@ describe('User Pool', () => { new UserPool(stack, 'pool'); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { AccountRecoverySetting: { RecoveryMechanisms: [ { Name: 'verified_phone_number', Priority: 1 }, @@ -1152,7 +1152,7 @@ describe('User Pool', () => { new UserPool(stack, 'pool'); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { SmsConfiguration: Match.absentProperty(), }); }); @@ -1171,7 +1171,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { SmsConfiguration: { ExternalId: 'role-external-id', SnsCallerArn: { 'Fn::GetAtt': ['smsRoleA4587CE8', 'Arn'] }, @@ -1189,13 +1189,13 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { SmsConfiguration: { ExternalId: 'pool', SnsCallerArn: { 'Fn::GetAtt': ['poolsmsRole04048F13', 'Arn'] }, }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { AssumeRolePolicyDocument: { Statement: [ { @@ -1244,7 +1244,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { SmsConfiguration: Match.absentProperty(), }); }); @@ -1266,7 +1266,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { SmsConfiguration: Match.absentProperty(), }); }); @@ -1282,7 +1282,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { SmsConfiguration: { ExternalId: 'pool', SnsCallerArn: { 'Fn::GetAtt': ['poolsmsRole04048F13', 'Arn'] }, @@ -1302,7 +1302,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { SmsConfiguration: { ExternalId: 'pool', SnsCallerArn: { 'Fn::GetAtt': ['poolsmsRole04048F13', 'Arn'] }, @@ -1327,7 +1327,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { SmsConfiguration: { ExternalId: 'pool', SnsCallerArn: { 'Fn::GetAtt': ['poolsmsRole04048F13', 'Arn'] }, @@ -1350,7 +1350,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { SmsConfiguration: Match.absentProperty(), }); }); @@ -1381,7 +1381,7 @@ describe('User Pool', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { + Template.fromStack(stack).hasResourceProperties('AWS::Cognito::UserPool', { EmailConfiguration: { From: 'от@xn--d1acufc.xn--p1ai', ReplyToEmailAddress: 'ответить@xn--d1acufc.xn--p1ai', diff --git a/packages/@aws-cdk/aws-connect/package.json b/packages/@aws-cdk/aws-connect/package.json index 02e16855e466b..93d08397cf375 100644 --- a/packages/@aws-cdk/aws-connect/package.json +++ b/packages/@aws-cdk/aws-connect/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-connect/test/connect.test.ts b/packages/@aws-cdk/aws-connect/test/connect.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-connect/test/connect.test.ts +++ b/packages/@aws-cdk/aws-connect/test/connect.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-cur/package.json b/packages/@aws-cdk/aws-cur/package.json index ec2fb98a0d60c..8969e73dc4399 100644 --- a/packages/@aws-cdk/aws-cur/package.json +++ b/packages/@aws-cdk/aws-cur/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-cur/test/cur.test.ts b/packages/@aws-cdk/aws-cur/test/cur.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-cur/test/cur.test.ts +++ b/packages/@aws-cdk/aws-cur/test/cur.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-customerprofiles/package.json b/packages/@aws-cdk/aws-customerprofiles/package.json index 387a792b7a373..36ccdda69b39d 100644 --- a/packages/@aws-cdk/aws-customerprofiles/package.json +++ b/packages/@aws-cdk/aws-customerprofiles/package.json @@ -77,7 +77,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", diff --git a/packages/@aws-cdk/aws-customerprofiles/test/customerprofiles.test.ts b/packages/@aws-cdk/aws-customerprofiles/test/customerprofiles.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-customerprofiles/test/customerprofiles.test.ts +++ b/packages/@aws-cdk/aws-customerprofiles/test/customerprofiles.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-databrew/package.json b/packages/@aws-cdk/aws-databrew/package.json index 9f36870538f10..bf710a7394d74 100644 --- a/packages/@aws-cdk/aws-databrew/package.json +++ b/packages/@aws-cdk/aws-databrew/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-databrew/test/databrew.test.ts b/packages/@aws-cdk/aws-databrew/test/databrew.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-databrew/test/databrew.test.ts +++ b/packages/@aws-cdk/aws-databrew/test/databrew.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-datapipeline/package.json b/packages/@aws-cdk/aws-datapipeline/package.json index f368c68baa360..b0c4cf9bf3218 100644 --- a/packages/@aws-cdk/aws-datapipeline/package.json +++ b/packages/@aws-cdk/aws-datapipeline/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-datapipeline/test/datapipeline.test.ts b/packages/@aws-cdk/aws-datapipeline/test/datapipeline.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-datapipeline/test/datapipeline.test.ts +++ b/packages/@aws-cdk/aws-datapipeline/test/datapipeline.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-datasync/package.json b/packages/@aws-cdk/aws-datasync/package.json index d63f373cfeef8..3ec205f0d6ee1 100644 --- a/packages/@aws-cdk/aws-datasync/package.json +++ b/packages/@aws-cdk/aws-datasync/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-datasync/test/datasync.test.ts b/packages/@aws-cdk/aws-datasync/test/datasync.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-datasync/test/datasync.test.ts +++ b/packages/@aws-cdk/aws-datasync/test/datasync.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-dax/package.json b/packages/@aws-cdk/aws-dax/package.json index bd4d0c94dc3d3..82d88fd70d8d1 100644 --- a/packages/@aws-cdk/aws-dax/package.json +++ b/packages/@aws-cdk/aws-dax/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-dax/test/dax.test.ts b/packages/@aws-cdk/aws-dax/test/dax.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-dax/test/dax.test.ts +++ b/packages/@aws-cdk/aws-dax/test/dax.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-detective/package.json b/packages/@aws-cdk/aws-detective/package.json index b5bd1c2a903df..3955b883cb2bf 100644 --- a/packages/@aws-cdk/aws-detective/package.json +++ b/packages/@aws-cdk/aws-detective/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-detective/test/detective.test.ts b/packages/@aws-cdk/aws-detective/test/detective.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-detective/test/detective.test.ts +++ b/packages/@aws-cdk/aws-detective/test/detective.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-devopsguru/package.json b/packages/@aws-cdk/aws-devopsguru/package.json index 6fc91c263db06..9c9ff7fdb0228 100644 --- a/packages/@aws-cdk/aws-devopsguru/package.json +++ b/packages/@aws-cdk/aws-devopsguru/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-devopsguru/test/devopsguru.test.ts b/packages/@aws-cdk/aws-devopsguru/test/devopsguru.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-devopsguru/test/devopsguru.test.ts +++ b/packages/@aws-cdk/aws-devopsguru/test/devopsguru.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-directoryservice/package.json b/packages/@aws-cdk/aws-directoryservice/package.json index 179e72a6a4a2a..1396430e3a34a 100644 --- a/packages/@aws-cdk/aws-directoryservice/package.json +++ b/packages/@aws-cdk/aws-directoryservice/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-directoryservice/test/directoryservice.test.ts b/packages/@aws-cdk/aws-directoryservice/test/directoryservice.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-directoryservice/test/directoryservice.test.ts +++ b/packages/@aws-cdk/aws-directoryservice/test/directoryservice.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-dlm/package.json b/packages/@aws-cdk/aws-dlm/package.json index 09d10c116da40..84fd44d939683 100644 --- a/packages/@aws-cdk/aws-dlm/package.json +++ b/packages/@aws-cdk/aws-dlm/package.json @@ -78,7 +78,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-dlm/test/dlm.test.ts b/packages/@aws-cdk/aws-dlm/test/dlm.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-dlm/test/dlm.test.ts +++ b/packages/@aws-cdk/aws-dlm/test/dlm.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-dms/package.json b/packages/@aws-cdk/aws-dms/package.json index 7e06f8859e421..d1ba735745e55 100644 --- a/packages/@aws-cdk/aws-dms/package.json +++ b/packages/@aws-cdk/aws-dms/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-dms/test/dms.test.ts b/packages/@aws-cdk/aws-dms/test/dms.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-dms/test/dms.test.ts +++ b/packages/@aws-cdk/aws-dms/test/dms.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-ec2/README.md b/packages/@aws-cdk/aws-ec2/README.md index fc48c31121bfe..ae628ce7d21dc 100644 --- a/packages/@aws-cdk/aws-ec2/README.md +++ b/packages/@aws-cdk/aws-ec2/README.md @@ -166,7 +166,13 @@ Which subnets are selected is evaluated as follows: * `onePerAz`: per availability zone, a maximum of one subnet will be returned (Useful for resource types that do not allow creating two ENIs in the same availability zone). * `subnetFilters`: additional filtering on subnets using any number of user-provided filters which - extend the SubnetFilter class. + extend `SubnetFilter`. The following methods on the `SubnetFilter` class can be used to create + a filter: + * `byIds`: chooses subnets from a list of ids + * `availabilityZones`: chooses subnets in the provided list of availability zones + * `onePerAz`: chooses at most one subnet per availability zone + * `containsIpAddresses`: chooses a subnet which contains *any* of the listed ip addresses + * `byCidrMask`: chooses subnets that have the provided CIDR netmask ### Using NAT instances diff --git a/packages/@aws-cdk/aws-ec2/lib/subnet.ts b/packages/@aws-cdk/aws-ec2/lib/subnet.ts index 204c81957c929..4854509fa60df 100644 --- a/packages/@aws-cdk/aws-ec2/lib/subnet.ts +++ b/packages/@aws-cdk/aws-ec2/lib/subnet.ts @@ -8,6 +8,13 @@ import { ISubnet } from './vpc'; */ export abstract class SubnetFilter { + /** + * Chooses subnets by id. + */ + public static byIds(subnetIds: string[]): SubnetFilter { + return new SubnetIdSubnetFilter(subnetIds); + } + /** * Chooses subnets which are in one of the given availability zones. */ @@ -29,6 +36,13 @@ export abstract class SubnetFilter { return new ContainsIpAddressesSubnetFilter(ipv4addrs); } + /** + * Chooses subnets which have the provided CIDR netmask. + */ + public static byCidrMask(mask: number): SubnetFilter { + return new CidrMaskSubnetFilter(mask); + } + /** * Executes the subnet filtering logic, returning a filtered set of subnets. */ @@ -112,4 +126,46 @@ class ContainsIpAddressesSubnetFilter extends SubnetFilter { return cidrBlockObjs.some(cidr => subnetCidrBlock.containsCidr(cidr)); }); } -} \ No newline at end of file +} + +/** + * Chooses subnets based on the subnetId + */ +class SubnetIdSubnetFilter extends SubnetFilter { + + private readonly subnetIds: string[]; + + constructor(subnetIds: string[]) { + super(); + this.subnetIds = subnetIds; + } + + /** + * Executes the subnet filtering logic. + */ + public selectSubnets(subnets: ISubnet[]): ISubnet[] { + return subnets.filter(subnet => this.subnetIds.includes(subnet.subnetId)); + } +} + +/** + * Chooses subnets based on the CIDR Netmask + */ +class CidrMaskSubnetFilter extends SubnetFilter { + private readonly mask: number + + constructor(mask: number) { + super(); + this.mask = mask; + } + + /** + * Executes the subnet filtering logic. + */ + public selectSubnets(subnets: ISubnet[]): ISubnet[] { + return subnets.filter(subnet => { + const subnetCidr = new CidrBlock(subnet.ipv4CidrBlock); + return subnetCidr.mask === this.mask; + }); + } +} diff --git a/packages/@aws-cdk/aws-ec2/lib/volume.ts b/packages/@aws-cdk/aws-ec2/lib/volume.ts index 64f920866a17b..a25ca459b7c63 100644 --- a/packages/@aws-cdk/aws-ec2/lib/volume.ts +++ b/packages/@aws-cdk/aws-ec2/lib/volume.ts @@ -614,6 +614,8 @@ export class Volume extends VolumeBase { }); resource.applyRemovalPolicy(props.removalPolicy); + if (props.volumeName) Tags.of(resource).add('Name', props.volumeName); + this.volumeId = resource.ref; this.availabilityZone = props.availabilityZone; this.encryptionKey = props.encryptionKey; diff --git a/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts b/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts index 2face39e7ccd5..dd28d74e84ea1 100644 --- a/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts +++ b/packages/@aws-cdk/aws-ec2/lib/vpc-endpoint.ts @@ -305,6 +305,7 @@ export class InterfaceVpcEndpointAwsService implements IInterfaceVpcEndpointServ public static readonly REKOGNITION_FIPS = new InterfaceVpcEndpointAwsService('rekognition-fips'); public static readonly STEP_FUNCTIONS = new InterfaceVpcEndpointAwsService('states'); public static readonly LAMBDA = new InterfaceVpcEndpointAwsService('lambda'); + public static readonly TRANSCRIBE = new InterfaceVpcEndpointAwsService('transcribe'); /** * The name of the service. diff --git a/packages/@aws-cdk/aws-ec2/package.json b/packages/@aws-cdk/aws-ec2/package.json index 2f2dd7ab6e1c4..941d598075411 100644 --- a/packages/@aws-cdk/aws-ec2/package.json +++ b/packages/@aws-cdk/aws-ec2/package.json @@ -261,6 +261,7 @@ "docs-public-apis:@aws-cdk/aws-ec2.InterfaceVpcEndpointAwsService.REKOGNITION_FIPS", "docs-public-apis:@aws-cdk/aws-ec2.InterfaceVpcEndpointAwsService.STEP_FUNCTIONS", "docs-public-apis:@aws-cdk/aws-ec2.InterfaceVpcEndpointAwsService.LAMBDA", + "docs-public-apis:@aws-cdk/aws-ec2.InterfaceVpcEndpointAwsService.TRANSCRIBE", "docs-public-apis:@aws-cdk/aws-ec2.Port.toString", "docs-public-apis:@aws-cdk/aws-ec2.PrivateSubnet.fromPrivateSubnetAttributes", "docs-public-apis:@aws-cdk/aws-ec2.PublicSubnet.fromPublicSubnetAttributes", diff --git a/packages/@aws-cdk/aws-ec2/test/volume.test.ts b/packages/@aws-cdk/aws-ec2/test/volume.test.ts index 308e1ad4fa1ef..af88164fcc439 100644 --- a/packages/@aws-cdk/aws-ec2/test/volume.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/volume.test.ts @@ -32,6 +32,7 @@ describe('volume', () => { new Volume(stack, 'Volume', { availabilityZone: 'us-east-1a', size: cdk.Size.gibibytes(8), + volumeName: 'MyVolume', }); // THEN @@ -40,6 +41,12 @@ describe('volume', () => { MultiAttachEnabled: false, Size: 8, VolumeType: 'gp2', + Tags: [ + { + Key: 'Name', + Value: 'MyVolume', + }, + ], }, ResourcePart.Properties)); cdkExpect(stack).to(haveResource('AWS::EC2::Volume', { diff --git a/packages/@aws-cdk/aws-ec2/test/vpc.test.ts b/packages/@aws-cdk/aws-ec2/test/vpc.test.ts index 172bec102ccd0..dd22090584a25 100644 --- a/packages/@aws-cdk/aws-ec2/test/vpc.test.ts +++ b/packages/@aws-cdk/aws-ec2/test/vpc.test.ts @@ -1688,6 +1688,58 @@ nodeunitShim({ })); test.done(); }, + + 'can filter by Subnet Ids'(test: Test) { + // GIVEN + const stack = getTestStack(); + + const vpc = Vpc.fromVpcAttributes(stack, 'VPC', { + vpcId: 'vpc-1234', + vpcCidrBlock: '192.168.0.0/16', + availabilityZones: ['dummy1a', 'dummy1b', 'dummy1c'], + privateSubnetIds: ['priv-1', 'priv-2', 'priv-3'], + }); + + // WHEN + new InterfaceVpcEndpoint(stack, 'VPC Endpoint', { + vpc, + service: new InterfaceVpcEndpointService('com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', 443), + subnets: { + subnetFilters: [SubnetFilter.byIds(['priv-1', 'priv-2'])], + }, + }); + + // THEN + cdkExpect(stack).to(haveResource('AWS::EC2::VPCEndpoint', { + ServiceName: 'com.amazonaws.vpce.us-east-1.vpce-svc-uuddlrlrbastrtsvc', + SubnetIds: ['priv-1', 'priv-2'], + })); + test.done(); + }, + + 'can filter by Cidr Netmask'(test: Test) { + // GIVEN + const stack = getTestStack(); + const vpc = new Vpc(stack, 'VpcNetwork', { + maxAzs: 1, + subnetConfiguration: [ + { name: 'normalSn1', subnetType: SubnetType.PUBLIC, cidrMask: 20 }, + { name: 'normalSn2', subnetType: SubnetType.PUBLIC, cidrMask: 20 }, + { name: 'smallSn', subnetType: SubnetType.PUBLIC, cidrMask: 28 }, + ], + }); + + // WHEN + const { subnetIds } = vpc.selectSubnets( + { subnetFilters: [SubnetFilter.byCidrMask(20)] }, + ); + + // THEN + test.deepEqual(subnetIds.length, 2); + const expected = vpc.publicSubnets.filter(s => s.ipv4CidrBlock.endsWith('/20')); + test.deepEqual(subnetIds, expected.map(s => s.subnetId)); + test.done(); + }, }, }); diff --git a/packages/@aws-cdk/aws-efs/test/access-point.test.ts b/packages/@aws-cdk/aws-efs/test/access-point.test.ts index 7a4981a5c4380..dd29d5aff5dc3 100644 --- a/packages/@aws-cdk/aws-efs/test/access-point.test.ts +++ b/packages/@aws-cdk/aws-efs/test/access-point.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import { Stack } from '@aws-cdk/core'; import { AccessPoint, FileSystem } from '../lib'; @@ -19,7 +19,7 @@ test('addAccessPoint correctly', () => { // WHEN fileSystem.addAccessPoint('MyAccessPoint'); // THEN - TemplateAssertions.fromStack(stack).resourceCountIs('AWS::EFS::AccessPoint', 1); + Template.fromStack(stack).resourceCountIs('AWS::EFS::AccessPoint', 1); }); test('new AccessPoint correctly', () => { @@ -28,7 +28,7 @@ test('new AccessPoint correctly', () => { fileSystem, }); // THEN - TemplateAssertions.fromStack(stack).resourceCountIs('AWS::EFS::AccessPoint', 1); + Template.fromStack(stack).resourceCountIs('AWS::EFS::AccessPoint', 1); }); test('import an AccessPoint using fromAccessPointId', () => { @@ -143,7 +143,7 @@ test('custom access point is created correctly', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::EFS::AccessPoint', { + Template.fromStack(stack).hasResourceProperties('AWS::EFS::AccessPoint', { FileSystemId: { Ref: 'EfsFileSystem37910666', }, diff --git a/packages/@aws-cdk/aws-efs/test/efs-file-system.test.ts b/packages/@aws-cdk/aws-efs/test/efs-file-system.test.ts index 8db4c262c1aac..60a0133e63ca2 100644 --- a/packages/@aws-cdk/aws-efs/test/efs-file-system.test.ts +++ b/packages/@aws-cdk/aws-efs/test/efs-file-system.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions, Match } from '@aws-cdk/assertions'; +import { Template, Match } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; @@ -27,7 +27,7 @@ testFutureBehavior( vpc: customVpc, }); - TemplateAssertions.fromStack(customStack).hasResourceProperties('AWS::EFS::FileSystem', { + Template.fromStack(customStack).hasResourceProperties('AWS::EFS::FileSystem', { Encrypted: true, }); @@ -41,7 +41,7 @@ testLegacyBehavior('when @aws-cdk/aws-efs:defaultEncryptionAtRest is missing, en vpc: customVpc, }); - TemplateAssertions.fromStack(customStack).hasResourceProperties('AWS::EFS::FileSystem', { + Template.fromStack(customStack).hasResourceProperties('AWS::EFS::FileSystem', { Encrypted: Match.absentProperty(), }); @@ -53,7 +53,7 @@ test('default file system is created correctly', () => { vpc, }); // THEN - const assertions = TemplateAssertions.fromStack(stack); + const assertions = Template.fromStack(stack); assertions.hasResource('AWS::EFS::FileSystem', { DeletionPolicy: 'Retain', UpdateReplacePolicy: 'Retain', @@ -69,7 +69,7 @@ test('unencrypted file system is created correctly with default KMS', () => { encrypted: false, }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { + Template.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { Encrypted: false, }); }); @@ -81,7 +81,7 @@ test('encrypted file system is created correctly with default KMS', () => { encrypted: true, }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { + Template.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { Encrypted: true, }); }); @@ -103,7 +103,7 @@ test('encrypted file system is created correctly with custom KMS', () => { * in generated CDK, hence hardcoding the MD5 hash here for assertion. Assumption is that the path of the Key wont * change in this UT. Checked the unique id by generating the cloud formation stack. */ - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { + Template.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { Encrypted: true, KmsKeyId: { 'Fn::GetAtt': [ @@ -121,7 +121,7 @@ test('file system is created correctly with a life cycle property', () => { lifecyclePolicy: LifecyclePolicy.AFTER_7_DAYS, }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { + Template.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { LifecyclePolicies: [{ TransitionToIA: 'AFTER_7_DAYS', }], @@ -135,7 +135,7 @@ test('file system is created correctly with performance mode', () => { performanceMode: PerformanceMode.MAX_IO, }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { + Template.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { PerformanceMode: 'maxIO', }); }); @@ -147,7 +147,7 @@ test('file system is created correctly with bursting throughput mode', () => { throughputMode: ThroughputMode.BURSTING, }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { + Template.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { ThroughputMode: 'bursting', }); }); @@ -187,7 +187,7 @@ test('file system is created correctly with provisioned throughput mode', () => provisionedThroughputPerSecond: Size.mebibytes(5), }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { + Template.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { ThroughputMode: 'provisioned', ProvisionedThroughputInMibps: 5, }); @@ -205,7 +205,7 @@ test('existing file system is imported correctly using id', () => { fs.connections.allowToAnyIpv4(ec2.Port.tcp(443)); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroupEgress', { + Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroupEgress', { GroupId: 'sg-123456789', }); }); @@ -227,7 +227,7 @@ test('existing file system is imported correctly using arn', () => { fs.connections.allowToAnyIpv4(ec2.Port.tcp(443)); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroupEgress', { + Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroupEgress', { GroupId: 'sg-123456789', }); @@ -276,7 +276,7 @@ test('support granting permissions', () => { fileSystem.grant(role, 'elasticfilesystem:ClientWrite'); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -309,7 +309,7 @@ test('support tags', () => { Tags.of(fileSystem).add('Name', 'LookAtMeAndMyFancyTags'); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { + Template.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { FileSystemTags: [ { Key: 'Name', Value: 'LookAtMeAndMyFancyTags' }, ], @@ -324,7 +324,7 @@ test('file system is created correctly when given a name', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { + Template.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { FileSystemTags: [ { Key: 'Name', Value: 'MyNameableFileSystem' }, ], @@ -338,7 +338,7 @@ test('auto-named if none provided', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { + Template.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { FileSystemTags: [ { Key: 'Name', Value: fileSystem.node.path }, ], @@ -350,7 +350,7 @@ test('removalPolicy is DESTROY', () => { new FileSystem(stack, 'EfsFileSystem', { vpc, removalPolicy: RemovalPolicy.DESTROY }); // THEN - TemplateAssertions.fromStack(stack).hasResource('AWS::EFS::FileSystem', { + Template.fromStack(stack).hasResource('AWS::EFS::FileSystem', { DeletionPolicy: 'Delete', UpdateReplacePolicy: 'Delete', }); @@ -361,7 +361,7 @@ test('can specify backup policy', () => { new FileSystem(stack, 'EfsFileSystem', { vpc, enableAutomaticBackups: true }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { + Template.fromStack(stack).hasResourceProperties('AWS::EFS::FileSystem', { BackupPolicy: { Status: 'ENABLED', }, @@ -379,5 +379,5 @@ test('can create when using a VPC with multiple subnets per availability zone', vpc: oneAzVpc, }); // make sure only one mount target is created. - TemplateAssertions.fromStack(stack).resourceCountIs('AWS::EFS::MountTarget', 1); + Template.fromStack(stack).resourceCountIs('AWS::EFS::MountTarget', 1); }); diff --git a/packages/@aws-cdk/aws-eks/README.md b/packages/@aws-cdk/aws-eks/README.md index fc96f314debbf..7e1d7ebb8ad04 100644 --- a/packages/@aws-cdk/aws-eks/README.md +++ b/packages/@aws-cdk/aws-eks/README.md @@ -49,7 +49,7 @@ This example defines an Amazon EKS cluster with the following configuration: ```ts // provisiong a cluster const cluster = new eks.Cluster(this, 'hello-eks', { - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, }); // apply a kubernetes manifest to the cluster @@ -142,7 +142,7 @@ Creating a new cluster is done using the `Cluster` or `FargateCluster` construct ```ts new eks.Cluster(this, 'HelloEKS', { - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, }); ``` @@ -150,7 +150,7 @@ You can also use `FargateCluster` to provision a cluster that uses only fargate ```ts new eks.FargateCluster(this, 'HelloEKS', { - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, }); ``` @@ -174,7 +174,7 @@ At cluster instantiation time, you can customize the number of instances and the ```ts new eks.Cluster(this, 'HelloEKS', { - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, defaultCapacity: 5, defaultCapacityInstance: ec2.InstanceType.of(ec2.InstanceClass.M5, ec2.InstanceSize.SMALL), }); @@ -186,7 +186,7 @@ Additional customizations are available post instantiation. To apply them, set t ```ts const cluster = new eks.Cluster(this, 'HelloEKS', { - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, defaultCapacity: 0, }); @@ -338,7 +338,7 @@ The following code defines an Amazon EKS cluster with a default Fargate Profile ```ts const cluster = new eks.FargateCluster(this, 'MyCluster', { - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, }); ``` @@ -397,7 +397,7 @@ You can also configure the cluster to use an auto-scaling group as the default c ```ts cluster = new eks.Cluster(this, 'HelloEKS', { - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, defaultCapacityType: eks.DefaultCapacityType.EC2, }); ``` @@ -477,7 +477,7 @@ You can configure the [cluster endpoint access](https://docs.aws.amazon.com/eks/ ```ts const cluster = new eks.Cluster(this, 'hello-eks', { - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, endpointAccess: eks.EndpointAccess.PRIVATE // No access outside of your VPC. }); ``` @@ -492,7 +492,7 @@ You can specify the VPC of the cluster using the `vpc` and `vpcSubnets` properti const vpc = new ec2.Vpc(this, 'Vpc'); new eks.Cluster(this, 'HelloEKS', { - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, vpc, vpcSubnets: [{ subnetType: ec2.SubnetType.PRIVATE }] }); @@ -531,7 +531,7 @@ You can configure the environment of this function by specifying it at cluster i ```ts const cluster = new eks.Cluster(this, 'hello-eks', { - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, clusterHandlerEnvironment: { 'http_proxy': 'http://proxy.myproxy.com' } @@ -548,7 +548,7 @@ You can configure the environment of this function by specifying it at cluster i ```ts const cluster = new eks.Cluster(this, 'hello-eks', { - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, kubectlEnvironment: { 'http_proxy': 'http://proxy.myproxy.com' } @@ -638,7 +638,7 @@ When you create a cluster, you can specify a `mastersRole`. The `Cluster` constr ```ts const role = new iam.Role(...); new eks.Cluster(this, 'HelloEKS', { - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, mastersRole: role, }); ``` diff --git a/packages/@aws-cdk/aws-eks/lib/cluster.ts b/packages/@aws-cdk/aws-eks/lib/cluster.ts index 2f2232861a240..009a79ecdb8ce 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster.ts @@ -644,6 +644,11 @@ export class KubernetesVersion { */ public static readonly V1_20 = KubernetesVersion.of('1.20'); + /** + * Kubernetes version 1.21 + */ + public static readonly V1_21 = KubernetesVersion.of('1.21'); + /** * Custom cluster version * @param version custom version number diff --git a/packages/@aws-cdk/aws-eks/lib/managed-nodegroup.ts b/packages/@aws-cdk/aws-eks/lib/managed-nodegroup.ts index ccb48e4687b7c..69dd8223edc09 100644 --- a/packages/@aws-cdk/aws-eks/lib/managed-nodegroup.ts +++ b/packages/@aws-cdk/aws-eks/lib/managed-nodegroup.ts @@ -1,6 +1,6 @@ import { InstanceType, ISecurityGroup, SubnetSelection } from '@aws-cdk/aws-ec2'; import { IRole, ManagedPolicy, Role, ServicePrincipal } from '@aws-cdk/aws-iam'; -import { IResource, Resource, Annotations } from '@aws-cdk/core'; +import { IResource, Resource, Annotations, withResolved } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { Cluster, ICluster } from './cluster'; import { CfnNodegroup } from './eks.generated'; @@ -321,12 +321,19 @@ export class Nodegroup extends Resource implements INodegroup { this.maxSize = props.maxSize ?? this.desiredSize; this.minSize = props.minSize ?? 1; - if (this.desiredSize > this.maxSize) { - throw new Error(`Desired capacity ${this.desiredSize} can't be greater than max size ${this.maxSize}`); - } - if (this.desiredSize < this.minSize) { - throw new Error(`Minimum capacity ${this.minSize} can't be greater than desired size ${this.desiredSize}`); - } + withResolved(this.desiredSize, this.maxSize, (desired, max) => { + if (desired === undefined) {return ;} + if (desired > max) { + throw new Error(`Desired capacity ${desired} can't be greater than max size ${max}`); + } + }); + + withResolved(this.desiredSize, this.minSize, (desired, min) => { + if (desired === undefined) {return ;} + if (desired < min) { + throw new Error(`Minimum capacity ${min} can't be greater than desired size ${desired}`); + } + }); if (props.launchTemplateSpec && props.diskSize) { // see - https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html diff --git a/packages/@aws-cdk/aws-eks/test/example.ssh-into-nodes.lit.ts b/packages/@aws-cdk/aws-eks/test/example.ssh-into-nodes.lit.ts index 9b1ea16a0fed3..63cedbca45c53 100644 --- a/packages/@aws-cdk/aws-eks/test/example.ssh-into-nodes.lit.ts +++ b/packages/@aws-cdk/aws-eks/test/example.ssh-into-nodes.lit.ts @@ -10,7 +10,7 @@ class EksClusterStack extends cdk.Stack { const cluster = new eks.Cluster(this, 'EKSCluster', { vpc, - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, }); /// !show diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-handlers-vpc.expected.json b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-handlers-vpc.expected.json index 8b901e2f20436..cdb744ed6be0e 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-handlers-vpc.expected.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-handlers-vpc.expected.json @@ -107,15 +107,15 @@ "EksAllHandlersInVpcStackDefaultVpcPublicSubnet1NATGatewayFD57AC6C": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "EksAllHandlersInVpcStackDefaultVpcPublicSubnet1SubnetEA05A5C7" + }, "AllocationId": { "Fn::GetAtt": [ "EksAllHandlersInVpcStackDefaultVpcPublicSubnet1EIP9380B54C", "AllocationId" ] }, - "SubnetId": { - "Ref": "EksAllHandlersInVpcStackDefaultVpcPublicSubnet1SubnetEA05A5C7" - }, "Tags": [ { "Key": "kubernetes.io/role/elb", @@ -220,15 +220,15 @@ "EksAllHandlersInVpcStackDefaultVpcPublicSubnet2NATGatewayEC0B8252": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "EksAllHandlersInVpcStackDefaultVpcPublicSubnet2Subnet8A9F7D50" + }, "AllocationId": { "Fn::GetAtt": [ "EksAllHandlersInVpcStackDefaultVpcPublicSubnet2EIP9186922F", "AllocationId" ] }, - "SubnetId": { - "Ref": "EksAllHandlersInVpcStackDefaultVpcPublicSubnet2Subnet8A9F7D50" - }, "Tags": [ { "Key": "kubernetes.io/role/elb", @@ -333,15 +333,15 @@ "EksAllHandlersInVpcStackDefaultVpcPublicSubnet3NATGateway7AE6F6B3": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "EksAllHandlersInVpcStackDefaultVpcPublicSubnet3SubnetB436275F" + }, "AllocationId": { "Fn::GetAtt": [ "EksAllHandlersInVpcStackDefaultVpcPublicSubnet3EIPBF5ED908", "AllocationId" ] }, - "SubnetId": { - "Ref": "EksAllHandlersInVpcStackDefaultVpcPublicSubnet3SubnetB436275F" - }, "Tags": [ { "Key": "kubernetes.io/role/elb", @@ -818,7 +818,7 @@ ] }, "Config": { - "version": "1.20", + "version": "1.21", "roleArn": { "Fn::GetAtt": [ "EksAllHandlersInVpcStackRoleC36F09F0", @@ -1196,7 +1196,7 @@ }, "/", { - "Ref": "AssetParameters8bdecc7d36d3a82fef0f8acd79a1b98980868636dd7e1e04ba2982b67127ca90S3BucketC889A64C" + "Ref": "AssetParametersa894c8b40c44a95ab449d327b83cd64ab07c12c1d95cbe2852f2e36a1780ef30S3Bucket3108034A" }, "/", { @@ -1206,7 +1206,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters8bdecc7d36d3a82fef0f8acd79a1b98980868636dd7e1e04ba2982b67127ca90S3VersionKeyB6157388" + "Ref": "AssetParametersa894c8b40c44a95ab449d327b83cd64ab07c12c1d95cbe2852f2e36a1780ef30S3VersionKey72F9CB08" } ] } @@ -1219,7 +1219,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters8bdecc7d36d3a82fef0f8acd79a1b98980868636dd7e1e04ba2982b67127ca90S3VersionKeyB6157388" + "Ref": "AssetParametersa894c8b40c44a95ab449d327b83cd64ab07c12c1d95cbe2852f2e36a1780ef30S3VersionKey72F9CB08" } ] } @@ -1268,11 +1268,11 @@ "referencetoawscdkekshandlersinvpctestAssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyF4C27F59Ref": { "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" }, - "referencetoawscdkekshandlersinvpctestAssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3Bucket68F78FB6Ref": { - "Ref": "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3Bucket6ABE1927" + "referencetoawscdkekshandlersinvpctestAssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3Bucket74F7CECDRef": { + "Ref": "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3BucketD4F52C82" }, - "referencetoawscdkekshandlersinvpctestAssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3VersionKeyCE91E7FDRef": { - "Ref": "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3VersionKeyF55A2EA9" + "referencetoawscdkekshandlersinvpctestAssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3VersionKeyE5A09AFARef": { + "Ref": "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3VersionKey9D243E8D" }, "referencetoawscdkekshandlersinvpctestAssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3Bucket9D7E9998Ref": { "Ref": "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1" @@ -1377,17 +1377,17 @@ "Type": "String", "Description": "Artifact hash for asset \"e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68\"" }, - "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3Bucket6ABE1927": { + "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3BucketD4F52C82": { "Type": "String", - "Description": "S3 bucket for asset \"844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0\"" + "Description": "S3 bucket for asset \"cd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793\"" }, - "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3VersionKeyF55A2EA9": { + "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3VersionKey9D243E8D": { "Type": "String", - "Description": "S3 key for asset version \"844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0\"" + "Description": "S3 key for asset version \"cd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793\"" }, - "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0ArtifactHash1D7A2D6E": { + "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793ArtifactHash42EBA5B2": { "Type": "String", - "Description": "Artifact hash for asset \"844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0\"" + "Description": "Artifact hash for asset \"cd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793\"" }, "AssetParameters7b7589d8284d359f531f595891e11720582fb63d0f0051cb08b5bfbcd6d60f60S3BucketE63A0899": { "Type": "String", @@ -1401,17 +1401,17 @@ "Type": "String", "Description": "Artifact hash for asset \"7b7589d8284d359f531f595891e11720582fb63d0f0051cb08b5bfbcd6d60f60\"" }, - "AssetParameters8bdecc7d36d3a82fef0f8acd79a1b98980868636dd7e1e04ba2982b67127ca90S3BucketC889A64C": { + "AssetParametersa894c8b40c44a95ab449d327b83cd64ab07c12c1d95cbe2852f2e36a1780ef30S3Bucket3108034A": { "Type": "String", - "Description": "S3 bucket for asset \"8bdecc7d36d3a82fef0f8acd79a1b98980868636dd7e1e04ba2982b67127ca90\"" + "Description": "S3 bucket for asset \"a894c8b40c44a95ab449d327b83cd64ab07c12c1d95cbe2852f2e36a1780ef30\"" }, - "AssetParameters8bdecc7d36d3a82fef0f8acd79a1b98980868636dd7e1e04ba2982b67127ca90S3VersionKeyB6157388": { + "AssetParametersa894c8b40c44a95ab449d327b83cd64ab07c12c1d95cbe2852f2e36a1780ef30S3VersionKey72F9CB08": { "Type": "String", - "Description": "S3 key for asset version \"8bdecc7d36d3a82fef0f8acd79a1b98980868636dd7e1e04ba2982b67127ca90\"" + "Description": "S3 key for asset version \"a894c8b40c44a95ab449d327b83cd64ab07c12c1d95cbe2852f2e36a1780ef30\"" }, - "AssetParameters8bdecc7d36d3a82fef0f8acd79a1b98980868636dd7e1e04ba2982b67127ca90ArtifactHash8A7D59E8": { + "AssetParametersa894c8b40c44a95ab449d327b83cd64ab07c12c1d95cbe2852f2e36a1780ef30ArtifactHash95BE80EE": { "Type": "String", - "Description": "Artifact hash for asset \"8bdecc7d36d3a82fef0f8acd79a1b98980868636dd7e1e04ba2982b67127ca90\"" + "Description": "Artifact hash for asset \"a894c8b40c44a95ab449d327b83cd64ab07c12c1d95cbe2852f2e36a1780ef30\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-handlers-vpc.ts b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-handlers-vpc.ts index c7434dd1f93ac..28a3bf35ece94 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-handlers-vpc.ts +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-handlers-vpc.ts @@ -3,7 +3,7 @@ import { App } from '@aws-cdk/core'; import * as eks from '../lib'; import { TestStack } from './util'; -const CLUSTER_VERSION = eks.KubernetesVersion.V1_20; +const CLUSTER_VERSION = eks.KubernetesVersion.V1_21; class EksAllHandlersInVpcStack extends TestStack { diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-private-endpoint.expected.json b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-private-endpoint.expected.json index 82a9699ed1d0b..1f5d852a6ec76 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-private-endpoint.expected.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-private-endpoint.expected.json @@ -135,15 +135,15 @@ "VpcPublicSubnet1NATGateway4D7517AA": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, "AllocationId": { "Fn::GetAtt": [ "VpcPublicSubnet1EIPD7E02669", "AllocationId" ] }, - "SubnetId": { - "Ref": "VpcPublicSubnet1Subnet5C2D37C4" - }, "Tags": [ { "Key": "kubernetes.io/role/elb", @@ -758,7 +758,7 @@ ] }, "Config": { - "version": "1.20", + "version": "1.21", "roleArn": { "Fn::GetAtt": [ "ClusterRoleFA261979", @@ -1117,7 +1117,7 @@ }, "/", { - "Ref": "AssetParameters5988c5261a097d0fc0f9ce78bb67db66f6ddf5c934fc58fa695dc27acaf6e69fS3Bucket5150D79C" + "Ref": "AssetParametersdfe35aaa6ae98d71e5f9b7ada4fe74c141cb56fbf3fba2bef43a5e4f26ad0ea6S3Bucket1FD74644" }, "/", { @@ -1127,7 +1127,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters5988c5261a097d0fc0f9ce78bb67db66f6ddf5c934fc58fa695dc27acaf6e69fS3VersionKey7F05152C" + "Ref": "AssetParametersdfe35aaa6ae98d71e5f9b7ada4fe74c141cb56fbf3fba2bef43a5e4f26ad0ea6S3VersionKey618B12D4" } ] } @@ -1140,7 +1140,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters5988c5261a097d0fc0f9ce78bb67db66f6ddf5c934fc58fa695dc27acaf6e69fS3VersionKey7F05152C" + "Ref": "AssetParametersdfe35aaa6ae98d71e5f9b7ada4fe74c141cb56fbf3fba2bef43a5e4f26ad0ea6S3VersionKey618B12D4" } ] } @@ -1189,11 +1189,11 @@ "referencetoawscdkeksclusterprivateendpointtestAssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKey69E4725CRef": { "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" }, - "referencetoawscdkeksclusterprivateendpointtestAssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3Bucket5323F34ARef": { - "Ref": "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3Bucket6ABE1927" + "referencetoawscdkeksclusterprivateendpointtestAssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3Bucket0DEFF6BBRef": { + "Ref": "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3BucketD4F52C82" }, - "referencetoawscdkeksclusterprivateendpointtestAssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3VersionKey548D79B4Ref": { - "Ref": "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3VersionKeyF55A2EA9" + "referencetoawscdkeksclusterprivateendpointtestAssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3VersionKeyE878793ARef": { + "Ref": "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3VersionKey9D243E8D" }, "referencetoawscdkeksclusterprivateendpointtestAssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3Bucket7DDAFC04Ref": { "Ref": "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1" @@ -1298,17 +1298,17 @@ "Type": "String", "Description": "Artifact hash for asset \"e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68\"" }, - "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3Bucket6ABE1927": { + "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3BucketD4F52C82": { "Type": "String", - "Description": "S3 bucket for asset \"844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0\"" + "Description": "S3 bucket for asset \"cd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793\"" }, - "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3VersionKeyF55A2EA9": { + "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3VersionKey9D243E8D": { "Type": "String", - "Description": "S3 key for asset version \"844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0\"" + "Description": "S3 key for asset version \"cd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793\"" }, - "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0ArtifactHash1D7A2D6E": { + "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793ArtifactHash42EBA5B2": { "Type": "String", - "Description": "Artifact hash for asset \"844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0\"" + "Description": "Artifact hash for asset \"cd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793\"" }, "AssetParametersf2b553bd53fbb997e6f23206daa298a3f8bfa7c9805c8c7c99155b4acc2d0cd6S3BucketFA2AD206": { "Type": "String", @@ -1322,17 +1322,17 @@ "Type": "String", "Description": "Artifact hash for asset \"f2b553bd53fbb997e6f23206daa298a3f8bfa7c9805c8c7c99155b4acc2d0cd6\"" }, - "AssetParameters5988c5261a097d0fc0f9ce78bb67db66f6ddf5c934fc58fa695dc27acaf6e69fS3Bucket5150D79C": { + "AssetParametersdfe35aaa6ae98d71e5f9b7ada4fe74c141cb56fbf3fba2bef43a5e4f26ad0ea6S3Bucket1FD74644": { "Type": "String", - "Description": "S3 bucket for asset \"5988c5261a097d0fc0f9ce78bb67db66f6ddf5c934fc58fa695dc27acaf6e69f\"" + "Description": "S3 bucket for asset \"dfe35aaa6ae98d71e5f9b7ada4fe74c141cb56fbf3fba2bef43a5e4f26ad0ea6\"" }, - "AssetParameters5988c5261a097d0fc0f9ce78bb67db66f6ddf5c934fc58fa695dc27acaf6e69fS3VersionKey7F05152C": { + "AssetParametersdfe35aaa6ae98d71e5f9b7ada4fe74c141cb56fbf3fba2bef43a5e4f26ad0ea6S3VersionKey618B12D4": { "Type": "String", - "Description": "S3 key for asset version \"5988c5261a097d0fc0f9ce78bb67db66f6ddf5c934fc58fa695dc27acaf6e69f\"" + "Description": "S3 key for asset version \"dfe35aaa6ae98d71e5f9b7ada4fe74c141cb56fbf3fba2bef43a5e4f26ad0ea6\"" }, - "AssetParameters5988c5261a097d0fc0f9ce78bb67db66f6ddf5c934fc58fa695dc27acaf6e69fArtifactHashEE0F431C": { + "AssetParametersdfe35aaa6ae98d71e5f9b7ada4fe74c141cb56fbf3fba2bef43a5e4f26ad0ea6ArtifactHash378913E5": { "Type": "String", - "Description": "Artifact hash for asset \"5988c5261a097d0fc0f9ce78bb67db66f6ddf5c934fc58fa695dc27acaf6e69f\"" + "Description": "Artifact hash for asset \"dfe35aaa6ae98d71e5f9b7ada4fe74c141cb56fbf3fba2bef43a5e4f26ad0ea6\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-private-endpoint.ts b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-private-endpoint.ts index ab25232b25882..1785bb43be903 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-private-endpoint.ts +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster-private-endpoint.ts @@ -5,7 +5,7 @@ import { App } from '@aws-cdk/core'; import * as eks from '../lib'; import { TestStack } from './util'; -const CLUSTER_VERSION = eks.KubernetesVersion.V1_20; +const CLUSTER_VERSION = eks.KubernetesVersion.V1_21; class EksClusterStack extends TestStack { diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json index f8185453880b9..1509f2e16bcf6 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.expected.json @@ -166,15 +166,15 @@ "VpcPublicSubnet1NATGateway4D7517AA": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "VpcPublicSubnet1Subnet5C2D37C4" + }, "AllocationId": { "Fn::GetAtt": [ "VpcPublicSubnet1EIPD7E02669", "AllocationId" ] }, - "SubnetId": { - "Ref": "VpcPublicSubnet1Subnet5C2D37C4" - }, "Tags": [ { "Key": "kubernetes.io/role/elb", @@ -919,7 +919,7 @@ ] }, "Config": { - "version": "1.20", + "version": "1.21", "roleArn": { "Fn::GetAtt": [ "ClusterRoleFA261979", @@ -1653,7 +1653,7 @@ "Type": "AWS::AutoScaling::LaunchConfiguration", "Properties": { "ImageId": { - "Ref": "SsmParameterValueawsserviceeksoptimizedami120amazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter" + "Ref": "SsmParameterValueawsserviceeksoptimizedami121amazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter" }, "InstanceType": "t2.medium", "IamInstanceProfile": { @@ -1978,7 +1978,7 @@ "Type": "AWS::AutoScaling::LaunchConfiguration", "Properties": { "ImageId": { - "Ref": "SsmParameterValueawsserviceeksoptimizedami120amazonlinux2arm64recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter" + "Ref": "SsmParameterValueawsserviceeksoptimizedami121amazonlinux2arm64recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter" }, "InstanceType": "m6g.medium", "IamInstanceProfile": { @@ -2303,7 +2303,7 @@ "Type": "AWS::AutoScaling::LaunchConfiguration", "Properties": { "ImageId": { - "Ref": "SsmParameterValueawsservicebottlerocketawsk8s120x8664latestimageidC96584B6F00A464EAD1953AFF4B05118Parameter" + "Ref": "SsmParameterValueawsservicebottlerocketawsk8s121x8664latestimageidC96584B6F00A464EAD1953AFF4B05118Parameter" }, "InstanceType": "t3.small", "IamInstanceProfile": { @@ -2628,7 +2628,7 @@ "Type": "AWS::AutoScaling::LaunchConfiguration", "Properties": { "ImageId": { - "Ref": "SsmParameterValueawsserviceeksoptimizedami120amazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter" + "Ref": "SsmParameterValueawsserviceeksoptimizedami121amazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter" }, "InstanceType": "t3.large", "IamInstanceProfile": { @@ -2986,7 +2986,7 @@ "Type": "AWS::AutoScaling::LaunchConfiguration", "Properties": { "ImageId": { - "Ref": "SsmParameterValueawsserviceeksoptimizedami120amazonlinux2gpurecommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter" + "Ref": "SsmParameterValueawsserviceeksoptimizedami121amazonlinux2gpurecommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter" }, "InstanceType": "inf1.2xlarge", "IamInstanceProfile": { @@ -3935,7 +3935,7 @@ }, "/", { - "Ref": "AssetParameterse334ff007b5126b62d66d4baac94004f4281dc2b0b0c4685ec93e330cb59e921S3Bucket706500B1" + "Ref": "AssetParameterscbbfa09db37e6a37ee43fbb48d73d4d96f216270558c932674a48e856763ce79S3Bucket2C7FA0F3" }, "/", { @@ -3945,7 +3945,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameterse334ff007b5126b62d66d4baac94004f4281dc2b0b0c4685ec93e330cb59e921S3VersionKeyAB3509E4" + "Ref": "AssetParameterscbbfa09db37e6a37ee43fbb48d73d4d96f216270558c932674a48e856763ce79S3VersionKey4D3075F9" } ] } @@ -3958,7 +3958,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameterse334ff007b5126b62d66d4baac94004f4281dc2b0b0c4685ec93e330cb59e921S3VersionKeyAB3509E4" + "Ref": "AssetParameterscbbfa09db37e6a37ee43fbb48d73d4d96f216270558c932674a48e856763ce79S3VersionKey4D3075F9" } ] } @@ -4007,11 +4007,11 @@ "referencetoawscdkeksclustertestAssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKey1C7C1F5FRef": { "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" }, - "referencetoawscdkeksclustertestAssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3Bucket8834EE90Ref": { - "Ref": "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3Bucket6ABE1927" + "referencetoawscdkeksclustertestAssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3BucketBEBB0185Ref": { + "Ref": "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3BucketD4F52C82" }, - "referencetoawscdkeksclustertestAssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3VersionKey1CADE360Ref": { - "Ref": "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3VersionKeyF55A2EA9" + "referencetoawscdkeksclustertestAssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3VersionKey8BEC8371Ref": { + "Ref": "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3VersionKey9D243E8D" }, "referencetoawscdkeksclustertestAssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3Bucket0815E7B5Ref": { "Ref": "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1" @@ -4029,7 +4029,7 @@ "Properties": { "LaunchTemplateData": { "ImageId": { - "Ref": "SsmParameterValueawsserviceeksoptimizedami120amazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter" + "Ref": "SsmParameterValueawsserviceeksoptimizedami121amazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter" }, "InstanceType": "t3.small", "UserData": { @@ -4706,17 +4706,17 @@ "Type": "String", "Description": "Artifact hash for asset \"e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68\"" }, - "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3Bucket6ABE1927": { + "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3BucketD4F52C82": { "Type": "String", - "Description": "S3 bucket for asset \"844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0\"" + "Description": "S3 bucket for asset \"cd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793\"" }, - "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3VersionKeyF55A2EA9": { + "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3VersionKey9D243E8D": { "Type": "String", - "Description": "S3 key for asset version \"844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0\"" + "Description": "S3 key for asset version \"cd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793\"" }, - "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0ArtifactHash1D7A2D6E": { + "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793ArtifactHash42EBA5B2": { "Type": "String", - "Description": "Artifact hash for asset \"844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0\"" + "Description": "Artifact hash for asset \"cd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793\"" }, "AssetParametersb7d38dc0eeb2c5d024919020e09d2590b68559eab4a5264c3b1aa7a429d1edd4S3BucketF7BC1777": { "Type": "String", @@ -4766,33 +4766,33 @@ "Type": "String", "Description": "Artifact hash for asset \"5598bd5ce38da10f7a9c6f8e54d4f50d7c0befd5309540ab64d64985236f2ef9\"" }, - "AssetParameterse334ff007b5126b62d66d4baac94004f4281dc2b0b0c4685ec93e330cb59e921S3Bucket706500B1": { + "AssetParameterscbbfa09db37e6a37ee43fbb48d73d4d96f216270558c932674a48e856763ce79S3Bucket2C7FA0F3": { "Type": "String", - "Description": "S3 bucket for asset \"e334ff007b5126b62d66d4baac94004f4281dc2b0b0c4685ec93e330cb59e921\"" + "Description": "S3 bucket for asset \"cbbfa09db37e6a37ee43fbb48d73d4d96f216270558c932674a48e856763ce79\"" }, - "AssetParameterse334ff007b5126b62d66d4baac94004f4281dc2b0b0c4685ec93e330cb59e921S3VersionKeyAB3509E4": { + "AssetParameterscbbfa09db37e6a37ee43fbb48d73d4d96f216270558c932674a48e856763ce79S3VersionKey4D3075F9": { "Type": "String", - "Description": "S3 key for asset version \"e334ff007b5126b62d66d4baac94004f4281dc2b0b0c4685ec93e330cb59e921\"" + "Description": "S3 key for asset version \"cbbfa09db37e6a37ee43fbb48d73d4d96f216270558c932674a48e856763ce79\"" }, - "AssetParameterse334ff007b5126b62d66d4baac94004f4281dc2b0b0c4685ec93e330cb59e921ArtifactHash31BE978F": { + "AssetParameterscbbfa09db37e6a37ee43fbb48d73d4d96f216270558c932674a48e856763ce79ArtifactHashF865E7E6": { "Type": "String", - "Description": "Artifact hash for asset \"e334ff007b5126b62d66d4baac94004f4281dc2b0b0c4685ec93e330cb59e921\"" + "Description": "Artifact hash for asset \"cbbfa09db37e6a37ee43fbb48d73d4d96f216270558c932674a48e856763ce79\"" }, - "SsmParameterValueawsserviceeksoptimizedami120amazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { + "SsmParameterValueawsserviceeksoptimizedami121amazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { "Type": "AWS::SSM::Parameter::Value", - "Default": "/aws/service/eks/optimized-ami/1.20/amazon-linux-2/recommended/image_id" + "Default": "/aws/service/eks/optimized-ami/1.21/amazon-linux-2/recommended/image_id" }, - "SsmParameterValueawsserviceeksoptimizedami120amazonlinux2arm64recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { + "SsmParameterValueawsserviceeksoptimizedami121amazonlinux2arm64recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { "Type": "AWS::SSM::Parameter::Value", - "Default": "/aws/service/eks/optimized-ami/1.20/amazon-linux-2-arm64/recommended/image_id" + "Default": "/aws/service/eks/optimized-ami/1.21/amazon-linux-2-arm64/recommended/image_id" }, - "SsmParameterValueawsservicebottlerocketawsk8s120x8664latestimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { + "SsmParameterValueawsservicebottlerocketawsk8s121x8664latestimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { "Type": "AWS::SSM::Parameter::Value", - "Default": "/aws/service/bottlerocket/aws-k8s-1.20/x86_64/latest/image_id" + "Default": "/aws/service/bottlerocket/aws-k8s-1.21/x86_64/latest/image_id" }, - "SsmParameterValueawsserviceeksoptimizedami120amazonlinux2gpurecommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { + "SsmParameterValueawsserviceeksoptimizedami121amazonlinux2gpurecommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { "Type": "AWS::SSM::Parameter::Value", - "Default": "/aws/service/eks/optimized-ami/1.20/amazon-linux-2-gpu/recommended/image_id" + "Default": "/aws/service/eks/optimized-ami/1.21/amazon-linux-2-gpu/recommended/image_id" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts index 04579ed71e922..c39c6edfbe9a4 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts @@ -35,7 +35,7 @@ class EksClusterStack extends TestStack { vpc: this.vpc, mastersRole, defaultCapacity: 2, - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, secretsEncryptionKey, }); @@ -188,7 +188,7 @@ class EksClusterStack extends TestStack { const lt = new ec2.CfnLaunchTemplate(this, 'LaunchTemplate', { launchTemplateData: { imageId: new eks.EksOptimizedImage({ - kubernetesVersion: eks.KubernetesVersion.V1_20.version, + kubernetesVersion: eks.KubernetesVersion.V1_21.version, }).getImage(this).imageId, instanceType: new ec2.InstanceType('t3.small').toString(), userData: Fn.base64(userData.render()), diff --git a/packages/@aws-cdk/aws-eks/test/integ.fargate-cluster.expected.json b/packages/@aws-cdk/aws-eks/test/integ.fargate-cluster.expected.json index 624ed521e7a6e..895978548bc4c 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.fargate-cluster.expected.json +++ b/packages/@aws-cdk/aws-eks/test/integ.fargate-cluster.expected.json @@ -107,15 +107,15 @@ "FargateClusterDefaultVpcPublicSubnet1NATGatewayEC4DEB51": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "FargateClusterDefaultVpcPublicSubnet1Subnet96AFDABC" + }, "AllocationId": { "Fn::GetAtt": [ "FargateClusterDefaultVpcPublicSubnet1EIP0093A4E0", "AllocationId" ] }, - "SubnetId": { - "Ref": "FargateClusterDefaultVpcPublicSubnet1Subnet96AFDABC" - }, "Tags": [ { "Key": "kubernetes.io/role/elb", @@ -220,15 +220,15 @@ "FargateClusterDefaultVpcPublicSubnet2NATGateway77D6A579": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "FargateClusterDefaultVpcPublicSubnet2Subnet92A9CC93" + }, "AllocationId": { "Fn::GetAtt": [ "FargateClusterDefaultVpcPublicSubnet2EIPA4C07B68", "AllocationId" ] }, - "SubnetId": { - "Ref": "FargateClusterDefaultVpcPublicSubnet2Subnet92A9CC93" - }, "Tags": [ { "Key": "kubernetes.io/role/elb", @@ -333,15 +333,15 @@ "FargateClusterDefaultVpcPublicSubnet3NATGateway0AAE540F": { "Type": "AWS::EC2::NatGateway", "Properties": { + "SubnetId": { + "Ref": "FargateClusterDefaultVpcPublicSubnet3SubnetB408ADA9" + }, "AllocationId": { "Fn::GetAtt": [ "FargateClusterDefaultVpcPublicSubnet3EIP46E028EF", "AllocationId" ] }, - "SubnetId": { - "Ref": "FargateClusterDefaultVpcPublicSubnet3SubnetB408ADA9" - }, "Tags": [ { "Key": "kubernetes.io/role/elb", @@ -828,7 +828,7 @@ ] }, "Config": { - "version": "1.20", + "version": "1.21", "roleArn": { "Fn::GetAtt": [ "FargateClusterRole8E36B33A", @@ -1194,7 +1194,7 @@ }, "/", { - "Ref": "AssetParameters66581105512a058e4f8b54fb8be68bf58cd32bfa5e87be3574d5e53eab943e49S3Bucket860C7E3D" + "Ref": "AssetParametersb8180d6aa1f3be56dff3c797e0e2b7efda1b899b5ce276930cbccf6ce61b6ff9S3BucketDEA37CED" }, "/", { @@ -1204,7 +1204,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters66581105512a058e4f8b54fb8be68bf58cd32bfa5e87be3574d5e53eab943e49S3VersionKey11F1F533" + "Ref": "AssetParametersb8180d6aa1f3be56dff3c797e0e2b7efda1b899b5ce276930cbccf6ce61b6ff9S3VersionKey2C845455" } ] } @@ -1217,7 +1217,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters66581105512a058e4f8b54fb8be68bf58cd32bfa5e87be3574d5e53eab943e49S3VersionKey11F1F533" + "Ref": "AssetParametersb8180d6aa1f3be56dff3c797e0e2b7efda1b899b5ce276930cbccf6ce61b6ff9S3VersionKey2C845455" } ] } @@ -1266,11 +1266,11 @@ "referencetoawscdkeksfargateclustertestAssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyB82BAEF8Ref": { "Ref": "AssetParameterse9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68S3VersionKeyE415415F" }, - "referencetoawscdkeksfargateclustertestAssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3Bucket9ED34BB4Ref": { - "Ref": "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3Bucket6ABE1927" + "referencetoawscdkeksfargateclustertestAssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3BucketC0936E6ARef": { + "Ref": "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3BucketD4F52C82" }, - "referencetoawscdkeksfargateclustertestAssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3VersionKeyFE6D1F78Ref": { - "Ref": "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3VersionKeyF55A2EA9" + "referencetoawscdkeksfargateclustertestAssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3VersionKey3CFF45CERef": { + "Ref": "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3VersionKey9D243E8D" }, "referencetoawscdkeksfargateclustertestAssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3Bucket8EEF0922Ref": { "Ref": "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1" @@ -1375,17 +1375,17 @@ "Type": "String", "Description": "Artifact hash for asset \"e9882ab123687399f934da0d45effe675ecc8ce13b40cb946f3e1d6141fe8d68\"" }, - "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3Bucket6ABE1927": { + "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3BucketD4F52C82": { "Type": "String", - "Description": "S3 bucket for asset \"844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0\"" + "Description": "S3 bucket for asset \"cd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793\"" }, - "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0S3VersionKeyF55A2EA9": { + "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793S3VersionKey9D243E8D": { "Type": "String", - "Description": "S3 key for asset version \"844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0\"" + "Description": "S3 key for asset version \"cd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793\"" }, - "AssetParameters844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0ArtifactHash1D7A2D6E": { + "AssetParameterscd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793ArtifactHash42EBA5B2": { "Type": "String", - "Description": "Artifact hash for asset \"844c1a4b13479b359ea0e607dccb4a04b73e22cf88cf9b64feed2c5f0de213c0\"" + "Description": "Artifact hash for asset \"cd15c6fb3a2eee6979f62b25e35a7df43d506bc62054eb8bf9355d1a71a3a793\"" }, "AssetParameters8f90971131eea6a356f7cfb4997f4b70bb577cf34d007550f5e28c342f6c47f7S3Bucket3C7D361B": { "Type": "String", @@ -1399,17 +1399,17 @@ "Type": "String", "Description": "Artifact hash for asset \"8f90971131eea6a356f7cfb4997f4b70bb577cf34d007550f5e28c342f6c47f7\"" }, - "AssetParameters66581105512a058e4f8b54fb8be68bf58cd32bfa5e87be3574d5e53eab943e49S3Bucket860C7E3D": { + "AssetParametersb8180d6aa1f3be56dff3c797e0e2b7efda1b899b5ce276930cbccf6ce61b6ff9S3BucketDEA37CED": { "Type": "String", - "Description": "S3 bucket for asset \"66581105512a058e4f8b54fb8be68bf58cd32bfa5e87be3574d5e53eab943e49\"" + "Description": "S3 bucket for asset \"b8180d6aa1f3be56dff3c797e0e2b7efda1b899b5ce276930cbccf6ce61b6ff9\"" }, - "AssetParameters66581105512a058e4f8b54fb8be68bf58cd32bfa5e87be3574d5e53eab943e49S3VersionKey11F1F533": { + "AssetParametersb8180d6aa1f3be56dff3c797e0e2b7efda1b899b5ce276930cbccf6ce61b6ff9S3VersionKey2C845455": { "Type": "String", - "Description": "S3 key for asset version \"66581105512a058e4f8b54fb8be68bf58cd32bfa5e87be3574d5e53eab943e49\"" + "Description": "S3 key for asset version \"b8180d6aa1f3be56dff3c797e0e2b7efda1b899b5ce276930cbccf6ce61b6ff9\"" }, - "AssetParameters66581105512a058e4f8b54fb8be68bf58cd32bfa5e87be3574d5e53eab943e49ArtifactHash660928E1": { + "AssetParametersb8180d6aa1f3be56dff3c797e0e2b7efda1b899b5ce276930cbccf6ce61b6ff9ArtifactHashAC123599": { "Type": "String", - "Description": "Artifact hash for asset \"66581105512a058e4f8b54fb8be68bf58cd32bfa5e87be3574d5e53eab943e49\"" + "Description": "Artifact hash for asset \"b8180d6aa1f3be56dff3c797e0e2b7efda1b899b5ce276930cbccf6ce61b6ff9\"" } } } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-eks/test/integ.fargate-cluster.ts b/packages/@aws-cdk/aws-eks/test/integ.fargate-cluster.ts index 8fe5666c76dc8..036454c19c1ce 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.fargate-cluster.ts +++ b/packages/@aws-cdk/aws-eks/test/integ.fargate-cluster.ts @@ -3,7 +3,7 @@ import { App } from '@aws-cdk/core'; import * as eks from '../lib'; import { TestStack } from './util'; -const CLUSTER_VERSION = eks.KubernetesVersion.V1_20; +const CLUSTER_VERSION = eks.KubernetesVersion.V1_21; class EksFargateClusterStack extends TestStack { diff --git a/packages/@aws-cdk/aws-eks/test/test.cluster.ts b/packages/@aws-cdk/aws-eks/test/test.cluster.ts index 61eef3a2bed13..3dac50ea1eac1 100644 --- a/packages/@aws-cdk/aws-eks/test/test.cluster.ts +++ b/packages/@aws-cdk/aws-eks/test/test.cluster.ts @@ -17,7 +17,7 @@ import { testFixture, testFixtureNoVpc } from './util'; /* eslint-disable max-len */ -const CLUSTER_VERSION = eks.KubernetesVersion.V1_20; +const CLUSTER_VERSION = eks.KubernetesVersion.V1_21; export = { @@ -85,7 +85,7 @@ export = { vpc: vpc, vpcSubnets: [{ subnetType: ec2.SubnetType.PUBLIC }, { subnetType: ec2.SubnetType.PRIVATE }], defaultCapacity: 0, - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, }), /cannot select multiple subnet groups/); test.done(); @@ -97,7 +97,7 @@ export = { vpc: vpc, vpcSubnets: [{ subnetType: ec2.SubnetType.PUBLIC }], defaultCapacity: 0, - version: eks.KubernetesVersion.V1_20, + version: eks.KubernetesVersion.V1_21, }); // THEN @@ -629,7 +629,7 @@ export = { expect(stack).to(haveResourceLike('Custom::AWSCDK-EKS-Cluster', { Config: { roleArn: { 'Fn::GetAtt': ['ClusterRoleFA261979', 'Arn'] }, - version: '1.20', + version: '1.21', resourcesVpcConfig: { securityGroupIds: [{ 'Fn::GetAtt': ['ClusterControlPlaneSecurityGroupD274242C', 'GroupId'] }], subnetIds: [ @@ -1462,7 +1462,7 @@ export = { const { app, stack } = testFixtureNoVpc(); // WHEN - new eks.EksOptimizedImage({ kubernetesVersion: '1.20' }).getImage(stack); + new eks.EksOptimizedImage({ kubernetesVersion: '1.21' }).getImage(stack); // THEN const assembly = app.synth(); @@ -1473,7 +1473,7 @@ export = { ), 'EKS STANDARD AMI should be in ssm parameters'); test.ok(Object.entries(parameters).some( ([k, v]) => k.startsWith('SsmParameterValueawsserviceeksoptimizedami') && - (v as any).Default.includes('/1.20/'), + (v as any).Default.includes('/1.21/'), ), 'kubernetesVersion should be in ssm parameters'); test.done(); }, @@ -1611,7 +1611,7 @@ export = { const { app, stack } = testFixtureNoVpc(); // WHEN - new BottleRocketImage({ kubernetesVersion: '1.20' }).getImage(stack); + new BottleRocketImage({ kubernetesVersion: '1.21' }).getImage(stack); // THEN const assembly = app.synth(); @@ -1622,7 +1622,7 @@ export = { ), 'BottleRocket AMI should be in ssm parameters'); test.ok(Object.entries(parameters).some( ([k, v]) => k.startsWith('SsmParameterValueawsservicebottlerocketaws') && - (v as any).Default.includes('/aws-k8s-1.20/'), + (v as any).Default.includes('/aws-k8s-1.21/'), ), 'kubernetesVersion should be in ssm parameters'); test.done(); }, @@ -1643,7 +1643,7 @@ export = { Config: { name: 'my-cluster-name', roleArn: { 'Fn::GetAtt': ['MyClusterRoleBA20FE72', 'Arn'] }, - version: '1.20', + version: '1.21', resourcesVpcConfig: { securityGroupIds: [ { 'Fn::GetAtt': ['MyClusterControlPlaneSecurityGroup6B658F79', 'GroupId'] }, diff --git a/packages/@aws-cdk/aws-eks/test/test.fargate.ts b/packages/@aws-cdk/aws-eks/test/test.fargate.ts index e21160386c556..e07eb2c8c4f59 100644 --- a/packages/@aws-cdk/aws-eks/test/test.fargate.ts +++ b/packages/@aws-cdk/aws-eks/test/test.fargate.ts @@ -7,7 +7,7 @@ import { Test } from 'nodeunit'; import * as eks from '../lib'; -const CLUSTER_VERSION = eks.KubernetesVersion.V1_20; +const CLUSTER_VERSION = eks.KubernetesVersion.V1_21; export = { 'can be added to a cluster'(test: Test) { diff --git a/packages/@aws-cdk/aws-eks/test/test.nodegroup.ts b/packages/@aws-cdk/aws-eks/test/test.nodegroup.ts index d2bb855cdf1b0..2ffab57cd1d01 100644 --- a/packages/@aws-cdk/aws-eks/test/test.nodegroup.ts +++ b/packages/@aws-cdk/aws-eks/test/test.nodegroup.ts @@ -7,7 +7,7 @@ import { testFixture } from './util'; /* eslint-disable max-len */ -const CLUSTER_VERSION = eks.KubernetesVersion.V1_20; +const CLUSTER_VERSION = eks.KubernetesVersion.V1_21; export = { @@ -598,6 +598,58 @@ export = { test.throws(() => cluster.addNodegroupCapacity('ng', { desiredSize: 2, minSize: 3 }), /Minimum capacity 3 can't be greater than desired size 2/); test.done(); }, + 'can set minSize , maxSize and DesiredSize'(test: Test) { + // GIVEN + const { stack, vpc } = testFixture(); + const cluster = new eks.Cluster(stack, 'Cluster', { + vpc, + defaultCapacity: 0, + version: CLUSTER_VERSION, + }); + // WHEN + new eks.Nodegroup(stack, 'NodeGroup', { + cluster: cluster, + minSize: 2, + maxSize: 6, + desiredSize: 4, + }); + // THEN + expect(stack).to(haveResourceLike('AWS::EKS::Nodegroup', { + ScalingConfig: { + MinSize: 2, + MaxSize: 6, + DesiredSize: 4, + }, + }, + )); + test.done(); + }, + 'validation is not performed when using Tokens'(test: Test) { + // GIVEN + const { stack, vpc } = testFixture(); + const cluster = new eks.Cluster(stack, 'Cluster', { + vpc, + defaultCapacity: 0, + version: CLUSTER_VERSION, + }); + // WHEN + new eks.Nodegroup(stack, 'NodeGroup', { + cluster: cluster, + minSize: cdk.Lazy.number({ produce: () => 5 }), + maxSize: cdk.Lazy.number({ produce: () => 1 }), + desiredSize: cdk.Lazy.number({ produce: () => 20 }), + }); + // THEN + expect(stack).to(haveResourceLike('AWS::EKS::Nodegroup', { + ScalingConfig: { + MinSize: 5, + MaxSize: 1, + DesiredSize: 20, + }, + }, + )); + test.done(); + }, 'create nodegroup correctly with launch template'(test: Test) { // GIVEN const { stack, vpc } = testFixture(); diff --git a/packages/@aws-cdk/aws-eks/test/test.user-data.ts b/packages/@aws-cdk/aws-eks/test/test.user-data.ts index ce5c61539c1a8..d7c32aff15c98 100644 --- a/packages/@aws-cdk/aws-eks/test/test.user-data.ts +++ b/packages/@aws-cdk/aws-eks/test/test.user-data.ts @@ -367,7 +367,7 @@ function newFixtures(spot = false) { const stack = new Stack(app, 'my-stack', { env: { region: 'us-west-33' } }); const vpc = new ec2.Vpc(stack, 'vpc'); const cluster = new Cluster(stack, 'cluster', { - version: KubernetesVersion.V1_20, + version: KubernetesVersion.V1_21, clusterName: 'my-cluster-name', vpc, }); diff --git a/packages/@aws-cdk/aws-elasticache/package.json b/packages/@aws-cdk/aws-elasticache/package.json index c0b500a42f22d..8a8a5a70c6c16 100644 --- a/packages/@aws-cdk/aws-elasticache/package.json +++ b/packages/@aws-cdk/aws-elasticache/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-elasticache/test/elasticache.test.ts b/packages/@aws-cdk/aws-elasticache/test/elasticache.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-elasticache/test/elasticache.test.ts +++ b/packages/@aws-cdk/aws-elasticache/test/elasticache.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-elasticbeanstalk/package.json b/packages/@aws-cdk/aws-elasticbeanstalk/package.json index 80d5033ecc931..a9bde94b14589 100644 --- a/packages/@aws-cdk/aws-elasticbeanstalk/package.json +++ b/packages/@aws-cdk/aws-elasticbeanstalk/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-elasticbeanstalk/test/elasticbeanstalk.test.ts b/packages/@aws-cdk/aws-elasticbeanstalk/test/elasticbeanstalk.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-elasticbeanstalk/test/elasticbeanstalk.test.ts +++ b/packages/@aws-cdk/aws-elasticbeanstalk/test/elasticbeanstalk.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener-rule.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener-rule.ts index 7a3bb91cb3457..e71ccbd5c74de 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener-rule.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/lib/alb/application-listener-rule.ts @@ -229,7 +229,7 @@ export class ApplicationListenerRule extends CoreConstruct { throw new Error(`'${providedActions}' specified together, specify only one`); } - if (props.priority <= 0) { + if (!cdk.Token.isUnresolved(props.priority) && props.priority <= 0) { throw new Error('Priority must have value greater than or equal to 1'); } diff --git a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/listener.test.ts b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/listener.test.ts index 6de716df113e2..fffc6e365bcea 100644 --- a/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/listener.test.ts +++ b/packages/@aws-cdk/aws-elasticloadbalancingv2/test/alb/listener.test.ts @@ -987,6 +987,28 @@ describe('tests', () => { })).toThrowError('Priority must have value greater than or equal to 1'); }); + test('Accepts unresolved priority', () => { + // GIVEN + const stack = new cdk.Stack(); + const vpc = new ec2.Vpc(stack, 'VPC'); + const lb = new elbv2.ApplicationLoadBalancer(stack, 'LoadBalancer', { + vpc, + }); + const listener = lb.addListener('Listener', { + port: 80, + }); + + // THEN + expect(() => new elbv2.ApplicationListenerRule(stack, 'Rule', { + listener, + priority: new cdk.CfnParameter(stack, 'PriorityParam', { type: 'Number' }).valueAsNumber, + pathPattern: '/hello', + fixedResponse: { + statusCode: '500', + }, + })).not.toThrowError('Priority must have value greater than or equal to 1'); + }); + test('Throws when specifying both target groups and redirect response', () => { // GIVEN const stack = new cdk.Stack(); diff --git a/packages/@aws-cdk/aws-emr/package.json b/packages/@aws-cdk/aws-emr/package.json index f216a69bdf839..337790cd07b03 100644 --- a/packages/@aws-cdk/aws-emr/package.json +++ b/packages/@aws-cdk/aws-emr/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-emr/test/emr.test.ts b/packages/@aws-cdk/aws-emr/test/emr.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-emr/test/emr.test.ts +++ b/packages/@aws-cdk/aws-emr/test/emr.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-emrcontainers/package.json b/packages/@aws-cdk/aws-emrcontainers/package.json index bf2a7fbe9a627..8ea1659c08e57 100644 --- a/packages/@aws-cdk/aws-emrcontainers/package.json +++ b/packages/@aws-cdk/aws-emrcontainers/package.json @@ -81,7 +81,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-emrcontainers/test/emrcontainers.test.ts b/packages/@aws-cdk/aws-emrcontainers/test/emrcontainers.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-emrcontainers/test/emrcontainers.test.ts +++ b/packages/@aws-cdk/aws-emrcontainers/test/emrcontainers.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-eventschemas/package.json b/packages/@aws-cdk/aws-eventschemas/package.json index 0e16baa12d4f4..2d9ea8b2602d6 100644 --- a/packages/@aws-cdk/aws-eventschemas/package.json +++ b/packages/@aws-cdk/aws-eventschemas/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-eventschemas/test/eventschemas.test.ts b/packages/@aws-cdk/aws-eventschemas/test/eventschemas.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-eventschemas/test/eventschemas.test.ts +++ b/packages/@aws-cdk/aws-eventschemas/test/eventschemas.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-finspace/package.json b/packages/@aws-cdk/aws-finspace/package.json index 8b70bc5443455..1886725b8d68e 100644 --- a/packages/@aws-cdk/aws-finspace/package.json +++ b/packages/@aws-cdk/aws-finspace/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-finspace/test/finspace.test.ts b/packages/@aws-cdk/aws-finspace/test/finspace.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-finspace/test/finspace.test.ts +++ b/packages/@aws-cdk/aws-finspace/test/finspace.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-fis/package.json b/packages/@aws-cdk/aws-fis/package.json index 7412ed44a10fc..ba17edd8f186f 100644 --- a/packages/@aws-cdk/aws-fis/package.json +++ b/packages/@aws-cdk/aws-fis/package.json @@ -81,7 +81,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-fis/test/fis.test.ts b/packages/@aws-cdk/aws-fis/test/fis.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-fis/test/fis.test.ts +++ b/packages/@aws-cdk/aws-fis/test/fis.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-fms/package.json b/packages/@aws-cdk/aws-fms/package.json index 5ed725a88b4cc..d9056b520b7f1 100644 --- a/packages/@aws-cdk/aws-fms/package.json +++ b/packages/@aws-cdk/aws-fms/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-fms/test/fms.test.ts b/packages/@aws-cdk/aws-fms/test/fms.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-fms/test/fms.test.ts +++ b/packages/@aws-cdk/aws-fms/test/fms.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-frauddetector/package.json b/packages/@aws-cdk/aws-frauddetector/package.json index fbf05f78a7640..84cfc1ce40738 100644 --- a/packages/@aws-cdk/aws-frauddetector/package.json +++ b/packages/@aws-cdk/aws-frauddetector/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-frauddetector/test/frauddetector.test.ts b/packages/@aws-cdk/aws-frauddetector/test/frauddetector.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-frauddetector/test/frauddetector.test.ts +++ b/packages/@aws-cdk/aws-frauddetector/test/frauddetector.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-gamelift/package.json b/packages/@aws-cdk/aws-gamelift/package.json index 07774ebf11293..299bf7e8ca563 100644 --- a/packages/@aws-cdk/aws-gamelift/package.json +++ b/packages/@aws-cdk/aws-gamelift/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-gamelift/test/gamelift.test.ts b/packages/@aws-cdk/aws-gamelift/test/gamelift.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-gamelift/test/gamelift.test.ts +++ b/packages/@aws-cdk/aws-gamelift/test/gamelift.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-glue/package.json b/packages/@aws-cdk/aws-glue/package.json index f489c1955478e..5f11a3895db92 100644 --- a/packages/@aws-cdk/aws-glue/package.json +++ b/packages/@aws-cdk/aws-glue/package.json @@ -74,14 +74,14 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", + "@aws-cdk/assertions": "0.0.0", "@aws-cdk/cx-api": "0.0.0", "@types/nodeunit": "^0.0.32", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", "jest": "^26.6.3", - "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/aws-ec2": "0.0.0", diff --git a/packages/@aws-cdk/aws-glue/test/connection.test.ts b/packages/@aws-cdk/aws-glue/test/connection.test.ts index c61cc6197130d..b4fdaa2988cde 100644 --- a/packages/@aws-cdk/aws-glue/test/connection.test.ts +++ b/packages/@aws-cdk/aws-glue/test/connection.test.ts @@ -1,7 +1,6 @@ -import * as cdkassert from '@aws-cdk/assert-internal'; +import { Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as cdk from '@aws-cdk/core'; -import '@aws-cdk/assert-internal/jest'; import * as glue from '../lib'; test('a connection with connection properties', () => { @@ -15,7 +14,7 @@ test('a connection with connection properties', () => { }, }); - cdkassert.expect(stack).to(cdkassert.haveResource('AWS::Glue::Connection', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Connection', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -27,7 +26,7 @@ test('a connection with connection properties', () => { }, ConnectionType: 'JDBC', }, - })); + }); }); test('a connection with a subnet and security group', () => { @@ -43,7 +42,7 @@ test('a connection with a subnet and security group', () => { subnet, }); - cdkassert.expect(stack).to(cdkassert.haveResource('AWS::Glue::Connection', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Connection', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -55,7 +54,7 @@ test('a connection with a subnet and security group', () => { SecurityGroupIdList: ['sgId'], }, }, - })); + }); }); test('a connection with a name and description', () => { @@ -66,7 +65,7 @@ test('a connection with a name and description', () => { type: glue.ConnectionType.NETWORK, }); - cdkassert.expect(stack).to(cdkassert.haveResource('AWS::Glue::Connection', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Connection', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -75,7 +74,7 @@ test('a connection with a name and description', () => { Name: 'name', Description: 'description', }, - })); + }); }); test('a connection with a custom type', () => { @@ -86,7 +85,7 @@ test('a connection with a custom type', () => { type: new glue.ConnectionType('CUSTOM_TYPE'), }); - cdkassert.expect(stack).to(cdkassert.haveResource('AWS::Glue::Connection', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Connection', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -95,7 +94,7 @@ test('a connection with a custom type', () => { Name: 'name', Description: 'description', }, - })); + }); }); test('a connection with match criteria', () => { @@ -105,7 +104,7 @@ test('a connection with match criteria', () => { matchCriteria: ['c1', 'c2'], }); - cdkassert.expect(stack).to(cdkassert.haveResource('AWS::Glue::Connection', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Connection', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -113,7 +112,7 @@ test('a connection with match criteria', () => { ConnectionType: 'NETWORK', MatchCriteria: ['c1', 'c2'], }, - })); + }); }); test('addProperty', () => { @@ -123,7 +122,7 @@ test('addProperty', () => { }); connection.addProperty('SomeKey', 'SomeValue'); - cdkassert.expect(stack).to(cdkassert.haveResource('AWS::Glue::Connection', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Connection', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -133,7 +132,7 @@ test('addProperty', () => { SomeKey: 'SomeValue', }, }, - })); + }); }); test('fromConnectionName', () => { diff --git a/packages/@aws-cdk/aws-glue/test/database.test.ts b/packages/@aws-cdk/aws-glue/test/database.test.ts index f5ad6461ee190..6c8171df3547c 100644 --- a/packages/@aws-cdk/aws-glue/test/database.test.ts +++ b/packages/@aws-cdk/aws-glue/test/database.test.ts @@ -1,6 +1,4 @@ -import { deepEqual, throws } from 'assert'; -import { expect } from '@aws-cdk/assert-internal'; -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { Stack } from '@aws-cdk/core'; import * as glue from '../lib'; @@ -11,7 +9,7 @@ test('default database does not create a bucket', () => { databaseName: 'test_database', }); - expect(stack).toMatch({ + Template.fromStack(stack).templateMatches({ Resources: { DatabaseB269D8BB: { Type: 'AWS::Glue::Database', @@ -37,7 +35,7 @@ test('explicit locationURI', () => { locationUri: 's3://my-uri/', }); - expect(stack).toMatch({ + Template.fromStack(stack).templateMatches({ Resources: { DatabaseB269D8BB: { Type: 'AWS::Glue::Database', @@ -64,31 +62,31 @@ test('fromDatabase', () => { const database = glue.Database.fromDatabaseArn(stack, 'import', 'arn:aws:glue:us-east-1:123456789012:database/db1'); // THEN - deepEqual(database.databaseArn, 'arn:aws:glue:us-east-1:123456789012:database/db1'); - deepEqual(database.databaseName, 'db1'); - deepEqual(stack.resolve(database.catalogArn), { + expect(database.databaseArn).toEqual('arn:aws:glue:us-east-1:123456789012:database/db1'); + expect(database.databaseName).toEqual('db1'); + expect(stack.resolve(database.catalogArn)).toEqual({ 'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':glue:', { Ref: 'AWS::Region' }, ':', { Ref: 'AWS::AccountId' }, ':catalog']], }); - deepEqual(stack.resolve(database.catalogId), { Ref: 'AWS::AccountId' }); + expect(stack.resolve(database.catalogId)).toEqual({ Ref: 'AWS::AccountId' }); }); test('locationUri length must be >= 1', () => { const stack = new Stack(); - throws(() => + expect(() => new glue.Database(stack, 'Database', { databaseName: 'test_database', locationUri: '', }), - ); + ).toThrow(); }); test('locationUri length must be <= 1024', () => { const stack = new Stack(); - throws(() => + expect(() => new glue.Database(stack, 'Database', { databaseName: 'test_database', locationUri: 'a'.repeat(1025), }), - ); + ).toThrow(); }); diff --git a/packages/@aws-cdk/aws-glue/test/schema.test.ts b/packages/@aws-cdk/aws-glue/test/schema.test.ts index 2155655e27e6d..dcb6b731a0e27 100644 --- a/packages/@aws-cdk/aws-glue/test/schema.test.ts +++ b/packages/@aws-cdk/aws-glue/test/schema.test.ts @@ -1,126 +1,124 @@ -import '@aws-cdk/assert-internal/jest'; -import { doesNotThrow, equal, throws } from 'assert'; import { Schema } from '../lib'; test('boolean type', () => { - equal(Schema.BOOLEAN.inputString, 'boolean'); - equal(Schema.BOOLEAN.isPrimitive, true); + expect(Schema.BOOLEAN.inputString).toEqual('boolean'); + expect(Schema.BOOLEAN.isPrimitive).toEqual(true); }); test('binary type', () => { - equal(Schema.BINARY.inputString, 'binary'); - equal(Schema.BINARY.isPrimitive, true); + expect(Schema.BINARY.inputString).toEqual('binary'); + expect(Schema.BINARY.isPrimitive).toEqual(true); }); test('bigint type', () => { - equal(Schema.BIG_INT.inputString, 'bigint'); - equal(Schema.BIG_INT.isPrimitive, true); + expect(Schema.BIG_INT.inputString).toEqual('bigint'); + expect(Schema.BIG_INT.isPrimitive).toEqual(true); }); test('double type', () => { - equal(Schema.DOUBLE.inputString, 'double'); - equal(Schema.DOUBLE.isPrimitive, true); + expect(Schema.DOUBLE.inputString).toEqual('double'); + expect(Schema.DOUBLE.isPrimitive).toEqual(true); }); test('float type', () => { - equal(Schema.FLOAT.inputString, 'float'); - equal(Schema.FLOAT.isPrimitive, true); + expect(Schema.FLOAT.inputString).toEqual('float'); + expect(Schema.FLOAT.isPrimitive).toEqual(true); }); test('integer type', () => { - equal(Schema.INTEGER.inputString, 'int'); - equal(Schema.INTEGER.isPrimitive, true); + expect(Schema.INTEGER.inputString).toEqual('int'); + expect(Schema.INTEGER.isPrimitive).toEqual(true); }); test('smallint type', () => { - equal(Schema.SMALL_INT.inputString, 'smallint'); - equal(Schema.SMALL_INT.isPrimitive, true); + expect(Schema.SMALL_INT.inputString).toEqual('smallint'); + expect(Schema.SMALL_INT.isPrimitive).toEqual(true); }); test('tinyint type', () => { - equal(Schema.TINY_INT.inputString, 'tinyint'); - equal(Schema.TINY_INT.isPrimitive, true); + expect(Schema.TINY_INT.inputString).toEqual('tinyint'); + expect(Schema.TINY_INT.isPrimitive).toEqual(true); }); test('decimal type', () => { - equal(Schema.decimal(16).inputString, 'decimal(16)'); - equal(Schema.decimal(16, 1).inputString, 'decimal(16,1)'); - equal(Schema.decimal(16).isPrimitive, true); - equal(Schema.decimal(16, 1).isPrimitive, true); + expect(Schema.decimal(16).inputString).toEqual('decimal(16)'); + expect(Schema.decimal(16, 1).inputString).toEqual('decimal(16,1)'); + expect(Schema.decimal(16).isPrimitive).toEqual(true); + expect(Schema.decimal(16, 1).isPrimitive).toEqual(true); }); // TODO: decimal bounds test('date type', () => { - equal(Schema.DATE.inputString, 'date'); - equal(Schema.DATE.isPrimitive, true); + expect(Schema.DATE.inputString).toEqual('date'); + expect(Schema.DATE.isPrimitive).toEqual(true); }); test('timestamp type', () => { - equal(Schema.TIMESTAMP.inputString, 'timestamp'); - equal(Schema.TIMESTAMP.isPrimitive, true); + expect(Schema.TIMESTAMP.inputString).toEqual('timestamp'); + expect(Schema.TIMESTAMP.isPrimitive).toEqual(true); }); test('string type', () => { - equal(Schema.STRING.inputString, 'string'); - equal(Schema.STRING.isPrimitive, true); + expect(Schema.STRING.inputString).toEqual('string'); + expect(Schema.STRING.isPrimitive).toEqual(true); }); test('char type', () => { - equal(Schema.char(1).inputString, 'char(1)'); - equal(Schema.char(1).isPrimitive, true); + expect(Schema.char(1).inputString).toEqual('char(1)'); + expect(Schema.char(1).isPrimitive).toEqual(true); }); test('char length must be test(at least 1', () => { - doesNotThrow(() => Schema.char(1)); - throws(() => Schema.char(0)); - throws(() => Schema.char(-1)); + expect(() => Schema.char(1)).not.toThrow(); + expect(() => Schema.char(0)).toThrow(); + expect(() => Schema.char(-1)).toThrow(); }); test('char length must test(be <= 255', () => { - doesNotThrow(() => Schema.char(255)); - throws(() => Schema.char(256)); + expect(() => Schema.char(255)).not.toThrow(); + expect(() => Schema.char(256)).toThrow(); }); test('varchar type', () => { - equal(Schema.varchar(1).inputString, 'varchar(1)'); - equal(Schema.varchar(1).isPrimitive, true); + expect(Schema.varchar(1).inputString).toEqual('varchar(1)'); + expect(Schema.varchar(1).isPrimitive).toEqual(true); }); test('varchar length must be test(at least 1', () => { - doesNotThrow(() => Schema.varchar(1)); - throws(() => Schema.varchar(0)); - throws(() => Schema.varchar(-1)); + expect(() => Schema.varchar(1)).not.toThrow(); + expect(() => Schema.varchar(0)).toThrow(); + expect(() => Schema.varchar(-1)).toThrow(); }); test('varchar length must test(be <= 65535', () => { - doesNotThrow(() => Schema.varchar(65535)); - throws(() => Schema.varchar(65536)); + expect(() => Schema.varchar(65535)).not.toThrow(); + expect(() => Schema.varchar(65536)).toThrow(); }); test('test(array', () => { const type = Schema.array(Schema.STRING); - equal(type.inputString, 'array'); - equal(type.isPrimitive, false); + expect(type.inputString).toEqual('array'); + expect(type.isPrimitive).toEqual(false); }); test('array', () => { const type = Schema.array(Schema.char(1)); - equal(type.inputString, 'array'); - equal(type.isPrimitive, false); + expect(type.inputString).toEqual('array'); + expect(type.isPrimitive).toEqual(false); }); test('test(array', () => { const type = Schema.array( Schema.array(Schema.STRING)); - equal(type.inputString, 'array>'); - equal(type.isPrimitive, false); + expect(type.inputString).toEqual('array>'); + expect(type.isPrimitive).toEqual(false); }); test('test(array', () => { const type = Schema.array( Schema.map(Schema.STRING, Schema.STRING)); - equal(type.inputString, 'array>'); - equal(type.isPrimitive, false); + expect(type.inputString).toEqual('array>'); + expect(type.isPrimitive).toEqual(false); }); test('test(array', () => { @@ -129,8 +127,8 @@ test('test(array', () => { name: 'key', type: Schema.STRING, }])); - equal(type.inputString, 'array>'); - equal(type.isPrimitive, false); + expect(type.inputString).toEqual('array>'); + expect(type.isPrimitive).toEqual(false); }); test('map', () => { @@ -138,8 +136,8 @@ test('map', () => { Schema.STRING, Schema.STRING, ); - equal(type.inputString, 'map'); - equal(type.isPrimitive, false); + expect(type.inputString).toEqual('map'); + expect(type.isPrimitive).toEqual(false); }); test('map', () => { @@ -147,8 +145,8 @@ test('map', () => { Schema.INTEGER, Schema.STRING, ); - equal(type.inputString, 'map'); - equal(type.isPrimitive, false); + expect(type.inputString).toEqual('map'); + expect(type.isPrimitive).toEqual(false); }); test('map', () => { @@ -156,8 +154,8 @@ test('map', () => { Schema.char(1), Schema.char(1), ); - equal(type.inputString, 'map'); - equal(type.isPrimitive, false); + expect(type.inputString).toEqual('map'); + expect(type.isPrimitive).toEqual(false); }); test('map', () => { @@ -165,8 +163,8 @@ test('map', () => { Schema.char(1), Schema.array(Schema.STRING), ); - equal(type.inputString, 'map>'); - equal(type.isPrimitive, false); + expect(type.inputString).toEqual('map>'); + expect(type.isPrimitive).toEqual(false); }); test('map', () => { @@ -176,8 +174,8 @@ test('map', () => { Schema.STRING, Schema.STRING), ); - equal(type.inputString, 'map>'); - equal(type.isPrimitive, false); + expect(type.inputString).toEqual('map>'); + expect(type.isPrimitive).toEqual(false); }); test('map', () => { @@ -188,26 +186,26 @@ test('map', () => { type: Schema.STRING, }]), ); - equal(type.inputString, 'map>'); - equal(type.isPrimitive, false); + expect(type.inputString).toEqual('map>'); + expect(type.isPrimitive).toEqual(false); }); test('map throws if keyType is test(non-primitive', () => { - throws(() => Schema.map( + expect(() => Schema.map( Schema.array(Schema.STRING), Schema.STRING, - )); - throws(() => Schema.map( + )).toThrow(); + expect(() => Schema.map( Schema.map(Schema.STRING, Schema.STRING), Schema.STRING, - )); - throws(() => Schema.map( + )).toThrow(); + expect(() => Schema.map( Schema.struct([{ name: 'key', type: Schema.STRING, }]), Schema.STRING, - )); + )).toThrow(); }); test('struct type', () => { @@ -233,9 +231,9 @@ test('struct type', () => { }]), }]); - equal(type.isPrimitive, false); - equal( - type.inputString, + expect(type.isPrimitive).toEqual(false); + expect(type.inputString).toEqual( // eslint-disable-next-line max-len - 'struct,map:map,nested_struct:struct>'); + 'struct,map:map,nested_struct:struct>', + ); }); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-glue/test/security-configuration.test.ts b/packages/@aws-cdk/aws-glue/test/security-configuration.test.ts index ce89c393e5301..ca42a4eb53453 100644 --- a/packages/@aws-cdk/aws-glue/test/security-configuration.test.ts +++ b/packages/@aws-cdk/aws-glue/test/security-configuration.test.ts @@ -1,7 +1,6 @@ -import * as cdkassert from '@aws-cdk/assert-internal'; +import { Template } from '@aws-cdk/assertions'; import * as kms from '@aws-cdk/aws-kms'; import * as cdk from '@aws-cdk/core'; -import '@aws-cdk/assert-internal/jest'; import * as glue from '../lib'; test('throws when a security configuration has no encryption config', () => { @@ -29,7 +28,7 @@ test('a security configuration with encryption configuration requiring kms key a expect(securityConfiguration.jobBookmarksEncryptionKey).toBeUndefined(); expect(securityConfiguration.s3EncryptionKey).toBeUndefined(); - cdkassert.expect(stack).to(cdkassert.haveResource('AWS::Glue::SecurityConfiguration', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::SecurityConfiguration', { Name: 'name', EncryptionConfiguration: { CloudWatchEncryption: { @@ -37,7 +36,7 @@ test('a security configuration with encryption configuration requiring kms key a KmsKeyArn: keyArn, }, }, - })); + }); }); test('a security configuration with an encryption configuration requiring kms key but not providing an explicit one', () => { @@ -54,9 +53,9 @@ test('a security configuration with an encryption configuration requiring kms ke expect(securityConfiguration.jobBookmarksEncryptionKey).toBeUndefined(); expect(securityConfiguration.s3EncryptionKey).toBeUndefined(); - cdkassert.expect(stack).to(cdkassert.haveResource('AWS::KMS::Key')); + Template.fromStack(stack).resourceCountIs('AWS::KMS::Key', 1); - cdkassert.expect(stack).to(cdkassert.haveResource('AWS::Glue::SecurityConfiguration', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::SecurityConfiguration', { Name: 'name', EncryptionConfiguration: { CloudWatchEncryption: { @@ -64,7 +63,7 @@ test('a security configuration with an encryption configuration requiring kms ke KmsKeyArn: stack.resolve(securityConfiguration.cloudWatchEncryptionKey?.keyArn), }, }, - })); + }); }); test('a security configuration with all encryption configs and mixed kms key inputs', () => { @@ -90,9 +89,9 @@ test('a security configuration with all encryption configs and mixed kms key inp expect(securityConfiguration.jobBookmarksEncryptionKey?.keyArn).toEqual(keyArn); expect(securityConfiguration.s3EncryptionKey).toBeUndefined(); - cdkassert.expect(stack).to(cdkassert.haveResource('AWS::KMS::Key')); + Template.fromStack(stack).resourceCountIs('AWS::KMS::Key', 1); - cdkassert.expect(stack).to(cdkassert.haveResource('AWS::Glue::SecurityConfiguration', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::SecurityConfiguration', { Name: 'name', EncryptionConfiguration: { CloudWatchEncryption: { @@ -109,7 +108,7 @@ test('a security configuration with all encryption configs and mixed kms key inp S3EncryptionMode: 'SSE-S3', }], }, - })); + }); }); test('fromSecurityConfigurationName', () => { diff --git a/packages/@aws-cdk/aws-glue/test/table.test.ts b/packages/@aws-cdk/aws-glue/test/table.test.ts index 084eaa67ab564..fbb1424f766c1 100644 --- a/packages/@aws-cdk/aws-glue/test/table.test.ts +++ b/packages/@aws-cdk/aws-glue/test/table.test.ts @@ -1,6 +1,4 @@ -import { deepEqual, doesNotThrow, equal, notEqual, ok } from 'assert'; -import { expect as cdkExpect, haveResource, ResourcePart } from '@aws-cdk/assert-internal'; -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; import * as s3 from '@aws-cdk/aws-s3'; @@ -28,15 +26,15 @@ test('unpartitioned JSON table', () => { }], dataFormat: glue.DataFormat.JSON, }); - equal(table.encryption, glue.TableEncryption.UNENCRYPTED); + expect(table.encryption).toEqual(glue.TableEncryption.UNENCRYPTED); - cdkExpect(tableStack).to(haveResource('AWS::S3::Bucket', { + Template.fromStack(tableStack).hasResource('AWS::S3::Bucket', { Type: 'AWS::S3::Bucket', DeletionPolicy: 'Retain', UpdateReplacePolicy: 'Retain', - }, ResourcePart.CompleteDefinition)); + }); - cdkExpect(tableStack).to(haveResource('AWS::Glue::Table', { + Template.fromStack(tableStack).hasResourceProperties('AWS::Glue::Table', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -79,7 +77,7 @@ test('unpartitioned JSON table', () => { }, TableType: 'EXTERNAL_TABLE', }, - })); + }); }); @@ -104,11 +102,11 @@ test('partitioned JSON table', () => { }], dataFormat: glue.DataFormat.JSON, }); - equal(table.encryption, glue.TableEncryption.UNENCRYPTED); - equal(table.encryptionKey, undefined); - equal(table.bucket.encryptionKey, undefined); + expect(table.encryption).toEqual(glue.TableEncryption.UNENCRYPTED); + expect(table.encryptionKey).toEqual(undefined); + expect(table.bucket.encryptionKey).toEqual(undefined); - cdkExpect(tableStack).to(haveResource('AWS::Glue::Table', { + Template.fromStack(tableStack).hasResourceProperties('AWS::Glue::Table', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -157,7 +155,7 @@ test('partitioned JSON table', () => { }, TableType: 'EXTERNAL_TABLE', }, - })); + }); }); @@ -177,10 +175,10 @@ test('compressed table', () => { compressed: true, dataFormat: glue.DataFormat.JSON, }); - equal(table.encryptionKey, undefined); - equal(table.bucket.encryptionKey, undefined); + expect(table.encryptionKey).toEqual(undefined); + expect(table.bucket.encryptionKey).toEqual(undefined); - cdkExpect(stack).to(haveResource('AWS::Glue::Table', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Table', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -223,7 +221,7 @@ test('compressed table', () => { }, TableType: 'EXTERNAL_TABLE', }, - })); + }); }); @@ -247,7 +245,7 @@ test('table.node.defaultChild', () => { }); // THEN - ok(table.node.defaultChild instanceof glue.CfnTable); + expect(table.node.defaultChild instanceof glue.CfnTable).toEqual(true); }); test('encrypted table: SSE-S3', () => { @@ -266,11 +264,11 @@ test('encrypted table: SSE-S3', () => { encryption: glue.TableEncryption.S3_MANAGED, dataFormat: glue.DataFormat.JSON, }); - equal(table.encryption, glue.TableEncryption.S3_MANAGED); - equal(table.encryptionKey, undefined); - equal(table.bucket.encryptionKey, undefined); + expect(table.encryption).toEqual(glue.TableEncryption.S3_MANAGED); + expect(table.encryptionKey).toEqual(undefined); + expect(table.bucket.encryptionKey).toEqual(undefined); - cdkExpect(stack).to(haveResource('AWS::Glue::Table', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Table', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -313,9 +311,9 @@ test('encrypted table: SSE-S3', () => { }, TableType: 'EXTERNAL_TABLE', }, - })); + }); - cdkExpect(stack).to(haveResource('AWS::S3::Bucket', { + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { BucketEncryption: { ServerSideEncryptionConfiguration: [ { @@ -325,7 +323,7 @@ test('encrypted table: SSE-S3', () => { }, ], }, - })); + }); }); @@ -345,14 +343,14 @@ test('encrypted table: SSE-KMS (implicitly created key)', () => { encryption: glue.TableEncryption.KMS, dataFormat: glue.DataFormat.JSON, }); - equal(table.encryption, glue.TableEncryption.KMS); - equal(table.encryptionKey, table.bucket.encryptionKey); + expect(table.encryption).toEqual(glue.TableEncryption.KMS); + expect(table.encryptionKey).toEqual(table.bucket.encryptionKey); - cdkExpect(stack).to(haveResource('AWS::KMS::Key', { + Template.fromStack(stack).hasResourceProperties('AWS::KMS::Key', { Description: 'Created by Default/Table/Bucket', - })); + }); - cdkExpect(stack).to(haveResource('AWS::S3::Bucket', { + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { BucketEncryption: { ServerSideEncryptionConfiguration: [ { @@ -368,9 +366,9 @@ test('encrypted table: SSE-KMS (implicitly created key)', () => { }, ], }, - })); + }); - cdkExpect(stack).to(haveResource('AWS::Glue::Table', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Table', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -413,7 +411,7 @@ test('encrypted table: SSE-KMS (implicitly created key)', () => { }, TableType: 'EXTERNAL_TABLE', }, - })); + }); }); @@ -437,15 +435,15 @@ test('encrypted table: SSE-KMS (explicitly created key)', () => { encryptionKey, dataFormat: glue.DataFormat.JSON, }); - equal(table.encryption, glue.TableEncryption.KMS); - equal(table.encryptionKey, table.bucket.encryptionKey); - notEqual(table.encryptionKey, undefined); + expect(table.encryption).toEqual(glue.TableEncryption.KMS); + expect(table.encryptionKey).toEqual(table.bucket.encryptionKey); + expect(table.encryptionKey).not.toEqual(undefined); - cdkExpect(stack).to(haveResource('AWS::KMS::Key', { + Template.fromStack(stack).hasResourceProperties('AWS::KMS::Key', { Description: 'OurKey', - })); + }); - cdkExpect(stack).to(haveResource('AWS::S3::Bucket', { + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { BucketEncryption: { ServerSideEncryptionConfiguration: [ { @@ -461,9 +459,9 @@ test('encrypted table: SSE-KMS (explicitly created key)', () => { }, ], }, - })); + }); - cdkExpect(stack).to(haveResource('AWS::Glue::Table', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Table', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -506,7 +504,7 @@ test('encrypted table: SSE-KMS (explicitly created key)', () => { }, TableType: 'EXTERNAL_TABLE', }, - })); + }); }); @@ -526,11 +524,11 @@ test('encrypted table: SSE-KMS_MANAGED', () => { encryption: glue.TableEncryption.KMS_MANAGED, dataFormat: glue.DataFormat.JSON, }); - equal(table.encryption, glue.TableEncryption.KMS_MANAGED); - equal(table.encryptionKey, undefined); - equal(table.bucket.encryptionKey, undefined); + expect(table.encryption).toEqual(glue.TableEncryption.KMS_MANAGED); + expect(table.encryptionKey).toEqual(undefined); + expect(table.bucket.encryptionKey).toEqual(undefined); - cdkExpect(stack).to(haveResource('AWS::S3::Bucket', { + Template.fromStack(stack).hasResourceProperties('AWS::S3::Bucket', { BucketEncryption: { ServerSideEncryptionConfiguration: [ { @@ -540,9 +538,9 @@ test('encrypted table: SSE-KMS_MANAGED', () => { }, ], }, - })); + }); - cdkExpect(stack).to(haveResource('AWS::Glue::Table', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Table', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -585,7 +583,7 @@ test('encrypted table: SSE-KMS_MANAGED', () => { }, TableType: 'EXTERNAL_TABLE', }, - })); + }); }); @@ -605,13 +603,13 @@ test('encrypted table: CSE-KMS (implicitly created key)', () => { encryption: glue.TableEncryption.CLIENT_SIDE_KMS, dataFormat: glue.DataFormat.JSON, }); - equal(table.encryption, glue.TableEncryption.CLIENT_SIDE_KMS); - notEqual(table.encryptionKey, undefined); - equal(table.bucket.encryptionKey, undefined); + expect(table.encryption).toEqual(glue.TableEncryption.CLIENT_SIDE_KMS); + expect(table.encryptionKey).not.toEqual(undefined); + expect(table.bucket.encryptionKey).toEqual(undefined); - cdkExpect(stack).to(haveResource('AWS::KMS::Key')); + Template.fromStack(stack).resourceCountIs('AWS::KMS::Key', 1); - cdkExpect(stack).to(haveResource('AWS::Glue::Table', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Table', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -654,7 +652,7 @@ test('encrypted table: CSE-KMS (implicitly created key)', () => { }, TableType: 'EXTERNAL_TABLE', }, - })); + }); }); @@ -678,15 +676,15 @@ test('encrypted table: CSE-KMS (explicitly created key)', () => { encryptionKey, dataFormat: glue.DataFormat.JSON, }); - equal(table.encryption, glue.TableEncryption.CLIENT_SIDE_KMS); - notEqual(table.encryptionKey, undefined); - equal(table.bucket.encryptionKey, undefined); + expect(table.encryption).toEqual(glue.TableEncryption.CLIENT_SIDE_KMS); + expect(table.encryptionKey).not.toEqual(undefined); + expect(table.bucket.encryptionKey).toEqual(undefined); - cdkExpect(stack).to(haveResource('AWS::KMS::Key', { + Template.fromStack(stack).hasResourceProperties('AWS::KMS::Key', { Description: 'MyKey', - })); + }); - cdkExpect(stack).to(haveResource('AWS::Glue::Table', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Table', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -729,7 +727,7 @@ test('encrypted table: CSE-KMS (explicitly created key)', () => { }, TableType: 'EXTERNAL_TABLE', }, - })); + }); }); @@ -755,15 +753,15 @@ test('encrypted table: CSE-KMS (explicitly passed bucket and key)', () => { encryptionKey, dataFormat: glue.DataFormat.JSON, }); - equal(table.encryption, glue.TableEncryption.CLIENT_SIDE_KMS); - notEqual(table.encryptionKey, undefined); - equal(table.bucket.encryptionKey, undefined); + expect(table.encryption).toEqual(glue.TableEncryption.CLIENT_SIDE_KMS); + expect(table.encryptionKey).not.toEqual(undefined); + expect(table.bucket.encryptionKey).toEqual(undefined); - cdkExpect(stack).to(haveResource('AWS::KMS::Key', { + Template.fromStack(stack).hasResourceProperties('AWS::KMS::Key', { Description: 'MyKey', - })); + }); - cdkExpect(stack).to(haveResource('AWS::Glue::Table', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Table', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -806,7 +804,7 @@ test('encrypted table: CSE-KMS (explicitly passed bucket and key)', () => { }, TableType: 'EXTERNAL_TABLE', }, - })); + }); }); @@ -831,7 +829,7 @@ test('explicit s3 bucket and prefix', () => { dataFormat: glue.DataFormat.JSON, }); - cdkExpect(stack).to(haveResource('AWS::Glue::Table', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Table', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -874,7 +872,7 @@ test('explicit s3 bucket and prefix', () => { }, TableType: 'EXTERNAL_TABLE', }, - })); + }); }); @@ -899,7 +897,7 @@ test('explicit s3 bucket and with empty prefix', () => { dataFormat: glue.DataFormat.JSON, }); - cdkExpect(stack).to(haveResource('AWS::Glue::Table', { + Template.fromStack(stack).hasResourceProperties('AWS::Glue::Table', { CatalogId: { Ref: 'AWS::AccountId', }, @@ -942,7 +940,7 @@ test('explicit s3 bucket and with empty prefix', () => { }, TableType: 'EXTERNAL_TABLE', }, - })); + }); }); @@ -966,7 +964,7 @@ test('grants: read only', () => { table.grantRead(user); - cdkExpect(stack).to(haveResource('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -1048,7 +1046,7 @@ test('grants: read only', () => { Ref: 'User00B015A1', }, ], - })); + }); }); @@ -1072,7 +1070,7 @@ testFutureBehavior('grants: write only', s3GrantWriteCtx, cdk.App, (app) => { table.grantWrite(user); - cdkExpect(stack).to(haveResource('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -1151,7 +1149,7 @@ testFutureBehavior('grants: write only', s3GrantWriteCtx, cdk.App, (app) => { Ref: 'User00B015A1', }, ], - })); + }); }); @@ -1175,7 +1173,7 @@ testFutureBehavior('grants: read and write', s3GrantWriteCtx, cdk.App, (app) => table.grantReadWrite(user); - cdkExpect(stack).to(haveResource('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -1264,7 +1262,7 @@ testFutureBehavior('grants: read and write', s3GrantWriteCtx, cdk.App, (app) => Ref: 'User00B015A1', }, ], - })); + }); }); @@ -1346,7 +1344,7 @@ test('validate: can not specify an explicit bucket and encryption', () => { }); test('validate: can explicitly pass bucket if Encryption undefined', () => { - doesNotThrow(() => createTable({ + expect(() => createTable({ tableName: 'name', columns: [{ name: 'col1', @@ -1354,11 +1352,11 @@ test('validate: can explicitly pass bucket if Encryption undefined', () => { }], bucket: new s3.Bucket(new cdk.Stack(), 'Bucket'), encryption: undefined, - })); + })).not.toThrow(); }); test('validate: can explicitly pass bucket if Unencrypted', () => { - doesNotThrow(() => createTable({ + expect(() => createTable({ tableName: 'name', columns: [{ name: 'col1', @@ -1366,11 +1364,11 @@ test('validate: can explicitly pass bucket if Unencrypted', () => { }], bucket: new s3.Bucket(new cdk.Stack(), 'Bucket'), encryption: undefined, - })); + })).not.toThrow(); }); test('validate: can explicitly pass bucket if ClientSideKms', () => { - doesNotThrow(() => createTable({ + expect(() => createTable({ tableName: 'name', columns: [{ name: 'col1', @@ -1378,7 +1376,7 @@ test('validate: can explicitly pass bucket if ClientSideKms', () => { }], bucket: new s3.Bucket(new cdk.Stack(), 'Bucket'), encryption: glue.TableEncryption.CLIENT_SIDE_KMS, - })); + })).not.toThrow(); }); test('Table.fromTableArn', () => { @@ -1389,8 +1387,8 @@ test('Table.fromTableArn', () => { const table = glue.Table.fromTableArn(stack, 'boom', 'arn:aws:glue:us-east-1:123456789012:table/db1/tbl1'); // THEN - deepEqual(table.tableArn, 'arn:aws:glue:us-east-1:123456789012:table/db1/tbl1'); - deepEqual(table.tableName, 'tbl1'); + expect(table.tableArn).toEqual('arn:aws:glue:us-east-1:123456789012:table/db1/tbl1'); + expect(table.tableName).toEqual('tbl1'); }); function createTable(props: Pick>): void { diff --git a/packages/@aws-cdk/aws-greengrass/package.json b/packages/@aws-cdk/aws-greengrass/package.json index 9fa8de9238ee2..e5909de8cf591 100644 --- a/packages/@aws-cdk/aws-greengrass/package.json +++ b/packages/@aws-cdk/aws-greengrass/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-greengrass/test/greengrass.test.ts b/packages/@aws-cdk/aws-greengrass/test/greengrass.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-greengrass/test/greengrass.test.ts +++ b/packages/@aws-cdk/aws-greengrass/test/greengrass.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-greengrassv2/package.json b/packages/@aws-cdk/aws-greengrassv2/package.json index 8096e3269ac30..4c21e7594e26b 100644 --- a/packages/@aws-cdk/aws-greengrassv2/package.json +++ b/packages/@aws-cdk/aws-greengrassv2/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-greengrassv2/test/greengrass.test.ts b/packages/@aws-cdk/aws-greengrassv2/test/greengrass.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-greengrassv2/test/greengrass.test.ts +++ b/packages/@aws-cdk/aws-greengrassv2/test/greengrass.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-groundstation/package.json b/packages/@aws-cdk/aws-groundstation/package.json index f337bfd5dc79e..f24da08699f70 100644 --- a/packages/@aws-cdk/aws-groundstation/package.json +++ b/packages/@aws-cdk/aws-groundstation/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-groundstation/test/groundstation.test.ts b/packages/@aws-cdk/aws-groundstation/test/groundstation.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-groundstation/test/groundstation.test.ts +++ b/packages/@aws-cdk/aws-groundstation/test/groundstation.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-guardduty/package.json b/packages/@aws-cdk/aws-guardduty/package.json index 671cd3e85044c..0fb30da82ef61 100644 --- a/packages/@aws-cdk/aws-guardduty/package.json +++ b/packages/@aws-cdk/aws-guardduty/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-guardduty/test/guardduty.test.ts b/packages/@aws-cdk/aws-guardduty/test/guardduty.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-guardduty/test/guardduty.test.ts +++ b/packages/@aws-cdk/aws-guardduty/test/guardduty.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-imagebuilder/package.json b/packages/@aws-cdk/aws-imagebuilder/package.json index 0f37220e9e269..64537f6b27401 100644 --- a/packages/@aws-cdk/aws-imagebuilder/package.json +++ b/packages/@aws-cdk/aws-imagebuilder/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-imagebuilder/test/imagebuilder.test.ts b/packages/@aws-cdk/aws-imagebuilder/test/imagebuilder.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-imagebuilder/test/imagebuilder.test.ts +++ b/packages/@aws-cdk/aws-imagebuilder/test/imagebuilder.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-inspector/package.json b/packages/@aws-cdk/aws-inspector/package.json index 489f584c5b6e8..dad54ff5b2e51 100644 --- a/packages/@aws-cdk/aws-inspector/package.json +++ b/packages/@aws-cdk/aws-inspector/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-inspector/test/inspector.test.ts b/packages/@aws-cdk/aws-inspector/test/inspector.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-inspector/test/inspector.test.ts +++ b/packages/@aws-cdk/aws-inspector/test/inspector.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-iot/package.json b/packages/@aws-cdk/aws-iot/package.json index 1e83190d4b532..f816d5f680164 100644 --- a/packages/@aws-cdk/aws-iot/package.json +++ b/packages/@aws-cdk/aws-iot/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-iot/test/iot.test.ts b/packages/@aws-cdk/aws-iot/test/iot.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-iot/test/iot.test.ts +++ b/packages/@aws-cdk/aws-iot/test/iot.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-iot1click/package.json b/packages/@aws-cdk/aws-iot1click/package.json index b1821fe309430..17ad106a288f2 100644 --- a/packages/@aws-cdk/aws-iot1click/package.json +++ b/packages/@aws-cdk/aws-iot1click/package.json @@ -78,7 +78,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-iot1click/test/iot1click.test.ts b/packages/@aws-cdk/aws-iot1click/test/iot1click.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-iot1click/test/iot1click.test.ts +++ b/packages/@aws-cdk/aws-iot1click/test/iot1click.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-iotanalytics/package.json b/packages/@aws-cdk/aws-iotanalytics/package.json index 97acc44632e9b..66434d4db2d33 100644 --- a/packages/@aws-cdk/aws-iotanalytics/package.json +++ b/packages/@aws-cdk/aws-iotanalytics/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-iotanalytics/test/iotanalytics.test.ts b/packages/@aws-cdk/aws-iotanalytics/test/iotanalytics.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-iotanalytics/test/iotanalytics.test.ts +++ b/packages/@aws-cdk/aws-iotanalytics/test/iotanalytics.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-iotcoredeviceadvisor/package.json b/packages/@aws-cdk/aws-iotcoredeviceadvisor/package.json index ca500daa21d26..80fc81f75a022 100644 --- a/packages/@aws-cdk/aws-iotcoredeviceadvisor/package.json +++ b/packages/@aws-cdk/aws-iotcoredeviceadvisor/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-iotcoredeviceadvisor/test/iotcoredeviceadvisor.test.ts b/packages/@aws-cdk/aws-iotcoredeviceadvisor/test/iotcoredeviceadvisor.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-iotcoredeviceadvisor/test/iotcoredeviceadvisor.test.ts +++ b/packages/@aws-cdk/aws-iotcoredeviceadvisor/test/iotcoredeviceadvisor.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-iotevents/package.json b/packages/@aws-cdk/aws-iotevents/package.json index e6e819bba2aed..9125c6a9a05b1 100644 --- a/packages/@aws-cdk/aws-iotevents/package.json +++ b/packages/@aws-cdk/aws-iotevents/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-iotevents/test/iotevents.test.ts b/packages/@aws-cdk/aws-iotevents/test/iotevents.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-iotevents/test/iotevents.test.ts +++ b/packages/@aws-cdk/aws-iotevents/test/iotevents.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-iotfleethub/package.json b/packages/@aws-cdk/aws-iotfleethub/package.json index f873c33b08634..69891556a7f4b 100644 --- a/packages/@aws-cdk/aws-iotfleethub/package.json +++ b/packages/@aws-cdk/aws-iotfleethub/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-iotfleethub/test/iotfleethub.test.ts b/packages/@aws-cdk/aws-iotfleethub/test/iotfleethub.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-iotfleethub/test/iotfleethub.test.ts +++ b/packages/@aws-cdk/aws-iotfleethub/test/iotfleethub.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-iotsitewise/package.json b/packages/@aws-cdk/aws-iotsitewise/package.json index 81750ea6c4221..9c86ba4bcd889 100644 --- a/packages/@aws-cdk/aws-iotsitewise/package.json +++ b/packages/@aws-cdk/aws-iotsitewise/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-iotsitewise/test/iotsitewise.test.ts b/packages/@aws-cdk/aws-iotsitewise/test/iotsitewise.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-iotsitewise/test/iotsitewise.test.ts +++ b/packages/@aws-cdk/aws-iotsitewise/test/iotsitewise.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-iotthingsgraph/package.json b/packages/@aws-cdk/aws-iotthingsgraph/package.json index 39dee778b632f..a00fc435787fe 100644 --- a/packages/@aws-cdk/aws-iotthingsgraph/package.json +++ b/packages/@aws-cdk/aws-iotthingsgraph/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-iotthingsgraph/test/iotthingsgraph.test.ts b/packages/@aws-cdk/aws-iotthingsgraph/test/iotthingsgraph.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-iotthingsgraph/test/iotthingsgraph.test.ts +++ b/packages/@aws-cdk/aws-iotthingsgraph/test/iotthingsgraph.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-iotwireless/package.json b/packages/@aws-cdk/aws-iotwireless/package.json index 176941dd97bb4..ee46fc9ca58ec 100644 --- a/packages/@aws-cdk/aws-iotwireless/package.json +++ b/packages/@aws-cdk/aws-iotwireless/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-iotwireless/test/iotwireless.test.ts b/packages/@aws-cdk/aws-iotwireless/test/iotwireless.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-iotwireless/test/iotwireless.test.ts +++ b/packages/@aws-cdk/aws-iotwireless/test/iotwireless.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-ivs/package.json b/packages/@aws-cdk/aws-ivs/package.json index 31a2a63490f4d..b199d66182db2 100644 --- a/packages/@aws-cdk/aws-ivs/package.json +++ b/packages/@aws-cdk/aws-ivs/package.json @@ -85,12 +85,12 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", - "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-ivs/test/ivs.test.ts b/packages/@aws-cdk/aws-ivs/test/ivs.test.ts index 5f4f29e833df7..0e5efd63d5b2a 100644 --- a/packages/@aws-cdk/aws-ivs/test/ivs.test.ts +++ b/packages/@aws-cdk/aws-ivs/test/ivs.test.ts @@ -1,5 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; -import { expect as expectStack } from '@aws-cdk/assert-internal'; +import { Template } from '@aws-cdk/assertions'; import { Stack } from '@aws-cdk/core'; import * as ivs from '../lib'; @@ -13,7 +12,7 @@ test('channel default properties', () => { const stack = new Stack(); new ivs.Channel(stack, 'Channel'); - expectStack(stack).toMatch({ + Template.fromStack(stack).templateMatches({ Resources: { Channel4048F119: { Type: 'AWS::IVS::Channel', @@ -28,7 +27,7 @@ test('channel name', () => { name: 'CarrotsAreTasty', }); - expectStack(stack).toMatch({ + Template.fromStack(stack).templateMatches({ Resources: { Channel4048F119: { Type: 'AWS::IVS::Channel', @@ -46,7 +45,7 @@ test('channel is authorized', () => { authorized: true, }); - expectStack(stack).toMatch({ + Template.fromStack(stack).templateMatches({ Resources: { Channel4048F119: { Type: 'AWS::IVS::Channel', @@ -64,7 +63,7 @@ test('channel type', () => { type: ivs.ChannelType.BASIC, }); - expectStack(stack).toMatch({ + Template.fromStack(stack).templateMatches({ Resources: { Channel4048F119: { Type: 'AWS::IVS::Channel', @@ -82,7 +81,7 @@ test('channel latency mode', () => { latencyMode: ivs.LatencyMode.NORMAL, }); - expectStack(stack).toMatch({ + Template.fromStack(stack).templateMatches({ Resources: { Channel4048F119: { Type: 'AWS::IVS::Channel', @@ -115,7 +114,7 @@ test('playback key pair mandatory properties', () => { publicKeyMaterial: publicKey, }); - expectStack(stack).toMatch({ + Template.fromStack(stack).templateMatches({ Resources: { PlaybackKeyPairBE17315B: { Type: 'AWS::IVS::PlaybackKeyPair', @@ -134,7 +133,7 @@ test('playback key pair name', () => { name: 'CarrotsAreNutritious', }); - expectStack(stack).toMatch({ + Template.fromStack(stack).templateMatches({ Resources: { PlaybackKeyPairBE17315B: { Type: 'AWS::IVS::PlaybackKeyPair', @@ -162,7 +161,7 @@ test('stream key mandatory properties', () => { channel: ivs.Channel.fromChannelArn(stack, 'ChannelRef', 'arn:aws:ivs:us-west-2:123456789012:channel/abcdABCDefgh'), }); - expectStack(stack).toMatch({ + Template.fromStack(stack).templateMatches({ Resources: { StreamKey9F296F4F: { Type: 'AWS::IVS::StreamKey', @@ -179,7 +178,7 @@ test('channel and stream key.. at the same time', () => { const channel = new ivs.Channel(stack, 'Channel'); channel.addStreamKey('StreamKey'); - expectStack(stack).toMatch({ + Template.fromStack(stack).templateMatches({ Resources: { Channel4048F119: { Type: 'AWS::IVS::Channel', @@ -199,7 +198,7 @@ test('stream key from channel reference', () => { const channel = ivs.Channel.fromChannelArn(stack, 'Channel', 'arn:aws:ivs:us-west-2:123456789012:channel/abcdABCDefgh'); channel.addStreamKey('StreamKey'); - expectStack(stack).toMatch({ + Template.fromStack(stack).templateMatches({ Resources: { ChannelStreamKey60BDC2BE: { Type: 'AWS::IVS::StreamKey', diff --git a/packages/@aws-cdk/aws-kendra/package.json b/packages/@aws-cdk/aws-kendra/package.json index c78e48ea705e7..33ab4f2afa7f2 100644 --- a/packages/@aws-cdk/aws-kendra/package.json +++ b/packages/@aws-cdk/aws-kendra/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-kendra/test/kendra.test.ts b/packages/@aws-cdk/aws-kendra/test/kendra.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-kendra/test/kendra.test.ts +++ b/packages/@aws-cdk/aws-kendra/test/kendra.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-kinesisanalytics-flink/package.json b/packages/@aws-cdk/aws-kinesisanalytics-flink/package.json index 02ffcb62439e7..d9ee895e0ed29 100644 --- a/packages/@aws-cdk/aws-kinesisanalytics-flink/package.json +++ b/packages/@aws-cdk/aws-kinesisanalytics-flink/package.json @@ -66,12 +66,12 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "jest": "^26.6.3", - "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/assets": "0.0.0", diff --git a/packages/@aws-cdk/aws-kinesisanalytics-flink/test/application.test.ts b/packages/@aws-cdk/aws-kinesisanalytics-flink/test/application.test.ts index 09ccedef9bc83..a4546a5fa9423 100644 --- a/packages/@aws-cdk/aws-kinesisanalytics-flink/test/application.test.ts +++ b/packages/@aws-cdk/aws-kinesisanalytics-flink/test/application.test.ts @@ -1,10 +1,9 @@ -import { arrayWith, objectLike, ResourcePart } from '@aws-cdk/assert-internal'; -import '@aws-cdk/assert-internal/jest'; +import * as path from 'path'; +import { Match, Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; import * as logs from '@aws-cdk/aws-logs'; import * as s3 from '@aws-cdk/aws-s3'; import * as core from '@aws-cdk/core'; -import * as path from 'path'; import * as flink from '../lib'; describe('Application', () => { @@ -31,7 +30,7 @@ describe('Application', () => { applicationName: 'MyFlinkApplication', }); - expect(stack).toHaveResource('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisAnalyticsV2::Application', { ApplicationName: 'MyFlinkApplication', RuntimeEnvironment: 'FLINK-1_11', ServiceExecutionRole: { @@ -56,11 +55,11 @@ describe('Application', () => { }, }); - expect(stack).toHaveResourceLike('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResource('AWS::KinesisAnalyticsV2::Application', { DeletionPolicy: 'Delete', - }, ResourcePart.CompleteDefinition); + }); - expect(stack).toHaveResource('AWS::IAM::Role', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { AssumeRolePolicyDocument: { Statement: [{ Action: 'sts:AssumeRole', @@ -73,9 +72,9 @@ describe('Application', () => { }, }); - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { - Statement: arrayWith( + Statement: Match.arrayWith([ { Action: 'cloudwatch:PutMetricData', Effect: 'Allow', Resource: '*' }, { Action: 'logs:DescribeLogGroups', @@ -119,7 +118,7 @@ describe('Application', () => { ]], }, }, - ), + ]), }, }); }); @@ -132,7 +131,7 @@ describe('Application', () => { }), }); - expect(stack).toHaveResource('AWS::IAM::Role', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { AssumeRolePolicyDocument: { Statement: [ { @@ -158,11 +157,11 @@ describe('Application', () => { resources: ['*'], })); - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { - Statement: arrayWith( - objectLike({ Action: 'custom:action', Effect: 'Allow', Resource: '*' }), - ), + Statement: Match.arrayWith([ + Match.objectLike({ Action: 'custom:action', Effect: 'Allow', Resource: '*' }), + ]), }, }); }); @@ -173,7 +172,7 @@ describe('Application', () => { runtime: flink.Runtime.of('custom'), }); - expect(stack).toHaveResourceLike('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisAnalyticsV2::Application', { RuntimeEnvironment: 'custom', }); }); @@ -184,9 +183,9 @@ describe('Application', () => { removalPolicy: core.RemovalPolicy.RETAIN, }); - expect(stack).toHaveResourceLike('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResource('AWS::KinesisAnalyticsV2::Application', { DeletionPolicy: 'Retain', - }, ResourcePart.CompleteDefinition); + }); }); test('granting permissions to resources', () => { @@ -197,12 +196,12 @@ describe('Application', () => { const dataBucket = new s3.Bucket(stack, 'DataBucket'); dataBucket.grantRead(app); - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Version: '2012-10-17', - Statement: arrayWith( - objectLike({ Action: ['s3:GetObject*', 's3:GetBucket*', 's3:List*'] }), - ), + Statement: Match.arrayWith([ + Match.objectLike({ Action: ['s3:GetObject*', 's3:GetBucket*', 's3:List*'] }), + ]), }, }); }); @@ -216,7 +215,7 @@ describe('Application', () => { const assetRef = 'AssetParameters8be9e0b5f53d41e9a3b1d51c9572c65f24f8170a7188d0ed57fb7d571de4d577S3BucketEBA17A67'; const versionKeyRef = 'AssetParameters8be9e0b5f53d41e9a3b1d51c9572c65f24f8170a7188d0ed57fb7d571de4d577S3VersionKey5922697E'; - expect(stack).toHaveResourceLike('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisAnalyticsV2::Application', { ApplicationConfiguration: { ApplicationCodeConfiguration: { CodeContent: { @@ -253,7 +252,7 @@ describe('Application', () => { }, }); - expect(stack).toHaveResourceLike('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisAnalyticsV2::Application', { ApplicationConfiguration: { EnvironmentProperties: { PropertyGroups: [ @@ -275,7 +274,7 @@ describe('Application', () => { checkpointingEnabled: false, }); - expect(stack).toHaveResourceLike('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisAnalyticsV2::Application', { ApplicationConfiguration: { FlinkApplicationConfiguration: { CheckpointConfiguration: { @@ -293,7 +292,7 @@ describe('Application', () => { checkpointInterval: core.Duration.minutes(5), }); - expect(stack).toHaveResourceLike('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisAnalyticsV2::Application', { ApplicationConfiguration: { FlinkApplicationConfiguration: { CheckpointConfiguration: { @@ -311,7 +310,7 @@ describe('Application', () => { minPauseBetweenCheckpoints: core.Duration.seconds(10), }); - expect(stack).toHaveResourceLike('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisAnalyticsV2::Application', { ApplicationConfiguration: { FlinkApplicationConfiguration: { CheckpointConfiguration: { @@ -329,7 +328,7 @@ describe('Application', () => { logLevel: flink.LogLevel.DEBUG, }); - expect(stack).toHaveResourceLike('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisAnalyticsV2::Application', { ApplicationConfiguration: { FlinkApplicationConfiguration: { MonitoringConfiguration: { @@ -347,7 +346,7 @@ describe('Application', () => { metricsLevel: flink.MetricsLevel.PARALLELISM, }); - expect(stack).toHaveResourceLike('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisAnalyticsV2::Application', { ApplicationConfiguration: { FlinkApplicationConfiguration: { MonitoringConfiguration: { @@ -365,7 +364,7 @@ describe('Application', () => { autoScalingEnabled: false, }); - expect(stack).toHaveResourceLike('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisAnalyticsV2::Application', { ApplicationConfiguration: { FlinkApplicationConfiguration: { ParallelismConfiguration: { @@ -383,7 +382,7 @@ describe('Application', () => { parallelism: 2, }); - expect(stack).toHaveResourceLike('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisAnalyticsV2::Application', { ApplicationConfiguration: { FlinkApplicationConfiguration: { ParallelismConfiguration: { @@ -401,7 +400,7 @@ describe('Application', () => { parallelismPerKpu: 2, }); - expect(stack).toHaveResourceLike('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisAnalyticsV2::Application', { ApplicationConfiguration: { FlinkApplicationConfiguration: { ParallelismConfiguration: { @@ -419,7 +418,7 @@ describe('Application', () => { snapshotsEnabled: false, }); - expect(stack).toHaveResourceLike('AWS::KinesisAnalyticsV2::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisAnalyticsV2::Application', { ApplicationConfiguration: { ApplicationSnapshotConfiguration: { SnapshotsEnabled: false, @@ -434,7 +433,7 @@ describe('Application', () => { snapshotsEnabled: false, }); - expect(stack).toHaveResource('AWS::KinesisAnalyticsV2::ApplicationCloudWatchLoggingOption', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisAnalyticsV2::ApplicationCloudWatchLoggingOption', { ApplicationName: { Ref: 'FlinkApplicationC5836815', }, @@ -469,18 +468,18 @@ describe('Application', () => { }, }); - expect(stack).toHaveResource('AWS::Logs::LogGroup', { + Template.fromStack(stack).hasResource('AWS::Logs::LogGroup', { Properties: { RetentionInDays: 731, }, UpdateReplacePolicy: 'Retain', DeletionPolicy: 'Retain', - }, ResourcePart.CompleteDefinition); + }); - expect(stack).toHaveResource('AWS::Logs::LogStream', { + Template.fromStack(stack).hasResource('AWS::Logs::LogStream', { UpdateReplacePolicy: 'Retain', DeletionPolicy: 'Retain', - }, ResourcePart.CompleteDefinition); + }); }); test('logGroup setting', () => { @@ -491,7 +490,7 @@ describe('Application', () => { }), }); - expect(stack).toHaveResource('AWS::Logs::LogGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::Logs::LogGroup', { LogGroupName: 'custom', }); }); diff --git a/packages/@aws-cdk/aws-kinesisanalytics/package.json b/packages/@aws-cdk/aws-kinesisanalytics/package.json index 3a3933d62d655..db7c571c963c8 100644 --- a/packages/@aws-cdk/aws-kinesisanalytics/package.json +++ b/packages/@aws-cdk/aws-kinesisanalytics/package.json @@ -80,7 +80,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-kinesisanalytics/test/kinesisanalytics.test.ts b/packages/@aws-cdk/aws-kinesisanalytics/test/kinesisanalytics.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-kinesisanalytics/test/kinesisanalytics.test.ts +++ b/packages/@aws-cdk/aws-kinesisanalytics/test/kinesisanalytics.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-kinesisfirehose-destinations/lib/common.ts b/packages/@aws-cdk/aws-kinesisfirehose-destinations/lib/common.ts index 3a97970d1ddbb..81e53e8288a73 100644 --- a/packages/@aws-cdk/aws-kinesisfirehose-destinations/lib/common.ts +++ b/packages/@aws-cdk/aws-kinesisfirehose-destinations/lib/common.ts @@ -1,10 +1,66 @@ import * as iam from '@aws-cdk/aws-iam'; +import * as firehose from '@aws-cdk/aws-kinesisfirehose'; +import * as kms from '@aws-cdk/aws-kms'; import * as logs from '@aws-cdk/aws-logs'; +import * as s3 from '@aws-cdk/aws-s3'; +import * as cdk from '@aws-cdk/core'; /** - * Generic properties for defining a delivery stream destination. + * Possible compression options Kinesis Data Firehose can use to compress data on delivery. + */ +export class Compression { + /** + * gzip + */ + public static readonly GZIP = new Compression('GZIP'); + + /** + * Hadoop-compatible Snappy + */ + public static readonly HADOOP_SNAPPY = new Compression('HADOOP_SNAPPY'); + + /** + * Snappy + */ + public static readonly SNAPPY = new Compression('Snappy'); + + /** + * ZIP + */ + public static readonly ZIP = new Compression('ZIP'); + + /** + * Creates a new Compression instance with a custom value. + */ + public static of(value: string): Compression { + return new Compression(value); + } + + /** + * @param value the string value of the Compression. + */ + private constructor(public readonly value: string) { } +} + +/** + * Options for S3 record backup of a delivery stream. */ -export interface CommonDestinationProps { +export enum BackupMode { + /** + * All records are backed up. + */ + ALL, + + /** + * Only records that failed to deliver or transform are backed up. + */ + FAILED, +} + +/** + * Logging related properties for a delivery stream destination. + */ +interface DestinationLoggingProps { /** * If true, log errors when data transformation or data delivery fails. * @@ -20,7 +76,102 @@ export interface CommonDestinationProps { * @default - if `logging` is set to `true`, a log group will be created for you. */ readonly logGroup?: logs.ILogGroup; +} + +/** + * Common properties for defining a backup, intermediary, or final S3 destination for a Kinesis Data Firehose delivery stream. + */ +export interface CommonDestinationS3Props { + /** + * The length of time that Firehose buffers incoming data before delivering + * it to the S3 bucket. + * + * Minimum: Duration.seconds(60) + * Maximum: Duration.seconds(900) + * + * @default Duration.seconds(300) + */ + readonly bufferingInterval?: cdk.Duration; + + /** + * The size of the buffer that Kinesis Data Firehose uses for incoming data before + * delivering it to the S3 bucket. + * + * Minimum: Size.mebibytes(1) + * Maximum: Size.mebibytes(128) + * + * @default Size.mebibytes(5) + */ + readonly bufferingSize?: cdk.Size; + + /** + * The type of compression that Kinesis Data Firehose uses to compress the data + * that it delivers to the Amazon S3 bucket. + * + * The compression formats SNAPPY or ZIP cannot be specified for Amazon Redshift + * destinations because they are not supported by the Amazon Redshift COPY operation + * that reads from the S3 bucket. + * + * @default - UNCOMPRESSED + */ + readonly compression?: Compression; + + /** + * The AWS KMS key used to encrypt the data that it delivers to your Amazon S3 bucket. + * + * @default - Data is not encrypted. + */ + readonly encryptionKey?: kms.IKey; + + /** + * A prefix that Kinesis Data Firehose evaluates and adds to failed records before writing them to S3. + * + * This prefix appears immediately following the bucket name. + * @see https://docs.aws.amazon.com/firehose/latest/dev/s3-prefixes.html + * + * @default "YYYY/MM/DD/HH" + */ + readonly errorOutputPrefix?: string; + /** + * A prefix that Kinesis Data Firehose evaluates and adds to records before writing them to S3. + * + * This prefix appears immediately following the bucket name. + * @see https://docs.aws.amazon.com/firehose/latest/dev/s3-prefixes.html + * + * @default "YYYY/MM/DD/HH" + */ + readonly dataOutputPrefix?: string; +} + +/** + * Properties for defining an S3 backup destination. + * + * S3 backup is available for all destinations, regardless of whether the final destination is S3 or not. + */ +export interface DestinationS3BackupProps extends DestinationLoggingProps, CommonDestinationS3Props { + /** + * The S3 bucket that will store data and failed records. + * + * @default - If `mode` is set to `BackupMode.ALL` or `BackupMode.FAILED`, a bucket will be created for you. + */ + readonly bucket?: s3.IBucket; + + /** + * Indicates the mode by which incoming records should be backed up to S3, if any. + * + * If `bucket` is provided, this will be implicitly set to `BackupMode.ALL`. + * + * @default - If `bucket` is provided, the default will be `BackupMode.ALL`. Otherwise, + * source records are not backed up to S3. + */ + readonly mode?: BackupMode; +} + +/** + * Generic properties for defining a delivery stream destination. + */ +export interface CommonDestinationProps extends DestinationLoggingProps { /** * The IAM role associated with this destination. * @@ -29,4 +180,18 @@ export interface CommonDestinationProps { * @default - a role will be created with default permissions. */ readonly role?: iam.IRole; + + /** + * The data transformation that should be performed on the data before writing to the destination. + * + * @default - no data transformation will occur. + */ + readonly processor?: firehose.IDataProcessor; + + /** + * The configuration for backing up source records to S3. + * + * @default - source records will not be backed up to S3. + */ + readonly s3Backup?: DestinationS3BackupProps; } diff --git a/packages/@aws-cdk/aws-kinesisfirehose-destinations/lib/private/helpers.ts b/packages/@aws-cdk/aws-kinesisfirehose-destinations/lib/private/helpers.ts index a2032c41914a0..d8ef3d4ac43a5 100644 --- a/packages/@aws-cdk/aws-kinesisfirehose-destinations/lib/private/helpers.ts +++ b/packages/@aws-cdk/aws-kinesisfirehose-destinations/lib/private/helpers.ts @@ -1,8 +1,11 @@ import * as iam from '@aws-cdk/aws-iam'; import * as firehose from '@aws-cdk/aws-kinesisfirehose'; +import * as kms from '@aws-cdk/aws-kms'; import * as logs from '@aws-cdk/aws-logs'; +import * as s3 from '@aws-cdk/aws-s3'; import * as cdk from '@aws-cdk/core'; import { Construct, Node } from 'constructs'; +import { DestinationS3BackupProps } from '../common'; export interface DestinationLoggingProps { /** @@ -34,19 +37,28 @@ export interface DestinationLoggingProps { readonly streamId: string; } -export interface DestinationLoggingOutput { +interface ConfigWithDependables { + /** + * Resources that were created by the sub-config creator that must be deployed before the delivery stream is deployed. + */ + readonly dependables: cdk.IDependable[]; +} + +export interface DestinationLoggingConfig extends ConfigWithDependables { /** * Logging options that will be injected into the destination configuration. */ readonly loggingOptions: firehose.CfnDeliveryStream.CloudWatchLoggingOptionsProperty; +} +export interface DestinationBackupConfig extends ConfigWithDependables { /** - * Resources that were created by the sub-config creator that must be deployed before the delivery stream is deployed. + * S3 backup configuration that will be injected into the destination configuration. */ - readonly dependables: cdk.IDependable[]; + readonly backupConfig: firehose.CfnDeliveryStream.S3DestinationConfigurationProperty; } -export function createLoggingOptions(scope: Construct, props: DestinationLoggingProps): DestinationLoggingOutput | undefined { +export function createLoggingOptions(scope: Construct, props: DestinationLoggingProps): DestinationLoggingConfig | undefined { if (props.logging === false && props.logGroup) { throw new Error('logging cannot be set to false when logGroup is provided'); } @@ -64,3 +76,98 @@ export function createLoggingOptions(scope: Construct, props: DestinationLogging } return undefined; } + +export function createBufferingHints( + interval?: cdk.Duration, + size?: cdk.Size, +): firehose.CfnDeliveryStream.BufferingHintsProperty | undefined { + if (!interval && !size) { + return undefined; + } + + const intervalInSeconds = interval?.toSeconds() ?? 300; + if (intervalInSeconds < 60 || intervalInSeconds > 900) { + throw new Error(`Buffering interval must be between 60 and 900 seconds. Buffering interval provided was ${intervalInSeconds} seconds.`); + } + const sizeInMBs = size?.toMebibytes() ?? 5; + if (sizeInMBs < 1 || sizeInMBs > 128) { + throw new Error(`Buffering size must be between 1 and 128 MiBs. Buffering size provided was ${sizeInMBs} MiBs.`); + } + return { intervalInSeconds, sizeInMBs }; +} + +export function createEncryptionConfig( + role: iam.IRole, + encryptionKey?: kms.IKey, +): firehose.CfnDeliveryStream.EncryptionConfigurationProperty | undefined { + encryptionKey?.grantEncryptDecrypt(role); + return encryptionKey + ? { kmsEncryptionConfig: { awskmsKeyArn: encryptionKey.keyArn } } + : undefined; +} + +export function createProcessingConfig( + scope: Construct, + role: iam.IRole, + dataProcessor?: firehose.IDataProcessor, +): firehose.CfnDeliveryStream.ProcessingConfigurationProperty | undefined { + return dataProcessor + ? { + enabled: true, + processors: [renderDataProcessor(dataProcessor, scope, role)], + } + : undefined; +} + +function renderDataProcessor( + processor: firehose.IDataProcessor, + scope: Construct, + role: iam.IRole, +): firehose.CfnDeliveryStream.ProcessorProperty { + const processorConfig = processor.bind(scope, { role }); + const parameters = [{ parameterName: 'RoleArn', parameterValue: role.roleArn }]; + parameters.push(processorConfig.processorIdentifier); + if (processor.props.bufferInterval) { + parameters.push({ parameterName: 'BufferIntervalInSeconds', parameterValue: processor.props.bufferInterval.toSeconds().toString() }); + } + if (processor.props.bufferSize) { + parameters.push({ parameterName: 'BufferSizeInMBs', parameterValue: processor.props.bufferSize.toMebibytes().toString() }); + } + if (processor.props.retries) { + parameters.push({ parameterName: 'NumberOfRetries', parameterValue: processor.props.retries.toString() }); + } + return { + type: processorConfig.processorType, + parameters, + }; +} + +export function createBackupConfig(scope: Construct, role: iam.IRole, props?: DestinationS3BackupProps): DestinationBackupConfig | undefined { + if (!props || (props.mode === undefined && !props.bucket)) { + return undefined; + } + + const bucket = props.bucket ?? new s3.Bucket(scope, 'BackupBucket'); + const bucketGrant = bucket.grantReadWrite(role); + + const { loggingOptions, dependables: loggingDependables } = createLoggingOptions(scope, { + logging: props.logging, + logGroup: props.logGroup, + role, + streamId: 'S3Backup', + }) ?? {}; + + return { + backupConfig: { + bucketArn: bucket.bucketArn, + roleArn: role.roleArn, + prefix: props.dataOutputPrefix, + errorOutputPrefix: props.errorOutputPrefix, + bufferingHints: createBufferingHints(props.bufferingInterval, props.bufferingSize), + compressionFormat: props.compression?.value, + encryptionConfiguration: createEncryptionConfig(role, props.encryptionKey), + cloudWatchLoggingOptions: loggingOptions, + }, + dependables: [bucketGrant, ...(loggingDependables ?? [])], + }; +} diff --git a/packages/@aws-cdk/aws-kinesisfirehose-destinations/lib/s3-bucket.ts b/packages/@aws-cdk/aws-kinesisfirehose-destinations/lib/s3-bucket.ts index ad3c0313ff061..100c73af16b10 100644 --- a/packages/@aws-cdk/aws-kinesisfirehose-destinations/lib/s3-bucket.ts +++ b/packages/@aws-cdk/aws-kinesisfirehose-destinations/lib/s3-bucket.ts @@ -2,19 +2,24 @@ import * as iam from '@aws-cdk/aws-iam'; import * as firehose from '@aws-cdk/aws-kinesisfirehose'; import * as s3 from '@aws-cdk/aws-s3'; import { Construct } from 'constructs'; -import { CommonDestinationProps } from './common'; -import { createLoggingOptions } from './private/helpers'; +import { BackupMode, CommonDestinationProps, CommonDestinationS3Props } from './common'; +import { createBackupConfig, createBufferingHints, createEncryptionConfig, createLoggingOptions, createProcessingConfig } from './private/helpers'; /** * Props for defining an S3 destination of a Kinesis Data Firehose delivery stream. */ -export interface S3BucketProps extends CommonDestinationProps { } +export interface S3BucketProps extends CommonDestinationS3Props, CommonDestinationProps { +} /** * An S3 bucket destination for data from a Kinesis Data Firehose delivery stream. */ export class S3Bucket implements firehose.IDestination { - constructor(private readonly bucket: s3.IBucket, private readonly props: S3BucketProps = {}) { } + constructor(private readonly bucket: s3.IBucket, private readonly props: S3BucketProps = {}) { + if (this.props.s3Backup?.mode === BackupMode.FAILED) { + throw new Error('S3 destinations do not support BackupMode.FAILED'); + } + } bind(scope: Construct, _options: firehose.DestinationBindOptions): firehose.DestinationConfig { const role = this.props.role ?? new iam.Role(scope, 'S3 Destination Role', { @@ -30,13 +35,28 @@ export class S3Bucket implements firehose.IDestination { streamId: 'S3Destination', }) ?? {}; + const { backupConfig, dependables: backupDependables } = createBackupConfig(scope, role, this.props.s3Backup) ?? {}; return { extendedS3DestinationConfiguration: { cloudWatchLoggingOptions: loggingOptions, + processingConfiguration: createProcessingConfig(scope, role, this.props.processor), roleArn: role.roleArn, + s3BackupConfiguration: backupConfig, + s3BackupMode: this.getS3BackupMode(), + bufferingHints: createBufferingHints(this.props.bufferingInterval, this.props.bufferingSize), bucketArn: this.bucket.bucketArn, + compressionFormat: this.props.compression?.value, + encryptionConfiguration: createEncryptionConfig(role, this.props.encryptionKey), + errorOutputPrefix: this.props.errorOutputPrefix, + prefix: this.props.dataOutputPrefix, }, - dependables: [bucketGrant, ...(loggingDependables ?? [])], + dependables: [bucketGrant, ...(loggingDependables ?? []), ...(backupDependables ?? [])], }; } + + private getS3BackupMode(): string | undefined { + return this.props.s3Backup?.bucket || this.props.s3Backup?.mode === BackupMode.ALL + ? 'Enabled' + : undefined; + } } diff --git a/packages/@aws-cdk/aws-kinesisfirehose-destinations/package.json b/packages/@aws-cdk/aws-kinesisfirehose-destinations/package.json index 92cb7c8aa4332..6633645989caf 100644 --- a/packages/@aws-cdk/aws-kinesisfirehose-destinations/package.json +++ b/packages/@aws-cdk/aws-kinesisfirehose-destinations/package.json @@ -71,17 +71,20 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", "jest": "^26.6.3", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/aws-lambda": "0.0.0", + "@aws-cdk/aws-lambda-nodejs": "0.0.0" }, "dependencies": { "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kinesisfirehose": "0.0.0", + "@aws-cdk/aws-kms": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/core": "0.0.0", @@ -91,6 +94,7 @@ "peerDependencies": { "@aws-cdk/aws-iam": "0.0.0", "@aws-cdk/aws-kinesisfirehose": "0.0.0", + "@aws-cdk/aws-kms": "0.0.0", "@aws-cdk/aws-logs": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/integ.s3-bucket.expected.json b/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/integ.s3-bucket.expected.json deleted file mode 100644 index 00bc62879e11e..0000000000000 --- a/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/integ.s3-bucket.expected.json +++ /dev/null @@ -1,408 +0,0 @@ -{ - "Resources": { - "Bucket83908E77": { - "Type": "AWS::S3::Bucket", - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "BucketPolicyE9A3008A": { - "Type": "AWS::S3::BucketPolicy", - "Properties": { - "Bucket": { - "Ref": "Bucket83908E77" - }, - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "s3:GetBucket*", - "s3:List*", - "s3:DeleteObject*" - ], - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::GetAtt": [ - "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", - "Arn" - ] - } - }, - "Resource": [ - { - "Fn::GetAtt": [ - "Bucket83908E77", - "Arn" - ] - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "Bucket83908E77", - "Arn" - ] - }, - "/*" - ] - ] - } - ] - } - ], - "Version": "2012-10-17" - } - } - }, - "BucketAutoDeleteObjectsCustomResourceBAFD23C2": { - "Type": "Custom::S3AutoDeleteObjects", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F", - "Arn" - ] - }, - "BucketName": { - "Ref": "Bucket83908E77" - } - }, - "DependsOn": [ - "BucketPolicyE9A3008A" - ], - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Version": "2012-10-17", - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ] - }, - "ManagedPolicyArns": [ - { - "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - } - ] - } - }, - "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "S3Bucket": { - "Ref": "AssetParameters1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1S3BucketF01ADF6B" - }, - "S3Key": { - "Fn::Join": [ - "", - [ - { - "Fn::Select": [ - 0, - { - "Fn::Split": [ - "||", - { - "Ref": "AssetParameters1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1S3VersionKey6FC34F51" - } - ] - } - ] - }, - { - "Fn::Select": [ - 1, - { - "Fn::Split": [ - "||", - { - "Ref": "AssetParameters1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1S3VersionKey6FC34F51" - } - ] - } - ] - } - ] - ] - } - }, - "Timeout": 900, - "MemorySize": 128, - "Handler": "__entrypoint__.handler", - "Role": { - "Fn::GetAtt": [ - "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", - "Arn" - ] - }, - "Runtime": "nodejs12.x", - "Description": { - "Fn::Join": [ - "", - [ - "Lambda function for auto-deleting objects in ", - { - "Ref": "Bucket83908E77" - }, - " S3 bucket." - ] - ] - } - }, - "DependsOn": [ - "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092" - ] - }, - "LogGroupF5B46931": { - "Type": "AWS::Logs::LogGroup", - "Properties": { - "RetentionInDays": 731 - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "LogGroupS3Destination70CE1003": { - "Type": "AWS::Logs::LogStream", - "Properties": { - "LogGroupName": { - "Ref": "LogGroupF5B46931" - } - }, - "UpdateReplacePolicy": "Retain", - "DeletionPolicy": "Retain" - }, - "DeliveryStreamServiceRole964EEBCC": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "firehose.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - } - } - }, - "DeliveryStreamS3DestinationRole500FC089": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "firehose.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - } - } - }, - "DeliveryStreamS3DestinationRoleDefaultPolicy3015D8C7": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*", - "s3:DeleteObject*", - "s3:PutObject", - "s3:Abort*" - ], - "Effect": "Allow", - "Resource": [ - { - "Fn::GetAtt": [ - "Bucket83908E77", - "Arn" - ] - }, - { - "Fn::Join": [ - "", - [ - { - "Fn::GetAtt": [ - "Bucket83908E77", - "Arn" - ] - }, - "/*" - ] - ] - } - ] - }, - { - "Action": [ - "logs:CreateLogStream", - "logs:PutLogEvents" - ], - "Effect": "Allow", - "Resource": { - "Fn::GetAtt": [ - "LogGroupF5B46931", - "Arn" - ] - } - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "DeliveryStreamS3DestinationRoleDefaultPolicy3015D8C7", - "Roles": [ - { - "Ref": "DeliveryStreamS3DestinationRole500FC089" - } - ] - } - }, - "DeliveryStreamF6D5572D": { - "Type": "AWS::KinesisFirehose::DeliveryStream", - "Properties": { - "DeliveryStreamType": "DirectPut", - "ExtendedS3DestinationConfiguration": { - "BucketARN": { - "Fn::GetAtt": [ - "Bucket83908E77", - "Arn" - ] - }, - "CloudWatchLoggingOptions": { - "Enabled": true, - "LogGroupName": { - "Ref": "LogGroupF5B46931" - }, - "LogStreamName": { - "Ref": "LogGroupS3Destination70CE1003" - } - }, - "RoleARN": { - "Fn::GetAtt": [ - "DeliveryStreamS3DestinationRole500FC089", - "Arn" - ] - } - } - }, - "DependsOn": [ - "DeliveryStreamS3DestinationRoleDefaultPolicy3015D8C7" - ] - } - }, - "Parameters": { - "AssetParameters1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1S3BucketF01ADF6B": { - "Type": "String", - "Description": "S3 bucket for asset \"1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1\"" - }, - "AssetParameters1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1S3VersionKey6FC34F51": { - "Type": "String", - "Description": "S3 key for asset version \"1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1\"" - }, - "AssetParameters1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1ArtifactHash9ECACDFD": { - "Type": "String", - "Description": "Artifact hash for asset \"1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1\"" - } - }, - "Mappings": { - "awscdkawskinesisfirehoseCidrBlocks": { - "af-south-1": { - "FirehoseCidrBlock": "13.244.121.224/27" - }, - "ap-east-1": { - "FirehoseCidrBlock": "18.162.221.32/27" - }, - "ap-northeast-1": { - "FirehoseCidrBlock": "13.113.196.224/27" - }, - "ap-northeast-2": { - "FirehoseCidrBlock": "13.209.1.64/27" - }, - "ap-northeast-3": { - "FirehoseCidrBlock": "13.208.177.192/27" - }, - "ap-south-1": { - "FirehoseCidrBlock": "13.232.67.32/27" - }, - "ap-southeast-1": { - "FirehoseCidrBlock": "13.228.64.192/27" - }, - "ap-southeast-2": { - "FirehoseCidrBlock": "13.210.67.224/27" - }, - "ca-central-1": { - "FirehoseCidrBlock": "35.183.92.128/27" - }, - "cn-north-1": { - "FirehoseCidrBlock": "52.81.151.32/27" - }, - "cn-northwest-1": { - "FirehoseCidrBlock": "161.189.23.64/27" - }, - "eu-central-1": { - "FirehoseCidrBlock": "35.158.127.160/27" - }, - "eu-north-1": { - "FirehoseCidrBlock": "13.53.63.224/27" - }, - "eu-south-1": { - "FirehoseCidrBlock": "15.161.135.128/27" - }, - "eu-west-1": { - "FirehoseCidrBlock": "52.19.239.192/27" - }, - "eu-west-2": { - "FirehoseCidrBlock": "18.130.1.96/27" - }, - "eu-west-3": { - "FirehoseCidrBlock": "35.180.1.96/27" - }, - "me-south-1": { - "FirehoseCidrBlock": "15.185.91.0/27" - }, - "sa-east-1": { - "FirehoseCidrBlock": "18.228.1.128/27" - }, - "us-east-1": { - "FirehoseCidrBlock": "52.70.63.192/27" - }, - "us-east-2": { - "FirehoseCidrBlock": "13.58.135.96/27" - }, - "us-gov-east-1": { - "FirehoseCidrBlock": "18.253.138.96/27" - }, - "us-gov-west-1": { - "FirehoseCidrBlock": "52.61.204.160/27" - }, - "us-west-1": { - "FirehoseCidrBlock": "13.57.135.192/27" - }, - "us-west-2": { - "FirehoseCidrBlock": "52.89.255.224/27" - } - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/integ.s3-bucket.lit.expected.json b/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/integ.s3-bucket.lit.expected.json new file mode 100644 index 0000000000000..2a85e28a6984d --- /dev/null +++ b/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/integ.s3-bucket.lit.expected.json @@ -0,0 +1,858 @@ +{ + "Resources": { + "Bucket83908E77": { + "Type": "AWS::S3::Bucket", + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "BucketPolicyE9A3008A": { + "Type": "AWS::S3::BucketPolicy", + "Properties": { + "Bucket": { + "Ref": "Bucket83908E77" + }, + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetBucket*", + "s3:List*", + "s3:DeleteObject*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + } + }, + "Resource": [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "BucketAutoDeleteObjectsCustomResourceBAFD23C2": { + "Type": "Custom::S3AutoDeleteObjects", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F", + "Arn" + ] + }, + "BucketName": { + "Ref": "Bucket83908E77" + } + }, + "DependsOn": [ + "BucketPolicyE9A3008A" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ] + } + }, + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "AssetParameters1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1S3BucketF01ADF6B" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1S3VersionKey6FC34F51" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1S3VersionKey6FC34F51" + } + ] + } + ] + } + ] + ] + } + }, + "Timeout": 900, + "MemorySize": 128, + "Handler": "__entrypoint__.handler", + "Role": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + }, + "Runtime": "nodejs12.x", + "Description": { + "Fn::Join": [ + "", + [ + "Lambda function for auto-deleting objects in ", + { + "Ref": "Bucket83908E77" + }, + " S3 bucket." + ] + ] + } + }, + "DependsOn": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092" + ] + }, + "BackupBucket26B8E51C": { + "Type": "AWS::S3::Bucket", + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "BackupBucketPolicy8C403F71": { + "Type": "AWS::S3::BucketPolicy", + "Properties": { + "Bucket": { + "Ref": "BackupBucket26B8E51C" + }, + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetBucket*", + "s3:List*", + "s3:DeleteObject*" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + } + }, + "Resource": [ + { + "Fn::GetAtt": [ + "BackupBucket26B8E51C", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "BackupBucket26B8E51C", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "BackupBucketAutoDeleteObjectsCustomResourceD2F511C5": { + "Type": "Custom::S3AutoDeleteObjects", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F", + "Arn" + ] + }, + "BucketName": { + "Ref": "BackupBucket26B8E51C" + } + }, + "DependsOn": [ + "BackupBucketPolicy8C403F71" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "LogGroupF5B46931": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "RetentionInDays": 731 + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "LogGroupS3Destination70CE1003": { + "Type": "AWS::Logs::LogStream", + "Properties": { + "LogGroupName": { + "Ref": "LogGroupF5B46931" + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "DataProcessorFunctionServiceRole12E05500": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "DataProcessorFunctionAD472B9A": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Ref": "AssetParameters5ee078f2a1957fe672d6cfd84faf49e07b8460758b5cd2669b3df1212a14cd19S3BucketFEDDFB43" + }, + "S3Key": { + "Fn::Join": [ + "", + [ + { + "Fn::Select": [ + 0, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters5ee078f2a1957fe672d6cfd84faf49e07b8460758b5cd2669b3df1212a14cd19S3VersionKey244C2747" + } + ] + } + ] + }, + { + "Fn::Select": [ + 1, + { + "Fn::Split": [ + "||", + { + "Ref": "AssetParameters5ee078f2a1957fe672d6cfd84faf49e07b8460758b5cd2669b3df1212a14cd19S3VersionKey244C2747" + } + ] + } + ] + } + ] + ] + } + }, + "Role": { + "Fn::GetAtt": [ + "DataProcessorFunctionServiceRole12E05500", + "Arn" + ] + }, + "Environment": { + "Variables": { + "AWS_NODEJS_CONNECTION_REUSE_ENABLED": "1" + } + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x", + "Timeout": 60 + }, + "DependsOn": [ + "DataProcessorFunctionServiceRole12E05500" + ] + }, + "Key961B73FD": { + "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": "*" + } + ], + "Version": "2012-10-17" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "BackupKey60B97760": { + "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": "*" + } + ], + "Version": "2012-10-17" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "DeliveryStreamServiceRole964EEBCC": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "firehose.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "DeliveryStreamS3DestinationRole500FC089": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "firehose.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "DeliveryStreamS3DestinationRoleDefaultPolicy3015D8C7": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*", + "s3:DeleteObject*", + "s3:PutObject", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "LogGroupF5B46931", + "Arn" + ] + } + }, + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*", + "s3:DeleteObject*", + "s3:PutObject", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "BackupBucket26B8E51C", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "BackupBucket26B8E51C", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "DeliveryStreamLogGroup9D8FA3BB", + "Arn" + ] + } + }, + { + "Action": [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "BackupKey60B97760", + "Arn" + ] + } + }, + { + "Action": "lambda:InvokeFunction", + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "DataProcessorFunctionAD472B9A", + "Arn" + ] + } + }, + { + "Action": [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "DeliveryStreamS3DestinationRoleDefaultPolicy3015D8C7", + "Roles": [ + { + "Ref": "DeliveryStreamS3DestinationRole500FC089" + } + ] + } + }, + "DeliveryStreamLogGroup9D8FA3BB": { + "Type": "AWS::Logs::LogGroup", + "Properties": { + "RetentionInDays": 731 + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "DeliveryStreamLogGroupS3BackupD5DF41B2": { + "Type": "AWS::Logs::LogStream", + "Properties": { + "LogGroupName": { + "Ref": "DeliveryStreamLogGroup9D8FA3BB" + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "DeliveryStreamF6D5572D": { + "Type": "AWS::KinesisFirehose::DeliveryStream", + "Properties": { + "DeliveryStreamType": "DirectPut", + "ExtendedS3DestinationConfiguration": { + "BucketARN": { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "BufferingHints": { + "IntervalInSeconds": 60, + "SizeInMBs": 1 + }, + "CloudWatchLoggingOptions": { + "Enabled": true, + "LogGroupName": { + "Ref": "LogGroupF5B46931" + }, + "LogStreamName": { + "Ref": "LogGroupS3Destination70CE1003" + } + }, + "CompressionFormat": "GZIP", + "EncryptionConfiguration": { + "KMSEncryptionConfig": { + "AWSKMSKeyARN": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + } + } + }, + "ErrorOutputPrefix": "errorPrefix", + "Prefix": "regularPrefix", + "ProcessingConfiguration": { + "Enabled": true, + "Processors": [ + { + "Parameters": [ + { + "ParameterName": "RoleArn", + "ParameterValue": { + "Fn::GetAtt": [ + "DeliveryStreamS3DestinationRole500FC089", + "Arn" + ] + } + }, + { + "ParameterName": "LambdaArn", + "ParameterValue": { + "Fn::GetAtt": [ + "DataProcessorFunctionAD472B9A", + "Arn" + ] + } + }, + { + "ParameterName": "BufferIntervalInSeconds", + "ParameterValue": "60" + }, + { + "ParameterName": "BufferSizeInMBs", + "ParameterValue": "1" + }, + { + "ParameterName": "NumberOfRetries", + "ParameterValue": "1" + } + ], + "Type": "Lambda" + } + ] + }, + "RoleARN": { + "Fn::GetAtt": [ + "DeliveryStreamS3DestinationRole500FC089", + "Arn" + ] + }, + "S3BackupConfiguration": { + "BucketARN": { + "Fn::GetAtt": [ + "BackupBucket26B8E51C", + "Arn" + ] + }, + "BufferingHints": { + "IntervalInSeconds": 60, + "SizeInMBs": 1 + }, + "CloudWatchLoggingOptions": { + "Enabled": true, + "LogGroupName": { + "Ref": "DeliveryStreamLogGroup9D8FA3BB" + }, + "LogStreamName": { + "Ref": "DeliveryStreamLogGroupS3BackupD5DF41B2" + } + }, + "CompressionFormat": "ZIP", + "EncryptionConfiguration": { + "KMSEncryptionConfig": { + "AWSKMSKeyARN": { + "Fn::GetAtt": [ + "BackupKey60B97760", + "Arn" + ] + } + } + }, + "ErrorOutputPrefix": "backupErrorPrefix", + "Prefix": "backupPrefix", + "RoleARN": { + "Fn::GetAtt": [ + "DeliveryStreamS3DestinationRole500FC089", + "Arn" + ] + } + }, + "S3BackupMode": "Enabled" + } + }, + "DependsOn": [ + "DeliveryStreamS3DestinationRoleDefaultPolicy3015D8C7" + ] + } + }, + "Parameters": { + "AssetParameters1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1S3BucketF01ADF6B": { + "Type": "String", + "Description": "S3 bucket for asset \"1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1\"" + }, + "AssetParameters1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1S3VersionKey6FC34F51": { + "Type": "String", + "Description": "S3 key for asset version \"1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1\"" + }, + "AssetParameters1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1ArtifactHash9ECACDFD": { + "Type": "String", + "Description": "Artifact hash for asset \"1a8becf42c48697a059094af1e94aa6bc6df0512d30433db8c22618ca02dfca1\"" + }, + "AssetParameters5ee078f2a1957fe672d6cfd84faf49e07b8460758b5cd2669b3df1212a14cd19S3BucketFEDDFB43": { + "Type": "String", + "Description": "S3 bucket for asset \"5ee078f2a1957fe672d6cfd84faf49e07b8460758b5cd2669b3df1212a14cd19\"" + }, + "AssetParameters5ee078f2a1957fe672d6cfd84faf49e07b8460758b5cd2669b3df1212a14cd19S3VersionKey244C2747": { + "Type": "String", + "Description": "S3 key for asset version \"5ee078f2a1957fe672d6cfd84faf49e07b8460758b5cd2669b3df1212a14cd19\"" + }, + "AssetParameters5ee078f2a1957fe672d6cfd84faf49e07b8460758b5cd2669b3df1212a14cd19ArtifactHashC1C6FCBC": { + "Type": "String", + "Description": "Artifact hash for asset \"5ee078f2a1957fe672d6cfd84faf49e07b8460758b5cd2669b3df1212a14cd19\"" + } + }, + "Mappings": { + "awscdkawskinesisfirehoseCidrBlocks": { + "af-south-1": { + "FirehoseCidrBlock": "13.244.121.224/27" + }, + "ap-east-1": { + "FirehoseCidrBlock": "18.162.221.32/27" + }, + "ap-northeast-1": { + "FirehoseCidrBlock": "13.113.196.224/27" + }, + "ap-northeast-2": { + "FirehoseCidrBlock": "13.209.1.64/27" + }, + "ap-northeast-3": { + "FirehoseCidrBlock": "13.208.177.192/27" + }, + "ap-south-1": { + "FirehoseCidrBlock": "13.232.67.32/27" + }, + "ap-southeast-1": { + "FirehoseCidrBlock": "13.228.64.192/27" + }, + "ap-southeast-2": { + "FirehoseCidrBlock": "13.210.67.224/27" + }, + "ca-central-1": { + "FirehoseCidrBlock": "35.183.92.128/27" + }, + "cn-north-1": { + "FirehoseCidrBlock": "52.81.151.32/27" + }, + "cn-northwest-1": { + "FirehoseCidrBlock": "161.189.23.64/27" + }, + "eu-central-1": { + "FirehoseCidrBlock": "35.158.127.160/27" + }, + "eu-north-1": { + "FirehoseCidrBlock": "13.53.63.224/27" + }, + "eu-south-1": { + "FirehoseCidrBlock": "15.161.135.128/27" + }, + "eu-west-1": { + "FirehoseCidrBlock": "52.19.239.192/27" + }, + "eu-west-2": { + "FirehoseCidrBlock": "18.130.1.96/27" + }, + "eu-west-3": { + "FirehoseCidrBlock": "35.180.1.96/27" + }, + "me-south-1": { + "FirehoseCidrBlock": "15.185.91.0/27" + }, + "sa-east-1": { + "FirehoseCidrBlock": "18.228.1.128/27" + }, + "us-east-1": { + "FirehoseCidrBlock": "52.70.63.192/27" + }, + "us-east-2": { + "FirehoseCidrBlock": "13.58.135.96/27" + }, + "us-gov-east-1": { + "FirehoseCidrBlock": "18.253.138.96/27" + }, + "us-gov-west-1": { + "FirehoseCidrBlock": "52.61.204.160/27" + }, + "us-west-1": { + "FirehoseCidrBlock": "13.57.135.192/27" + }, + "us-west-2": { + "FirehoseCidrBlock": "52.89.255.224/27" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/integ.s3-bucket.lit.ts b/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/integ.s3-bucket.lit.ts new file mode 100644 index 0000000000000..0527cbd26f7d7 --- /dev/null +++ b/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/integ.s3-bucket.lit.ts @@ -0,0 +1,71 @@ +#!/usr/bin/env node +import * as path from 'path'; +import * as firehose from '@aws-cdk/aws-kinesisfirehose'; +import * as kms from '@aws-cdk/aws-kms'; +import * as lambdanodejs from '@aws-cdk/aws-lambda-nodejs'; +import * as logs from '@aws-cdk/aws-logs'; +import * as s3 from '@aws-cdk/aws-s3'; +import * as cdk from '@aws-cdk/core'; +import * as destinations from '../lib'; + +const app = new cdk.App(); + +const stack = new cdk.Stack(app, 'aws-cdk-firehose-delivery-stream-s3-all-properties'); + +const bucket = new s3.Bucket(stack, 'Bucket', { + removalPolicy: cdk.RemovalPolicy.DESTROY, + autoDeleteObjects: true, +}); + +const backupBucket = new s3.Bucket(stack, 'BackupBucket', { + removalPolicy: cdk.RemovalPolicy.DESTROY, + autoDeleteObjects: true, +}); +const logGroup = new logs.LogGroup(stack, 'LogGroup', { + removalPolicy: cdk.RemovalPolicy.DESTROY, +}); + +const dataProcessorFunction = new lambdanodejs.NodejsFunction(stack, 'DataProcessorFunction', { + entry: path.join(__dirname, 'lambda-data-processor.js'), + timeout: cdk.Duration.minutes(1), +}); + +const processor = new firehose.LambdaFunctionProcessor(dataProcessorFunction, { + bufferInterval: cdk.Duration.seconds(60), + bufferSize: cdk.Size.mebibytes(1), + retries: 1, +}); + +const key = new kms.Key(stack, 'Key', { + removalPolicy: cdk.RemovalPolicy.DESTROY, +}); + +const backupKey = new kms.Key(stack, 'BackupKey', { + removalPolicy: cdk.RemovalPolicy.DESTROY, +}); + +new firehose.DeliveryStream(stack, 'Delivery Stream', { + destinations: [new destinations.S3Bucket(bucket, { + logging: true, + logGroup: logGroup, + processor: processor, + compression: destinations.Compression.GZIP, + dataOutputPrefix: 'regularPrefix', + errorOutputPrefix: 'errorPrefix', + bufferingInterval: cdk.Duration.seconds(60), + bufferingSize: cdk.Size.mebibytes(1), + encryptionKey: key, + s3Backup: { + mode: destinations.BackupMode.ALL, + bucket: backupBucket, + compression: destinations.Compression.ZIP, + dataOutputPrefix: 'backupPrefix', + errorOutputPrefix: 'backupErrorPrefix', + bufferingInterval: cdk.Duration.seconds(60), + bufferingSize: cdk.Size.mebibytes(1), + encryptionKey: backupKey, + }, + })], +}); + +app.synth(); diff --git a/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/integ.s3-bucket.ts b/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/integ.s3-bucket.ts deleted file mode 100644 index 222eaa6c0fb84..0000000000000 --- a/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/integ.s3-bucket.ts +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env node -import * as firehose from '@aws-cdk/aws-kinesisfirehose'; -import * as logs from '@aws-cdk/aws-logs'; -import * as s3 from '@aws-cdk/aws-s3'; -import * as cdk from '@aws-cdk/core'; -import * as destinations from '../lib'; - -const app = new cdk.App(); - -const stack = new cdk.Stack(app, 'aws-cdk-firehose-delivery-stream-s3-all-properties'); - -const bucket = new s3.Bucket(stack, 'Bucket', { - removalPolicy: cdk.RemovalPolicy.DESTROY, - autoDeleteObjects: true, -}); - -const logGroup = new logs.LogGroup(stack, 'LogGroup', { - removalPolicy: cdk.RemovalPolicy.DESTROY, -}); - -new firehose.DeliveryStream(stack, 'Delivery Stream', { - destinations: [new destinations.S3Bucket(bucket, { - logging: true, - logGroup: logGroup, - })], -}); - -app.synth(); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/lambda-data-processor.js b/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/lambda-data-processor.js new file mode 100644 index 0000000000000..90acfda02abeb --- /dev/null +++ b/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/lambda-data-processor.js @@ -0,0 +1,11 @@ +export async function handler(event, context) { + /* Process the list of records and transform them */ + const output = event.records.map((record) => ({ + /* This transformation is the "identity" transformation, the data is left intact */ + recordId: record.recordId, + result: 'Ok', + data: record.data, + })); + console.log(`Processing completed. Successful records ${output.length}.`); + return { records: output }; +}; diff --git a/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/s3-bucket.test.ts b/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/s3-bucket.test.ts index 50e891b3091d1..448d0b8efcf40 100644 --- a/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/s3-bucket.test.ts +++ b/packages/@aws-cdk/aws-kinesisfirehose-destinations/test/s3-bucket.test.ts @@ -1,7 +1,8 @@ -import '@aws-cdk/assert-internal/jest'; -import { ABSENT, MatchStyle, ResourcePart, anything, arrayWith } from '@aws-cdk/assert-internal'; +import { Match, Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; import * as firehose from '@aws-cdk/aws-kinesisfirehose'; +import * as kms from '@aws-cdk/aws-kms'; +import * as lambda from '@aws-cdk/aws-lambda'; import * as logs from '@aws-cdk/aws-logs'; import * as s3 from '@aws-cdk/aws-s3'; import * as cdk from '@aws-cdk/core'; @@ -25,19 +26,17 @@ describe('S3 destination', () => { destinations: [new firehosedestinations.S3Bucket(bucket, { role: destinationRole })], }); - expect(stack).toHaveResource('AWS::KinesisFirehose::DeliveryStream', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { ExtendedS3DestinationConfiguration: { BucketARN: stack.resolve(bucket.bucketArn), CloudWatchLoggingOptions: { Enabled: true, - LogGroupName: anything(), - LogStreamName: anything(), }, RoleARN: stack.resolve(destinationRole.roleArn), }, }); - expect(stack).toHaveResource('AWS::Logs::LogGroup'); - expect(stack).toHaveResource('AWS::Logs::LogStream'); + Template.fromStack(stack).resourceCountIs('AWS::Logs::LogGroup', 1); + Template.fromStack(stack).resourceCountIs('AWS::Logs::LogStream', 1); }); it('creates a role when none is provided', () => { @@ -46,7 +45,7 @@ describe('S3 destination', () => { destinations: [new firehosedestinations.S3Bucket(bucket)], }); - expect(stack).toHaveResourceLike('AWS::KinesisFirehose::DeliveryStream', { + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { ExtendedS3DestinationConfiguration: { RoleARN: { 'Fn::GetAtt': [ @@ -56,11 +55,19 @@ describe('S3 destination', () => { }, }, }); - expect(stack).toMatchTemplate({ - ['DeliveryStreamS3DestinationRoleD96B8345']: { - Type: 'AWS::IAM::Role', + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Effect: 'Allow', + Principal: { + Service: 'firehose.amazonaws.com', + }, + Action: 'sts:AssumeRole', + }, + ], }, - }, MatchStyle.SUPERSET); + }); }); it('grants read/write access to the bucket', () => { @@ -70,10 +77,10 @@ describe('S3 destination', () => { destinations: [destination], }); - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { Roles: [stack.resolve(destinationRole.roleName)], PolicyDocument: { - Statement: [ + Statement: Match.arrayWith([ { Action: [ 's3:GetObject*', @@ -89,7 +96,7 @@ describe('S3 destination', () => { { 'Fn::Join': ['', [stack.resolve(bucket.bucketArn), '/*']] }, ], }, - ], + ]), }, }); }); @@ -101,7 +108,7 @@ describe('S3 destination', () => { destinations: [destination], }); - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyName: 'DestinationRoleDefaultPolicy1185C75D', Roles: [stack.resolve(destinationRole.roleName)], PolicyDocument: { @@ -132,9 +139,9 @@ describe('S3 destination', () => { ], }, }); - expect(stack).toHaveResourceLike('AWS::KinesisFirehose::DeliveryStream', { + Template.fromStack(stack).hasResource('AWS::KinesisFirehose::DeliveryStream', { DependsOn: ['DestinationRoleDefaultPolicy1185C75D'], - }, ResourcePart.CompleteDefinition); + }); }); describe('logging', () => { @@ -143,14 +150,12 @@ describe('S3 destination', () => { destinations: [new firehosedestinations.S3Bucket(bucket)], }); - expect(stack).toHaveResource('AWS::Logs::LogGroup'); - expect(stack).toHaveResource('AWS::Logs::LogStream'); - expect(stack).toHaveResourceLike('AWS::KinesisFirehose::DeliveryStream', { + Template.fromStack(stack).resourceCountIs('AWS::Logs::LogGroup', 1); + Template.fromStack(stack).resourceCountIs('AWS::Logs::LogStream', 1); + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { ExtendedS3DestinationConfiguration: { CloudWatchLoggingOptions: { Enabled: true, - LogGroupName: anything(), - LogStreamName: anything(), }, }, }); @@ -161,10 +166,10 @@ describe('S3 destination', () => { destinations: [new firehosedestinations.S3Bucket(bucket, { logging: false })], }); - expect(stack).not.toHaveResource('AWS::Logs::LogGroup'); - expect(stack).toHaveResourceLike('AWS::KinesisFirehose::DeliveryStream', { + Template.fromStack(stack).resourceCountIs('AWS::Logs::LogGroup', 0); + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { ExtendedS3DestinationConfiguration: { - CloudWatchLoggingOptions: ABSENT, + CloudWatchLoggingOptions: Match.absentProperty(), }, }); }); @@ -176,13 +181,12 @@ describe('S3 destination', () => { destinations: [new firehosedestinations.S3Bucket(bucket, { logGroup })], }); - expect(stack).toCountResources('AWS::Logs::LogGroup', 1); - expect(stack).toHaveResourceLike('AWS::KinesisFirehose::DeliveryStream', { + Template.fromStack(stack).resourceCountIs('AWS::Logs::LogGroup', 1); + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { ExtendedS3DestinationConfiguration: { CloudWatchLoggingOptions: { Enabled: true, LogGroupName: stack.resolve(logGroup.logGroupName), - LogStreamName: anything(), }, }, }); @@ -203,10 +207,10 @@ describe('S3 destination', () => { destinations: [new firehosedestinations.S3Bucket(bucket, { logGroup, role: destinationRole })], }); - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { Roles: [stack.resolve(destinationRole.roleName)], PolicyDocument: { - Statement: arrayWith( + Statement: Match.arrayWith([ { Action: [ 'logs:CreateLogStream', @@ -215,7 +219,383 @@ describe('S3 destination', () => { Effect: 'Allow', Resource: stack.resolve(logGroup.logGroupArn), }, - ), + ]), + }, + }); + }); + }); + + describe('processing configuration', () => { + let lambdaFunction: lambda.IFunction; + let basicLambdaProcessor: firehose.LambdaFunctionProcessor; + let destinationWithBasicLambdaProcessor: firehosedestinations.S3Bucket; + + beforeEach(() => { + lambdaFunction = new lambda.Function(stack, 'DataProcessorFunction', { + runtime: lambda.Runtime.NODEJS_12_X, + code: lambda.Code.fromInline('foo'), + handler: 'bar', + }); + basicLambdaProcessor = new firehose.LambdaFunctionProcessor(lambdaFunction); + destinationWithBasicLambdaProcessor = new firehosedestinations.S3Bucket(bucket, { + role: destinationRole, + processor: basicLambdaProcessor, + }); + }); + + it('creates configuration for LambdaFunctionProcessor', () => { + new firehose.DeliveryStream(stack, 'DeliveryStream', { + destinations: [destinationWithBasicLambdaProcessor], + }); + + Template.fromStack(stack).resourceCountIs('AWS::Lambda::Function', 1); + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { + ExtendedS3DestinationConfiguration: { + ProcessingConfiguration: { + Enabled: true, + Processors: [{ + Type: 'Lambda', + Parameters: [ + { + ParameterName: 'RoleArn', + ParameterValue: stack.resolve(destinationRole.roleArn), + }, + { + ParameterName: 'LambdaArn', + ParameterValue: stack.resolve(lambdaFunction.functionArn), + }, + ], + }], + }, + }, + }); + }); + + it('set all optional parameters', () => { + const processor = new firehose.LambdaFunctionProcessor(lambdaFunction, { + bufferInterval: cdk.Duration.minutes(1), + bufferSize: cdk.Size.mebibytes(1), + retries: 5, + }); + const destination = new firehosedestinations.S3Bucket(bucket, { + role: destinationRole, + processor: processor, + }); + new firehose.DeliveryStream(stack, 'DeliveryStream', { + destinations: [destination], + }); + + Template.fromStack(stack).resourceCountIs('AWS::Lambda::Function', 1); + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { + ExtendedS3DestinationConfiguration: { + ProcessingConfiguration: { + Enabled: true, + Processors: [{ + Type: 'Lambda', + Parameters: [ + { + ParameterName: 'RoleArn', + ParameterValue: stack.resolve(destinationRole.roleArn), + }, + { + ParameterName: 'LambdaArn', + ParameterValue: stack.resolve(lambdaFunction.functionArn), + }, + { + ParameterName: 'BufferIntervalInSeconds', + ParameterValue: '60', + }, + { + ParameterName: 'BufferSizeInMBs', + ParameterValue: '1', + }, + { + ParameterName: 'NumberOfRetries', + ParameterValue: '5', + }, + ], + }], + }, + }, + }); + }); + + it('grants invoke access to the lambda function and delivery stream depends on grant', () => { + new firehose.DeliveryStream(stack, 'DeliveryStream', { + destinations: [destinationWithBasicLambdaProcessor], + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyName: 'DestinationRoleDefaultPolicy1185C75D', + Roles: [stack.resolve(destinationRole.roleName)], + PolicyDocument: { + Statement: Match.arrayWith([ + { + Action: 'lambda:InvokeFunction', + Effect: 'Allow', + Resource: stack.resolve(lambdaFunction.functionArn), + }, + ]), + }, + }); + Template.fromStack(stack).hasResource('AWS::KinesisFirehose::DeliveryStream', { + DependsOn: ['DestinationRoleDefaultPolicy1185C75D'], + }); + }); + }); + + describe('compression', () => { + it('configures when specified', () => { + const destination = new firehosedestinations.S3Bucket(bucket, { + compression: firehosedestinations.Compression.GZIP, + }); + new firehose.DeliveryStream(stack, 'DeliveryStream', { + destinations: [destination], + }); + + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { + ExtendedS3DestinationConfiguration: { + CompressionFormat: 'GZIP', + }, + }); + }); + + it('allows custom compression types', () => { + const destination = new firehosedestinations.S3Bucket(bucket, { + compression: firehosedestinations.Compression.of('SNAZZY'), + }); + new firehose.DeliveryStream(stack, 'DeliveryStream', { + destinations: [destination], + }); + + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { + ExtendedS3DestinationConfiguration: { + CompressionFormat: 'SNAZZY', + }, + }); + }); + }); + + describe('buffering', () => { + it('creates configuration when interval and size provided', () => { + new firehose.DeliveryStream(stack, 'DeliveryStream', { + destinations: [new firehosedestinations.S3Bucket(bucket, { + bufferingInterval: cdk.Duration.minutes(1), + bufferingSize: cdk.Size.mebibytes(1), + })], + }); + + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { + ExtendedS3DestinationConfiguration: { + BufferingHints: { + IntervalInSeconds: 60, + SizeInMBs: 1, + }, + }, + }); + }); + + it('validates bufferingInterval', () => { + expect(() => new firehose.DeliveryStream(stack, 'DeliveryStream', { + destinations: [new firehosedestinations.S3Bucket(bucket, { + bufferingInterval: cdk.Duration.seconds(30), + bufferingSize: cdk.Size.mebibytes(1), + })], + })).toThrowError('Buffering interval must be between 60 and 900 seconds. Buffering interval provided was 30 seconds.'); + + expect(() => new firehose.DeliveryStream(stack, 'DeliveryStream2', { + destinations: [new firehosedestinations.S3Bucket(bucket, { + bufferingInterval: cdk.Duration.minutes(16), + bufferingSize: cdk.Size.mebibytes(1), + })], + })).toThrowError('Buffering interval must be between 60 and 900 seconds. Buffering interval provided was 960 seconds.'); + }); + + it('validates bufferingSize', () => { + expect(() => new firehose.DeliveryStream(stack, 'DeliveryStream', { + destinations: [new firehosedestinations.S3Bucket(bucket, { + bufferingInterval: cdk.Duration.minutes(1), + bufferingSize: cdk.Size.mebibytes(0), + + })], + })).toThrowError('Buffering size must be between 1 and 128 MiBs. Buffering size provided was 0 MiBs'); + + expect(() => new firehose.DeliveryStream(stack, 'DeliveryStream2', { + destinations: [new firehosedestinations.S3Bucket(bucket, { + bufferingInterval: cdk.Duration.minutes(1), + bufferingSize: cdk.Size.mebibytes(256), + })], + })).toThrowError('Buffering size must be between 1 and 128 MiBs. Buffering size provided was 256 MiBs'); + }); + }); + + describe('destination encryption', () => { + it('creates configuration', () => { + const key = new kms.Key(stack, 'Key'); + + new firehose.DeliveryStream(stack, 'DeliveryStream', { + destinations: [new firehosedestinations.S3Bucket(bucket, { + encryptionKey: key, + role: destinationRole, + })], + }); + + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { + ExtendedS3DestinationConfiguration: { + EncryptionConfiguration: { + KMSEncryptionConfig: { + AWSKMSKeyARN: stack.resolve(key.keyArn), + }, + }, + }, + }); + }); + + it('grants encrypt/decrypt access to the destination encryptionKey', () => { + const key = new kms.Key(stack, 'Key'); + + new firehose.DeliveryStream(stack, 'DeliveryStream', { + destinations: [new firehosedestinations.S3Bucket(bucket, { + encryptionKey: key, + role: destinationRole, + })], + }); + + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + Roles: [stack.resolve(destinationRole.roleName)], + PolicyDocument: { + Statement: Match.arrayWith([{ + Action: [ + 'kms:Decrypt', + 'kms:Encrypt', + 'kms:ReEncrypt*', + 'kms:GenerateDataKey*', + ], + Effect: 'Allow', + Resource: stack.resolve(key.keyArn), + }]), + }, + }); + }); + }); + + describe('s3 backup configuration', () => { + it('set backupMode to ALL creates resources', () => { + const destination = new firehosedestinations.S3Bucket(bucket, { + role: destinationRole, + s3Backup: { + mode: firehosedestinations.BackupMode.ALL, + }, + }); + new firehose.DeliveryStream(stack, 'DeliveryStream', { + destinations: [destination], + }); + + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { + ExtendedS3DestinationConfiguration: { + S3BackupConfiguration: { + CloudWatchLoggingOptions: { + Enabled: true, + }, + RoleARN: stack.resolve(destinationRole.roleArn), + }, + S3BackupMode: 'Enabled', + }, + }); + }); + + it('sets backup configuration if backup bucket provided', () => { + const backupBucket = new s3.Bucket(stack, 'MyBackupBucket'); + const destination = new firehosedestinations.S3Bucket(bucket, { + role: destinationRole, + s3Backup: { + bucket: backupBucket, + }, + }); + new firehose.DeliveryStream(stack, 'DeliveryStream', { + destinations: [destination], + }); + + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { + ExtendedS3DestinationConfiguration: { + S3BackupConfiguration: { + BucketARN: stack.resolve(backupBucket.bucketArn), + CloudWatchLoggingOptions: { + Enabled: true, + }, + RoleARN: stack.resolve(destinationRole.roleArn), + }, + S3BackupMode: 'Enabled', + }, + }); + }); + + it('throws error if backupMode set to FAILED', () => { + expect(() => new firehosedestinations.S3Bucket(bucket, { + role: destinationRole, + s3Backup: { + mode: firehosedestinations.BackupMode.FAILED, + }, + })).toThrowError('S3 destinations do not support BackupMode.FAILED'); + }); + + it('by default does not create resources', () => { + const destination = new firehosedestinations.S3Bucket(bucket); + new firehose.DeliveryStream(stack, 'DeliveryStream', { + destinations: [destination], + }); + + Template.fromStack(stack).resourceCountIs('AWS::S3::Bucket', 1); + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { + ExtendedS3DestinationConfiguration: { + S3BackupConfiguration: Match.absentProperty(), + }, + }); + }); + + it('sets full backup configuration', () => { + const backupBucket = new s3.Bucket(stack, 'MyBackupBucket'); + const key = new kms.Key(stack, 'Key'); + const logGroup = new logs.LogGroup(stack, 'BackupLogGroup'); + const destination = new firehosedestinations.S3Bucket(bucket, { + role: destinationRole, + s3Backup: { + mode: firehosedestinations.BackupMode.ALL, + bucket: backupBucket, + dataOutputPrefix: 'myBackupPrefix', + errorOutputPrefix: 'myBackupErrorPrefix', + bufferingSize: cdk.Size.mebibytes(1), + bufferingInterval: cdk.Duration.minutes(1), + compression: firehosedestinations.Compression.ZIP, + encryptionKey: key, + logging: true, + logGroup: logGroup, + }, + }); + new firehose.DeliveryStream(stack, 'DeliveryStream', { + destinations: [destination], + }); + + Template.fromStack(stack).hasResourceProperties('AWS::KinesisFirehose::DeliveryStream', { + ExtendedS3DestinationConfiguration: { + S3BackupConfiguration: { + BucketARN: stack.resolve(backupBucket.bucketArn), + CloudWatchLoggingOptions: { + Enabled: true, + LogGroupName: stack.resolve(logGroup.logGroupName), + }, + RoleARN: stack.resolve(destinationRole.roleArn), + EncryptionConfiguration: { + KMSEncryptionConfig: { + AWSKMSKeyARN: stack.resolve(key.keyArn), + }, + }, + Prefix: 'myBackupPrefix', + ErrorOutputPrefix: 'myBackupErrorPrefix', + BufferingHints: {}, + CompressionFormat: 'ZIP', + }, + S3BackupMode: 'Enabled', }, }); }); diff --git a/packages/@aws-cdk/aws-kinesisfirehose/README.md b/packages/@aws-cdk/aws-kinesisfirehose/README.md index 5034ac4a0765f..936fcdc881a86 100644 --- a/packages/@aws-cdk/aws-kinesisfirehose/README.md +++ b/packages/@aws-cdk/aws-kinesisfirehose/README.md @@ -63,11 +63,27 @@ The above example defines the following resources: ## Sources There are two main methods of sourcing input data: Kinesis Data Streams and via a "direct -put". This construct library currently only supports "direct put". See [#15500](https://github.com/aws/aws-cdk/issues/15500) to track the status of adding support for Kinesis Data Streams. +put". See: [Sending Data to a Delivery Stream](https://docs.aws.amazon.com/firehose/latest/dev/basic-write.html) in the *Kinesis Data Firehose Developer Guide*. +### Kinesis Data Stream + +A delivery stream can read directly from a Kinesis data stream as a consumer of the data +stream. Configure this behaviour by providing a data stream in the `sourceStream` +property when constructing a delivery stream: + +```ts fixture=with-destination +import * as kinesis from '@aws-cdk/aws-kinesis'; + +const sourceStream = new kinesis.Stream(this, 'Source Stream'); +new DeliveryStream(this, 'Delivery Stream', { + sourceStream: sourceStream, + destinations: [destination], +}); +``` + ### Direct Put Data must be provided via "direct put", ie., by using a `PutRecord` or `PutRecordBatch` API call. There are a number of ways of doing @@ -109,6 +125,63 @@ new DeliveryStream(this, 'Delivery Stream', { }); ``` +The S3 destination also supports custom dynamic prefixes. `prefix` will be used for files +successfully delivered to S3. `errorOutputPrefix` will be added to failed records before +writing them to S3. + +```ts fixture=with-bucket +const s3Destination = new destinations.S3Bucket(bucket, { + dataOutputPrefix: 'myFirehose/DeliveredYear=!{timestamp:yyyy}/anyMonth/rand=!{firehose:random-string}', + errorOutputPrefix: 'myFirehoseFailures/!{firehose:error-output-type}/!{timestamp:yyyy}/anyMonth/!{timestamp:dd}', +}); +``` + +See: [Custom S3 Prefixes](https://docs.aws.amazon.com/firehose/latest/dev/s3-prefixes.html) in the *Kinesis Data Firehose Developer Guide*. + +## Server-side Encryption + +Enabling server-side encryption (SSE) requires Kinesis Data Firehose to encrypt all data +sent to delivery stream when it is stored at rest. This means that data is encrypted +before being written to the service's internal storage layer and decrypted after it is +received from the internal storage layer. The service manages keys and cryptographic +operations so that sources and destinations do not need to, as the data is encrypted and +decrypted at the boundaries of the service (ie., before the data is delivered to a +destination). By default, delivery streams do not have SSE enabled. + +The Key Management Service (KMS) Customer Managed Key (CMK) used for SSE can either be +AWS-owned or customer-managed. AWS-owned CMKs are keys that an AWS service (in this case +Kinesis Data Firehose) owns and manages for use in multiple AWS accounts. As a customer, +you cannot view, use, track, or manage these keys, and you are not charged for their +use. On the other hand, customer-managed CMKs are keys that are created and owned within +your account and managed entirely by you. As a customer, you are responsible for managing +access, rotation, aliases, and deletion for these keys, and you are changed for their +use. See: [Customer master keys](https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys) +in the *KMS Developer Guide*. + +```ts fixture=with-destination +import * as kms from '@aws-cdk/aws-kms'; + +// SSE with an AWS-owned CMK +new DeliveryStream(this, 'Delivery Stream AWS Owned', { + encryption: StreamEncryption.AWS_OWNED, + destinations: [destination], +}); +// SSE with an customer-managed CMK that is created automatically by the CDK +new DeliveryStream(this, 'Delivery Stream Implicit Customer Managed', { + encryption: StreamEncryption.CUSTOMER_MANAGED, + destinations: [destination], +}); +// SSE with an customer-managed CMK that is explicitly specified +const key = new kms.Key(this, 'Key'); +new DeliveryStream(this, 'Delivery Stream Explicit Customer Managed', { + encryptionKey: key, + destinations: [destination], +}); +``` + +See: [Data Protection](https://docs.aws.amazon.com/firehose/latest/dev/encryption.html) in +the *Kinesis Data Firehose Developer Guide*. + ## Monitoring Kinesis Data Firehose is integrated with CloudWatch, so you can monitor the performance of @@ -152,6 +225,215 @@ new DeliveryStream(this, 'Delivery Stream', { See: [Monitoring using CloudWatch Logs](https://docs.aws.amazon.com/firehose/latest/dev/monitoring-with-cloudwatch-logs.html) in the *Kinesis Data Firehose Developer Guide*. +### Metrics + +Kinesis Data Firehose sends metrics to CloudWatch so that you can collect and analyze the +performance of the delivery stream, including data delivery, data ingestion, data +transformation, format conversion, API usage, encryption, and resource usage. You can then +use CloudWatch alarms to alert you, for example, when data freshness (the age of the +oldest record in the delivery stream) exceeds the buffering limit (indicating that data is +not being delivered to your destination), or when the rate of incoming records exceeds the +limit of records per second (indicating data is flowing into your delivery stream faster +than it is configured to process). + +CDK provides methods for accessing delivery stream metrics with default configuration, +such as `metricIncomingBytes`, and `metricIncomingRecords` (see [`IDeliveryStream`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-kinesisfirehose.IDeliveryStream.html) +for a full list). CDK also provides a generic `metric` method that can be used to produce +metric configurations for any metric provided by Kinesis Data Firehose; the configurations +are pre-populated with the correct dimensions for the delivery stream. + +```ts fixture=with-delivery-stream +import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; + +// Alarm that triggers when the per-second average of incoming bytes exceeds 90% of the current service limit +const incomingBytesPercentOfLimit = new cloudwatch.MathExpression({ + expression: 'incomingBytes / 300 / bytePerSecLimit', + usingMetrics: { + incomingBytes: deliveryStream.metricIncomingBytes({ statistic: cloudwatch.Statistic.SUM }), + bytePerSecLimit: deliveryStream.metric('BytesPerSecondLimit'), + }, +}); +new cloudwatch.Alarm(this, 'Alarm', { + metric: incomingBytesPercentOfLimit, + threshold: 0.9, + evaluationPeriods: 3, +}); +``` + +See: [Monitoring Using CloudWatch Metrics](https://docs.aws.amazon.com/firehose/latest/dev/monitoring-with-cloudwatch-metrics.html) +in the *Kinesis Data Firehose Developer Guide*. + +## Compression + +Your data can automatically be compressed when it is delivered to S3 as either a final or +an intermediary/backup destination. Supported compression formats are: gzip, Snappy, +Hadoop-compatible Snappy, and ZIP, except for Redshift destinations, where Snappy +(regardless of Hadoop-compatibility) and ZIP are not supported. By default, data is +delivered to S3 without compression. + +```ts fixture=with-bucket +// Compress data delivered to S3 using Snappy +const s3Destination = new destinations.S3Bucket(bucket, { + compression: Compression.SNAPPY, +}); +new DeliveryStream(this, 'Delivery Stream', { + destinations: [destination], +}); +``` + +## Buffering + +Incoming data is buffered before it is delivered to the specified destination. The +delivery stream will wait until the amount of incoming data has exceeded some threshold +(the "buffer size") or until the time since the last data delivery occurred exceeds some +threshold (the "buffer interval"), whichever happens first. You can configure these +thresholds based on the capabilities of the destination and your use-case. By default, the +buffer size is 5 MiB and the buffer interval is 5 minutes. + +```ts fixture=with-bucket +import * as cdk from '@aws-cdk/core'; + +// Increase the buffer interval and size to 10 minutes and 8 MiB, respectively +const destination = new destinations.S3Bucket(bucket, { + bufferingInterval: cdk.Duration.minutes(10), + bufferingSize: cdk.Size.mebibytes(8), +}); +new DeliveryStream(this, 'Delivery Stream', { + destinations: [destination], +}); +``` + +See: [Data Delivery Frequency](https://docs.aws.amazon.com/firehose/latest/dev/basic-deliver.html#frequency) +in the *Kinesis Data Firehose Developer Guide*. + +## Destination Encryption + +Your data can be automatically encrypted when it is delivered to S3 as a final or +an intermediary/backup destination. Kinesis Data Firehose supports Amazon S3 server-side +encryption with AWS Key Management Service (AWS KMS) for encrypting delivered data +in Amazon S3. You can choose to not encrypt the data or to encrypt with a key from +the list of AWS KMS keys that you own. For more information, see [Protecting Data +Using Server-Side Encryption with AWS KMS–Managed Keys (SSE-KMS)](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html). Data is not encrypted by default. + +```ts fixture=with-bucket +import * as cdk from '@aws-cdk/core'; +import * as kms from '@aws-cdk/aws-kms'; + +const destination = new destinations.S3Bucket(bucket, { + encryptionKey: new kms.Key(this, 'MyKey'), +}); +new DeliveryStream(this, 'Delivery Stream', { + destinations: [destination], +}); +``` + +## Backup + +A delivery stream can be configured to backup data to S3 that it attempted to deliver to +the configured destination. Backed up data can be all the data that the delivery stream +attempted to deliver or just data that it failed to deliver (Redshift and S3 destinations +can only backup all data). CDK can create a new S3 bucket where it will back up data or +you can provide a bucket where data will be backed up. You can also provide a prefix under +which your backed-up data will be placed within the bucket. By default, source data is not +backed up to S3. + +```ts fixture=with-bucket +import * as destinations from '@aws-cdk/aws-kinesisfirehose-destinations'; +import * as s3 from '@aws-cdk/aws-s3'; + +// Enable backup of all source records (to an S3 bucket created by CDK). +new DeliveryStream(this, 'Delivery Stream Backup All', { + destinations: [ + new destinations.S3Bucket(bucket, { + s3Backup: { + mode: BackupMode.ALL, + } + }), + ], +}); +// Explicitly provide an S3 bucket to which all source records will be backed up. +const backupBucket = new s3.Bucket(this, 'Bucket'); +new DeliveryStream(this, 'Delivery Stream Backup All Explicit Bucket', { + destinations: [ + new destinations.S3Bucket(bucket, { + s3Backup: { + bucket: backupBucket, + } + }), + ], +}); +// Explicitly provide an S3 prefix under which all source records will be backed up. +new DeliveryStream(this, 'Delivery Stream Backup All Explicit Prefix', { + destinations: [ + new destinations.S3Bucket(bucket, { + s3Backup: { + mode: BackupMode.ALL, + dataOutputPrefix: 'mybackup', + }, + }), + ], +}); +``` + +If any Data Processing or Transformation is configured on your Delivery Stream, the source +records will be backed up in their original format. + +## Data Processing/Transformation + +Data can be transformed before being delivered to destinations. There are two types of +data processing for delivery streams: record transformation with AWS Lambda, and record +format conversion using a schema stored in an AWS Glue table. If both types of data +processing are configured, then the Lambda transformation is performed first. By default, +no data processing occurs. This construct library currently only supports data +transformation with AWS Lambda. See [#15501](https://github.com/aws/aws-cdk/issues/15501) +to track the status of adding support for record format conversion. + +### Data transformation with AWS Lambda + +To transform the data, Kinesis Data Firehose will call a Lambda function that you provide +and deliver the data returned in place of the source record. The function must return a +result that contains records in a specific format, including the following fields: + +- `recordId` -- the ID of the input record that corresponds the results. +- `result` -- the status of the transformation of the record: "Ok" (success), "Dropped" + (not processed intentionally), or "ProcessingFailed" (not processed due to an error). +- `data` -- the transformed data, Base64-encoded. + +The data is buffered up to 1 minute and up to 3 MiB by default before being sent to the +function, but can be configured using `bufferInterval` and `bufferSize` in the processor +configuration (see: [Buffering](#buffering)). If the function invocation fails due to a +network timeout or because of hitting an invocation limit, the invocation is retried 3 +times by default, but can be configured using `retries` in the processor configuration. + +```ts fixture=with-bucket +import * as cdk from '@aws-cdk/core'; +import * as lambda from '@aws-cdk/aws-lambda'; + +// Provide a Lambda function that will transform records before delivery, with custom +// buffering and retry configuration +const lambdaFunction = new lambda.Function(this, 'Processor', { + runtime: lambda.Runtime.NODEJS_12_X, + handler: 'index.handler', + code: lambda.Code.fromAsset(path.join(__dirname, 'process-records')), +}); +const lambdaProcessor = new LambdaFunctionProcessor(lambdaFunction, { + bufferingInterval: cdk.Duration.minutes(5), + bufferingSize: cdk.Size.mebibytes(5), + retries: 5, +}); +const s3Destination = new destinations.S3Bucket(bucket, { + processor: lambdaProcessor, +}); +new DeliveryStream(this, 'Delivery Stream', { + destinations: [destination], +}); +``` + +[Example Lambda data processor performing the identity transformation.](../aws-kinesisfirehose-destinations/test/integ.s3-bucket.lit.ts) + +See: [Data Transformation](https://docs.aws.amazon.com/firehose/latest/dev/data-transformation.html) +in the *Kinesis Data Firehose Developer Guide*. + ## Specifying an IAM role The DeliveryStream class automatically creates IAM service roles with all the minimum @@ -208,6 +490,7 @@ can be granted permissions to a delivery stream by calling: ```ts fixture=with-delivery-stream import * as iam from '@aws-cdk/aws-iam'; + const lambdaRole = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), }); diff --git a/packages/@aws-cdk/aws-kinesisfirehose/lib/delivery-stream.ts b/packages/@aws-cdk/aws-kinesisfirehose/lib/delivery-stream.ts index 4968930808be6..7dfaed8eb384b 100644 --- a/packages/@aws-cdk/aws-kinesisfirehose/lib/delivery-stream.ts +++ b/packages/@aws-cdk/aws-kinesisfirehose/lib/delivery-stream.ts @@ -1,10 +1,13 @@ import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; +import * as kinesis from '@aws-cdk/aws-kinesis'; +import * as kms from '@aws-cdk/aws-kms'; import * as cdk from '@aws-cdk/core'; import { RegionInfo } from '@aws-cdk/region-info'; import { Construct, Node } from 'constructs'; import { IDestination } from './destination'; +import { FirehoseMetrics } from './kinesisfirehose-canned-metrics.generated'; import { CfnDeliveryStream } from './kinesisfirehose.generated'; const PUT_RECORD_ACTIONS = [ @@ -44,6 +47,43 @@ export interface IDeliveryStream extends cdk.IResource, iam.IGrantable, ec2.ICon * Return the given named metric for this delivery stream. */ metric(metricName: string, props?: cloudwatch.MetricOptions): cloudwatch.Metric; + + /** + * Metric for the number of bytes ingested successfully into the delivery stream over the specified time period after throttling. + * + * By default, this metric will be calculated as an average over a period of 5 minutes. + */ + metricIncomingBytes(props?: cloudwatch.MetricOptions): cloudwatch.Metric; + + /** + * Metric for the number of records ingested successfully into the delivery stream over the specified time period after throttling. + * + * By default, this metric will be calculated as an average over a period of 5 minutes. + */ + metricIncomingRecords(props?: cloudwatch.MetricOptions): cloudwatch.Metric; + + /** + * Metric for the number of bytes delivered to Amazon S3 for backup over the specified time period. + * + * By default, this metric will be calculated as an average over a period of 5 minutes. + */ + metricBackupToS3Bytes(props?: cloudwatch.MetricOptions): cloudwatch.Metric; + + /** + * Metric for the age (from getting into Kinesis Data Firehose to now) of the oldest record in Kinesis Data Firehose. + * + * Any record older than this age has been delivered to the Amazon S3 bucket for backup. + * + * By default, this metric will be calculated as an average over a period of 5 minutes. + */ + metricBackupToS3DataFreshness(props?: cloudwatch.MetricOptions): cloudwatch.Metric; + + /** + * Metric for the number of records delivered to Amazon S3 for backup over the specified time period. + * + * By default, this metric will be calculated as an average over a period of 5 minutes. + */ + metricBackupToS3Records(props?: cloudwatch.MetricOptions): cloudwatch.Metric; } /** @@ -90,6 +130,53 @@ abstract class DeliveryStreamBase extends cdk.Resource implements IDeliveryStrea ...props, }).attachTo(this); } + + public metricIncomingBytes(props?: cloudwatch.MetricOptions): cloudwatch.Metric { + return this.cannedMetric(FirehoseMetrics.incomingBytesAverage, props); + } + + public metricIncomingRecords(props?: cloudwatch.MetricOptions): cloudwatch.Metric { + return this.cannedMetric(FirehoseMetrics.incomingRecordsAverage, props); + } + + public metricBackupToS3Bytes(props?: cloudwatch.MetricOptions): cloudwatch.Metric { + return this.cannedMetric(FirehoseMetrics.backupToS3BytesAverage, props); + } + + public metricBackupToS3DataFreshness(props?: cloudwatch.MetricOptions): cloudwatch.Metric { + return this.cannedMetric(FirehoseMetrics.backupToS3DataFreshnessAverage, props); + } + + public metricBackupToS3Records(props?: cloudwatch.MetricOptions): cloudwatch.Metric { + return this.cannedMetric(FirehoseMetrics.backupToS3RecordsAverage, props); + } + + private cannedMetric(fn: (dims: { DeliveryStreamName: string }) => cloudwatch.MetricProps, props?: cloudwatch.MetricOptions): cloudwatch.Metric { + return new cloudwatch.Metric({ + ...fn({ DeliveryStreamName: this.deliveryStreamName }), + ...props, + }).attachTo(this); + } +} + +/** + * Options for server-side encryption of a delivery stream. + */ +export enum StreamEncryption { + /** + * Data in the stream is stored unencrypted. + */ + UNENCRYPTED, + + /** + * Data in the stream is stored encrypted by a KMS key managed by the customer. + */ + CUSTOMER_MANAGED, + + /** + * Data in the stream is stored encrypted by a KMS key owned by AWS and managed for use in multiple AWS accounts. + */ + AWS_OWNED, } /** @@ -110,6 +197,13 @@ export interface DeliveryStreamProps { */ readonly deliveryStreamName?: string; + /** + * The Kinesis data stream to use as a source for this delivery stream. + * + * @default - data must be written to the delivery stream via a direct put. + */ + readonly sourceStream?: kinesis.IStream; + /** * The IAM role associated with this delivery stream. * @@ -118,6 +212,20 @@ export interface DeliveryStreamProps { * @default - a role will be created with default permissions. */ readonly role?: iam.IRole; + + /** + * Indicates the type of customer master key (CMK) to use for server-side encryption, if any. + * + * @default StreamEncryption.UNENCRYPTED - unless `encryptionKey` is provided, in which case this will be implicitly set to `StreamEncryption.CUSTOMER_MANAGED` + */ + readonly encryption?: StreamEncryption; + + /** + * Customer managed key to server-side encrypt data in the stream. + * + * @default - no KMS key will be used; if `encryption` is set to `CUSTOMER_MANAGED`, a KMS key will be created for you + */ + readonly encryptionKey?: kms.IKey; } /** @@ -219,14 +327,59 @@ export class DeliveryStream extends DeliveryStreamBase { }); this.grantPrincipal = role; + if ( + props.sourceStream && + (props.encryption === StreamEncryption.AWS_OWNED || props.encryption === StreamEncryption.CUSTOMER_MANAGED || props.encryptionKey) + ) { + throw new Error('Requested server-side encryption but delivery stream source is a Kinesis data stream. Specify server-side encryption on the data stream instead.'); + } + if ((props.encryption === StreamEncryption.AWS_OWNED || props.encryption === StreamEncryption.UNENCRYPTED) && props.encryptionKey) { + throw new Error(`Specified stream encryption as ${StreamEncryption[props.encryption]} but provided a customer-managed key`); + } + const encryptionKey = props.encryptionKey ?? (props.encryption === StreamEncryption.CUSTOMER_MANAGED ? new kms.Key(this, 'Key') : undefined); + const encryptionConfig = (encryptionKey || (props.encryption === StreamEncryption.AWS_OWNED)) ? { + keyArn: encryptionKey?.keyArn, + keyType: encryptionKey ? 'CUSTOMER_MANAGED_CMK' : 'AWS_OWNED_CMK', + } : undefined; + /* + * In order for the service role to have access to the encryption key before the delivery stream is created, the + * CfnDeliveryStream below should have a dependency on the grant returned by the function call below: + * > `keyGrant?.applyBefore(resource)` + * However, an error during synthesis is thrown if this is added: + * > ${Token[PolicyDocument.###]} does not implement DependableTrait + * Data will not be lost if the permissions are not granted to the service role immediately; Firehose has a 24 hour + * period where data will be buffered and retried if access is denied to the encryption key. For that reason, it is + * acceptable to omit the dependency for now. See: https://github.com/aws/aws-cdk/issues/15790 + */ + encryptionKey?.grantEncryptDecrypt(role); + + const sourceStreamConfig = props.sourceStream ? { + kinesisStreamArn: props.sourceStream.streamArn, + roleArn: role.roleArn, + } : undefined; + const readStreamGrant = props.sourceStream?.grantRead(role); + /* + * Firehose still uses the deprecated DescribeStream API instead of the modern DescribeStreamSummary API. + * kinesis.IStream.grantRead does not provide DescribeStream permissions so we add it manually here. + */ + if (readStreamGrant && readStreamGrant.principalStatement) { + readStreamGrant.principalStatement.addActions('kinesis:DescribeStream'); + } + const destinationConfig = props.destinations[0].bind(this, {}); const resource = new CfnDeliveryStream(this, 'Resource', { + deliveryStreamEncryptionConfigurationInput: encryptionConfig, deliveryStreamName: props.deliveryStreamName, - deliveryStreamType: 'DirectPut', + deliveryStreamType: props.sourceStream ? 'KinesisStreamAsSource' : 'DirectPut', + kinesisStreamSourceConfiguration: sourceStreamConfig, ...destinationConfig, }); + destinationConfig.dependables?.forEach(dependable => resource.node.addDependency(dependable)); + if (readStreamGrant) { + resource.node.addDependency(readStreamGrant); + } this.deliveryStreamArn = this.getResourceArnAttribute(resource.attrArn, { service: 'kinesis', diff --git a/packages/@aws-cdk/aws-kinesisfirehose/lib/index.ts b/packages/@aws-cdk/aws-kinesisfirehose/lib/index.ts index 3eddb6dec468e..72a166b3ec467 100644 --- a/packages/@aws-cdk/aws-kinesisfirehose/lib/index.ts +++ b/packages/@aws-cdk/aws-kinesisfirehose/lib/index.ts @@ -1,5 +1,7 @@ export * from './delivery-stream'; export * from './destination'; +export * from './lambda-function-processor'; +export * from './processor'; // AWS::KinesisFirehose CloudFormation Resources: export * from './kinesisfirehose.generated'; diff --git a/packages/@aws-cdk/aws-kinesisfirehose/lib/lambda-function-processor.ts b/packages/@aws-cdk/aws-kinesisfirehose/lib/lambda-function-processor.ts new file mode 100644 index 0000000000000..afe3bb0cfa549 --- /dev/null +++ b/packages/@aws-cdk/aws-kinesisfirehose/lib/lambda-function-processor.ts @@ -0,0 +1,29 @@ +import * as lambda from '@aws-cdk/aws-lambda'; +import { Construct } from 'constructs'; +import { DataProcessorBindOptions, DataProcessorConfig, DataProcessorProps, IDataProcessor } from './processor'; + +/** + * Use an AWS Lambda function to transform records. + */ +export class LambdaFunctionProcessor implements IDataProcessor { + /** + * The constructor props of the LambdaFunctionProcessor. + */ + public readonly props: DataProcessorProps; + + constructor(private readonly lambdaFunction: lambda.IFunction, props: DataProcessorProps = {}) { + this.props = props; + } + + public bind(_scope: Construct, options: DataProcessorBindOptions): DataProcessorConfig { + this.lambdaFunction.grantInvoke(options.role); + + return { + processorType: 'Lambda', + processorIdentifier: { + parameterName: 'LambdaArn', + parameterValue: this.lambdaFunction.functionArn, + }, + }; + } +} diff --git a/packages/@aws-cdk/aws-kinesisfirehose/lib/processor.ts b/packages/@aws-cdk/aws-kinesisfirehose/lib/processor.ts new file mode 100644 index 0000000000000..960996f8dc0cc --- /dev/null +++ b/packages/@aws-cdk/aws-kinesisfirehose/lib/processor.ts @@ -0,0 +1,96 @@ +import * as iam from '@aws-cdk/aws-iam'; +import { Duration, Size } from '@aws-cdk/core'; + +import { Construct } from 'constructs'; + +/** + * Configure the data processor. + */ +export interface DataProcessorProps { + /** + * The length of time Kinesis Data Firehose will buffer incoming data before calling the processor. + *s + * @default Duration.minutes(1) + */ + readonly bufferInterval?: Duration; + + /** + * The amount of incoming data Kinesis Data Firehose will buffer before calling the processor. + * + * @default Size.mebibytes(3) + */ + readonly bufferSize?: Size; + + /** + * The number of times Kinesis Data Firehose will retry the processor invocation after a failure due to network timeout or invocation limits. + * + * @default 3 + */ + readonly retries?: number; +} + +/** + * The key-value pair that identifies the underlying processor resource. + * + * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-kinesisfirehose-deliverystream-processorparameter.html + */ +export interface DataProcessorIdentifier { + /** + * The parameter name that corresponds to the processor resource's identifier. + * + * Must be an accepted value in `CfnDeliveryStream.ProcessoryParameterProperty.ParameterName`. + */ + readonly parameterName: string; + + /** + * The identifier of the underlying processor resource. + */ + readonly parameterValue: string; +} + +/** + * The full configuration of a data processor. + */ +export interface DataProcessorConfig { + /** + * The type of the underlying processor resource. + * + * Must be an accepted value in `CfnDeliveryStream.ProcessorProperty.Type`. + * @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-kinesisfirehose-deliverystream-processor.html#cfn-kinesisfirehose-deliverystream-processor-type + * @example 'Lambda' + */ + readonly processorType: string; + + /** + * The key-value pair that identifies the underlying processor resource. + */ + readonly processorIdentifier: DataProcessorIdentifier; +} + +/** + * Options when binding a DataProcessor to a delivery stream destination. + */ +export interface DataProcessorBindOptions { + /** + * The IAM role assumed by Kinesis Data Firehose to write to the destination that this DataProcessor will bind to. + */ + readonly role: iam.IRole; +} + +/** + * A data processor that Kinesis Data Firehose will call to transform records before delivering data. + */ +export interface IDataProcessor { + /** + * The constructor props of the DataProcessor. + */ + readonly props: DataProcessorProps; + + /** + * Binds this processor to a destination of a delivery stream. + * + * Implementers should use this method to grant processor invocation permissions to the provided stream and return the + * necessary configuration to register as a processor. + */ + bind(scope: Construct, options: DataProcessorBindOptions): DataProcessorConfig; +} diff --git a/packages/@aws-cdk/aws-kinesisfirehose/package.json b/packages/@aws-cdk/aws-kinesisfirehose/package.json index d6651f8d08c62..58c5568c8c299 100644 --- a/packages/@aws-cdk/aws-kinesisfirehose/package.json +++ b/packages/@aws-cdk/aws-kinesisfirehose/package.json @@ -85,6 +85,11 @@ "@aws-cdk/aws-cloudwatch": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", + "@aws-cdk/aws-kinesis": "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-s3": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/region-info": "0.0.0", "constructs": "^3.3.69" @@ -94,6 +99,11 @@ "@aws-cdk/aws-cloudwatch": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", "@aws-cdk/aws-iam": "0.0.0", + "@aws-cdk/aws-kinesis": "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-s3": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/region-info": "0.0.0", "constructs": "^3.3.69" diff --git a/packages/@aws-cdk/aws-kinesisfirehose/test/delivery-stream.test.ts b/packages/@aws-cdk/aws-kinesisfirehose/test/delivery-stream.test.ts index bb9c3ba744a2f..345e7feb0774a 100644 --- a/packages/@aws-cdk/aws-kinesisfirehose/test/delivery-stream.test.ts +++ b/packages/@aws-cdk/aws-kinesisfirehose/test/delivery-stream.test.ts @@ -1,13 +1,17 @@ import '@aws-cdk/assert-internal/jest'; -import { ABSENT, ResourcePart, SynthUtils, anything } from '@aws-cdk/assert-internal'; +import { ABSENT, ResourcePart, SynthUtils, anything, arrayWith } from '@aws-cdk/assert-internal'; +import * as cloudwatch from '@aws-cdk/aws-cloudwatch'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; +import * as kinesis from '@aws-cdk/aws-kinesis'; +import * as kms from '@aws-cdk/aws-kms'; import * as cdk from '@aws-cdk/core'; import { Construct, Node } from 'constructs'; import * as firehose from '../lib'; describe('delivery stream', () => { let stack: cdk.Stack; + let deliveryStreamRole: iam.IRole; let dependable: Construct; let mockS3Destination: firehose.IDestination; @@ -16,6 +20,9 @@ describe('delivery stream', () => { beforeEach(() => { stack = new cdk.Stack(); + deliveryStreamRole = new iam.Role(stack, 'DeliveryStreamRole', { + assumedBy: new iam.ServicePrincipal('firehose.amazonaws.com'), + }); mockS3Destination = { bind(scope: Construct, _options: firehose.DestinationBindOptions): firehose.DestinationConfig { dependable = new class extends cdk.Construct { @@ -83,6 +90,206 @@ describe('delivery stream', () => { }); }); + test('providing source stream creates configuration and grants permission', () => { + const sourceStream = new kinesis.Stream(stack, 'Source Stream'); + + new firehose.DeliveryStream(stack, 'Delivery Stream', { + destinations: [mockS3Destination], + sourceStream: sourceStream, + role: deliveryStreamRole, + }); + + expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: arrayWith( + 'kinesis:DescribeStream', + 'kinesis:GetRecords', + 'kinesis:GetShardIterator', + 'kinesis:ListShards', + ), + Resource: stack.resolve(sourceStream.streamArn), + }, + ], + }, + Roles: [stack.resolve(deliveryStreamRole.roleName)], + }); + expect(stack).toHaveResource('AWS::KinesisFirehose::DeliveryStream', { + DeliveryStreamType: 'KinesisStreamAsSource', + KinesisStreamSourceConfiguration: { + KinesisStreamARN: stack.resolve(sourceStream.streamArn), + RoleARN: stack.resolve(deliveryStreamRole.roleArn), + }, + }); + expect(stack).toHaveResourceLike('AWS::KinesisFirehose::DeliveryStream', { + DependsOn: arrayWith('DeliveryStreamRoleDefaultPolicy2759968B'), + }, ResourcePart.CompleteDefinition); + }); + + test('requesting customer-owned encryption creates key and configuration', () => { + new firehose.DeliveryStream(stack, 'Delivery Stream', { + destinations: [mockS3Destination], + encryption: firehose.StreamEncryption.CUSTOMER_MANAGED, + role: deliveryStreamRole, + }); + + expect(stack).toHaveResource('AWS::KMS::Key'); + expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: arrayWith( + 'kms:Encrypt', + 'kms:Decrypt', + ), + }, + ], + }, + Roles: [stack.resolve(deliveryStreamRole.roleName)], + }); + expect(stack).toHaveResourceLike('AWS::KinesisFirehose::DeliveryStream', { + DeliveryStreamEncryptionConfigurationInput: { + KeyARN: { + 'Fn::GetAtt': [ + 'DeliveryStreamKey56A6407F', + 'Arn', + ], + }, + KeyType: 'CUSTOMER_MANAGED_CMK', + }, + }); + }); + + test('providing encryption key creates configuration', () => { + const key = new kms.Key(stack, 'Key'); + + new firehose.DeliveryStream(stack, 'Delivery Stream', { + destinations: [mockS3Destination], + encryptionKey: key, + role: deliveryStreamRole, + }); + + expect(stack).toHaveResource('AWS::KMS::Key'); + expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: arrayWith( + 'kms:Encrypt', + 'kms:Decrypt', + ), + Resource: stack.resolve(key.keyArn), + }, + ], + }, + Roles: [stack.resolve(deliveryStreamRole.roleName)], + }); + expect(stack).toHaveResourceLike('AWS::KinesisFirehose::DeliveryStream', { + DeliveryStreamEncryptionConfigurationInput: { + KeyARN: stack.resolve(key.keyArn), + KeyType: 'CUSTOMER_MANAGED_CMK', + }, + }); + }); + + test('requesting AWS-owned key does not create key and creates configuration', () => { + new firehose.DeliveryStream(stack, 'Delivery Stream', { + destinations: [mockS3Destination], + encryption: firehose.StreamEncryption.AWS_OWNED, + role: deliveryStreamRole, + }); + + expect(stack).not.toHaveResource('AWS::KMS::Key'); + expect(stack).not.toHaveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: arrayWith( + 'kms:Encrypt', + 'kms:Decrypt', + ), + }, + ], + }, + Roles: [stack.resolve(deliveryStreamRole.roleName)], + }); + expect(stack).toHaveResourceLike('AWS::KinesisFirehose::DeliveryStream', { + DeliveryStreamType: 'DirectPut', + DeliveryStreamEncryptionConfigurationInput: { + KeyARN: ABSENT, + KeyType: 'AWS_OWNED_CMK', + }, + }); + }); + + test('requesting no encryption creates no configuration', () => { + new firehose.DeliveryStream(stack, 'Delivery Stream', { + destinations: [mockS3Destination], + encryption: firehose.StreamEncryption.UNENCRYPTED, + role: deliveryStreamRole, + }); + + expect(stack).not.toHaveResource('AWS::KMS::Key'); + expect(stack).not.toHaveResourceLike('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [ + { + Action: arrayWith( + 'kms:Encrypt', + 'kms:Decrypt', + ), + }, + ], + }, + Roles: [stack.resolve(deliveryStreamRole.roleName)], + }); + expect(stack).toHaveResourceLike('AWS::KinesisFirehose::DeliveryStream', { + DeliveryStreamType: 'DirectPut', + DeliveryStreamEncryptionConfigurationInput: ABSENT, + }); + }); + + test('requesting AWS-owned key and providing a key throws an error', () => { + const key = new kms.Key(stack, 'Key'); + + expect(() => new firehose.DeliveryStream(stack, 'Delivery Stream', { + destinations: [mockS3Destination], + encryption: firehose.StreamEncryption.AWS_OWNED, + encryptionKey: key, + })).toThrowError('Specified stream encryption as AWS_OWNED but provided a customer-managed key'); + }); + + test('requesting no encryption and providing a key throws an error', () => { + const key = new kms.Key(stack, 'Key'); + + expect(() => new firehose.DeliveryStream(stack, 'Delivery Stream', { + destinations: [mockS3Destination], + encryption: firehose.StreamEncryption.UNENCRYPTED, + encryptionKey: key, + })).toThrowError('Specified stream encryption as UNENCRYPTED but provided a customer-managed key'); + }); + + test('requesting encryption or providing a key when source is a stream throws an error', () => { + const sourceStream = new kinesis.Stream(stack, 'Source Stream'); + + expect(() => new firehose.DeliveryStream(stack, 'Delivery Stream 1', { + destinations: [mockS3Destination], + encryption: firehose.StreamEncryption.AWS_OWNED, + sourceStream, + })).toThrowError('Requested server-side encryption but delivery stream source is a Kinesis data stream. Specify server-side encryption on the data stream instead.'); + expect(() => new firehose.DeliveryStream(stack, 'Delivery Stream 2', { + destinations: [mockS3Destination], + encryption: firehose.StreamEncryption.CUSTOMER_MANAGED, + sourceStream, + })).toThrowError('Requested server-side encryption but delivery stream source is a Kinesis data stream. Specify server-side encryption on the data stream instead.'); + expect(() => new firehose.DeliveryStream(stack, 'Delivery Stream 3', { + destinations: [mockS3Destination], + encryptionKey: new kms.Key(stack, 'Key'), + sourceStream, + })).toThrowError('Requested server-side encryption but delivery stream source is a Kinesis data stream. Specify server-side encryption on the data stream instead.'); + }); + test('grant provides access to stream', () => { const role = new iam.Role(stack, 'Role', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), @@ -157,22 +364,98 @@ describe('delivery stream', () => { }); describe('metric methods provide a Metric with configured and attached properties', () => { + let deliveryStream: firehose.DeliveryStream; + beforeEach(() => { stack = new cdk.Stack(undefined, undefined, { env: { account: '000000000000', region: 'us-west-1' } }); + deliveryStream = new firehose.DeliveryStream(stack, 'Delivery Stream', { + destinations: [mockS3Destination], + }); }); test('metric', () => { - const deliveryStream = new firehose.DeliveryStream(stack, 'Delivery Stream', { - destinations: [mockS3Destination], + const metric = deliveryStream.metric('IncomingRecords'); + + expect(metric).toMatchObject({ + account: stack.account, + region: stack.region, + namespace: 'AWS/Firehose', + metricName: 'IncomingRecords', + dimensions: { + DeliveryStreamName: deliveryStream.deliveryStreamName, + }, }); + }); - const metric = deliveryStream.metric('IncomingRecords'); + test('metricIncomingBytes', () => { + const metric = deliveryStream.metricIncomingBytes(); + + expect(metric).toMatchObject({ + account: stack.account, + region: stack.region, + namespace: 'AWS/Firehose', + metricName: 'IncomingBytes', + statistic: cloudwatch.Statistic.AVERAGE, + dimensions: { + DeliveryStreamName: deliveryStream.deliveryStreamName, + }, + }); + }); + + test('metricIncomingRecords', () => { + const metric = deliveryStream.metricIncomingRecords(); expect(metric).toMatchObject({ account: stack.account, region: stack.region, namespace: 'AWS/Firehose', metricName: 'IncomingRecords', + statistic: cloudwatch.Statistic.AVERAGE, + dimensions: { + DeliveryStreamName: deliveryStream.deliveryStreamName, + }, + }); + }); + + test('metricBackupToS3Bytes', () => { + const metric = deliveryStream.metricBackupToS3Bytes(); + + expect(metric).toMatchObject({ + account: stack.account, + region: stack.region, + namespace: 'AWS/Firehose', + metricName: 'BackupToS3.Bytes', + statistic: cloudwatch.Statistic.AVERAGE, + dimensions: { + DeliveryStreamName: deliveryStream.deliveryStreamName, + }, + }); + }); + + test('metricBackupToS3DataFreshness', () => { + const metric = deliveryStream.metricBackupToS3DataFreshness(); + + expect(metric).toMatchObject({ + account: stack.account, + region: stack.region, + namespace: 'AWS/Firehose', + metricName: 'BackupToS3.DataFreshness', + statistic: cloudwatch.Statistic.AVERAGE, + dimensions: { + DeliveryStreamName: deliveryStream.deliveryStreamName, + }, + }); + }); + + test('metricBackupToS3Records', () => { + const metric = deliveryStream.metricBackupToS3Records(); + + expect(metric).toMatchObject({ + account: stack.account, + region: stack.region, + namespace: 'AWS/Firehose', + metricName: 'BackupToS3.Records', + statistic: cloudwatch.Statistic.AVERAGE, dimensions: { DeliveryStreamName: deliveryStream.deliveryStreamName, }, diff --git a/packages/@aws-cdk/aws-kinesisfirehose/test/integ.delivery-stream.expected.json b/packages/@aws-cdk/aws-kinesisfirehose/test/integ.delivery-stream.expected.json index f9e785a3def9e..1c23bbcee1092 100644 --- a/packages/@aws-cdk/aws-kinesisfirehose/test/integ.delivery-stream.expected.json +++ b/packages/@aws-cdk/aws-kinesisfirehose/test/integ.delivery-stream.expected.json @@ -71,6 +71,41 @@ ] } }, + "Key961B73FD": { + "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": "*" + } + ], + "Version": "2012-10-17" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, "DeliveryStreamServiceRole964EEBCC": { "Type": "AWS::IAM::Role", "Properties": { @@ -88,9 +123,49 @@ } } }, + "DeliveryStreamServiceRoleDefaultPolicyB87D9ACF": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "DeliveryStreamServiceRoleDefaultPolicyB87D9ACF", + "Roles": [ + { + "Ref": "DeliveryStreamServiceRole964EEBCC" + } + ] + } + }, "DeliveryStreamF6D5572D": { "Type": "AWS::KinesisFirehose::DeliveryStream", "Properties": { + "DeliveryStreamEncryptionConfigurationInput": { + "KeyARN": { + "Fn::GetAtt": [ + "Key961B73FD", + "Arn" + ] + }, + "KeyType": "CUSTOMER_MANAGED_CMK" + }, "DeliveryStreamType": "DirectPut", "ExtendedS3DestinationConfiguration": { "BucketARN": { diff --git a/packages/@aws-cdk/aws-kinesisfirehose/test/integ.delivery-stream.source-stream.expected.json b/packages/@aws-cdk/aws-kinesisfirehose/test/integ.delivery-stream.source-stream.expected.json new file mode 100644 index 0000000000000..eb46541a1cdf2 --- /dev/null +++ b/packages/@aws-cdk/aws-kinesisfirehose/test/integ.delivery-stream.source-stream.expected.json @@ -0,0 +1,283 @@ +{ + "Resources": { + "Bucket83908E77": { + "Type": "AWS::S3::Bucket", + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Role1ABCC5F0": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "firehose.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "RoleDefaultPolicy5FFB7DAB": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*", + "s3:DeleteObject*", + "s3:PutObject", + "s3:Abort*" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "RoleDefaultPolicy5FFB7DAB", + "Roles": [ + { + "Ref": "Role1ABCC5F0" + } + ] + } + }, + "SourceStream95FF52BE": { + "Type": "AWS::Kinesis::Stream", + "Properties": { + "ShardCount": 1, + "RetentionPeriodHours": 24, + "StreamEncryption": { + "Fn::If": [ + "AwsCdkKinesisEncryptedStreamsUnsupportedRegions", + { + "Ref": "AWS::NoValue" + }, + { + "EncryptionType": "KMS", + "KeyId": "alias/aws/kinesis" + } + ] + } + } + }, + "DeliveryStreamServiceRole964EEBCC": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "firehose.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "DeliveryStreamServiceRoleDefaultPolicyB87D9ACF": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "kinesis:DescribeStreamSummary", + "kinesis:GetRecords", + "kinesis:GetShardIterator", + "kinesis:ListShards", + "kinesis:SubscribeToShard", + "kinesis:DescribeStream" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "SourceStream95FF52BE", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "DeliveryStreamServiceRoleDefaultPolicyB87D9ACF", + "Roles": [ + { + "Ref": "DeliveryStreamServiceRole964EEBCC" + } + ] + } + }, + "DeliveryStreamF6D5572D": { + "Type": "AWS::KinesisFirehose::DeliveryStream", + "Properties": { + "DeliveryStreamType": "KinesisStreamAsSource", + "ExtendedS3DestinationConfiguration": { + "BucketARN": { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "RoleARN": { + "Fn::GetAtt": [ + "Role1ABCC5F0", + "Arn" + ] + } + }, + "KinesisStreamSourceConfiguration": { + "KinesisStreamARN": { + "Fn::GetAtt": [ + "SourceStream95FF52BE", + "Arn" + ] + }, + "RoleARN": { + "Fn::GetAtt": [ + "DeliveryStreamServiceRole964EEBCC", + "Arn" + ] + } + } + }, + "DependsOn": [ + "DeliveryStreamServiceRoleDefaultPolicyB87D9ACF", + "RoleDefaultPolicy5FFB7DAB" + ] + } + }, + "Conditions": { + "AwsCdkKinesisEncryptedStreamsUnsupportedRegions": { + "Fn::Or": [ + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "cn-north-1" + ] + }, + { + "Fn::Equals": [ + { + "Ref": "AWS::Region" + }, + "cn-northwest-1" + ] + } + ] + } + }, + "Mappings": { + "awscdkawskinesisfirehoseCidrBlocks": { + "af-south-1": { + "FirehoseCidrBlock": "13.244.121.224/27" + }, + "ap-east-1": { + "FirehoseCidrBlock": "18.162.221.32/27" + }, + "ap-northeast-1": { + "FirehoseCidrBlock": "13.113.196.224/27" + }, + "ap-northeast-2": { + "FirehoseCidrBlock": "13.209.1.64/27" + }, + "ap-northeast-3": { + "FirehoseCidrBlock": "13.208.177.192/27" + }, + "ap-south-1": { + "FirehoseCidrBlock": "13.232.67.32/27" + }, + "ap-southeast-1": { + "FirehoseCidrBlock": "13.228.64.192/27" + }, + "ap-southeast-2": { + "FirehoseCidrBlock": "13.210.67.224/27" + }, + "ca-central-1": { + "FirehoseCidrBlock": "35.183.92.128/27" + }, + "cn-north-1": { + "FirehoseCidrBlock": "52.81.151.32/27" + }, + "cn-northwest-1": { + "FirehoseCidrBlock": "161.189.23.64/27" + }, + "eu-central-1": { + "FirehoseCidrBlock": "35.158.127.160/27" + }, + "eu-north-1": { + "FirehoseCidrBlock": "13.53.63.224/27" + }, + "eu-south-1": { + "FirehoseCidrBlock": "15.161.135.128/27" + }, + "eu-west-1": { + "FirehoseCidrBlock": "52.19.239.192/27" + }, + "eu-west-2": { + "FirehoseCidrBlock": "18.130.1.96/27" + }, + "eu-west-3": { + "FirehoseCidrBlock": "35.180.1.96/27" + }, + "me-south-1": { + "FirehoseCidrBlock": "15.185.91.0/27" + }, + "sa-east-1": { + "FirehoseCidrBlock": "18.228.1.128/27" + }, + "us-east-1": { + "FirehoseCidrBlock": "52.70.63.192/27" + }, + "us-east-2": { + "FirehoseCidrBlock": "13.58.135.96/27" + }, + "us-gov-east-1": { + "FirehoseCidrBlock": "18.253.138.96/27" + }, + "us-gov-west-1": { + "FirehoseCidrBlock": "52.61.204.160/27" + }, + "us-west-1": { + "FirehoseCidrBlock": "13.57.135.192/27" + }, + "us-west-2": { + "FirehoseCidrBlock": "52.89.255.224/27" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-kinesisfirehose/test/integ.delivery-stream.source-stream.ts b/packages/@aws-cdk/aws-kinesisfirehose/test/integ.delivery-stream.source-stream.ts new file mode 100644 index 0000000000000..f39510a74322b --- /dev/null +++ b/packages/@aws-cdk/aws-kinesisfirehose/test/integ.delivery-stream.source-stream.ts @@ -0,0 +1,41 @@ +#!/usr/bin/env node +import * as iam from '@aws-cdk/aws-iam'; +import * as kinesis from '@aws-cdk/aws-kinesis'; +import * as s3 from '@aws-cdk/aws-s3'; +import * as cdk from '@aws-cdk/core'; +import * as constructs from 'constructs'; +import * as firehose from '../lib'; + +const app = new cdk.App(); + +const stack = new cdk.Stack(app, 'aws-cdk-firehose-delivery-stream-source-stream'); + +const bucket = new s3.Bucket(stack, 'Bucket', { + removalPolicy: cdk.RemovalPolicy.DESTROY, +}); + +const role = new iam.Role(stack, 'Role', { + assumedBy: new iam.ServicePrincipal('firehose.amazonaws.com'), +}); + +const mockS3Destination: firehose.IDestination = { + bind(_scope: constructs.Construct, _options: firehose.DestinationBindOptions): firehose.DestinationConfig { + const bucketGrant = bucket.grantReadWrite(role); + return { + extendedS3DestinationConfiguration: { + bucketArn: bucket.bucketArn, + roleArn: role.roleArn, + }, + dependables: [bucketGrant], + }; + }, +}; + +const sourceStream = new kinesis.Stream(stack, 'Source Stream'); + +new firehose.DeliveryStream(stack, 'Delivery Stream', { + destinations: [mockS3Destination], + sourceStream, +}); + +app.synth(); diff --git a/packages/@aws-cdk/aws-kinesisfirehose/test/integ.delivery-stream.ts b/packages/@aws-cdk/aws-kinesisfirehose/test/integ.delivery-stream.ts index 1adfd9bfc0221..ed0478f54e6c1 100644 --- a/packages/@aws-cdk/aws-kinesisfirehose/test/integ.delivery-stream.ts +++ b/packages/@aws-cdk/aws-kinesisfirehose/test/integ.delivery-stream.ts @@ -1,5 +1,6 @@ #!/usr/bin/env node import * as iam from '@aws-cdk/aws-iam'; +import * as kms from '@aws-cdk/aws-kms'; import * as s3 from '@aws-cdk/aws-s3'; import * as cdk from '@aws-cdk/core'; import * as constructs from 'constructs'; @@ -30,8 +31,13 @@ const mockS3Destination: firehose.IDestination = { }, }; +const key = new kms.Key(stack, 'Key', { + removalPolicy: cdk.RemovalPolicy.DESTROY, +}); + new firehose.DeliveryStream(stack, 'Delivery Stream', { destinations: [mockS3Destination], + encryptionKey: key, }); app.synth(); diff --git a/packages/@aws-cdk/aws-lakeformation/package.json b/packages/@aws-cdk/aws-lakeformation/package.json index a374c0d9627da..87af67a50de81 100644 --- a/packages/@aws-cdk/aws-lakeformation/package.json +++ b/packages/@aws-cdk/aws-lakeformation/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-lakeformation/test/lakeformation.test.ts b/packages/@aws-cdk/aws-lakeformation/test/lakeformation.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-lakeformation/test/lakeformation.test.ts +++ b/packages/@aws-cdk/aws-lakeformation/test/lakeformation.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-lambda-event-sources/lib/sqs.ts b/packages/@aws-cdk/aws-lambda-event-sources/lib/sqs.ts index 8a67e63fb6199..ba900178d006a 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/lib/sqs.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/lib/sqs.ts @@ -9,6 +9,7 @@ export interface SqsEventSourceProps { * event with all the retrieved records. * * Valid Range: Minimum value of 1. Maximum value of 10. + * If `maxBatchingWindow` is configured, this value can go up to 10,000. * * @default 10 */ diff --git a/packages/@aws-cdk/aws-lambda-event-sources/test/api.test.ts b/packages/@aws-cdk/aws-lambda-event-sources/test/api.test.ts index b0b2e9fb5ec71..07f873804938d 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/test/api.test.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/test/api.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import * as lambda from '@aws-cdk/aws-lambda'; import * as cdk from '@aws-cdk/core'; import * as events from '../lib'; @@ -17,12 +17,12 @@ describe('ApiEventSource', () => { handler.addEventSource(new events.ApiEventSource('get', '/foo')); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Resource', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Resource', { PathPart: 'foo', ParentId: { 'Fn::GetAtt': ['MyFuncApiEventSourceA7A86A4FFB3F557C', 'RootResourceId'] }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Method', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Method', { HttpMethod: 'GET', ResourceId: { Ref: 'MyFuncApiEventSourceA7A86A4FfooCA6F87E4' }, }); @@ -44,22 +44,22 @@ describe('ApiEventSource', () => { handler.addEventSource(new events.ApiEventSource('post', '/bar')); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Resource', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Resource', { PathPart: 'foo', ParentId: { 'Fn::GetAtt': ['MyFuncApiEventSourceA7A86A4FFB3F557C', 'RootResourceId'] }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Resource', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Resource', { PathPart: 'bar', ParentId: { 'Fn::GetAtt': ['MyFuncApiEventSourceA7A86A4FFB3F557C', 'RootResourceId'] }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Method', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Method', { HttpMethod: 'GET', ResourceId: { Ref: 'MyFuncApiEventSourceA7A86A4FfooCA6F87E4' }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Method', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Method', { HttpMethod: 'POST', ResourceId: { Ref: 'MyFuncApiEventSourceA7A86A4FbarDFB0F21B' }, }); @@ -82,22 +82,22 @@ describe('ApiEventSource', () => { handler.addEventSource(new events.ApiEventSource('post', '/foo/bar/zoo')); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Resource', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Resource', { PathPart: 'foo', ParentId: { 'Fn::GetAtt': ['MyFuncApiEventSourceA7A86A4FFB3F557C', 'RootResourceId'] }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Resource', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Resource', { PathPart: 'bar', ParentId: { Ref: 'MyFuncApiEventSourceA7A86A4FfooCA6F87E4' }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Method', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Method', { HttpMethod: 'GET', ResourceId: { Ref: 'MyFuncApiEventSourceA7A86A4FfooCA6F87E4' }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Method', { + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Method', { HttpMethod: 'POST', ResourceId: { Ref: 'MyFuncApiEventSourceA7A86A4Ffoobar028FFFDE' }, }); diff --git a/packages/@aws-cdk/aws-lambda-event-sources/test/dynamo.test.ts b/packages/@aws-cdk/aws-lambda-event-sources/test/dynamo.test.ts index 8ea8da3c026f4..3e90ab5a4ab3b 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/test/dynamo.test.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/test/dynamo.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import * as dynamodb from '@aws-cdk/aws-dynamodb'; import * as lambda from '@aws-cdk/aws-lambda'; import * as sqs from '@aws-cdk/aws-sqs'; @@ -27,7 +27,7 @@ describe('DynamoEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { 'PolicyDocument': { 'Statement': [ { @@ -58,7 +58,7 @@ describe('DynamoEventSource', () => { }], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'TD925BC7E', @@ -95,7 +95,7 @@ describe('DynamoEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { TumblingWindowInSeconds: 60, }); @@ -121,7 +121,7 @@ describe('DynamoEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'TD925BC7E', @@ -219,7 +219,7 @@ describe('DynamoEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'TD925BC7E', @@ -319,7 +319,7 @@ describe('DynamoEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'TD925BC7E', @@ -399,7 +399,7 @@ describe('DynamoEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'TD925BC7E', @@ -435,7 +435,7 @@ describe('DynamoEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'TD925BC7E', @@ -515,7 +515,7 @@ describe('DynamoEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'TD925BC7E', @@ -596,7 +596,7 @@ describe('DynamoEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'TD925BC7E', @@ -642,7 +642,7 @@ describe('DynamoEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'TD925BC7E', @@ -678,7 +678,7 @@ describe('DynamoEventSource', () => { })); //THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'Enabled': false, }); diff --git a/packages/@aws-cdk/aws-lambda-event-sources/test/integ.s3.expected.json b/packages/@aws-cdk/aws-lambda-event-sources/test/integ.s3.expected.json index 7425814364cff..ff71167d19f9e 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/test/integ.s3.expected.json +++ b/packages/@aws-cdk/aws-lambda-event-sources/test/integ.s3.expected.json @@ -186,7 +186,7 @@ "Arn" ] }, - "Runtime": "python3.8", + "Runtime": "python3.7", "Timeout": 300 }, "DependsOn": [ diff --git a/packages/@aws-cdk/aws-lambda-event-sources/test/kafka.test.ts b/packages/@aws-cdk/aws-lambda-event-sources/test/kafka.test.ts index 1b973242f2f3c..1c361ffe7a442 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/test/kafka.test.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/test/kafka.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions, Match } from '@aws-cdk/assertions'; +import { Template, Match } from '@aws-cdk/assertions'; import { SecurityGroup, SubnetType, Vpc } from '@aws-cdk/aws-ec2'; import * as lambda from '@aws-cdk/aws-lambda'; import { Secret } from '@aws-cdk/aws-secretsmanager'; @@ -24,7 +24,7 @@ describe('KafkaEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -47,7 +47,7 @@ describe('KafkaEventSource', () => { ], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { EventSourceArn: clusterArn, FunctionName: { Ref: 'Fn9270CBC0', @@ -79,7 +79,7 @@ describe('KafkaEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -112,7 +112,7 @@ describe('KafkaEventSource', () => { ], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { EventSourceArn: clusterArn, FunctionName: { Ref: 'Fn9270CBC0', @@ -155,7 +155,7 @@ describe('KafkaEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -179,7 +179,7 @@ describe('KafkaEventSource', () => { ], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { FunctionName: { Ref: 'Fn9270CBC0', }, @@ -245,8 +245,8 @@ describe('KafkaEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).resourceCountIs('AWS::IAM::Policy', 0); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).resourceCountIs('AWS::IAM::Policy', 0); + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { FunctionName: { Ref: 'Fn9270CBC0', }, @@ -305,7 +305,7 @@ describe('KafkaEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { PolicyDocument: { Statement: [ { @@ -329,7 +329,7 @@ describe('KafkaEventSource', () => { ], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { FunctionName: { Ref: 'Fn9270CBC0', }, @@ -442,7 +442,7 @@ describe('KafkaEventSource', () => { authenticationMethod: sources.AuthenticationMethod.SASL_SCRAM_256_AUTH, })); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { SourceAccessConfigurations: Match.arrayWith([ { Type: 'SASL_SCRAM_256_AUTH', diff --git a/packages/@aws-cdk/aws-lambda-event-sources/test/kinesis.test.ts b/packages/@aws-cdk/aws-lambda-event-sources/test/kinesis.test.ts index b8217be186f0f..96701d6c83f7a 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/test/kinesis.test.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/test/kinesis.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import * as kinesis from '@aws-cdk/aws-kinesis'; import * as lambda from '@aws-cdk/aws-lambda'; import * as cdk from '@aws-cdk/core'; @@ -20,7 +20,7 @@ describe('KinesisEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { 'PolicyDocument': { 'Statement': [ { @@ -58,7 +58,7 @@ describe('KinesisEventSource', () => { }], }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'S509448A1', @@ -89,7 +89,7 @@ describe('KinesisEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'S509448A1', @@ -120,7 +120,7 @@ describe('KinesisEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'S509448A1', @@ -195,7 +195,7 @@ describe('KinesisEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'S509448A1', @@ -256,7 +256,7 @@ describe('KinesisEventSource', () => { fn.addEventSource(eventSource); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'Enabled': false, }); diff --git a/packages/@aws-cdk/aws-lambda-event-sources/test/s3.test.ts b/packages/@aws-cdk/aws-lambda-event-sources/test/s3.test.ts index 5c77a130fa23f..6c7b076bba2b0 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/test/s3.test.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/test/s3.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import * as s3 from '@aws-cdk/aws-s3'; import * as cdk from '@aws-cdk/core'; import * as sources from '../lib'; @@ -23,7 +23,7 @@ describe('S3EventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('Custom::S3BucketNotifications', { + Template.fromStack(stack).hasResourceProperties('Custom::S3BucketNotifications', { 'NotificationConfiguration': { 'LambdaFunctionConfigurations': [ { diff --git a/packages/@aws-cdk/aws-lambda-event-sources/test/sns.test.ts b/packages/@aws-cdk/aws-lambda-event-sources/test/sns.test.ts index 498172c2a321e..81d2b0db37b6d 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/test/sns.test.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/test/sns.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import * as sns from '@aws-cdk/aws-sns'; import * as sqs from '@aws-cdk/aws-sqs'; import * as cdk from '@aws-cdk/core'; @@ -18,7 +18,7 @@ describe('SNSEventSource', () => { fn.addEventSource(new sources.SnsEventSource(topic)); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { 'Action': 'lambda:InvokeFunction', 'FunctionName': { 'Fn::GetAtt': [ @@ -32,7 +32,7 @@ describe('SNSEventSource', () => { }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::Subscription', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Subscription', { 'Endpoint': { 'Fn::GetAtt': [ 'Fn9270CBC0', @@ -67,7 +67,7 @@ describe('SNSEventSource', () => { fn.addEventSource(new sources.SnsEventSource(topic, props)); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { 'Action': 'lambda:InvokeFunction', 'FunctionName': { 'Fn::GetAtt': [ @@ -81,7 +81,7 @@ describe('SNSEventSource', () => { }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::Subscription', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Subscription', { 'Endpoint': { 'Fn::GetAtt': [ 'Fn9270CBC0', diff --git a/packages/@aws-cdk/aws-lambda-event-sources/test/sqs.test.ts b/packages/@aws-cdk/aws-lambda-event-sources/test/sqs.test.ts index b6b12c3b17a63..807b1a4fb107a 100644 --- a/packages/@aws-cdk/aws-lambda-event-sources/test/sqs.test.ts +++ b/packages/@aws-cdk/aws-lambda-event-sources/test/sqs.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import * as sqs from '@aws-cdk/aws-sqs'; import * as cdk from '@aws-cdk/core'; import * as sources from '../lib'; @@ -17,7 +17,7 @@ describe('SQSEventSource', () => { fn.addEventSource(new sources.SqsEventSource(q)); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { 'PolicyDocument': { 'Statement': [ { @@ -41,7 +41,7 @@ describe('SQSEventSource', () => { }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'Q63C6E3AB', @@ -68,7 +68,7 @@ describe('SQSEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'EventSourceArn': { 'Fn::GetAtt': [ 'Q63C6E3AB', @@ -101,7 +101,7 @@ describe('SQSEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'BatchSize': 500, }); @@ -149,7 +149,7 @@ describe('SQSEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'BatchSize': 1000, 'MaximumBatchingWindowInSeconds': 300, }); @@ -184,7 +184,7 @@ describe('SQSEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'MaximumBatchingWindowInSeconds': 300, }); @@ -259,7 +259,7 @@ describe('SQSEventSource', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::EventSourceMapping', { 'Enabled': false, }); diff --git a/packages/@aws-cdk/aws-lambda-go/package.json b/packages/@aws-cdk/aws-lambda-go/package.json index 9f83f91c15963..5ab8238df938e 100644 --- a/packages/@aws-cdk/aws-lambda-go/package.json +++ b/packages/@aws-cdk/aws-lambda-go/package.json @@ -66,7 +66,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "@aws-cdk/aws-ec2": "0.0.0", "cdk-build-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-lambda-go/test/bundling.test.ts b/packages/@aws-cdk/aws-lambda-go/test/bundling.test.ts index c6a743a422719..474657dff61b9 100644 --- a/packages/@aws-cdk/aws-lambda-go/test/bundling.test.ts +++ b/packages/@aws-cdk/aws-lambda-go/test/bundling.test.ts @@ -6,7 +6,7 @@ import { AssetHashType, DockerImage } from '@aws-cdk/core'; import { Bundling } from '../lib/bundling'; import * as util from '../lib/util'; -jest.mock('@aws-cdk/aws-lambda'); +jest.spyOn(Code, 'fromAsset'); const fromAssetMock = jest.spyOn(DockerImage, 'fromBuild'); let getGoBuildVersionMock = jest.spyOn(util, 'getGoBuildVersion'); diff --git a/packages/@aws-cdk/aws-lambda-go/test/function.test.ts b/packages/@aws-cdk/aws-lambda-go/test/function.test.ts index 472dc39fc769f..1feb0db637ade 100644 --- a/packages/@aws-cdk/aws-lambda-go/test/function.test.ts +++ b/packages/@aws-cdk/aws-lambda-go/test/function.test.ts @@ -1,5 +1,5 @@ -import '@aws-cdk/assert-internal/jest'; import * as path from 'path'; +import { Template } from '@aws-cdk/assertions'; import { Runtime } from '@aws-cdk/aws-lambda'; import { Stack } from '@aws-cdk/core'; import { GoFunction } from '../lib'; @@ -31,10 +31,10 @@ test('GoFunction with defaults', () => { }); expect(Bundling.bundle).toHaveBeenCalledWith(expect.objectContaining({ - entry: expect.stringMatching(/@aws-cdk\/aws-lambda-go\/test\/lambda-handler-vendor\/cmd\/api$/), + entry: expect.stringMatching(/aws-lambda-go\/test\/lambda-handler-vendor\/cmd\/api$/), })); - expect(stack).toHaveResource('AWS::Lambda::Function', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { Handler: 'bootstrap', Runtime: 'provided.al2', }); @@ -48,10 +48,10 @@ test('GoFunction with using provided runtime', () => { }); expect(Bundling.bundle).toHaveBeenCalledWith(expect.objectContaining({ - entry: expect.stringMatching(/@aws-cdk\/aws-lambda-go\/test\/lambda-handler-vendor\/cmd\/api$/), + entry: expect.stringMatching(/aws-lambda-go\/test\/lambda-handler-vendor\/cmd\/api$/), })); - expect(stack).toHaveResource('AWS::Lambda::Function', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { Handler: 'bootstrap', Runtime: 'provided', }); @@ -65,10 +65,10 @@ test('GoFunction with using golang runtime', () => { }); expect(Bundling.bundle).toHaveBeenCalledWith(expect.objectContaining({ - entry: expect.stringMatching(/@aws-cdk\/aws-lambda-go\/test\/lambda-handler-vendor\/cmd\/api$/), + entry: expect.stringMatching(/aws-lambda-go\/test\/lambda-handler-vendor\/cmd\/api$/), })); - expect(stack).toHaveResource('AWS::Lambda::Function', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { Handler: 'bootstrap', Runtime: 'go1.x', }); @@ -106,7 +106,7 @@ test('resolves entry to an absolute path', () => { }); expect(Bundling.bundle).toHaveBeenCalledWith(expect.objectContaining({ - entry: expect.stringMatching(/@aws-cdk\/aws-lambda-go\/test\/lambda-handler-vendor\/cmd\/api\/main.go$/), + entry: expect.stringMatching(/aws-lambda-go\/test\/lambda-handler-vendor\/cmd\/api\/main.go$/), })); }); @@ -130,7 +130,7 @@ test('custom moduleDir can be used', () => { moduleDir: 'test/lambda-handler-vendor', }); - expect(stack).toHaveResource('AWS::Lambda::Function', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { Handler: 'bootstrap', }); }); @@ -141,7 +141,7 @@ test('custom moduleDir with file path can be used', () => { moduleDir: 'test/lambda-handler-vendor/go.mod', }); - expect(stack).toHaveResource('AWS::Lambda::Function', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { Handler: 'bootstrap', }); }); diff --git a/packages/@aws-cdk/aws-lambda-python/package.json b/packages/@aws-cdk/aws-lambda-python/package.json index 814ec44de6c69..72e5a12de703a 100644 --- a/packages/@aws-cdk/aws-lambda-python/package.json +++ b/packages/@aws-cdk/aws-lambda-python/package.json @@ -64,11 +64,11 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", - "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/aws-lambda": "0.0.0", diff --git a/packages/@aws-cdk/aws-lambda-python/test/function.test.ts b/packages/@aws-cdk/aws-lambda-python/test/function.test.ts index a6bc4778e14f2..0eda2a419e97c 100644 --- a/packages/@aws-cdk/aws-lambda-python/test/function.test.ts +++ b/packages/@aws-cdk/aws-lambda-python/test/function.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import { Code, Runtime } from '@aws-cdk/aws-lambda'; import { AssetHashType, AssetOptions, Stack } from '@aws-cdk/core'; import { PythonFunction } from '../lib'; @@ -52,7 +52,7 @@ test('PythonFunction with defaults', () => { outputPathSuffix: '.', })); - expect(stack).toHaveResource('AWS::Lambda::Function', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { Handler: 'index.handler', }); }); @@ -69,7 +69,7 @@ test('PythonFunction with index in a subdirectory', () => { outputPathSuffix: '.', })); - expect(stack).toHaveResource('AWS::Lambda::Function', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { Handler: 'inner/custom_index.custom_handler', }); }); @@ -122,21 +122,21 @@ test('allows specifying hash type', () => { assetHash: 'MY_CUSTOM_HASH', }); - expect(stack).toHaveResource('AWS::Lambda::Function', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { Code: { S3Bucket: 'mock-bucket-name', S3Key: 'SOURCE_MOCK', }, }); - expect(stack).toHaveResource('AWS::Lambda::Function', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { Code: { S3Bucket: 'mock-bucket-name', S3Key: 'OUTPUT_MOCK', }, }); - expect(stack).toHaveResource('AWS::Lambda::Function', { + Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Function', { Code: { S3Bucket: 'mock-bucket-name', S3Key: 'MY_CUSTOM_HASH', diff --git a/packages/@aws-cdk/aws-lambda-python/test/layer.test.ts b/packages/@aws-cdk/aws-lambda-python/test/layer.test.ts index ff828301ee7f3..4f0199878a205 100644 --- a/packages/@aws-cdk/aws-lambda-python/test/layer.test.ts +++ b/packages/@aws-cdk/aws-lambda-python/test/layer.test.ts @@ -1,4 +1,3 @@ -import '@aws-cdk/assert-internal/jest'; import * as path from 'path'; import { Runtime } from '@aws-cdk/aws-lambda'; import { Stack } from '@aws-cdk/core'; diff --git a/packages/@aws-cdk/aws-lambda/README.md b/packages/@aws-cdk/aws-lambda/README.md index 0a452182153bc..03839a99a2155 100644 --- a/packages/@aws-cdk/aws-lambda/README.md +++ b/packages/@aws-cdk/aws-lambda/README.md @@ -323,6 +323,28 @@ new LayerVersion(this, 'MyLayer', { }); ``` +## Lambda Insights + +Lambda functions can be configured to use CloudWatch [Lambda Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Lambda-Insights.html) +which provides low-level runtime metrics for a Lambda functions. + +```ts +import * as lambda from '@aws-cdk/lambda'; + +new Function(this, 'MyFunction', { + insightsVersion: lambda.LambdaInsightsVersion.VERSION_1_0_98_0 +}) +``` + +If the version of insights is not yet available in the CDK, you can also provide the ARN directly as so - + +```ts +const layerArn = 'arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:14'; +new Function(this, 'MyFunction', { + insightsVersion: lambda.LambdaInsightsVersion.fromInsightVersionArn(layerArn) +}) +``` + ## Event Rule Target You can use an AWS Lambda function as a target for an Amazon CloudWatch event diff --git a/packages/@aws-cdk/aws-lambda/lib/function.ts b/packages/@aws-cdk/aws-lambda/lib/function.ts index 93777c3394a9c..2d2fadc8d808b 100644 --- a/packages/@aws-cdk/aws-lambda/lib/function.ts +++ b/packages/@aws-cdk/aws-lambda/lib/function.ts @@ -15,9 +15,10 @@ import { FileSystem } from './filesystem'; import { FunctionAttributes, FunctionBase, IFunction } from './function-base'; import { calculateFunctionHash, trimFromStart } from './function-hash'; import { Handler } from './handler'; +import { LambdaInsightsVersion } from './lambda-insights'; import { Version, VersionOptions } from './lambda-version'; import { CfnFunction } from './lambda.generated'; -import { ILayerVersion } from './layers'; +import { LayerVersion, ILayerVersion } from './layers'; import { Runtime } from './runtime'; // keep this import separate from other imports to reduce chance for merge conflicts with v2-main @@ -214,6 +215,14 @@ export interface FunctionOptions extends EventInvokeConfigOptions { */ readonly profilingGroup?: IProfilingGroup; + /** + * Specify the version of CloudWatch Lambda insights to use for monitoring + * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Lambda-Insights.html + * + * @default - No Lambda Insights + */ + readonly insightsVersion?: LambdaInsightsVersion; + /** * A list of layers to add to the function's execution environment. You can configure your Lambda function to pull in * additional code during initialization in the form of layers. Layers are packages of libraries or other dependencies @@ -649,7 +658,7 @@ export class Function extends FunctionBase { zipFile: code.inlineCode, imageUri: code.image?.imageUri, }, - layers: Lazy.list({ produce: () => this.layers.map(layer => layer.layerVersionArn) }, { omitEmpty: true }), + layers: Lazy.list({ produce: () => this.layers.map(layer => layer.layerVersionArn) }, { omitEmpty: true }), // Evaluated on synthesis handler: props.handler === Handler.FROM_IMAGE ? undefined : props.handler, timeout: props.timeout && props.timeout.toSeconds(), packageType: props.runtime === Runtime.FROM_IMAGE ? 'Image' : undefined, @@ -747,6 +756,11 @@ export class Function extends FunctionBase { }); }); } + + // Configure Lambda insights + if (props.insightsVersion !== undefined) { + this.configureLambdaInsights(props.insightsVersion); + } } /** @@ -863,6 +877,17 @@ Environment variables can be marked for removal when used in Lambda@Edge by sett return; } + /** + * Configured lambda insights on the function if specified. This is acheived by adding an imported layer which is added to the + * list of lambda layers on synthesis. + * + * https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Lambda-Insights-extension-versions.html + */ + private configureLambdaInsights(insightsVersion: LambdaInsightsVersion): void { + this.addLayers(LayerVersion.fromLayerVersionArn(this, 'LambdaInsightsLayer', insightsVersion.layerVersionArn)); + this.role?.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName('CloudWatchLambdaInsightsExecutionRolePolicy')); + } + private renderEnvironment() { if (!this.environment || Object.keys(this.environment).length === 0) { return undefined; diff --git a/packages/@aws-cdk/aws-lambda/lib/index.ts b/packages/@aws-cdk/aws-lambda/lib/index.ts index 2d936755d6ad1..41c77bb8d038d 100644 --- a/packages/@aws-cdk/aws-lambda/lib/index.ts +++ b/packages/@aws-cdk/aws-lambda/lib/index.ts @@ -17,7 +17,7 @@ export * from './destination'; export * from './event-invoke-config'; export * from './scalable-attribute-api'; export * from './code-signing-config'; - +export * from './lambda-insights'; export * from './log-retention'; // AWS::Lambda CloudFormation Resources: diff --git a/packages/@aws-cdk/aws-lambda/lib/lambda-insights.ts b/packages/@aws-cdk/aws-lambda/lib/lambda-insights.ts new file mode 100644 index 0000000000000..2d2b88511786e --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/lib/lambda-insights.ts @@ -0,0 +1,134 @@ +import { Aws, CfnMapping, Fn, IResolveContext, Lazy, Stack, Token } from '@aws-cdk/core'; +import { FactName, RegionInfo } from '@aws-cdk/region-info'; + +// This is the name of the mapping that will be added to the CloudFormation template, if a stack is region agnostic +const DEFAULT_MAPPING_PREFIX = 'LambdaInsightsVersions'; + +// To add new versions, update fact-tables.ts `CLOUDWATCH_LAMBDA_INSIGHTS_ARNS` and create a new `public static readonly VERSION_A_B_C_D` + +/** + * Version of CloudWatch Lambda Insights + */ +export abstract class LambdaInsightsVersion { + + /** + * Version 1.0.54.0 + */ + public static readonly VERSION_1_0_54_0 = LambdaInsightsVersion.fromInsightsVersion('1.0.54.0'); + + /** + * Version 1.0.86.0 + */ + public static readonly VERSION_1_0_86_0 = LambdaInsightsVersion.fromInsightsVersion('1.0.86.0'); + + /** + * Version 1.0.89.0 + */ + public static readonly VERSION_1_0_89_0 = LambdaInsightsVersion.fromInsightsVersion('1.0.89.0'); + + /** + * Version 1.0.98.0 + */ + public static readonly VERSION_1_0_98_0 = LambdaInsightsVersion.fromInsightsVersion('1.0.98.0'); + + /** + * Use the insights extension associated with the provided ARN. Make sure the ARN is associated + * with same region as your function + * + * @see https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Lambda-Insights-extension-versions.html + */ + public static fromInsightVersionArn(arn: string): LambdaInsightsVersion { + class InsightsArn extends LambdaInsightsVersion { + public readonly layerVersionArn = arn; + } + return new InsightsArn(); + } + + // Use the verison to build the object. Not meant to be called by the user -- user should use e.g. VERSION_1_0_54_0 + private static fromInsightsVersion(insightsVersion: string): LambdaInsightsVersion { + + // Check if insights version is valid. This should only happen if one of the public static readonly versions are set incorrectly + const versionExists = RegionInfo.regions.some(regionInfo => regionInfo.cloudwatchLambdaInsightsArn(insightsVersion)); + if (!versionExists) { + throw new Error(`Insights version ${insightsVersion} does not exist.`); + } + + class InsightsVersion extends LambdaInsightsVersion { + public readonly layerVersionArn = Lazy.uncachedString({ + produce: (context) => getVersionArn(context, insightsVersion), + }); + } + return new InsightsVersion(); + } + + /** + * The arn of the Lambda Insights extension + */ + public readonly layerVersionArn: string = ''; +} + +/** + * Function to retrieve the correct Lambda Insights ARN from RegionInfo, + * or create a mapping to look it up at stack deployment time. + * + * This function is run on CDK synthesis. + */ +function getVersionArn(context: IResolveContext, insightsVersion: string): string { + + const scopeStack = Stack.of(context.scope); + const region = scopeStack.region; + + // Region is defined, look up the arn, or throw an error if the version isn't supported by a region + if (region !== undefined && !Token.isUnresolved(region)) { + const arn = RegionInfo.get(region).cloudwatchLambdaInsightsArn(insightsVersion); + if (arn === undefined) { + throw new Error(`Insights version ${insightsVersion} is not supported in region ${region}`); + } + return arn; + } + + // Otherwise, need to add a mapping to be looked up at deployment time + + /** + * See this for the context as to why the mappings are the way they are + * https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html + * + * Mappings have to have a structure like this, and no functions can be used inside them: + * + * - + * -- { : "value1"}, + * -- { : "value2"} + * + * So we cannot have an otherwise ideal mapping like this, because '1.0.98.0' is non-alphanumeric: + * LambdaInsightsVersions + * - us-east-1 + * -- {'1.0.98.0': 'arn1'}, + * -- {'1.0.89.0': 'arn2'} + * + * To get around this limitation, this is the mapping structure: + * LambdaInsightsVersions10980 // for version 1.0.98.0 + * - us-east-1 + * -- {'arn': 'arn1'}, + * - us-east-2 + * -- {'arn': 'arn2'} + * LambdaInsightsVersions10890 // a separate mapping version 1.0.89.0 + * - us-east-1 + * -- {'arn': 'arn3'}, + * - us-east-2 + * -- {'arn': 'arn4'} + */ + + const mapName = DEFAULT_MAPPING_PREFIX + insightsVersion.split('.').join(''); + const mapping: { [k1: string]: { [k2: string]: any } } = {}; + const region2arns = RegionInfo.regionMap(FactName.cloudwatchLambdaInsightsVersion(insightsVersion)); + for (const [reg, arn] of Object.entries(region2arns)) { + mapping[reg] = { arn }; + } + + // Only create a given mapping once. If another version of insights is used elsewhere, that mapping will also exist + if (!scopeStack.node.tryFindChild(mapName)) { + new CfnMapping(scopeStack, mapName, { mapping }); + } + // The ARN will be looked up at deployment time from the mapping we created + return Fn.findInMap(mapName, Aws.REGION, 'arn'); +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/package.json b/packages/@aws-cdk/aws-lambda/package.json index e3a1ec3289d46..7c2ece3a6bd33 100644 --- a/packages/@aws-cdk/aws-lambda/package.json +++ b/packages/@aws-cdk/aws-lambda/package.json @@ -106,6 +106,7 @@ "@aws-cdk/aws-sqs": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/cx-api": "0.0.0", + "@aws-cdk/region-info": "0.0.0", "constructs": "^3.3.69" }, "homepage": "https://github.com/aws/aws-cdk", @@ -127,6 +128,7 @@ "@aws-cdk/aws-sqs": "0.0.0", "@aws-cdk/core": "0.0.0", "@aws-cdk/cx-api": "0.0.0", + "@aws-cdk/region-info": "0.0.0", "constructs": "^3.3.69" }, "engines": { diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda-insights-mapping.expected.json b/packages/@aws-cdk/aws-lambda/test/integ.lambda-insights-mapping.expected.json new file mode 100644 index 0000000000000..7c6fabf1b1fa2 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda-insights-mapping.expected.json @@ -0,0 +1,516 @@ +{ + "Resources": { + "MyFunc1ServiceRoleF96C5B5C": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy" + ] + ] + } + ] + } + }, + "MyFunc11BE70A62": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "exports.handler = function handler(event, _context, callback) {\n console.log(JSON.stringify(event, undefined, 2));\n return callback();\n}" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunc1ServiceRoleF96C5B5C", + "Arn" + ] + }, + "Handler": "index.handler", + "Layers": [ + { + "Fn::FindInMap": [ + "LambdaInsightsVersions10540", + { + "Ref": "AWS::Region" + }, + "arn" + ] + } + ], + "Runtime": "nodejs10.x" + }, + "DependsOn": [ + "MyFunc1ServiceRoleF96C5B5C" + ] + }, + "MyFunc2ServiceRole68E50443": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy" + ] + ] + } + ] + } + }, + "MyFunc242557A97": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "exports.handler = function handler(event, _context, callback) {\n console.log(JSON.stringify(event, undefined, 2));\n return callback();\n}" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunc2ServiceRole68E50443", + "Arn" + ] + }, + "Handler": "index.handler", + "Layers": [ + { + "Fn::FindInMap": [ + "LambdaInsightsVersions10860", + { + "Ref": "AWS::Region" + }, + "arn" + ] + } + ], + "Runtime": "nodejs10.x" + }, + "DependsOn": [ + "MyFunc2ServiceRole68E50443" + ] + }, + "MyFunc3ServiceRoleA69795ED": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy" + ] + ] + } + ] + } + }, + "MyFunc3666B7A2F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "exports.handler = function handler(event, _context, callback) {\n console.log(JSON.stringify(event, undefined, 2));\n return callback();\n}" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunc3ServiceRoleA69795ED", + "Arn" + ] + }, + "Handler": "index.handler", + "Layers": [ + { + "Fn::FindInMap": [ + "LambdaInsightsVersions10890", + { + "Ref": "AWS::Region" + }, + "arn" + ] + } + ], + "Runtime": "nodejs10.x" + }, + "DependsOn": [ + "MyFunc3ServiceRoleA69795ED" + ] + }, + "MyFunc4ServiceRole93C4DEFF": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy" + ] + ] + } + ] + } + }, + "MyFunc4B88F85C6": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "exports.handler = function handler(event, _context, callback) {\n console.log(JSON.stringify(event, undefined, 2));\n return callback();\n}" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunc4ServiceRole93C4DEFF", + "Arn" + ] + }, + "Handler": "index.handler", + "Layers": [ + { + "Fn::FindInMap": [ + "LambdaInsightsVersions10980", + { + "Ref": "AWS::Region" + }, + "arn" + ] + } + ], + "Runtime": "nodejs10.x" + }, + "DependsOn": [ + "MyFunc4ServiceRole93C4DEFF" + ] + } + }, + "Mappings": { + "LambdaInsightsVersions10540": { + "ap-northeast-1": { + "arn": "arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:2" + }, + "ap-northeast-2": { + "arn": "arn:aws:lambda:ap-northeast-2:580247275435:layer:LambdaInsightsExtension:2" + }, + "ap-south-1": { + "arn": "arn:aws:lambda:ap-south-1:580247275435:layer:LambdaInsightsExtension:2" + }, + "ap-southeast-1": { + "arn": "arn:aws:lambda:ap-southeast-1:580247275435:layer:LambdaInsightsExtension:2" + }, + "ap-southeast-2": { + "arn": "arn:aws:lambda:ap-southeast-2:580247275435:layer:LambdaInsightsExtension:2" + }, + "ca-central-1": { + "arn": "arn:aws:lambda:ca-central-1:580247275435:layer:LambdaInsightsExtension:2" + }, + "eu-central-1": { + "arn": "arn:aws:lambda:eu-central-1:580247275435:layer:LambdaInsightsExtension:2" + }, + "eu-north-1": { + "arn": "arn:aws:lambda:eu-north-1:580247275435:layer:LambdaInsightsExtension:2" + }, + "eu-west-1": { + "arn": "arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:2" + }, + "eu-west-2": { + "arn": "arn:aws:lambda:eu-west-2:580247275435:layer:LambdaInsightsExtension:2" + }, + "eu-west-3": { + "arn": "arn:aws:lambda:eu-west-3:580247275435:layer:LambdaInsightsExtension:2" + }, + "sa-east-1": { + "arn": "arn:aws:lambda:sa-east-1:580247275435:layer:LambdaInsightsExtension:2" + }, + "us-east-1": { + "arn": "arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:2" + }, + "us-east-2": { + "arn": "arn:aws:lambda:us-east-2:580247275435:layer:LambdaInsightsExtension:2" + }, + "us-west-1": { + "arn": "arn:aws:lambda:us-west-1:580247275435:layer:LambdaInsightsExtension:2" + }, + "us-west-2": { + "arn": "arn:aws:lambda:us-west-2:580247275435:layer:LambdaInsightsExtension:2" + } + }, + "LambdaInsightsVersions10860": { + "ap-northeast-1": { + "arn": "arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:11" + }, + "ap-northeast-2": { + "arn": "arn:aws:lambda:ap-northeast-2:580247275435:layer:LambdaInsightsExtension:11" + }, + "ap-south-1": { + "arn": "arn:aws:lambda:ap-south-1:580247275435:layer:LambdaInsightsExtension:11" + }, + "ap-southeast-1": { + "arn": "arn:aws:lambda:ap-southeast-1:580247275435:layer:LambdaInsightsExtension:11" + }, + "ap-southeast-2": { + "arn": "arn:aws:lambda:ap-southeast-2:580247275435:layer:LambdaInsightsExtension:11" + }, + "ca-central-1": { + "arn": "arn:aws:lambda:ca-central-1:580247275435:layer:LambdaInsightsExtension:11" + }, + "eu-central-1": { + "arn": "arn:aws:lambda:eu-central-1:580247275435:layer:LambdaInsightsExtension:11" + }, + "eu-north-1": { + "arn": "arn:aws:lambda:eu-north-1:580247275435:layer:LambdaInsightsExtension:11" + }, + "eu-west-1": { + "arn": "arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:11" + }, + "eu-west-2": { + "arn": "arn:aws:lambda:eu-west-2:580247275435:layer:LambdaInsightsExtension:11" + }, + "eu-west-3": { + "arn": "arn:aws:lambda:eu-west-3:580247275435:layer:LambdaInsightsExtension:11" + }, + "sa-east-1": { + "arn": "arn:aws:lambda:sa-east-1:580247275435:layer:LambdaInsightsExtension:11" + }, + "us-east-1": { + "arn": "arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:11" + }, + "us-east-2": { + "arn": "arn:aws:lambda:us-east-2:580247275435:layer:LambdaInsightsExtension:11" + }, + "us-west-1": { + "arn": "arn:aws:lambda:us-west-1:580247275435:layer:LambdaInsightsExtension:11" + }, + "us-west-2": { + "arn": "arn:aws:lambda:us-west-2:580247275435:layer:LambdaInsightsExtension:11" + } + }, + "LambdaInsightsVersions10890": { + "ap-northeast-1": { + "arn": "arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:12" + }, + "ap-northeast-2": { + "arn": "arn:aws:lambda:ap-northeast-2:580247275435:layer:LambdaInsightsExtension:12" + }, + "ap-south-1": { + "arn": "arn:aws:lambda:ap-south-1:580247275435:layer:LambdaInsightsExtension:12" + }, + "ap-southeast-1": { + "arn": "arn:aws:lambda:ap-southeast-1:580247275435:layer:LambdaInsightsExtension:12" + }, + "ap-southeast-2": { + "arn": "arn:aws:lambda:ap-southeast-2:580247275435:layer:LambdaInsightsExtension:12" + }, + "ca-central-1": { + "arn": "arn:aws:lambda:ca-central-1:580247275435:layer:LambdaInsightsExtension:12" + }, + "eu-central-1": { + "arn": "arn:aws:lambda:eu-central-1:580247275435:layer:LambdaInsightsExtension:12" + }, + "eu-north-1": { + "arn": "arn:aws:lambda:eu-north-1:580247275435:layer:LambdaInsightsExtension:12" + }, + "eu-west-1": { + "arn": "arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:12" + }, + "eu-west-2": { + "arn": "arn:aws:lambda:eu-west-2:580247275435:layer:LambdaInsightsExtension:12" + }, + "eu-west-3": { + "arn": "arn:aws:lambda:eu-west-3:580247275435:layer:LambdaInsightsExtension:12" + }, + "sa-east-1": { + "arn": "arn:aws:lambda:sa-east-1:580247275435:layer:LambdaInsightsExtension:12" + }, + "us-east-1": { + "arn": "arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:12" + }, + "us-east-2": { + "arn": "arn:aws:lambda:us-east-2:580247275435:layer:LambdaInsightsExtension:12" + }, + "us-west-1": { + "arn": "arn:aws:lambda:us-west-1:580247275435:layer:LambdaInsightsExtension:12" + }, + "us-west-2": { + "arn": "arn:aws:lambda:us-west-2:580247275435:layer:LambdaInsightsExtension:12" + } + }, + "LambdaInsightsVersions10980": { + "af-south-1": { + "arn": "arn:aws:lambda:af-south-1:012438385374:layer:LambdaInsightsExtension:8" + }, + "ap-east-1": { + "arn": "arn:aws:lambda:ap-east-1:519774774795:layer:LambdaInsightsExtension:8" + }, + "ap-northeast-1": { + "arn": "arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:14" + }, + "ap-northeast-2": { + "arn": "arn:aws:lambda:ap-northeast-2:580247275435:layer:LambdaInsightsExtension:14" + }, + "ap-south-1": { + "arn": "arn:aws:lambda:ap-south-1:580247275435:layer:LambdaInsightsExtension:14" + }, + "ap-southeast-1": { + "arn": "arn:aws:lambda:ap-southeast-1:580247275435:layer:LambdaInsightsExtension:14" + }, + "ap-southeast-2": { + "arn": "arn:aws:lambda:ap-southeast-2:580247275435:layer:LambdaInsightsExtension:14" + }, + "ca-central-1": { + "arn": "arn:aws:lambda:ca-central-1:580247275435:layer:LambdaInsightsExtension:14" + }, + "cn-north-1": { + "arn": "arn:aws-cn:lambda:cn-north-1:488211338238:layer:LambdaInsightsExtension:8" + }, + "cn-northwest-1": { + "arn": "arn:aws-cn:lambda:cn-northwest-1:488211338238:layer:LambdaInsightsExtension:8" + }, + "eu-central-1": { + "arn": "arn:aws:lambda:eu-central-1:580247275435:layer:LambdaInsightsExtension:14" + }, + "eu-north-1": { + "arn": "arn:aws:lambda:eu-north-1:580247275435:layer:LambdaInsightsExtension:14" + }, + "eu-south-1": { + "arn": "arn:aws:lambda:eu-south-1:339249233099:layer:LambdaInsightsExtension:8" + }, + "eu-west-1": { + "arn": "arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:14" + }, + "eu-west-2": { + "arn": "arn:aws:lambda:eu-west-2:580247275435:layer:LambdaInsightsExtension:14" + }, + "eu-west-3": { + "arn": "arn:aws:lambda:eu-west-3:580247275435:layer:LambdaInsightsExtension:14" + }, + "me-south-1": { + "arn": "arn:aws:lambda:me-south-1:285320876703:layer:LambdaInsightsExtension:8" + }, + "sa-east-1": { + "arn": "arn:aws:lambda:sa-east-1:580247275435:layer:LambdaInsightsExtension:14" + }, + "us-east-1": { + "arn": "arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:14" + }, + "us-east-2": { + "arn": "arn:aws:lambda:us-east-2:580247275435:layer:LambdaInsightsExtension:14" + }, + "us-west-1": { + "arn": "arn:aws:lambda:us-west-1:580247275435:layer:LambdaInsightsExtension:14" + }, + "us-west-2": { + "arn": "arn:aws:lambda:us-west-2:580247275435:layer:LambdaInsightsExtension:14" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/aws-lambda/test/integ.lambda-insights-mapping.ts b/packages/@aws-cdk/aws-lambda/test/integ.lambda-insights-mapping.ts new file mode 100644 index 0000000000000..78cf8d74106ed --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/integ.lambda-insights-mapping.ts @@ -0,0 +1,42 @@ +import * as cdk from '@aws-cdk/core'; +import * as lambda from '../lib'; + +const app = new cdk.App(); + +const stack = new cdk.Stack(app, 'stack'); + +new lambda.Function(stack, 'MyFunc1', { + runtime: lambda.Runtime.NODEJS_10_X, + handler: 'index.handler', + code: lambda.Code.fromInline(`exports.handler = ${handler.toString()}`), + insightsVersion: lambda.LambdaInsightsVersion.VERSION_1_0_54_0, +}); + +new lambda.Function(stack, 'MyFunc2', { + runtime: lambda.Runtime.NODEJS_10_X, + handler: 'index.handler', + code: lambda.Code.fromInline(`exports.handler = ${handler.toString()}`), + insightsVersion: lambda.LambdaInsightsVersion.VERSION_1_0_86_0, +}); + +new lambda.Function(stack, 'MyFunc3', { + runtime: lambda.Runtime.NODEJS_10_X, + handler: 'index.handler', + code: lambda.Code.fromInline(`exports.handler = ${handler.toString()}`), + insightsVersion: lambda.LambdaInsightsVersion.VERSION_1_0_89_0, +}); + +new lambda.Function(stack, 'MyFunc4', { + runtime: lambda.Runtime.NODEJS_10_X, + handler: 'index.handler', + code: lambda.Code.fromInline(`exports.handler = ${handler.toString()}`), + insightsVersion: lambda.LambdaInsightsVersion.VERSION_1_0_98_0, +}); + +app.synth(); + +/* eslint-disable no-console */ +function handler(event: any, _context: any, callback: any) { + console.log(JSON.stringify(event, undefined, 2)); + return callback(); +} diff --git a/packages/@aws-cdk/aws-lambda/test/lambda-insights.test.ts b/packages/@aws-cdk/aws-lambda/test/lambda-insights.test.ts new file mode 100644 index 0000000000000..990c0c7fb7405 --- /dev/null +++ b/packages/@aws-cdk/aws-lambda/test/lambda-insights.test.ts @@ -0,0 +1,316 @@ +import '@aws-cdk/assert-internal/jest'; +import { MatchStyle } from '@aws-cdk/assert-internal'; +import * as cdk from '@aws-cdk/core'; +import * as lambda from '../lib'; + +/** + * Boilerplate code to create a Function with a given insights version + */ +function functionWithInsightsVersion(stack: cdk.Stack, id: string, insightsVersion: lambda.LambdaInsightsVersion): lambda.IFunction { + return new lambda.Function(stack, id, { + code: new lambda.InlineCode('foo'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_10_X, + insightsVersion, + }); +} + +/** + * Check if the function's Role has the Lambda Insights IAM policy + */ +function verifyRoleHasCorrectPolicies(stack: cdk.Stack) { + expect(stack).toHaveResource('AWS::IAM::Role', { + ManagedPolicyArns: + [ + { 'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':iam::aws:policy/service-role/AWSLambdaBasicExecutionRole']] }, + { 'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy']] }, + ], + }); +} + +// This test code has app.synth() because the lambda-insights code has functions that are only run on synthesis +describe('lambda-insights', () => { + test('can provide arn to enable insights', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'Stack', {}); + const layerArn = 'arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:14'; + functionWithInsightsVersion(stack, 'MyLambda', lambda.LambdaInsightsVersion.fromInsightVersionArn(layerArn)); + + verifyRoleHasCorrectPolicies(stack); + + expect(stack).toHaveResource('AWS::Lambda::Function', { + Layers: [layerArn], + }); + + // On synthesis it should not throw an error + expect(() => app.synth()).not.toThrow(); + }); + + test('can provide a version to enable insights', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'Stack', { + env: { account: '123456789012', region: 'us-east-1' }, + }); + functionWithInsightsVersion(stack, 'MyLambda', lambda.LambdaInsightsVersion.VERSION_1_0_54_0); + + verifyRoleHasCorrectPolicies(stack); + + expect(stack).toHaveResource('AWS::Lambda::Function', { + Layers: ['arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:2'], + }); + + // On synthesis it should not throw an error + expect(() => app.synth()).not.toThrow(); + }); + + test('existing region with existing but unsupported version throws error', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'Stack', { + env: { account: '123456789012', region: 'af-south-1' }, + }); + + // AF-SOUTH-1 exists, 1.0.54.0 exists, but 1.0.54.0 isn't supported in AF-SOUTH-1 + functionWithInsightsVersion(stack, 'BadVersion', lambda.LambdaInsightsVersion.VERSION_1_0_54_0); + + // On synthesis it should throw an error + expect(() => app.synth()).toThrow('Insights version 1.0.54.0 is not supported in region af-south-1'); + }); + + test('using a specific version without providing a region', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'Stack', {}); + + functionWithInsightsVersion(stack, 'MyLambda', lambda.LambdaInsightsVersion.VERSION_1_0_54_0); + + // Should be looking up a mapping + expect(stack).toHaveResource('AWS::Lambda::Function', { + Layers: [{ + 'Fn::FindInMap': [ + 'LambdaInsightsVersions10540', + { + Ref: 'AWS::Region', + }, + 'arn', + ], + }], + }); + + // On synthesis it should not throw an error + expect(() => app.synth()).not.toThrow(); + }); + + // Here we're error checking the code which verifies if the mapping exists already + test('can create two functions in a region agnostic stack with the same version', () => { + const app = new cdk.App(); + const stack = new cdk.Stack(app, 'Stack', {}); + + functionWithInsightsVersion(stack, 'MyLambda1', lambda.LambdaInsightsVersion.VERSION_1_0_54_0); + functionWithInsightsVersion(stack, 'MyLambda2', lambda.LambdaInsightsVersion.VERSION_1_0_54_0); + + /* eslint-disable quote-props */ + expect(stack).toMatchTemplate({ + Resources: { + MyLambda1ServiceRole69A7E1EA: { + 'Type': 'AWS::IAM::Role', + 'Properties': { + 'AssumeRolePolicyDocument': { + 'Statement': [ + { + 'Action': 'sts:AssumeRole', + 'Effect': 'Allow', + 'Principal': { + 'Service': 'lambda.amazonaws.com', + }, + }, + ], + 'Version': '2012-10-17', + }, + 'ManagedPolicyArns': [ + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + 'Ref': 'AWS::Partition', + }, + ':iam::aws:policy/service-role/AWSLambdaBasicExecutionRole', + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + 'Ref': 'AWS::Partition', + }, + ':iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy', + ], + ], + }, + ], + }, + }, + MyLambda1AAFB4554: { + 'Type': 'AWS::Lambda::Function', + 'Properties': { + 'Code': { + 'ZipFile': 'foo', + }, + 'Role': { + 'Fn::GetAtt': [ + 'MyLambda1ServiceRole69A7E1EA', + 'Arn', + ], + }, + 'Handler': 'index.handler', + 'Layers': [ + { + 'Fn::FindInMap': [ + 'LambdaInsightsVersions10540', + { + 'Ref': 'AWS::Region', + }, + 'arn', + ], + }, + ], + 'Runtime': 'nodejs10.x', + }, + 'DependsOn': [ + 'MyLambda1ServiceRole69A7E1EA', + ], + }, + MyLambda2ServiceRoleD09B370C: { + 'Type': 'AWS::IAM::Role', + 'Properties': { + 'AssumeRolePolicyDocument': { + 'Statement': [ + { + 'Action': 'sts:AssumeRole', + 'Effect': 'Allow', + 'Principal': { + 'Service': 'lambda.amazonaws.com', + }, + }, + ], + 'Version': '2012-10-17', + }, + 'ManagedPolicyArns': [ + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + 'Ref': 'AWS::Partition', + }, + ':iam::aws:policy/service-role/AWSLambdaBasicExecutionRole', + ], + ], + }, + { + 'Fn::Join': [ + '', + [ + 'arn:', + { + 'Ref': 'AWS::Partition', + }, + ':iam::aws:policy/CloudWatchLambdaInsightsExecutionRolePolicy', + ], + ], + }, + ], + }, + }, + MyLambda2254B54D5: { + 'Type': 'AWS::Lambda::Function', + 'Properties': { + 'Code': { + 'ZipFile': 'foo', + }, + 'Role': { + 'Fn::GetAtt': [ + 'MyLambda2ServiceRoleD09B370C', + 'Arn', + ], + }, + 'Handler': 'index.handler', + 'Layers': [ + { + 'Fn::FindInMap': [ + 'LambdaInsightsVersions10540', + { + 'Ref': 'AWS::Region', + }, + 'arn', + ], + }, + ], + 'Runtime': 'nodejs10.x', + }, + 'DependsOn': [ + 'MyLambda2ServiceRoleD09B370C', + ], + }, + }, + Mappings: { + LambdaInsightsVersions10540: { + 'ap-northeast-1': { + arn: 'arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:2', + }, + 'ap-northeast-2': { + 'arn': 'arn:aws:lambda:ap-northeast-2:580247275435:layer:LambdaInsightsExtension:2', + }, + 'ap-south-1': { + 'arn': 'arn:aws:lambda:ap-south-1:580247275435:layer:LambdaInsightsExtension:2', + }, + 'ap-southeast-1': { + 'arn': 'arn:aws:lambda:ap-southeast-1:580247275435:layer:LambdaInsightsExtension:2', + }, + 'ap-southeast-2': { + 'arn': 'arn:aws:lambda:ap-southeast-2:580247275435:layer:LambdaInsightsExtension:2', + }, + 'ca-central-1': { + 'arn': 'arn:aws:lambda:ca-central-1:580247275435:layer:LambdaInsightsExtension:2', + }, + 'eu-central-1': { + 'arn': 'arn:aws:lambda:eu-central-1:580247275435:layer:LambdaInsightsExtension:2', + }, + 'eu-north-1': { + 'arn': 'arn:aws:lambda:eu-north-1:580247275435:layer:LambdaInsightsExtension:2', + }, + 'eu-west-1': { + 'arn': 'arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:2', + }, + 'eu-west-2': { + 'arn': 'arn:aws:lambda:eu-west-2:580247275435:layer:LambdaInsightsExtension:2', + }, + 'eu-west-3': { + 'arn': 'arn:aws:lambda:eu-west-3:580247275435:layer:LambdaInsightsExtension:2', + }, + 'sa-east-1': { + 'arn': 'arn:aws:lambda:sa-east-1:580247275435:layer:LambdaInsightsExtension:2', + }, + 'us-east-1': { + 'arn': 'arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:2', + }, + 'us-east-2': { + 'arn': 'arn:aws:lambda:us-east-2:580247275435:layer:LambdaInsightsExtension:2', + }, + 'us-west-1': { + 'arn': 'arn:aws:lambda:us-west-1:580247275435:layer:LambdaInsightsExtension:2', + }, + 'us-west-2': { + 'arn': 'arn:aws:lambda:us-west-2:580247275435:layer:LambdaInsightsExtension:2', + }, + }, + }, + }, MatchStyle.EXACT); + // On synthesis it should not throw an error + expect(() => app.synth()).not.toThrow(); + }); +}); diff --git a/packages/@aws-cdk/aws-licensemanager/package.json b/packages/@aws-cdk/aws-licensemanager/package.json index eb66089eae974..0219ff3d93dc0 100644 --- a/packages/@aws-cdk/aws-licensemanager/package.json +++ b/packages/@aws-cdk/aws-licensemanager/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-licensemanager/test/licensemanager.test.ts b/packages/@aws-cdk/aws-licensemanager/test/licensemanager.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-licensemanager/test/licensemanager.test.ts +++ b/packages/@aws-cdk/aws-licensemanager/test/licensemanager.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-location/package.json b/packages/@aws-cdk/aws-location/package.json index dedff67266046..5a9473d0d22dd 100644 --- a/packages/@aws-cdk/aws-location/package.json +++ b/packages/@aws-cdk/aws-location/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-location/test/location.test.ts b/packages/@aws-cdk/aws-location/test/location.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-location/test/location.test.ts +++ b/packages/@aws-cdk/aws-location/test/location.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-lookoutequipment/package.json b/packages/@aws-cdk/aws-lookoutequipment/package.json index e34187a2c7e57..3d3d93d1a9bb4 100644 --- a/packages/@aws-cdk/aws-lookoutequipment/package.json +++ b/packages/@aws-cdk/aws-lookoutequipment/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.22", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-lookoutequipment/test/lookoutequipment.test.ts b/packages/@aws-cdk/aws-lookoutequipment/test/lookoutequipment.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-lookoutequipment/test/lookoutequipment.test.ts +++ b/packages/@aws-cdk/aws-lookoutequipment/test/lookoutequipment.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-lookoutmetrics/package.json b/packages/@aws-cdk/aws-lookoutmetrics/package.json index 93c04870c0f5d..f79a8e599ed12 100644 --- a/packages/@aws-cdk/aws-lookoutmetrics/package.json +++ b/packages/@aws-cdk/aws-lookoutmetrics/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-lookoutmetrics/test/lookoutmetrics.test.ts b/packages/@aws-cdk/aws-lookoutmetrics/test/lookoutmetrics.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-lookoutmetrics/test/lookoutmetrics.test.ts +++ b/packages/@aws-cdk/aws-lookoutmetrics/test/lookoutmetrics.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-lookoutvision/package.json b/packages/@aws-cdk/aws-lookoutvision/package.json index d55a122cb7624..33ede00a2af8c 100644 --- a/packages/@aws-cdk/aws-lookoutvision/package.json +++ b/packages/@aws-cdk/aws-lookoutvision/package.json @@ -81,7 +81,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-lookoutvision/test/lookoutvision.test.ts b/packages/@aws-cdk/aws-lookoutvision/test/lookoutvision.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-lookoutvision/test/lookoutvision.test.ts +++ b/packages/@aws-cdk/aws-lookoutvision/test/lookoutvision.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-macie/package.json b/packages/@aws-cdk/aws-macie/package.json index 1cbdb49f09399..cd1d450bd73b6 100644 --- a/packages/@aws-cdk/aws-macie/package.json +++ b/packages/@aws-cdk/aws-macie/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-macie/test/macie.test.ts b/packages/@aws-cdk/aws-macie/test/macie.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-macie/test/macie.test.ts +++ b/packages/@aws-cdk/aws-macie/test/macie.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-managedblockchain/package.json b/packages/@aws-cdk/aws-managedblockchain/package.json index 675de2f297c20..09d5ad7a954ea 100644 --- a/packages/@aws-cdk/aws-managedblockchain/package.json +++ b/packages/@aws-cdk/aws-managedblockchain/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-managedblockchain/test/managedblockchain.test.ts b/packages/@aws-cdk/aws-managedblockchain/test/managedblockchain.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-managedblockchain/test/managedblockchain.test.ts +++ b/packages/@aws-cdk/aws-managedblockchain/test/managedblockchain.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-mediaconnect/package.json b/packages/@aws-cdk/aws-mediaconnect/package.json index b67436e9224aa..d0f29ba806f03 100644 --- a/packages/@aws-cdk/aws-mediaconnect/package.json +++ b/packages/@aws-cdk/aws-mediaconnect/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-mediaconnect/test/mediaconnect.test.ts b/packages/@aws-cdk/aws-mediaconnect/test/mediaconnect.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-mediaconnect/test/mediaconnect.test.ts +++ b/packages/@aws-cdk/aws-mediaconnect/test/mediaconnect.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-mediaconvert/package.json b/packages/@aws-cdk/aws-mediaconvert/package.json index 4808bc6dda2ff..725541270f71b 100644 --- a/packages/@aws-cdk/aws-mediaconvert/package.json +++ b/packages/@aws-cdk/aws-mediaconvert/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-mediaconvert/test/mediaconvert.test.ts b/packages/@aws-cdk/aws-mediaconvert/test/mediaconvert.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-mediaconvert/test/mediaconvert.test.ts +++ b/packages/@aws-cdk/aws-mediaconvert/test/mediaconvert.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-medialive/package.json b/packages/@aws-cdk/aws-medialive/package.json index 3e1e7088f1f0c..dd9f764f06d1b 100644 --- a/packages/@aws-cdk/aws-medialive/package.json +++ b/packages/@aws-cdk/aws-medialive/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-medialive/test/medialive.test.ts b/packages/@aws-cdk/aws-medialive/test/medialive.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-medialive/test/medialive.test.ts +++ b/packages/@aws-cdk/aws-medialive/test/medialive.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-mediapackage/package.json b/packages/@aws-cdk/aws-mediapackage/package.json index 84077872af4d5..9910b1dc2f864 100644 --- a/packages/@aws-cdk/aws-mediapackage/package.json +++ b/packages/@aws-cdk/aws-mediapackage/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-mediapackage/test/mediapackage.test.ts b/packages/@aws-cdk/aws-mediapackage/test/mediapackage.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-mediapackage/test/mediapackage.test.ts +++ b/packages/@aws-cdk/aws-mediapackage/test/mediapackage.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-mediastore/package.json b/packages/@aws-cdk/aws-mediastore/package.json index 20e9b4057dbe5..5a5ec1ff16709 100644 --- a/packages/@aws-cdk/aws-mediastore/package.json +++ b/packages/@aws-cdk/aws-mediastore/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-mediastore/test/mediastore.test.ts b/packages/@aws-cdk/aws-mediastore/test/mediastore.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-mediastore/test/mediastore.test.ts +++ b/packages/@aws-cdk/aws-mediastore/test/mediastore.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-msk/package.json b/packages/@aws-cdk/aws-msk/package.json index 7309920e959ac..dd1523cffaf01 100644 --- a/packages/@aws-cdk/aws-msk/package.json +++ b/packages/@aws-cdk/aws-msk/package.json @@ -75,13 +75,13 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "cdk-integ-tools": "0.0.0", "pkglint": "0.0.0", - "jest": "^26.6.3", - "@aws-cdk/assert-internal": "0.0.0" + "jest": "^26.6.3" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-msk/test/cluster.test.ts b/packages/@aws-cdk/aws-msk/test/cluster.test.ts index 86b15c099f2a5..a990895e16d9c 100644 --- a/packages/@aws-cdk/aws-msk/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-msk/test/cluster.test.ts @@ -1,6 +1,4 @@ -import { ResourcePart, SynthUtils } from '@aws-cdk/assert-internal'; -import '@aws-cdk/assert-internal/jest'; - +import { Template } from '@aws-cdk/assertions'; import * as acmpca from '@aws-cdk/aws-acmpca'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as kms from '@aws-cdk/aws-kms'; @@ -26,32 +24,31 @@ describe('MSK Cluster', () => { vpc, }); - expect(stack).toHaveResourceLike( + Template.fromStack(stack).hasResource( 'AWS::MSK::Cluster', { DeletionPolicy: 'Retain', UpdateReplacePolicy: 'Retain', }, - ResourcePart.CompleteDefinition, ); - expect(stack).toHaveResourceLike('AWS::MSK::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::MSK::Cluster', { KafkaVersion: '2.6.1', }); - expect(stack).toHaveResourceLike('AWS::MSK::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::MSK::Cluster', { EncryptionInfo: { EncryptionInTransit: { ClientBroker: 'TLS', InCluster: true }, }, }); - expect(stack).toHaveResourceLike('AWS::MSK::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::MSK::Cluster', { NumberOfBrokerNodes: 2, }); - expect(stack).toHaveResourceLike('AWS::MSK::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::MSK::Cluster', { BrokerNodeGroupInfo: { StorageInfo: { EBSStorageInfo: { VolumeSize: 1000 } }, }, }); - expect(stack).toHaveResource('AWS::EC2::SecurityGroup'); - expect(stack).toHaveResourceLike('AWS::MSK::Cluster', { + Template.fromStack(stack).resourceCountIs('AWS::EC2::SecurityGroup', 1); + Template.fromStack(stack).hasResourceProperties('AWS::MSK::Cluster', { BrokerNodeGroupInfo: { SecurityGroups: [ { @@ -141,7 +138,7 @@ describe('MSK Cluster', () => { iam: true, }), }); - expect(stack).toHaveResourceLike('AWS::MSK::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::MSK::Cluster', { ClientAuthentication: { Sasl: { Iam: { Enabled: true } }, }, @@ -202,13 +199,13 @@ describe('MSK Cluster', () => { }); test('with alias msk/${clusterName}/sasl/scram', () => { - expect(stack).toHaveResourceLike('AWS::KMS::Alias', { + Template.fromStack(stack).hasResourceProperties('AWS::KMS::Alias', { AliasName: 'alias/msk/cluster/sasl/scram', }); }); test('with a policy allowing the secrets manager service to use the key', () => { - expect(stack).toHaveResourceLike('AWS::KMS::Key', { + Template.fromStack(stack).hasResourceProperties('AWS::KMS::Key', { KeyPolicy: { Statement: [ { @@ -281,6 +278,7 @@ describe('MSK Cluster', () => { Effect: 'Allow', Principal: { AWS: '*' }, Resource: '*', + Sid: 'Allow access through AWS Secrets Manager for all principals in the account that are authorized to use AWS Secrets Manager', }, ], }, @@ -319,7 +317,7 @@ describe('MSK Cluster', () => { ), }); - expect(stack).toHaveResourceLike('AWS::MSK::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::MSK::Cluster', { BrokerNodeGroupInfo: { InstanceType: 'kafka.m5.xlarge' }, }); }); @@ -336,7 +334,7 @@ describe('MSK Cluster', () => { ), }); - expect(stack).toHaveResourceLike('AWS::MSK::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::MSK::Cluster', { BrokerNodeGroupInfo: { InstanceType: 'kafka.m5.xlarge' }, }); }); @@ -352,7 +350,7 @@ describe('MSK Cluster', () => { }, }); - expect(stack).toHaveResourceLike('AWS::MSK::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::MSK::Cluster', { LoggingInfo: { BrokerLogs: { CloudWatchLogs: { @@ -376,7 +374,7 @@ describe('MSK Cluster', () => { }, }); - expect(stack).toHaveResourceLike('AWS::MSK::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::MSK::Cluster', { LoggingInfo: { BrokerLogs: { S3: { @@ -400,7 +398,7 @@ describe('MSK Cluster', () => { }, }); - expect(stack).toHaveResourceLike('AWS::MSK::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::MSK::Cluster', { LoggingInfo: { BrokerLogs: { Firehose: { @@ -445,7 +443,7 @@ describe('MSK Cluster', () => { ebsStorageInfo: { encryptionKey: new kms.Key(stack, 'Key') }, }); - expect(stack).toHaveResourceLike('AWS::MSK::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::MSK::Cluster', { EncryptionInfo: { EncryptionAtRest: { DataVolumeKMSKeyId: { @@ -526,7 +524,7 @@ describe('MSK Cluster', () => { ); // THEN - expect(SynthUtils.toCloudFormation(stack)).toMatchSnapshot(); + expect(Template.fromStack(stack)).toMatchSnapshot(); }); describe('when creating sasl/scram users', () => { @@ -555,7 +553,7 @@ describe('MSK Cluster', () => { const username = 'my-user'; cluster.addUser(username); - expect(stack).toHaveResourceLike('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { 'Name': { 'Fn::Join': [ '', diff --git a/packages/@aws-cdk/aws-mwaa/package.json b/packages/@aws-cdk/aws-mwaa/package.json index 07fbbab350909..0a784d8121200 100644 --- a/packages/@aws-cdk/aws-mwaa/package.json +++ b/packages/@aws-cdk/aws-mwaa/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-mwaa/test/mwaa.test.ts b/packages/@aws-cdk/aws-mwaa/test/mwaa.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-mwaa/test/mwaa.test.ts +++ b/packages/@aws-cdk/aws-mwaa/test/mwaa.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-networkfirewall/package.json b/packages/@aws-cdk/aws-networkfirewall/package.json index 27b3aa04a7136..3b6617b2582c5 100644 --- a/packages/@aws-cdk/aws-networkfirewall/package.json +++ b/packages/@aws-cdk/aws-networkfirewall/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-networkfirewall/test/networkfirewall.test.ts b/packages/@aws-cdk/aws-networkfirewall/test/networkfirewall.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-networkfirewall/test/networkfirewall.test.ts +++ b/packages/@aws-cdk/aws-networkfirewall/test/networkfirewall.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-networkmanager/package.json b/packages/@aws-cdk/aws-networkmanager/package.json index f0666a1e676cc..dd671b4ffd623 100644 --- a/packages/@aws-cdk/aws-networkmanager/package.json +++ b/packages/@aws-cdk/aws-networkmanager/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-networkmanager/test/networkmanager.test.ts b/packages/@aws-cdk/aws-networkmanager/test/networkmanager.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-networkmanager/test/networkmanager.test.ts +++ b/packages/@aws-cdk/aws-networkmanager/test/networkmanager.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-nimblestudio/package.json b/packages/@aws-cdk/aws-nimblestudio/package.json index 5f9f77d2f58b2..8270304b555fa 100644 --- a/packages/@aws-cdk/aws-nimblestudio/package.json +++ b/packages/@aws-cdk/aws-nimblestudio/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-nimblestudio/test/nimblestudio.test.ts b/packages/@aws-cdk/aws-nimblestudio/test/nimblestudio.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-nimblestudio/test/nimblestudio.test.ts +++ b/packages/@aws-cdk/aws-nimblestudio/test/nimblestudio.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-opsworks/package.json b/packages/@aws-cdk/aws-opsworks/package.json index 978dd2b2b07c5..5d6f8b77a7d04 100644 --- a/packages/@aws-cdk/aws-opsworks/package.json +++ b/packages/@aws-cdk/aws-opsworks/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-opsworks/test/opsworks.test.ts b/packages/@aws-cdk/aws-opsworks/test/opsworks.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-opsworks/test/opsworks.test.ts +++ b/packages/@aws-cdk/aws-opsworks/test/opsworks.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-opsworkscm/package.json b/packages/@aws-cdk/aws-opsworkscm/package.json index 42c0e014301cb..03870f42fa5a0 100644 --- a/packages/@aws-cdk/aws-opsworkscm/package.json +++ b/packages/@aws-cdk/aws-opsworkscm/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-opsworkscm/test/opsworkscm.test.ts b/packages/@aws-cdk/aws-opsworkscm/test/opsworkscm.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-opsworkscm/test/opsworkscm.test.ts +++ b/packages/@aws-cdk/aws-opsworkscm/test/opsworkscm.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-pinpoint/package.json b/packages/@aws-cdk/aws-pinpoint/package.json index 0f5b7b48a84cf..8475739eaa6f7 100644 --- a/packages/@aws-cdk/aws-pinpoint/package.json +++ b/packages/@aws-cdk/aws-pinpoint/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-pinpoint/test/pinpoint.test.ts b/packages/@aws-cdk/aws-pinpoint/test/pinpoint.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-pinpoint/test/pinpoint.test.ts +++ b/packages/@aws-cdk/aws-pinpoint/test/pinpoint.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-pinpointemail/package.json b/packages/@aws-cdk/aws-pinpointemail/package.json index 7659ce4025b4a..d57fe0f9ac922 100644 --- a/packages/@aws-cdk/aws-pinpointemail/package.json +++ b/packages/@aws-cdk/aws-pinpointemail/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-pinpointemail/test/pinpointemail.test.ts b/packages/@aws-cdk/aws-pinpointemail/test/pinpointemail.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-pinpointemail/test/pinpointemail.test.ts +++ b/packages/@aws-cdk/aws-pinpointemail/test/pinpointemail.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-qldb/package.json b/packages/@aws-cdk/aws-qldb/package.json index ac50a35b7c1aa..3922e74b5a384 100644 --- a/packages/@aws-cdk/aws-qldb/package.json +++ b/packages/@aws-cdk/aws-qldb/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-qldb/test/qldb.test.ts b/packages/@aws-cdk/aws-qldb/test/qldb.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-qldb/test/qldb.test.ts +++ b/packages/@aws-cdk/aws-qldb/test/qldb.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-quicksight/package.json b/packages/@aws-cdk/aws-quicksight/package.json index 3d55f0052512b..00f42d396c801 100644 --- a/packages/@aws-cdk/aws-quicksight/package.json +++ b/packages/@aws-cdk/aws-quicksight/package.json @@ -81,7 +81,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-quicksight/test/quicksight.test.ts b/packages/@aws-cdk/aws-quicksight/test/quicksight.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-quicksight/test/quicksight.test.ts +++ b/packages/@aws-cdk/aws-quicksight/test/quicksight.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-ram/package.json b/packages/@aws-cdk/aws-ram/package.json index 6383a8a7ce1a1..6f817b0f45b4b 100644 --- a/packages/@aws-cdk/aws-ram/package.json +++ b/packages/@aws-cdk/aws-ram/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-ram/test/ram.test.ts b/packages/@aws-cdk/aws-ram/test/ram.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-ram/test/ram.test.ts +++ b/packages/@aws-cdk/aws-ram/test/ram.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-redshift/package.json b/packages/@aws-cdk/aws-redshift/package.json index 5ccccb2f4f2df..3bf492f83ee7b 100644 --- a/packages/@aws-cdk/aws-redshift/package.json +++ b/packages/@aws-cdk/aws-redshift/package.json @@ -73,12 +73,12 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "jest": "^26.6.3", - "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/aws-ec2": "0.0.0", diff --git a/packages/@aws-cdk/aws-redshift/test/cluster.test.ts b/packages/@aws-cdk/aws-redshift/test/cluster.test.ts index 7731320e8756c..28f2fbfd4655b 100644 --- a/packages/@aws-cdk/aws-redshift/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-redshift/test/cluster.test.ts @@ -1,5 +1,4 @@ -import { ABSENT, expect as cdkExpect, haveResource, ResourcePart } from '@aws-cdk/assert-internal'; -import '@aws-cdk/assert-internal/jest'; +import { Match, Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as kms from '@aws-cdk/aws-kms'; import * as s3 from '@aws-cdk/aws-s3'; @@ -25,7 +24,7 @@ test('check that instantiation works', () => { }); // THEN - cdkExpect(stack).to(haveResource('AWS::Redshift::Cluster', { + Template.fromStack(stack).hasResource('AWS::Redshift::Cluster', { Properties: { AllowVersionUpgrade: true, MasterUsername: 'admin', @@ -42,9 +41,9 @@ test('check that instantiation works', () => { }, DeletionPolicy: 'Retain', UpdateReplacePolicy: 'Retain', - }, ResourcePart.CompleteDefinition)); + }); - cdkExpect(stack).to(haveResource('AWS::Redshift::ClusterSubnetGroup', { + Template.fromStack(stack).hasResource('AWS::Redshift::ClusterSubnetGroup', { Properties: { Description: 'Subnets for Redshift Redshift cluster', SubnetIds: [ @@ -55,7 +54,7 @@ test('check that instantiation works', () => { }, DeletionPolicy: 'Retain', UpdateReplacePolicy: 'Retain', - }, ResourcePart.CompleteDefinition)); + }); }); test('can create a cluster with imported vpc and security group', () => { @@ -76,12 +75,12 @@ test('can create a cluster with imported vpc and security group', () => { }); // THEN - cdkExpect(stack).to(haveResource('AWS::Redshift::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', { ClusterSubnetGroupName: { Ref: 'RedshiftSubnetsDFE70E0A' }, MasterUsername: 'admin', MasterUserPassword: 'tooshort', VpcSecurityGroupIds: ['SecurityGroupId12345'], - })); + }); }); test('creates a secret when master credentials are not specified', () => { @@ -94,7 +93,7 @@ test('creates a secret when master credentials are not specified', () => { }); // THEN - cdkExpect(stack).to(haveResource('AWS::Redshift::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', { MasterUsername: { 'Fn::Join': [ '', @@ -119,16 +118,16 @@ test('creates a secret when master credentials are not specified', () => { ], ], }, - })); + }); - cdkExpect(stack).to(haveResource('AWS::SecretsManager::Secret', { + Template.fromStack(stack).hasResourceProperties('AWS::SecretsManager::Secret', { GenerateSecretString: { ExcludeCharacters: '"@/\\\ \'', GenerateStringKey: 'password', PasswordLength: 30, SecretStringTemplate: '{"username":"admin"}', }, - })); + }); }); describe('node count', () => { @@ -144,10 +143,10 @@ describe('node count', () => { }); // THEN - cdkExpect(stack).to(haveResource('AWS::Redshift::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', { ClusterType: 'single-node', - NumberOfNodes: ABSENT, - })); + NumberOfNodes: Match.absentProperty(), + }); }); test('Single Node Clusters treat 1 node as undefined', () => { @@ -162,10 +161,10 @@ describe('node count', () => { }); // THEN - cdkExpect(stack).to(haveResource('AWS::Redshift::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', { ClusterType: 'single-node', - NumberOfNodes: ABSENT, - })); + NumberOfNodes: Match.absentProperty(), + }); }); test('Single Node Clusters throw if any other node count is specified', () => { @@ -192,10 +191,10 @@ describe('node count', () => { }); // THEN - cdkExpect(stack).to(haveResource('AWS::Redshift::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', { ClusterType: 'multi-node', NumberOfNodes: 2, - })); + }); }); test.each([0, 1, -1, 101])('Multi-Node Clusters throw with %s nodes', (numberOfNodes: number) => { @@ -227,12 +226,12 @@ describe('node count', () => { }); // THEN - cdkExpect(stack).to(haveResource('AWS::Redshift::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', { ClusterType: 'multi-node', NumberOfNodes: { Ref: 'numberOfNodes', }, - })); + }); }); }); @@ -247,14 +246,14 @@ test('create an encrypted cluster with custom KMS key', () => { }); // THEN - cdkExpect(stack).to(haveResource('AWS::Redshift::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', { KmsKeyId: { 'Fn::GetAtt': [ 'Key961B73FD', 'Arn', ], }, - })); + }); }); test('cluster with parameter group', () => { @@ -275,9 +274,9 @@ test('cluster with parameter group', () => { }); // THEN - cdkExpect(stack).to(haveResource('AWS::Redshift::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', { ClusterParameterGroupName: { Ref: 'ParamsA8366201' }, - })); + }); }); @@ -292,9 +291,9 @@ test('publicly accessible cluster', () => { }); // THEN - cdkExpect(stack).to(haveResource('AWS::Redshift::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', { PubliclyAccessible: true, - })); + }); }); test('imported cluster with imported security group honors allowAllOutbound', () => { @@ -314,9 +313,9 @@ test('imported cluster with imported security group honors allowAllOutbound', () cluster.connections.allowToAnyIpv4(ec2.Port.tcp(443)); // THEN - cdkExpect(stack).to(haveResource('AWS::EC2::SecurityGroupEgress', { + Template.fromStack(stack).hasResourceProperties('AWS::EC2::SecurityGroupEgress', { GroupId: 'sg-123456789', - })); + }); }); test('can create a cluster with logging enabled', () => { @@ -334,12 +333,12 @@ test('can create a cluster with logging enabled', () => { }); // THEN - cdkExpect(stack).to(haveResource('AWS::Redshift::Cluster', { + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', { LoggingProperties: { BucketName: 'logging-bucket', S3KeyPrefix: 'prefix', }, - })); + }); }); test('throws when trying to add rotation to a cluster without secret', () => { @@ -408,8 +407,8 @@ test('can use existing cluster subnet group', () => { subnetGroup: ClusterSubnetGroup.fromClusterSubnetGroupName(stack, 'Group', 'my-existing-cluster-subnet-group'), }); - expect(stack).not.toHaveResource('AWS::Redshift::ClusterSubnetGroup'); - expect(stack).toHaveResourceLike('AWS::Redshift::Cluster', { + Template.fromStack(stack).resourceCountIs('AWS::Redshift::ClusterSubnetGroup', 0); + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::Cluster', { ClusterSubnetGroupName: 'my-existing-cluster-subnet-group', }); }); diff --git a/packages/@aws-cdk/aws-redshift/test/parameter-group.test.ts b/packages/@aws-cdk/aws-redshift/test/parameter-group.test.ts index c49708b8eb557..1853fc0f5baf5 100644 --- a/packages/@aws-cdk/aws-redshift/test/parameter-group.test.ts +++ b/packages/@aws-cdk/aws-redshift/test/parameter-group.test.ts @@ -1,4 +1,4 @@ -import { expect as cdkExpect, haveResource } from '@aws-cdk/assert-internal'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import { ClusterParameterGroup } from '../lib'; @@ -15,7 +15,7 @@ test('create a cluster parameter group', () => { }); // THEN - cdkExpect(stack).to(haveResource('AWS::Redshift::ClusterParameterGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::ClusterParameterGroup', { Description: 'desc', ParameterGroupFamily: 'redshift-1.0', Parameters: [ @@ -24,6 +24,6 @@ test('create a cluster parameter group', () => { ParameterValue: 'value', }, ], - })); + }); }); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-redshift/test/subnet-group.test.ts b/packages/@aws-cdk/aws-redshift/test/subnet-group.test.ts index c27a4998ce76e..0fb5c6b17f21d 100644 --- a/packages/@aws-cdk/aws-redshift/test/subnet-group.test.ts +++ b/packages/@aws-cdk/aws-redshift/test/subnet-group.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import { Stack } from '@aws-cdk/core'; import { ClusterSubnetGroup } from '../lib'; @@ -17,7 +17,7 @@ test('creates a subnet group from minimal properties', () => { vpc, }); - expect(stack).toHaveResource('AWS::Redshift::ClusterSubnetGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::ClusterSubnetGroup', { Description: 'MyGroup', SubnetIds: [ { Ref: 'VPCPrivateSubnet1Subnet8BCA10E0' }, @@ -33,7 +33,7 @@ describe('subnet selection', () => { vpc, }); - expect(stack).toHaveResource('AWS::Redshift::ClusterSubnetGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::ClusterSubnetGroup', { Description: 'MyGroup', SubnetIds: [ { Ref: 'VPCPrivateSubnet1Subnet8BCA10E0' }, @@ -49,7 +49,7 @@ describe('subnet selection', () => { vpcSubnets: { subnetType: ec2.SubnetType.PUBLIC }, }); - expect(stack).toHaveResource('AWS::Redshift::ClusterSubnetGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::Redshift::ClusterSubnetGroup', { Description: 'MyGroup', SubnetIds: [ { Ref: 'VPCPublicSubnet1SubnetB4246D30' }, diff --git a/packages/@aws-cdk/aws-resourcegroups/package.json b/packages/@aws-cdk/aws-resourcegroups/package.json index 611c01ef93ae8..88e73e2bd2426 100644 --- a/packages/@aws-cdk/aws-resourcegroups/package.json +++ b/packages/@aws-cdk/aws-resourcegroups/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-resourcegroups/test/resourcegroups.test.ts b/packages/@aws-cdk/aws-resourcegroups/test/resourcegroups.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-resourcegroups/test/resourcegroups.test.ts +++ b/packages/@aws-cdk/aws-resourcegroups/test/resourcegroups.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-robomaker/package.json b/packages/@aws-cdk/aws-robomaker/package.json index 8f4f5c4350cc7..124451f52e67b 100644 --- a/packages/@aws-cdk/aws-robomaker/package.json +++ b/packages/@aws-cdk/aws-robomaker/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-robomaker/test/robomaker.test.ts b/packages/@aws-cdk/aws-robomaker/test/robomaker.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-robomaker/test/robomaker.test.ts +++ b/packages/@aws-cdk/aws-robomaker/test/robomaker.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-route53/lib/record-set.ts b/packages/@aws-cdk/aws-route53/lib/record-set.ts index aa3d4b2303285..6f49f06b5c70c 100644 --- a/packages/@aws-cdk/aws-route53/lib/record-set.ts +++ b/packages/@aws-cdk/aws-route53/lib/record-set.ts @@ -1,6 +1,6 @@ import * as path from 'path'; import * as iam from '@aws-cdk/aws-iam'; -import { CustomResource, CustomResourceProvider, CustomResourceProviderRuntime, Duration, IResource, Resource, Token } from '@aws-cdk/core'; +import { CustomResource, CustomResourceProvider, CustomResourceProviderRuntime, Duration, IResource, RemovalPolicy, Resource, Token } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { IAliasRecordTarget } from './alias-record-target'; import { IHostedZone } from './hosted-zone-ref'; @@ -659,6 +659,13 @@ export interface CrossAccountZoneDelegationRecordProps { * @default Duration.days(2) */ readonly ttl?: Duration; + + /** + * The removal policy to apply to the record set. + * + * @default RemovalPolicy.DESTROY + */ + readonly removalPolicy?: RemovalPolicy; } /** @@ -685,6 +692,7 @@ export class CrossAccountZoneDelegationRecord extends CoreConstruct { new CustomResource(this, 'CrossAccountZoneDelegationCustomResource', { resourceType: CROSS_ACCOUNT_ZONE_DELEGATION_RESOURCE_TYPE, serviceToken, + removalPolicy: props.removalPolicy, properties: { AssumeRoleArn: props.delegationRole.roleArn, ParentZoneName: props.parentHostedZoneName, diff --git a/packages/@aws-cdk/aws-route53/test/record-set.test.ts b/packages/@aws-cdk/aws-route53/test/record-set.test.ts index ff3a7f6d08c29..a071ad2a1aeea 100644 --- a/packages/@aws-cdk/aws-route53/test/record-set.test.ts +++ b/packages/@aws-cdk/aws-route53/test/record-set.test.ts @@ -1,6 +1,6 @@ -import { expect, haveResource } from '@aws-cdk/assert-internal'; +import { expect, haveResource, ResourcePart } from '@aws-cdk/assert-internal'; import * as iam from '@aws-cdk/aws-iam'; -import { Duration, Stack } from '@aws-cdk/core'; +import { Duration, RemovalPolicy, Stack } from '@aws-cdk/core'; import { nodeunitShim, Test } from 'nodeunit-shim'; import * as route53 from '../lib'; @@ -617,6 +617,7 @@ nodeunitShim({ parentHostedZoneId: parentZone.hostedZoneId, delegationRole: parentZone.crossAccountZoneDelegationRole!, ttl: Duration.seconds(60), + removalPolicy: RemovalPolicy.RETAIN, }); // THEN @@ -645,6 +646,10 @@ nodeunitShim({ }, TTL: 60, })); + expect(stack).to(haveResource('Custom::CrossAccountZoneDelegation', { + DeletionPolicy: 'Retain', + UpdateReplacePolicy: 'Retain', + }, ResourcePart.CompleteDefinition)); test.done(); }, diff --git a/packages/@aws-cdk/aws-route53recoverycontrol/.eslintrc.js b/packages/@aws-cdk/aws-route53recoverycontrol/.eslintrc.js new file mode 100644 index 0000000000000..61dd8dd001f63 --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoverycontrol/.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-route53recoverycontrol/.gitignore b/packages/@aws-cdk/aws-route53recoverycontrol/.gitignore new file mode 100644 index 0000000000000..62ebc95d75ce6 --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoverycontrol/.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-route53recoverycontrol/.npmignore b/packages/@aws-cdk/aws-route53recoverycontrol/.npmignore new file mode 100644 index 0000000000000..f931fede67c44 --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoverycontrol/.npmignore @@ -0,0 +1,29 @@ +# Don't include original .ts files when doing `npm pack` +*.ts +!*.d.ts +coverage +.nyc_output +*.tgz + +dist +.LAST_PACKAGE +.LAST_BUILD +!*.js + +# Include .jsii +!.jsii + +*.snk + +*.tsbuildinfo + +tsconfig.json + +.eslintrc.js +jest.config.js + +# exclude cdk artifacts +**/cdk.out +junit.xml +test/ +!*.lit.ts diff --git a/packages/@aws-cdk/aws-route53recoverycontrol/LICENSE b/packages/@aws-cdk/aws-route53recoverycontrol/LICENSE new file mode 100644 index 0000000000000..28e4bdcec77ec --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoverycontrol/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-route53recoverycontrol/NOTICE b/packages/@aws-cdk/aws-route53recoverycontrol/NOTICE new file mode 100644 index 0000000000000..5fc3826926b5b --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoverycontrol/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-route53recoverycontrol/README.md b/packages/@aws-cdk/aws-route53recoverycontrol/README.md new file mode 100644 index 0000000000000..9a4113847129c --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoverycontrol/README.md @@ -0,0 +1,20 @@ +# AWS::Route53RecoveryControl 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 route53recoverycontrol = require('@aws-cdk/aws-route53recoverycontrol'); +``` diff --git a/packages/@aws-cdk/aws-route53recoverycontrol/jest.config.js b/packages/@aws-cdk/aws-route53recoverycontrol/jest.config.js new file mode 100644 index 0000000000000..54e28beb9798b --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoverycontrol/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-route53recoverycontrol/lib/index.ts b/packages/@aws-cdk/aws-route53recoverycontrol/lib/index.ts new file mode 100644 index 0000000000000..ca032e47c0b98 --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoverycontrol/lib/index.ts @@ -0,0 +1,2 @@ +// AWS::Route53RecoveryControl CloudFormation Resources: +export * from './route53recoverycontrol.generated'; diff --git a/packages/@aws-cdk/aws-route53recoverycontrol/package.json b/packages/@aws-cdk/aws-route53recoverycontrol/package.json new file mode 100644 index 0000000000000..8ceaa50512b21 --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoverycontrol/package.json @@ -0,0 +1,103 @@ +{ + "name": "@aws-cdk/aws-route53recoverycontrol", + "version": "0.0.0", + "description": "The CDK Construct Library for AWS::Route53RecoveryControl", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "jsii": { + "outdir": "dist", + "projectReferences": true, + "targets": { + "dotnet": { + "namespace": "Amazon.CDK.AWS.Route53RecoveryControl", + "packageId": "Amazon.CDK.AWS.Route53RecoveryControl", + "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.route53recoverycontrol", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "route53recoverycontrol" + } + }, + "python": { + "classifiers": [ + "Framework :: AWS CDK", + "Framework :: AWS CDK :: 1" + ], + "distName": "aws-cdk.aws-route53recoverycontrol", + "module": "aws_cdk.aws_route53recoverycontrol" + } + } + }, + "repository": { + "type": "git", + "url": "https://github.com/aws/aws-cdk.git", + "directory": "packages/@aws-cdk/aws-route53recoverycontrol" + }, + "homepage": "https://github.com/aws/aws-cdk", + "scripts": { + "build": "cdk-build", + "watch": "cdk-watch", + "lint": "cdk-lint", + "test": "cdk-test", + "integ": "cdk-integ", + "pkglint": "pkglint -f", + "package": "cdk-package", + "awslint": "cdk-awslint", + "cfn2ts": "cfn2ts", + "build+test": "yarn build && yarn test", + "build+test+package": "yarn build+test && yarn package", + "compat": "cdk-compat", + "gen": "cfn2ts", + "rosetta:extract": "yarn --silent jsii-rosetta extract", + "build+extract": "yarn build && yarn rosetta:extract", + "build+test+extract": "yarn build+test && yarn rosetta:extract" + }, + "cdk-build": { + "cloudformation": "AWS::Route53RecoveryControl", + "jest": true, + "env": { + "AWSLINT_BASE_CONSTRUCT": "true" + } + }, + "keywords": [ + "aws", + "cdk", + "constructs", + "AWS::Route53RecoveryControl", + "aws-route53recoverycontrol" + ], + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "organization": true + }, + "license": "Apache-2.0", + "devDependencies": { + "@types/jest": "^26.0.22", + "@aws-cdk/assertions": "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-batch/test/batch.test.ts b/packages/@aws-cdk/aws-route53recoverycontrol/test/route53recoverycontrol.test.ts similarity index 73% rename from packages/@aws-cdk/aws-batch/test/batch.test.ts rename to packages/@aws-cdk/aws-route53recoverycontrol/test/route53recoverycontrol.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-batch/test/batch.test.ts +++ b/packages/@aws-cdk/aws-route53recoverycontrol/test/route53recoverycontrol.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-route53recoveryreadiness/.eslintrc.js b/packages/@aws-cdk/aws-route53recoveryreadiness/.eslintrc.js new file mode 100644 index 0000000000000..61dd8dd001f63 --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoveryreadiness/.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-route53recoveryreadiness/.gitignore b/packages/@aws-cdk/aws-route53recoveryreadiness/.gitignore new file mode 100644 index 0000000000000..62ebc95d75ce6 --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoveryreadiness/.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-route53recoveryreadiness/.npmignore b/packages/@aws-cdk/aws-route53recoveryreadiness/.npmignore new file mode 100644 index 0000000000000..f931fede67c44 --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoveryreadiness/.npmignore @@ -0,0 +1,29 @@ +# Don't include original .ts files when doing `npm pack` +*.ts +!*.d.ts +coverage +.nyc_output +*.tgz + +dist +.LAST_PACKAGE +.LAST_BUILD +!*.js + +# Include .jsii +!.jsii + +*.snk + +*.tsbuildinfo + +tsconfig.json + +.eslintrc.js +jest.config.js + +# exclude cdk artifacts +**/cdk.out +junit.xml +test/ +!*.lit.ts diff --git a/packages/@aws-cdk/aws-route53recoveryreadiness/LICENSE b/packages/@aws-cdk/aws-route53recoveryreadiness/LICENSE new file mode 100644 index 0000000000000..28e4bdcec77ec --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoveryreadiness/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-route53recoveryreadiness/NOTICE b/packages/@aws-cdk/aws-route53recoveryreadiness/NOTICE new file mode 100644 index 0000000000000..5fc3826926b5b --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoveryreadiness/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-route53recoveryreadiness/README.md b/packages/@aws-cdk/aws-route53recoveryreadiness/README.md new file mode 100644 index 0000000000000..fd92f9a6d4954 --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoveryreadiness/README.md @@ -0,0 +1,20 @@ +# AWS::Route53RecoveryReadiness 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 route53recoveryreadiness = require('@aws-cdk/aws-route53recoveryreadiness'); +``` diff --git a/packages/@aws-cdk/aws-route53recoveryreadiness/jest.config.js b/packages/@aws-cdk/aws-route53recoveryreadiness/jest.config.js new file mode 100644 index 0000000000000..54e28beb9798b --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoveryreadiness/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-route53recoveryreadiness/lib/index.ts b/packages/@aws-cdk/aws-route53recoveryreadiness/lib/index.ts new file mode 100644 index 0000000000000..92d4e5587a6c6 --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoveryreadiness/lib/index.ts @@ -0,0 +1,2 @@ +// AWS::Route53RecoveryReadiness CloudFormation Resources: +export * from './route53recoveryreadiness.generated'; diff --git a/packages/@aws-cdk/aws-route53recoveryreadiness/package.json b/packages/@aws-cdk/aws-route53recoveryreadiness/package.json new file mode 100644 index 0000000000000..afa6c384f2f7b --- /dev/null +++ b/packages/@aws-cdk/aws-route53recoveryreadiness/package.json @@ -0,0 +1,103 @@ +{ + "name": "@aws-cdk/aws-route53recoveryreadiness", + "version": "0.0.0", + "description": "The CDK Construct Library for AWS::Route53RecoveryReadiness", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "jsii": { + "outdir": "dist", + "projectReferences": true, + "targets": { + "dotnet": { + "namespace": "Amazon.CDK.AWS.Route53RecoveryReadiness", + "packageId": "Amazon.CDK.AWS.Route53RecoveryReadiness", + "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.route53recoveryreadiness", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "route53recoveryreadiness" + } + }, + "python": { + "classifiers": [ + "Framework :: AWS CDK", + "Framework :: AWS CDK :: 1" + ], + "distName": "aws-cdk.aws-route53recoveryreadiness", + "module": "aws_cdk.aws_route53recoveryreadiness" + } + } + }, + "repository": { + "type": "git", + "url": "https://github.com/aws/aws-cdk.git", + "directory": "packages/@aws-cdk/aws-route53recoveryreadiness" + }, + "homepage": "https://github.com/aws/aws-cdk", + "scripts": { + "build": "cdk-build", + "watch": "cdk-watch", + "lint": "cdk-lint", + "test": "cdk-test", + "integ": "cdk-integ", + "pkglint": "pkglint -f", + "package": "cdk-package", + "awslint": "cdk-awslint", + "cfn2ts": "cfn2ts", + "build+test": "yarn build && yarn test", + "build+test+package": "yarn build+test && yarn package", + "compat": "cdk-compat", + "gen": "cfn2ts", + "rosetta:extract": "yarn --silent jsii-rosetta extract", + "build+extract": "yarn build && yarn rosetta:extract", + "build+test+extract": "yarn build+test && yarn rosetta:extract" + }, + "cdk-build": { + "cloudformation": "AWS::Route53RecoveryReadiness", + "jest": true, + "env": { + "AWSLINT_BASE_CONSTRUCT": "true" + } + }, + "keywords": [ + "aws", + "cdk", + "constructs", + "AWS::Route53RecoveryReadiness", + "aws-route53recoveryreadiness" + ], + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "organization": true + }, + "license": "Apache-2.0", + "devDependencies": { + "@types/jest": "^26.0.22", + "@aws-cdk/assertions": "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-cloud9/test/cloud9.test.ts b/packages/@aws-cdk/aws-route53recoveryreadiness/test/route53recoveryreadiness.test.ts similarity index 73% rename from packages/@aws-cdk/aws-cloud9/test/cloud9.test.ts rename to packages/@aws-cdk/aws-route53recoveryreadiness/test/route53recoveryreadiness.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-cloud9/test/cloud9.test.ts +++ b/packages/@aws-cdk/aws-route53recoveryreadiness/test/route53recoveryreadiness.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-route53resolver/package.json b/packages/@aws-cdk/aws-route53resolver/package.json index ab96545ce6345..a515fecb3c120 100644 --- a/packages/@aws-cdk/aws-route53resolver/package.json +++ b/packages/@aws-cdk/aws-route53resolver/package.json @@ -78,7 +78,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-route53resolver/test/route53resolver.test.ts b/packages/@aws-cdk/aws-route53resolver/test/route53resolver.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-route53resolver/test/route53resolver.test.ts +++ b/packages/@aws-cdk/aws-route53resolver/test/route53resolver.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-s3-deployment/NOTICE b/packages/@aws-cdk/aws-s3-deployment/NOTICE index 5fc3826926b5b..39cd25bf899ae 100644 --- a/packages/@aws-cdk/aws-s3-deployment/NOTICE +++ b/packages/@aws-cdk/aws-s3-deployment/NOTICE @@ -1,2 +1,32 @@ AWS Cloud Development Kit (AWS CDK) Copyright 2018-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + +------------------------------------------------------------------------------- + +The AWS CDK includes the following third-party software/licensing: + +** case - https://www.npmjs.com/package/case +Copyright (c) 2013 Nathan Bubna + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +---------------- diff --git a/packages/@aws-cdk/aws-s3-deployment/README.md b/packages/@aws-cdk/aws-s3-deployment/README.md index 3818a8e469cf5..a896d55cfc575 100644 --- a/packages/@aws-cdk/aws-s3-deployment/README.md +++ b/packages/@aws-cdk/aws-s3-deployment/README.md @@ -147,17 +147,22 @@ User-defined metadata are not used by S3 and keys always begin with `x-amz-meta- System defined metadata keys include the following: -- cache-control -- content-disposition -- content-encoding -- content-language -- content-type -- expires -- server-side-encryption -- storage-class -- website-redirect-location -- ssekms-key-id -- sse-customer-algorithm +- cache-control (`--cache-control` in `aws s3 sync`) +- content-disposition (`--content-disposition` in `aws s3 sync`) +- content-encoding (`--content-encoding` in `aws s3 sync`) +- content-language (`--content-language` in `aws s3 sync`) +- content-type (`--content-type` in `aws s3 sync`) +- expires (`--expires` in `aws s3 sync`) +- x-amz-storage-class (`--storage-class` in `aws s3 sync`) +- x-amz-website-redirect-location (`--website-redirect` in `aws s3 sync`) +- x-amz-server-side-encryption (`--sse` in `aws s3 sync`) +- x-amz-server-side-encryption-aws-kms-key-id (`--sse-kms-key-id` in `aws s3 sync`) +- x-amz-server-side-encryption-customer-algorithm (`--sse-c-copy-source` in `aws s3 sync`) +- x-amz-acl (`--acl` in `aws s3 sync`) + +You can find more information about system defined metadata keys in +[S3 PutObject documentation](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) +and [`aws s3 sync` documentation](https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html). ```ts const websiteBucket = new s3.Bucket(this, 'WebsiteBucket', { @@ -177,6 +182,7 @@ new s3deploy.BucketDeployment(this, 'DeployWebsite', { storageClass: StorageClass.INTELLIGENT_TIERING, serverSideEncryption: ServerSideEncryption.AES_256, cacheControl: [CacheControl.setPublic(), CacheControl.maxAge(cdk.Duration.hours(1))], + accessControl: s3.BucketAccessControl.BUCKET_OWNER_FULL_CONTROL, }); ``` @@ -230,7 +236,7 @@ size of the AWS Lambda resource handler. ## Development The custom resource is implemented in Python 3.6 in order to be able to leverage -the AWS CLI for "aws sync". The code is under [`lib/lambda`](https://github.com/aws/aws-cdk/tree/master/packages/%40aws-cdk/aws-s3-deployment/lib/lambda) and +the AWS CLI for "aws s3 sync". The code is under [`lib/lambda`](https://github.com/aws/aws-cdk/tree/master/packages/%40aws-cdk/aws-s3-deployment/lib/lambda) and unit tests are under [`test/lambda`](https://github.com/aws/aws-cdk/tree/master/packages/%40aws-cdk/aws-s3-deployment/test/lambda). This package requires Python 3.6 during build time in order to create the custom diff --git a/packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts b/packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts index ca91f036dc5ed..3a73b950792bf 100644 --- a/packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts +++ b/packages/@aws-cdk/aws-s3-deployment/lib/bucket-deployment.ts @@ -6,6 +6,7 @@ import * as lambda from '@aws-cdk/aws-lambda'; import * as s3 from '@aws-cdk/aws-s3'; import * as cdk from '@aws-cdk/core'; import { AwsCliLayer } from '@aws-cdk/lambda-layer-awscli'; +import { kebab as toKebabCase } from 'case'; import { Construct } from 'constructs'; import { ISource, SourceConfig } from './source'; @@ -164,6 +165,12 @@ export interface BucketDeploymentProps { * @see https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html#sse-c-how-to-programmatically-intro */ readonly serverSideEncryptionCustomerAlgorithm?: string; + /** + * System-defined x-amz-acl metadata to be set on all objects in the deployment. + * @default - Not set. + * @see https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#canned-acl + */ + readonly accessControl?: s3.BucketAccessControl; /** * The VPC network to place the deployment lambda handler in. @@ -282,6 +289,7 @@ function mapSystemMetadata(metadata: BucketDeploymentProps) { if (metadata.websiteRedirectLocation) { res['website-redirect'] = metadata.websiteRedirectLocation; } if (metadata.serverSideEncryptionAwsKmsKeyId) { res['sse-kms-key-id'] = metadata.serverSideEncryptionAwsKmsKeyId; } if (metadata.serverSideEncryptionCustomerAlgorithm) { res['sse-c-copy-source'] = metadata.serverSideEncryptionCustomerAlgorithm; } + if (metadata.accessControl) { res.acl = toKebabCase(metadata.accessControl.toString()); } return Object.keys(res).length === 0 ? undefined : res; } diff --git a/packages/@aws-cdk/aws-s3-deployment/package.json b/packages/@aws-cdk/aws-s3-deployment/package.json index c5ae455fc2928..f7c6225d64233 100644 --- a/packages/@aws-cdk/aws-s3-deployment/package.json +++ b/packages/@aws-cdk/aws-s3-deployment/package.json @@ -96,6 +96,7 @@ "@aws-cdk/aws-s3-assets": "0.0.0", "@aws-cdk/lambda-layer-awscli": "0.0.0", "@aws-cdk/core": "0.0.0", + "case": "1.6.3", "constructs": "^3.3.69" }, "homepage": "https://github.com/aws/aws-cdk", @@ -110,6 +111,9 @@ "@aws-cdk/core": "0.0.0", "constructs": "^3.3.69" }, + "bundledDependencies": [ + "case" + ], "engines": { "node": ">= 10.13.0 <13 || >=13.7.0" }, diff --git a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.test.ts b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.test.ts index c111629e46769..2bbe5e34a41a6 100644 --- a/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.test.ts +++ b/packages/@aws-cdk/aws-s3-deployment/test/bucket-deployment.test.ts @@ -325,6 +325,7 @@ test('system metadata is correctly transformed', () => { websiteRedirectLocation: 'example', cacheControl: [s3deploy.CacheControl.setPublic(), s3deploy.CacheControl.maxAge(cdk.Duration.hours(1))], expires: expiration, + accessControl: s3.BucketAccessControl.BUCKET_OWNER_FULL_CONTROL, }); // THEN @@ -340,10 +341,47 @@ test('system metadata is correctly transformed', () => { 'expires': expiration.date.toUTCString(), 'sse-c-copy-source': 'rot13', 'website-redirect': 'example', + 'acl': 'bucket-owner-full-control', }, }); }); +// type checking structure that forces to update it if BucketAccessControl changes +// see `--acl` here: https://docs.aws.amazon.com/cli/latest/reference/s3/sync.html +const accessControlMap: Record = { + [s3.BucketAccessControl.PRIVATE]: 'private', + [s3.BucketAccessControl.PUBLIC_READ]: 'public-read', + [s3.BucketAccessControl.PUBLIC_READ_WRITE]: 'public-read-write', + [s3.BucketAccessControl.AUTHENTICATED_READ]: 'authenticated-read', + [s3.BucketAccessControl.AWS_EXEC_READ]: 'aws-exec-read', + [s3.BucketAccessControl.BUCKET_OWNER_READ]: 'bucket-owner-read', + [s3.BucketAccessControl.BUCKET_OWNER_FULL_CONTROL]: 'bucket-owner-full-control', + [s3.BucketAccessControl.LOG_DELIVERY_WRITE]: 'log-delivery-write', +}; + +test.each(Object.entries(accessControlMap) as [s3.BucketAccessControl, string][])( + 'system metadata acl %s is correctly transformed', + (accessControl, systemMetadataKeyword) => { + // GIVEN + const stack = new cdk.Stack(); + const bucket = new s3.Bucket(stack, 'Dest'); + + // WHEN + new s3deploy.BucketDeployment(stack, 'Deploy', { + sources: [s3deploy.Source.asset(path.join(__dirname, 'my-website.zip'))], + destinationBucket: bucket, + accessControl: accessControl, + }); + + // THEN + expect(stack).toHaveResource('Custom::CDKBucketDeployment', { + SystemMetadata: { + acl: systemMetadataKeyword, + }, + }); + }, +); + test('expires type has correct values', () => { expect(cdk.Expiration.atDate(new Date('Sun, 26 Jan 2020 00:53:20 GMT')).date.toUTCString()).toEqual('Sun, 26 Jan 2020 00:53:20 GMT'); expect(cdk.Expiration.atTimestamp(1580000000000).date.toUTCString()).toEqual('Sun, 26 Jan 2020 00:53:20 GMT'); diff --git a/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.expected.json b/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.expected.json index c24d991f31ed5..9026931306ab4 100644 --- a/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.expected.json +++ b/packages/@aws-cdk/aws-s3-notifications/test/integ.notifications.expected.json @@ -256,7 +256,7 @@ "Arn" ] }, - "Runtime": "python3.8", + "Runtime": "python3.7", "Timeout": 300 }, "DependsOn": [ diff --git a/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.expected.json b/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.expected.json index 42d6d71d603bc..731effea95a53 100644 --- a/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.expected.json +++ b/packages/@aws-cdk/aws-s3-notifications/test/lambda/integ.bucket-notifications.expected.json @@ -246,7 +246,7 @@ "Arn" ] }, - "Runtime": "python3.8", + "Runtime": "python3.7", "Timeout": 300 }, "DependsOn": [ diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sns/integ.sns-bucket-notifications.expected.json b/packages/@aws-cdk/aws-s3-notifications/test/sns/integ.sns-bucket-notifications.expected.json index 74d8086ffe175..47f2a8ea6e0ce 100644 --- a/packages/@aws-cdk/aws-s3-notifications/test/sns/integ.sns-bucket-notifications.expected.json +++ b/packages/@aws-cdk/aws-s3-notifications/test/sns/integ.sns-bucket-notifications.expected.json @@ -204,7 +204,7 @@ "Arn" ] }, - "Runtime": "python3.8", + "Runtime": "python3.7", "Timeout": 300 }, "DependsOn": [ diff --git a/packages/@aws-cdk/aws-s3-notifications/test/sqs/integ.bucket-notifications.expected.json b/packages/@aws-cdk/aws-s3-notifications/test/sqs/integ.bucket-notifications.expected.json index dee0ec6922ed7..229b916beac4b 100644 --- a/packages/@aws-cdk/aws-s3-notifications/test/sqs/integ.bucket-notifications.expected.json +++ b/packages/@aws-cdk/aws-s3-notifications/test/sqs/integ.bucket-notifications.expected.json @@ -193,7 +193,7 @@ "Arn" ] }, - "Runtime": "python3.8", + "Runtime": "python3.7", "Timeout": 300 }, "DependsOn": [ diff --git a/packages/@aws-cdk/aws-s3/README.md b/packages/@aws-cdk/aws-s3/README.md index 8b60ec35eb766..3470a526ded88 100644 --- a/packages/@aws-cdk/aws-s3/README.md +++ b/packages/@aws-cdk/aws-s3/README.md @@ -211,7 +211,7 @@ The following example will subscribe an SNS topic to be notified of all `s3:Obje ```ts import * as s3n from '@aws-cdk/aws-s3-notifications'; -const myTopic = new sns.Topic(this, 'MyTopic'); +const topic = new sns.Topic(this, 'MyTopic'); bucket.addEventNotification(s3.EventType.OBJECT_CREATED, new s3n.SnsDestination(topic)); ``` diff --git a/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource-handler.ts b/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource-handler.ts index 296bebe265374..c093487a8f105 100644 --- a/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource-handler.ts +++ b/packages/@aws-cdk/aws-s3/lib/notifications-resource/notifications-resource-handler.ts @@ -87,7 +87,7 @@ export class NotificationsResourceHandler extends Construct { Code: { ZipFile: fs.readFileSync(path.join(__dirname, 'lambda/index.py'), 'utf8') }, Handler: 'index.handler', Role: this.role.roleArn, - Runtime: 'python3.8', + Runtime: 'python3.7', Timeout: 300, }, }); diff --git a/packages/@aws-cdk/aws-s3/test/notifications-resource-handler/Dockerfile b/packages/@aws-cdk/aws-s3/test/notifications-resource-handler/Dockerfile index 916f369bcd353..50dc41b3e6722 100644 --- a/packages/@aws-cdk/aws-s3/test/notifications-resource-handler/Dockerfile +++ b/packages/@aws-cdk/aws-s3/test/notifications-resource-handler/Dockerfile @@ -1,4 +1,4 @@ -FROM public.ecr.aws/lambda/python:3.8 +FROM public.ecr.aws/lambda/python:3.7 ADD . /opt/lambda WORKDIR /opt/lambda diff --git a/packages/@aws-cdk/aws-s3objectlambda/package.json b/packages/@aws-cdk/aws-s3objectlambda/package.json index 7818c261a21bc..f8e0d0986fe8a 100644 --- a/packages/@aws-cdk/aws-s3objectlambda/package.json +++ b/packages/@aws-cdk/aws-s3objectlambda/package.json @@ -81,7 +81,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-s3objectlambda/test/s3objectlambda.test.ts b/packages/@aws-cdk/aws-s3objectlambda/test/s3objectlambda.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-s3objectlambda/test/s3objectlambda.test.ts +++ b/packages/@aws-cdk/aws-s3objectlambda/test/s3objectlambda.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-s3outposts/package.json b/packages/@aws-cdk/aws-s3outposts/package.json index 4645c65189333..da5317e14e7b3 100644 --- a/packages/@aws-cdk/aws-s3outposts/package.json +++ b/packages/@aws-cdk/aws-s3outposts/package.json @@ -81,7 +81,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-s3outposts/test/s3outposts.test.ts b/packages/@aws-cdk/aws-s3outposts/test/s3outposts.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-s3outposts/test/s3outposts.test.ts +++ b/packages/@aws-cdk/aws-s3outposts/test/s3outposts.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-sagemaker/package.json b/packages/@aws-cdk/aws-sagemaker/package.json index 3f2fa9d8ab857..136d5ad52ea25 100644 --- a/packages/@aws-cdk/aws-sagemaker/package.json +++ b/packages/@aws-cdk/aws-sagemaker/package.json @@ -78,7 +78,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-sagemaker/test/sagemaker.test.ts b/packages/@aws-cdk/aws-sagemaker/test/sagemaker.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-sagemaker/test/sagemaker.test.ts +++ b/packages/@aws-cdk/aws-sagemaker/test/sagemaker.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-sam/package.json b/packages/@aws-cdk/aws-sam/package.json index 0fa097ffba069..9083b5b5d83bf 100644 --- a/packages/@aws-cdk/aws-sam/package.json +++ b/packages/@aws-cdk/aws-sam/package.json @@ -80,7 +80,7 @@ "jest": "^26.6.3", "pkglint": "0.0.0", "ts-jest": "^26.5.6", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-sam/test/api.test.ts b/packages/@aws-cdk/aws-sam/test/api.test.ts index bed8a90ae4e57..6b2fd6853ba8a 100644 --- a/packages/@aws-cdk/aws-sam/test/api.test.ts +++ b/packages/@aws-cdk/aws-sam/test/api.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as sam from '../lib'; @@ -19,7 +19,7 @@ describe('AWS::Serverless::Api', () => { }, }); - expect(stack).toHaveResourceLike('AWS::Serverless::Api', { + Template.fromStack(stack).hasResourceProperties('AWS::Serverless::Api', { StageName: 'prod', EndpointConfiguration: { Type: 'GLOBAL', @@ -36,7 +36,7 @@ describe('AWS::Serverless::Api', () => { endpointConfiguration: 'GLOBAL', }); - expect(stack).toHaveResourceLike('AWS::Serverless::Api', { + Template.fromStack(stack).hasResourceProperties('AWS::Serverless::Api', { StageName: 'prod', EndpointConfiguration: 'GLOBAL', }); diff --git a/packages/@aws-cdk/aws-sam/test/application.test.ts b/packages/@aws-cdk/aws-sam/test/application.test.ts index 748eaf75732e9..5ba6e59a186ed 100644 --- a/packages/@aws-cdk/aws-sam/test/application.test.ts +++ b/packages/@aws-cdk/aws-sam/test/application.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import { CfnApplication } from '../lib'; @@ -16,7 +16,7 @@ test('construct an AWS::Serverless::Application', () => { }, }); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ Transform: 'AWS::Serverless-2016-10-31', Resources: { App: { diff --git a/packages/@aws-cdk/aws-sam/test/function.test.ts b/packages/@aws-cdk/aws-sam/test/function.test.ts index 2633c1ea46af3..889e3366549ec 100644 --- a/packages/@aws-cdk/aws-sam/test/function.test.ts +++ b/packages/@aws-cdk/aws-sam/test/function.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as sam from '../lib'; @@ -15,7 +15,7 @@ test("correctly chooses a string array from the type unions of the 'policies' pr policies: ['AWSLambdaExecute'], }); - expect(stack).toHaveResourceLike('AWS::Serverless::Function', { + Template.fromStack(stack).hasResourceProperties('AWS::Serverless::Function', { CodeUri: { Bucket: 'my-bucket', Key: 'my-key', diff --git a/packages/@aws-cdk/aws-sdb/package.json b/packages/@aws-cdk/aws-sdb/package.json index b1773cf5a3907..9863fe0333e24 100644 --- a/packages/@aws-cdk/aws-sdb/package.json +++ b/packages/@aws-cdk/aws-sdb/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-sdb/test/sdb.test.ts b/packages/@aws-cdk/aws-sdb/test/sdb.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-sdb/test/sdb.test.ts +++ b/packages/@aws-cdk/aws-sdb/test/sdb.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-securityhub/package.json b/packages/@aws-cdk/aws-securityhub/package.json index ad2e1abf1e401..e71153d4822ad 100644 --- a/packages/@aws-cdk/aws-securityhub/package.json +++ b/packages/@aws-cdk/aws-securityhub/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-securityhub/test/securityhub.test.ts b/packages/@aws-cdk/aws-securityhub/test/securityhub.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-securityhub/test/securityhub.test.ts +++ b/packages/@aws-cdk/aws-securityhub/test/securityhub.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-servicecatalog/README.md b/packages/@aws-cdk/aws-servicecatalog/README.md index b90748a2125ad..4bb6885c601eb 100644 --- a/packages/@aws-cdk/aws-servicecatalog/README.md +++ b/packages/@aws-cdk/aws-servicecatalog/README.md @@ -35,6 +35,7 @@ enables organizations to create and manage catalogs of products for their end us - [Constraints](#constraints) - [Tag update constraint](#tag-update-constraint) - [Notify on stack events](#notify-on-stack-events) + - [CloudFormation parameters constraint](#cloudformation-parameters-constraint) - [Set launch role](#set-launch-role) - [Deploy with StackSets](#deploy-with-stacksets) @@ -162,7 +163,7 @@ A product can be added to multiple portfolios depending on your resource and org portfolio.addProduct(product); ``` -### Tag Options +## Tag Options TagOptions allow administrators to easily manage tags on provisioned products by creating a selection of tags for end users to choose from. For example, an end user can choose an `ec2` for the instance type size. @@ -228,6 +229,32 @@ portfolio.notifyOnStackEvents(product, topic2, { }); ``` +### CloudFormation parameters constraint + +CloudFormation parameters constraints allow you to configure the that are available to end users when they launch a product via defined rules. +A rule consists of one or more assertions that narrow the allowable values for parameters in a product. +You can configure multiple parameter constraints to govern the different parameters and parameter options in your products. +For example, a rule might define the various instance types that users can choose from when launching a stack that includes EC2 instances. +A parameter rule has an optional `condition` field that allows ability to configure when rules are applied. +If a `condition` is specified, all the assertions will be applied if the condition evalutates to true. +For information on rule-specific intrinsic functions to define rule conditions and assertions, +see [AWS Rule Functions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-rules.html). + +```ts fixture=portfolio-product +import * as cdk from '@aws-cdk/core'; + +portfolio.constrainCloudFormationParameters(product, { + rule: { + ruleName: 'testInstanceType', + condition: cdk.Fn.conditionEquals(cdk.Fn.ref('Environment'), 'test'), + assertions: [{ + assert: cdk.Fn.conditionContains(['t2.micro', 't2.small'], cdk.Fn.ref('InstanceType')), + description: 'For test environment, the instance type should be small', + }], + }, +}); +``` + ### Set launch role Allows you to configure a specific AWS `IAM` role that a user must assume when launching a product. diff --git a/packages/@aws-cdk/aws-servicecatalog/lib/constraints.ts b/packages/@aws-cdk/aws-servicecatalog/lib/constraints.ts index 50cb619aa0889..f3e2c32297003 100644 --- a/packages/@aws-cdk/aws-servicecatalog/lib/constraints.ts +++ b/packages/@aws-cdk/aws-servicecatalog/lib/constraints.ts @@ -1,4 +1,5 @@ import * as iam from '@aws-cdk/aws-iam'; +import * as cdk from '@aws-cdk/core'; import { MessageLanguage } from './common'; /** @@ -62,4 +63,51 @@ export interface TagUpdateConstraintOptions extends CommonConstraintOptions { * @default true */ readonly allow?: boolean; +} + +/** + * An assertion within a template rule, defined by intrinsic functions. + */ +export interface TemplateRuleAssertion { + /** + * The assertion condition. + */ + readonly assert: cdk.ICfnRuleConditionExpression; + + /** + * The description for the asssertion. + * @default - no description provided for the assertion. + */ + readonly description?: string; +} + +/** + * Defines the provisioning template constraints. + */ +export interface TemplateRule { + /** + * Name of the rule. + */ + readonly ruleName: string; + + /** + * Specify when to apply rule with a rule-specific intrinsic function. + * @default - no rule condition provided + */ + readonly condition?: cdk.ICfnRuleConditionExpression; + + /** + * A list of assertions that make up the rule. + */ + readonly assertions: TemplateRuleAssertion[]; +} + +/** + * Properties for provisoning rule constraint. + */ +export interface CloudFormationRuleConstraintOptions extends CommonConstraintOptions { + /** + * The rule with condition and assertions to apply to template. + */ + readonly rule: TemplateRule; } \ No newline at end of file diff --git a/packages/@aws-cdk/aws-servicecatalog/lib/portfolio.ts b/packages/@aws-cdk/aws-servicecatalog/lib/portfolio.ts index 73d4452ce348b..3056a48e19777 100644 --- a/packages/@aws-cdk/aws-servicecatalog/lib/portfolio.ts +++ b/packages/@aws-cdk/aws-servicecatalog/lib/portfolio.ts @@ -2,7 +2,10 @@ import * as iam from '@aws-cdk/aws-iam'; import * as sns from '@aws-cdk/aws-sns'; import * as cdk from '@aws-cdk/core'; import { MessageLanguage } from './common'; -import { CommonConstraintOptions, StackSetsConstraintOptions, TagUpdateConstraintOptions } from './constraints'; +import { + CloudFormationRuleConstraintOptions, CommonConstraintOptions, + StackSetsConstraintOptions, TagUpdateConstraintOptions, +} from './constraints'; import { AssociationManager } from './private/association-manager'; import { hashValues } from './private/util'; import { InputValidator } from './private/validation'; @@ -100,6 +103,13 @@ export interface IPortfolio extends cdk.IResource { */ notifyOnStackEvents(product: IProduct, topic: sns.ITopic, options?: CommonConstraintOptions): void; + /** + * Set provisioning rules for the product. + * @param product A service catalog product. + * @param options options for the constraint. + */ + constrainCloudFormationParameters(product:IProduct, options: CloudFormationRuleConstraintOptions): void; + /** * Force users to assume a certain role when launching a product. * @@ -136,7 +146,7 @@ abstract class PortfolioBase extends cdk.Resource implements IPortfolio { } public addProduct(product: IProduct): void { - AssociationManager.associateProductWithPortfolio(this, product); + AssociationManager.associateProductWithPortfolio(this, product, undefined); } public shareWithAccount(accountId: string, options: PortfolioShareOptions = {}): void { @@ -161,6 +171,10 @@ abstract class PortfolioBase extends cdk.Resource implements IPortfolio { AssociationManager.notifyOnStackEvents(this, product, topic, options); } + public constrainCloudFormationParameters(product: IProduct, options: CloudFormationRuleConstraintOptions): void { + AssociationManager.constrainCloudFormationParameters(this, product, options); + } + public setLaunchRole(product: IProduct, launchRole: iam.IRole, options: CommonConstraintOptions = {}): void { AssociationManager.setLaunchRole(this, product, launchRole, options); } diff --git a/packages/@aws-cdk/aws-servicecatalog/lib/private/association-manager.ts b/packages/@aws-cdk/aws-servicecatalog/lib/private/association-manager.ts index e4e8326f2bb19..bf5a68a8e70d3 100644 --- a/packages/@aws-cdk/aws-servicecatalog/lib/private/association-manager.ts +++ b/packages/@aws-cdk/aws-servicecatalog/lib/private/association-manager.ts @@ -1,11 +1,14 @@ import * as iam from '@aws-cdk/aws-iam'; import * as sns from '@aws-cdk/aws-sns'; import * as cdk from '@aws-cdk/core'; -import { CommonConstraintOptions, StackSetsConstraintOptions, TagUpdateConstraintOptions } from '../constraints'; +import { + CloudFormationRuleConstraintOptions, CommonConstraintOptions, StackSetsConstraintOptions, + TagUpdateConstraintOptions, TemplateRule, TemplateRuleAssertion, +} from '../constraints'; import { IPortfolio } from '../portfolio'; import { IProduct } from '../product'; import { - CfnLaunchNotificationConstraint, CfnLaunchRoleConstraint, CfnPortfolioProductAssociation, + CfnLaunchNotificationConstraint, CfnLaunchRoleConstraint, CfnLaunchTemplateConstraint, CfnPortfolioProductAssociation, CfnResourceUpdateConstraint, CfnStackSetConstraint, CfnTagOption, CfnTagOptionAssociation, } from '../servicecatalog.generated'; import { TagOptions } from '../tag-options'; @@ -14,8 +17,9 @@ import { InputValidator } from './validation'; export class AssociationManager { public static associateProductWithPortfolio( - portfolio: IPortfolio, product: IProduct, + portfolio: IPortfolio, product: IProduct, options: CommonConstraintOptions | undefined, ): { associationKey: string, cfnPortfolioProductAssociation: CfnPortfolioProductAssociation } { + InputValidator.validateLength(this.prettyPrintAssociation(portfolio, product), 'description', 0, 2000, options?.description); const associationKey = hashValues(portfolio.node.addr, product.node.addr, product.stack.node.addr); const constructId = `PortfolioProductAssociation${associationKey}`; const existingAssociation = portfolio.node.tryFindChild(constructId); @@ -33,8 +37,7 @@ export class AssociationManager { } public static constrainTagUpdates(portfolio: IPortfolio, product: IProduct, options: TagUpdateConstraintOptions): void { - this.validateCommonConstraintOptions(portfolio, product, options); - const association = this.associateProductWithPortfolio(portfolio, product); + const association = this.associateProductWithPortfolio(portfolio, product, options); const constructId = `ResourceUpdateConstraint${association.associationKey}`; if (!portfolio.node.tryFindChild(constructId)) { @@ -54,8 +57,7 @@ export class AssociationManager { } public static notifyOnStackEvents(portfolio: IPortfolio, product: IProduct, topic: sns.ITopic, options: CommonConstraintOptions): void { - this.validateCommonConstraintOptions(portfolio, product, options); - const association = this.associateProductWithPortfolio(portfolio, product); + const association = this.associateProductWithPortfolio(portfolio, product, options); const constructId = `LaunchNotificationConstraint${hashValues(topic.node.addr, topic.stack.node.addr, association.associationKey)}`; if (!portfolio.node.tryFindChild(constructId)) { @@ -74,9 +76,31 @@ export class AssociationManager { } } + public static constrainCloudFormationParameters( + portfolio: IPortfolio, product: IProduct, + options: CloudFormationRuleConstraintOptions, + ): void { + const association = this.associateProductWithPortfolio(portfolio, product, options); + const constructId = `LaunchTemplateConstraint${hashValues(association.associationKey, options.rule.ruleName)}`; + + if (!portfolio.node.tryFindChild(constructId)) { + const constraint = new CfnLaunchTemplateConstraint(portfolio as unknown as cdk.Resource, constructId, { + acceptLanguage: options.messageLanguage, + description: options.description, + portfolioId: portfolio.portfolioId, + productId: product.productId, + rules: this.formatTemplateRule(portfolio.stack, options.rule), + }); + + // Add dependsOn to force proper order in deployment. + constraint.addDependsOn(association.cfnPortfolioProductAssociation); + } else { + throw new Error(`Provisioning rule ${options.rule.ruleName} already configured on association ${this.prettyPrintAssociation(portfolio, product)}`); + } + } + public static setLaunchRole(portfolio: IPortfolio, product: IProduct, launchRole: iam.IRole, options: CommonConstraintOptions): void { - this.validateCommonConstraintOptions(portfolio, product, options); - const association = this.associateProductWithPortfolio(portfolio, product); + const association = this.associateProductWithPortfolio(portfolio, product, options); // Check if a stackset deployment constraint has already been configured. if (portfolio.node.tryFindChild(this.stackSetConstraintLogicalId(association.associationKey))) { throw new Error(`Cannot set launch role when a StackSet rule is already defined for association ${this.prettyPrintAssociation(portfolio, product)}`); @@ -100,8 +124,7 @@ export class AssociationManager { } public static deployWithStackSets(portfolio: IPortfolio, product: IProduct, options: StackSetsConstraintOptions) { - this.validateCommonConstraintOptions(portfolio, product, options); - const association = this.associateProductWithPortfolio(portfolio, product); + const association = this.associateProductWithPortfolio(portfolio, product, options); // Check if a launch role has already been set. if (portfolio.node.tryFindChild(this.launchRoleConstraintLogicalId(association.associationKey))) { throw new Error(`Cannot configure StackSet deployment when a launch role is already defined for association ${this.prettyPrintAssociation(portfolio, product)}`); @@ -168,7 +191,25 @@ export class AssociationManager { return `- Portfolio: ${portfolio.node.path} | Product: ${product.node.path}`; } - private static validateCommonConstraintOptions(portfolio: IPortfolio, product: IProduct, options: CommonConstraintOptions): void { - InputValidator.validateLength(this.prettyPrintAssociation(portfolio, product), 'description', 0, 2000, options.description); + private static formatTemplateRule(stack: cdk.Stack, rule: TemplateRule): string { + return JSON.stringify({ + [rule.ruleName]: { + Assertions: this.formatAssertions(stack, rule.assertions), + RuleCondition: rule.condition ? stack.resolve(rule.condition) : undefined, + }, + }); } + + private static formatAssertions( + stack: cdk.Stack, assertions : TemplateRuleAssertion[], + ): { Assert: string, AssertDescription: string | undefined }[] { + return assertions.reduce((formattedAssertions, assertion) => { + formattedAssertions.push( { + Assert: stack.resolve(assertion.assert), + AssertDescription: assertion.description, + }); + return formattedAssertions; + }, new Array<{ Assert: string, AssertDescription: string | undefined }>()); + }; } + diff --git a/packages/@aws-cdk/aws-servicecatalog/package.json b/packages/@aws-cdk/aws-servicecatalog/package.json index 442fdbe8eb5c8..bc482eedff82e 100644 --- a/packages/@aws-cdk/aws-servicecatalog/package.json +++ b/packages/@aws-cdk/aws-servicecatalog/package.json @@ -73,12 +73,12 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "cfn2ts": "0.0.0", - "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/aws-iam": "0.0.0", diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.portfolio.expected.json b/packages/@aws-cdk/aws-servicecatalog/test/integ.portfolio.expected.json index bc21e236fd3dd..5407c293f09b5 100644 --- a/packages/@aws-cdk/aws-servicecatalog/test/integ.portfolio.expected.json +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.portfolio.expected.json @@ -202,6 +202,21 @@ "TestPortfolioPortfolioProductAssociationa0185761d231B0D998A7" ] }, + "TestPortfolioLaunchTemplateConstraintfac7b49c426e599F9FFF": { + "Type": "AWS::ServiceCatalog::LaunchTemplateConstraint", + "Properties": { + "PortfolioId": { + "Ref": "TestPortfolio4AC794EB" + }, + "ProductId": { + "Ref": "TestProduct7606930B" + }, + "Rules": "{\"SubnetsinVPC\":{\"Assertions\":[{\"Assert\":{\"Fn::EachMemberIn\":[{\"Fn::ValueOfAll\":[\"AWs::EC2::Subnet::Id\",\"VpcId\"]},{\"Fn::RefAll\":\"AWS::EC2::VPC::Id\"}]},\"AssertDescription\":\"test description\"}]}}" + }, + "DependsOn": [ + "TestPortfolioPortfolioProductAssociationa0185761d231B0D998A7" + ] + }, "TagOptionc0d88a3c4b8b": { "Type": "AWS::ServiceCatalog::TagOption", "Properties": { diff --git a/packages/@aws-cdk/aws-servicecatalog/test/integ.portfolio.ts b/packages/@aws-cdk/aws-servicecatalog/test/integ.portfolio.ts index c9aa607880619..a96c11a45ba3f 100644 --- a/packages/@aws-cdk/aws-servicecatalog/test/integ.portfolio.ts +++ b/packages/@aws-cdk/aws-servicecatalog/test/integ.portfolio.ts @@ -1,10 +1,10 @@ import * as iam from '@aws-cdk/aws-iam'; import * as sns from '@aws-cdk/aws-sns'; -import { App, Stack } from '@aws-cdk/core'; +import * as cdk from '@aws-cdk/core'; import * as servicecatalog from '../lib'; -const app = new App(); -const stack = new Stack(app, 'integ-servicecatalog-portfolio'); +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'integ-servicecatalog-portfolio'); const role = new iam.Role(stack, 'TestRole', { assumedBy: new iam.AccountRootPrincipal(), @@ -79,4 +79,16 @@ secondPortfolio.deployWithStackSets(product, { allowStackSetInstanceOperations: true, }); +portfolio.constrainCloudFormationParameters(product, { + rule: { + ruleName: 'SubnetsinVPC', + assertions: [{ + assert: cdk.Fn.conditionEachMemberIn( + cdk.Fn.valueOfAll('AWs::EC2::Subnet::Id', 'VpcId'), + cdk.Fn.refAll('AWS::EC2::VPC::Id')), + description: 'test description', + }], + }, +}); + app.synth(); diff --git a/packages/@aws-cdk/aws-servicecatalog/test/portfolio.test.ts b/packages/@aws-cdk/aws-servicecatalog/test/portfolio.test.ts index 3c76619c03a1f..216c34295cab2 100644 --- a/packages/@aws-cdk/aws-servicecatalog/test/portfolio.test.ts +++ b/packages/@aws-cdk/aws-servicecatalog/test/portfolio.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; import * as sns from '@aws-cdk/aws-sns'; import * as cdk from '@aws-cdk/core'; @@ -18,7 +18,7 @@ describe('Portfolio', () => { providerName: 'testProvider', }); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ Resources: { MyPortfolio59CCA9C9: { Type: 'AWS::ServiceCatalog::Portfolio', @@ -39,7 +39,7 @@ describe('Portfolio', () => { messageLanguage: servicecatalog.MessageLanguage.ZH, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::Portfolio', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::Portfolio', { Description: 'test portfolio description', AcceptLanguage: servicecatalog.MessageLanguage.ZH, }); @@ -105,7 +105,7 @@ describe('Portfolio', () => { description: tokenDescription.valueAsString, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::Portfolio', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::Portfolio', { Description: { Ref: 'Description', }, @@ -120,7 +120,7 @@ describe('Portfolio', () => { providerName: 'testProvider', }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::Portfolio', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::Portfolio', { DisplayName: { Ref: 'DisplayName', }, @@ -135,7 +135,7 @@ describe('Portfolio', () => { providerName: tokenProviderName.valueAsString, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::Portfolio', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::Portfolio', { ProviderName: { Ref: 'ProviderName', }, @@ -157,7 +157,7 @@ describe('Portfolio', () => { cdk.Tags.of(portfolio).add('myTestKey1', 'myTestKeyValue1'); cdk.Tags.of(portfolio).add('myTestKey2', 'myTestKeyValue2'); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::Portfolio', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::Portfolio', { Tags: [ { Key: 'myTestKey1', @@ -176,7 +176,7 @@ describe('Portfolio', () => { portfolio.shareWithAccount(shareAccountId); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::PortfolioShare', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::PortfolioShare', { AccountId: shareAccountId, }); }), @@ -189,7 +189,7 @@ describe('Portfolio', () => { messageLanguage: servicecatalog.MessageLanguage.EN, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::PortfolioShare', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::PortfolioShare', { AccountId: shareAccountId, ShareTagOptions: true, AcceptLanguage: 'en', @@ -201,7 +201,7 @@ describe('Portfolio', () => { portfolio.shareWithAccount(shareAccountId, { shareTagOptions: false }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::PortfolioShare', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::PortfolioShare', { AccountId: shareAccountId, ShareTagOptions: false, }); @@ -212,7 +212,7 @@ describe('Portfolio', () => { portfolio.shareWithAccount(shareAccountId); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::PortfolioShare', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::PortfolioShare', { AccountId: shareAccountId, }); }), @@ -224,7 +224,7 @@ describe('Portfolio', () => { portfolio.giveAccessToRole(role); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::PortfolioPrincipalAssociation', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::PortfolioPrincipalAssociation', { PrincipalARN: { 'Fn::GetAtt': ['TestRole6C9272DF', 'Arn'] }, }); }), @@ -234,7 +234,7 @@ describe('Portfolio', () => { portfolio.giveAccessToUser(user); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::PortfolioPrincipalAssociation', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::PortfolioPrincipalAssociation', { PrincipalARN: { 'Fn::GetAtt': ['TestUser6A619381', 'Arn'] }, }); }), @@ -244,7 +244,7 @@ describe('Portfolio', () => { portfolio.giveAccessToGroup(group); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::PortfolioPrincipalAssociation', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::PortfolioPrincipalAssociation', { PrincipalARN: { 'Fn::GetAtt': ['TestGroupAF88660E', 'Arn'] }, }); }), @@ -288,14 +288,14 @@ describe('portfolio associations and product constraints', () => { test('basic portfolio product association', () => { portfolio.addProduct(product); - expect(stack).toHaveResource('AWS::ServiceCatalog::PortfolioProductAssociation'); + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalog::PortfolioProductAssociation', 1); }); test('portfolio product associations are idempotent', () => { portfolio.addProduct(product); portfolio.addProduct(product); // If not idempotent these calls should fail - expect(stack).toCountResources('AWS::ServiceCatalog::PortfolioProductAssociation', 1); //check anyway + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalog::PortfolioProductAssociation', 1); //check anyway }), test('add tag options to portfolio', () => { @@ -306,8 +306,8 @@ describe('portfolio associations and product constraints', () => { portfolio.associateTagOptions(tagOptions); - expect(stack).toCountResources('AWS::ServiceCatalog::TagOption', 3); //Generates a resource for each unique key-value pair - expect(stack).toHaveResource('AWS::ServiceCatalog::TagOptionAssociation'); + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalog::TagOption', 3); //Generates a resource for each unique key-value pair + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalog::TagOptionAssociation', 3); }), test('add tag options to portfolio as prop', () => { @@ -322,8 +322,8 @@ describe('portfolio associations and product constraints', () => { tagOptions: tagOptions, }); - expect(stack).toCountResources('AWS::ServiceCatalog::TagOption', 3); //Generates a resource for each unique key-value pair - expect(stack).toHaveResource('AWS::ServiceCatalog::TagOptionAssociation'); + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalog::TagOption', 3); //Generates a resource for each unique key-value pair + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalog::TagOptionAssociation', 3); }), test('adding identical tag options to portfolio is idempotent', () => { @@ -339,8 +339,8 @@ describe('portfolio associations and product constraints', () => { portfolio.associateTagOptions(tagOptions1); portfolio.associateTagOptions(tagOptions2); // If not idempotent this would fail - expect(stack).toCountResources('AWS::ServiceCatalog::TagOption', 3); //Generates a resource for each unique key-value pair - expect(stack).toHaveResource('AWS::ServiceCatalog::TagOptionAssociation'); + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalog::TagOption', 3); //Generates a resource for each unique key-value pair + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalog::TagOptionAssociation', 3); }), test('fails to add tag options with invalid minimum key length', () => { @@ -379,7 +379,7 @@ describe('portfolio associations and product constraints', () => { allow: true, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::ResourceUpdateConstraint', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::ResourceUpdateConstraint', { TagUpdateOnProvisionedProduct: 'ALLOWED', }); }); @@ -391,7 +391,7 @@ describe('portfolio associations and product constraints', () => { allow: false, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::ResourceUpdateConstraint', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::ResourceUpdateConstraint', { AcceptLanguage: servicecatalog.MessageLanguage.EN, Description: 'test constraint description', TagUpdateOnProvisionedProduct: 'NOT_ALLOWED', @@ -421,7 +421,7 @@ describe('portfolio associations and product constraints', () => { description: description, }); - expect(stack).toHaveResource('AWS::ServiceCatalog::LaunchNotificationConstraint', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::LaunchNotificationConstraint', { NotificationArns: [{ Ref: 'TopicBFC7AF6E' }], Description: description, PortfolioId: { Ref: 'MyPortfolio59CCA9C9' }, @@ -434,7 +434,7 @@ describe('portfolio associations and product constraints', () => { portfolio.notifyOnStackEvents(product, topic); - expect(stack).toCountResources('AWS::ServiceCatalog::LaunchNotificationConstraint', 1); + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalog::LaunchNotificationConstraint', 1); }), test('can add multiple notifications', () => { @@ -446,7 +446,7 @@ describe('portfolio associations and product constraints', () => { portfolio.notifyOnStackEvents(product, topic2); portfolio.notifyOnStackEvents(product, topic3); - expect(stack).toCountResources('AWS::ServiceCatalog::LaunchNotificationConstraint', 3); + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalog::LaunchNotificationConstraint', 3); }), test('fails to add same topic multiple times in event notification constraint', () => { @@ -457,7 +457,104 @@ describe('portfolio associations and product constraints', () => { expect(() => { portfolio.notifyOnStackEvents(product, topic); }).toThrowError(`Topic ${topic} is already subscribed to association`); - }); + }), + + test('creates a CloudFormation parameters constraint', () => { + portfolio.addProduct(product); + portfolio.constrainCloudFormationParameters(product, { + rule: { + ruleName: 'Rule', + assertions: [ + { + assert: cdk.Fn.conditionContains(['t2.micro', 't2.small'], cdk.Fn.ref('InstanceType')), + description: 'assert description', + }, + ], + }, + }); + + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::LaunchTemplateConstraint', { + PortfolioId: { Ref: 'MyPortfolio59CCA9C9' }, + ProductId: { Ref: 'MyProduct49A3C587' }, + Rules: JSON.stringify( { + Rule: { + Assertions: [ + { + Assert: { 'Fn::Contains': [['t2.micro', 't2.small'], { Ref: 'InstanceType' }] }, + AssertDescription: 'assert description', + }, + ], + }, + }), + }); + }), + + test('CloudFormation parameters constraint still creates without explicit association', () => { + portfolio.constrainCloudFormationParameters(product, { + rule: { + ruleName: 'Rule', + condition: cdk.Fn.conditionContains(['a', 'b'], 'text'), + assertions: [ + { + assert: cdk.Fn.conditionContains(['t2.micro', 't2.small'], cdk.Fn.ref('InstanceType')), + description: 'assert description', + }, + ], + }, + description: 'test description', + messageLanguage: servicecatalog.MessageLanguage.EN, + }); + + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalog::LaunchTemplateConstraint', 1); + }), + + test('set multiple CloudFormation parameters constraints', () => { + portfolio.constrainCloudFormationParameters(product, { + rule: { + ruleName: 'Rule01', + assertions: [{ + assert: cdk.Fn.conditionContains(['BucketOwnerRead'], cdk.Fn.ref('AccessControl')), + description: 'assert description', + }], + }, + }); + + portfolio.constrainCloudFormationParameters(product, { + rule: { + ruleName: 'Rule02', + assertions: [{ + assert: cdk.Fn.conditionContains(['BucketOwnerWrite'], cdk.Fn.ref('AccessControl')), + description: 'assert description', + }], + }, + }); + + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalog::LaunchTemplateConstraint', 2); + }), + + test('fails to set a duplicate CloudFormation parameters constraint', () => { + portfolio.constrainCloudFormationParameters(product, { + rule: { + ruleName: 'Rule01', + assertions: [{ + assert: cdk.Fn.conditionContains(['BucketOwnerRead'], cdk.Fn.ref('AccessControl')), + description: 'assert description', + }], + }, + }); + + expect(() => { + portfolio.constrainCloudFormationParameters(product, { + rule: { + ruleName: 'Rule01', + assertions: [{ + assert: cdk.Fn.conditionContains(['BucketOwnerWrite'], cdk.Fn.ref('AccessControl')), + description: 'assert description', + }], + }, + }); + }).toThrowError(/Provisioning rule Rule01 already configured on association/); + }), describe('portfolio constraints that have roles', () => { let launchRole: iam.IRole, adminRole: iam.IRole; @@ -478,7 +575,7 @@ describe('portfolio associations and product constraints', () => { messageLanguage: servicecatalog.MessageLanguage.EN, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::LaunchRoleConstraint', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::LaunchRoleConstraint', { PortfolioId: { Ref: 'MyPortfolio59CCA9C9' }, ProductId: { Ref: 'MyProduct49A3C587' }, Description: 'set launch role description', @@ -492,7 +589,7 @@ describe('portfolio associations and product constraints', () => { test('set launch role constraint still adds without explicit association', () => { portfolio.setLaunchRole(product, launchRole); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::LaunchRoleConstraint'); + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalog::LaunchRoleConstraint', 1); }), test('fails to add multiple set launch roles', () => { @@ -534,7 +631,7 @@ describe('portfolio associations and product constraints', () => { messageLanguage: servicecatalog.MessageLanguage.JP, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::StackSetConstraint', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::StackSetConstraint', { PortfolioId: { Ref: 'MyPortfolio59CCA9C9' }, ProductId: { Ref: 'MyProduct49A3C587' }, AdminRole: { @@ -561,7 +658,7 @@ describe('portfolio associations and product constraints', () => { allowStackSetInstanceOperations: true, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::StackSetConstraint'); + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalog::StackSetConstraint', 1); }), test('fails to add multiple deploy with stackset constraints', () => { diff --git a/packages/@aws-cdk/aws-servicecatalog/test/product.test.ts b/packages/@aws-cdk/aws-servicecatalog/test/product.test.ts index 7325549db63d3..57f4e50bda0c0 100644 --- a/packages/@aws-cdk/aws-servicecatalog/test/product.test.ts +++ b/packages/@aws-cdk/aws-servicecatalog/test/product.test.ts @@ -1,5 +1,5 @@ -import '@aws-cdk/assert-internal/jest'; import * as path from 'path'; +import { Match, Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as servicecatalog from '../lib'; @@ -24,7 +24,7 @@ describe('Product', () => { ], }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::CloudFormationProduct', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::CloudFormationProduct', { Name: 'testProduct', Owner: 'testOwner', ProvisioningArtifactParameters: [ @@ -50,7 +50,7 @@ describe('Product', () => { ], }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::CloudFormationProduct', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::CloudFormationProduct', { Name: 'testProduct', Owner: 'testOwner', ProvisioningArtifactParameters: [ @@ -100,16 +100,16 @@ describe('Product', () => { ], }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalog::CloudFormationProduct', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalog::CloudFormationProduct', { Name: 'testProduct', Owner: 'testOwner', - ProvisioningArtifactParameters: [ - { + ProvisioningArtifactParameters: Match.arrayWith([ + Match.objectLike({ 'Info': { 'LoadTemplateFromURL': 'https://awsdocs.s3.amazonaws.com/servicecatalog/development-environment.template', }, - }, - ], + }), + ]), }); }), diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/package.json b/packages/@aws-cdk/aws-servicecatalogappregistry/package.json index ecf6b6990c3ad..921cb1fd4de60 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/package.json +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/package.json @@ -77,7 +77,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/application.test.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/test/application.test.ts index bdd4e26af2616..2cd30da1b5eb8 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/application.test.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/application.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as appreg from '../lib'; @@ -14,7 +14,7 @@ describe('Application', () => { applicationName: 'testApplication', }); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ Resources: { MyApplication5C63EC1D: { Type: 'AWS::ServiceCatalogAppRegistry::Application', @@ -33,7 +33,7 @@ describe('Application', () => { description: description, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalogAppRegistry::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::Application', { Description: description, }); }), @@ -46,7 +46,7 @@ describe('Application', () => { cdk.Tags.of(application).add('key1', 'value1'); cdk.Tags.of(application).add('key2', 'value2'); - expect(stack).toHaveResourceLike('AWS::ServiceCatalogAppRegistry::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::Application', { Tags: { key1: 'value1', key2: 'value2', @@ -76,7 +76,7 @@ describe('Application', () => { description: tokenDescription.valueAsString, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalogAppRegistry::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::Application', { Description: { Ref: 'Description', }, @@ -90,7 +90,7 @@ describe('Application', () => { applicationName: tokenApplicationName.valueAsString, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalogAppRegistry::Application', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::Application', { Name: { Ref: 'ApplicationName', }, @@ -147,7 +147,7 @@ describe('Application', () => { application.associateAttributeGroup(attributeGroup); - expect(stack).toHaveResourceLike('AWS::ServiceCatalogAppRegistry::AttributeGroupAssociation', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::AttributeGroupAssociation', { Application: { 'Fn::GetAtt': ['MyApplication5C63EC1D', 'Id'] }, AttributeGroup: { 'Fn::GetAtt': ['AttributeGroup409C6335', 'Id'] }, }); @@ -163,7 +163,7 @@ describe('Application', () => { application.associateAttributeGroup(attributeGroup); application.associateAttributeGroup(attributeGroup); - expect(stack).toCountResources('AWS::ServiceCatalogAppRegistry::AttributeGroupAssociation', 1); + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalogAppRegistry::AttributeGroupAssociation', 1); }), test('multiple applications and attribute groups can associate', () => { @@ -187,7 +187,7 @@ describe('Application', () => { application2.associateAttributeGroup(attributeGroup1); application2.associateAttributeGroup(attributeGroup2); - expect(stack).toCountResources('AWS::ServiceCatalogAppRegistry::AttributeGroupAssociation', 4); + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalogAppRegistry::AttributeGroupAssociation', 4); }), test('associate resource', () => { @@ -195,7 +195,7 @@ describe('Application', () => { application.associateStack(resource); - expect(stack).toHaveResourceLike('AWS::ServiceCatalogAppRegistry::ResourceAssociation', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::ResourceAssociation', { Application: { 'Fn::GetAtt': ['MyApplication5C63EC1D', 'Id'] }, Resource: { 'Fn::ImportValue': 'MyStack:MyStackExportsOutputRefAWSStackId23D778D8' }, }); @@ -208,7 +208,7 @@ describe('Application', () => { application.associateStack(resource); application.associateStack(resource); - expect(stack).toCountResources('AWS::ServiceCatalogAppRegistry::ResourceAssociation', 1); + Template.fromStack(stack).resourceCountIs('AWS::ServiceCatalogAppRegistry::ResourceAssociation', 1); }); }); }); diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/attribute-group.test.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/test/attribute-group.test.ts index 35bce4b8c5e29..728ee04976623 100644 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/attribute-group.test.ts +++ b/packages/@aws-cdk/aws-servicecatalogappregistry/test/attribute-group.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import { Template } from '@aws-cdk/assertions'; import * as cdk from '@aws-cdk/core'; import * as appreg from '../lib'; @@ -17,7 +17,7 @@ describe('Attribute Group', () => { }, }); - expect(stack).toMatchTemplate({ + Template.fromStack(stack).templateMatches({ Resources: { MyAttributeGroup99099500: { Type: 'AWS::ServiceCatalogAppRegistry::AttributeGroup', @@ -42,7 +42,7 @@ describe('Attribute Group', () => { description: description, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalogAppRegistry::AttributeGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::AttributeGroup', { Description: description, }); }), @@ -58,7 +58,7 @@ describe('Attribute Group', () => { cdk.Tags.of(attributeGroup).add('key1', 'value1'); cdk.Tags.of(attributeGroup).add('key2', 'value2'); - expect(stack).toHaveResourceLike('AWS::ServiceCatalogAppRegistry::AttributeGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::AttributeGroup', { Tags: { key1: 'value1', key2: 'value2', @@ -90,7 +90,7 @@ describe('Attribute Group', () => { description: tokenDescription.valueAsString, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalogAppRegistry::AttributeGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::AttributeGroup', { Description: { Ref: 'Description', }, @@ -107,7 +107,7 @@ describe('Attribute Group', () => { }, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalogAppRegistry::AttributeGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::AttributeGroup', { Name: { Ref: 'AttributeGroupName', }, @@ -165,7 +165,7 @@ describe('Attribute Group', () => { attributes: {}, }); - expect(stack).toHaveResourceLike('AWS::ServiceCatalogAppRegistry::AttributeGroup', { + Template.fromStack(stack).hasResourceProperties('AWS::ServiceCatalogAppRegistry::AttributeGroup', { Attributes: {}, }); }); diff --git a/packages/@aws-cdk/aws-servicecatalogappregistry/test/servicecatalogappregistry.test.ts b/packages/@aws-cdk/aws-servicecatalogappregistry/test/servicecatalogappregistry.test.ts deleted file mode 100644 index c4505ad966984..0000000000000 --- a/packages/@aws-cdk/aws-servicecatalogappregistry/test/servicecatalogappregistry.test.ts +++ /dev/null @@ -1,6 +0,0 @@ -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-sns/test/sns.test.ts b/packages/@aws-cdk/aws-sns/test/sns.test.ts index b07fdce78dab0..950aef6cbcef1 100644 --- a/packages/@aws-cdk/aws-sns/test/sns.test.ts +++ b/packages/@aws-cdk/aws-sns/test/sns.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import * as notifications from '@aws-cdk/aws-codestarnotifications'; import * as iam from '@aws-cdk/aws-iam'; import * as kms from '@aws-cdk/aws-kms'; @@ -13,7 +13,7 @@ describe('Topic', () => { const stack = new cdk.Stack(); new sns.Topic(stack, 'MyTopic'); - TemplateAssertions.fromStack(stack).resourceCountIs('AWS::SNS::Topic', 1); + Template.fromStack(stack).resourceCountIs('AWS::SNS::Topic', 1); }); @@ -24,7 +24,7 @@ describe('Topic', () => { topicName: 'topicName', }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { 'TopicName': 'topicName', }); @@ -38,7 +38,7 @@ describe('Topic', () => { displayName: 'displayName', }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { 'DisplayName': 'displayName', }); @@ -53,7 +53,7 @@ describe('Topic', () => { masterKey: key, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { 'KmsMasterKeyId': { 'Fn::GetAtt': ['CustomKey1E6D0D07', 'Arn'] }, }); @@ -68,7 +68,7 @@ describe('Topic', () => { displayName: 'displayName', }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { 'DisplayName': 'displayName', 'TopicName': 'topicName', }); @@ -96,7 +96,7 @@ describe('Topic', () => { topicName: 'topicName', }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { 'FifoTopic': true, 'TopicName': 'topicName.fifo', }); @@ -112,7 +112,7 @@ describe('Topic', () => { topicName: 'topicName.fifo', }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { 'FifoTopic': true, 'TopicName': 'topicName.fifo', }); @@ -128,7 +128,7 @@ describe('Topic', () => { topicName: 'topicName', }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { 'FifoTopic': true, 'TopicName': 'topicName.fifo', }); @@ -145,7 +145,7 @@ describe('Topic', () => { topicName: 'topicName', }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Topic', { 'ContentBasedDeduplication': true, 'FifoTopic': true, 'TopicName': 'topicName.fifo', @@ -178,7 +178,7 @@ describe('Topic', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::TopicPolicy', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::TopicPolicy', { PolicyDocument: { Version: '2012-10-17', Statement: [{ @@ -204,7 +204,7 @@ describe('Topic', () => { topic.grantPublish(user); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { 'PolicyDocument': { Version: '2012-10-17', 'Statement': [ @@ -233,7 +233,7 @@ describe('Topic', () => { new sns.TopicPolicy(stack, 'topicpolicy', { topics: [topic], policyDocument: new iam.PolicyDocument({ assignSids: true, statements: [ps] }) }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::TopicPolicy', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::TopicPolicy', { 'PolicyDocument': { 'Statement': [ { @@ -270,7 +270,7 @@ describe('Topic', () => { })); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::TopicPolicy', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::TopicPolicy', { 'PolicyDocument': { 'Statement': [ { @@ -305,7 +305,7 @@ describe('Topic', () => { principals: [new iam.ArnPrincipal('arn')], })); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::TopicPolicy', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::TopicPolicy', { 'PolicyDocument': { 'Statement': [ { @@ -386,7 +386,7 @@ describe('Topic', () => { }); // THEN - TemplateAssertions.fromStack(stack).resourceCountIs('AWS::SNS::Subscription', 1); + Template.fromStack(stack).resourceCountIs('AWS::SNS::Subscription', 1); }); @@ -408,8 +408,8 @@ describe('Topic', () => { }); // THEN - TemplateAssertions.fromStack(stack).resourceCountIs('AWS::SNS::Subscription', 0); - TemplateAssertions.fromStack(stack2).resourceCountIs('AWS::SNS::Subscription', 1); + Template.fromStack(stack).resourceCountIs('AWS::SNS::Subscription', 0); + Template.fromStack(stack2).resourceCountIs('AWS::SNS::Subscription', 1); }); @@ -462,7 +462,7 @@ describe('Topic', () => { rule.addTarget(topic); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::TopicPolicy', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::TopicPolicy', { PolicyDocument: { Version: '2012-10-17', Statement: [{ diff --git a/packages/@aws-cdk/aws-sns/test/subscription.test.ts b/packages/@aws-cdk/aws-sns/test/subscription.test.ts index 7717b7f12c7d4..0c19eddc0c7d5 100644 --- a/packages/@aws-cdk/aws-sns/test/subscription.test.ts +++ b/packages/@aws-cdk/aws-sns/test/subscription.test.ts @@ -1,4 +1,4 @@ -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import { Queue } from '@aws-cdk/aws-sqs'; import * as cdk from '@aws-cdk/core'; import * as sns from '../lib'; @@ -17,7 +17,7 @@ describe('Subscription', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::Subscription', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Subscription', { Endpoint: 'endpoint', Protocol: 'lambda', TopicArn: { @@ -45,7 +45,7 @@ describe('Subscription', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::Subscription', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Subscription', { Endpoint: 'endpoint', Protocol: 'lambda', TopicArn: { @@ -60,11 +60,11 @@ describe('Subscription', () => { }, }, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SQS::Queue', { + Template.fromStack(stack).hasResourceProperties('AWS::SQS::Queue', { QueueName: 'MySubscription_DLQ', MessageRetentionPeriod: 1209600, }); - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SQS::QueuePolicy', { + Template.fromStack(stack).hasResourceProperties('AWS::SQS::QueuePolicy', { PolicyDocument: { Statement: [ { @@ -128,7 +128,7 @@ describe('Subscription', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::Subscription', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Subscription', { FilterPolicy: { color: [ 'red', @@ -168,7 +168,7 @@ describe('Subscription', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::SNS::Subscription', { + Template.fromStack(stack).hasResourceProperties('AWS::SNS::Subscription', { FilterPolicy: { size: [{ exists: true }], }, diff --git a/packages/@aws-cdk/aws-ssmcontacts/package.json b/packages/@aws-cdk/aws-ssmcontacts/package.json index fb7c8defd4291..350d243514340 100644 --- a/packages/@aws-cdk/aws-ssmcontacts/package.json +++ b/packages/@aws-cdk/aws-ssmcontacts/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-ssmcontacts/test/ssmcontacts.test.ts b/packages/@aws-cdk/aws-ssmcontacts/test/ssmcontacts.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-ssmcontacts/test/ssmcontacts.test.ts +++ b/packages/@aws-cdk/aws-ssmcontacts/test/ssmcontacts.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-ssmincidents/package.json b/packages/@aws-cdk/aws-ssmincidents/package.json index 1ef3f6cc287f7..668f68e02fd64 100644 --- a/packages/@aws-cdk/aws-ssmincidents/package.json +++ b/packages/@aws-cdk/aws-ssmincidents/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-ssmincidents/test/ssmincidents.test.ts b/packages/@aws-cdk/aws-ssmincidents/test/ssmincidents.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-ssmincidents/test/ssmincidents.test.ts +++ b/packages/@aws-cdk/aws-ssmincidents/test/ssmincidents.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-sso/package.json b/packages/@aws-cdk/aws-sso/package.json index 9eae6cfdc23a0..b6361b2336306 100644 --- a/packages/@aws-cdk/aws-sso/package.json +++ b/packages/@aws-cdk/aws-sso/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-sso/test/sso.test.ts b/packages/@aws-cdk/aws-sso/test/sso.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-sso/test/sso.test.ts +++ b/packages/@aws-cdk/aws-sso/test/sso.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md index 0ee1cbaba53f9..5bb2d7a9c4fbb 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/README.md +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/README.md @@ -1050,7 +1050,23 @@ const topic = new sns.Topic(this, 'Topic'); const task1 = new tasks.SnsPublish(this, 'Publish1', { topic, integrationPattern: sfn.IntegrationPattern.REQUEST_RESPONSE, - message: sfn.TaskInput.fromJsonPathAt('$.state.message'), + message: sfn.TaskInput.fromDataAt('$.state.message'), + messageAttributes: { + place: { + value: sfn.JsonPath.stringAt('$.place'), + }, + pic: { + // BINARY must be explicitly set + type: MessageAttributeDataType.BINARY, + value: sfn.JsonPath.stringAt('$.pic'), + }, + people: { + value: 4, + }, + handles: { + value: ['@kslater', '@jjf', null, '@mfanning'], + }, + }); // Combine a field from the execution data with diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/apigateway/call-http-api.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/apigateway/call-http-api.ts index 4624bcba049a0..876626ea05fd3 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/apigateway/call-http-api.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/apigateway/call-http-api.ts @@ -44,6 +44,7 @@ export class CallApiGatewayHttpApiEndpoint extends CallApiGatewayEndpointBase { this.apiEndpoint = this.getApiEndpoint(); this.arnForExecuteApi = this.getArnForExecuteApi(); + this.stageName = props.stageName; this.taskPolicies = this.createPolicyStatements(); } diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish.ts index 16f10051f0531..8c37c35c9b9f9 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/lib/sns/publish.ts @@ -1,9 +1,63 @@ import * as iam from '@aws-cdk/aws-iam'; import * as sns from '@aws-cdk/aws-sns'; import * as sfn from '@aws-cdk/aws-stepfunctions'; +import { Token } from '@aws-cdk/core'; import { Construct } from 'constructs'; import { integrationResourceArn, validatePatternSupported } from '../private/task-utils'; +/** + * The data type set for the SNS message attributes + * + * @see https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html#SNSMessageAttributes.DataTypes + */ +export enum MessageAttributeDataType { + /** + * Strings are Unicode with UTF-8 binary encoding + */ + STRING = 'String', + + /** + * An array, formatted as a string + * + * @see https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html#SNSMessageAttributes.DataTypes + */ + STRING_ARRAY = 'String.Array', + + /** + * Numbers are positive or negative integers or floating-point numbers + * + * @see https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html#SNSMessageAttributes.DataTypes + */ + NUMBER = 'Number', + + /** + * Binary type attributes can store any binary data + * + * @see https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html#SNSMessageAttributes.DataTypes + */ + BINARY = 'Binary' +} + +/** + * A message attribute to add to the SNS message + * + * @see https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html + */ +export interface MessageAttribute { + /** + * The value of the attribute + */ + readonly value: any; + + /** + * The data type for the attribute + * + * @see https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html#SNSMessageAttributes.DataTypes + * @default determined by type inspection if possible, fallback is String + */ + readonly dataType?: MessageAttributeDataType +} + /** * Properties for publishing a message to an SNS topic */ @@ -23,6 +77,17 @@ export interface SnsPublishProps extends sfn.TaskStateBaseProps { */ readonly message: sfn.TaskInput; + /** + * Add message attributes when publishing. + * + * These attributes carry additional metadata about the message and may be used + * for subscription filters. + * + * @see https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html + * @default {} + */ + readonly messageAttributes?: { [key: string]: MessageAttribute }; + /** * Send different messages for each transport protocol. * @@ -98,8 +163,95 @@ export class SnsPublish extends sfn.TaskStateBase { TopicArn: this.props.topic.topicArn, Message: this.props.message.value, MessageStructure: this.props.messagePerSubscriptionType ? 'json' : undefined, + MessageAttributes: renderMessageAttributes(this.props.messageAttributes), Subject: this.props.subject, }), }; } } + +interface MessageAttributeValue { + DataType: string; + StringValue?: string; + BinaryValue?: string; +} + +function renderMessageAttributes(attributes?: { [key: string]: MessageAttribute }): any { + if (attributes === undefined) { return undefined; } + const renderedAttributes: { [key: string]: MessageAttributeValue } = {}; + Object.entries(attributes).map(([key, val]) => { + renderedAttributes[key] = renderMessageAttributeValue(val); + }); + return sfn.TaskInput.fromObject(renderedAttributes).value; +} + +function renderMessageAttributeValue(attribute: MessageAttribute): MessageAttributeValue { + const dataType = attribute.dataType; + if (attribute.value instanceof sfn.TaskInput) { + return { + DataType: dataType ?? MessageAttributeDataType.STRING, + StringValue: dataType !== MessageAttributeDataType.BINARY ? attribute.value.value : undefined, + BinaryValue: dataType === MessageAttributeDataType.BINARY ? attribute.value.value : undefined, + }; + } + + if (dataType === MessageAttributeDataType.BINARY) { + return { DataType: dataType, BinaryValue: `${attribute.value}` }; + } + + if (Token.isUnresolved(attribute.value)) { + return { DataType: dataType ?? MessageAttributeDataType.STRING, StringValue: attribute.value }; + } + + validateMessageAttribute(attribute); + if (Array.isArray(attribute.value)) { + return { DataType: MessageAttributeDataType.STRING_ARRAY, StringValue: JSON.stringify(attribute.value) }; + } + const value = attribute.value; + if (typeof value === 'number') { + return { DataType: MessageAttributeDataType.NUMBER, StringValue: `${value}` }; + } else { + return { DataType: MessageAttributeDataType.STRING, StringValue: `${value}` }; + } +} + +function validateMessageAttribute(attribute: MessageAttribute): void { + const dataType = attribute.dataType; + const value = attribute.value; + if (dataType === undefined) { + return; + } + if (Array.isArray(value)) { + if (dataType !== MessageAttributeDataType.STRING_ARRAY) { + throw new Error(`Requested SNS message attribute type was ${dataType} but ${value} was of type Array`); + } + const validArrayTypes = ['string', 'boolean', 'number']; + value.forEach((v) => { + if (v !== null || !validArrayTypes.includes(typeof v)) { + throw new Error(`Requested SNS message attribute type was ${typeof value} but Array values must be one of ${validArrayTypes}`); + } + }); + return; + } + const error = new Error(`Requested SNS message attribute type was ${dataType} but ${value} was of type ${typeof value}`); + switch (typeof value) { + case 'string': + // trust the user or will default to string + if (sfn.JsonPath.isEncodedJsonPath(attribute.value)) { + return; + } + if (dataType === MessageAttributeDataType.STRING || + dataType === MessageAttributeDataType.BINARY) { + return; + } + throw error; + case 'number': + if (dataType === MessageAttributeDataType.NUMBER) { return; } + throw error; + case 'boolean': + if (dataType === MessageAttributeDataType.STRING) { return; } + throw error; + default: + throw error; + } +} diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/call-http-api.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/call-http-api.test.ts index f72272d13558e..2eb7846574e38 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/call-http-api.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/apigateway/call-http-api.test.ts @@ -146,4 +146,59 @@ describe('CallApiGatewayHttpApiEndpoint', () => { }); }).toThrow(/Unsupported service integration pattern./); }); + + test('render Stage field', () => { + // GIVEN + const stack = new cdk.Stack(); + const httpApi = new apigatewayv2.HttpApi(stack, 'HttpApi'); + + // WHEN + const task = new CallApiGatewayHttpApiEndpoint(stack, 'Call', { + apiId: httpApi.apiId, + apiStack: cdk.Stack.of(httpApi), + method: HttpMethod.GET, + stageName: 'stage', + }); + + // THEN + expect(stack.resolve(task.toStateJson())).toEqual({ + Type: 'Task', + End: true, + Parameters: { + ApiEndpoint: { + 'Fn::Join': [ + '', + [ + { + Ref: 'HttpApiF5A9A8A7', + }, + '.execute-api.', + { + Ref: 'AWS::Region', + }, + '.', + { + Ref: 'AWS::URLSuffix', + }, + ], + ], + }, + AuthType: 'NO_AUTH', + Method: 'GET', + Stage: 'stage', + }, + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:::apigateway:invoke', + ], + ], + }, + }); + }); }); diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sns/publish.test.ts b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sns/publish.test.ts index e336d4c8d8a5d..5b81034e48cc2 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/sns/publish.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/sns/publish.test.ts @@ -1,7 +1,7 @@ import * as sns from '@aws-cdk/aws-sns'; import * as sfn from '@aws-cdk/aws-stepfunctions'; import * as cdk from '@aws-cdk/core'; -import { SnsPublish } from '../../lib/sns/publish'; +import { SnsPublish, MessageAttributeDataType, MessageAttribute } from '../../lib/sns/publish'; describe('Publish', () => { @@ -38,6 +38,154 @@ describe('Publish', () => { }, }); }); + test('with message attributes', () => { + // GIVEN + const stack = new cdk.Stack(); + const topic = new sns.Topic(stack, 'Topic'); + const token = cdk.Token.asString('cakes can be resolved'); + + // WHEN + const task = new SnsPublish(stack, 'Publish', { + topic, + message: sfn.TaskInput.fromText('Publish this message'), + messageAttributes: { + cake: { + value: 'chocolate', + }, + cakeCount: { + value: 2, + }, + resolvable: { + value: token, + }, + binary: { + value: 'a2345', + dataType: MessageAttributeDataType.BINARY, + }, + binaryNumberIsString: { + value: 123456987, + dataType: MessageAttributeDataType.BINARY, + }, + taskInput: { + value: sfn.TaskInput.fromJsonPathAt('$$.StateMachine.Name'), + }, + executionId: { + value: sfn.JsonPath.stringAt('$$.Execution.Id'), + }, + vendors: { + value: ['Great Cakes', true, false, null, 3, 'Local Cakes'], + }, + }, + }); + + // THEN + expect(stack.resolve(task.toStateJson())).toEqual({ + Type: 'Task', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:::sns:publish', + ], + ], + }, + End: true, + Parameters: { + TopicArn: { Ref: 'TopicBFC7AF6E' }, + Message: 'Publish this message', + MessageAttributes: { + binary: { + DataType: 'Binary', + BinaryValue: 'a2345', + }, + binaryNumberIsString: { + DataType: 'Binary', + BinaryValue: '123456987', + }, + cake: { + DataType: 'String', + StringValue: 'chocolate', + }, + cakeCount: { + DataType: 'Number', + StringValue: '2', + }, + resolvable: { + DataType: 'String', + StringValue: 'cakes can be resolved', + }, + executionId: { + 'DataType': 'String', + 'StringValue.$': '$$.Execution.Id', + }, + taskInput: { + 'DataType': 'String', + 'StringValue.$': '$$.StateMachine.Name', + }, + vendors: { + DataType: 'String.Array', + StringValue: '["Great Cakes",true,false,null,3,"Local Cakes"]', + }, + }, + }, + }); + }); + describe('invalid message attribute configurations', () => { + // GIVEN + const attributes: MessageAttribute[] = [ + { + value: 2, + dataType: MessageAttributeDataType.STRING, + }, + { + value: 'foo', + dataType: MessageAttributeDataType.NUMBER, + }, + { + value: 'foo', + dataType: MessageAttributeDataType.STRING_ARRAY, + }, + { + value: ['foo', undefined, 2, true], + dataType: MessageAttributeDataType.STRING_ARRAY, + }, + { + value: ['foo', { bar: 2 }, 2, true], + dataType: MessageAttributeDataType.STRING_ARRAY, + }, + { + value: false, + dataType: MessageAttributeDataType.STRING_ARRAY, + }, + { + value: false, + dataType: MessageAttributeDataType.NUMBER, + }, + ]; + attributes.forEach((a) => { + test(`${JSON.stringify(a)} is not valid`, () => { + // WHEN + const stack = new cdk.Stack(); + const topic = new sns.Topic(stack, 'Topic'); + const task = new SnsPublish(stack, 'Publish', { + topic, + message: sfn.TaskInput.fromText('Publish this message'), + messageAttributes: { + test: a, + }, + }); + + // THEN + expect(() => { + stack.resolve(task.toStateJson()); + }).toThrow(/Requested SNS message attribute type was/); + }); + }); + }); test('publish SNS message and wait for task token', () => { // GIVEN @@ -188,4 +336,4 @@ describe('Publish', () => { }); }).toThrow(/Unsupported service integration pattern. Supported Patterns: REQUEST_RESPONSE,WAIT_FOR_TASK_TOKEN. Received: RUN_JOB/); }); -}); \ No newline at end of file +}); diff --git a/packages/@aws-cdk/aws-synthetics/test/canary.test.ts b/packages/@aws-cdk/aws-synthetics/test/canary.test.ts index f266e60eee06e..8a0baa8cb0c29 100644 --- a/packages/@aws-cdk/aws-synthetics/test/canary.test.ts +++ b/packages/@aws-cdk/aws-synthetics/test/canary.test.ts @@ -1,4 +1,4 @@ -import { Match, TemplateAssertions } from '@aws-cdk/assertions'; +import { Match, Template } from '@aws-cdk/assertions'; import * as iam from '@aws-cdk/aws-iam'; import * as s3 from '@aws-cdk/aws-s3'; import { Duration, Lazy, Stack } from '@aws-cdk/core'; @@ -23,7 +23,7 @@ test('Basic canary properties work', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { Name: 'mycanary', SuccessRetentionPeriod: 10, FailureRetentionPeriod: 10, @@ -47,7 +47,7 @@ test('Canary can have generated name', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { Name: 'canary', }); }); @@ -67,7 +67,7 @@ test('Name validation does not fail when using Tokens', () => { }); // THEN: no exception - TemplateAssertions.fromStack(stack).resourceCountIs('AWS::Synthetics::Canary', 1); + Template.fromStack(stack).resourceCountIs('AWS::Synthetics::Canary', 1); }); test('Throws when name is specified incorrectly', () => { @@ -123,7 +123,7 @@ test('An existing role can be specified instead of auto-created', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { ExecutionRoleArn: stack.resolve(role.roleArn), }); }); @@ -145,7 +145,7 @@ test('An existing bucket and prefix can be specified instead of auto-created', ( }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { ArtifactS3Location: stack.resolve(bucket.s3UrlForObject(prefix)), }); }); @@ -164,7 +164,7 @@ test('Runtime can be specified', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { RuntimeVersion: 'syn-1.0', }); }); @@ -188,7 +188,7 @@ test('environment variables can be specified', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { RunConfig: { EnvironmentVariables: environmentVariables, }, @@ -209,7 +209,7 @@ test('environment variables are skipped if not provided', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { RunConfig: Match.absentProperty(), }); }); @@ -228,7 +228,7 @@ test('Runtime can be customized', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { RuntimeVersion: 'fancy-future-runtime-1337.42', }); }); @@ -248,7 +248,7 @@ test('Schedule can be set with Rate', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { Schedule: Match.objectLike({ Expression: 'rate(3 minutes)' }), }); }); @@ -268,7 +268,7 @@ test('Schedule can be set to 1 minute', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { Schedule: Match.objectLike({ Expression: 'rate(1 minute)' }), }); }); @@ -288,7 +288,7 @@ test('Schedule can be set with Expression', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { Schedule: Match.objectLike({ Expression: 'rate(1 hour)' }), }); }); @@ -308,7 +308,7 @@ test('Schedule can be set to run once', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { Schedule: Match.objectLike({ Expression: 'rate(0 minutes)' }), }); }); @@ -390,7 +390,7 @@ test('can specify custom test', () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { Code: { Handler: 'index.handler', Script: ` diff --git a/packages/@aws-cdk/aws-synthetics/test/code.test.ts b/packages/@aws-cdk/aws-synthetics/test/code.test.ts index c5b4081e46a1a..95c7883b42dbf 100644 --- a/packages/@aws-cdk/aws-synthetics/test/code.test.ts +++ b/packages/@aws-cdk/aws-synthetics/test/code.test.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import { TemplateAssertions } from '@aws-cdk/assertions'; +import { Template } from '@aws-cdk/assertions'; import * as s3 from '@aws-cdk/aws-s3'; import { App, Stack } from '@aws-cdk/core'; import * as synthetics from '../lib'; @@ -53,7 +53,7 @@ describe(synthetics.Code.fromAsset, () => { }); // THEN - TemplateAssertions.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { + Template.fromStack(stack).hasResourceProperties('AWS::Synthetics::Canary', { Code: { Handler: 'canary.handler', S3Bucket: stack.resolve(directoryAsset.bind(stack, 'canary.handler').s3Location?.bucketName), diff --git a/packages/@aws-cdk/aws-timestream/package.json b/packages/@aws-cdk/aws-timestream/package.json index 7a00e4fcb5c84..82e1fb198680b 100644 --- a/packages/@aws-cdk/aws-timestream/package.json +++ b/packages/@aws-cdk/aws-timestream/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0" diff --git a/packages/@aws-cdk/aws-timestream/test/timestream.test.ts b/packages/@aws-cdk/aws-timestream/test/timestream.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-timestream/test/timestream.test.ts +++ b/packages/@aws-cdk/aws-timestream/test/timestream.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-transfer/package.json b/packages/@aws-cdk/aws-transfer/package.json index 45fc2b0164fc1..4d8e05fab19f5 100644 --- a/packages/@aws-cdk/aws-transfer/package.json +++ b/packages/@aws-cdk/aws-transfer/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-transfer/test/transfer.test.ts b/packages/@aws-cdk/aws-transfer/test/transfer.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-transfer/test/transfer.test.ts +++ b/packages/@aws-cdk/aws-transfer/test/transfer.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-waf/package.json b/packages/@aws-cdk/aws-waf/package.json index ec2e3ec379265..8c4f85f3402b7 100644 --- a/packages/@aws-cdk/aws-waf/package.json +++ b/packages/@aws-cdk/aws-waf/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-waf/test/waf.test.ts b/packages/@aws-cdk/aws-waf/test/waf.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-waf/test/waf.test.ts +++ b/packages/@aws-cdk/aws-waf/test/waf.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-wafregional/package.json b/packages/@aws-cdk/aws-wafregional/package.json index 4003f4ff7b0f0..e82afe0e25e4a 100644 --- a/packages/@aws-cdk/aws-wafregional/package.json +++ b/packages/@aws-cdk/aws-wafregional/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-wafregional/test/wafregional.test.ts b/packages/@aws-cdk/aws-wafregional/test/wafregional.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-wafregional/test/wafregional.test.ts +++ b/packages/@aws-cdk/aws-wafregional/test/wafregional.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-wafv2/package.json b/packages/@aws-cdk/aws-wafv2/package.json index f7c5ae3b14798..c46028b894625 100644 --- a/packages/@aws-cdk/aws-wafv2/package.json +++ b/packages/@aws-cdk/aws-wafv2/package.json @@ -79,7 +79,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-wafv2/test/wafv2.test.ts b/packages/@aws-cdk/aws-wafv2/test/wafv2.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-wafv2/test/wafv2.test.ts +++ b/packages/@aws-cdk/aws-wafv2/test/wafv2.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-workspaces/package.json b/packages/@aws-cdk/aws-workspaces/package.json index ab45c38ed0fbd..84f7406237f45 100644 --- a/packages/@aws-cdk/aws-workspaces/package.json +++ b/packages/@aws-cdk/aws-workspaces/package.json @@ -77,7 +77,7 @@ "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "@aws-cdk/assertions": "0.0.0" }, "dependencies": { "@aws-cdk/core": "0.0.0", diff --git a/packages/@aws-cdk/aws-workspaces/test/workspaces.test.ts b/packages/@aws-cdk/aws-workspaces/test/workspaces.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-workspaces/test/workspaces.test.ts +++ b/packages/@aws-cdk/aws-workspaces/test/workspaces.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/aws-xray/package.json b/packages/@aws-cdk/aws-xray/package.json index 1d63e8fa740b3..e5ec9ff9da5fa 100644 --- a/packages/@aws-cdk/aws-xray/package.json +++ b/packages/@aws-cdk/aws-xray/package.json @@ -78,7 +78,7 @@ "license": "Apache-2.0", "devDependencies": { "@types/jest": "^26.0.24", - "@aws-cdk/assert-internal": "0.0.0", + "@aws-cdk/assertions": "0.0.0", "cdk-build-tools": "0.0.0", "cfn2ts": "0.0.0", "pkglint": "0.0.0" diff --git a/packages/@aws-cdk/aws-xray/test/xray.test.ts b/packages/@aws-cdk/aws-xray/test/xray.test.ts index c4505ad966984..465c7bdea0693 100644 --- a/packages/@aws-cdk/aws-xray/test/xray.test.ts +++ b/packages/@aws-cdk/aws-xray/test/xray.test.ts @@ -1,4 +1,4 @@ -import '@aws-cdk/assert-internal/jest'; +import '@aws-cdk/assertions'; import {} from '../lib'; test('No tests are specified for this package', () => { diff --git a/packages/@aws-cdk/cfnspec/CHANGELOG.md b/packages/@aws-cdk/cfnspec/CHANGELOG.md index 2e7ba5e22bf56..cbadd0a7eda90 100644 --- a/packages/@aws-cdk/cfnspec/CHANGELOG.md +++ b/packages/@aws-cdk/cfnspec/CHANGELOG.md @@ -1,3 +1,98 @@ +# CloudFormation Resource Specification v39.8.0 + +## New Resource Types + +* AWS::Route53RecoveryControl::Cluster +* AWS::Route53RecoveryControl::ControlPanel +* AWS::Route53RecoveryControl::RoutingControl +* AWS::Route53RecoveryControl::SafetyRule +* AWS::Route53RecoveryReadiness::Cell +* AWS::Route53RecoveryReadiness::ReadinessCheck +* AWS::Route53RecoveryReadiness::RecoveryGroup +* AWS::Route53RecoveryReadiness::ResourceSet + +## Attribute Changes + + +## Property Changes + +* AWS::DataBrew::Job DatabaseOutputs (__added__) +* AWS::DataBrew::Job ProfileConfiguration (__added__) +* AWS::DataSync::LocationNFS MountOptions.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationNFS OnPremConfig.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationNFS Subdirectory.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationObjectStorage AccessKey.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationObjectStorage AgentArns.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationObjectStorage SecretKey.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationObjectStorage ServerPort.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationObjectStorage ServerProtocol.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationObjectStorage Subdirectory.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationSMB AgentArns.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationSMB Domain.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationSMB MountOptions.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationSMB Password.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationSMB Subdirectory.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationSMB User.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::S3Outposts::Endpoint AccessType (__added__) +* AWS::S3Outposts::Endpoint CustomerOwnedIpv4Pool (__added__) + +## Property Type Changes + +* AWS::DLM::LifecyclePolicy.CrossRegionCopyDeprecateRule (__added__) +* AWS::DLM::LifecyclePolicy.DeprecateRule (__added__) +* AWS::DataBrew::Job.ColumnSelector (__added__) +* AWS::DataBrew::Job.ColumnStatisticsConfiguration (__added__) +* AWS::DataBrew::Job.DatabaseOutput (__added__) +* AWS::DataBrew::Job.ParameterMap (__added__) +* AWS::DataBrew::Job.ProfileConfiguration (__added__) +* AWS::DataBrew::Job.StatisticOverride (__added__) +* AWS::DataBrew::Job.StatisticsConfiguration (__added__) +* AWS::FSx::FileSystem.AuditLogConfiguration (__added__) +* AWS::DLM::LifecyclePolicy.CrossRegionCopyRule DeprecateRule (__added__) +* AWS::DLM::LifecyclePolicy.Schedule DeprecateRule (__added__) +* AWS::DataSync::LocationNFS.MountOptions Version.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationNFS.OnPremConfig AgentArns.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::LocationSMB.MountOptions Version.UpdateType (__changed__) + * Old: Immutable + * New: Mutable +* AWS::DataSync::Task.Options SecurityDescriptorCopyFlags (__added__) +* AWS::FSx::FileSystem.WindowsConfiguration AuditLogConfiguration (__added__) + + # CloudFormation Resource Specification v39.7.0 ## New Resource Types diff --git a/packages/@aws-cdk/cfnspec/build-tools/create-missing-libraries.ts b/packages/@aws-cdk/cfnspec/build-tools/create-missing-libraries.ts index 8a62868591119..db1edab50e8a4 100644 --- a/packages/@aws-cdk/cfnspec/build-tools/create-missing-libraries.ts +++ b/packages/@aws-cdk/cfnspec/build-tools/create-missing-libraries.ts @@ -179,7 +179,7 @@ async function main() { license: 'Apache-2.0', devDependencies: { '@types/jest': '^26.0.22', - '@aws-cdk/assert-internal': version, + '@aws-cdk/assertions': version, 'cdk-build-tools': version, 'cfn2ts': version, 'pkglint': version, @@ -263,7 +263,7 @@ async function main() { ]); await write(`test/${lowcaseModuleName}.test.ts`, [ - "import '@aws-cdk/assert-internal/jest';", + "import '@aws-cdk/assertions';", "import {} from '../lib';", '', "test('No tests are specified for this package', () => {", diff --git a/packages/@aws-cdk/cfnspec/cfn.version b/packages/@aws-cdk/cfnspec/cfn.version index ac8cf4b235806..212ba4596ef15 100644 --- a/packages/@aws-cdk/cfnspec/cfn.version +++ b/packages/@aws-cdk/cfnspec/cfn.version @@ -1 +1 @@ -39.7.0 +39.8.0 diff --git a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json index 7ea26213ba6ce..5e6a900098e55 100644 --- a/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json +++ b/packages/@aws-cdk/cfnspec/spec-source/000_CloudFormationResourceSpecification.json @@ -15572,6 +15572,23 @@ } } }, + "AWS::DLM::LifecyclePolicy.CrossRegionCopyDeprecateRule": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-crossregioncopydeprecaterule.html", + "Properties": { + "Interval": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-crossregioncopydeprecaterule.html#cfn-dlm-lifecyclepolicy-crossregioncopydeprecaterule-interval", + "PrimitiveType": "Integer", + "Required": true, + "UpdateType": "Mutable" + }, + "IntervalUnit": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-crossregioncopydeprecaterule.html#cfn-dlm-lifecyclepolicy-crossregioncopydeprecaterule-intervalunit", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, "AWS::DLM::LifecyclePolicy.CrossRegionCopyRetainRule": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-crossregioncopyretainrule.html", "Properties": { @@ -15604,6 +15621,12 @@ "Required": false, "UpdateType": "Mutable" }, + "DeprecateRule": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-crossregioncopyrule.html#cfn-dlm-lifecyclepolicy-crossregioncopyrule-deprecaterule", + "Required": false, + "Type": "CrossRegionCopyDeprecateRule", + "UpdateType": "Mutable" + }, "Encrypted": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-crossregioncopyrule.html#cfn-dlm-lifecyclepolicy-crossregioncopyrule-encrypted", "PrimitiveType": "Boolean", @@ -15630,6 +15653,29 @@ } } }, + "AWS::DLM::LifecyclePolicy.DeprecateRule": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-deprecaterule.html", + "Properties": { + "Count": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-deprecaterule.html#cfn-dlm-lifecyclepolicy-deprecaterule-count", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "Interval": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-deprecaterule.html#cfn-dlm-lifecyclepolicy-deprecaterule-interval", + "PrimitiveType": "Integer", + "Required": false, + "UpdateType": "Mutable" + }, + "IntervalUnit": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-deprecaterule.html#cfn-dlm-lifecyclepolicy-deprecaterule-intervalunit", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, "AWS::DLM::LifecyclePolicy.EncryptionConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-encryptionconfiguration.html", "Properties": { @@ -15838,6 +15884,12 @@ "Type": "List", "UpdateType": "Mutable" }, + "DeprecateRule": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-schedule.html#cfn-dlm-lifecyclepolicy-schedule-deprecaterule", + "Required": false, + "Type": "DeprecateRule", + "UpdateType": "Mutable" + }, "FastRestoreRule": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-dlm-lifecyclepolicy-schedule.html#cfn-dlm-lifecyclepolicy-schedule-fastrestorerule", "Required": false, @@ -16633,6 +16685,41 @@ } } }, + "AWS::DataBrew::Job.ColumnSelector": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-columnselector.html", + "Properties": { + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-columnselector.html#cfn-databrew-job-columnselector-name", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Regex": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-columnselector.html#cfn-databrew-job-columnselector-regex", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::DataBrew::Job.ColumnStatisticsConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-columnstatisticsconfiguration.html", + "Properties": { + "Selectors": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-columnstatisticsconfiguration.html#cfn-databrew-job-columnstatisticsconfiguration-selectors", + "ItemType": "ColumnSelector", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "Statistics": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-columnstatisticsconfiguration.html#cfn-databrew-job-columnstatisticsconfiguration-statistics", + "Required": true, + "Type": "StatisticsConfiguration", + "UpdateType": "Mutable" + } + } + }, "AWS::DataBrew::Job.CsvOutputOptions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-csvoutputoptions.html", "Properties": { @@ -16685,6 +16772,29 @@ } } }, + "AWS::DataBrew::Job.DatabaseOutput": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-databaseoutput.html", + "Properties": { + "DatabaseOptions": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-databaseoutput.html#cfn-databrew-job-databaseoutput-databaseoptions", + "Required": true, + "Type": "DatabaseTableOutputOptions", + "UpdateType": "Mutable" + }, + "DatabaseOutputMode": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-databaseoutput.html#cfn-databrew-job-databaseoutput-databaseoutputmode", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "GlueConnectionName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-databaseoutput.html#cfn-databrew-job-databaseoutput-glueconnectionname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, "AWS::DataBrew::Job.DatabaseTableOutputOptions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-databasetableoutputoptions.html", "Properties": { @@ -16790,6 +16900,34 @@ } } }, + "AWS::DataBrew::Job.ParameterMap": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-parametermap.html" + }, + "AWS::DataBrew::Job.ProfileConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-profileconfiguration.html", + "Properties": { + "ColumnStatisticsConfigurations": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-profileconfiguration.html#cfn-databrew-job-profileconfiguration-columnstatisticsconfigurations", + "ItemType": "ColumnStatisticsConfiguration", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "DatasetStatisticsConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-profileconfiguration.html#cfn-databrew-job-profileconfiguration-datasetstatisticsconfiguration", + "Required": false, + "Type": "StatisticsConfiguration", + "UpdateType": "Mutable" + }, + "ProfileColumns": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-profileconfiguration.html#cfn-databrew-job-profileconfiguration-profilecolumns", + "ItemType": "ColumnSelector", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "AWS::DataBrew::Job.Recipe": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-recipe.html", "Properties": { @@ -16835,6 +16973,42 @@ } } }, + "AWS::DataBrew::Job.StatisticOverride": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-statisticoverride.html", + "Properties": { + "Parameters": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-statisticoverride.html#cfn-databrew-job-statisticoverride-parameters", + "Required": true, + "Type": "ParameterMap", + "UpdateType": "Mutable" + }, + "Statistic": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-statisticoverride.html#cfn-databrew-job-statisticoverride-statistic", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::DataBrew::Job.StatisticsConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-statisticsconfiguration.html", + "Properties": { + "IncludedStatistics": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-statisticsconfiguration.html#cfn-databrew-job-statisticsconfiguration-includedstatistics", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "Overrides": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-job-statisticsconfiguration.html#cfn-databrew-job-statisticsconfiguration-overrides", + "ItemType": "StatisticOverride", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "AWS::DataBrew::Project.Sample": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-databrew-project-sample.html", "Properties": { @@ -17734,7 +17908,7 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationnfs-mountoptions.html#cfn-datasync-locationnfs-mountoptions-version", "PrimitiveType": "String", "Required": false, - "UpdateType": "Immutable" + "UpdateType": "Mutable" } } }, @@ -17746,7 +17920,7 @@ "PrimitiveItemType": "String", "Required": true, "Type": "List", - "UpdateType": "Immutable" + "UpdateType": "Mutable" } } }, @@ -17768,7 +17942,7 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-locationsmb-mountoptions.html#cfn-datasync-locationsmb-mountoptions-version", "PrimitiveType": "String", "Required": false, - "UpdateType": "Immutable" + "UpdateType": "Mutable" } } }, @@ -17846,6 +18020,12 @@ "Required": false, "UpdateType": "Mutable" }, + "SecurityDescriptorCopyFlags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-task-options.html#cfn-datasync-task-options-securitydescriptorcopyflags", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, "TaskQueueing": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-datasync-task-options.html#cfn-datasync-task-options-taskqueueing", "PrimitiveType": "String", @@ -27165,6 +27345,29 @@ } } }, + "AWS::FSx::FileSystem.AuditLogConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-filesystem-windowsconfiguration-auditlogconfiguration.html", + "Properties": { + "AuditLogDestination": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-filesystem-windowsconfiguration-auditlogconfiguration.html#cfn-fsx-filesystem-windowsconfiguration-auditlogconfiguration-auditlogdestination", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "FileAccessAuditLogLevel": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-filesystem-windowsconfiguration-auditlogconfiguration.html#cfn-fsx-filesystem-windowsconfiguration-auditlogconfiguration-fileaccessauditloglevel", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "FileShareAccessAuditLogLevel": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-filesystem-windowsconfiguration-auditlogconfiguration.html#cfn-fsx-filesystem-windowsconfiguration-auditlogconfiguration-fileshareaccessauditloglevel", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, "AWS::FSx::FileSystem.LustreConfiguration": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-filesystem-lustreconfiguration.html", "Properties": { @@ -27300,6 +27503,12 @@ "Type": "List", "UpdateType": "Mutable" }, + "AuditLogConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-filesystem-windowsconfiguration.html#cfn-fsx-filesystem-windowsconfiguration-auditlogconfiguration", + "Required": false, + "Type": "AuditLogConfiguration", + "UpdateType": "Mutable" + }, "AutomaticBackupRetentionDays": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-fsx-filesystem-windowsconfiguration.html#cfn-fsx-filesystem-windowsconfiguration-automaticbackupretentiondays", "PrimitiveType": "Integer", @@ -52866,6 +53075,199 @@ } } }, + "AWS::Route53RecoveryControl::Cluster.ClusterEndpoint": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-cluster-clusterendpoint.html", + "Properties": { + "Endpoint": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-cluster-clusterendpoint.html#cfn-route53recoverycontrol-cluster-clusterendpoint-endpoint", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Region": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-cluster-clusterendpoint.html#cfn-route53recoverycontrol-cluster-clusterendpoint-region", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Route53RecoveryControl::SafetyRule.AssertionRule": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-safetyrule-assertionrule.html", + "Properties": { + "AssertedControls": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-safetyrule-assertionrule.html#cfn-route53recoverycontrol-safetyrule-assertionrule-assertedcontrols", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "WaitPeriodMs": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-safetyrule-assertionrule.html#cfn-route53recoverycontrol-safetyrule-assertionrule-waitperiodms", + "PrimitiveType": "Integer", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::Route53RecoveryControl::SafetyRule.GatingRule": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-safetyrule-gatingrule.html", + "Properties": { + "GatingControls": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-safetyrule-gatingrule.html#cfn-route53recoverycontrol-safetyrule-gatingrule-gatingcontrols", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "TargetControls": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-safetyrule-gatingrule.html#cfn-route53recoverycontrol-safetyrule-gatingrule-targetcontrols", + "PrimitiveItemType": "String", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "WaitPeriodMs": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-safetyrule-gatingrule.html#cfn-route53recoverycontrol-safetyrule-gatingrule-waitperiodms", + "PrimitiveType": "Integer", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::Route53RecoveryControl::SafetyRule.RuleConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-safetyrule-ruleconfig.html", + "Properties": { + "Inverted": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-safetyrule-ruleconfig.html#cfn-route53recoverycontrol-safetyrule-ruleconfig-inverted", + "PrimitiveType": "Boolean", + "Required": true, + "UpdateType": "Immutable" + }, + "Threshold": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-safetyrule-ruleconfig.html#cfn-route53recoverycontrol-safetyrule-ruleconfig-threshold", + "PrimitiveType": "Integer", + "Required": true, + "UpdateType": "Immutable" + }, + "Type": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoverycontrol-safetyrule-ruleconfig.html#cfn-route53recoverycontrol-safetyrule-ruleconfig-type", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + } + } + }, + "AWS::Route53RecoveryReadiness::ResourceSet.DNSTargetResource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-dnstargetresource.html", + "Properties": { + "DomainName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-dnstargetresource.html#cfn-route53recoveryreadiness-resourceset-dnstargetresource-domainname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "HostedZoneArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-dnstargetresource.html#cfn-route53recoveryreadiness-resourceset-dnstargetresource-hostedzonearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "RecordSetId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-dnstargetresource.html#cfn-route53recoveryreadiness-resourceset-dnstargetresource-recordsetid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "RecordType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-dnstargetresource.html#cfn-route53recoveryreadiness-resourceset-dnstargetresource-recordtype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "TargetResource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-dnstargetresource.html#cfn-route53recoveryreadiness-resourceset-dnstargetresource-targetresource", + "Required": false, + "Type": "TargetResource", + "UpdateType": "Mutable" + } + } + }, + "AWS::Route53RecoveryReadiness::ResourceSet.NLBResource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-nlbresource.html", + "Properties": { + "Arn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-nlbresource.html#cfn-route53recoveryreadiness-resourceset-nlbresource-arn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Route53RecoveryReadiness::ResourceSet.R53ResourceRecord": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-r53resourcerecord.html", + "Properties": { + "DomainName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-r53resourcerecord.html#cfn-route53recoveryreadiness-resourceset-r53resourcerecord-domainname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "RecordSetId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-r53resourcerecord.html#cfn-route53recoveryreadiness-resourceset-r53resourcerecord-recordsetid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Route53RecoveryReadiness::ResourceSet.Resource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-resource.html", + "Properties": { + "ComponentId": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-resource.html#cfn-route53recoveryreadiness-resourceset-resource-componentid", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "DnsTargetResource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-resource.html#cfn-route53recoveryreadiness-resourceset-resource-dnstargetresource", + "Required": false, + "Type": "DNSTargetResource", + "UpdateType": "Mutable" + }, + "ReadinessScopes": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-resource.html#cfn-route53recoveryreadiness-resourceset-resource-readinessscopes", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "ResourceArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-resource.html#cfn-route53recoveryreadiness-resourceset-resource-resourcearn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + } + } + }, + "AWS::Route53RecoveryReadiness::ResourceSet.TargetResource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-targetresource.html", + "Properties": { + "NLBResource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-targetresource.html#cfn-route53recoveryreadiness-resourceset-targetresource-nlbresource", + "Required": false, + "Type": "NLBResource", + "UpdateType": "Mutable" + }, + "R53Resource": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53recoveryreadiness-resourceset-targetresource.html#cfn-route53recoveryreadiness-resourceset-targetresource-r53resource", + "Required": false, + "Type": "R53ResourceRecord", + "UpdateType": "Mutable" + } + } + }, "AWS::Route53Resolver::FirewallRuleGroup.FirewallRule": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53resolver-firewallrulegroup-firewallrule.html", "Properties": { @@ -61123,7 +61525,7 @@ } } }, - "ResourceSpecificationVersion": "39.7.0", + "ResourceSpecificationVersion": "39.8.0", "ResourceTypes": { "AWS::ACMPCA::Certificate": { "Attributes": { @@ -70946,6 +71348,13 @@ "Type": "List", "UpdateType": "Mutable" }, + "DatabaseOutputs": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-databrew-job.html#cfn-databrew-job-databaseoutputs", + "ItemType": "DatabaseOutput", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, "DatasetName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-databrew-job.html#cfn-databrew-job-datasetname", "PrimitiveType": "String", @@ -71007,6 +71416,12 @@ "Type": "List", "UpdateType": "Mutable" }, + "ProfileConfiguration": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-databrew-job.html#cfn-databrew-job-profileconfiguration", + "Required": false, + "Type": "ProfileConfiguration", + "UpdateType": "Mutable" + }, "ProjectName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-databrew-job.html#cfn-databrew-job-projectname", "PrimitiveType": "String", @@ -71376,13 +71791,13 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationnfs.html#cfn-datasync-locationnfs-mountoptions", "Required": false, "Type": "MountOptions", - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "OnPremConfig": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationnfs.html#cfn-datasync-locationnfs-onpremconfig", "Required": true, "Type": "OnPremConfig", - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "ServerHostname": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationnfs.html#cfn-datasync-locationnfs-serverhostname", @@ -71394,7 +71809,7 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationnfs.html#cfn-datasync-locationnfs-subdirectory", "PrimitiveType": "String", "Required": true, - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationnfs.html#cfn-datasync-locationnfs-tags", @@ -71421,14 +71836,14 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationobjectstorage.html#cfn-datasync-locationobjectstorage-accesskey", "PrimitiveType": "String", "Required": false, - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "AgentArns": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationobjectstorage.html#cfn-datasync-locationobjectstorage-agentarns", "PrimitiveItemType": "String", "Required": true, "Type": "List", - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "BucketName": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationobjectstorage.html#cfn-datasync-locationobjectstorage-bucketname", @@ -71440,7 +71855,7 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationobjectstorage.html#cfn-datasync-locationobjectstorage-secretkey", "PrimitiveType": "String", "Required": false, - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "ServerHostname": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationobjectstorage.html#cfn-datasync-locationobjectstorage-serverhostname", @@ -71452,19 +71867,19 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationobjectstorage.html#cfn-datasync-locationobjectstorage-serverport", "PrimitiveType": "Integer", "Required": false, - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "ServerProtocol": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationobjectstorage.html#cfn-datasync-locationobjectstorage-serverprotocol", "PrimitiveType": "String", "Required": false, - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "Subdirectory": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationobjectstorage.html#cfn-datasync-locationobjectstorage-subdirectory", "PrimitiveType": "String", "Required": false, - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationobjectstorage.html#cfn-datasync-locationobjectstorage-tags", @@ -71537,25 +71952,25 @@ "PrimitiveItemType": "String", "Required": true, "Type": "List", - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "Domain": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationsmb.html#cfn-datasync-locationsmb-domain", "PrimitiveType": "String", "Required": false, - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "MountOptions": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationsmb.html#cfn-datasync-locationsmb-mountoptions", "Required": false, "Type": "MountOptions", - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "Password": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationsmb.html#cfn-datasync-locationsmb-password", "PrimitiveType": "String", "Required": true, - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "ServerHostname": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationsmb.html#cfn-datasync-locationsmb-serverhostname", @@ -71567,7 +71982,7 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationsmb.html#cfn-datasync-locationsmb-subdirectory", "PrimitiveType": "String", "Required": true, - "UpdateType": "Immutable" + "UpdateType": "Mutable" }, "Tags": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationsmb.html#cfn-datasync-locationsmb-tags", @@ -71581,7 +71996,7 @@ "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-datasync-locationsmb.html#cfn-datasync-locationsmb-user", "PrimitiveType": "String", "Required": true, - "UpdateType": "Immutable" + "UpdateType": "Mutable" } } }, @@ -93167,6 +93582,263 @@ } } }, + "AWS::Route53RecoveryControl::Cluster": { + "Attributes": { + "ClusterArn": { + "PrimitiveType": "String" + }, + "ClusterEndpoints": { + "ItemType": "ClusterEndpoint", + "Type": "List" + }, + "Status": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-cluster.html", + "Properties": { + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-cluster.html#cfn-route53recoverycontrol-cluster-name", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + } + } + }, + "AWS::Route53RecoveryControl::ControlPanel": { + "Attributes": { + "ControlPanelArn": { + "PrimitiveType": "String" + }, + "DefaultControlPanel": { + "PrimitiveType": "Boolean" + }, + "RoutingControlCount": { + "PrimitiveType": "Integer" + }, + "Status": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-controlpanel.html", + "Properties": { + "ClusterArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-controlpanel.html#cfn-route53recoverycontrol-controlpanel-clusterarn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-controlpanel.html#cfn-route53recoverycontrol-controlpanel-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::Route53RecoveryControl::RoutingControl": { + "Attributes": { + "RoutingControlArn": { + "PrimitiveType": "String" + }, + "Status": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-routingcontrol.html", + "Properties": { + "ClusterArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-routingcontrol.html#cfn-route53recoverycontrol-routingcontrol-clusterarn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "ControlPanelArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-routingcontrol.html#cfn-route53recoverycontrol-routingcontrol-controlpanelarn", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-routingcontrol.html#cfn-route53recoverycontrol-routingcontrol-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + } + } + }, + "AWS::Route53RecoveryControl::SafetyRule": { + "Attributes": { + "SafetyRuleArn": { + "PrimitiveType": "String" + }, + "Status": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-safetyrule.html", + "Properties": { + "AssertionRule": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-safetyrule.html#cfn-route53recoverycontrol-safetyrule-assertionrule", + "Required": false, + "Type": "AssertionRule", + "UpdateType": "Mutable" + }, + "ControlPanelArn": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-safetyrule.html#cfn-route53recoverycontrol-safetyrule-controlpanelarn", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "GatingRule": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-safetyrule.html#cfn-route53recoverycontrol-safetyrule-gatingrule", + "Required": false, + "Type": "GatingRule", + "UpdateType": "Mutable" + }, + "Name": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-safetyrule.html#cfn-route53recoverycontrol-safetyrule-name", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Mutable" + }, + "RuleConfig": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoverycontrol-safetyrule.html#cfn-route53recoverycontrol-safetyrule-ruleconfig", + "Required": true, + "Type": "RuleConfig", + "UpdateType": "Immutable" + } + } + }, + "AWS::Route53RecoveryReadiness::Cell": { + "Attributes": { + "CellArn": { + "PrimitiveType": "String" + }, + "ParentReadinessScopes": { + "PrimitiveItemType": "String", + "Type": "List" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-cell.html", + "Properties": { + "CellName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-cell.html#cfn-route53recoveryreadiness-cell-cellname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Cells": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-cell.html#cfn-route53recoveryreadiness-cell-cells", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-cell.html#cfn-route53recoveryreadiness-cell-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::Route53RecoveryReadiness::ReadinessCheck": { + "Attributes": { + "ReadinessCheckArn": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-readinesscheck.html", + "Properties": { + "ReadinessCheckName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-readinesscheck.html#cfn-route53recoveryreadiness-readinesscheck-readinesscheckname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "ResourceSetName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-readinesscheck.html#cfn-route53recoveryreadiness-readinesscheck-resourcesetname", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-readinesscheck.html#cfn-route53recoveryreadiness-readinesscheck-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::Route53RecoveryReadiness::RecoveryGroup": { + "Attributes": { + "RecoveryGroupArn": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-recoverygroup.html", + "Properties": { + "Cells": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-recoverygroup.html#cfn-route53recoveryreadiness-recoverygroup-cells", + "PrimitiveItemType": "String", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + }, + "RecoveryGroupName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-recoverygroup.html#cfn-route53recoveryreadiness-recoverygroup-recoverygroupname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-recoverygroup.html#cfn-route53recoveryreadiness-recoverygroup-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, + "AWS::Route53RecoveryReadiness::ResourceSet": { + "Attributes": { + "ResourceSetArn": { + "PrimitiveType": "String" + } + }, + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-resourceset.html", + "Properties": { + "ResourceSetName": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-resourceset.html#cfn-route53recoveryreadiness-resourceset-resourcesetname", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "ResourceSetType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-resourceset.html#cfn-route53recoveryreadiness-resourceset-resourcesettype", + "PrimitiveType": "String", + "Required": true, + "UpdateType": "Immutable" + }, + "Resources": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-resourceset.html#cfn-route53recoveryreadiness-resourceset-resources", + "ItemType": "Resource", + "Required": true, + "Type": "List", + "UpdateType": "Mutable" + }, + "Tags": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53recoveryreadiness-resourceset.html#cfn-route53recoveryreadiness-resourceset-tags", + "ItemType": "Tag", + "Required": false, + "Type": "List", + "UpdateType": "Mutable" + } + } + }, "AWS::Route53Resolver::FirewallDomainList": { "Attributes": { "Arn": { @@ -94007,6 +94679,18 @@ }, "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3outposts-endpoint.html", "Properties": { + "AccessType": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3outposts-endpoint.html#cfn-s3outposts-endpoint-accesstype", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, + "CustomerOwnedIpv4Pool": { + "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3outposts-endpoint.html#cfn-s3outposts-endpoint-customerownedipv4pool", + "PrimitiveType": "String", + "Required": false, + "UpdateType": "Immutable" + }, "OutpostId": { "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3outposts-endpoint.html#cfn-s3outposts-endpoint-outpostid", "PrimitiveType": "String", diff --git a/packages/@aws-cdk/cloudformation-include/package.json b/packages/@aws-cdk/cloudformation-include/package.json index f8c09b12fc8ea..71fcc718b4e3d 100644 --- a/packages/@aws-cdk/cloudformation-include/package.json +++ b/packages/@aws-cdk/cloudformation-include/package.json @@ -201,6 +201,8 @@ "@aws-cdk/aws-resourcegroups": "0.0.0", "@aws-cdk/aws-robomaker": "0.0.0", "@aws-cdk/aws-route53": "0.0.0", + "@aws-cdk/aws-route53recoverycontrol": "0.0.0", + "@aws-cdk/aws-route53recoveryreadiness": "0.0.0", "@aws-cdk/aws-route53resolver": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/aws-s3objectlambda": "0.0.0", @@ -369,6 +371,8 @@ "@aws-cdk/aws-resourcegroups": "0.0.0", "@aws-cdk/aws-robomaker": "0.0.0", "@aws-cdk/aws-route53": "0.0.0", + "@aws-cdk/aws-route53recoverycontrol": "0.0.0", + "@aws-cdk/aws-route53recoveryreadiness": "0.0.0", "@aws-cdk/aws-route53resolver": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/aws-s3objectlambda": "0.0.0", diff --git a/packages/@aws-cdk/core/lib/cfn-condition.ts b/packages/@aws-cdk/core/lib/cfn-condition.ts index db3fe5915e512..51a1e071de6a3 100644 --- a/packages/@aws-cdk/core/lib/cfn-condition.ts +++ b/packages/@aws-cdk/core/lib/cfn-condition.ts @@ -86,4 +86,16 @@ export class CfnCondition extends CfnElement implements ICfnConditionExpression, * }); * ``` */ -export interface ICfnConditionExpression extends IResolvable { } +export interface ICfnConditionExpression extends IResolvable {} + +/** + * Interface to specify certain functions as Service Catalog rule-specifc. + * These functions can only be used in ``Rules`` section of template. + */ +export interface ICfnRuleConditionExpression extends ICfnConditionExpression { + /** + * This field is only needed to defeat TypeScript's structural typing. + * It is never used. + */ + readonly disambiguator: boolean; +} diff --git a/packages/@aws-cdk/core/lib/cfn-fn.ts b/packages/@aws-cdk/core/lib/cfn-fn.ts index d8a871ca478e1..3ef1c265654bd 100644 --- a/packages/@aws-cdk/core/lib/cfn-fn.ts +++ b/packages/@aws-cdk/core/lib/cfn-fn.ts @@ -1,4 +1,4 @@ -import { ICfnConditionExpression } from './cfn-condition'; +import { ICfnConditionExpression, ICfnRuleConditionExpression } from './cfn-condition'; import { minimalCloudFormationJoin } from './private/cloudformation-lang'; import { Intrinsic } from './private/intrinsic'; import { Reference } from './reference'; @@ -267,12 +267,12 @@ export class Fn { * @param conditions conditions to AND * @returns an FnCondition token */ - public static conditionAnd(...conditions: ICfnConditionExpression[]): ICfnConditionExpression { + public static conditionAnd(...conditions: ICfnConditionExpression[]): ICfnRuleConditionExpression { if (conditions.length === 0) { throw new Error('Fn.conditionAnd() needs at least one argument'); } if (conditions.length === 1) { - return conditions[0]; + return conditions[0] as ICfnRuleConditionExpression; } return Fn.conditionAnd(..._inGroupsOf(conditions, 10).map(group => new FnAnd(...group))); } @@ -284,7 +284,7 @@ export class Fn { * @param rhs A value of any type that you want to compare. * @returns an FnCondition token */ - public static conditionEquals(lhs: any, rhs: any): ICfnConditionExpression { + public static conditionEquals(lhs: any, rhs: any): ICfnRuleConditionExpression { return new FnEquals(lhs, rhs); } @@ -303,7 +303,7 @@ export class Fn { * evaluates to false. * @returns an FnCondition token */ - public static conditionIf(conditionId: string, valueIfTrue: any, valueIfFalse: any): ICfnConditionExpression { + public static conditionIf(conditionId: string, valueIfTrue: any, valueIfFalse: any): ICfnRuleConditionExpression { return new FnIf(conditionId, valueIfTrue, valueIfFalse); } @@ -314,7 +314,7 @@ export class Fn { * or false. * @returns an FnCondition token */ - public static conditionNot(condition: ICfnConditionExpression): ICfnConditionExpression { + public static conditionNot(condition: ICfnConditionExpression): ICfnRuleConditionExpression { return new FnNot(condition); } @@ -326,12 +326,12 @@ export class Fn { * @param conditions conditions that evaluates to true or false. * @returns an FnCondition token */ - public static conditionOr(...conditions: ICfnConditionExpression[]): ICfnConditionExpression { + public static conditionOr(...conditions: ICfnConditionExpression[]): ICfnRuleConditionExpression { if (conditions.length === 0) { throw new Error('Fn.conditionOr() needs at least one argument'); } if (conditions.length === 1) { - return conditions[0]; + return conditions[0] as ICfnRuleConditionExpression; } return Fn.conditionOr(..._inGroupsOf(conditions, 10).map(group => new FnOr(...group))); } @@ -343,7 +343,7 @@ export class Fn { * @param value A string, such as "A", that you want to compare against a list of strings. * @returns an FnCondition token */ - public static conditionContains(listOfStrings: string[], value: string): ICfnConditionExpression { + public static conditionContains(listOfStrings: string[], value: string): ICfnRuleConditionExpression { return new FnContains(listOfStrings, value); } @@ -354,7 +354,7 @@ export class Fn { * of strings. * @returns an FnCondition token */ - public static conditionEachMemberEquals(listOfStrings: string[], value: string): ICfnConditionExpression { + public static conditionEachMemberEquals(listOfStrings: string[], value: string): ICfnRuleConditionExpression { return new FnEachMemberEquals(listOfStrings, value); } @@ -369,7 +369,7 @@ export class Fn { * strings_to_check parameter. * @returns an FnCondition token */ - public static conditionEachMemberIn(stringsToCheck: string[], stringsToMatch: string[]): ICfnConditionExpression { + public static conditionEachMemberIn(stringsToCheck: string[], stringsToMatch: string[]): ICfnRuleConditionExpression { return new FnEachMemberIn(stringsToCheck, stringsToMatch); } @@ -604,7 +604,8 @@ class FnCidr extends FnBase { } } -class FnConditionBase extends Intrinsic implements ICfnConditionExpression { +class FnConditionBase extends Intrinsic implements ICfnRuleConditionExpression { + readonly disambiguator = true; constructor(type: string, value: any) { super({ [type]: value }); } diff --git a/packages/@aws-cdk/cx-api/lib/features.ts b/packages/@aws-cdk/cx-api/lib/features.ts index 92cce54f2325c..554c41929651d 100644 --- a/packages/@aws-cdk/cx-api/lib/features.ts +++ b/packages/@aws-cdk/cx-api/lib/features.ts @@ -153,6 +153,13 @@ export const EFS_DEFAULT_ENCRYPTION_AT_REST = '@aws-cdk/aws-efs:defaultEncryptio */ export const LAMBDA_RECOGNIZE_VERSION_PROPS = '@aws-cdk/aws-lambda:recognizeVersionProps'; +/** + * Enable this feature flag to have cloudfront distributions use the security policy TLSv1.2_2021 by default. + * + * The security policy can also be configured explicitly using the `minimumProtocolVersion` property. + */ +export const CLOUDFRONT_DEFAULT_SECURITY_POLICY_TLS_V1_2_2021 = '@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021'; + /** * This map includes context keys and values for feature flags that enable * capabilities "from the future", which we could not introduce as the default @@ -179,6 +186,7 @@ export const FUTURE_FLAGS: { [key: string]: any } = { [RDS_LOWERCASE_DB_IDENTIFIER]: true, [EFS_DEFAULT_ENCRYPTION_AT_REST]: true, [LAMBDA_RECOGNIZE_VERSION_PROPS]: true, + [CLOUDFRONT_DEFAULT_SECURITY_POLICY_TLS_V1_2_2021]: true, // We will advertise this flag when the feature is complete // [NEW_STYLE_STACK_SYNTHESIS_CONTEXT]: 'true', @@ -209,6 +217,7 @@ const FUTURE_FLAGS_DEFAULTS: { [key: string]: boolean } = { [RDS_LOWERCASE_DB_IDENTIFIER]: false, [EFS_DEFAULT_ENCRYPTION_AT_REST]: false, [LAMBDA_RECOGNIZE_VERSION_PROPS]: false, + [CLOUDFRONT_DEFAULT_SECURITY_POLICY_TLS_V1_2_2021]: false, }; export function futureFlagDefault(flag: string): boolean { diff --git a/packages/@aws-cdk/example-construct-library/package.json b/packages/@aws-cdk/example-construct-library/package.json index 9eb248eba276e..7f66f7c22ee55 100644 --- a/packages/@aws-cdk/example-construct-library/package.json +++ b/packages/@aws-cdk/example-construct-library/package.json @@ -66,12 +66,12 @@ }, "license": "Apache-2.0", "devDependencies": { + "@aws-cdk/assertions": "0.0.0", "@types/jest": "^26.0.24", "cdk-build-tools": "0.0.0", "cdk-integ-tools": "0.0.0", "jest": "^26.6.3", - "pkglint": "0.0.0", - "@aws-cdk/assert-internal": "0.0.0" + "pkglint": "0.0.0" }, "dependencies": { "@aws-cdk/aws-cloudwatch": "0.0.0", diff --git a/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts b/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts index 8145feddb307d..091c0c7d1f65a 100644 --- a/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts +++ b/packages/@aws-cdk/example-construct-library/test/example-resource.test.ts @@ -4,10 +4,7 @@ * but it's considered Names, and we want to migrate to Jest). */ -// import the various CDK assertion helpers -import { ABSENT, ResourcePart } from '@aws-cdk/assert-internal'; -// always import our Jest-specific helpers -import '@aws-cdk/assert-internal/jest'; +import { Match, Template } from '@aws-cdk/assertions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; @@ -40,13 +37,13 @@ describe('Example Resource', () => { test('creates a CFN WaitConditionHandle resource', () => { // you can simply assert that a resource of a given type // was generated in the resulting template - expect(stack).toHaveResource('AWS::CloudFormation::WaitConditionHandle'); + Template.fromStack(stack).resourceCountIs('AWS::CloudFormation::WaitConditionHandle', 1); }); describe('creates a CFN WaitCondition resource', () => { test('with count = 0 and timeout = 10', () => { // you can also assert the properties of the resulting resource - expect(stack).toHaveResource('AWS::CloudFormation::WaitCondition', { + Template.fromStack(stack).hasResourceProperties('AWS::CloudFormation::WaitCondition', { 'Count': 0, 'Timeout': '10', 'Handle': { @@ -59,19 +56,19 @@ describe('Example Resource', () => { 'Ref': 'ExampleResourceWaitConditionHandle9C53A8D3', }, // this is how you can check a given property is _not_ set - 'RandomProperty': ABSENT, + 'RandomProperty': Match.absentProperty(), }); }); test('with retention policy = Retain', () => { - // haveResource asserts _all_ properties of a resource, - // while haveResourceLike only those that you provide - expect(stack).toHaveResourceLike('AWS::CloudFormation::WaitCondition', { + // hasResource asserts _all_ properties of a resource, + // while hasResourceProperties only those within the 'Property' block + Template.fromStack(stack).hasResource('AWS::CloudFormation::WaitCondition', { 'DeletionPolicy': 'Retain', 'UpdateReplacePolicy': 'Retain', // by default, haveResource and haveResourceLike only assert the properties of a resource - // here's how you make them look at the entire resource definition - }, ResourcePart.CompleteDefinition); + }); }); }); @@ -91,11 +88,12 @@ describe('Example Resource', () => { exampleResource.grantRead(role); - expect(stack).toHaveResourceLike('AWS::IAM::Policy', { + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { 'PolicyDocument': { 'Statement': [ { 'Action': 's3:Get*', + 'Effect': 'Allow', 'Resource': { 'Fn::Join': ['', [ 'arn:', @@ -131,7 +129,7 @@ describe('Example Resource', () => { }); test('correctly fills out the subnetIds property of the created VPC endpoint', () => { - expect(stack).toHaveResourceLike('AWS::EC2::VPCEndpoint', { + Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCEndpoint', { 'SubnetIds': [ { 'Ref': 'VpcPrivateSubnet1Subnet536B997A' }, { 'Ref': 'VpcPrivateSubnet2Subnet3788AAA1' }, diff --git a/packages/@aws-cdk/lambda-layer-kubectl/layer/Dockerfile b/packages/@aws-cdk/lambda-layer-kubectl/layer/Dockerfile index a16378b13d91b..27081a5c0d9cf 100644 --- a/packages/@aws-cdk/lambda-layer-kubectl/layer/Dockerfile +++ b/packages/@aws-cdk/lambda-layer-kubectl/layer/Dockerfile @@ -5,7 +5,9 @@ FROM public.ecr.aws/lambda/provided:latest # versions # -ARG KUBECTL_VERSION=1.20.0 +# KUBECTL_VERSION should not be changed at the moment, see https://github.com/aws/aws-cdk/issues/15736 +# Version 1.21.0 is not compatible with version 1.20 (and lower) of the server. +ARG KUBECTL_VERSION=1.20.0 ARG HELM_VERSION=3.5.4 USER root diff --git a/packages/@aws-cdk/pipelines/lib/codepipeline/codepipeline.ts b/packages/@aws-cdk/pipelines/lib/codepipeline/codepipeline.ts index 4e509faee2111..cc4cdeea3aa3f 100644 --- a/packages/@aws-cdk/pipelines/lib/codepipeline/codepipeline.ts +++ b/packages/@aws-cdk/pipelines/lib/codepipeline/codepipeline.ts @@ -4,7 +4,7 @@ import * as cp from '@aws-cdk/aws-codepipeline'; import * as cpa from '@aws-cdk/aws-codepipeline-actions'; import * as ec2 from '@aws-cdk/aws-ec2'; import * as iam from '@aws-cdk/aws-iam'; -import { Aws, Fn, Lazy, PhysicalName, Stack } from '@aws-cdk/core'; +import { Aws, CfnCapabilities, Fn, Lazy, PhysicalName, Stack } from '@aws-cdk/core'; import * as cxapi from '@aws-cdk/cx-api'; import { Construct, Node } from 'constructs'; import { AssetType, FileSet, IFileSetProducer, ManualApprovalStep, ShellStep, StackAsset, StackDeployment, Step } from '../blueprint'; @@ -536,6 +536,7 @@ export class CodePipeline extends PipelineBase { templateConfiguration: templateConfigurationPath ? templateArtifact.atPath(toPosixPath(templateConfigurationPath)) : undefined, + cfnCapabilities: [CfnCapabilities.NAMED_IAM, CfnCapabilities.AUTO_EXPAND], })); return { runOrdersConsumed: 1 }; }, diff --git a/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json b/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json index 848406b0ad02e..7a937f57d6a8e 100644 --- a/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json +++ b/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json @@ -911,7 +911,7 @@ }, "Configuration": { "StackName": "Beta-Stack1", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", diff --git a/packages/@aws-cdk/pipelines/test/integ.newpipeline.expected.json b/packages/@aws-cdk/pipelines/test/integ.newpipeline.expected.json index 27f47b7a985a2..96ffa58af1c62 100644 --- a/packages/@aws-cdk/pipelines/test/integ.newpipeline.expected.json +++ b/packages/@aws-cdk/pipelines/test/integ.newpipeline.expected.json @@ -320,7 +320,7 @@ }, "Configuration": { "StackName": "Beta-Stack1", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", @@ -426,7 +426,7 @@ }, "Configuration": { "StackName": "Beta-Stack2", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", @@ -537,7 +537,7 @@ }, "Configuration": { "StackName": "Prod1-Stack1", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", @@ -605,7 +605,7 @@ }, "Configuration": { "StackName": "Prod2-Stack1", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", @@ -749,7 +749,7 @@ }, "Configuration": { "StackName": "Prod1-Stack2", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", @@ -817,7 +817,7 @@ }, "Configuration": { "StackName": "Prod2-Stack2", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", @@ -966,7 +966,7 @@ }, "Configuration": { "StackName": "Prod3-Stack1", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", @@ -1034,7 +1034,7 @@ }, "Configuration": { "StackName": "Prod4-Stack1", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", @@ -1102,7 +1102,7 @@ }, "Configuration": { "StackName": "Prod5-Stack1", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", @@ -1170,7 +1170,7 @@ }, "Configuration": { "StackName": "Prod6-Stack1", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", @@ -1390,7 +1390,7 @@ }, "Configuration": { "StackName": "Prod3-Stack2", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", @@ -1458,7 +1458,7 @@ }, "Configuration": { "StackName": "Prod4-Stack2", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", @@ -1526,7 +1526,7 @@ }, "Configuration": { "StackName": "Prod5-Stack2", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", @@ -1594,7 +1594,7 @@ }, "Configuration": { "StackName": "Prod6-Stack2", - "Capabilities": "CAPABILITY_NAMED_IAM", + "Capabilities": "CAPABILITY_NAMED_IAM,CAPABILITY_AUTO_EXPAND", "RoleArn": { "Fn::Join": [ "", diff --git a/packages/@aws-cdk/pipelines/test/integ.newpipeline.ts b/packages/@aws-cdk/pipelines/test/integ.newpipeline.ts index b777b61a23e09..b327745145505 100644 --- a/packages/@aws-cdk/pipelines/test/integ.newpipeline.ts +++ b/packages/@aws-cdk/pipelines/test/integ.newpipeline.ts @@ -1,5 +1,5 @@ // eslint-disable-next-line import/no-extraneous-dependencies -/// !cdk-integ PipelineStack +/// !cdk-integ PipelineStack pragma:set-context:@aws-cdk/core:newStyleStackSynthesis=true import * as sqs from '@aws-cdk/aws-sqs'; import { App, Stack, StackProps, Stage, StageProps } from '@aws-cdk/core'; import { Construct } from 'constructs'; diff --git a/packages/@aws-cdk/pipelines/test/integ.pipeline-security.ts b/packages/@aws-cdk/pipelines/test/integ.pipeline-security.ts index 8b43db6087a1c..a5d257b78523e 100644 --- a/packages/@aws-cdk/pipelines/test/integ.pipeline-security.ts +++ b/packages/@aws-cdk/pipelines/test/integ.pipeline-security.ts @@ -1,4 +1,4 @@ -/// !cdk-integ PipelineSecurityStack +/// !cdk-integ PipelineSecurityStack pragma:set-context:@aws-cdk/core:newStyleStackSynthesis=true import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as codepipeline_actions from '@aws-cdk/aws-codepipeline-actions'; import * as iam from '@aws-cdk/aws-iam'; diff --git a/packages/@aws-cdk/region-info/build-tools/fact-tables.ts b/packages/@aws-cdk/region-info/build-tools/fact-tables.ts index 28ec007b00c84..28d61f7fd9387 100644 --- a/packages/@aws-cdk/region-info/build-tools/fact-tables.ts +++ b/packages/@aws-cdk/region-info/build-tools/fact-tables.ts @@ -159,6 +159,88 @@ export const APPMESH_ECR_ACCOUNTS: { [region: string]: string } = { 'us-west-2': '840364872350', }; +// https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Lambda-Insights-extension-versions.html +export const CLOUDWATCH_LAMBDA_INSIGHTS_ARNS: { [key: string]: any } = { + '1.0.98.0': { + 'us-east-1': 'arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:14', + 'us-east-2': 'arn:aws:lambda:us-east-2:580247275435:layer:LambdaInsightsExtension:14', + 'us-west-1': 'arn:aws:lambda:us-west-1:580247275435:layer:LambdaInsightsExtension:14', + 'us-west-2': 'arn:aws:lambda:us-west-2:580247275435:layer:LambdaInsightsExtension:14', + 'af-south-1': 'arn:aws:lambda:af-south-1:012438385374:layer:LambdaInsightsExtension:8', + 'ap-east-1': 'arn:aws:lambda:ap-east-1:519774774795:layer:LambdaInsightsExtension:8', + 'ap-south-1': 'arn:aws:lambda:ap-south-1:580247275435:layer:LambdaInsightsExtension:14', + 'ap-northeast-2': 'arn:aws:lambda:ap-northeast-2:580247275435:layer:LambdaInsightsExtension:14', + 'ap-southeast-1': 'arn:aws:lambda:ap-southeast-1:580247275435:layer:LambdaInsightsExtension:14', + 'ap-southeast-2': 'arn:aws:lambda:ap-southeast-2:580247275435:layer:LambdaInsightsExtension:14', + 'ap-northeast-1': 'arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:14', + 'ca-central-1': 'arn:aws:lambda:ca-central-1:580247275435:layer:LambdaInsightsExtension:14', + 'cn-north-1': 'arn:aws-cn:lambda:cn-north-1:488211338238:layer:LambdaInsightsExtension:8', + 'cn-northwest-1': 'arn:aws-cn:lambda:cn-northwest-1:488211338238:layer:LambdaInsightsExtension:8', + 'eu-central-1': 'arn:aws:lambda:eu-central-1:580247275435:layer:LambdaInsightsExtension:14', + 'eu-west-1': 'arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:14', + 'eu-west-2': 'arn:aws:lambda:eu-west-2:580247275435:layer:LambdaInsightsExtension:14', + 'eu-south-1': 'arn:aws:lambda:eu-south-1:339249233099:layer:LambdaInsightsExtension:8', + 'eu-west-3': 'arn:aws:lambda:eu-west-3:580247275435:layer:LambdaInsightsExtension:14', + 'eu-north-1': 'arn:aws:lambda:eu-north-1:580247275435:layer:LambdaInsightsExtension:14', + 'me-south-1': 'arn:aws:lambda:me-south-1:285320876703:layer:LambdaInsightsExtension:8', + 'sa-east-1': 'arn:aws:lambda:sa-east-1:580247275435:layer:LambdaInsightsExtension:14', + }, + '1.0.89.0': { + 'us-east-1': 'arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:12', + 'us-east-2': 'arn:aws:lambda:us-east-2:580247275435:layer:LambdaInsightsExtension:12', + 'us-west-1': 'arn:aws:lambda:us-west-1:580247275435:layer:LambdaInsightsExtension:12', + 'us-west-2': 'arn:aws:lambda:us-west-2:580247275435:layer:LambdaInsightsExtension:12', + 'ap-south-1': 'arn:aws:lambda:ap-south-1:580247275435:layer:LambdaInsightsExtension:12', + 'ap-northeast-2': 'arn:aws:lambda:ap-northeast-2:580247275435:layer:LambdaInsightsExtension:12', + 'ap-southeast-1': 'arn:aws:lambda:ap-southeast-1:580247275435:layer:LambdaInsightsExtension:12', + 'ap-southeast-2': 'arn:aws:lambda:ap-southeast-2:580247275435:layer:LambdaInsightsExtension:12', + 'ap-northeast-1': 'arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:12', + 'ca-central-1': 'arn:aws:lambda:ca-central-1:580247275435:layer:LambdaInsightsExtension:12', + 'eu-central-1': 'arn:aws:lambda:eu-central-1:580247275435:layer:LambdaInsightsExtension:12', + 'eu-west-1': 'arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:12', + 'eu-west-2': 'arn:aws:lambda:eu-west-2:580247275435:layer:LambdaInsightsExtension:12', + 'eu-west-3': 'arn:aws:lambda:eu-west-3:580247275435:layer:LambdaInsightsExtension:12', + 'eu-north-1': 'arn:aws:lambda:eu-north-1:580247275435:layer:LambdaInsightsExtension:12', + 'sa-east-1': 'arn:aws:lambda:sa-east-1:580247275435:layer:LambdaInsightsExtension:12', + }, + '1.0.86.0': { + 'us-east-1': 'arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:11', + 'us-east-2': 'arn:aws:lambda:us-east-2:580247275435:layer:LambdaInsightsExtension:11', + 'us-west-1': 'arn:aws:lambda:us-west-1:580247275435:layer:LambdaInsightsExtension:11', + 'us-west-2': 'arn:aws:lambda:us-west-2:580247275435:layer:LambdaInsightsExtension:11', + 'ap-south-1': 'arn:aws:lambda:ap-south-1:580247275435:layer:LambdaInsightsExtension:11', + 'ap-northeast-2': 'arn:aws:lambda:ap-northeast-2:580247275435:layer:LambdaInsightsExtension:11', + 'ap-southeast-1': 'arn:aws:lambda:ap-southeast-1:580247275435:layer:LambdaInsightsExtension:11', + 'ap-southeast-2': 'arn:aws:lambda:ap-southeast-2:580247275435:layer:LambdaInsightsExtension:11', + 'ap-northeast-1': 'arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:11', + 'ca-central-1': 'arn:aws:lambda:ca-central-1:580247275435:layer:LambdaInsightsExtension:11', + 'eu-central-1': 'arn:aws:lambda:eu-central-1:580247275435:layer:LambdaInsightsExtension:11', + 'eu-west-1': 'arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:11', + 'eu-west-2': 'arn:aws:lambda:eu-west-2:580247275435:layer:LambdaInsightsExtension:11', + 'eu-west-3': 'arn:aws:lambda:eu-west-3:580247275435:layer:LambdaInsightsExtension:11', + 'eu-north-1': 'arn:aws:lambda:eu-north-1:580247275435:layer:LambdaInsightsExtension:11', + 'sa-east-1': 'arn:aws:lambda:sa-east-1:580247275435:layer:LambdaInsightsExtension:11', + }, + '1.0.54.0': { + 'us-east-1': 'arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:2', + 'us-east-2': 'arn:aws:lambda:us-east-2:580247275435:layer:LambdaInsightsExtension:2', + 'us-west-1': 'arn:aws:lambda:us-west-1:580247275435:layer:LambdaInsightsExtension:2', + 'us-west-2': 'arn:aws:lambda:us-west-2:580247275435:layer:LambdaInsightsExtension:2', + 'ap-south-1': 'arn:aws:lambda:ap-south-1:580247275435:layer:LambdaInsightsExtension:2', + 'ap-northeast-2': 'arn:aws:lambda:ap-northeast-2:580247275435:layer:LambdaInsightsExtension:2', + 'ap-southeast-1': 'arn:aws:lambda:ap-southeast-1:580247275435:layer:LambdaInsightsExtension:2', + 'ap-southeast-2': 'arn:aws:lambda:ap-southeast-2:580247275435:layer:LambdaInsightsExtension:2', + 'ap-northeast-1': 'arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:2', + 'ca-central-1': 'arn:aws:lambda:ca-central-1:580247275435:layer:LambdaInsightsExtension:2', + 'eu-central-1': 'arn:aws:lambda:eu-central-1:580247275435:layer:LambdaInsightsExtension:2', + 'eu-west-1': 'arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:2', + 'eu-west-2': 'arn:aws:lambda:eu-west-2:580247275435:layer:LambdaInsightsExtension:2', + 'eu-west-3': 'arn:aws:lambda:eu-west-3:580247275435:layer:LambdaInsightsExtension:2', + 'eu-north-1': 'arn:aws:lambda:eu-north-1:580247275435:layer:LambdaInsightsExtension:2', + 'sa-east-1': 'arn:aws:lambda:sa-east-1:580247275435:layer:LambdaInsightsExtension:2', + }, +}; + // https://docs.aws.amazon.com/firehose/latest/dev/controlling-access.html#using-iam-rs-vpc export const FIREHOSE_CIDR_BLOCKS: { [region: string]: string } = { 'af-south-1': '13.244.121.224', diff --git a/packages/@aws-cdk/region-info/build-tools/generate-static-data.ts b/packages/@aws-cdk/region-info/build-tools/generate-static-data.ts index 63455b72ef665..dd42309b78c8a 100644 --- a/packages/@aws-cdk/region-info/build-tools/generate-static-data.ts +++ b/packages/@aws-cdk/region-info/build-tools/generate-static-data.ts @@ -3,8 +3,8 @@ import * as fs from 'fs-extra'; import { Default } from '../lib/default'; import { AWS_REGIONS, AWS_SERVICES } from './aws-entities'; import { - APPMESH_ECR_ACCOUNTS, AWS_CDK_METADATA, AWS_OLDER_REGIONS, DLC_REPOSITORY_ACCOUNTS, ELBV2_ACCOUNTS, FIREHOSE_CIDR_BLOCKS, - PARTITION_MAP, ROUTE_53_BUCKET_WEBSITE_ZONE_IDS, + APPMESH_ECR_ACCOUNTS, AWS_CDK_METADATA, AWS_OLDER_REGIONS, CLOUDWATCH_LAMBDA_INSIGHTS_ARNS, DLC_REPOSITORY_ACCOUNTS, + ELBV2_ACCOUNTS, FIREHOSE_CIDR_BLOCKS, PARTITION_MAP, ROUTE_53_BUCKET_WEBSITE_ZONE_IDS, } from './fact-tables'; async function main(): Promise { @@ -13,6 +13,7 @@ async function main(): Promise { checkRegions(ELBV2_ACCOUNTS); checkRegions(FIREHOSE_CIDR_BLOCKS); checkRegions(ROUTE_53_BUCKET_WEBSITE_ZONE_IDS); + checkRegionsSubMap(CLOUDWATCH_LAMBDA_INSIGHTS_ARNS); const lines = [ "import { Fact, FactName } from './fact';", @@ -73,6 +74,10 @@ async function main(): Promise { for (const service of AWS_SERVICES) { registerFact(region, ['servicePrincipal', service], Default.servicePrincipal(service, region, domainSuffix)); } + + for (const version in CLOUDWATCH_LAMBDA_INSIGHTS_ARNS) { + registerFact(region, ['cloudwatchLambdaInsightsVersion', version], CLOUDWATCH_LAMBDA_INSIGHTS_ARNS[version][region]); + } } lines.push(' }'); lines.push(''); @@ -100,6 +105,21 @@ function checkRegions(map: Record) { } } +/** + * Verifies that the provided map of to region to fact does not contain an entry + * for a region that was not registered in `AWS_REGIONS`. + */ +function checkRegionsSubMap(map: Record>) { + const allRegions = new Set(AWS_REGIONS); + for (const key of Object.keys(map)) { + for (const region of Object.keys(map[key])) { + if (!allRegions.has(region)) { + throw new Error(`Un-registered region fact found: ${region}. Add to AWS_REGIONS list!`); + } + } + } +} + main().catch(e => { // eslint-disable-next-line no-console console.error(e); diff --git a/packages/@aws-cdk/region-info/lib/fact.ts b/packages/@aws-cdk/region-info/lib/fact.ts index 6ccef0e8b794f..c099aced9fd55 100644 --- a/packages/@aws-cdk/region-info/lib/fact.ts +++ b/packages/@aws-cdk/region-info/lib/fact.ts @@ -157,6 +157,13 @@ export class FactName { */ public static readonly FIREHOSE_CIDR_BLOCK = 'firehoseCidrBlock'; + /** + * The ARN of CloudWatch Lambda Insights for a version (e.g. 1.0.98.0) + */ + public static cloudwatchLambdaInsightsVersion(version: string) { + return `cloudwatch-lambda-insights-version:${version.split('.').join('_')}`; + } + /** * The name of the regional service principal for a given service. * diff --git a/packages/@aws-cdk/region-info/lib/region-info.ts b/packages/@aws-cdk/region-info/lib/region-info.ts index 9e28120a8da62..baa2c43635892 100644 --- a/packages/@aws-cdk/region-info/lib/region-info.ts +++ b/packages/@aws-cdk/region-info/lib/region-info.ts @@ -110,6 +110,14 @@ export class RegionInfo { return Fact.find(this.name, FactName.DLC_REPOSITORY_ACCOUNT); } + /** + * The ARN of the CloudWatch Lambda Insights extension, for the given version. + * @param insightsVersion the version (e.g. 1.0.98.0) + */ + public cloudwatchLambdaInsightsArn(insightsVersion: string): string | undefined { + return Fact.find(this.name, FactName.cloudwatchLambdaInsightsVersion(insightsVersion)); + } + /** * The ID of the AWS account that owns the public ECR repository that contains the * AWS App Mesh Envoy Proxy images in a given region. diff --git a/packages/@aws-cdk/region-info/test/__snapshots__/region-info.test.js.snap b/packages/@aws-cdk/region-info/test/__snapshots__/region-info.test.js.snap index eb7c82b6eb28d..f1797f8083af5 100644 --- a/packages/@aws-cdk/region-info/test/__snapshots__/region-info.test.js.snap +++ b/packages/@aws-cdk/region-info/test/__snapshots__/region-info.test.js.snap @@ -5,6 +5,12 @@ Object { "af-south-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": undefined, + "1.0.86.0": undefined, + "1.0.89.0": undefined, + "1.0.98.0": "arn:aws:lambda:af-south-1:012438385374:layer:LambdaInsightsExtension:8", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website.af-south-1.amazonaws.com", "servicePrincipals": Object { @@ -25,6 +31,12 @@ Object { "ap-east-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": undefined, + "1.0.86.0": undefined, + "1.0.89.0": undefined, + "1.0.98.0": "arn:aws:lambda:ap-east-1:519774774795:layer:LambdaInsightsExtension:8", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website.ap-east-1.amazonaws.com", "servicePrincipals": Object { @@ -45,6 +57,12 @@ Object { "ap-northeast-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:ap-northeast-1:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website-ap-northeast-1.amazonaws.com", "servicePrincipals": Object { @@ -65,6 +83,12 @@ Object { "ap-northeast-2": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:ap-northeast-2:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:ap-northeast-2:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:ap-northeast-2:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:ap-northeast-2:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website.ap-northeast-2.amazonaws.com", "servicePrincipals": Object { @@ -85,6 +109,12 @@ Object { "ap-northeast-3": Object { "cdkMetadataResourceAvailable": false, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": undefined, + "1.0.86.0": undefined, + "1.0.89.0": undefined, + "1.0.98.0": undefined, + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website.ap-northeast-3.amazonaws.com", "servicePrincipals": Object { @@ -105,6 +135,12 @@ Object { "ap-south-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:ap-south-1:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:ap-south-1:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:ap-south-1:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:ap-south-1:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website.ap-south-1.amazonaws.com", "servicePrincipals": Object { @@ -125,6 +161,12 @@ Object { "ap-southeast-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:ap-southeast-1:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:ap-southeast-1:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:ap-southeast-1:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:ap-southeast-1:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website-ap-southeast-1.amazonaws.com", "servicePrincipals": Object { @@ -145,6 +187,12 @@ Object { "ap-southeast-2": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:ap-southeast-2:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:ap-southeast-2:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:ap-southeast-2:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:ap-southeast-2:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website-ap-southeast-2.amazonaws.com", "servicePrincipals": Object { @@ -165,6 +213,12 @@ Object { "ca-central-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:ca-central-1:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:ca-central-1:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:ca-central-1:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:ca-central-1:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website.ca-central-1.amazonaws.com", "servicePrincipals": Object { @@ -185,6 +239,12 @@ Object { "cn-north-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com.cn", + "lambdaInsightsVersions": Object { + "1.0.54.0": undefined, + "1.0.86.0": undefined, + "1.0.89.0": undefined, + "1.0.98.0": "arn:aws-cn:lambda:cn-north-1:488211338238:layer:LambdaInsightsExtension:8", + }, "partition": "aws-cn", "s3StaticWebsiteEndpoint": "s3-website.cn-north-1.amazonaws.com.cn", "servicePrincipals": Object { @@ -205,6 +265,12 @@ Object { "cn-northwest-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com.cn", + "lambdaInsightsVersions": Object { + "1.0.54.0": undefined, + "1.0.86.0": undefined, + "1.0.89.0": undefined, + "1.0.98.0": "arn:aws-cn:lambda:cn-northwest-1:488211338238:layer:LambdaInsightsExtension:8", + }, "partition": "aws-cn", "s3StaticWebsiteEndpoint": "s3-website.cn-northwest-1.amazonaws.com.cn", "servicePrincipals": Object { @@ -225,6 +291,12 @@ Object { "eu-central-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:eu-central-1:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:eu-central-1:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:eu-central-1:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:eu-central-1:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website.eu-central-1.amazonaws.com", "servicePrincipals": Object { @@ -245,6 +317,12 @@ Object { "eu-north-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:eu-north-1:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:eu-north-1:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:eu-north-1:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:eu-north-1:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website.eu-north-1.amazonaws.com", "servicePrincipals": Object { @@ -265,6 +343,12 @@ Object { "eu-south-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": undefined, + "1.0.86.0": undefined, + "1.0.89.0": undefined, + "1.0.98.0": "arn:aws:lambda:eu-south-1:339249233099:layer:LambdaInsightsExtension:8", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website.eu-south-1.amazonaws.com", "servicePrincipals": Object { @@ -285,6 +369,12 @@ Object { "eu-west-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:eu-west-1:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website-eu-west-1.amazonaws.com", "servicePrincipals": Object { @@ -305,6 +395,12 @@ Object { "eu-west-2": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:eu-west-2:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:eu-west-2:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:eu-west-2:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:eu-west-2:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website.eu-west-2.amazonaws.com", "servicePrincipals": Object { @@ -325,6 +421,12 @@ Object { "eu-west-3": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:eu-west-3:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:eu-west-3:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:eu-west-3:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:eu-west-3:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website.eu-west-3.amazonaws.com", "servicePrincipals": Object { @@ -345,6 +447,12 @@ Object { "me-south-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": undefined, + "1.0.86.0": undefined, + "1.0.89.0": undefined, + "1.0.98.0": "arn:aws:lambda:me-south-1:285320876703:layer:LambdaInsightsExtension:8", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website.me-south-1.amazonaws.com", "servicePrincipals": Object { @@ -365,6 +473,12 @@ Object { "sa-east-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:sa-east-1:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:sa-east-1:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:sa-east-1:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:sa-east-1:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website-sa-east-1.amazonaws.com", "servicePrincipals": Object { @@ -385,6 +499,12 @@ Object { "us-east-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:us-east-1:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website-us-east-1.amazonaws.com", "servicePrincipals": Object { @@ -405,6 +525,12 @@ Object { "us-east-2": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:us-east-2:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:us-east-2:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:us-east-2:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:us-east-2:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website.us-east-2.amazonaws.com", "servicePrincipals": Object { @@ -425,6 +551,12 @@ Object { "us-gov-east-1": Object { "cdkMetadataResourceAvailable": false, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": undefined, + "1.0.86.0": undefined, + "1.0.89.0": undefined, + "1.0.98.0": undefined, + }, "partition": "aws-us-gov", "s3StaticWebsiteEndpoint": "s3-website.us-gov-east-1.amazonaws.com", "servicePrincipals": Object { @@ -445,6 +577,12 @@ Object { "us-gov-west-1": Object { "cdkMetadataResourceAvailable": false, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": undefined, + "1.0.86.0": undefined, + "1.0.89.0": undefined, + "1.0.98.0": undefined, + }, "partition": "aws-us-gov", "s3StaticWebsiteEndpoint": "s3-website-us-gov-west-1.amazonaws.com", "servicePrincipals": Object { @@ -465,6 +603,12 @@ Object { "us-iso-east-1": Object { "cdkMetadataResourceAvailable": false, "domainSuffix": "c2s.ic.gov", + "lambdaInsightsVersions": Object { + "1.0.54.0": undefined, + "1.0.86.0": undefined, + "1.0.89.0": undefined, + "1.0.98.0": undefined, + }, "partition": "aws-iso", "s3StaticWebsiteEndpoint": "s3-website.us-iso-east-1.c2s.ic.gov", "servicePrincipals": Object { @@ -485,6 +629,12 @@ Object { "us-isob-east-1": Object { "cdkMetadataResourceAvailable": false, "domainSuffix": "sc2s.sgov.gov", + "lambdaInsightsVersions": Object { + "1.0.54.0": undefined, + "1.0.86.0": undefined, + "1.0.89.0": undefined, + "1.0.98.0": undefined, + }, "partition": "aws-iso-b", "s3StaticWebsiteEndpoint": "s3-website.us-isob-east-1.sc2s.sgov.gov", "servicePrincipals": Object { @@ -505,6 +655,12 @@ Object { "us-west-1": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:us-west-1:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:us-west-1:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:us-west-1:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:us-west-1:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website-us-west-1.amazonaws.com", "servicePrincipals": Object { @@ -525,6 +681,12 @@ Object { "us-west-2": Object { "cdkMetadataResourceAvailable": true, "domainSuffix": "amazonaws.com", + "lambdaInsightsVersions": Object { + "1.0.54.0": "arn:aws:lambda:us-west-2:580247275435:layer:LambdaInsightsExtension:2", + "1.0.86.0": "arn:aws:lambda:us-west-2:580247275435:layer:LambdaInsightsExtension:11", + "1.0.89.0": "arn:aws:lambda:us-west-2:580247275435:layer:LambdaInsightsExtension:12", + "1.0.98.0": "arn:aws:lambda:us-west-2:580247275435:layer:LambdaInsightsExtension:14", + }, "partition": "aws", "s3StaticWebsiteEndpoint": "s3-website-us-west-2.amazonaws.com", "servicePrincipals": Object { diff --git a/packages/@aws-cdk/region-info/test/region-info.test.ts b/packages/@aws-cdk/region-info/test/region-info.test.ts index 5f9f68ea4a787..8c06907052b23 100644 --- a/packages/@aws-cdk/region-info/test/region-info.test.ts +++ b/packages/@aws-cdk/region-info/test/region-info.test.ts @@ -1,4 +1,5 @@ import { AWS_REGIONS, AWS_SERVICES } from '../build-tools/aws-entities'; +import { CLOUDWATCH_LAMBDA_INSIGHTS_ARNS } from '../build-tools/fact-tables'; import { RegionInfo } from '../lib'; test('built-in data is correct', () => { @@ -7,8 +8,14 @@ test('built-in data is correct', () => { const region = RegionInfo.get(name); const servicePrincipals: { [service: string]: string | undefined } = {}; + const lambdaInsightsVersions: { [service: string]: string | undefined } = {}; + AWS_SERVICES.forEach(service => servicePrincipals[service] = region.servicePrincipal(service)); + for (const version in CLOUDWATCH_LAMBDA_INSIGHTS_ARNS) { + lambdaInsightsVersions[version] = region.cloudwatchLambdaInsightsArn(version); + }; + snapshot[name] = { cdkMetadataResourceAvailable: region.cdkMetadataResourceAvailable, domainSuffix: region.domainSuffix, @@ -16,6 +23,7 @@ test('built-in data is correct', () => { s3StaticWebsiteEndpoint: region.s3StaticWebsiteEndpoint, vpcEndPointServiceNamePrefix: region.vpcEndpointServiceNamePrefix, servicePrincipals, + lambdaInsightsVersions, }; } expect(snapshot).toMatchSnapshot(); diff --git a/packages/aws-cdk-lib/package.json b/packages/aws-cdk-lib/package.json index 411d6eed9a312..e3b5cfb83db95 100644 --- a/packages/aws-cdk-lib/package.json +++ b/packages/aws-cdk-lib/package.json @@ -282,6 +282,8 @@ "@aws-cdk/aws-route53": "0.0.0", "@aws-cdk/aws-route53-patterns": "0.0.0", "@aws-cdk/aws-route53-targets": "0.0.0", + "@aws-cdk/aws-route53recoverycontrol": "0.0.0", + "@aws-cdk/aws-route53recoveryreadiness": "0.0.0", "@aws-cdk/aws-route53resolver": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/aws-s3-assets": "0.0.0", diff --git a/packages/aws-cdk/bin/cdk.ts b/packages/aws-cdk/bin/cdk.ts index f072a557c4783..1103b6354bf67 100644 --- a/packages/aws-cdk/bin/cdk.ts +++ b/packages/aws-cdk/bin/cdk.ts @@ -114,8 +114,8 @@ async function parseCommandLineArguments() { .option('context-lines', { type: 'number', desc: 'Number of context lines to include in arbitrary JSON diff rendering', default: 3, requiresArg: true }) .option('template', { type: 'string', desc: 'The path to the CloudFormation template to compare with', requiresArg: true }) .option('strict', { type: 'boolean', desc: 'Do not filter out AWS::CDK::Metadata resources', default: false }) - .option('security-only', { type: 'boolean', desc: 'Only diff for broadened security changes', default: false })) - .option('fail', { type: 'boolean', desc: 'Fail with exit code 1 in case of diff', default: false }) + .option('security-only', { type: 'boolean', desc: 'Only diff for broadened security changes', default: false }) + .option('fail', { type: 'boolean', desc: 'Fail with exit code 1 in case of diff', default: false })) .command('metadata [STACK]', 'Returns all metadata associated with this stack') .command('init [TEMPLATE]', 'Create a new, empty CDK project from a template.', yargs => yargs .option('language', { type: 'string', alias: 'l', desc: 'The language to be used for the new project (default can be configured in ~/.cdk.json)', choices: initTemplateLanguages }) diff --git a/packages/decdk/package.json b/packages/decdk/package.json index 73c670cec466d..f386bef25c9e5 100644 --- a/packages/decdk/package.json +++ b/packages/decdk/package.json @@ -189,6 +189,8 @@ "@aws-cdk/aws-route53": "0.0.0", "@aws-cdk/aws-route53-patterns": "0.0.0", "@aws-cdk/aws-route53-targets": "0.0.0", + "@aws-cdk/aws-route53recoverycontrol": "0.0.0", + "@aws-cdk/aws-route53recoveryreadiness": "0.0.0", "@aws-cdk/aws-route53resolver": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/aws-s3-assets": "0.0.0", diff --git a/packages/monocdk/package.json b/packages/monocdk/package.json index 43227b31a4041..10c0235667470 100644 --- a/packages/monocdk/package.json +++ b/packages/monocdk/package.json @@ -283,6 +283,8 @@ "@aws-cdk/aws-route53": "0.0.0", "@aws-cdk/aws-route53-patterns": "0.0.0", "@aws-cdk/aws-route53-targets": "0.0.0", + "@aws-cdk/aws-route53recoverycontrol": "0.0.0", + "@aws-cdk/aws-route53recoveryreadiness": "0.0.0", "@aws-cdk/aws-route53resolver": "0.0.0", "@aws-cdk/aws-s3": "0.0.0", "@aws-cdk/aws-s3-assets": "0.0.0", diff --git a/tools/cdk-integ-tools/lib/integ-helpers.ts b/tools/cdk-integ-tools/lib/integ-helpers.ts index 5aabc99210663..bf52cbc4247cc 100644 --- a/tools/cdk-integ-tools/lib/integ-helpers.ts +++ b/tools/cdk-integ-tools/lib/integ-helpers.ts @@ -8,6 +8,7 @@ const CDK_OUTDIR = 'cdk-integ.out'; const CDK_INTEG_STACK_PRAGMA = '/// !cdk-integ'; const PRAGMA_PREFIX = 'pragma:'; +const SET_CONTEXT_PRAGMA_PREFIX = 'pragma:set-context:'; export class IntegrationTests { constructor(private readonly directory: string) { @@ -95,10 +96,23 @@ export class IntegrationTest { * Return the "main" template or a concatenation of all listed templates in the pragma */ public async cdkSynthFast(options: SynthOptions = {}): Promise { - const context = { + const context: Record = { ...options.context, }; + // apply context from set-context pragma + // usage: pragma:set-context:key=value + const ctxPragmas = (await this.pragmas()).filter(p => p.startsWith(SET_CONTEXT_PRAGMA_PREFIX)); + for (const p of ctxPragmas) { + const instruction = p.substring(SET_CONTEXT_PRAGMA_PREFIX.length); + const [key, value] = instruction.split('='); + if (key == null || value == null) { + throw new Error(`invalid "set-context" pragma syntax. example: "pragma:set-context:@aws-cdk/core:newStyleStackSynthesis=true" got: ${p}`); + } + + context[key] = value; + } + try { await exec(['node', `${this.name}`], { cwd: this.directory, diff --git a/version.v1.json b/version.v1.json index 63c5030d06ef4..95b9ca9e3c2f0 100644 --- a/version.v1.json +++ b/version.v1.json @@ -1,3 +1,3 @@ { - "version": "1.116.0" + "version": "1.117.0" }