From f5e7717c6bbde805fc5565e266776b495d45490a Mon Sep 17 00:00:00 2001 From: mulmar-aws <79669851+mulmar-aws@users.noreply.github.com> Date: Thu, 7 Mar 2024 11:05:50 -0700 Subject: [PATCH 1/6] feat(autoscaling): add support for InstanceRefresh suspended process (#29113) Also add InstanceRefresh as a default suspended process for RollingUpdate. I have also submitted a request to update https://repost.aws/knowledge-center/auto-scaling-group-rolling-updates to conform with this change. ### Reason for this change Instance Refresh is a feature of ASG. It performs a similar function to Rolling Update. If an Instance Refresh is running at the same time as a Rolling Update, the Rolling Update will fail. It is safer to suspend the process. ### Description of changes See above. ### Description of how you validated changes Unit tests. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...efaultTestDeployAssert35BEDF6F.assets.json | 19 + ...aultTestDeployAssert35BEDF6F.template.json | 36 + ...-cdk-autoscaling-update-policy.assets.json | 19 + ...dk-autoscaling-update-policy.template.json | 603 ++++++++++ .../cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 281 +++++ .../tree.json | 1008 +++++++++++++++++ .../test/integ.asg-update-policy.ts | 26 + .../aws-autoscaling/lib/auto-scaling-group.ts | 3 +- .../test/auto-scaling-group.test.ts | 2 +- .../test/scheduled-action.test.ts | 1 + .../aws-cdk-lib/aws-ecs/test/cluster.test.ts | 1 + 13 files changed, 2010 insertions(+), 2 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/aws-cdk-autoscaling-update-policy.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/aws-cdk-autoscaling-update-policy.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F.assets.json new file mode 100644 index 0000000000000..06bd825a3a7c0 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/aws-cdk-autoscaling-update-policy.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/aws-cdk-autoscaling-update-policy.assets.json new file mode 100644 index 0000000000000..467f0be9718b3 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/aws-cdk-autoscaling-update-policy.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "b56f07823cf33a45df7bbc97f046b93f15cfc29b73aa1888f1d4fd5caec64c2e": { + "source": { + "path": "aws-cdk-autoscaling-update-policy.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "b56f07823cf33a45df7bbc97f046b93f15cfc29b73aa1888f1d4fd5caec64c2e.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/aws-cdk-autoscaling-update-policy.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/aws-cdk-autoscaling-update-policy.template.json new file mode 100644 index 0000000000000..04d2fb37aefc5 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/aws-cdk-autoscaling-update-policy.template.json @@ -0,0 +1,603 @@ +{ + "Resources": { + "VPCB9E5F0B4": { + "Type": "AWS::EC2::VPC", + "Properties": { + "CidrBlock": "10.0.0.0/16", + "EnableDnsHostnames": true, + "EnableDnsSupport": true, + "InstanceTenancy": "default", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/VPC" + } + ] + } + }, + "VPCPublicSubnet1SubnetB4246D30": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.0.0/18", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet1RouteTableFEE4B781": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet1RouteTableAssociation0B0896DC": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "VPCPublicSubnet1DefaultRoute91CEF279": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "RouteTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet1EIP6AD938E8": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1NATGatewayE0556630": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1" + } + ] + }, + "DependsOn": [ + "VPCPublicSubnet1DefaultRoute91CEF279", + "VPCPublicSubnet1RouteTableAssociation0B0896DC" + ] + }, + "VPCPublicSubnet2Subnet74179F39": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.64.0/18", + "MapPublicIpOnLaunch": true, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Public" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Public" + }, + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet2RouteTable6F1A15F1": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet2RouteTableAssociation5A808732": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "VPCPublicSubnet2DefaultRouteB7481BBA": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "GatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "RouteTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + } + }, + "DependsOn": [ + "VPCVPCGW99B986DC" + ] + }, + "VPCPublicSubnet2EIP4947BC00": { + "Type": "AWS::EC2::EIP", + "Properties": { + "Domain": "vpc", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2NATGateway3C070193": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet2EIP4947BC00", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2" + } + ] + }, + "DependsOn": [ + "VPCPublicSubnet2DefaultRouteB7481BBA", + "VPCPublicSubnet2RouteTableAssociation5A808732" + ] + }, + "VPCPrivateSubnet1Subnet8BCA10E0": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.128.0/18", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet1RouteTableBE8A6027": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet1RouteTableAssociation347902D1": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "VPCPrivateSubnet1DefaultRouteAE1D6490": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + }, + "RouteTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + } + } + }, + "VPCPrivateSubnet2SubnetCFCDAA7A": { + "Type": "AWS::EC2::Subnet", + "Properties": { + "AvailabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "CidrBlock": "10.0.192.0/18", + "MapPublicIpOnLaunch": false, + "Tags": [ + { + "Key": "aws-cdk:subnet-name", + "Value": "Private" + }, + { + "Key": "aws-cdk:subnet-type", + "Value": "Private" + }, + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet2RouteTable0A19E10E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet2RouteTableAssociation0C73D413": { + "Type": "AWS::EC2::SubnetRouteTableAssociation", + "Properties": { + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "SubnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "VPCPrivateSubnet2DefaultRouteF4F5CFD2": { + "Type": "AWS::EC2::Route", + "Properties": { + "DestinationCidrBlock": "0.0.0.0/0", + "NatGatewayId": { + "Ref": "VPCPublicSubnet2NATGateway3C070193" + }, + "RouteTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + } + } + }, + "VPCIGWB7E252D3": { + "Type": "AWS::EC2::InternetGateway", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/VPC" + } + ] + } + }, + "VPCVPCGW99B986DC": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "InternetGatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "ASGInstanceSecurityGroup0525485D": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "aws-cdk-autoscaling-update-policy/ASG/InstanceSecurityGroup", + "SecurityGroupEgress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow all outbound traffic by default", + "IpProtocol": "-1" + } + ], + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/ASG" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "ASGInstanceRoleE263A41B": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/ASG" + } + ] + } + }, + "ASGInstanceProfile0A2834D7": { + "Type": "AWS::IAM::InstanceProfile", + "Properties": { + "Roles": [ + { + "Ref": "ASGInstanceRoleE263A41B" + } + ] + } + }, + "ASGLaunchTemplate0CA92847": { + "Type": "AWS::EC2::LaunchTemplate", + "Properties": { + "LaunchTemplateData": { + "IamInstanceProfile": { + "Arn": { + "Fn::GetAtt": [ + "ASGInstanceProfile0A2834D7", + "Arn" + ] + } + }, + "ImageId": { + "Ref": "SsmParameterValueawsserviceamiamazonlinuxlatestamzn2amihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter" + }, + "InstanceType": "t2.micro", + "Monitoring": { + "Enabled": false + }, + "SecurityGroupIds": [ + { + "Fn::GetAtt": [ + "ASGInstanceSecurityGroup0525485D", + "GroupId" + ] + } + ], + "TagSpecifications": [ + { + "ResourceType": "instance", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/ASG/LaunchTemplate" + } + ] + }, + { + "ResourceType": "volume", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/ASG/LaunchTemplate" + } + ] + } + ], + "UserData": { + "Fn::Base64": "#!/bin/bash" + } + }, + "TagSpecifications": [ + { + "ResourceType": "launch-template", + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-autoscaling-update-policy/ASG/LaunchTemplate" + } + ] + } + ] + }, + "DependsOn": [ + "ASGInstanceRoleE263A41B" + ] + }, + "ASG46ED3070": { + "Type": "AWS::AutoScaling::AutoScalingGroup", + "Properties": { + "LaunchTemplate": { + "LaunchTemplateId": { + "Ref": "ASGLaunchTemplate0CA92847" + }, + "Version": { + "Fn::GetAtt": [ + "ASGLaunchTemplate0CA92847", + "LatestVersionNumber" + ] + } + }, + "MaxSize": "1", + "MinSize": "1", + "Tags": [ + { + "Key": "Name", + "PropagateAtLaunch": true, + "Value": "aws-cdk-autoscaling-update-policy/ASG" + } + ], + "VPCZoneIdentifier": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ] + }, + "UpdatePolicy": { + "AutoScalingRollingUpdate": { + "SuspendProcesses": [ + "HealthCheck", + "ReplaceUnhealthy", + "AZRebalance", + "AlarmNotification", + "ScheduledActions", + "InstanceRefresh" + ] + }, + "AutoScalingScheduledAction": { + "IgnoreUnmodifiedGroupSizeProperties": true + } + } + } + }, + "Parameters": { + "SsmParameterValueawsserviceamiamazonlinuxlatestamzn2amihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2" + }, + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/integ.json new file mode 100644 index 0000000000000..7db0c0e4c9d49 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.0", + "testCases": { + "AutoScalingUpdatePolicyTest/DefaultTest": { + "stacks": [ + "aws-cdk-autoscaling-update-policy" + ], + "assertionStack": "AutoScalingUpdatePolicyTest/DefaultTest/DeployAssert", + "assertionStackName": "AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/manifest.json new file mode 100644 index 0000000000000..1e13e42d3206f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/manifest.json @@ -0,0 +1,281 @@ +{ + "version": "36.0.0", + "artifacts": { + "aws-cdk-autoscaling-update-policy.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-cdk-autoscaling-update-policy.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-cdk-autoscaling-update-policy": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "aws-cdk-autoscaling-update-policy.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/b56f07823cf33a45df7bbc97f046b93f15cfc29b73aa1888f1d4fd5caec64c2e.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-cdk-autoscaling-update-policy.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-cdk-autoscaling-update-policy.assets" + ], + "metadata": { + "/aws-cdk-autoscaling-update-policy/VPC/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCB9E5F0B4" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1SubnetB4246D30" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1RouteTableFEE4B781" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1RouteTableAssociation0B0896DC" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1DefaultRoute91CEF279" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1EIP6AD938E8" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1NATGatewayE0556630" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2Subnet74179F39" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2RouteTable6F1A15F1" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2RouteTableAssociation5A808732" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2DefaultRouteB7481BBA" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2EIP4947BC00" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2NATGateway3C070193" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1Subnet8BCA10E0" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1RouteTableBE8A6027" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1RouteTableAssociation347902D1" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1DefaultRouteAE1D6490" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2RouteTable0A19E10E" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2RouteTableAssociation0C73D413" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2DefaultRouteF4F5CFD2" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/IGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCIGWB7E252D3" + } + ], + "/aws-cdk-autoscaling-update-policy/VPC/VPCGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCVPCGW99B986DC" + } + ], + "/aws-cdk-autoscaling-update-policy/ASG/InstanceSecurityGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ASGInstanceSecurityGroup0525485D" + } + ], + "/aws-cdk-autoscaling-update-policy/ASG/InstanceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ASGInstanceRoleE263A41B" + } + ], + "/aws-cdk-autoscaling-update-policy/ASG/InstanceProfile": [ + { + "type": "aws:cdk:logicalId", + "data": "ASGInstanceProfile0A2834D7" + } + ], + "/aws-cdk-autoscaling-update-policy/ASG/LaunchTemplate/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ASGLaunchTemplate0CA92847" + } + ], + "/aws-cdk-autoscaling-update-policy/ASG/ASG": [ + { + "type": "aws:cdk:logicalId", + "data": "ASG46ED3070" + } + ], + "/aws-cdk-autoscaling-update-policy/SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter": [ + { + "type": "aws:cdk:logicalId", + "data": "SsmParameterValueawsserviceamiamazonlinuxlatestamzn2amihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter" + } + ], + "/aws-cdk-autoscaling-update-policy/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-autoscaling-update-policy/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-autoscaling-update-policy" + }, + "AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "AutoScalingUpdatePolicyTestDefaultTestDeployAssert35BEDF6F.assets" + ], + "metadata": { + "/AutoScalingUpdatePolicyTest/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/AutoScalingUpdatePolicyTest/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "AutoScalingUpdatePolicyTest/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/tree.json new file mode 100644 index 0000000000000..f2dae94b73f4f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.js.snapshot/tree.json @@ -0,0 +1,1008 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-cdk-autoscaling-update-policy": { + "id": "aws-cdk-autoscaling-update-policy", + "path": "aws-cdk-autoscaling-update-policy", + "children": { + "VPC": { + "id": "VPC", + "path": "aws-cdk-autoscaling-update-policy/VPC", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-autoscaling-update-policy/VPC/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPC", + "aws:cdk:cloudformation:props": { + "cidrBlock": "10.0.0.0/16", + "enableDnsHostnames": true, + "enableDnsSupport": true, + "instanceTenancy": "default", + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/VPC" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPC", + "version": "0.0.0" + } + }, + "PublicSubnet1": { + "id": "PublicSubnet1", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.0.0/18", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + }, + "subnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "routeTableId": { + "Ref": "VPCPublicSubnet1RouteTableFEE4B781" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "allocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "subnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PublicSubnet2": { + "id": "PublicSubnet2", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.64.0/18", + "mapPublicIpOnLaunch": true, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Public" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Public" + }, + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + }, + "subnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "gatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "routeTableId": { + "Ref": "VPCPublicSubnet2RouteTable6F1A15F1" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + }, + "EIP": { + "id": "EIP", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2/NATGateway", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::NatGateway", + "aws:cdk:cloudformation:props": { + "allocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet2EIP4947BC00", + "AllocationId" + ] + }, + "subnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnNatGateway", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PublicSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet1": { + "id": "PrivateSubnet1", + "path": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet1/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 0, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.128.0/18", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet1/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet1/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + }, + "subnetId": { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet1/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "VPCPublicSubnet1NATGatewayE0556630" + }, + "routeTableId": { + "Ref": "VPCPrivateSubnet1RouteTableBE8A6027" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "PrivateSubnet2": { + "id": "PrivateSubnet2", + "path": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet2/Subnet", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Subnet", + "aws:cdk:cloudformation:props": { + "availabilityZone": { + "Fn::Select": [ + 1, + { + "Fn::GetAZs": "" + } + ] + }, + "cidrBlock": "10.0.192.0/18", + "mapPublicIpOnLaunch": false, + "tags": [ + { + "key": "aws-cdk:subnet-name", + "value": "Private" + }, + { + "key": "aws-cdk:subnet-type", + "value": "Private" + }, + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet2/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet2/RouteTableAssociation", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SubnetRouteTableAssociation", + "aws:cdk:cloudformation:props": { + "routeTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + }, + "subnetId": { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnetRouteTableAssociation", + "version": "0.0.0" + } + }, + "DefaultRoute": { + "id": "DefaultRoute", + "path": "aws-cdk-autoscaling-update-policy/VPC/PrivateSubnet2/DefaultRoute", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::Route", + "aws:cdk:cloudformation:props": { + "destinationCidrBlock": "0.0.0.0/0", + "natGatewayId": { + "Ref": "VPCPublicSubnet2NATGateway3C070193" + }, + "routeTableId": { + "Ref": "VPCPrivateSubnet2RouteTable0A19E10E" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRoute", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.PrivateSubnet", + "version": "0.0.0" + } + }, + "IGW": { + "id": "IGW", + "path": "aws-cdk-autoscaling-update-policy/VPC/IGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/VPC" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnInternetGateway", + "version": "0.0.0" + } + }, + "VPCGW": { + "id": "VPCGW", + "path": "aws-cdk-autoscaling-update-policy/VPC/VPCGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::VPCGatewayAttachment", + "aws:cdk:cloudformation:props": { + "internetGatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPCGatewayAttachment", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.Vpc", + "version": "0.0.0" + } + }, + "ASG": { + "id": "ASG", + "path": "aws-cdk-autoscaling-update-policy/ASG", + "children": { + "InstanceSecurityGroup": { + "id": "InstanceSecurityGroup", + "path": "aws-cdk-autoscaling-update-policy/ASG/InstanceSecurityGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-autoscaling-update-policy/ASG/InstanceSecurityGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "aws-cdk-autoscaling-update-policy/ASG/InstanceSecurityGroup", + "securityGroupEgress": [ + { + "cidrIp": "0.0.0.0/0", + "description": "Allow all outbound traffic by default", + "ipProtocol": "-1" + } + ], + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/ASG" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSecurityGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.SecurityGroup", + "version": "0.0.0" + } + }, + "InstanceRole": { + "id": "InstanceRole", + "path": "aws-cdk-autoscaling-update-policy/ASG/InstanceRole", + "children": { + "ImportInstanceRole": { + "id": "ImportInstanceRole", + "path": "aws-cdk-autoscaling-update-policy/ASG/InstanceRole/ImportInstanceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-autoscaling-update-policy/ASG/InstanceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/ASG" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "InstanceProfile": { + "id": "InstanceProfile", + "path": "aws-cdk-autoscaling-update-policy/ASG/InstanceProfile", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::InstanceProfile", + "aws:cdk:cloudformation:props": { + "roles": [ + { + "Ref": "ASGInstanceRoleE263A41B" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnInstanceProfile", + "version": "0.0.0" + } + }, + "ImportedInstanceProfile": { + "id": "ImportedInstanceProfile", + "path": "aws-cdk-autoscaling-update-policy/ASG/ImportedInstanceProfile", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "LaunchTemplate": { + "id": "LaunchTemplate", + "path": "aws-cdk-autoscaling-update-policy/ASG/LaunchTemplate", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-autoscaling-update-policy/ASG/LaunchTemplate/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::LaunchTemplate", + "aws:cdk:cloudformation:props": { + "launchTemplateData": { + "iamInstanceProfile": { + "arn": { + "Fn::GetAtt": [ + "ASGInstanceProfile0A2834D7", + "Arn" + ] + } + }, + "imageId": { + "Ref": "SsmParameterValueawsserviceamiamazonlinuxlatestamzn2amihvmx8664gp2C96584B6F00A464EAD1953AFF4B05118Parameter" + }, + "instanceType": "t2.micro", + "monitoring": { + "enabled": false + }, + "securityGroupIds": [ + { + "Fn::GetAtt": [ + "ASGInstanceSecurityGroup0525485D", + "GroupId" + ] + } + ], + "tagSpecifications": [ + { + "resourceType": "instance", + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/ASG/LaunchTemplate" + } + ] + }, + { + "resourceType": "volume", + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/ASG/LaunchTemplate" + } + ] + } + ], + "userData": { + "Fn::Base64": "#!/bin/bash" + } + }, + "tagSpecifications": [ + { + "resourceType": "launch-template", + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/ASG/LaunchTemplate" + } + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnLaunchTemplate", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.LaunchTemplate", + "version": "0.0.0" + } + }, + "ASG": { + "id": "ASG", + "path": "aws-cdk-autoscaling-update-policy/ASG/ASG", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::AutoScaling::AutoScalingGroup", + "aws:cdk:cloudformation:props": { + "launchTemplate": { + "launchTemplateId": { + "Ref": "ASGLaunchTemplate0CA92847" + }, + "version": { + "Fn::GetAtt": [ + "ASGLaunchTemplate0CA92847", + "LatestVersionNumber" + ] + } + }, + "maxSize": "1", + "minSize": "1", + "tags": [ + { + "key": "Name", + "value": "aws-cdk-autoscaling-update-policy/ASG", + "propagateAtLaunch": true + } + ], + "vpcZoneIdentifier": [ + { + "Ref": "VPCPrivateSubnet1Subnet8BCA10E0" + }, + { + "Ref": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_autoscaling.CfnAutoScalingGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_autoscaling.AutoScalingGroup", + "version": "0.0.0" + } + }, + "SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter": { + "id": "SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter", + "path": "aws-cdk-autoscaling-update-policy/SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118.Parameter", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118": { + "id": "SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118", + "path": "aws-cdk-autoscaling-update-policy/SsmParameterValue:--aws--service--ami-amazon-linux-latest--amzn2-ami-hvm-x86_64-gp2:C96584B6-F00A-464E-AD19-53AFF4B05118", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-autoscaling-update-policy/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-autoscaling-update-policy/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "AutoScalingUpdatePolicyTest": { + "id": "AutoScalingUpdatePolicyTest", + "path": "AutoScalingUpdatePolicyTest", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "AutoScalingUpdatePolicyTest/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "AutoScalingUpdatePolicyTest/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "AutoScalingUpdatePolicyTest/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "AutoScalingUpdatePolicyTest/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "AutoScalingUpdatePolicyTest/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.ts new file mode 100644 index 0000000000000..8936cda67ce89 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-autoscaling/test/integ.asg-update-policy.ts @@ -0,0 +1,26 @@ +#!/usr/bin/env node +import * as ec2 from 'aws-cdk-lib/aws-ec2'; +import * as cdk from 'aws-cdk-lib'; +import * as integ from '@aws-cdk/integ-tests-alpha'; +import * as autoscaling from 'aws-cdk-lib/aws-autoscaling'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-cdk-autoscaling-update-policy'); + +const vpc = new ec2.Vpc(stack, 'VPC', { + maxAzs: 2, + restrictDefaultSecurityGroup: false, +}); + +new autoscaling.AutoScalingGroup(stack, 'ASG', { + vpc, + instanceType: new ec2.InstanceType('t2.micro'), + machineImage: new ec2.AmazonLinuxImage({ generation: ec2.AmazonLinuxGeneration.AMAZON_LINUX_2 }), + updatePolicy: autoscaling.UpdatePolicy.rollingUpdate(), +}); + +new integ.IntegTest(app, 'AutoScalingUpdatePolicyTest', { + testCases: [stack], +}); + +app.synth(); diff --git a/packages/aws-cdk-lib/aws-autoscaling/lib/auto-scaling-group.ts b/packages/aws-cdk-lib/aws-autoscaling/lib/auto-scaling-group.ts index dee4d5b3a372a..eab143ef5d80c 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/lib/auto-scaling-group.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/lib/auto-scaling-group.ts @@ -2166,12 +2166,13 @@ export enum ScalingProcess { ALARM_NOTIFICATION = 'AlarmNotification', SCHEDULED_ACTIONS = 'ScheduledActions', ADD_TO_LOAD_BALANCER = 'AddToLoadBalancer', + INSTANCE_REFRESH = 'InstanceRefresh', } // Recommended list of processes to suspend from here: // https://aws.amazon.com/premiumsupport/knowledge-center/auto-scaling-group-rolling-updates/ const DEFAULT_SUSPEND_PROCESSES = [ScalingProcess.HEALTH_CHECK, ScalingProcess.REPLACE_UNHEALTHY, ScalingProcess.AZ_REBALANCE, - ScalingProcess.ALARM_NOTIFICATION, ScalingProcess.SCHEDULED_ACTIONS]; + ScalingProcess.ALARM_NOTIFICATION, ScalingProcess.SCHEDULED_ACTIONS, ScalingProcess.INSTANCE_REFRESH]; /** * EC2 Heath check options diff --git a/packages/aws-cdk-lib/aws-autoscaling/test/auto-scaling-group.test.ts b/packages/aws-cdk-lib/aws-autoscaling/test/auto-scaling-group.test.ts index df0b4f6c40c59..5096a78132ce3 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/test/auto-scaling-group.test.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/test/auto-scaling-group.test.ts @@ -620,7 +620,7 @@ describe('auto scaling group', () => { 'MinSuccessfulInstancesPercent': 50, 'WaitOnResourceSignals': true, 'PauseTime': 'PT5M45S', - 'SuspendProcesses': ['HealthCheck', 'ReplaceUnhealthy', 'AZRebalance', 'AlarmNotification', 'ScheduledActions'], + 'SuspendProcesses': ['HealthCheck', 'ReplaceUnhealthy', 'AZRebalance', 'AlarmNotification', 'ScheduledActions', 'InstanceRefresh'], }, }, }); diff --git a/packages/aws-cdk-lib/aws-autoscaling/test/scheduled-action.test.ts b/packages/aws-cdk-lib/aws-autoscaling/test/scheduled-action.test.ts index a1192d003acd5..54d6325b1d13f 100644 --- a/packages/aws-cdk-lib/aws-autoscaling/test/scheduled-action.test.ts +++ b/packages/aws-cdk-lib/aws-autoscaling/test/scheduled-action.test.ts @@ -104,6 +104,7 @@ describeDeprecated('scheduled action', () => { 'AZRebalance', 'AlarmNotification', 'ScheduledActions', + 'InstanceRefresh', ], }, AutoScalingScheduledAction: { diff --git a/packages/aws-cdk-lib/aws-ecs/test/cluster.test.ts b/packages/aws-cdk-lib/aws-ecs/test/cluster.test.ts index 260cd89b60c9c..4f10a1163f98f 100644 --- a/packages/aws-cdk-lib/aws-ecs/test/cluster.test.ts +++ b/packages/aws-cdk-lib/aws-ecs/test/cluster.test.ts @@ -2052,6 +2052,7 @@ describe('cluster', () => { 'AZRebalance', 'AlarmNotification', 'ScheduledActions', + 'InstanceRefresh', ], }, AutoScalingScheduledAction: { From 4f2b75772c8c8075665627d79f8874bda5bd0dd5 Mon Sep 17 00:00:00 2001 From: kazuho cryer-shinozuka Date: Fri, 8 Mar 2024 04:26:39 +0900 Subject: [PATCH 2/6] feat(stepfunctions-tasks): start build batch integration (#29296) ### Issue # (if applicable) Closes #29119. ### Reason for this change There is an optimized integration with codebuild but it is not able to integrate by AWS CDK. ### Description of changes Add CodeBuildStartBuildBatch class ```ts declare const project: codebuild.Project; const buildconfig = project.enableBatchBuilds(); const startBuildBatch = new tasks.CodeBuildStartBuildBatch(this, 'buildTask', { project, integrationPattern: sfn.IntegrationPattern.REQUEST_RESPONSE, environmentVariablesOverride: { test: { type: codebuild.BuildEnvironmentVariableType.PLAINTEXT, value: 'testValue', }, }, }); ``` ### Description of how you validated changes I've implemented both unit and integ tests. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../StartBuildBatch.assets.json | 19 + .../StartBuildBatch.template.json | 364 +++++++++++ ...efaultTestDeployAssert142C169A.assets.json | 19 + ...aultTestDeployAssert142C169A.template.json | 36 + .../cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 155 +++++ .../tree.json | 613 ++++++++++++++++++ .../test/codebuild/integ.start-build-batch.ts | 94 +++ .../aws-stepfunctions-tasks/README.md | 39 ++ .../lib/codebuild/start-build-batch.ts | 127 ++++ .../aws-stepfunctions-tasks/lib/index.ts | 1 + .../test/codebuild/start-build-batch.test.ts | 215 ++++++ 13 files changed, 1695 insertions(+) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatch.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatch.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatchIntegDefaultTestDeployAssert142C169A.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatchIntegDefaultTestDeployAssert142C169A.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.ts create mode 100644 packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/codebuild/start-build-batch.ts create mode 100644 packages/aws-cdk-lib/aws-stepfunctions-tasks/test/codebuild/start-build-batch.test.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatch.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatch.assets.json new file mode 100644 index 0000000000000..fc26527706df7 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatch.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "5a4a7364d62c5bab6b3ec3ccfa6d371f59724308214a3fd5da99da666d1c943a": { + "source": { + "path": "StartBuildBatch.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "5a4a7364d62c5bab6b3ec3ccfa6d371f59724308214a3fd5da99da666d1c943a.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatch.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatch.template.json new file mode 100644 index 0000000000000..baa81c2db7b3a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatch.template.json @@ -0,0 +1,364 @@ +{ + "Resources": { + "ProjectRole4CCB274E": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "codebuild.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "ProjectRoleDefaultPolicy7F29461B": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/codebuild/", + { + "Ref": "ProjectC78D97AD" + }, + ":*" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/codebuild/", + { + "Ref": "ProjectC78D97AD" + } + ] + ] + } + ] + }, + { + "Action": [ + "codebuild:BatchPutCodeCoverages", + "codebuild:BatchPutTestCases", + "codebuild:CreateReport", + "codebuild:CreateReportGroup", + "codebuild:UpdateReport" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":codebuild:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":report-group/", + { + "Ref": "ProjectC78D97AD" + }, + "-*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ProjectRoleDefaultPolicy7F29461B", + "Roles": [ + { + "Ref": "ProjectRole4CCB274E" + } + ] + } + }, + "ProjectC78D97AD": { + "Type": "AWS::CodeBuild::Project", + "Properties": { + "Artifacts": { + "Type": "NO_ARTIFACTS" + }, + "BuildBatchConfig": { + "ServiceRole": { + "Fn::GetAtt": [ + "ProjectBatchServiceRoleF97A1CFB", + "Arn" + ] + } + }, + "Cache": { + "Type": "NO_CACHE" + }, + "EncryptionKey": "alias/aws/s3", + "Environment": { + "ComputeType": "BUILD_GENERAL1_SMALL", + "Image": "aws/codebuild/standard:5.0", + "ImagePullCredentialsType": "CODEBUILD", + "PrivilegedMode": false, + "Type": "LINUX_CONTAINER" + }, + "Name": "MyTestProject", + "ServiceRole": { + "Fn::GetAtt": [ + "ProjectRole4CCB274E", + "Arn" + ] + }, + "Source": { + "BuildSpec": "version: 0.2\nbatch:\n fast-fail: true\n build-list:\n - identifier: linux_small\n env:\n compute-type: BUILD_GENERAL1_SMALL\n image: aws/codebuild/standard:5.0\n type: LINUX_CONTAINER\n variables:\n key1: value1\n buildspec: |-\n version: 0.2\n phases:\n build:\n commands:\n - echo \"Hello, from small!\"\n - identifier: linux_medium\n env:\n compute-type: BUILD_GENERAL1_MEDIUM\n image: aws/codebuild/standard:4.0\n type: LINUX_CONTAINER\n variables:\n key2: value2\n buildspec: |-\n version: 0.2\n phases:\n build:\n commands:\n - echo \"Hello, from medium!\"\n", + "Type": "NO_SOURCE" + }, + "TimeoutInMinutes": 60 + } + }, + "ProjectBatchServiceRoleF97A1CFB": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "codebuild.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "ProjectBatchServiceRoleDefaultPolicy5E00842B": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "codebuild:RetryBuild", + "codebuild:StartBuild", + "codebuild:StopBuild" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "ProjectC78D97AD", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "ProjectBatchServiceRoleDefaultPolicy5E00842B", + "Roles": [ + { + "Ref": "ProjectBatchServiceRoleF97A1CFB" + } + ] + } + }, + "StateMachineRoleB840431D": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "StateMachineRoleDefaultPolicyDF1E6607": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "codebuild:BatchGetBuildBatches", + "codebuild:StartBuildBatch", + "codebuild:StopBuildBatch" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "ProjectC78D97AD", + "Arn" + ] + } + }, + { + "Action": [ + "events:DescribeRule", + "events:PutRule", + "events:PutTargets" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":events:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":rule/StepFunctionsGetEventForCodeBuildStartBuildBatchRule" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "StateMachineRoleDefaultPolicyDF1E6607", + "Roles": [ + { + "Ref": "StateMachineRoleB840431D" + } + ] + } + }, + "StateMachine2E01A3A5": { + "Type": "AWS::StepFunctions::StateMachine", + "Properties": { + "DefinitionString": { + "Fn::Join": [ + "", + [ + "{\"StartAt\":\"Start\",\"States\":{\"Start\":{\"Type\":\"Pass\",\"Result\":{\"bar\":\"SomeValue\"},\"Next\":\"buildTask1\"},\"buildTask1\":{\"Next\":\"buildTask2\",\"Type\":\"Task\",\"Resource\":\"arn:", + { + "Ref": "AWS::Partition" + }, + ":states:::codebuild:startBuildBatch\",\"Parameters\":{\"ProjectName\":\"", + { + "Ref": "ProjectC78D97AD" + }, + "\",\"EnvironmentVariablesOverride\":[{\"Name\":\"test\",\"Type\":\"PLAINTEXT\",\"Value\":\"testValue\"}]}},\"buildTask2\":{\"End\":true,\"Type\":\"Task\",\"Resource\":\"arn:", + { + "Ref": "AWS::Partition" + }, + ":states:::codebuild:startBuildBatch.sync\",\"Parameters\":{\"ProjectName\":\"", + { + "Ref": "ProjectC78D97AD" + }, + "\",\"EnvironmentVariablesOverride\":[{\"Name\":\"test\",\"Type\":\"PLAINTEXT\",\"Value\":\"testValue\"}]}}}}" + ] + ] + }, + "RoleArn": { + "Fn::GetAtt": [ + "StateMachineRoleB840431D", + "Arn" + ] + } + }, + "DependsOn": [ + "StateMachineRoleDefaultPolicyDF1E6607", + "StateMachineRoleB840431D" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatchIntegDefaultTestDeployAssert142C169A.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatchIntegDefaultTestDeployAssert142C169A.assets.json new file mode 100644 index 0000000000000..bb963bcd7c8ab --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatchIntegDefaultTestDeployAssert142C169A.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "StartBuildBatchIntegDefaultTestDeployAssert142C169A.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatchIntegDefaultTestDeployAssert142C169A.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatchIntegDefaultTestDeployAssert142C169A.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/StartBuildBatchIntegDefaultTestDeployAssert142C169A.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/integ.json new file mode 100644 index 0000000000000..fa32ffe5a59f1 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.0", + "testCases": { + "StartBuildBatchInteg/DefaultTest": { + "stacks": [ + "StartBuildBatch" + ], + "assertionStack": "StartBuildBatchInteg/DefaultTest/DeployAssert", + "assertionStackName": "StartBuildBatchIntegDefaultTestDeployAssert142C169A" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/manifest.json new file mode 100644 index 0000000000000..22303e0a7c37c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/manifest.json @@ -0,0 +1,155 @@ +{ + "version": "36.0.0", + "artifacts": { + "StartBuildBatch.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "StartBuildBatch.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "StartBuildBatch": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "StartBuildBatch.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/5a4a7364d62c5bab6b3ec3ccfa6d371f59724308214a3fd5da99da666d1c943a.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "StartBuildBatch.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "StartBuildBatch.assets" + ], + "metadata": { + "/StartBuildBatch/Project/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ProjectRole4CCB274E" + } + ], + "/StartBuildBatch/Project/Role/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ProjectRoleDefaultPolicy7F29461B" + } + ], + "/StartBuildBatch/Project/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ProjectC78D97AD" + } + ], + "/StartBuildBatch/Project/BatchServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ProjectBatchServiceRoleF97A1CFB" + } + ], + "/StartBuildBatch/Project/BatchServiceRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ProjectBatchServiceRoleDefaultPolicy5E00842B" + } + ], + "/StartBuildBatch/StateMachine/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineRoleB840431D" + } + ], + "/StartBuildBatch/StateMachine/Role/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachineRoleDefaultPolicyDF1E6607" + } + ], + "/StartBuildBatch/StateMachine/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "StateMachine2E01A3A5" + } + ], + "/StartBuildBatch/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/StartBuildBatch/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "StartBuildBatch" + }, + "StartBuildBatchIntegDefaultTestDeployAssert142C169A.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "StartBuildBatchIntegDefaultTestDeployAssert142C169A.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "StartBuildBatchIntegDefaultTestDeployAssert142C169A": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "StartBuildBatchIntegDefaultTestDeployAssert142C169A.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "StartBuildBatchIntegDefaultTestDeployAssert142C169A.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "StartBuildBatchIntegDefaultTestDeployAssert142C169A.assets" + ], + "metadata": { + "/StartBuildBatchInteg/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/StartBuildBatchInteg/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "StartBuildBatchInteg/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/tree.json new file mode 100644 index 0000000000000..b9568a47cac9f --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.js.snapshot/tree.json @@ -0,0 +1,613 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "StartBuildBatch": { + "id": "StartBuildBatch", + "path": "StartBuildBatch", + "children": { + "Project": { + "id": "Project", + "path": "StartBuildBatch/Project", + "children": { + "Role": { + "id": "Role", + "path": "StartBuildBatch/Project/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "StartBuildBatch/Project/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "StartBuildBatch/Project/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "codebuild.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "StartBuildBatch/Project/Role/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "StartBuildBatch/Project/Role/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/codebuild/", + { + "Ref": "ProjectC78D97AD" + }, + ":*" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/codebuild/", + { + "Ref": "ProjectC78D97AD" + } + ] + ] + } + ] + }, + { + "Action": [ + "codebuild:BatchPutCodeCoverages", + "codebuild:BatchPutTestCases", + "codebuild:CreateReport", + "codebuild:CreateReportGroup", + "codebuild:UpdateReport" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":codebuild:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":report-group/", + { + "Ref": "ProjectC78D97AD" + }, + "-*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "ProjectRoleDefaultPolicy7F29461B", + "roles": [ + { + "Ref": "ProjectRole4CCB274E" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "StartBuildBatch/Project/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CodeBuild::Project", + "aws:cdk:cloudformation:props": { + "artifacts": { + "type": "NO_ARTIFACTS" + }, + "buildBatchConfig": { + "serviceRole": { + "Fn::GetAtt": [ + "ProjectBatchServiceRoleF97A1CFB", + "Arn" + ] + } + }, + "cache": { + "type": "NO_CACHE" + }, + "encryptionKey": "alias/aws/s3", + "environment": { + "type": "LINUX_CONTAINER", + "image": "aws/codebuild/standard:5.0", + "imagePullCredentialsType": "CODEBUILD", + "privilegedMode": false, + "computeType": "BUILD_GENERAL1_SMALL" + }, + "name": "MyTestProject", + "serviceRole": { + "Fn::GetAtt": [ + "ProjectRole4CCB274E", + "Arn" + ] + }, + "source": { + "type": "NO_SOURCE", + "buildSpec": "version: 0.2\nbatch:\n fast-fail: true\n build-list:\n - identifier: linux_small\n env:\n compute-type: BUILD_GENERAL1_SMALL\n image: aws/codebuild/standard:5.0\n type: LINUX_CONTAINER\n variables:\n key1: value1\n buildspec: |-\n version: 0.2\n phases:\n build:\n commands:\n - echo \"Hello, from small!\"\n - identifier: linux_medium\n env:\n compute-type: BUILD_GENERAL1_MEDIUM\n image: aws/codebuild/standard:4.0\n type: LINUX_CONTAINER\n variables:\n key2: value2\n buildspec: |-\n version: 0.2\n phases:\n build:\n commands:\n - echo \"Hello, from medium!\"\n" + }, + "timeoutInMinutes": 60 + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codebuild.CfnProject", + "version": "0.0.0" + } + }, + "BatchServiceRole": { + "id": "BatchServiceRole", + "path": "StartBuildBatch/Project/BatchServiceRole", + "children": { + "ImportBatchServiceRole": { + "id": "ImportBatchServiceRole", + "path": "StartBuildBatch/Project/BatchServiceRole/ImportBatchServiceRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "StartBuildBatch/Project/BatchServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "codebuild.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "StartBuildBatch/Project/BatchServiceRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "StartBuildBatch/Project/BatchServiceRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "codebuild:RetryBuild", + "codebuild:StartBuild", + "codebuild:StopBuild" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "ProjectC78D97AD", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "ProjectBatchServiceRoleDefaultPolicy5E00842B", + "roles": [ + { + "Ref": "ProjectBatchServiceRoleF97A1CFB" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_codebuild.Project", + "version": "0.0.0" + } + }, + "buildTask1": { + "id": "buildTask1", + "path": "StartBuildBatch/buildTask1", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions_tasks.CodeBuildStartBuildBatch", + "version": "0.0.0" + } + }, + "buildTask2": { + "id": "buildTask2", + "path": "StartBuildBatch/buildTask2", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions_tasks.CodeBuildStartBuildBatch", + "version": "0.0.0" + } + }, + "Start": { + "id": "Start", + "path": "StartBuildBatch/Start", + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.Pass", + "version": "0.0.0" + } + }, + "StateMachine": { + "id": "StateMachine", + "path": "StartBuildBatch/StateMachine", + "children": { + "Role": { + "id": "Role", + "path": "StartBuildBatch/StateMachine/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "StartBuildBatch/StateMachine/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "StartBuildBatch/StateMachine/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "states.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "StartBuildBatch/StateMachine/Role/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "StartBuildBatch/StateMachine/Role/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "codebuild:BatchGetBuildBatches", + "codebuild:StartBuildBatch", + "codebuild:StopBuildBatch" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "ProjectC78D97AD", + "Arn" + ] + } + }, + { + "Action": [ + "events:DescribeRule", + "events:PutRule", + "events:PutTargets" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":events:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":rule/StepFunctionsGetEventForCodeBuildStartBuildBatchRule" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "StateMachineRoleDefaultPolicyDF1E6607", + "roles": [ + { + "Ref": "StateMachineRoleB840431D" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Policy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "StartBuildBatch/StateMachine/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::StepFunctions::StateMachine", + "aws:cdk:cloudformation:props": { + "definitionString": { + "Fn::Join": [ + "", + [ + "{\"StartAt\":\"Start\",\"States\":{\"Start\":{\"Type\":\"Pass\",\"Result\":{\"bar\":\"SomeValue\"},\"Next\":\"buildTask1\"},\"buildTask1\":{\"Next\":\"buildTask2\",\"Type\":\"Task\",\"Resource\":\"arn:", + { + "Ref": "AWS::Partition" + }, + ":states:::codebuild:startBuildBatch\",\"Parameters\":{\"ProjectName\":\"", + { + "Ref": "ProjectC78D97AD" + }, + "\",\"EnvironmentVariablesOverride\":[{\"Name\":\"test\",\"Type\":\"PLAINTEXT\",\"Value\":\"testValue\"}]}},\"buildTask2\":{\"End\":true,\"Type\":\"Task\",\"Resource\":\"arn:", + { + "Ref": "AWS::Partition" + }, + ":states:::codebuild:startBuildBatch.sync\",\"Parameters\":{\"ProjectName\":\"", + { + "Ref": "ProjectC78D97AD" + }, + "\",\"EnvironmentVariablesOverride\":[{\"Name\":\"test\",\"Type\":\"PLAINTEXT\",\"Value\":\"testValue\"}]}}}}" + ] + ] + }, + "roleArn": { + "Fn::GetAtt": [ + "StateMachineRoleB840431D", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.CfnStateMachine", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_stepfunctions.StateMachine", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "StartBuildBatch/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "StartBuildBatch/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "StartBuildBatchInteg": { + "id": "StartBuildBatchInteg", + "path": "StartBuildBatchInteg", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "StartBuildBatchInteg/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "StartBuildBatchInteg/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "StartBuildBatchInteg/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "StartBuildBatchInteg/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "StartBuildBatchInteg/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.ts new file mode 100644 index 0000000000000..9556b37f07af8 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-stepfunctions-tasks/test/codebuild/integ.start-build-batch.ts @@ -0,0 +1,94 @@ +import * as codebuild from 'aws-cdk-lib/aws-codebuild'; +import * as sfn from 'aws-cdk-lib/aws-stepfunctions'; +import * as cdk from 'aws-cdk-lib'; +import * as tasks from 'aws-cdk-lib/aws-stepfunctions-tasks'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; + +class TestStack extends cdk.Stack { + constructor(scope: cdk.App, id: string, props: cdk.StackProps = {}) { + super(scope, id, props); + + const project = new codebuild.Project(this, 'Project', { + projectName: 'MyTestProject', + environment: { + buildImage: codebuild.LinuxBuildImage.STANDARD_5_0, + }, + timeout: cdk.Duration.hours(1), + buildSpec: codebuild.BuildSpec.fromObjectToYaml({ + version: 0.2, + batch: { + 'fast-fail': true, + 'build-list': [ + { + identifier: 'linux_small', + env: { + 'compute-type': 'BUILD_GENERAL1_SMALL', + 'image': 'aws/codebuild/standard:5.0', + 'type': 'LINUX_CONTAINER', + 'variables': { + key1: 'value1', + }, + }, + buildspec: 'version: 0.2\nphases:\n build:\n commands:\n - echo "Hello, from small!"', + }, + { + identifier: 'linux_medium', + env: { + 'compute-type': 'BUILD_GENERAL1_MEDIUM', + 'image': 'aws/codebuild/standard:4.0', + 'type': 'LINUX_CONTAINER', + 'variables': { + key2: 'value2', + }, + }, + buildspec: 'version: 0.2\nphases:\n build:\n commands:\n - echo "Hello, from medium!"', + }, + ], + }, + }), + }); + const buildconfig = project.enableBatchBuilds(); + + if (buildconfig == null) { + throw new Error('Batch builds not enabled'); + } + + const startBuildBatch1 = new tasks.CodeBuildStartBuildBatch(this, 'buildTask1', { + project, + integrationPattern: sfn.IntegrationPattern.REQUEST_RESPONSE, + environmentVariablesOverride: { + test: { + type: codebuild.BuildEnvironmentVariableType.PLAINTEXT, + value: 'testValue', + }, + }, + }); + + const startBuildBatch2 = new tasks.CodeBuildStartBuildBatch(this, 'buildTask2', { + project, + integrationPattern: sfn.IntegrationPattern.RUN_JOB, + environmentVariablesOverride: { + test: { + type: codebuild.BuildEnvironmentVariableType.PLAINTEXT, + value: 'testValue', + }, + }, + }); + + const definition = new sfn.Pass(this, 'Start', { + result: sfn.Result.fromObject({ bar: 'SomeValue' }), + }).next(startBuildBatch1).next(startBuildBatch2); + + new sfn.StateMachine(this, 'StateMachine', { + definition, + }); + } +} + +const app = new cdk.App(); +const stack = new TestStack(app, 'StartBuildBatch'); +new IntegTest(app, 'StartBuildBatchInteg', { + testCases: [stack], +}); + +app.synth(); diff --git a/packages/aws-cdk-lib/aws-stepfunctions-tasks/README.md b/packages/aws-cdk-lib/aws-stepfunctions-tasks/README.md index c19d860f46892..7d6d69da5df58 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions-tasks/README.md +++ b/packages/aws-cdk-lib/aws-stepfunctions-tasks/README.md @@ -386,6 +386,45 @@ const task = new tasks.CodeBuildStartBuild(this, 'Task', { }); ``` +### StartBuildBatch + +[StartBuildBatch](https://docs.aws.amazon.com/codebuild/latest/APIReference/API_StartBuildBatch.html) starts a batch CodeBuild for a project by project name. +It is necessary to enable the batch build feature in the CodeBuild project. + +```ts +import * as codebuild from 'aws-cdk-lib/aws-codebuild'; + +const project = new codebuild.Project(this, 'Project', { + projectName: 'MyTestProject', + buildSpec: codebuild.BuildSpec.fromObjectToYaml({ + version: 0.2, + batch: { + 'build-list': [ + { + identifier: 'id', + buildspec: 'version: 0.2\nphases:\n build:\n commands:\n - echo "Hello, from small!"', + }, + ], + }, + }), +}); +project.enableBatchBuilds(); + +const task = new tasks.CodeBuildStartBuildBatch(this, 'buildBatchTask', { + project, + integrationPattern: sfn.IntegrationPattern.REQUEST_RESPONSE, + environmentVariablesOverride: { + test: { + type: codebuild.BuildEnvironmentVariableType.PLAINTEXT, + value: 'testValue', + }, + }, +}); +``` + +**Note**: `enableBatchBuilds()` will do nothing for imported projects. +If you are using an imported project, you must ensure that the project is already configured for batch builds. + ## DynamoDB You can call DynamoDB APIs from a `Task` state. diff --git a/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/codebuild/start-build-batch.ts b/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/codebuild/start-build-batch.ts new file mode 100644 index 0000000000000..c08c3299b9107 --- /dev/null +++ b/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/codebuild/start-build-batch.ts @@ -0,0 +1,127 @@ +import { Construct } from 'constructs'; +import * as codebuild from '../../../aws-codebuild'; +import * as iam from '../../../aws-iam'; +import * as sfn from '../../../aws-stepfunctions'; +import * as cdk from '../../../core'; +import { integrationResourceArn, validatePatternSupported } from '../private/task-utils'; + +/** + * Properties for CodeBuildStartBuildBatch + */ +export interface CodeBuildStartBuildBatchProps extends sfn.TaskStateBaseProps { + /** + * CodeBuild project to start + */ + readonly project: codebuild.IProject; + + /** + * A set of environment variables to be used for this build only. + * + * @default - the latest environment variables already defined in the build project. + */ + readonly environmentVariablesOverride?: { [name: string]: codebuild.BuildEnvironmentVariable }; +} + +/** + * Start a CodeBuild BatchBuild as a task + * + * @see https://docs.aws.amazon.com/codebuild/latest/APIReference/API_StartBuildBatch.html + */ +export class CodeBuildStartBuildBatch extends sfn.TaskStateBase { + private static readonly SUPPORTED_INTEGRATION_PATTERNS: sfn.IntegrationPattern[] = [ + sfn.IntegrationPattern.REQUEST_RESPONSE, + sfn.IntegrationPattern.RUN_JOB, + ]; + + protected readonly taskMetrics?: sfn.TaskMetricsConfig; + protected readonly taskPolicies?: iam.PolicyStatement[]; + + private readonly integrationPattern: sfn.IntegrationPattern; + + constructor(scope: Construct, id: string, private readonly props: CodeBuildStartBuildBatchProps) { + super(scope, id, props); + this.integrationPattern = props.integrationPattern ?? sfn.IntegrationPattern.REQUEST_RESPONSE; + + validatePatternSupported(this.integrationPattern, CodeBuildStartBuildBatch.SUPPORTED_INTEGRATION_PATTERNS); + + this.taskMetrics = { + metricPrefixSingular: 'CodeBuildProject', + metricPrefixPlural: 'CodeBuildProjects', + metricDimensions: { + ProjectArn: this.props.project.projectArn, + }, + }; + + this.taskPolicies = this.configurePolicyStatements(); + } + + /** + * Configure the necessary permissions to invoke the CodeBuild StartBuildBatch API + * + * @see https://docs.aws.amazon.com/step-functions/latest/dg/codebuild-iam.html#codebuild-iam-startbuildbatch + */ + private configurePolicyStatements(): iam.PolicyStatement[] { + let policyStatements: iam.PolicyStatement[]; + + switch (this.integrationPattern) { + case sfn.IntegrationPattern.RUN_JOB: + policyStatements = [ + new iam.PolicyStatement({ + resources: [this.props.project.projectArn], + actions: [ + 'codebuild:StartBuildBatch', + 'codebuild:StopBuildBatch', + 'codebuild:BatchGetBuildBatches', + ], + }), + new iam.PolicyStatement({ + actions: ['events:PutTargets', 'events:PutRule', 'events:DescribeRule'], + resources: [ + cdk.Stack.of(this).formatArn({ + service: 'events', + resource: 'rule/StepFunctionsGetEventForCodeBuildStartBuildBatchRule', + }), + ], + }), + ]; + break; + case sfn.IntegrationPattern.REQUEST_RESPONSE: + policyStatements = [ + new iam.PolicyStatement({ + resources: [this.props.project.projectArn], + actions: ['codebuild:StartBuildBatch'], + }), + ]; + break; + default: + throw new Error(`Unsupported integration pattern: ${this.integrationPattern}`); + } + + return policyStatements; + } + + /** + * Provides the CodeBuild StartBuild service integration task configuration + * + * @internal + */ + protected _renderTask(): any { + return { + Resource: integrationResourceArn('codebuild', 'startBuildBatch', this.integrationPattern), + Parameters: sfn.FieldUtils.renderObject({ + ProjectName: this.props.project.projectName, + EnvironmentVariablesOverride: this.props.environmentVariablesOverride + ? this.serializeEnvVariables(this.props.environmentVariablesOverride) + : undefined, + }), + }; + } + + private serializeEnvVariables(environmentVariables: { [name: string]: codebuild.BuildEnvironmentVariable }) { + return Object.keys(environmentVariables).map(name => ({ + Name: name, + Type: environmentVariables[name].type || codebuild.BuildEnvironmentVariableType.PLAINTEXT, + Value: environmentVariables[name].value, + })); + } +} diff --git a/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/index.ts b/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/index.ts index 575464d22dcf0..1021c7e9950a6 100644 --- a/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/index.ts +++ b/packages/aws-cdk-lib/aws-stepfunctions-tasks/lib/index.ts @@ -42,6 +42,7 @@ export * from './dynamodb/update-item'; export * from './dynamodb/delete-item'; export * from './dynamodb/shared-types'; export * from './codebuild/start-build'; +export * from './codebuild/start-build-batch'; export * from './athena/start-query-execution'; export * from './athena/stop-query-execution'; export * from './athena/get-query-execution'; diff --git a/packages/aws-cdk-lib/aws-stepfunctions-tasks/test/codebuild/start-build-batch.test.ts b/packages/aws-cdk-lib/aws-stepfunctions-tasks/test/codebuild/start-build-batch.test.ts new file mode 100644 index 0000000000000..15d1d3f71ded3 --- /dev/null +++ b/packages/aws-cdk-lib/aws-stepfunctions-tasks/test/codebuild/start-build-batch.test.ts @@ -0,0 +1,215 @@ +import { Template, Match } from '../../../assertions'; +import * as codebuild from '../../../aws-codebuild'; +import * as sfn from '../../../aws-stepfunctions'; +import * as cdk from '../../../core'; +import { CodeBuildStartBuildBatch } from '../../lib'; + +let stack: cdk.Stack; +let codebuildProject: codebuild.Project; + +beforeEach(() => { + // GIVEN + stack = new cdk.Stack(); + + codebuildProject = new codebuild.Project(stack, 'Project', { + projectName: 'MyTestProject', + buildSpec: codebuild.BuildSpec.fromObjectToYaml({ + version: '0.2', + batch: { + 'fast-fail': true, + 'build-list': [ + { + identifier: 'id', + buildspec: 'version: 0.2\nphases:\n build:\n commands:\n - echo "Hello, CodeBuild!"', + }, + ], + }, + }), + }); + codebuildProject.enableBatchBuilds(); +}); + +test('only the required parameters', () => { + // WHEN + const task = new CodeBuildStartBuildBatch(stack, 'Task', { + project: codebuildProject, + }); + new sfn.StateMachine(stack, 'StateMachine', { + definitionBody: sfn.DefinitionBody.fromChainable(task), + }); + + // THEN + expect(stack.resolve(task.toStateJson())).toEqual({ + Type: 'Task', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:::codebuild:startBuildBatch', + ], + ], + }, + End: true, + Parameters: { + ProjectName: { + Ref: 'ProjectC78D97AD', + }, + }, + }); + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: [{ + Action: 'codebuild:StartBuildBatch', + Effect: 'Allow', + Resource: { + 'Fn::GetAtt': ['ProjectC78D97AD', 'Arn'], + }, + }], + }, + }); +}); + +test('supports tokens', () => { + // WHEN + const task = new CodeBuildStartBuildBatch(stack, 'Task', { + project: codebuildProject, + environmentVariablesOverride: { + ZONE: { + type: codebuild.BuildEnvironmentVariableType.PLAINTEXT, + value: sfn.JsonPath.stringAt('$.envVariables.zone'), + }, + }, + }); + new sfn.StateMachine(stack, 'StateMachine', { + definitionBody: sfn.DefinitionBody.fromChainable(task), + }); + + // THEN + expect(stack.resolve(task.toStateJson())).toEqual({ + Type: 'Task', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:::codebuild:startBuildBatch', + ], + ], + }, + End: true, + Parameters: { + ProjectName: { + Ref: 'ProjectC78D97AD', + }, + EnvironmentVariablesOverride: [ + { + 'Name': 'ZONE', + 'Type': codebuild.BuildEnvironmentVariableType.PLAINTEXT, + 'Value.$': '$.envVariables.zone', + }, + ], + }, + }); +}); + +test('with all the parameters', () => { + // WHEN + const task = new CodeBuildStartBuildBatch(stack, 'Task', { + project: codebuildProject, + integrationPattern: sfn.IntegrationPattern.RUN_JOB, + environmentVariablesOverride: { + env: { + type: codebuild.BuildEnvironmentVariableType.PLAINTEXT, + value: 'prod', + }, + }, + }); + new sfn.StateMachine(stack, 'StateMachine', { + definitionBody: sfn.DefinitionBody.fromChainable(task), + }); + + // THEN + expect(stack.resolve(task.toStateJson())).toEqual({ + Type: 'Task', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':states:::codebuild:startBuildBatch.sync', + ], + ], + }, + End: true, + Parameters: { + ProjectName: { + Ref: 'ProjectC78D97AD', + }, + EnvironmentVariablesOverride: [ + { + Name: 'env', + Type: codebuild.BuildEnvironmentVariableType.PLAINTEXT, + Value: 'prod', + }, + ], + }, + }); + Template.fromStack(stack).hasResourceProperties('AWS::IAM::Policy', { + PolicyDocument: { + Statement: Match.arrayWith([ + { + Action: ['codebuild:StartBuildBatch', 'codebuild:StopBuildBatch', 'codebuild:BatchGetBuildBatches'], + Effect: 'Allow', + Resource: { + 'Fn::GetAtt': ['ProjectC78D97AD', 'Arn'], + }, + }, + { + Action: ['events:PutTargets', 'events:PutRule', 'events:DescribeRule'], + Effect: 'Allow', + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { + Ref: 'AWS::Partition', + }, + ':events:', + { + Ref: 'AWS::Region', + }, + ':', + { + Ref: 'AWS::AccountId', + }, + ':rule/StepFunctionsGetEventForCodeBuildStartBuildBatchRule', + ], + ], + }, + }, + ]), + }, + }); +}); + +test('throw error when WAIT_FOR_TASK_TOKEN is supplied as service integration pattern', () => { + expect(() => { + new CodeBuildStartBuildBatch(stack, 'Task', { + project: codebuildProject, + integrationPattern: sfn.IntegrationPattern.WAIT_FOR_TASK_TOKEN, + }); + }).toThrow( + /Unsupported service integration pattern. Supported Patterns: REQUEST_RESPONSE,RUN_JOB. Received: WAIT_FOR_TASK_TOKEN/, + ); +}); From 54f0f4303a36da8dacdc390311769a9757b2a09b Mon Sep 17 00:00:00 2001 From: armmanvaillancourt <133890309+armmanvaillancourt@users.noreply.github.com> Date: Thu, 7 Mar 2024 15:23:57 -0500 Subject: [PATCH 3/6] chore: typo fix in cli README.md (#29390) ### Reason for this change I was reading the documentation and found a small typo to be fixed. ### Description of changes Fixed the typo ### Description of how you validated changes It's just a README ### Checklist - [X] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk/README.md b/packages/aws-cdk/README.md index 42c3f9f6ec1f3..2b06a12c6b2d4 100644 --- a/packages/aws-cdk/README.md +++ b/packages/aws-cdk/README.md @@ -128,7 +128,7 @@ $ cdk synth $ # Synthesize cloud assembly for StackName, but don't include dependencies $ cdk synth MyStackName --exclusively -$ # Synthesize cloud assembly for StackName, but don't cloudFormation template output to STDOUT +$ # Synthesize cloud assembly for StackName, but don't write CloudFormation template output to STDOUT $ cdk synth MyStackName --quiet ``` From d33cafff6ed72a0e9b4dd0f282b3f1191c4d62c2 Mon Sep 17 00:00:00 2001 From: Parker Scanlon <69879391+scanlonp@users.noreply.github.com> Date: Thu, 7 Mar 2024 12:52:45 -0800 Subject: [PATCH 4/6] fix(cli): prevent changeset diff for non-deployed stacks (#29394) ### Reason for this change When a stack does not exist in CloudFormation, creating a changeset makes an empty `REVIEW_IN_PROGRESS` stack. We then call `delete-stack` to clean up the empty stack. However, this can cause a race condition with a deploy call. ### Description of changes This change prevents changeset diffs for stacks that do not yet exist in CloudFormation. This overrides the changeset diff flag. This change also adds logic for migrate stacks in the old diff logic to represent resource imports without needing the changeset present. ### Description of how you validated changes Testing with new stacks only uses changeset diffs once the stack is deployed. Testing with new migrate stacks only uses changeset diffs once deployed. Pre-deployment the resources correctly show as imports. Note: the deleted test assumes the diff will be calculated using the mocked changeset. The new logic avoids the changeset, so the test is no longer relevant. Closes #29265. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../cloudformation-diff/lib/diff-template.ts | 29 ++++-- packages/aws-cdk/lib/cdk-toolkit.ts | 26 ++++- packages/aws-cdk/lib/diff.ts | 5 +- packages/aws-cdk/test/diff.test.ts | 94 ------------------- 4 files changed, 48 insertions(+), 106 deletions(-) diff --git a/packages/@aws-cdk/cloudformation-diff/lib/diff-template.ts b/packages/@aws-cdk/cloudformation-diff/lib/diff-template.ts index 734753b1d7fc9..1902d757f486d 100644 --- a/packages/@aws-cdk/cloudformation-diff/lib/diff-template.ts +++ b/packages/@aws-cdk/cloudformation-diff/lib/diff-template.ts @@ -37,6 +37,7 @@ const DIFF_HANDLERS: HandlerRegistry = { * @param currentTemplate the current state of the stack. * @param newTemplate the target state of the stack. * @param changeSet the change set for this stack. + * @param isImport if the stack is importing resources (a migrate stack). * * @returns a +types.TemplateDiff+ object that represents the changes that will happen if * a stack which current state is described by +currentTemplate+ is updated with @@ -46,6 +47,7 @@ export function fullDiff( currentTemplate: { [key: string]: any }, newTemplate: { [key: string]: any }, changeSet?: CloudFormation.DescribeChangeSetOutput, + isImport?: boolean, ): types.TemplateDiff { normalize(currentTemplate); @@ -55,6 +57,9 @@ export function fullDiff( filterFalsePositivies(theDiff, changeSet); addImportInformation(theDiff, changeSet); } + if (isImport) { + addImportInformation(theDiff); + } return theDiff; } @@ -209,13 +214,25 @@ function deepCopy(x: any): any { return x; } -function addImportInformation(diff: types.TemplateDiff, changeSet: CloudFormation.DescribeChangeSetOutput) { - const imports = findResourceImports(changeSet); - diff.resources.forEachDifference((logicalId: string, change: types.ResourceDifference) => { - if (imports.includes(logicalId)) { +/** + * Sets import flag to true for resource imports. + * When the changeset parameter is not set, the stack is a new migrate stack, + * so all resource changes are imports. + */ +function addImportInformation(diff: types.TemplateDiff, changeSet?: CloudFormation.DescribeChangeSetOutput) { + if (changeSet) { + const imports = findResourceImports(changeSet); + diff.resources.forEachDifference((logicalId: string, change: types.ResourceDifference) => { + if (imports.includes(logicalId)) { + change.isImport = true; + } + }); + } else { + diff.resources.forEachDifference((logicalId: string, change: types.ResourceDifference) => { + logicalId; // dont know how to get past warning that this variable is not used. change.isImport = true; - } - }); + }); + } } function filterFalsePositivies(diff: types.TemplateDiff, changeSet: CloudFormation.DescribeChangeSetOutput) { diff --git a/packages/aws-cdk/lib/cdk-toolkit.ts b/packages/aws-cdk/lib/cdk-toolkit.ts index 3e721bb47e32a..c67b02dbc9cf2 100644 --- a/packages/aws-cdk/lib/cdk-toolkit.ts +++ b/packages/aws-cdk/lib/cdk-toolkit.ts @@ -136,7 +136,14 @@ export class CdkToolkit { throw new Error(`There is no file at ${options.templatePath}`); } - const changeSet = options.changeSet ? await createDiffChangeSet({ + const stackExistsOptions = { + stack: stacks.firstStack, + deployName: stacks.firstStack.stackName, + }; + + const stackExists = await this.props.deployments.stackExists(stackExistsOptions); + + const changeSet = (stackExists && options.changeSet) ? await createDiffChangeSet({ stack: stacks.firstStack, uuid: uuid.v4(), willExecute: false, @@ -168,13 +175,23 @@ export class CdkToolkit { removeNonImportResources(stack); } - const changeSet = options.changeSet ? await createDiffChangeSet({ + const stackExistsOptions = { + stack, + deployName: stack.stackName, + }; + + const stackExists = await this.props.deployments.stackExists(stackExistsOptions); + + // if the stack does not already exist, do not do a changeset + // this prevents race conditions between deleting the dummy changeset stack and deploying the real changeset stack + // migrate stacks that import resources will not previously exist and default to old diff logic + const changeSet = (stackExists && options.changeSet) ? await createDiffChangeSet({ stack, uuid: uuid.v4(), deployments: this.props.deployments, willExecute: false, sdkProvider: this.props.sdkProvider, - parameters: Object.assign({}, parameterMap['*'], parameterMap[stacks.firstStack.stackName]), + parameters: Object.assign({}, parameterMap['*'], parameterMap[stacks.firstStack.stackName]), // should this be stack? resourcesToImport, stream, }) : undefined; @@ -183,10 +200,11 @@ export class CdkToolkit { stream.write('Parameters and rules created during migration do not affect resource configuration.\n'); } + // pass a boolean to print if the stack is a migrate stack in order to set all resource diffs to import const stackCount = options.securityOnly ? (numberFromBool(printSecurityDiff(currentTemplate, stack, RequireApproval.Broadening, changeSet)) > 0 ? 1 : 0) - : (printStackDiff(currentTemplate, stack, strict, contextLines, quiet, changeSet, stream) > 0 ? 1 : 0); + : (printStackDiff(currentTemplate, stack, strict, contextLines, quiet, changeSet, stream, !!resourcesToImport) > 0 ? 1 : 0); diffs += stackCount + nestedStackCount; } diff --git a/packages/aws-cdk/lib/diff.ts b/packages/aws-cdk/lib/diff.ts index 399f08abeac6a..fa897430ad37b 100644 --- a/packages/aws-cdk/lib/diff.ts +++ b/packages/aws-cdk/lib/diff.ts @@ -23,9 +23,10 @@ export function printStackDiff( context: number, quiet: boolean, changeSet?: CloudFormation.DescribeChangeSetOutput, - stream?: cfnDiff.FormatStream): number { + stream?: cfnDiff.FormatStream, + isImport?: boolean): number { - let diff = cfnDiff.fullDiff(oldTemplate, newTemplate.template, changeSet); + let diff = cfnDiff.fullDiff(oldTemplate, newTemplate.template, changeSet, isImport); // detect and filter out mangled characters from the diff let filteredChangesCount = 0; diff --git a/packages/aws-cdk/test/diff.test.ts b/packages/aws-cdk/test/diff.test.ts index a92c6d53551c3..a7b5905e12f87 100644 --- a/packages/aws-cdk/test/diff.test.ts +++ b/packages/aws-cdk/test/diff.test.ts @@ -12,100 +12,6 @@ let cloudExecutable: MockCloudExecutable; let cloudFormation: jest.Mocked; let toolkit: CdkToolkit; -describe('imports', () => { - beforeEach(() => { - jest.spyOn(cfn, 'createDiffChangeSet').mockImplementation(async () => { - return { - Changes: [ - { - ResourceChange: { - Action: 'Import', - LogicalResourceId: 'Queue', - }, - }, - { - ResourceChange: { - Action: 'Import', - LogicalResourceId: 'Bucket', - }, - }, - { - ResourceChange: { - Action: 'Import', - LogicalResourceId: 'Queue2', - }, - }, - ], - }; - }); - cloudExecutable = new MockCloudExecutable({ - stacks: [{ - stackName: 'A', - template: { - Resources: { - Queue: { - Type: 'AWS::SQS::Queue', - }, - Queue2: { - Type: 'AWS::SQS::Queue', - }, - Bucket: { - Type: 'AWS::S3::Bucket', - }, - }, - }, - }], - }); - - cloudFormation = instanceMockFrom(Deployments); - - toolkit = new CdkToolkit({ - cloudExecutable, - deployments: cloudFormation, - configuration: cloudExecutable.configuration, - sdkProvider: cloudExecutable.sdkProvider, - }); - - // Default implementations - cloudFormation.readCurrentTemplateWithNestedStacks.mockImplementation((_stackArtifact: CloudFormationStackArtifact) => { - return Promise.resolve({ - deployedTemplate: {}, - nestedStackCount: 0, - }); - }); - cloudFormation.deployStack.mockImplementation((options) => Promise.resolve({ - noOp: true, - outputs: {}, - stackArn: '', - stackArtifact: options.stack, - })); - }); - - test('imports', async () => { - // GIVEN - const buffer = new StringWritable(); - - // WHEN - const exitCode = await toolkit.diff({ - stackNames: ['A'], - stream: buffer, - changeSet: true, - }); - - // THEN - const plainTextOutput = buffer.data.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, ''); - expect(plainTextOutput).toContain(`Stack A -Resources -[←] AWS::SQS::Queue Queue import -[←] AWS::SQS::Queue Queue2 import -[←] AWS::S3::Bucket Bucket import -`); - - expect(buffer.data.trim()).toContain('✨ Number of stacks with differences: 1'); - expect(exitCode).toBe(0); - }); -}); - describe('non-nested stacks', () => { beforeEach(() => { cloudExecutable = new MockCloudExecutable({ From 3fb0254552c73e3467aeaee107423364206bca4e Mon Sep 17 00:00:00 2001 From: GZ Date: Thu, 7 Mar 2024 14:10:08 -0800 Subject: [PATCH 5/6] fix(spec2cdk): use modern type when building tag type (#29389) ### Issue # (if applicable) Closes https://github.com/aws/aws-cdk/issues/29388 ### Reason for this change Some of the modern tags failed to run `cdk synth` due to type misconfiguration. ### Description of changes Always default to use the latest type for modern tags. ### Description of how you validated changes Fixed for failed resources. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../aws-cdk-lib/aws-xray/test/xray.test.ts | 41 +++++++++++++++++++ .../spec2cdk/lib/cdk/resource-decider.ts | 2 +- .../spec2cdk/lib/cdk/type-converter.ts | 10 +++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 packages/aws-cdk-lib/aws-xray/test/xray.test.ts diff --git a/packages/aws-cdk-lib/aws-xray/test/xray.test.ts b/packages/aws-cdk-lib/aws-xray/test/xray.test.ts new file mode 100644 index 0000000000000..6f4df4fc6f0dd --- /dev/null +++ b/packages/aws-cdk-lib/aws-xray/test/xray.test.ts @@ -0,0 +1,41 @@ +import { Match, Template } from '../../assertions'; +import * as iam from '../../aws-iam'; +import * as kms from '../../aws-kms'; +import { CfnParameter, Duration, Stack, App, Token, Tags } from '../../core'; +import * as xray from '../lib'; + +/* eslint-disable quote-props */ + +test('able to add tags to XRay CfnGroup', () => { + const stack = new Stack(); + new xray.CfnGroup(stack, 'Group', { + groupName: 'GroupName', + tags: [{ + key: 'Key', + value: 'Value', + }], + }); + + Template.fromStack(stack).hasResourceProperties('AWS::XRay::Group', { + Tags: [{ + Key: 'Key', + Value: 'Value', + }], + }); +}); + +test('able to add tags through Tags.of()... to XRay CfnGroup', () => { + const stack = new Stack(); + new xray.CfnGroup(stack, 'Group', { + groupName: 'GroupName', + }); + + Tags.of(stack).add('Key', 'Value'); + + Template.fromStack(stack).hasResourceProperties('AWS::XRay::Group', { + Tags: [{ + Key: 'Key', + Value: 'Value', + }], + }); +}); diff --git a/tools/@aws-cdk/spec2cdk/lib/cdk/resource-decider.ts b/tools/@aws-cdk/spec2cdk/lib/cdk/resource-decider.ts index 2db62bb3d0b4a..7b981cacb8fd7 100644 --- a/tools/@aws-cdk/spec2cdk/lib/cdk/resource-decider.ts +++ b/tools/@aws-cdk/spec2cdk/lib/cdk/resource-decider.ts @@ -179,7 +179,7 @@ export class ResourceDecider { private handleTagPropertyModern(cfnName: string, prop: Property, variant: TagVariant) { const originalName = propertyNameFromCloudFormation(cfnName); - const originalType = this.converter.typeFromProperty(prop); + const originalType = this.converter.typeFromPropertyForModernTags(prop); this.propsProperties.push({ propertySpec: { diff --git a/tools/@aws-cdk/spec2cdk/lib/cdk/type-converter.ts b/tools/@aws-cdk/spec2cdk/lib/cdk/type-converter.ts index df3a215e503e5..5accddfe15da2 100644 --- a/tools/@aws-cdk/spec2cdk/lib/cdk/type-converter.ts +++ b/tools/@aws-cdk/spec2cdk/lib/cdk/type-converter.ts @@ -96,6 +96,16 @@ export class TypeConverter { return this.typeFromSpecType(this.typeHistoryFromProperty(property)[0]); } + /** + * Return the appropriate typewriter type for a servicespec type for modern tags + * Unlike typeFromProperty, we want to default to use the newest type instead. + */ + public typeFromPropertyForModernTags(property: Property): Type { + // For backwards compatibility reasons we always have to use the original type + const types = this.typeHistoryFromProperty(property); + return this.typeFromSpecType(types[types.length - 1]); + } + /** * Return the full type history for a servicespec property */ From ba41996939a4c0b06e954c7de7232adef4ce78f5 Mon Sep 17 00:00:00 2001 From: GZ Date: Thu, 7 Mar 2024 15:03:13 -0800 Subject: [PATCH 6/6] fix(s3): revert incorrect account used for S3 event source mapping (#29405) Reverts aws/aws-cdk#29365 as it causes test failure. --- .../aws-lambda-event-sources/test/s3.test.ts | 82 ------------------- .../aws-s3-notifications/lib/lambda.ts | 2 +- packages/aws-cdk-lib/aws-s3/lib/bucket.ts | 20 ++--- 3 files changed, 8 insertions(+), 96 deletions(-) diff --git a/packages/aws-cdk-lib/aws-lambda-event-sources/test/s3.test.ts b/packages/aws-cdk-lib/aws-lambda-event-sources/test/s3.test.ts index 67b63190e315f..f5ab8a7fc4bb3 100644 --- a/packages/aws-cdk-lib/aws-lambda-event-sources/test/s3.test.ts +++ b/packages/aws-cdk-lib/aws-lambda-event-sources/test/s3.test.ts @@ -228,86 +228,4 @@ describe('S3EventSource', () => { }, }); }); - test('Cross account buckect access', () => { - // GIVEN - const app = new cdk.App(); - const stack = new cdk.Stack(app, 'stack'); - const fn = new TestFunction(stack, 'Fn'); - - let accountB = '1234567'; - //WHEN - const foreignBucket = - s3.Bucket.fromBucketAttributes(stack, 'ImportedBucket', { - bucketArn: 'arn:aws:s3:::some-bucket-not-in-this-account', - // The account the bucket really lives in - account: accountB, - }); - - // This will generate the IAM bindings - fn.addEventSource(new sources.S3EventSource(foreignBucket as s3.Bucket, - { events: [s3.EventType.OBJECT_CREATED] })); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { - 'Principal': 's3.amazonaws.com', - 'SourceAccount': '1234567', - 'SourceArn': 'arn:aws:s3:::some-bucket-not-in-this-account', - }); - }); - - test('Test bucket account is referenced intrinsicly', () => { - // GIVEN - const stack = new cdk.Stack(); - const fn = new TestFunction(stack, 'Fn'); - const bucket = new s3.Bucket(stack, 'B'); - - // WHEN - fn.addEventSource(new sources.S3EventSource(bucket, { - events: [s3.EventType.OBJECT_CREATED, s3.EventType.OBJECT_REMOVED], - filters: [ - { prefix: 'prefix/' }, - { suffix: '.png' }, - ], - })); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { - 'Principal': 's3.amazonaws.com', - 'SourceAccount': { - 'Ref': 'AWS::AccountId', - }, - 'SourceArn': { - 'Fn::GetAtt': ['B08E7C7AF', 'Arn'], - }, - }); - }); - - test('Default to stack account if bucket account doesnt exist', () => { - // GIVEN - const app = new cdk.App(); - const stack = new cdk.Stack(app, 'stack'); - const fn = new TestFunction(stack, 'Fn'); - - let accountB = ''; - //WHEN - const foreignBucket = - s3.Bucket.fromBucketAttributes(stack, 'ImportedBucket', { - bucketArn: 'arn:aws:s3:::some-bucket-not-in-this-account', - // The account the bucket really lives in - account: accountB, - }); - - // This will generate the IAM bindings - fn.addEventSource(new sources.S3EventSource(foreignBucket as s3.Bucket, - { events: [s3.EventType.OBJECT_CREATED] })); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Lambda::Permission', { - 'Principal': 's3.amazonaws.com', - 'SourceAccount': { - 'Ref': 'AWS::AccountId', - }, - 'SourceArn': 'arn:aws:s3:::some-bucket-not-in-this-account', - }); - }); }); diff --git a/packages/aws-cdk-lib/aws-s3-notifications/lib/lambda.ts b/packages/aws-cdk-lib/aws-s3-notifications/lib/lambda.ts index d7e9758eeecb8..e6159ff8c22aa 100644 --- a/packages/aws-cdk-lib/aws-s3-notifications/lib/lambda.ts +++ b/packages/aws-cdk-lib/aws-s3-notifications/lib/lambda.ts @@ -21,7 +21,7 @@ export class LambdaDestination implements s3.IBucketNotificationDestination { if (bucket.node.tryFindChild(permissionId) === undefined) { this.fn.addPermission(permissionId, { - sourceAccount: bucket.account || Stack.of(bucket).account, + sourceAccount: Stack.of(bucket).account, principal: new iam.ServicePrincipal('s3.amazonaws.com'), sourceArn: bucket.bucketArn, // Placing the permissions node in the same scope as the s3 bucket. diff --git a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts index d1d1c255f3513..a799062afc692 100644 --- a/packages/aws-cdk-lib/aws-s3/lib/bucket.ts +++ b/packages/aws-cdk-lib/aws-s3/lib/bucket.ts @@ -95,11 +95,6 @@ export interface IBucket extends IResource { */ policy?: BucketPolicy; - /** - * The account bucket belongs to. - */ - readonly account?: string; - /** * Adds a statement to the resource policy for a principal (i.e. * account/role/service) to perform actions on this bucket and/or its @@ -1759,7 +1754,6 @@ export class Bucket extends BucketBase { public readonly bucketWebsiteNewUrlFormat = attrs.bucketWebsiteNewUrlFormat ?? false; public readonly encryptionKey = attrs.encryptionKey; public readonly isWebsite = attrs.isWebsite ?? false; - public readonly account = attrs.account; public policy?: BucketPolicy = undefined; protected autoCreatePolicy = false; protected disallowPublicAccess = false; @@ -1973,11 +1967,11 @@ export class Bucket extends BucketBase { if (props.serverAccessLogsBucket instanceof Bucket) { props.serverAccessLogsBucket.allowLogDelivery(this, props.serverAccessLogsPrefix); - // It is possible that `serverAccessLogsBucket` was specified but is some other `IBucket` - // that cannot have the ACLs or bucket policy applied. In that scenario, we should only - // setup log delivery permissions to `this` if a bucket was not specified at all, as documented. - // For example, we should not allow log delivery to `this` if given an imported bucket or - // another situation that causes `instanceof` to fail + // It is possible that `serverAccessLogsBucket` was specified but is some other `IBucket` + // that cannot have the ACLs or bucket policy applied. In that scenario, we should only + // setup log delivery permissions to `this` if a bucket was not specified at all, as documented. + // For example, we should not allow log delivery to `this` if given an imported bucket or + // another situation that causes `instanceof` to fail } else if (!props.serverAccessLogsBucket && props.serverAccessLogsPrefix) { this.allowLogDelivery(this, props.serverAccessLogsPrefix); } else if (props.serverAccessLogsBucket) { @@ -2231,7 +2225,7 @@ export class Bucket extends BucketBase { function parseLifecycleRule(rule: LifecycleRule): CfnBucket.RuleProperty { const enabled = rule.enabled ?? true; if ((rule.expiredObjectDeleteMarker) - && (rule.expiration || rule.expirationDate || self.parseTagFilters(rule.tagFilters))) { + && (rule.expiration || rule.expirationDate || self.parseTagFilters(rule.tagFilters))) { // ExpiredObjectDeleteMarker cannot be specified with ExpirationInDays, ExpirationDate, or TagFilters. throw new Error('ExpiredObjectDeleteMarker cannot be specified with expiration, ExpirationDate, or TagFilters.'); } @@ -2356,7 +2350,7 @@ export class Bucket extends BucketBase { } if (accessControlRequiresObjectOwnership && this.objectOwnership === ObjectOwnership.BUCKET_OWNER_ENFORCED) { - throw new Error(`objectOwnership must be set to "${ObjectOwnership.OBJECT_WRITER}" when accessControl is "${this.accessControl}"`); + throw new Error (`objectOwnership must be set to "${ObjectOwnership.OBJECT_WRITER}" when accessControl is "${this.accessControl}"`); } return {