diff --git a/examples/cdk-application-pipeline/infrastructure/src/deployment.ts b/examples/cdk-application-pipeline/infrastructure/src/deployment.ts index 131d7bd..8e4aafb 100644 --- a/examples/cdk-application-pipeline/infrastructure/src/deployment.ts +++ b/examples/cdk-application-pipeline/infrastructure/src/deployment.ts @@ -1,14 +1,30 @@ -import { ApplicationLoadBalancedCodeDeployedFargateService } from '@cdklabs/cdk-ecs-codedeploy'; -import { CfnOutput, Duration, RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib'; -import { EcsDeploymentConfig, IEcsDeploymentConfig } from 'aws-cdk-lib/aws-codedeploy'; +import { + CfnOutput, + Duration, + RemovalPolicy, + Stack, + StackProps, +} from 'aws-cdk-lib'; +import { + IEcsDeploymentConfig, + EcsDeploymentConfig, +} from 'aws-cdk-lib/aws-codedeploy'; import * as ec2 from 'aws-cdk-lib/aws-ec2'; -import { FlowLog, FlowLogResourceType, Port } from 'aws-cdk-lib/aws-ec2'; -import * as ecs from 'aws-cdk-lib/aws-ecs'; +import { FlowLog, FlowLogResourceType } from 'aws-cdk-lib/aws-ec2'; import { AssetImage, AwsLogDriver, Secret } from 'aws-cdk-lib/aws-ecs'; import { PolicyStatement } from 'aws-cdk-lib/aws-iam'; import { LogGroup, RetentionDays } from 'aws-cdk-lib/aws-logs'; -import { Credentials, DatabaseClusterEngine, DatabaseSecret, ServerlessCluster } from 'aws-cdk-lib/aws-rds'; +import { + AuroraMysqlEngineVersion, + ClusterInstance, + Credentials, + DatabaseCluster, + DatabaseClusterEngine, + DatabaseSecret, +} from 'aws-cdk-lib/aws-rds'; import { Construct } from 'constructs'; +import { ApplicationLoadBalancedCodeDeployedFargateService } from '@cdklabs/cdk-ecs-codedeploy'; +import * as ecs from 'aws-cdk-lib/aws-ecs'; export interface DeploymentProps extends StackProps { deploymentConfigName?: string; @@ -24,25 +40,35 @@ export class DeploymentStack extends Stack { const image = new AssetImage('.', { target: 'build' }); - const appName = Stack.of(this).stackName.toLowerCase().replace(`-${Stack.of(this).region}-`, '-'); + const appName = Stack.of(this) + .stackName.toLowerCase() + .replace(`-${Stack.of(this).region}-`, '-'); const vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 3, natGateways: props?.natGateways, }); - new FlowLog(this, 'VpcFlowLog', { resourceType: FlowLogResourceType.fromVpc(vpc) }); + new FlowLog(this, 'VpcFlowLog', { + resourceType: FlowLogResourceType.fromVpc(vpc), + }); const dbName = 'fruits'; const dbSecret = new DatabaseSecret(this, 'AuroraSecret', { username: 'fruitapi', secretName: `${appName}-DB`, }); - const db = new ServerlessCluster(this, 'AuroraCluster', { - engine: DatabaseClusterEngine.AURORA_MYSQL, - vpc, + + const db = new DatabaseCluster(this, 'Database', { + engine: DatabaseClusterEngine.auroraMysql({ + version: AuroraMysqlEngineVersion.VER_3_07_1, + }), credentials: Credentials.fromSecret(dbSecret), + writer: ClusterInstance.serverlessV2('writer'), defaultDatabaseName: dbName, - deletionProtection: false, + serverlessV2MaxCapacity: 2, + serverlessV2MinCapacity: 0.5, + vpc, clusterIdentifier: appName, + storageEncrypted: true, }); const cluster = new ecs.Cluster(this, 'Cluster', { @@ -57,64 +83,86 @@ export class DeploymentStack extends Stack { }); let deploymentConfig: IEcsDeploymentConfig | undefined = undefined; if (props?.deploymentConfigName) { - deploymentConfig = EcsDeploymentConfig.fromEcsDeploymentConfigName(this, 'DeploymentConfig', props.deploymentConfigName); + deploymentConfig = EcsDeploymentConfig.fromEcsDeploymentConfigName( + this, + 'DeploymentConfig', + props.deploymentConfigName, + ); } - const appConfigEnabled = props?.appConfigRoleArn !== undefined && props.appConfigRoleArn.length > 0; - const service = new ApplicationLoadBalancedCodeDeployedFargateService(this, 'Api', { - cluster, - capacityProviderStrategies: [ - { - capacityProvider: 'FARGATE_SPOT', - weight: 1, + const appConfigEnabled = + props?.appConfigRoleArn !== undefined && + props.appConfigRoleArn.length > 0; + const service = new ApplicationLoadBalancedCodeDeployedFargateService( + this, + 'Api', + { + cluster, + capacityProviderStrategies: [ + { + capacityProvider: 'FARGATE_SPOT', + weight: 1, + }, + ], + minHealthyPercent: 50, + maxHealthyPercent: 200, + desiredCount: 3, + cpu: 512, + memoryLimitMiB: 1024, + taskImageOptions: { + image, + containerName: 'api', + containerPort: 8080, + family: appName, + logDriver: AwsLogDriver.awsLogs({ + logGroup: appLogGroup, + streamPrefix: 'service', + }), + secrets: { + SPRING_DATASOURCE_USERNAME: Secret.fromSecretsManager( + dbSecret, + 'username', + ), + SPRING_DATASOURCE_PASSWORD: Secret.fromSecretsManager( + dbSecret, + 'password', + ), + }, + environment: { + SPRING_DATASOURCE_URL: `jdbc:mysql://${db.clusterEndpoint.hostname}:${db.clusterEndpoint.port}/${dbName}`, + APPCONFIG_AGENT_APPLICATION: + this.node.tryGetContext('workloadName'), + APPCONFIG_AGENT_ENVIRONMENT: + this.node.tryGetContext('environmentName'), + APPCONFIG_AGENT_ENABLED: appConfigEnabled.toString(), + }, }, - ], - minHealthyPercent: 50, - maxHealthyPercent: 200, - desiredCount: 3, - cpu: 512, - memoryLimitMiB: 1024, - taskImageOptions: { - image, - containerName: 'api', - containerPort: 8080, - family: appName, - logDriver: AwsLogDriver.awsLogs({ - logGroup: appLogGroup, - streamPrefix: 'service', - }), - secrets: { - SPRING_DATASOURCE_USERNAME: Secret.fromSecretsManager( dbSecret, 'username' ), - SPRING_DATASOURCE_PASSWORD: Secret.fromSecretsManager( dbSecret, 'password' ), - }, - environment: { - SPRING_DATASOURCE_URL: `jdbc:mysql://${db.clusterEndpoint.hostname}:${db.clusterEndpoint.port}/${dbName}`, - APPCONFIG_AGENT_APPLICATION: this.node.tryGetContext('workloadName'), - APPCONFIG_AGENT_ENVIRONMENT: this.node.tryGetContext('environmentName'), - APPCONFIG_AGENT_ENABLED: appConfigEnabled.toString(), + deregistrationDelay: Duration.seconds(5), + responseTimeAlarmThreshold: Duration.seconds(3), + targetHealthCheck: { + healthyThresholdCount: 2, + unhealthyThresholdCount: 2, + interval: Duration.seconds(60), + path: '/actuator/health', }, + deploymentConfig, + terminationWaitTime: Duration.minutes(5), + apiCanaryTimeout: Duration.seconds(5), + apiTestSteps: [ + { + name: 'getAll', + path: '/api/fruits', + jmesPath: 'length(@)', + expectedValue: 5, + }, + ], }, - deregistrationDelay: Duration.seconds(5), - responseTimeAlarmThreshold: Duration.seconds(3), - targetHealthCheck: { - healthyThresholdCount: 2, - unhealthyThresholdCount: 2, - interval: Duration.seconds(60), - path: '/actuator/health', - }, - deploymentConfig, - terminationWaitTime: Duration.minutes(5), - apiCanaryTimeout: Duration.seconds(5), - apiTestSteps: [{ - name: 'getAll', - path: '/api/fruits', - jmesPath: 'length(@)', - expectedValue: 5, - }], - }); + ); if (appConfigEnabled) { service.taskDefinition.addContainer('appconfig-agent', { - image: ecs.ContainerImage.fromRegistry('public.ecr.aws/aws-appconfig/aws-appconfig-agent:2.x'), + image: ecs.ContainerImage.fromRegistry( + 'public.ecr.aws/aws-appconfig/aws-appconfig-agent:2.x', + ), essential: false, logging: AwsLogDriver.awsLogs({ logGroup: appLogGroup, @@ -129,13 +177,18 @@ export class DeploymentStack extends Stack { portMappings: [{ containerPort: 2772 }], }); - service.taskDefinition.addToTaskRolePolicy(new PolicyStatement({ - actions: ['sts:AssumeRole'], - resources: [props!.appConfigRoleArn!], - })); + service.taskDefinition.addToTaskRolePolicy( + new PolicyStatement({ + actions: ['sts:AssumeRole'], + resources: [props!.appConfigRoleArn!], + }), + ); } - service.service.connections.allowTo(db, Port.tcp(db.clusterEndpoint.port)); + service.service.connections.allowTo( + db, + ec2.Port.tcp(db.clusterEndpoint.port), + ); this.apiUrl = new CfnOutput(this, 'endpointUrl', { value: `http://${service.listener.loadBalancer.loadBalancerDnsName}`, diff --git a/examples/cdk-application-pipeline/infrastructure/test/__snapshots__/deployment.test.ts.snap b/examples/cdk-application-pipeline/infrastructure/test/__snapshots__/deployment.test.ts.snap index 49f9ff3..4dc7986 100644 --- a/examples/cdk-application-pipeline/infrastructure/test/__snapshots__/deployment.test.ts.snap +++ b/examples/cdk-application-pipeline/infrastructure/test/__snapshots__/deployment.test.ts.snap @@ -1799,14 +1799,14 @@ exports[`Deployment with AppConfig Snapshot 1`] = ` "jdbc:mysql://", { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Address", ], }, ":", { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, @@ -2070,19 +2070,67 @@ exports[`Deployment with AppConfig Snapshot 1`] = ` "Type": "AWS::Logs::LogGroup", "UpdateReplacePolicy": "Delete", }, - "AuroraCluster23D869C0": { + "AuroraSecret41E6E877": { + "DeletionPolicy": "Delete", + "Properties": { + "Description": { + "Fn::Join": [ + "", + [ + "Generated by the CDK for stack: ", + { + "Ref": "AWS::StackName", + }, + ], + ], + }, + "GenerateSecretString": { + "ExcludeCharacters": " %+~\`#$&*()|[]{}:;<>?!'/@"\\", + "GenerateStringKey": "password", + "PasswordLength": 30, + "SecretStringTemplate": "{"username":"fruitapi"}", + }, + "Name": "teststack-DB", + }, + "Type": "AWS::SecretsManager::Secret", + "UpdateReplacePolicy": "Delete", + }, + "AuroraSecretAttachment65089D67": { + "Properties": { + "SecretId": { + "Ref": "AuroraSecret41E6E877", + }, + "TargetId": { + "Ref": "DatabaseB269D8BB", + }, + "TargetType": "AWS::RDS::DBCluster", + }, + "Type": "AWS::SecretsManager::SecretTargetAttachment", + }, + "ClusterEB0386A7": { + "Properties": { + "ClusterName": "teststack", + "ClusterSettings": [ + { + "Name": "containerInsights", + "Value": "enabled", + }, + ], + }, + "Type": "AWS::ECS::Cluster", + }, + "DatabaseB269D8BB": { "DeletionPolicy": "Snapshot", "Properties": { "CopyTagsToSnapshot": true, "DBClusterIdentifier": "teststack", - "DBClusterParameterGroupName": "default.aurora-mysql5.7", + "DBClusterParameterGroupName": "default.aurora-mysql8.0", "DBSubnetGroupName": { - "Ref": "AuroraClusterSubnetsF3E9E6AD", + "Ref": "DatabaseSubnets56F17B9A", }, "DatabaseName": "fruits", - "DeletionProtection": false, "Engine": "aurora-mysql", - "EngineMode": "serverless", + "EngineVersion": "8.0.mysql_aurora.3.07.1", "MasterUserPassword": { "Fn::Join": [ "", @@ -2107,11 +2155,15 @@ exports[`Deployment with AppConfig Snapshot 1`] = ` ], ], }, + "ServerlessV2ScalingConfiguration": { + "MaxCapacity": 2, + "MinCapacity": 0.5, + }, "StorageEncrypted": true, "VpcSecurityGroupIds": [ { "Fn::GetAtt": [ - "AuroraClusterSecurityGroupD85BF9CB", + "DatabaseSecurityGroup5C91FDCB", "GroupId", ], }, @@ -2120,7 +2172,7 @@ exports[`Deployment with AppConfig Snapshot 1`] = ` "Type": "AWS::RDS::DBCluster", "UpdateReplacePolicy": "Snapshot", }, - "AuroraClusterSecurityGroupD85BF9CB": { + "DatabaseSecurityGroup5C91FDCB": { "Properties": { "GroupDescription": "RDS security group", "SecurityGroupEgress": [ @@ -2136,18 +2188,18 @@ exports[`Deployment with AppConfig Snapshot 1`] = ` }, "Type": "AWS::EC2::SecurityGroup", }, - "AuroraClusterSecurityGroupfromTestStackApiServiceSecurityGroup56AF4AC5IndirectPort7B73ECC0": { + "DatabaseSecurityGroupfromTestStackApiServiceSecurityGroup56AF4AC5IndirectPort605EA7CC": { "Properties": { "Description": "from TestStackApiServiceSecurityGroup56AF4AC5:{IndirectPort}", "FromPort": { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, "GroupId": { "Fn::GetAtt": [ - "AuroraClusterSecurityGroupD85BF9CB", + "DatabaseSecurityGroup5C91FDCB", "GroupId", ], }, @@ -2160,16 +2212,16 @@ exports[`Deployment with AppConfig Snapshot 1`] = ` }, "ToPort": { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, }, "Type": "AWS::EC2::SecurityGroupIngress", }, - "AuroraClusterSubnetsF3E9E6AD": { + "DatabaseSubnets56F17B9A": { "Properties": { - "DBSubnetGroupDescription": "Subnets for AuroraCluster database", + "DBSubnetGroupDescription": "Subnets for Database database", "SubnetIds": [ { "Ref": "VpcPrivateSubnet1Subnet536B997A", @@ -2184,55 +2236,27 @@ exports[`Deployment with AppConfig Snapshot 1`] = ` }, "Type": "AWS::RDS::DBSubnetGroup", }, - "AuroraSecret41E6E877": { + "Databasewriter2462CC03": { "DeletionPolicy": "Delete", + "DependsOn": [ + "VpcPrivateSubnet1DefaultRouteBE02A9ED", + "VpcPrivateSubnet1RouteTableAssociation70C59FA6", + "VpcPrivateSubnet2DefaultRoute060D2087", + "VpcPrivateSubnet2RouteTableAssociationA89CAD56", + "VpcPrivateSubnet3DefaultRoute94B74F0D", + "VpcPrivateSubnet3RouteTableAssociation16BDDC43", + ], "Properties": { - "Description": { - "Fn::Join": [ - "", - [ - "Generated by the CDK for stack: ", - { - "Ref": "AWS::StackName", - }, - ], - ], + "DBClusterIdentifier": { + "Ref": "DatabaseB269D8BB", }, - "GenerateSecretString": { - "ExcludeCharacters": " %+~\`#$&*()|[]{}:;<>?!'/@"\\", - "GenerateStringKey": "password", - "PasswordLength": 30, - "SecretStringTemplate": "{"username":"fruitapi"}", - }, - "Name": "teststack-DB", + "DBInstanceClass": "db.serverless", + "Engine": "aurora-mysql", + "PromotionTier": 0, }, - "Type": "AWS::SecretsManager::Secret", + "Type": "AWS::RDS::DBInstance", "UpdateReplacePolicy": "Delete", }, - "AuroraSecretAttachment65089D67": { - "Properties": { - "SecretId": { - "Ref": "AuroraSecret41E6E877", - }, - "TargetId": { - "Ref": "AuroraCluster23D869C0", - }, - "TargetType": "AWS::RDS::DBCluster", - }, - "Type": "AWS::SecretsManager::SecretTargetAttachment", - }, - "ClusterEB0386A7": { - "Properties": { - "ClusterName": "teststack", - "ClusterSettings": [ - { - "Name": "containerInsights", - "Value": "enabled", - }, - ], - }, - "Type": "AWS::ECS::Cluster", - }, "Vpc8378EB38": { "Properties": { "CidrBlock": "10.0.0.0/16", @@ -4689,14 +4713,14 @@ exports[`Deployment without AppConfig Snapshot 1`] = ` "jdbc:mysql://", { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Address", ], }, ":", { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, @@ -4899,19 +4923,67 @@ exports[`Deployment without AppConfig Snapshot 1`] = ` "Type": "AWS::Logs::LogGroup", "UpdateReplacePolicy": "Delete", }, - "AuroraCluster23D869C0": { + "AuroraSecret41E6E877": { + "DeletionPolicy": "Delete", + "Properties": { + "Description": { + "Fn::Join": [ + "", + [ + "Generated by the CDK for stack: ", + { + "Ref": "AWS::StackName", + }, + ], + ], + }, + "GenerateSecretString": { + "ExcludeCharacters": " %+~\`#$&*()|[]{}:;<>?!'/@"\\", + "GenerateStringKey": "password", + "PasswordLength": 30, + "SecretStringTemplate": "{"username":"fruitapi"}", + }, + "Name": "teststack-DB", + }, + "Type": "AWS::SecretsManager::Secret", + "UpdateReplacePolicy": "Delete", + }, + "AuroraSecretAttachment65089D67": { + "Properties": { + "SecretId": { + "Ref": "AuroraSecret41E6E877", + }, + "TargetId": { + "Ref": "DatabaseB269D8BB", + }, + "TargetType": "AWS::RDS::DBCluster", + }, + "Type": "AWS::SecretsManager::SecretTargetAttachment", + }, + "ClusterEB0386A7": { + "Properties": { + "ClusterName": "teststack", + "ClusterSettings": [ + { + "Name": "containerInsights", + "Value": "enabled", + }, + ], + }, + "Type": "AWS::ECS::Cluster", + }, + "DatabaseB269D8BB": { "DeletionPolicy": "Snapshot", "Properties": { "CopyTagsToSnapshot": true, "DBClusterIdentifier": "teststack", - "DBClusterParameterGroupName": "default.aurora-mysql5.7", + "DBClusterParameterGroupName": "default.aurora-mysql8.0", "DBSubnetGroupName": { - "Ref": "AuroraClusterSubnetsF3E9E6AD", + "Ref": "DatabaseSubnets56F17B9A", }, "DatabaseName": "fruits", - "DeletionProtection": false, "Engine": "aurora-mysql", - "EngineMode": "serverless", + "EngineVersion": "8.0.mysql_aurora.3.07.1", "MasterUserPassword": { "Fn::Join": [ "", @@ -4936,11 +5008,15 @@ exports[`Deployment without AppConfig Snapshot 1`] = ` ], ], }, + "ServerlessV2ScalingConfiguration": { + "MaxCapacity": 2, + "MinCapacity": 0.5, + }, "StorageEncrypted": true, "VpcSecurityGroupIds": [ { "Fn::GetAtt": [ - "AuroraClusterSecurityGroupD85BF9CB", + "DatabaseSecurityGroup5C91FDCB", "GroupId", ], }, @@ -4949,7 +5025,7 @@ exports[`Deployment without AppConfig Snapshot 1`] = ` "Type": "AWS::RDS::DBCluster", "UpdateReplacePolicy": "Snapshot", }, - "AuroraClusterSecurityGroupD85BF9CB": { + "DatabaseSecurityGroup5C91FDCB": { "Properties": { "GroupDescription": "RDS security group", "SecurityGroupEgress": [ @@ -4965,18 +5041,18 @@ exports[`Deployment without AppConfig Snapshot 1`] = ` }, "Type": "AWS::EC2::SecurityGroup", }, - "AuroraClusterSecurityGroupfromTestStackApiServiceSecurityGroup56AF4AC5IndirectPort7B73ECC0": { + "DatabaseSecurityGroupfromTestStackApiServiceSecurityGroup56AF4AC5IndirectPort605EA7CC": { "Properties": { "Description": "from TestStackApiServiceSecurityGroup56AF4AC5:{IndirectPort}", "FromPort": { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, "GroupId": { "Fn::GetAtt": [ - "AuroraClusterSecurityGroupD85BF9CB", + "DatabaseSecurityGroup5C91FDCB", "GroupId", ], }, @@ -4989,16 +5065,16 @@ exports[`Deployment without AppConfig Snapshot 1`] = ` }, "ToPort": { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, }, "Type": "AWS::EC2::SecurityGroupIngress", }, - "AuroraClusterSubnetsF3E9E6AD": { + "DatabaseSubnets56F17B9A": { "Properties": { - "DBSubnetGroupDescription": "Subnets for AuroraCluster database", + "DBSubnetGroupDescription": "Subnets for Database database", "SubnetIds": [ { "Ref": "VpcPrivateSubnet1Subnet536B997A", @@ -5013,55 +5089,27 @@ exports[`Deployment without AppConfig Snapshot 1`] = ` }, "Type": "AWS::RDS::DBSubnetGroup", }, - "AuroraSecret41E6E877": { + "Databasewriter2462CC03": { "DeletionPolicy": "Delete", + "DependsOn": [ + "VpcPrivateSubnet1DefaultRouteBE02A9ED", + "VpcPrivateSubnet1RouteTableAssociation70C59FA6", + "VpcPrivateSubnet2DefaultRoute060D2087", + "VpcPrivateSubnet2RouteTableAssociationA89CAD56", + "VpcPrivateSubnet3DefaultRoute94B74F0D", + "VpcPrivateSubnet3RouteTableAssociation16BDDC43", + ], "Properties": { - "Description": { - "Fn::Join": [ - "", - [ - "Generated by the CDK for stack: ", - { - "Ref": "AWS::StackName", - }, - ], - ], + "DBClusterIdentifier": { + "Ref": "DatabaseB269D8BB", }, - "GenerateSecretString": { - "ExcludeCharacters": " %+~\`#$&*()|[]{}:;<>?!'/@"\\", - "GenerateStringKey": "password", - "PasswordLength": 30, - "SecretStringTemplate": "{"username":"fruitapi"}", - }, - "Name": "teststack-DB", + "DBInstanceClass": "db.serverless", + "Engine": "aurora-mysql", + "PromotionTier": 0, }, - "Type": "AWS::SecretsManager::Secret", + "Type": "AWS::RDS::DBInstance", "UpdateReplacePolicy": "Delete", }, - "AuroraSecretAttachment65089D67": { - "Properties": { - "SecretId": { - "Ref": "AuroraSecret41E6E877", - }, - "TargetId": { - "Ref": "AuroraCluster23D869C0", - }, - "TargetType": "AWS::RDS::DBCluster", - }, - "Type": "AWS::SecretsManager::SecretTargetAttachment", - }, - "ClusterEB0386A7": { - "Properties": { - "ClusterName": "teststack", - "ClusterSettings": [ - { - "Name": "containerInsights", - "Value": "enabled", - }, - ], - }, - "Type": "AWS::ECS::Cluster", - }, "Vpc8378EB38": { "Properties": { "CidrBlock": "10.0.0.0/16", @@ -8027,14 +8075,14 @@ exports[`cdk-nag Snapshot 1`] = ` "jdbc:mysql://", { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Address", ], }, ":", { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, @@ -8251,7 +8299,66 @@ exports[`cdk-nag Snapshot 1`] = ` "Type": "AWS::Logs::LogGroup", "UpdateReplacePolicy": "Delete", }, - "AuroraCluster23D869C0": { + "AuroraSecret41E6E877": { + "DeletionPolicy": "Delete", + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-SMG4", + "reason": "Dont require secret rotation", + }, + ], + }, + }, + "Properties": { + "Description": { + "Fn::Join": [ + "", + [ + "Generated by the CDK for stack: ", + { + "Ref": "AWS::StackName", + }, + ], + ], + }, + "GenerateSecretString": { + "ExcludeCharacters": " %+~\`#$&*()|[]{}:;<>?!'/@"\\", + "GenerateStringKey": "password", + "PasswordLength": 30, + "SecretStringTemplate": "{"username":"fruitapi"}", + }, + "Name": "teststack-DB", + }, + "Type": "AWS::SecretsManager::Secret", + "UpdateReplacePolicy": "Delete", + }, + "AuroraSecretAttachment65089D67": { + "Properties": { + "SecretId": { + "Ref": "AuroraSecret41E6E877", + }, + "TargetId": { + "Ref": "DatabaseB269D8BB", + }, + "TargetType": "AWS::RDS::DBCluster", + }, + "Type": "AWS::SecretsManager::SecretTargetAttachment", + }, + "ClusterEB0386A7": { + "Properties": { + "ClusterName": "teststack", + "ClusterSettings": [ + { + "Name": "containerInsights", + "Value": "enabled", + }, + ], + }, + "Type": "AWS::ECS::Cluster", + }, + "DatabaseB269D8BB": { "DeletionPolicy": "Snapshot", "Metadata": { "cdk_nag": { @@ -8282,14 +8389,13 @@ exports[`cdk-nag Snapshot 1`] = ` "Properties": { "CopyTagsToSnapshot": true, "DBClusterIdentifier": "teststack", - "DBClusterParameterGroupName": "default.aurora-mysql5.7", + "DBClusterParameterGroupName": "default.aurora-mysql8.0", "DBSubnetGroupName": { - "Ref": "AuroraClusterSubnetsF3E9E6AD", + "Ref": "DatabaseSubnets56F17B9A", }, "DatabaseName": "fruits", - "DeletionProtection": false, "Engine": "aurora-mysql", - "EngineMode": "serverless", + "EngineVersion": "8.0.mysql_aurora.3.07.1", "MasterUserPassword": { "Fn::Join": [ "", @@ -8314,11 +8420,15 @@ exports[`cdk-nag Snapshot 1`] = ` ], ], }, + "ServerlessV2ScalingConfiguration": { + "MaxCapacity": 2, + "MinCapacity": 0.5, + }, "StorageEncrypted": true, "VpcSecurityGroupIds": [ { "Fn::GetAtt": [ - "AuroraClusterSecurityGroupD85BF9CB", + "DatabaseSecurityGroup5C91FDCB", "GroupId", ], }, @@ -8327,7 +8437,7 @@ exports[`cdk-nag Snapshot 1`] = ` "Type": "AWS::RDS::DBCluster", "UpdateReplacePolicy": "Snapshot", }, - "AuroraClusterSecurityGroupD85BF9CB": { + "DatabaseSecurityGroup5C91FDCB": { "Properties": { "GroupDescription": "RDS security group", "SecurityGroupEgress": [ @@ -8343,18 +8453,18 @@ exports[`cdk-nag Snapshot 1`] = ` }, "Type": "AWS::EC2::SecurityGroup", }, - "AuroraClusterSecurityGroupfromTestStackApiServiceSecurityGroup56AF4AC5IndirectPort7B73ECC0": { + "DatabaseSecurityGroupfromTestStackApiServiceSecurityGroup56AF4AC5IndirectPort605EA7CC": { "Properties": { "Description": "from TestStackApiServiceSecurityGroup56AF4AC5:{IndirectPort}", "FromPort": { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, "GroupId": { "Fn::GetAtt": [ - "AuroraClusterSecurityGroupD85BF9CB", + "DatabaseSecurityGroup5C91FDCB", "GroupId", ], }, @@ -8367,16 +8477,16 @@ exports[`cdk-nag Snapshot 1`] = ` }, "ToPort": { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, }, "Type": "AWS::EC2::SecurityGroupIngress", }, - "AuroraClusterSubnetsF3E9E6AD": { + "DatabaseSubnets56F17B9A": { "Properties": { - "DBSubnetGroupDescription": "Subnets for AuroraCluster database", + "DBSubnetGroupDescription": "Subnets for Database database", "SubnetIds": [ { "Ref": "VpcPrivateSubnet1Subnet536B997A", @@ -8391,65 +8501,27 @@ exports[`cdk-nag Snapshot 1`] = ` }, "Type": "AWS::RDS::DBSubnetGroup", }, - "AuroraSecret41E6E877": { + "Databasewriter2462CC03": { "DeletionPolicy": "Delete", - "Metadata": { - "cdk_nag": { - "rules_to_suppress": [ - { - "id": "AwsSolutions-SMG4", - "reason": "Dont require secret rotation", - }, - ], - }, - }, + "DependsOn": [ + "VpcPrivateSubnet1DefaultRouteBE02A9ED", + "VpcPrivateSubnet1RouteTableAssociation70C59FA6", + "VpcPrivateSubnet2DefaultRoute060D2087", + "VpcPrivateSubnet2RouteTableAssociationA89CAD56", + "VpcPrivateSubnet3DefaultRoute94B74F0D", + "VpcPrivateSubnet3RouteTableAssociation16BDDC43", + ], "Properties": { - "Description": { - "Fn::Join": [ - "", - [ - "Generated by the CDK for stack: ", - { - "Ref": "AWS::StackName", - }, - ], - ], + "DBClusterIdentifier": { + "Ref": "DatabaseB269D8BB", }, - "GenerateSecretString": { - "ExcludeCharacters": " %+~\`#$&*()|[]{}:;<>?!'/@"\\", - "GenerateStringKey": "password", - "PasswordLength": 30, - "SecretStringTemplate": "{"username":"fruitapi"}", - }, - "Name": "teststack-DB", + "DBInstanceClass": "db.serverless", + "Engine": "aurora-mysql", + "PromotionTier": 0, }, - "Type": "AWS::SecretsManager::Secret", + "Type": "AWS::RDS::DBInstance", "UpdateReplacePolicy": "Delete", }, - "AuroraSecretAttachment65089D67": { - "Properties": { - "SecretId": { - "Ref": "AuroraSecret41E6E877", - }, - "TargetId": { - "Ref": "AuroraCluster23D869C0", - }, - "TargetType": "AWS::RDS::DBCluster", - }, - "Type": "AWS::SecretsManager::SecretTargetAttachment", - }, - "ClusterEB0386A7": { - "Properties": { - "ClusterName": "teststack", - "ClusterSettings": [ - { - "Name": "containerInsights", - "Value": "enabled", - }, - ], - }, - "Type": "AWS::ECS::Cluster", - }, "Vpc8378EB38": { "Properties": { "CidrBlock": "10.0.0.0/16", diff --git a/examples/cdk-application-pipeline/infrastructure/test/deployment.test.ts b/examples/cdk-application-pipeline/infrastructure/test/deployment.test.ts index 283e6d2..1517eb3 100644 --- a/examples/cdk-application-pipeline/infrastructure/test/deployment.test.ts +++ b/examples/cdk-application-pipeline/infrastructure/test/deployment.test.ts @@ -51,7 +51,7 @@ describe('cdk-nag', () => { // Suppress CDK-NAG for RDS Serverless NagSuppressions.addResourceSuppressionsByPath( stack, - `/${stack.stackName}/AuroraCluster/Resource`, + `/${stack.stackName}/Database/Resource`, [ { id: 'AwsSolutions-RDS6', reason: 'IAM authentication not supported on Serverless v1' }, { id: 'AwsSolutions-RDS10', reason: 'Disable delete protection to simplify cleanup of Reference Implementation' }, diff --git a/examples/cdk-application-pipeline/package-lock.json b/examples/cdk-application-pipeline/package-lock.json index 8ebce11..c771f67 100644 --- a/examples/cdk-application-pipeline/package-lock.json +++ b/examples/cdk-application-pipeline/package-lock.json @@ -15,25 +15,25 @@ "@aws-sdk/client-codepipeline": "^3.682.0", "@aws-sdk/client-ecr": "^3.682.0", "@aws-sdk/client-iam": "^3.682.0", - "@aws-sdk/client-s3": "^3.682.0", + "@aws-sdk/client-s3": "^3.685.0", "@aws-sdk/client-sts": "^3.682.0", - "@aws-sdk/credential-providers": "^3.682.0", + "@aws-sdk/credential-providers": "^3.685.0", "@aws-sdk/shared-ini-file-loader": "^3.374.0", "@cdklabs/cdk-ecs-codedeploy": "^0.0.310", "@types/aws-lambda": "^8.10.145", "@types/prompts": "^2.4.9", - "aws-cdk-lib": "^2.165.0", + "aws-cdk-lib": "^2.166.0", "constructs": "^10.4.2", "prompts": "^2.4.2", "yaml": "^2.6.0" }, "devDependencies": { "@types/jest": "^29.5", - "@types/node": "^20.17.5", + "@types/node": "^20.17.6", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "aws-cdk": "^2.165.0", - "cdk-nag": "^2.31.0", + "cdk-nag": "^2.31.2", "esbuild": "^0.20.2", "eslint": "^8.57.1", "eslint-import-resolver-node": "^0.3.9", @@ -510,9 +510,9 @@ } }, "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.682.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.682.0.tgz", - "integrity": "sha512-BD8PPPk3+ZzFqCJSPraoXkgRcPTtjguXtyDYsyBMzFofWmN4YeswXSavZVAC354W98mkffDaXBvieyqu1Y9fKA==", + "version": "3.685.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.685.0.tgz", + "integrity": "sha512-4h+aw0pUEOVP77TpF1ec9AX0mzotsiw2alXfh+P0t+43eg2EjaKRftRpNXyt5XmUPws+wsH10uEL4CzSZo1sxQ==", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -665,9 +665,9 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.682.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.682.0.tgz", - "integrity": "sha512-gn8yPhOmExhqRENnR/vKvsbTw9jaRPbfNE8fQ2j91ejXhpj632QDNdobY8TxxPm2UEW2ISAVM55r2/UPl0YP1Q==", + "version": "3.685.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.685.0.tgz", + "integrity": "sha512-ClvMeQHbLhWkpxnVymo4qWS5/yZcPXjorDbSday3joCWYWCSHTO409nWd+jx6eA4MKT/EY/uJ6ZBJRFfByKLuA==", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", @@ -683,11 +683,11 @@ "@aws-sdk/middleware-location-constraint": "3.679.0", "@aws-sdk/middleware-logger": "3.679.0", "@aws-sdk/middleware-recursion-detection": "3.679.0", - "@aws-sdk/middleware-sdk-s3": "3.682.0", + "@aws-sdk/middleware-sdk-s3": "3.685.0", "@aws-sdk/middleware-ssec": "3.679.0", "@aws-sdk/middleware-user-agent": "3.682.0", "@aws-sdk/region-config-resolver": "3.679.0", - "@aws-sdk/signature-v4-multi-region": "3.682.0", + "@aws-sdk/signature-v4-multi-region": "3.685.0", "@aws-sdk/types": "3.679.0", "@aws-sdk/util-endpoints": "3.679.0", "@aws-sdk/util-user-agent-browser": "3.679.0", @@ -904,11 +904,11 @@ } }, "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.682.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.682.0.tgz", - "integrity": "sha512-V+y4qUQtc0kTnNR7u5LwnZn8EZk2pjdNX+84MwD9VjXekqbXikADu06Mj93kVGVW+qgqtNMvJ8PpiI3EaaxC7A==", + "version": "3.685.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.685.0.tgz", + "integrity": "sha512-qw9s09JFhJxEkmbo1gn94pAtyLHSx8YBX2qqrL6v3BdsJbP2fnRJMMssGMGR4jPyhklh5TSgZo0FzflbqJU8sw==", "dependencies": { - "@aws-sdk/client-cognito-identity": "3.682.0", + "@aws-sdk/client-cognito-identity": "3.685.0", "@aws-sdk/types": "3.679.0", "@smithy/property-provider": "^3.1.7", "@smithy/types": "^3.5.0", @@ -1053,15 +1053,15 @@ } }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.682.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.682.0.tgz", - "integrity": "sha512-vLBdUlTISEXVKYFFO665ajC0U0RdXFx21fwTHiN2g4edFH++di2XCJ8/Y34bu09z9bV/rwFT2jn41iAVWasNKg==", + "version": "3.685.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.685.0.tgz", + "integrity": "sha512-pIXNNwPG2KnzjGYYbADquEkROuKxAJxuWt87TJO7LCFqKwb5l6h0Mc7yc4j13zxOVd/EhXD0VsPeqnobDklUoQ==", "dependencies": { - "@aws-sdk/client-cognito-identity": "3.682.0", + "@aws-sdk/client-cognito-identity": "3.685.0", "@aws-sdk/client-sso": "3.682.0", "@aws-sdk/client-sts": "3.682.0", "@aws-sdk/core": "3.679.0", - "@aws-sdk/credential-provider-cognito-identity": "3.682.0", + "@aws-sdk/credential-provider-cognito-identity": "3.685.0", "@aws-sdk/credential-provider-env": "3.679.0", "@aws-sdk/credential-provider-http": "3.679.0", "@aws-sdk/credential-provider-ini": "3.682.0", @@ -1186,9 +1186,9 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.682.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.682.0.tgz", - "integrity": "sha512-Tqndx8elRD4xDR8f5Cng6jpZ/odcm1ZTOtGRFMzHgOCij4BeMf4+/+ecQScobcrAZpUTCUTCzaTvdCdJw8MYJA==", + "version": "3.685.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.685.0.tgz", + "integrity": "sha512-C4w92b3A99NbghrA2Ssw6y1RbDF3I3Bgzi2Izh0pXgyIoDiX0xs9bUs/FGYLK4uepYr78DAZY8DwEpzjWIXkSA==", "dependencies": { "@aws-sdk/core": "3.679.0", "@aws-sdk/types": "3.679.0", @@ -1292,11 +1292,11 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.682.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.682.0.tgz", - "integrity": "sha512-y7RAQSCb9pH8wCX5We9UXfiqPVwBLLvSljhuXC31mibHmYaZnpNEwHiQlRNQPblyaNpiKnXXQ0H3Ns3FDyDYdQ==", + "version": "3.685.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.685.0.tgz", + "integrity": "sha512-IHLwuAZGqfUWVrNqw0ugnBa7iL8uBP4x6A7bfBDXRXWCWjUCed/1/D//0lKDHwpFkV74fGW6KoBacnWSUlXmwA==", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.682.0", + "@aws-sdk/middleware-sdk-s3": "3.685.0", "@aws-sdk/types": "3.679.0", "@smithy/protocol-http": "^4.1.4", "@smithy/signature-v4": "^4.2.0", @@ -5329,9 +5329,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.17.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.5.tgz", - "integrity": "sha512-n8FYY/pRxu496441gIcAQFZPKXbhsd6VZygcq+PTSZ75eMh/Ke0hCAROdUa21qiFqKNsPPYic46yXDO1JGiPBQ==", + "version": "20.17.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.6.tgz", + "integrity": "sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==", "dependencies": { "undici-types": "~6.19.2" } @@ -5940,9 +5940,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.165.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.165.0.tgz", - "integrity": "sha512-jCIUcaNDhAO/Yxik29L2LJiXkZImbEOlw/dWwhlcIx1eJyxUW+IWuMbGjXEMg8/QH56FBA5TLkZpTTsRstHS/Q==", + "version": "2.166.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.166.0.tgz", + "integrity": "sha512-FAsIz/CpczbMrcShgvTWNp3kcGN6IDojJWNLqHioTRsTekcyN3OPmKvQJXUNWL0fnhTd8biFXC2esg6kM19xZw==", "bundleDependencies": [ "@balena/dockerignore", "case", @@ -6401,7 +6401,8 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/bowser": { "version": "2.11.0", @@ -6520,6 +6521,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -6721,9 +6723,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001676", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001676.tgz", - "integrity": "sha512-Qz6zwGCiPghQXGJvgQAem79esjitvJ+CxSbSQkW9H/UX5hg8XM88d4lp2W+MEQ81j+Hip58Il+jGVdazk1z9cw==", + "version": "1.0.30001677", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz", + "integrity": "sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==", "dev": true, "funding": [ { @@ -6741,9 +6743,9 @@ ] }, "node_modules/cdk-nag": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/cdk-nag/-/cdk-nag-2.31.0.tgz", - "integrity": "sha512-/f2K4SUJp1hZKLjhQvJxQGc/qQw0JguJL21B+IqVNkKgrAXFuIjDlzSqQ6neZgJWQUP+zr1dA1KxUy9/QFhplA==", + "version": "2.31.2", + "resolved": "https://registry.npmjs.org/cdk-nag/-/cdk-nag-2.31.2.tgz", + "integrity": "sha512-b1VfiDtfWkTXGzsLLsMk5+gNapZOgY+alNQpf6FsBfIIYWsSsPeZ7S0SqiKlEC+Kvta1k55MX7OPfJEYH8uDMA==", "dev": true, "peerDependencies": { "aws-cdk-lib": "^2.156.0", @@ -8833,6 +8835,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, "engines": { "node": ">= 4" } @@ -10514,6 +10517,7 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -12750,6 +12754,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "engines": { "node": ">=6" } @@ -13314,6 +13319,7 @@ "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, "bin": { "semver": "bin/semver.js" }, diff --git a/examples/cdk-application-pipeline/package.json b/examples/cdk-application-pipeline/package.json index b9af00c..179c35f 100644 --- a/examples/cdk-application-pipeline/package.json +++ b/examples/cdk-application-pipeline/package.json @@ -11,11 +11,11 @@ }, "devDependencies": { "@types/jest": "^29.5", - "@types/node": "^20.17.5", + "@types/node": "^20.17.6", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "aws-cdk": "^2.165.0", - "cdk-nag": "^2.31.0", + "cdk-nag": "^2.31.2", "esbuild": "^0.20.2", "eslint": "^8.57.1", "eslint-import-resolver-node": "^0.3.9", @@ -38,14 +38,14 @@ "@aws-sdk/client-codepipeline": "^3.682.0", "@aws-sdk/client-ecr": "^3.682.0", "@aws-sdk/client-iam": "^3.682.0", - "@aws-sdk/client-s3": "^3.682.0", + "@aws-sdk/client-s3": "^3.685.0", "@aws-sdk/client-sts": "^3.682.0", - "@aws-sdk/credential-providers": "^3.682.0", + "@aws-sdk/credential-providers": "^3.685.0", "@aws-sdk/shared-ini-file-loader": "^3.374.0", "@cdklabs/cdk-ecs-codedeploy": "^0.0.310", "@types/aws-lambda": "^8.10.145", "@types/prompts": "^2.4.9", - "aws-cdk-lib": "^2.165.0", + "aws-cdk-lib": "^2.166.0", "constructs": "^10.4.2", "prompts": "^2.4.2", "yaml": "^2.6.0" diff --git a/examples/codecatalyst-application-pipeline/infrastructure/src/deployment.ts b/examples/codecatalyst-application-pipeline/infrastructure/src/deployment.ts index 131d7bd..8e4aafb 100644 --- a/examples/codecatalyst-application-pipeline/infrastructure/src/deployment.ts +++ b/examples/codecatalyst-application-pipeline/infrastructure/src/deployment.ts @@ -1,14 +1,30 @@ -import { ApplicationLoadBalancedCodeDeployedFargateService } from '@cdklabs/cdk-ecs-codedeploy'; -import { CfnOutput, Duration, RemovalPolicy, Stack, StackProps } from 'aws-cdk-lib'; -import { EcsDeploymentConfig, IEcsDeploymentConfig } from 'aws-cdk-lib/aws-codedeploy'; +import { + CfnOutput, + Duration, + RemovalPolicy, + Stack, + StackProps, +} from 'aws-cdk-lib'; +import { + IEcsDeploymentConfig, + EcsDeploymentConfig, +} from 'aws-cdk-lib/aws-codedeploy'; import * as ec2 from 'aws-cdk-lib/aws-ec2'; -import { FlowLog, FlowLogResourceType, Port } from 'aws-cdk-lib/aws-ec2'; -import * as ecs from 'aws-cdk-lib/aws-ecs'; +import { FlowLog, FlowLogResourceType } from 'aws-cdk-lib/aws-ec2'; import { AssetImage, AwsLogDriver, Secret } from 'aws-cdk-lib/aws-ecs'; import { PolicyStatement } from 'aws-cdk-lib/aws-iam'; import { LogGroup, RetentionDays } from 'aws-cdk-lib/aws-logs'; -import { Credentials, DatabaseClusterEngine, DatabaseSecret, ServerlessCluster } from 'aws-cdk-lib/aws-rds'; +import { + AuroraMysqlEngineVersion, + ClusterInstance, + Credentials, + DatabaseCluster, + DatabaseClusterEngine, + DatabaseSecret, +} from 'aws-cdk-lib/aws-rds'; import { Construct } from 'constructs'; +import { ApplicationLoadBalancedCodeDeployedFargateService } from '@cdklabs/cdk-ecs-codedeploy'; +import * as ecs from 'aws-cdk-lib/aws-ecs'; export interface DeploymentProps extends StackProps { deploymentConfigName?: string; @@ -24,25 +40,35 @@ export class DeploymentStack extends Stack { const image = new AssetImage('.', { target: 'build' }); - const appName = Stack.of(this).stackName.toLowerCase().replace(`-${Stack.of(this).region}-`, '-'); + const appName = Stack.of(this) + .stackName.toLowerCase() + .replace(`-${Stack.of(this).region}-`, '-'); const vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 3, natGateways: props?.natGateways, }); - new FlowLog(this, 'VpcFlowLog', { resourceType: FlowLogResourceType.fromVpc(vpc) }); + new FlowLog(this, 'VpcFlowLog', { + resourceType: FlowLogResourceType.fromVpc(vpc), + }); const dbName = 'fruits'; const dbSecret = new DatabaseSecret(this, 'AuroraSecret', { username: 'fruitapi', secretName: `${appName}-DB`, }); - const db = new ServerlessCluster(this, 'AuroraCluster', { - engine: DatabaseClusterEngine.AURORA_MYSQL, - vpc, + + const db = new DatabaseCluster(this, 'Database', { + engine: DatabaseClusterEngine.auroraMysql({ + version: AuroraMysqlEngineVersion.VER_3_07_1, + }), credentials: Credentials.fromSecret(dbSecret), + writer: ClusterInstance.serverlessV2('writer'), defaultDatabaseName: dbName, - deletionProtection: false, + serverlessV2MaxCapacity: 2, + serverlessV2MinCapacity: 0.5, + vpc, clusterIdentifier: appName, + storageEncrypted: true, }); const cluster = new ecs.Cluster(this, 'Cluster', { @@ -57,64 +83,86 @@ export class DeploymentStack extends Stack { }); let deploymentConfig: IEcsDeploymentConfig | undefined = undefined; if (props?.deploymentConfigName) { - deploymentConfig = EcsDeploymentConfig.fromEcsDeploymentConfigName(this, 'DeploymentConfig', props.deploymentConfigName); + deploymentConfig = EcsDeploymentConfig.fromEcsDeploymentConfigName( + this, + 'DeploymentConfig', + props.deploymentConfigName, + ); } - const appConfigEnabled = props?.appConfigRoleArn !== undefined && props.appConfigRoleArn.length > 0; - const service = new ApplicationLoadBalancedCodeDeployedFargateService(this, 'Api', { - cluster, - capacityProviderStrategies: [ - { - capacityProvider: 'FARGATE_SPOT', - weight: 1, + const appConfigEnabled = + props?.appConfigRoleArn !== undefined && + props.appConfigRoleArn.length > 0; + const service = new ApplicationLoadBalancedCodeDeployedFargateService( + this, + 'Api', + { + cluster, + capacityProviderStrategies: [ + { + capacityProvider: 'FARGATE_SPOT', + weight: 1, + }, + ], + minHealthyPercent: 50, + maxHealthyPercent: 200, + desiredCount: 3, + cpu: 512, + memoryLimitMiB: 1024, + taskImageOptions: { + image, + containerName: 'api', + containerPort: 8080, + family: appName, + logDriver: AwsLogDriver.awsLogs({ + logGroup: appLogGroup, + streamPrefix: 'service', + }), + secrets: { + SPRING_DATASOURCE_USERNAME: Secret.fromSecretsManager( + dbSecret, + 'username', + ), + SPRING_DATASOURCE_PASSWORD: Secret.fromSecretsManager( + dbSecret, + 'password', + ), + }, + environment: { + SPRING_DATASOURCE_URL: `jdbc:mysql://${db.clusterEndpoint.hostname}:${db.clusterEndpoint.port}/${dbName}`, + APPCONFIG_AGENT_APPLICATION: + this.node.tryGetContext('workloadName'), + APPCONFIG_AGENT_ENVIRONMENT: + this.node.tryGetContext('environmentName'), + APPCONFIG_AGENT_ENABLED: appConfigEnabled.toString(), + }, }, - ], - minHealthyPercent: 50, - maxHealthyPercent: 200, - desiredCount: 3, - cpu: 512, - memoryLimitMiB: 1024, - taskImageOptions: { - image, - containerName: 'api', - containerPort: 8080, - family: appName, - logDriver: AwsLogDriver.awsLogs({ - logGroup: appLogGroup, - streamPrefix: 'service', - }), - secrets: { - SPRING_DATASOURCE_USERNAME: Secret.fromSecretsManager( dbSecret, 'username' ), - SPRING_DATASOURCE_PASSWORD: Secret.fromSecretsManager( dbSecret, 'password' ), - }, - environment: { - SPRING_DATASOURCE_URL: `jdbc:mysql://${db.clusterEndpoint.hostname}:${db.clusterEndpoint.port}/${dbName}`, - APPCONFIG_AGENT_APPLICATION: this.node.tryGetContext('workloadName'), - APPCONFIG_AGENT_ENVIRONMENT: this.node.tryGetContext('environmentName'), - APPCONFIG_AGENT_ENABLED: appConfigEnabled.toString(), + deregistrationDelay: Duration.seconds(5), + responseTimeAlarmThreshold: Duration.seconds(3), + targetHealthCheck: { + healthyThresholdCount: 2, + unhealthyThresholdCount: 2, + interval: Duration.seconds(60), + path: '/actuator/health', }, + deploymentConfig, + terminationWaitTime: Duration.minutes(5), + apiCanaryTimeout: Duration.seconds(5), + apiTestSteps: [ + { + name: 'getAll', + path: '/api/fruits', + jmesPath: 'length(@)', + expectedValue: 5, + }, + ], }, - deregistrationDelay: Duration.seconds(5), - responseTimeAlarmThreshold: Duration.seconds(3), - targetHealthCheck: { - healthyThresholdCount: 2, - unhealthyThresholdCount: 2, - interval: Duration.seconds(60), - path: '/actuator/health', - }, - deploymentConfig, - terminationWaitTime: Duration.minutes(5), - apiCanaryTimeout: Duration.seconds(5), - apiTestSteps: [{ - name: 'getAll', - path: '/api/fruits', - jmesPath: 'length(@)', - expectedValue: 5, - }], - }); + ); if (appConfigEnabled) { service.taskDefinition.addContainer('appconfig-agent', { - image: ecs.ContainerImage.fromRegistry('public.ecr.aws/aws-appconfig/aws-appconfig-agent:2.x'), + image: ecs.ContainerImage.fromRegistry( + 'public.ecr.aws/aws-appconfig/aws-appconfig-agent:2.x', + ), essential: false, logging: AwsLogDriver.awsLogs({ logGroup: appLogGroup, @@ -129,13 +177,18 @@ export class DeploymentStack extends Stack { portMappings: [{ containerPort: 2772 }], }); - service.taskDefinition.addToTaskRolePolicy(new PolicyStatement({ - actions: ['sts:AssumeRole'], - resources: [props!.appConfigRoleArn!], - })); + service.taskDefinition.addToTaskRolePolicy( + new PolicyStatement({ + actions: ['sts:AssumeRole'], + resources: [props!.appConfigRoleArn!], + }), + ); } - service.service.connections.allowTo(db, Port.tcp(db.clusterEndpoint.port)); + service.service.connections.allowTo( + db, + ec2.Port.tcp(db.clusterEndpoint.port), + ); this.apiUrl = new CfnOutput(this, 'endpointUrl', { value: `http://${service.listener.loadBalancer.loadBalancerDnsName}`, diff --git a/examples/codecatalyst-application-pipeline/infrastructure/test/__snapshots__/deployment.test.ts.snap b/examples/codecatalyst-application-pipeline/infrastructure/test/__snapshots__/deployment.test.ts.snap index 49f9ff3..4dc7986 100644 --- a/examples/codecatalyst-application-pipeline/infrastructure/test/__snapshots__/deployment.test.ts.snap +++ b/examples/codecatalyst-application-pipeline/infrastructure/test/__snapshots__/deployment.test.ts.snap @@ -1799,14 +1799,14 @@ exports[`Deployment with AppConfig Snapshot 1`] = ` "jdbc:mysql://", { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Address", ], }, ":", { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, @@ -2070,19 +2070,67 @@ exports[`Deployment with AppConfig Snapshot 1`] = ` "Type": "AWS::Logs::LogGroup", "UpdateReplacePolicy": "Delete", }, - "AuroraCluster23D869C0": { + "AuroraSecret41E6E877": { + "DeletionPolicy": "Delete", + "Properties": { + "Description": { + "Fn::Join": [ + "", + [ + "Generated by the CDK for stack: ", + { + "Ref": "AWS::StackName", + }, + ], + ], + }, + "GenerateSecretString": { + "ExcludeCharacters": " %+~\`#$&*()|[]{}:;<>?!'/@"\\", + "GenerateStringKey": "password", + "PasswordLength": 30, + "SecretStringTemplate": "{"username":"fruitapi"}", + }, + "Name": "teststack-DB", + }, + "Type": "AWS::SecretsManager::Secret", + "UpdateReplacePolicy": "Delete", + }, + "AuroraSecretAttachment65089D67": { + "Properties": { + "SecretId": { + "Ref": "AuroraSecret41E6E877", + }, + "TargetId": { + "Ref": "DatabaseB269D8BB", + }, + "TargetType": "AWS::RDS::DBCluster", + }, + "Type": "AWS::SecretsManager::SecretTargetAttachment", + }, + "ClusterEB0386A7": { + "Properties": { + "ClusterName": "teststack", + "ClusterSettings": [ + { + "Name": "containerInsights", + "Value": "enabled", + }, + ], + }, + "Type": "AWS::ECS::Cluster", + }, + "DatabaseB269D8BB": { "DeletionPolicy": "Snapshot", "Properties": { "CopyTagsToSnapshot": true, "DBClusterIdentifier": "teststack", - "DBClusterParameterGroupName": "default.aurora-mysql5.7", + "DBClusterParameterGroupName": "default.aurora-mysql8.0", "DBSubnetGroupName": { - "Ref": "AuroraClusterSubnetsF3E9E6AD", + "Ref": "DatabaseSubnets56F17B9A", }, "DatabaseName": "fruits", - "DeletionProtection": false, "Engine": "aurora-mysql", - "EngineMode": "serverless", + "EngineVersion": "8.0.mysql_aurora.3.07.1", "MasterUserPassword": { "Fn::Join": [ "", @@ -2107,11 +2155,15 @@ exports[`Deployment with AppConfig Snapshot 1`] = ` ], ], }, + "ServerlessV2ScalingConfiguration": { + "MaxCapacity": 2, + "MinCapacity": 0.5, + }, "StorageEncrypted": true, "VpcSecurityGroupIds": [ { "Fn::GetAtt": [ - "AuroraClusterSecurityGroupD85BF9CB", + "DatabaseSecurityGroup5C91FDCB", "GroupId", ], }, @@ -2120,7 +2172,7 @@ exports[`Deployment with AppConfig Snapshot 1`] = ` "Type": "AWS::RDS::DBCluster", "UpdateReplacePolicy": "Snapshot", }, - "AuroraClusterSecurityGroupD85BF9CB": { + "DatabaseSecurityGroup5C91FDCB": { "Properties": { "GroupDescription": "RDS security group", "SecurityGroupEgress": [ @@ -2136,18 +2188,18 @@ exports[`Deployment with AppConfig Snapshot 1`] = ` }, "Type": "AWS::EC2::SecurityGroup", }, - "AuroraClusterSecurityGroupfromTestStackApiServiceSecurityGroup56AF4AC5IndirectPort7B73ECC0": { + "DatabaseSecurityGroupfromTestStackApiServiceSecurityGroup56AF4AC5IndirectPort605EA7CC": { "Properties": { "Description": "from TestStackApiServiceSecurityGroup56AF4AC5:{IndirectPort}", "FromPort": { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, "GroupId": { "Fn::GetAtt": [ - "AuroraClusterSecurityGroupD85BF9CB", + "DatabaseSecurityGroup5C91FDCB", "GroupId", ], }, @@ -2160,16 +2212,16 @@ exports[`Deployment with AppConfig Snapshot 1`] = ` }, "ToPort": { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, }, "Type": "AWS::EC2::SecurityGroupIngress", }, - "AuroraClusterSubnetsF3E9E6AD": { + "DatabaseSubnets56F17B9A": { "Properties": { - "DBSubnetGroupDescription": "Subnets for AuroraCluster database", + "DBSubnetGroupDescription": "Subnets for Database database", "SubnetIds": [ { "Ref": "VpcPrivateSubnet1Subnet536B997A", @@ -2184,55 +2236,27 @@ exports[`Deployment with AppConfig Snapshot 1`] = ` }, "Type": "AWS::RDS::DBSubnetGroup", }, - "AuroraSecret41E6E877": { + "Databasewriter2462CC03": { "DeletionPolicy": "Delete", + "DependsOn": [ + "VpcPrivateSubnet1DefaultRouteBE02A9ED", + "VpcPrivateSubnet1RouteTableAssociation70C59FA6", + "VpcPrivateSubnet2DefaultRoute060D2087", + "VpcPrivateSubnet2RouteTableAssociationA89CAD56", + "VpcPrivateSubnet3DefaultRoute94B74F0D", + "VpcPrivateSubnet3RouteTableAssociation16BDDC43", + ], "Properties": { - "Description": { - "Fn::Join": [ - "", - [ - "Generated by the CDK for stack: ", - { - "Ref": "AWS::StackName", - }, - ], - ], + "DBClusterIdentifier": { + "Ref": "DatabaseB269D8BB", }, - "GenerateSecretString": { - "ExcludeCharacters": " %+~\`#$&*()|[]{}:;<>?!'/@"\\", - "GenerateStringKey": "password", - "PasswordLength": 30, - "SecretStringTemplate": "{"username":"fruitapi"}", - }, - "Name": "teststack-DB", + "DBInstanceClass": "db.serverless", + "Engine": "aurora-mysql", + "PromotionTier": 0, }, - "Type": "AWS::SecretsManager::Secret", + "Type": "AWS::RDS::DBInstance", "UpdateReplacePolicy": "Delete", }, - "AuroraSecretAttachment65089D67": { - "Properties": { - "SecretId": { - "Ref": "AuroraSecret41E6E877", - }, - "TargetId": { - "Ref": "AuroraCluster23D869C0", - }, - "TargetType": "AWS::RDS::DBCluster", - }, - "Type": "AWS::SecretsManager::SecretTargetAttachment", - }, - "ClusterEB0386A7": { - "Properties": { - "ClusterName": "teststack", - "ClusterSettings": [ - { - "Name": "containerInsights", - "Value": "enabled", - }, - ], - }, - "Type": "AWS::ECS::Cluster", - }, "Vpc8378EB38": { "Properties": { "CidrBlock": "10.0.0.0/16", @@ -4689,14 +4713,14 @@ exports[`Deployment without AppConfig Snapshot 1`] = ` "jdbc:mysql://", { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Address", ], }, ":", { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, @@ -4899,19 +4923,67 @@ exports[`Deployment without AppConfig Snapshot 1`] = ` "Type": "AWS::Logs::LogGroup", "UpdateReplacePolicy": "Delete", }, - "AuroraCluster23D869C0": { + "AuroraSecret41E6E877": { + "DeletionPolicy": "Delete", + "Properties": { + "Description": { + "Fn::Join": [ + "", + [ + "Generated by the CDK for stack: ", + { + "Ref": "AWS::StackName", + }, + ], + ], + }, + "GenerateSecretString": { + "ExcludeCharacters": " %+~\`#$&*()|[]{}:;<>?!'/@"\\", + "GenerateStringKey": "password", + "PasswordLength": 30, + "SecretStringTemplate": "{"username":"fruitapi"}", + }, + "Name": "teststack-DB", + }, + "Type": "AWS::SecretsManager::Secret", + "UpdateReplacePolicy": "Delete", + }, + "AuroraSecretAttachment65089D67": { + "Properties": { + "SecretId": { + "Ref": "AuroraSecret41E6E877", + }, + "TargetId": { + "Ref": "DatabaseB269D8BB", + }, + "TargetType": "AWS::RDS::DBCluster", + }, + "Type": "AWS::SecretsManager::SecretTargetAttachment", + }, + "ClusterEB0386A7": { + "Properties": { + "ClusterName": "teststack", + "ClusterSettings": [ + { + "Name": "containerInsights", + "Value": "enabled", + }, + ], + }, + "Type": "AWS::ECS::Cluster", + }, + "DatabaseB269D8BB": { "DeletionPolicy": "Snapshot", "Properties": { "CopyTagsToSnapshot": true, "DBClusterIdentifier": "teststack", - "DBClusterParameterGroupName": "default.aurora-mysql5.7", + "DBClusterParameterGroupName": "default.aurora-mysql8.0", "DBSubnetGroupName": { - "Ref": "AuroraClusterSubnetsF3E9E6AD", + "Ref": "DatabaseSubnets56F17B9A", }, "DatabaseName": "fruits", - "DeletionProtection": false, "Engine": "aurora-mysql", - "EngineMode": "serverless", + "EngineVersion": "8.0.mysql_aurora.3.07.1", "MasterUserPassword": { "Fn::Join": [ "", @@ -4936,11 +5008,15 @@ exports[`Deployment without AppConfig Snapshot 1`] = ` ], ], }, + "ServerlessV2ScalingConfiguration": { + "MaxCapacity": 2, + "MinCapacity": 0.5, + }, "StorageEncrypted": true, "VpcSecurityGroupIds": [ { "Fn::GetAtt": [ - "AuroraClusterSecurityGroupD85BF9CB", + "DatabaseSecurityGroup5C91FDCB", "GroupId", ], }, @@ -4949,7 +5025,7 @@ exports[`Deployment without AppConfig Snapshot 1`] = ` "Type": "AWS::RDS::DBCluster", "UpdateReplacePolicy": "Snapshot", }, - "AuroraClusterSecurityGroupD85BF9CB": { + "DatabaseSecurityGroup5C91FDCB": { "Properties": { "GroupDescription": "RDS security group", "SecurityGroupEgress": [ @@ -4965,18 +5041,18 @@ exports[`Deployment without AppConfig Snapshot 1`] = ` }, "Type": "AWS::EC2::SecurityGroup", }, - "AuroraClusterSecurityGroupfromTestStackApiServiceSecurityGroup56AF4AC5IndirectPort7B73ECC0": { + "DatabaseSecurityGroupfromTestStackApiServiceSecurityGroup56AF4AC5IndirectPort605EA7CC": { "Properties": { "Description": "from TestStackApiServiceSecurityGroup56AF4AC5:{IndirectPort}", "FromPort": { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, "GroupId": { "Fn::GetAtt": [ - "AuroraClusterSecurityGroupD85BF9CB", + "DatabaseSecurityGroup5C91FDCB", "GroupId", ], }, @@ -4989,16 +5065,16 @@ exports[`Deployment without AppConfig Snapshot 1`] = ` }, "ToPort": { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, }, "Type": "AWS::EC2::SecurityGroupIngress", }, - "AuroraClusterSubnetsF3E9E6AD": { + "DatabaseSubnets56F17B9A": { "Properties": { - "DBSubnetGroupDescription": "Subnets for AuroraCluster database", + "DBSubnetGroupDescription": "Subnets for Database database", "SubnetIds": [ { "Ref": "VpcPrivateSubnet1Subnet536B997A", @@ -5013,55 +5089,27 @@ exports[`Deployment without AppConfig Snapshot 1`] = ` }, "Type": "AWS::RDS::DBSubnetGroup", }, - "AuroraSecret41E6E877": { + "Databasewriter2462CC03": { "DeletionPolicy": "Delete", + "DependsOn": [ + "VpcPrivateSubnet1DefaultRouteBE02A9ED", + "VpcPrivateSubnet1RouteTableAssociation70C59FA6", + "VpcPrivateSubnet2DefaultRoute060D2087", + "VpcPrivateSubnet2RouteTableAssociationA89CAD56", + "VpcPrivateSubnet3DefaultRoute94B74F0D", + "VpcPrivateSubnet3RouteTableAssociation16BDDC43", + ], "Properties": { - "Description": { - "Fn::Join": [ - "", - [ - "Generated by the CDK for stack: ", - { - "Ref": "AWS::StackName", - }, - ], - ], + "DBClusterIdentifier": { + "Ref": "DatabaseB269D8BB", }, - "GenerateSecretString": { - "ExcludeCharacters": " %+~\`#$&*()|[]{}:;<>?!'/@"\\", - "GenerateStringKey": "password", - "PasswordLength": 30, - "SecretStringTemplate": "{"username":"fruitapi"}", - }, - "Name": "teststack-DB", + "DBInstanceClass": "db.serverless", + "Engine": "aurora-mysql", + "PromotionTier": 0, }, - "Type": "AWS::SecretsManager::Secret", + "Type": "AWS::RDS::DBInstance", "UpdateReplacePolicy": "Delete", }, - "AuroraSecretAttachment65089D67": { - "Properties": { - "SecretId": { - "Ref": "AuroraSecret41E6E877", - }, - "TargetId": { - "Ref": "AuroraCluster23D869C0", - }, - "TargetType": "AWS::RDS::DBCluster", - }, - "Type": "AWS::SecretsManager::SecretTargetAttachment", - }, - "ClusterEB0386A7": { - "Properties": { - "ClusterName": "teststack", - "ClusterSettings": [ - { - "Name": "containerInsights", - "Value": "enabled", - }, - ], - }, - "Type": "AWS::ECS::Cluster", - }, "Vpc8378EB38": { "Properties": { "CidrBlock": "10.0.0.0/16", @@ -8027,14 +8075,14 @@ exports[`cdk-nag Snapshot 1`] = ` "jdbc:mysql://", { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Address", ], }, ":", { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, @@ -8251,7 +8299,66 @@ exports[`cdk-nag Snapshot 1`] = ` "Type": "AWS::Logs::LogGroup", "UpdateReplacePolicy": "Delete", }, - "AuroraCluster23D869C0": { + "AuroraSecret41E6E877": { + "DeletionPolicy": "Delete", + "Metadata": { + "cdk_nag": { + "rules_to_suppress": [ + { + "id": "AwsSolutions-SMG4", + "reason": "Dont require secret rotation", + }, + ], + }, + }, + "Properties": { + "Description": { + "Fn::Join": [ + "", + [ + "Generated by the CDK for stack: ", + { + "Ref": "AWS::StackName", + }, + ], + ], + }, + "GenerateSecretString": { + "ExcludeCharacters": " %+~\`#$&*()|[]{}:;<>?!'/@"\\", + "GenerateStringKey": "password", + "PasswordLength": 30, + "SecretStringTemplate": "{"username":"fruitapi"}", + }, + "Name": "teststack-DB", + }, + "Type": "AWS::SecretsManager::Secret", + "UpdateReplacePolicy": "Delete", + }, + "AuroraSecretAttachment65089D67": { + "Properties": { + "SecretId": { + "Ref": "AuroraSecret41E6E877", + }, + "TargetId": { + "Ref": "DatabaseB269D8BB", + }, + "TargetType": "AWS::RDS::DBCluster", + }, + "Type": "AWS::SecretsManager::SecretTargetAttachment", + }, + "ClusterEB0386A7": { + "Properties": { + "ClusterName": "teststack", + "ClusterSettings": [ + { + "Name": "containerInsights", + "Value": "enabled", + }, + ], + }, + "Type": "AWS::ECS::Cluster", + }, + "DatabaseB269D8BB": { "DeletionPolicy": "Snapshot", "Metadata": { "cdk_nag": { @@ -8282,14 +8389,13 @@ exports[`cdk-nag Snapshot 1`] = ` "Properties": { "CopyTagsToSnapshot": true, "DBClusterIdentifier": "teststack", - "DBClusterParameterGroupName": "default.aurora-mysql5.7", + "DBClusterParameterGroupName": "default.aurora-mysql8.0", "DBSubnetGroupName": { - "Ref": "AuroraClusterSubnetsF3E9E6AD", + "Ref": "DatabaseSubnets56F17B9A", }, "DatabaseName": "fruits", - "DeletionProtection": false, "Engine": "aurora-mysql", - "EngineMode": "serverless", + "EngineVersion": "8.0.mysql_aurora.3.07.1", "MasterUserPassword": { "Fn::Join": [ "", @@ -8314,11 +8420,15 @@ exports[`cdk-nag Snapshot 1`] = ` ], ], }, + "ServerlessV2ScalingConfiguration": { + "MaxCapacity": 2, + "MinCapacity": 0.5, + }, "StorageEncrypted": true, "VpcSecurityGroupIds": [ { "Fn::GetAtt": [ - "AuroraClusterSecurityGroupD85BF9CB", + "DatabaseSecurityGroup5C91FDCB", "GroupId", ], }, @@ -8327,7 +8437,7 @@ exports[`cdk-nag Snapshot 1`] = ` "Type": "AWS::RDS::DBCluster", "UpdateReplacePolicy": "Snapshot", }, - "AuroraClusterSecurityGroupD85BF9CB": { + "DatabaseSecurityGroup5C91FDCB": { "Properties": { "GroupDescription": "RDS security group", "SecurityGroupEgress": [ @@ -8343,18 +8453,18 @@ exports[`cdk-nag Snapshot 1`] = ` }, "Type": "AWS::EC2::SecurityGroup", }, - "AuroraClusterSecurityGroupfromTestStackApiServiceSecurityGroup56AF4AC5IndirectPort7B73ECC0": { + "DatabaseSecurityGroupfromTestStackApiServiceSecurityGroup56AF4AC5IndirectPort605EA7CC": { "Properties": { "Description": "from TestStackApiServiceSecurityGroup56AF4AC5:{IndirectPort}", "FromPort": { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, "GroupId": { "Fn::GetAtt": [ - "AuroraClusterSecurityGroupD85BF9CB", + "DatabaseSecurityGroup5C91FDCB", "GroupId", ], }, @@ -8367,16 +8477,16 @@ exports[`cdk-nag Snapshot 1`] = ` }, "ToPort": { "Fn::GetAtt": [ - "AuroraCluster23D869C0", + "DatabaseB269D8BB", "Endpoint.Port", ], }, }, "Type": "AWS::EC2::SecurityGroupIngress", }, - "AuroraClusterSubnetsF3E9E6AD": { + "DatabaseSubnets56F17B9A": { "Properties": { - "DBSubnetGroupDescription": "Subnets for AuroraCluster database", + "DBSubnetGroupDescription": "Subnets for Database database", "SubnetIds": [ { "Ref": "VpcPrivateSubnet1Subnet536B997A", @@ -8391,65 +8501,27 @@ exports[`cdk-nag Snapshot 1`] = ` }, "Type": "AWS::RDS::DBSubnetGroup", }, - "AuroraSecret41E6E877": { + "Databasewriter2462CC03": { "DeletionPolicy": "Delete", - "Metadata": { - "cdk_nag": { - "rules_to_suppress": [ - { - "id": "AwsSolutions-SMG4", - "reason": "Dont require secret rotation", - }, - ], - }, - }, + "DependsOn": [ + "VpcPrivateSubnet1DefaultRouteBE02A9ED", + "VpcPrivateSubnet1RouteTableAssociation70C59FA6", + "VpcPrivateSubnet2DefaultRoute060D2087", + "VpcPrivateSubnet2RouteTableAssociationA89CAD56", + "VpcPrivateSubnet3DefaultRoute94B74F0D", + "VpcPrivateSubnet3RouteTableAssociation16BDDC43", + ], "Properties": { - "Description": { - "Fn::Join": [ - "", - [ - "Generated by the CDK for stack: ", - { - "Ref": "AWS::StackName", - }, - ], - ], + "DBClusterIdentifier": { + "Ref": "DatabaseB269D8BB", }, - "GenerateSecretString": { - "ExcludeCharacters": " %+~\`#$&*()|[]{}:;<>?!'/@"\\", - "GenerateStringKey": "password", - "PasswordLength": 30, - "SecretStringTemplate": "{"username":"fruitapi"}", - }, - "Name": "teststack-DB", + "DBInstanceClass": "db.serverless", + "Engine": "aurora-mysql", + "PromotionTier": 0, }, - "Type": "AWS::SecretsManager::Secret", + "Type": "AWS::RDS::DBInstance", "UpdateReplacePolicy": "Delete", }, - "AuroraSecretAttachment65089D67": { - "Properties": { - "SecretId": { - "Ref": "AuroraSecret41E6E877", - }, - "TargetId": { - "Ref": "AuroraCluster23D869C0", - }, - "TargetType": "AWS::RDS::DBCluster", - }, - "Type": "AWS::SecretsManager::SecretTargetAttachment", - }, - "ClusterEB0386A7": { - "Properties": { - "ClusterName": "teststack", - "ClusterSettings": [ - { - "Name": "containerInsights", - "Value": "enabled", - }, - ], - }, - "Type": "AWS::ECS::Cluster", - }, "Vpc8378EB38": { "Properties": { "CidrBlock": "10.0.0.0/16", diff --git a/examples/codecatalyst-application-pipeline/infrastructure/test/deployment.test.ts b/examples/codecatalyst-application-pipeline/infrastructure/test/deployment.test.ts index 283e6d2..1517eb3 100644 --- a/examples/codecatalyst-application-pipeline/infrastructure/test/deployment.test.ts +++ b/examples/codecatalyst-application-pipeline/infrastructure/test/deployment.test.ts @@ -51,7 +51,7 @@ describe('cdk-nag', () => { // Suppress CDK-NAG for RDS Serverless NagSuppressions.addResourceSuppressionsByPath( stack, - `/${stack.stackName}/AuroraCluster/Resource`, + `/${stack.stackName}/Database/Resource`, [ { id: 'AwsSolutions-RDS6', reason: 'IAM authentication not supported on Serverless v1' }, { id: 'AwsSolutions-RDS10', reason: 'Disable delete protection to simplify cleanup of Reference Implementation' }, diff --git a/examples/codecatalyst-application-pipeline/package-lock.json b/examples/codecatalyst-application-pipeline/package-lock.json index 8ebce11..c771f67 100644 --- a/examples/codecatalyst-application-pipeline/package-lock.json +++ b/examples/codecatalyst-application-pipeline/package-lock.json @@ -15,25 +15,25 @@ "@aws-sdk/client-codepipeline": "^3.682.0", "@aws-sdk/client-ecr": "^3.682.0", "@aws-sdk/client-iam": "^3.682.0", - "@aws-sdk/client-s3": "^3.682.0", + "@aws-sdk/client-s3": "^3.685.0", "@aws-sdk/client-sts": "^3.682.0", - "@aws-sdk/credential-providers": "^3.682.0", + "@aws-sdk/credential-providers": "^3.685.0", "@aws-sdk/shared-ini-file-loader": "^3.374.0", "@cdklabs/cdk-ecs-codedeploy": "^0.0.310", "@types/aws-lambda": "^8.10.145", "@types/prompts": "^2.4.9", - "aws-cdk-lib": "^2.165.0", + "aws-cdk-lib": "^2.166.0", "constructs": "^10.4.2", "prompts": "^2.4.2", "yaml": "^2.6.0" }, "devDependencies": { "@types/jest": "^29.5", - "@types/node": "^20.17.5", + "@types/node": "^20.17.6", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "aws-cdk": "^2.165.0", - "cdk-nag": "^2.31.0", + "cdk-nag": "^2.31.2", "esbuild": "^0.20.2", "eslint": "^8.57.1", "eslint-import-resolver-node": "^0.3.9", @@ -510,9 +510,9 @@ } }, "node_modules/@aws-sdk/client-cognito-identity": { - "version": "3.682.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.682.0.tgz", - "integrity": "sha512-BD8PPPk3+ZzFqCJSPraoXkgRcPTtjguXtyDYsyBMzFofWmN4YeswXSavZVAC354W98mkffDaXBvieyqu1Y9fKA==", + "version": "3.685.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.685.0.tgz", + "integrity": "sha512-4h+aw0pUEOVP77TpF1ec9AX0mzotsiw2alXfh+P0t+43eg2EjaKRftRpNXyt5XmUPws+wsH10uEL4CzSZo1sxQ==", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", @@ -665,9 +665,9 @@ } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.682.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.682.0.tgz", - "integrity": "sha512-gn8yPhOmExhqRENnR/vKvsbTw9jaRPbfNE8fQ2j91ejXhpj632QDNdobY8TxxPm2UEW2ISAVM55r2/UPl0YP1Q==", + "version": "3.685.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.685.0.tgz", + "integrity": "sha512-ClvMeQHbLhWkpxnVymo4qWS5/yZcPXjorDbSday3joCWYWCSHTO409nWd+jx6eA4MKT/EY/uJ6ZBJRFfByKLuA==", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", "@aws-crypto/sha256-browser": "5.2.0", @@ -683,11 +683,11 @@ "@aws-sdk/middleware-location-constraint": "3.679.0", "@aws-sdk/middleware-logger": "3.679.0", "@aws-sdk/middleware-recursion-detection": "3.679.0", - "@aws-sdk/middleware-sdk-s3": "3.682.0", + "@aws-sdk/middleware-sdk-s3": "3.685.0", "@aws-sdk/middleware-ssec": "3.679.0", "@aws-sdk/middleware-user-agent": "3.682.0", "@aws-sdk/region-config-resolver": "3.679.0", - "@aws-sdk/signature-v4-multi-region": "3.682.0", + "@aws-sdk/signature-v4-multi-region": "3.685.0", "@aws-sdk/types": "3.679.0", "@aws-sdk/util-endpoints": "3.679.0", "@aws-sdk/util-user-agent-browser": "3.679.0", @@ -904,11 +904,11 @@ } }, "node_modules/@aws-sdk/credential-provider-cognito-identity": { - "version": "3.682.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.682.0.tgz", - "integrity": "sha512-V+y4qUQtc0kTnNR7u5LwnZn8EZk2pjdNX+84MwD9VjXekqbXikADu06Mj93kVGVW+qgqtNMvJ8PpiI3EaaxC7A==", + "version": "3.685.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.685.0.tgz", + "integrity": "sha512-qw9s09JFhJxEkmbo1gn94pAtyLHSx8YBX2qqrL6v3BdsJbP2fnRJMMssGMGR4jPyhklh5TSgZo0FzflbqJU8sw==", "dependencies": { - "@aws-sdk/client-cognito-identity": "3.682.0", + "@aws-sdk/client-cognito-identity": "3.685.0", "@aws-sdk/types": "3.679.0", "@smithy/property-provider": "^3.1.7", "@smithy/types": "^3.5.0", @@ -1053,15 +1053,15 @@ } }, "node_modules/@aws-sdk/credential-providers": { - "version": "3.682.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.682.0.tgz", - "integrity": "sha512-vLBdUlTISEXVKYFFO665ajC0U0RdXFx21fwTHiN2g4edFH++di2XCJ8/Y34bu09z9bV/rwFT2jn41iAVWasNKg==", + "version": "3.685.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.685.0.tgz", + "integrity": "sha512-pIXNNwPG2KnzjGYYbADquEkROuKxAJxuWt87TJO7LCFqKwb5l6h0Mc7yc4j13zxOVd/EhXD0VsPeqnobDklUoQ==", "dependencies": { - "@aws-sdk/client-cognito-identity": "3.682.0", + "@aws-sdk/client-cognito-identity": "3.685.0", "@aws-sdk/client-sso": "3.682.0", "@aws-sdk/client-sts": "3.682.0", "@aws-sdk/core": "3.679.0", - "@aws-sdk/credential-provider-cognito-identity": "3.682.0", + "@aws-sdk/credential-provider-cognito-identity": "3.685.0", "@aws-sdk/credential-provider-env": "3.679.0", "@aws-sdk/credential-provider-http": "3.679.0", "@aws-sdk/credential-provider-ini": "3.682.0", @@ -1186,9 +1186,9 @@ } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.682.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.682.0.tgz", - "integrity": "sha512-Tqndx8elRD4xDR8f5Cng6jpZ/odcm1ZTOtGRFMzHgOCij4BeMf4+/+ecQScobcrAZpUTCUTCzaTvdCdJw8MYJA==", + "version": "3.685.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.685.0.tgz", + "integrity": "sha512-C4w92b3A99NbghrA2Ssw6y1RbDF3I3Bgzi2Izh0pXgyIoDiX0xs9bUs/FGYLK4uepYr78DAZY8DwEpzjWIXkSA==", "dependencies": { "@aws-sdk/core": "3.679.0", "@aws-sdk/types": "3.679.0", @@ -1292,11 +1292,11 @@ } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.682.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.682.0.tgz", - "integrity": "sha512-y7RAQSCb9pH8wCX5We9UXfiqPVwBLLvSljhuXC31mibHmYaZnpNEwHiQlRNQPblyaNpiKnXXQ0H3Ns3FDyDYdQ==", + "version": "3.685.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.685.0.tgz", + "integrity": "sha512-IHLwuAZGqfUWVrNqw0ugnBa7iL8uBP4x6A7bfBDXRXWCWjUCed/1/D//0lKDHwpFkV74fGW6KoBacnWSUlXmwA==", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.682.0", + "@aws-sdk/middleware-sdk-s3": "3.685.0", "@aws-sdk/types": "3.679.0", "@smithy/protocol-http": "^4.1.4", "@smithy/signature-v4": "^4.2.0", @@ -5329,9 +5329,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.17.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.5.tgz", - "integrity": "sha512-n8FYY/pRxu496441gIcAQFZPKXbhsd6VZygcq+PTSZ75eMh/Ke0hCAROdUa21qiFqKNsPPYic46yXDO1JGiPBQ==", + "version": "20.17.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.6.tgz", + "integrity": "sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==", "dependencies": { "undici-types": "~6.19.2" } @@ -5940,9 +5940,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.165.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.165.0.tgz", - "integrity": "sha512-jCIUcaNDhAO/Yxik29L2LJiXkZImbEOlw/dWwhlcIx1eJyxUW+IWuMbGjXEMg8/QH56FBA5TLkZpTTsRstHS/Q==", + "version": "2.166.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.166.0.tgz", + "integrity": "sha512-FAsIz/CpczbMrcShgvTWNp3kcGN6IDojJWNLqHioTRsTekcyN3OPmKvQJXUNWL0fnhTd8biFXC2esg6kM19xZw==", "bundleDependencies": [ "@balena/dockerignore", "case", @@ -6401,7 +6401,8 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/bowser": { "version": "2.11.0", @@ -6520,6 +6521,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -6721,9 +6723,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001676", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001676.tgz", - "integrity": "sha512-Qz6zwGCiPghQXGJvgQAem79esjitvJ+CxSbSQkW9H/UX5hg8XM88d4lp2W+MEQ81j+Hip58Il+jGVdazk1z9cw==", + "version": "1.0.30001677", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz", + "integrity": "sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==", "dev": true, "funding": [ { @@ -6741,9 +6743,9 @@ ] }, "node_modules/cdk-nag": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/cdk-nag/-/cdk-nag-2.31.0.tgz", - "integrity": "sha512-/f2K4SUJp1hZKLjhQvJxQGc/qQw0JguJL21B+IqVNkKgrAXFuIjDlzSqQ6neZgJWQUP+zr1dA1KxUy9/QFhplA==", + "version": "2.31.2", + "resolved": "https://registry.npmjs.org/cdk-nag/-/cdk-nag-2.31.2.tgz", + "integrity": "sha512-b1VfiDtfWkTXGzsLLsMk5+gNapZOgY+alNQpf6FsBfIIYWsSsPeZ7S0SqiKlEC+Kvta1k55MX7OPfJEYH8uDMA==", "dev": true, "peerDependencies": { "aws-cdk-lib": "^2.156.0", @@ -8833,6 +8835,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, "engines": { "node": ">= 4" } @@ -10514,6 +10517,7 @@ "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -12750,6 +12754,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "engines": { "node": ">=6" } @@ -13314,6 +13319,7 @@ "version": "7.6.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, "bin": { "semver": "bin/semver.js" }, diff --git a/examples/codecatalyst-application-pipeline/package.json b/examples/codecatalyst-application-pipeline/package.json index b9af00c..179c35f 100644 --- a/examples/codecatalyst-application-pipeline/package.json +++ b/examples/codecatalyst-application-pipeline/package.json @@ -11,11 +11,11 @@ }, "devDependencies": { "@types/jest": "^29.5", - "@types/node": "^20.17.5", + "@types/node": "^20.17.6", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", "aws-cdk": "^2.165.0", - "cdk-nag": "^2.31.0", + "cdk-nag": "^2.31.2", "esbuild": "^0.20.2", "eslint": "^8.57.1", "eslint-import-resolver-node": "^0.3.9", @@ -38,14 +38,14 @@ "@aws-sdk/client-codepipeline": "^3.682.0", "@aws-sdk/client-ecr": "^3.682.0", "@aws-sdk/client-iam": "^3.682.0", - "@aws-sdk/client-s3": "^3.682.0", + "@aws-sdk/client-s3": "^3.685.0", "@aws-sdk/client-sts": "^3.682.0", - "@aws-sdk/credential-providers": "^3.682.0", + "@aws-sdk/credential-providers": "^3.685.0", "@aws-sdk/shared-ini-file-loader": "^3.374.0", "@cdklabs/cdk-ecs-codedeploy": "^0.0.310", "@types/aws-lambda": "^8.10.145", "@types/prompts": "^2.4.9", - "aws-cdk-lib": "^2.165.0", + "aws-cdk-lib": "^2.166.0", "constructs": "^10.4.2", "prompts": "^2.4.2", "yaml": "^2.6.0"