From 8243601866e8c1771a18adb4c93579a7099984e3 Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Tue, 14 Nov 2023 18:21:47 +0100 Subject: [PATCH 1/8] fix(elasticloadbalancingv2): access logging fails on imported bucket (#27948) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/aws/aws-cdk/pull/27558 fixed a circular dependency issue between the bucket and the ELB when using `logAccessLogs` by adding the dependency at the L1 level. The dependency was added on both the bucket and the bucket policy (which already refers to the bucket). This introduced a new bug when adding a dependency for imported buckets (as `bucket.node.defaultChild` is `undefined`). This PR fixes the issue by adding the dependency at the L1 level on the bucket policy directly. Closes #27928. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...-alb-log-imported-bucket-integ.assets.json | 20 + ...lb-log-imported-bucket-integ.template.json | 655 ++++++++++ .../cdk.out | 1 + ...efaultTestDeployAssert163162C1.assets.json | 19 + ...aultTestDeployAssert163162C1.template.json | 36 + .../integ.json | 13 + .../manifest.json | 281 +++++ .../tree.json | 1066 +++++++++++++++++ .../test/integ.alb.log.imported-bucket.ts | 48 + .../lib/shared/base-load-balancer.ts | 28 +- .../test/alb/load-balancer.test.ts | 101 +- .../test/nlb/load-balancer.test.ts | 112 +- 12 files changed, 2359 insertions(+), 21 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/aws-cdk-alb-log-imported-bucket-integ.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/aws-cdk-alb-log-imported-bucket-integ.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/aws-cdk-alb-log-imported-bucket-integ.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/aws-cdk-alb-log-imported-bucket-integ.assets.json new file mode 100644 index 0000000000000..3e91c58d25201 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/aws-cdk-alb-log-imported-bucket-integ.assets.json @@ -0,0 +1,20 @@ +{ + "version": "34.0.0", + "files": { + "d102d01a93a63d71a570164bdea30b0eca472ac745027643a4a1b0adb9b0640b": { + "source": { + "path": "aws-cdk-alb-log-imported-bucket-integ.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-us-west-2": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-us-west-2", + "objectKey": "d102d01a93a63d71a570164bdea30b0eca472ac745027643a4a1b0adb9b0640b.json", + "region": "us-west-2", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-us-west-2" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/aws-cdk-alb-log-imported-bucket-integ.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/aws-cdk-alb-log-imported-bucket-integ.template.json new file mode 100644 index 0000000000000..e596a9c1e41e8 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/aws-cdk-alb-log-imported-bucket-integ.template.json @@ -0,0 +1,655 @@ +{ + "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-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PublicSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet1RouteTableFEE4B781": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PublicSubnet1" + } + ] + } + }, + "VPCPublicSubnet1NATGatewayE0556630": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet1EIP6AD938E8", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PublicSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPublicSubnet2RouteTable6F1A15F1": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PublicSubnet2" + } + ] + } + }, + "VPCPublicSubnet2NATGateway3C070193": { + "Type": "AWS::EC2::NatGateway", + "Properties": { + "AllocationId": { + "Fn::GetAtt": [ + "VPCPublicSubnet2EIP4947BC00", + "AllocationId" + ] + }, + "SubnetId": { + "Ref": "VPCPublicSubnet2Subnet74179F39" + }, + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PrivateSubnet1" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet1RouteTableBE8A6027": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PrivateSubnet2" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "VPCPrivateSubnet2RouteTable0A19E10E": { + "Type": "AWS::EC2::RouteTable", + "Properties": { + "Tags": [ + { + "Key": "Name", + "Value": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC" + } + ] + } + }, + "VPCVPCGW99B986DC": { + "Type": "AWS::EC2::VPCGatewayAttachment", + "Properties": { + "InternetGatewayId": { + "Ref": "VPCIGWB7E252D3" + }, + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "Bucket83908E77": { + "Type": "AWS::S3::Bucket", + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "ImportedBucketPolicyAE50CA2C": { + "Type": "AWS::S3::BucketPolicy", + "Properties": { + "Bucket": { + "Ref": "Bucket83908E77" + }, + "PolicyDocument": { + "Statement": [ + { + "Action": "s3:PutObject", + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::797873946194:root" + }, + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "Bucket83908E77" + }, + "/prefix/AWSLogs/", + { + "Ref": "AWS::AccountId" + }, + "/*" + ] + ] + } + }, + { + "Action": "s3:PutObject", + "Condition": { + "StringEquals": { + "s3:x-amz-acl": "bucket-owner-full-control" + } + }, + "Effect": "Allow", + "Principal": { + "Service": "delivery.logs.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "Bucket83908E77" + }, + "/prefix/AWSLogs/", + { + "Ref": "AWS::AccountId" + }, + "/*" + ] + ] + } + }, + { + "Action": "s3:GetBucketAcl", + "Effect": "Allow", + "Principal": { + "Service": "delivery.logs.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "Bucket83908E77" + } + ] + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, + "LB8A12904C": { + "Type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "Properties": { + "LoadBalancerAttributes": [ + { + "Key": "deletion_protection.enabled", + "Value": "false" + }, + { + "Key": "access_logs.s3.enabled", + "Value": "true" + }, + { + "Key": "access_logs.s3.bucket", + "Value": { + "Ref": "Bucket83908E77" + } + }, + { + "Key": "access_logs.s3.prefix", + "Value": "prefix" + } + ], + "Scheme": "internet-facing", + "SecurityGroups": [ + { + "Fn::GetAtt": [ + "LBSecurityGroup8A41EA2B", + "GroupId" + ] + } + ], + "Subnets": [ + { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + ], + "Type": "application" + }, + "DependsOn": [ + "ImportedBucketPolicyAE50CA2C", + "VPCPublicSubnet1DefaultRoute91CEF279", + "VPCPublicSubnet1RouteTableAssociation0B0896DC", + "VPCPublicSubnet2DefaultRouteB7481BBA", + "VPCPublicSubnet2RouteTableAssociation5A808732" + ] + }, + "LBSecurityGroup8A41EA2B": { + "Type": "AWS::EC2::SecurityGroup", + "Properties": { + "GroupDescription": "Automatically created Security Group for ELB awscdkalblogimportedbucketintegLB30D70CE3", + "SecurityGroupEgress": [ + { + "CidrIp": "255.255.255.255/32", + "Description": "Disallow all traffic", + "FromPort": 252, + "IpProtocol": "icmp", + "ToPort": 86 + } + ], + "SecurityGroupIngress": [ + { + "CidrIp": "0.0.0.0/0", + "Description": "Allow from anyone on port 80", + "FromPort": 80, + "IpProtocol": "tcp", + "ToPort": 80 + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "LBListener49E825B4": { + "Type": "AWS::ElasticLoadBalancingV2::Listener", + "Properties": { + "DefaultActions": [ + { + "TargetGroupArn": { + "Ref": "LBListenerTargetGroupF04FCF6D" + }, + "Type": "forward" + } + ], + "LoadBalancerArn": { + "Ref": "LB8A12904C" + }, + "Port": 80, + "Protocol": "HTTP" + } + }, + "LBListenerTargetGroupF04FCF6D": { + "Type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "Properties": { + "Port": 80, + "Protocol": "HTTP", + "TargetGroupAttributes": [ + { + "Key": "stickiness.enabled", + "Value": "true" + }, + { + "Key": "stickiness.type", + "Value": "lb_cookie" + }, + { + "Key": "stickiness.lb_cookie.duration_seconds", + "Value": "300" + } + ], + "TargetType": "ip", + "Targets": [ + { + "Id": "10.0.128.6" + } + ], + "VpcId": { + "Ref": "VPCB9E5F0B4" + } + }, + "DependsOn": [ + "VPCPublicSubnet1DefaultRoute91CEF279", + "VPCPublicSubnet1EIP6AD938E8", + "VPCPublicSubnet1NATGatewayE0556630", + "VPCPublicSubnet1RouteTableFEE4B781", + "VPCPublicSubnet1RouteTableAssociation0B0896DC", + "VPCPublicSubnet1SubnetB4246D30", + "VPCPublicSubnet2DefaultRouteB7481BBA", + "VPCPublicSubnet2EIP4947BC00", + "VPCPublicSubnet2NATGateway3C070193", + "VPCPublicSubnet2RouteTable6F1A15F1", + "VPCPublicSubnet2RouteTableAssociation5A808732", + "VPCPublicSubnet2Subnet74179F39" + ] + } + }, + "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-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/cdk.out new file mode 100644 index 0000000000000..2313ab5436501 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1.assets.json new file mode 100644 index 0000000000000..e45f2e7f3aa99 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1.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-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1.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-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/integ.json new file mode 100644 index 0000000000000..5198aa8d08cc7 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/integ.json @@ -0,0 +1,13 @@ +{ + "version": "34.0.0", + "testCases": { + "cdk-integ-alb-log-imported-bucket/DefaultTest": { + "stacks": [ + "aws-cdk-alb-log-imported-bucket-integ" + ], + "diffAssets": true, + "assertionStack": "cdk-integ-alb-log-imported-bucket/DefaultTest/DeployAssert", + "assertionStackName": "cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/manifest.json new file mode 100644 index 0000000000000..4c9a325295e57 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/manifest.json @@ -0,0 +1,281 @@ +{ + "version": "34.0.0", + "artifacts": { + "aws-cdk-alb-log-imported-bucket-integ.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "aws-cdk-alb-log-imported-bucket-integ.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "aws-cdk-alb-log-imported-bucket-integ": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/us-west-2", + "properties": { + "templateFile": "aws-cdk-alb-log-imported-bucket-integ.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-us-west-2", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-us-west-2", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-us-west-2/d102d01a93a63d71a570164bdea30b0eca472ac745027643a4a1b0adb9b0640b.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "aws-cdk-alb-log-imported-bucket-integ.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-us-west-2", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "aws-cdk-alb-log-imported-bucket-integ.assets" + ], + "metadata": { + "/aws-cdk-alb-log-imported-bucket-integ/VPC/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCB9E5F0B4" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1SubnetB4246D30" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1RouteTableFEE4B781" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1RouteTableAssociation0B0896DC" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1DefaultRoute91CEF279" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet1/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1EIP6AD938E8" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet1/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet1NATGatewayE0556630" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2Subnet74179F39" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2RouteTable6F1A15F1" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2RouteTableAssociation5A808732" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2DefaultRouteB7481BBA" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet2/EIP": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2EIP4947BC00" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet2/NATGateway": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPublicSubnet2NATGateway3C070193" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PrivateSubnet1/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1Subnet8BCA10E0" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PrivateSubnet1/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1RouteTableBE8A6027" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PrivateSubnet1/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1RouteTableAssociation347902D1" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PrivateSubnet1/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet1DefaultRouteAE1D6490" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PrivateSubnet2/Subnet": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2SubnetCFCDAA7A" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PrivateSubnet2/RouteTable": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2RouteTable0A19E10E" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PrivateSubnet2/RouteTableAssociation": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2RouteTableAssociation0C73D413" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/PrivateSubnet2/DefaultRoute": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCPrivateSubnet2DefaultRouteF4F5CFD2" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/IGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCIGWB7E252D3" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/VPC/VPCGW": [ + { + "type": "aws:cdk:logicalId", + "data": "VPCVPCGW99B986DC" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/Bucket/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Bucket83908E77" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/ImportedBucket/Policy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "ImportedBucketPolicy71C80354" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/LB/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LB8A12904C" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/LB/SecurityGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LBSecurityGroup8A41EA2B" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/LB/Listener/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LBListener49E825B4" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/LB/Listener/TargetGroup/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LBListenerTargetGroupF04FCF6D" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/aws-cdk-alb-log-imported-bucket-integ/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "aws-cdk-alb-log-imported-bucket-integ" + }, + "cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1.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": [ + "cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1.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": [ + "cdkintegalblogimportedbucketDefaultTestDeployAssert163162C1.assets" + ], + "metadata": { + "/cdk-integ-alb-log-imported-bucket/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/cdk-integ-alb-log-imported-bucket/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "cdk-integ-alb-log-imported-bucket/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-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/tree.json new file mode 100644 index 0000000000000..ebc9d24af07a2 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.js.snapshot/tree.json @@ -0,0 +1,1066 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "aws-cdk-alb-log-imported-bucket-integ": { + "id": "aws-cdk-alb-log-imported-bucket-integ", + "path": "aws-cdk-alb-log-imported-bucket-integ", + "children": { + "VPC": { + "id": "VPC", + "path": "aws-cdk-alb-log-imported-bucket-integ/VPC", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnVPC", + "version": "0.0.0" + } + }, + "PublicSubnet1": { + "id": "PublicSubnet1", + "path": "aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PublicSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet1/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PublicSubnet1/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet1" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PublicSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PublicSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet2/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PublicSubnet2/EIP", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::EIP", + "aws:cdk:cloudformation:props": { + "domain": "vpc", + "tags": [ + { + "key": "Name", + "value": "aws-cdk-alb-log-imported-bucket-integ/VPC/PublicSubnet2" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnEIP", + "version": "0.0.0" + } + }, + "NATGateway": { + "id": "NATGateway", + "path": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PrivateSubnet1", + "children": { + "Subnet": { + "id": "Subnet", + "path": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PrivateSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "aws-cdk-alb-log-imported-bucket-integ/VPC/PrivateSubnet1/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "aws-cdk-alb-log-imported-bucket-integ/VPC/PrivateSubnet1/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "aws-cdk-alb-log-imported-bucket-integ/VPC/PrivateSubnet1" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PrivateSubnet2", + "children": { + "Subnet": { + "id": "Subnet", + "path": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/PrivateSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnSubnet", + "version": "0.0.0" + } + }, + "Acl": { + "id": "Acl", + "path": "aws-cdk-alb-log-imported-bucket-integ/VPC/PrivateSubnet2/Acl", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "RouteTable": { + "id": "RouteTable", + "path": "aws-cdk-alb-log-imported-bucket-integ/VPC/PrivateSubnet2/RouteTable", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::RouteTable", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "aws-cdk-alb-log-imported-bucket-integ/VPC/PrivateSubnet2" + } + ], + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnRouteTable", + "version": "0.0.0" + } + }, + "RouteTableAssociation": { + "id": "RouteTableAssociation", + "path": "aws-cdk-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/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-alb-log-imported-bucket-integ/VPC/IGW", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::InternetGateway", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "Name", + "value": "aws-cdk-alb-log-imported-bucket-integ/VPC" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_ec2.CfnInternetGateway", + "version": "0.0.0" + } + }, + "VPCGW": { + "id": "VPCGW", + "path": "aws-cdk-alb-log-imported-bucket-integ/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" + } + }, + "Bucket": { + "id": "Bucket", + "path": "aws-cdk-alb-log-imported-bucket-integ/Bucket", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-alb-log-imported-bucket-integ/Bucket/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": {} + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.Bucket", + "version": "0.0.0" + } + }, + "ImportedBucket": { + "id": "ImportedBucket", + "path": "aws-cdk-alb-log-imported-bucket-integ/ImportedBucket", + "children": { + "Policy": { + "id": "Policy", + "path": "aws-cdk-alb-log-imported-bucket-integ/ImportedBucket/Policy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-alb-log-imported-bucket-integ/ImportedBucket/Policy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::BucketPolicy", + "aws:cdk:cloudformation:props": { + "bucket": { + "Ref": "Bucket83908E77" + }, + "policyDocument": { + "Statement": [ + { + "Action": "s3:PutObject", + "Effect": "Allow", + "Principal": { + "AWS": "arn:aws:iam::797873946194:root" + }, + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "Bucket83908E77" + }, + "/prefix/AWSLogs/", + { + "Ref": "AWS::AccountId" + }, + "/*" + ] + ] + } + }, + { + "Action": "s3:PutObject", + "Condition": { + "StringEquals": { + "s3:x-amz-acl": "bucket-owner-full-control" + } + }, + "Effect": "Allow", + "Principal": { + "Service": "delivery.logs.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "Bucket83908E77" + }, + "/prefix/AWSLogs/", + { + "Ref": "AWS::AccountId" + }, + "/*" + ] + ] + } + }, + { + "Action": "s3:GetBucketAcl", + "Effect": "Allow", + "Principal": { + "Service": "delivery.logs.amazonaws.com" + }, + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:s3:::", + { + "Ref": "Bucket83908E77" + } + ] + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.CfnBucketPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.BucketPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.BucketBase", + "version": "0.0.0" + } + }, + "LB": { + "id": "LB", + "path": "aws-cdk-alb-log-imported-bucket-integ/LB", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-alb-log-imported-bucket-integ/LB/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::LoadBalancer", + "aws:cdk:cloudformation:props": { + "loadBalancerAttributes": [ + { + "key": "deletion_protection.enabled", + "value": "false" + }, + { + "key": "access_logs.s3.enabled", + "value": "true" + }, + { + "key": "access_logs.s3.bucket", + "value": { + "Ref": "Bucket83908E77" + } + }, + { + "key": "access_logs.s3.prefix", + "value": "prefix" + } + ], + "scheme": "internet-facing", + "securityGroups": [ + { + "Fn::GetAtt": [ + "LBSecurityGroup8A41EA2B", + "GroupId" + ] + } + ], + "subnets": [ + { + "Ref": "VPCPublicSubnet1SubnetB4246D30" + }, + { + "Ref": "VPCPublicSubnet2Subnet74179F39" + } + ], + "type": "application" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnLoadBalancer", + "version": "0.0.0" + } + }, + "SecurityGroup": { + "id": "SecurityGroup", + "path": "aws-cdk-alb-log-imported-bucket-integ/LB/SecurityGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-alb-log-imported-bucket-integ/LB/SecurityGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::EC2::SecurityGroup", + "aws:cdk:cloudformation:props": { + "groupDescription": "Automatically created Security Group for ELB awscdkalblogimportedbucketintegLB30D70CE3", + "securityGroupEgress": [ + { + "cidrIp": "255.255.255.255/32", + "description": "Disallow all traffic", + "ipProtocol": "icmp", + "fromPort": 252, + "toPort": 86 + } + ], + "securityGroupIngress": [ + { + "cidrIp": "0.0.0.0/0", + "ipProtocol": "tcp", + "fromPort": 80, + "toPort": 80, + "description": "Allow from anyone on port 80" + } + ], + "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" + } + }, + "Listener": { + "id": "Listener", + "path": "aws-cdk-alb-log-imported-bucket-integ/LB/Listener", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-alb-log-imported-bucket-integ/LB/Listener/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::Listener", + "aws:cdk:cloudformation:props": { + "defaultActions": [ + { + "type": "forward", + "targetGroupArn": { + "Ref": "LBListenerTargetGroupF04FCF6D" + } + } + ], + "loadBalancerArn": { + "Ref": "LB8A12904C" + }, + "port": 80, + "protocol": "HTTP" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnListener", + "version": "0.0.0" + } + }, + "TargetGroup": { + "id": "TargetGroup", + "path": "aws-cdk-alb-log-imported-bucket-integ/LB/Listener/TargetGroup", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-alb-log-imported-bucket-integ/LB/Listener/TargetGroup/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ElasticLoadBalancingV2::TargetGroup", + "aws:cdk:cloudformation:props": { + "port": 80, + "protocol": "HTTP", + "targetGroupAttributes": [ + { + "key": "stickiness.enabled", + "value": "true" + }, + { + "key": "stickiness.type", + "value": "lb_cookie" + }, + { + "key": "stickiness.lb_cookie.duration_seconds", + "value": "300" + } + ], + "targets": [ + { + "id": "10.0.128.6" + } + ], + "targetType": "ip", + "vpcId": { + "Ref": "VPCB9E5F0B4" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.CfnTargetGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationTargetGroup", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationListener", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_elasticloadbalancingv2.ApplicationLoadBalancer", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "aws-cdk-alb-log-imported-bucket-integ/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "aws-cdk-alb-log-imported-bucket-integ/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "cdk-integ-alb-log-imported-bucket": { + "id": "cdk-integ-alb-log-imported-bucket", + "path": "cdk-integ-alb-log-imported-bucket", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "cdk-integ-alb-log-imported-bucket/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "cdk-integ-alb-log-imported-bucket/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "cdk-integ-alb-log-imported-bucket/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "cdk-integ-alb-log-imported-bucket/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "cdk-integ-alb-log-imported-bucket/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-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.ts new file mode 100644 index 0000000000000..0aefeaa37378e --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-elasticloadbalancingv2/test/integ.alb.log.imported-bucket.ts @@ -0,0 +1,48 @@ +#!/usr/bin/env node +import * as ec2 from 'aws-cdk-lib/aws-ec2'; +import * as s3 from 'aws-cdk-lib/aws-s3'; +import * as cdk from 'aws-cdk-lib'; +import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import { EC2_RESTRICT_DEFAULT_SECURITY_GROUP } from 'aws-cdk-lib/cx-api'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'aws-cdk-alb-log-imported-bucket-integ', { env: { region: 'us-west-2' } }); +stack.node.setContext(EC2_RESTRICT_DEFAULT_SECURITY_GROUP, false); + +const vpc = new ec2.Vpc(stack, 'VPC', { + maxAzs: 2, +}); + +const bucket = new s3.Bucket(stack, 'Bucket'); +const importedBucket = s3.Bucket.fromBucketName(stack, 'ImportedBucket', bucket.bucketName); +// Imported buckets have `autoCreatePolicy` disabled by default +importedBucket.policy = new s3.BucketPolicy(stack, 'ImportedBucketPolicy', { + bucket: importedBucket, +}); + +const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', { + vpc, + internetFacing: true, +}); + +lb.logAccessLogs(importedBucket, 'prefix'); + +const listener = lb.addListener('Listener', { + port: 80, +}); + +const group1 = listener.addTargets('Target', { + port: 80, + targets: [new elbv2.IpTarget('10.0.128.6')], + stickinessCookieDuration: cdk.Duration.minutes(5), +}); + +vpc.publicSubnets.forEach((subnet) => { + group1.node.addDependency(subnet); +}); + +new IntegTest(app, 'cdk-integ-alb-log-imported-bucket', { + testCases: [stack], + diffAssets: true, +}); diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts index f1cc1ad22538e..d6ccaeeee0507 100644 --- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts +++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/lib/shared/base-load-balancer.ts @@ -5,7 +5,7 @@ import * as iam from '../../../aws-iam'; import { PolicyStatement, ServicePrincipal } from '../../../aws-iam'; import * as s3 from '../../../aws-s3'; import * as cxschema from '../../../cloud-assembly-schema'; -import { ContextProvider, IResource, Lazy, Resource, Stack, Token } from '../../../core'; +import { CfnResource, ContextProvider, IResource, Lazy, Resource, Stack, Token } from '../../../core'; import * as cxapi from '../../../cx-api'; import { RegionInfo } from '../../../region-info'; import { CfnLoadBalancer } from '../elasticloadbalancingv2.generated'; @@ -253,15 +253,13 @@ export abstract class BaseLoadBalancer extends Resource { this.setAttribute('access_logs.s3.prefix', prefix); const logsDeliveryServicePrincipal = new ServicePrincipal('delivery.logs.amazonaws.com'); - bucket.addToResourcePolicy( - new PolicyStatement({ - actions: ['s3:PutObject'], - principals: [this.resourcePolicyPrincipal()], - resources: [ - bucket.arnForObjects(`${prefix ? prefix + '/' : ''}AWSLogs/${Stack.of(this).account}/*`), - ], - }), - ); + bucket.addToResourcePolicy(new PolicyStatement({ + actions: ['s3:PutObject'], + principals: [this.resourcePolicyPrincipal()], + resources: [ + bucket.arnForObjects(`${prefix ? prefix + '/' : ''}AWSLogs/${Stack.of(this).account}/*`), + ], + })); bucket.addToResourcePolicy( new PolicyStatement({ actions: ['s3:PutObject'], @@ -283,9 +281,13 @@ export abstract class BaseLoadBalancer extends Resource { ); // make sure the bucket's policy is created before the ALB (see https://github.com/aws/aws-cdk/issues/1633) - // at the L1 level to avoid creating a circular dependency (see https://github.com/aws/aws-cdk/issues/27528) - const lb = this.node.defaultChild as CfnLoadBalancer; - lb.addDependency(bucket.node.defaultChild as s3.CfnBucket); + // at the L1 level to avoid creating a circular dependency (see https://github.com/aws/aws-cdk/issues/27528 + // and https://github.com/aws/aws-cdk/issues/27928) + const lb = this.node.defaultChild; + const bucketPolicy = bucket.policy?.node.defaultChild; + if (lb && bucketPolicy && CfnResource.isCfnResource(lb) && CfnResource.isCfnResource(bucketPolicy)) { + lb.addDependency(bucketPolicy); + } } /** diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/alb/load-balancer.test.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/alb/load-balancer.test.ts index c6124b2674c86..9b12caafcd797 100644 --- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/alb/load-balancer.test.ts +++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/alb/load-balancer.test.ts @@ -289,9 +289,9 @@ describe('tests', () => { lb.logAccessLogs(bucket); // THEN - // verify the ALB depends on the bucket *and* the bucket policy + // verify the ALB depends on the bucket policy Template.fromStack(stack).hasResource('AWS::ElasticLoadBalancingV2::LoadBalancer', { - DependsOn: ['AccessLoggingBucketA6D88F29'], + DependsOn: ['AccessLoggingBucketPolicy700D7CC6'], }); }); @@ -403,6 +403,103 @@ describe('tests', () => { }); }); + test('access logging on imported bucket', () => { + // GIVEN + const { stack, lb } = loggingSetup(); + + const bucket = s3.Bucket.fromBucketName(stack, 'ImportedAccessLoggingBucket', 'imported-bucket'); + // Imported buckets have `autoCreatePolicy` disabled by default + bucket.policy = new s3.BucketPolicy(stack, 'ImportedAccessLoggingBucketPolicy', { + bucket, + }); + + // WHEN + lb.logAccessLogs(bucket); + + // THEN + // verify that the LB attributes reference the bucket + Template.fromStack(stack).hasResourceProperties('AWS::ElasticLoadBalancingV2::LoadBalancer', { + LoadBalancerAttributes: Match.arrayWith([ + { + Key: 'access_logs.s3.enabled', + Value: 'true', + }, + { + Key: 'access_logs.s3.bucket', + Value: 'imported-bucket', + }, + { + Key: 'access_logs.s3.prefix', + Value: '', + }, + ]), + }); + + // verify the bucket policy allows the ALB to put objects in the bucket + Template.fromStack(stack).hasResourceProperties('AWS::S3::BucketPolicy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [ + { + Action: 's3:PutObject', + Effect: 'Allow', + Principal: { AWS: { 'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':iam::127311923021:root']] } }, + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':s3:::imported-bucket/AWSLogs/', + { Ref: 'AWS::AccountId' }, + '/*', + ], + ], + }, + }, + { + Action: 's3:PutObject', + Effect: 'Allow', + Principal: { Service: 'delivery.logs.amazonaws.com' }, + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':s3:::imported-bucket/AWSLogs/', + { Ref: 'AWS::AccountId' }, + '/*', + ], + ], + }, + Condition: { StringEquals: { 's3:x-amz-acl': 'bucket-owner-full-control' } }, + }, + { + Action: 's3:GetBucketAcl', + Effect: 'Allow', + Principal: { Service: 'delivery.logs.amazonaws.com' }, + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':s3:::imported-bucket', + ], + ], + }, + }, + ], + }, + }); + + // verify the ALB depends on the bucket policy + Template.fromStack(stack).hasResource('AWS::ElasticLoadBalancingV2::LoadBalancer', { + DependsOn: ['ImportedAccessLoggingBucketPolicy97AE3371'], + }); + }); + test('does not add circular dependency on bucket with extended load balancer', () => { // GIVEN const { stack } = loggingSetup(); diff --git a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/nlb/load-balancer.test.ts b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/nlb/load-balancer.test.ts index eb780a0248eee..6e8dcea8dc685 100644 --- a/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/nlb/load-balancer.test.ts +++ b/packages/aws-cdk-lib/aws-elasticloadbalancingv2/test/nlb/load-balancer.test.ts @@ -124,7 +124,7 @@ describe('tests', () => { ]), }); - // verify the bucket policy allows the ALB to put objects in the bucket + // verify the bucket policy allows the NLB to put objects in the bucket Template.fromStack(stack).hasResourceProperties('AWS::S3::BucketPolicy', { PolicyDocument: { Version: '2012-10-17', @@ -160,9 +160,9 @@ describe('tests', () => { }, }); - // verify the ALB depends on the bucket *and* the bucket policy + // verify the NLB depends on the bucket policy Template.fromStack(stack).hasResource('AWS::ElasticLoadBalancingV2::LoadBalancer', { - DependsOn: ['AccessLoggingBucketA6D88F29'], + DependsOn: ['AccessLoggingBucketPolicy700D7CC6'], }); }); @@ -196,7 +196,7 @@ describe('tests', () => { ]), }); - // verify the bucket policy allows the ALB to put objects in the bucket + // verify the bucket policy allows the NLB to put objects in the bucket Template.fromStack(stack).hasResourceProperties('AWS::S3::BucketPolicy', { PolicyDocument: { Version: '2012-10-17', @@ -233,13 +233,113 @@ describe('tests', () => { }); }); + test('Access logging on imported bucket', () => { + // GIVEN + const app = new cdk.App(); + const stack = new cdk.Stack(app, undefined, { env: { region: 'us-east-1' } }); + const vpc = new ec2.Vpc(stack, 'Stack'); + const bucket = s3.Bucket.fromBucketName(stack, 'ImportedAccessLoggingBucket', 'imported-bucket'); + // Imported buckets have `autoCreatePolicy` disabled by default + bucket.policy = new s3.BucketPolicy(stack, 'ImportedAccessLoggingBucketPolicy', { + bucket, + }); + const lb = new elbv2.NetworkLoadBalancer(stack, 'LB', { vpc }); + + // WHEN + lb.logAccessLogs(bucket); + + // THEN + + // verify that the LB attributes reference the bucket + Template.fromStack(stack).hasResourceProperties('AWS::ElasticLoadBalancingV2::LoadBalancer', { + LoadBalancerAttributes: Match.arrayWith([ + { + Key: 'access_logs.s3.enabled', + Value: 'true', + }, + { + Key: 'access_logs.s3.bucket', + Value: 'imported-bucket', + }, + { + Key: 'access_logs.s3.prefix', + Value: '', + }, + ]), + }); + + // verify the bucket policy allows the NLB to put objects in the bucket + Template.fromStack(stack).hasResourceProperties('AWS::S3::BucketPolicy', { + PolicyDocument: { + Version: '2012-10-17', + Statement: [ + { + Action: 's3:PutObject', + Effect: 'Allow', + Principal: { AWS: { 'Fn::Join': ['', ['arn:', { Ref: 'AWS::Partition' }, ':iam::127311923021:root']] } }, + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':s3:::imported-bucket/AWSLogs/', + { Ref: 'AWS::AccountId' }, + '/*', + ], + ], + }, + }, + { + Action: 's3:PutObject', + Condition: { StringEquals: { 's3:x-amz-acl': 'bucket-owner-full-control' } }, + Effect: 'Allow', + Principal: { Service: 'delivery.logs.amazonaws.com' }, + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':s3:::imported-bucket/AWSLogs/', + { Ref: 'AWS::AccountId' }, + '/*', + ], + ], + }, + }, + { + Action: 's3:GetBucketAcl', + Effect: 'Allow', + Principal: { Service: 'delivery.logs.amazonaws.com' }, + Resource: { + 'Fn::Join': [ + '', + [ + 'arn:', + { Ref: 'AWS::Partition' }, + ':s3:::imported-bucket', + ], + ], + }, + }, + ], + }, + }); + + // verify the NLB depends on the bucket policy + Template.fromStack(stack).hasResource('AWS::ElasticLoadBalancingV2::LoadBalancer', { + DependsOn: ['ImportedAccessLoggingBucketPolicy97AE3371'], + }); + }); + test('loadBalancerName', () => { // GIVEN const stack = new cdk.Stack(); const vpc = new ec2.Vpc(stack, 'Stack'); // WHEN - new elbv2.NetworkLoadBalancer(stack, 'ALB', { + new elbv2.NetworkLoadBalancer(stack, 'NLB', { loadBalancerName: 'myLoadBalancer', vpc, }); @@ -371,7 +471,7 @@ describe('tests', () => { // WHEN const albArn = 'arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/my-load-balancer/50dc6c495c0c9188'; - const alb = elbv2.NetworkLoadBalancer.fromNetworkLoadBalancerAttributes(stack, 'ALB', { + const alb = elbv2.NetworkLoadBalancer.fromNetworkLoadBalancerAttributes(stack, 'NLB', { loadBalancerArn: albArn, }); From bdc235573d2474cafdec95798940ebe6abc50b44 Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Tue, 14 Nov 2023 13:11:30 -0500 Subject: [PATCH 2/8] chore(release): 2.108.1 --- CHANGELOG.v2.alpha.md | 2 ++ CHANGELOG.v2.md | 7 +++++++ version.v2.json | 4 ++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.v2.alpha.md b/CHANGELOG.v2.alpha.md index f42a9855c2e53..b82b718e83197 100644 --- a/CHANGELOG.v2.alpha.md +++ b/CHANGELOG.v2.alpha.md @@ -2,6 +2,8 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [2.108.1-alpha.0](https://github.com/aws/aws-cdk/compare/v2.108.0-alpha.0...v2.108.1-alpha.0) (2023-11-14) + ## [2.108.0-alpha.0](https://github.com/aws/aws-cdk/compare/v2.107.0-alpha.0...v2.108.0-alpha.0) (2023-11-13) ## [2.107.0-alpha.0](https://github.com/aws/aws-cdk/compare/v2.106.1-alpha.0...v2.107.0-alpha.0) (2023-11-13) diff --git a/CHANGELOG.v2.md b/CHANGELOG.v2.md index 9bf95d666c044..5a46fe92eb58e 100644 --- a/CHANGELOG.v2.md +++ b/CHANGELOG.v2.md @@ -2,6 +2,13 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +### [2.108.1](https://github.com/aws/aws-cdk/compare/v2.108.0...v2.108.1) (2023-11-14) + + +### Bug Fixes + +* **elasticloadbalancingv2:** access logging fails on imported bucket ([#27948](https://github.com/aws/aws-cdk/issues/27948)) ([8243601](https://github.com/aws/aws-cdk/commit/8243601866e8c1771a18adb4c93579a7099984e3)), closes [#27928](https://github.com/aws/aws-cdk/issues/27928) + ## [2.108.0](https://github.com/aws/aws-cdk/compare/v2.107.0...v2.108.0) (2023-11-13) diff --git a/version.v2.json b/version.v2.json index 899370d2ed966..0caf2c65448ab 100644 --- a/version.v2.json +++ b/version.v2.json @@ -1,4 +1,4 @@ { - "version": "2.108.0", - "alphaVersion": "2.108.0-alpha.0" + "version": "2.108.1", + "alphaVersion": "2.108.1-alpha.0" } \ No newline at end of file From 61c2056eb3661ea6ef8337797f0dc2cf6f822c0e Mon Sep 17 00:00:00 2001 From: Kaizen Conroy Date: Tue, 14 Nov 2023 13:13:26 -0500 Subject: [PATCH 3/8] fix changelog --- CHANGELOG.v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.v2.md b/CHANGELOG.v2.md index 5a46fe92eb58e..f241b93297f7d 100644 --- a/CHANGELOG.v2.md +++ b/CHANGELOG.v2.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. -### [2.108.1](https://github.com/aws/aws-cdk/compare/v2.108.0...v2.108.1) (2023-11-14) +## [2.108.1](https://github.com/aws/aws-cdk/compare/v2.108.0...v2.108.1) (2023-11-14) ### Bug Fixes From b1bf06f8973951fae595f0381519001c3e1e4e5e Mon Sep 17 00:00:00 2001 From: Kaizen Conroy <36202692+kaizencc@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:18:19 -0500 Subject: [PATCH 4/8] Update CHANGELOG.v2.alpha.md Co-authored-by: Mitchell Valine --- CHANGELOG.v2.alpha.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.v2.alpha.md b/CHANGELOG.v2.alpha.md index b82b718e83197..24207e5be895f 100644 --- a/CHANGELOG.v2.alpha.md +++ b/CHANGELOG.v2.alpha.md @@ -2,7 +2,7 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. -### [2.108.1-alpha.0](https://github.com/aws/aws-cdk/compare/v2.108.0-alpha.0...v2.108.1-alpha.0) (2023-11-14) +## [2.108.1-alpha.0](https://github.com/aws/aws-cdk/compare/v2.108.0-alpha.0...v2.108.1-alpha.0) (2023-11-14) ## [2.108.0-alpha.0](https://github.com/aws/aws-cdk/compare/v2.107.0-alpha.0...v2.108.0-alpha.0) (2023-11-13) From 33357aa2cfc09352c5ce95d1e894ae7eb53f3b32 Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Tue, 14 Nov 2023 23:10:15 +0100 Subject: [PATCH 5/8] feat(apigateway): support firehose access log destination (#27959) Adds support for Firehose delivery stream as access log destination of API gateway. Closes #27954. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- ...efaultTestDeployAssert6376A91B.assets.json | 19 + ...aultTestDeployAssert6376A91B.template.json | 36 ++ .../index.js | 1 + .../cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 191 ++++++ ...pigateway-access-logs-firehose.assets.json | 32 ++ ...gateway-access-logs-firehose.template.json | 355 ++++++++++++ .../tree.json | 544 ++++++++++++++++++ .../test/integ.restapi.access-log-firehose.ts | 65 +++ packages/aws-cdk-lib/aws-apigateway/README.md | 32 +- .../aws-apigateway/lib/access-log.ts | 21 + .../aws-cdk-lib/aws-apigateway/lib/stage.ts | 2 +- .../aws-apigateway/test/stage.test.ts | 84 +++ .../rosetta/aws_apigateway/default.ts-fixture | 1 + 15 files changed, 1393 insertions(+), 3 deletions(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/asset.2ec8ad9e91dcd6e7ad6a5c84ffc6c9c05c408aca3b26ceb2816d81043e6c4dc3/index.js create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/test-apigateway-access-logs-firehose.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/test-apigateway-access-logs-firehose.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B.assets.json new file mode 100644 index 0000000000000..8c6940690f59b --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B.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-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B.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-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/asset.2ec8ad9e91dcd6e7ad6a5c84ffc6c9c05c408aca3b26ceb2816d81043e6c4dc3/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/asset.2ec8ad9e91dcd6e7ad6a5c84ffc6c9c05c408aca3b26ceb2816d81043e6c4dc3/index.js new file mode 100644 index 0000000000000..9d841e15260d7 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/asset.2ec8ad9e91dcd6e7ad6a5c84ffc6c9c05c408aca3b26ceb2816d81043e6c4dc3/index.js @@ -0,0 +1 @@ +"use strict";var C=Object.create;var i=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,A=Object.prototype.hasOwnProperty;var L=(e,t)=>{for(var o in t)i(e,o,{get:t[o],enumerable:!0})},d=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of w(t))!A.call(e,s)&&s!==o&&i(e,s,{get:()=>t[s],enumerable:!(r=I(t,s))||r.enumerable});return e};var l=(e,t,o)=>(o=e!=null?C(P(e)):{},d(t||!e||!e.__esModule?i(o,"default",{value:e,enumerable:!0}):o,e)),k=e=>d(i({},"__esModule",{value:!0}),e);var U={};L(U,{autoDeleteHandler:()=>S,handler:()=>_});module.exports=k(U);var h=require("@aws-sdk/client-s3");var y=l(require("https")),m=l(require("url")),a={sendHttpRequest:T,log:b,includeStackTraces:!0,userHandlerIndex:"./index"},p="AWSCDK::CustomResourceProviderFramework::CREATE_FAILED",B="AWSCDK::CustomResourceProviderFramework::MISSING_PHYSICAL_ID";function R(e){return async(t,o)=>{let r={...t,ResponseURL:"..."};if(a.log(JSON.stringify(r,void 0,2)),t.RequestType==="Delete"&&t.PhysicalResourceId===p){a.log("ignoring DELETE event caused by a failed CREATE event"),await u("SUCCESS",t);return}try{let s=await e(r,o),n=D(t,s);await u("SUCCESS",n)}catch(s){let n={...t,Reason:a.includeStackTraces?s.stack:s.message};n.PhysicalResourceId||(t.RequestType==="Create"?(a.log("CREATE failed, responding with a marker physical resource id so that the subsequent DELETE will be ignored"),n.PhysicalResourceId=p):a.log(`ERROR: Malformed event. "PhysicalResourceId" is required: ${JSON.stringify(t)}`)),await u("FAILED",n)}}}function D(e,t={}){let o=t.PhysicalResourceId??e.PhysicalResourceId??e.RequestId;if(e.RequestType==="Delete"&&o!==e.PhysicalResourceId)throw new Error(`DELETE: cannot change the physical resource ID from "${e.PhysicalResourceId}" to "${t.PhysicalResourceId}" during deletion`);return{...e,...t,PhysicalResourceId:o}}async function u(e,t){let o={Status:e,Reason:t.Reason??e,StackId:t.StackId,RequestId:t.RequestId,PhysicalResourceId:t.PhysicalResourceId||B,LogicalResourceId:t.LogicalResourceId,NoEcho:t.NoEcho,Data:t.Data};a.log("submit response to cloudformation",o);let r=JSON.stringify(o),s=m.parse(t.ResponseURL),n={hostname:s.hostname,path:s.path,method:"PUT",headers:{"content-type":"","content-length":Buffer.byteLength(r,"utf8")}};await O({attempts:5,sleep:1e3},a.sendHttpRequest)(n,r)}async function T(e,t){return new Promise((o,r)=>{try{let s=y.request(e,n=>o());s.on("error",r),s.write(t),s.end()}catch(s){r(s)}})}function b(e,...t){console.log(e,...t)}function O(e,t){return async(...o)=>{let r=e.attempts,s=e.sleep;for(;;)try{return await t(...o)}catch(n){if(r--<=0)throw n;await x(Math.floor(Math.random()*s)),s*=2}}}async function x(e){return new Promise(t=>setTimeout(t,e))}var g="aws-cdk:auto-delete-objects",H=JSON.stringify({Version:"2012-10-17",Statement:[]}),c=new h.S3({}),_=R(S);async function S(e){switch(e.RequestType){case"Create":return;case"Update":return F(e);case"Delete":return f(e.ResourceProperties?.BucketName)}}async function F(e){let t=e,o=t.OldResourceProperties?.BucketName,r=t.ResourceProperties?.BucketName;if(r!=null&&o!=null&&r!==o)return f(o)}async function N(e){try{let t=(await c.getBucketPolicy({Bucket:e}))?.Policy??H,o=JSON.parse(t);o.Statement.push({Principal:"*",Effect:"Deny",Action:["s3:PutObject"],Resource:[`arn:aws:s3:::${e}/*`]}),await c.putBucketPolicy({Bucket:e,Policy:JSON.stringify(o)})}catch(t){if(t.name==="NoSuchBucket")throw t;console.log(`Could not set new object deny policy on bucket '${e}' prior to deletion.`)}}async function E(e){let t=await c.listObjectVersions({Bucket:e}),o=[...t.Versions??[],...t.DeleteMarkers??[]];if(o.length===0)return;let r=o.map(s=>({Key:s.Key,VersionId:s.VersionId}));await c.deleteObjects({Bucket:e,Delete:{Objects:r}}),t?.IsTruncated&&await E(e)}async function f(e){if(!e)throw new Error("No BucketName was provided.");try{if(!await W(e)){console.log(`Bucket does not have '${g}' tag, skipping cleaning.`);return}await N(e),await E(e)}catch(t){if(t.name==="NoSuchBucket"){console.log(`Bucket '${e}' does not exist.`);return}throw t}}async function W(e){return(await c.getBucketTagging({Bucket:e})).TagSet?.some(o=>o.Key===g&&o.Value==="true")}0&&(module.exports={autoDeleteHandler,handler}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/cdk.out new file mode 100644 index 0000000000000..2313ab5436501 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/integ.json new file mode 100644 index 0000000000000..583f343b0fa7b --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "34.0.0", + "testCases": { + "apigateway-access-logs-firehose/DefaultTest": { + "stacks": [ + "test-apigateway-access-logs-firehose" + ], + "assertionStack": "apigateway-access-logs-firehose/DefaultTest/DeployAssert", + "assertionStackName": "apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/manifest.json new file mode 100644 index 0000000000000..735da326c8cf2 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/manifest.json @@ -0,0 +1,191 @@ +{ + "version": "34.0.0", + "artifacts": { + "test-apigateway-access-logs-firehose.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "test-apigateway-access-logs-firehose.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "test-apigateway-access-logs-firehose": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "test-apigateway-access-logs-firehose.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}/82152e7007729e7e3c85aee383e9aa74f272a1c2b9eec64572fc7592d7303e25.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "test-apigateway-access-logs-firehose.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": [ + "test-apigateway-access-logs-firehose.assets" + ], + "metadata": { + "/test-apigateway-access-logs-firehose/Bucket/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Bucket83908E77" + } + ], + "/test-apigateway-access-logs-firehose/Bucket/Policy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "BucketPolicyE9A3008A" + } + ], + "/test-apigateway-access-logs-firehose/Bucket/AutoDeleteObjectsCustomResource/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "BucketAutoDeleteObjectsCustomResourceBAFD23C2" + } + ], + "/test-apigateway-access-logs-firehose/Custom::S3AutoDeleteObjectsCustomResourceProvider/Role": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092" + } + ], + "/test-apigateway-access-logs-firehose/Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler": [ + { + "type": "aws:cdk:logicalId", + "data": "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F" + } + ], + "/test-apigateway-access-logs-firehose/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Role1ABCC5F0" + } + ], + "/test-apigateway-access-logs-firehose/MyStream": [ + { + "type": "aws:cdk:logicalId", + "data": "MyStream" + } + ], + "/test-apigateway-access-logs-firehose/MyApi/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyApi49610EDF" + } + ], + "/test-apigateway-access-logs-firehose/MyApi/CloudWatchRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyApiCloudWatchRole2BEC1A9C" + } + ], + "/test-apigateway-access-logs-firehose/MyApi/Account": [ + { + "type": "aws:cdk:logicalId", + "data": "MyApiAccount13882D84" + } + ], + "/test-apigateway-access-logs-firehose/MyApi/Deployment/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyApiDeploymentECB0D05E81594d6748b4b291f993111a5070d710" + } + ], + "/test-apigateway-access-logs-firehose/MyApi/DeploymentStage.prod/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyApiDeploymentStageprodE1054AF0" + } + ], + "/test-apigateway-access-logs-firehose/MyApi/Endpoint": [ + { + "type": "aws:cdk:logicalId", + "data": "MyApiEndpoint869ABE96" + } + ], + "/test-apigateway-access-logs-firehose/MyApi/Default/GET/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyApiGETD0C7AA0C" + } + ], + "/test-apigateway-access-logs-firehose/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/test-apigateway-access-logs-firehose/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "test-apigateway-access-logs-firehose" + }, + "apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B.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": [ + "apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B.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": [ + "apigatewayaccesslogsfirehoseDefaultTestDeployAssert6376A91B.assets" + ], + "metadata": { + "/apigateway-access-logs-firehose/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/apigateway-access-logs-firehose/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "apigateway-access-logs-firehose/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-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/test-apigateway-access-logs-firehose.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/test-apigateway-access-logs-firehose.assets.json new file mode 100644 index 0000000000000..62f7deb0f018d --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/test-apigateway-access-logs-firehose.assets.json @@ -0,0 +1,32 @@ +{ + "version": "34.0.0", + "files": { + "2ec8ad9e91dcd6e7ad6a5c84ffc6c9c05c408aca3b26ceb2816d81043e6c4dc3": { + "source": { + "path": "asset.2ec8ad9e91dcd6e7ad6a5c84ffc6c9c05c408aca3b26ceb2816d81043e6c4dc3", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "2ec8ad9e91dcd6e7ad6a5c84ffc6c9c05c408aca3b26ceb2816d81043e6c4dc3.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "82152e7007729e7e3c85aee383e9aa74f272a1c2b9eec64572fc7592d7303e25": { + "source": { + "path": "test-apigateway-access-logs-firehose.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "82152e7007729e7e3c85aee383e9aa74f272a1c2b9eec64572fc7592d7303e25.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-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/test-apigateway-access-logs-firehose.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/test-apigateway-access-logs-firehose.template.json new file mode 100644 index 0000000000000..3d3af140711ba --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/test-apigateway-access-logs-firehose.template.json @@ -0,0 +1,355 @@ +{ + "Resources": { + "Bucket83908E77": { + "Type": "AWS::S3::Bucket", + "Properties": { + "Tags": [ + { + "Key": "aws-cdk:auto-delete-objects", + "Value": "true" + } + ] + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "BucketPolicyE9A3008A": { + "Type": "AWS::S3::BucketPolicy", + "Properties": { + "Bucket": { + "Ref": "Bucket83908E77" + }, + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:List*", + "s3:PutBucketPolicy" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + } + }, + "Resource": [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "BucketAutoDeleteObjectsCustomResourceBAFD23C2": { + "Type": "Custom::S3AutoDeleteObjects", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F", + "Arn" + ] + }, + "BucketName": { + "Ref": "Bucket83908E77" + } + }, + "DependsOn": [ + "BucketPolicyE9A3008A" + ], + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ] + }, + "ManagedPolicyArns": [ + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + } + ] + } + }, + "CustomS3AutoDeleteObjectsCustomResourceProviderHandler9D90184F": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "2ec8ad9e91dcd6e7ad6a5c84ffc6c9c05c408aca3b26ceb2816d81043e6c4dc3.zip" + }, + "Timeout": 900, + "MemorySize": 128, + "Handler": "index.handler", + "Role": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + }, + "Runtime": "nodejs18.x", + "Description": { + "Fn::Join": [ + "", + [ + "Lambda function for auto-deleting objects in ", + { + "Ref": "Bucket83908E77" + }, + " S3 bucket." + ] + ] + } + }, + "DependsOn": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092" + ] + }, + "Role1ABCC5F0": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "firehose.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "MyStream": { + "Type": "AWS::KinesisFirehose::DeliveryStream", + "Properties": { + "DeliveryStreamName": "amazon-apigateway-delivery-stream", + "S3DestinationConfiguration": { + "BucketARN": { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "RoleARN": { + "Fn::GetAtt": [ + "Role1ABCC5F0", + "Arn" + ] + } + } + } + }, + "MyApi49610EDF": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Name": "MyApi" + } + }, + "MyApiCloudWatchRole2BEC1A9C": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "apigateway.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" + ] + ] + } + ] + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "MyApiAccount13882D84": { + "Type": "AWS::ApiGateway::Account", + "Properties": { + "CloudWatchRoleArn": { + "Fn::GetAtt": [ + "MyApiCloudWatchRole2BEC1A9C", + "Arn" + ] + } + }, + "DependsOn": [ + "MyApi49610EDF" + ], + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "MyApiDeploymentECB0D05E81594d6748b4b291f993111a5070d710": { + "Type": "AWS::ApiGateway::Deployment", + "Properties": { + "Description": "Automatically created by the RestApi construct", + "RestApiId": { + "Ref": "MyApi49610EDF" + } + }, + "DependsOn": [ + "MyApiGETD0C7AA0C" + ] + }, + "MyApiDeploymentStageprodE1054AF0": { + "Type": "AWS::ApiGateway::Stage", + "Properties": { + "AccessLogSetting": { + "DestinationArn": { + "Fn::GetAtt": [ + "MyStream", + "Arn" + ] + }, + "Format": "{\"requestId\":\"$context.requestId\",\"sourceIp\":\"$context.identity.sourceIp\",\"method\":\"$context.httpMethod\",\"callerAccountId\":\"$context.identity.accountId\",\"ownerAccountId\":\"$context.accountId\",\"userContext\":{\"sub\":\"$context.authorizer.claims.sub\",\"email\":\"$context.authorizer.claims.email\"},\"clientCertPem\":\"$context.identity.clientCert.clientCertPem\",\"subjectDN\":\"$context.identity.clientCert.subjectDN\",\"issunerDN\":\"$context.identity.clientCert.issuerDN\",\"serialNumber\":\"$context.identity.clientCert.serialNumber\",\"validityNotBefore\":\"$context.identity.clientCert.validity.notBefore\",\"validityNotAfter\":\"$context.identity.clientCert.validity.notAfter\"}" + }, + "DeploymentId": { + "Ref": "MyApiDeploymentECB0D05E81594d6748b4b291f993111a5070d710" + }, + "RestApiId": { + "Ref": "MyApi49610EDF" + }, + "StageName": "prod" + }, + "DependsOn": [ + "MyApiAccount13882D84" + ] + }, + "MyApiGETD0C7AA0C": { + "Type": "AWS::ApiGateway::Method", + "Properties": { + "AuthorizationType": "NONE", + "HttpMethod": "GET", + "Integration": { + "Type": "MOCK" + }, + "ResourceId": { + "Fn::GetAtt": [ + "MyApi49610EDF", + "RootResourceId" + ] + }, + "RestApiId": { + "Ref": "MyApi49610EDF" + } + } + } + }, + "Outputs": { + "MyApiEndpoint869ABE96": { + "Value": { + "Fn::Join": [ + "", + [ + "https://", + { + "Ref": "MyApi49610EDF" + }, + ".execute-api.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Ref": "MyApiDeploymentStageprodE1054AF0" + }, + "/" + ] + ] + } + } + }, + "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-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/tree.json new file mode 100644 index 0000000000000..0bd7b1881b237 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.js.snapshot/tree.json @@ -0,0 +1,544 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "test-apigateway-access-logs-firehose": { + "id": "test-apigateway-access-logs-firehose", + "path": "test-apigateway-access-logs-firehose", + "children": { + "Bucket": { + "id": "Bucket", + "path": "test-apigateway-access-logs-firehose/Bucket", + "children": { + "Resource": { + "id": "Resource", + "path": "test-apigateway-access-logs-firehose/Bucket/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "tags": [ + { + "key": "aws-cdk:auto-delete-objects", + "value": "true" + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.CfnBucket", + "version": "0.0.0" + } + }, + "Policy": { + "id": "Policy", + "path": "test-apigateway-access-logs-firehose/Bucket/Policy", + "children": { + "Resource": { + "id": "Resource", + "path": "test-apigateway-access-logs-firehose/Bucket/Policy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::BucketPolicy", + "aws:cdk:cloudformation:props": { + "bucket": { + "Ref": "Bucket83908E77" + }, + "policyDocument": { + "Statement": [ + { + "Action": [ + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:List*", + "s3:PutBucketPolicy" + ], + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::GetAtt": [ + "CustomS3AutoDeleteObjectsCustomResourceProviderRole3B1BD092", + "Arn" + ] + } + }, + "Resource": [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.CfnBucketPolicy", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.BucketPolicy", + "version": "0.0.0" + } + }, + "AutoDeleteObjectsCustomResource": { + "id": "AutoDeleteObjectsCustomResource", + "path": "test-apigateway-access-logs-firehose/Bucket/AutoDeleteObjectsCustomResource", + "children": { + "Default": { + "id": "Default", + "path": "test-apigateway-access-logs-firehose/Bucket/AutoDeleteObjectsCustomResource/Default", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.CustomResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_s3.Bucket", + "version": "0.0.0" + } + }, + "Custom::S3AutoDeleteObjectsCustomResourceProvider": { + "id": "Custom::S3AutoDeleteObjectsCustomResourceProvider", + "path": "test-apigateway-access-logs-firehose/Custom::S3AutoDeleteObjectsCustomResourceProvider", + "children": { + "Staging": { + "id": "Staging", + "path": "test-apigateway-access-logs-firehose/Custom::S3AutoDeleteObjectsCustomResourceProvider/Staging", + "constructInfo": { + "fqn": "aws-cdk-lib.AssetStaging", + "version": "0.0.0" + } + }, + "Role": { + "id": "Role", + "path": "test-apigateway-access-logs-firehose/Custom::S3AutoDeleteObjectsCustomResourceProvider/Role", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnResource", + "version": "0.0.0" + } + }, + "Handler": { + "id": "Handler", + "path": "test-apigateway-access-logs-firehose/Custom::S3AutoDeleteObjectsCustomResourceProvider/Handler", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnResource", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.CustomResourceProvider", + "version": "0.0.0" + } + }, + "Role": { + "id": "Role", + "path": "test-apigateway-access-logs-firehose/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "test-apigateway-access-logs-firehose/Role/ImportRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-apigateway-access-logs-firehose/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "firehose.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "MyStream": { + "id": "MyStream", + "path": "test-apigateway-access-logs-firehose/MyStream", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::KinesisFirehose::DeliveryStream", + "aws:cdk:cloudformation:props": { + "deliveryStreamName": "amazon-apigateway-delivery-stream", + "s3DestinationConfiguration": { + "bucketArn": { + "Fn::GetAtt": [ + "Bucket83908E77", + "Arn" + ] + }, + "roleArn": { + "Fn::GetAtt": [ + "Role1ABCC5F0", + "Arn" + ] + } + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_kinesisfirehose.CfnDeliveryStream", + "version": "0.0.0" + } + }, + "MyApi": { + "id": "MyApi", + "path": "test-apigateway-access-logs-firehose/MyApi", + "children": { + "Resource": { + "id": "Resource", + "path": "test-apigateway-access-logs-firehose/MyApi/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::RestApi", + "aws:cdk:cloudformation:props": { + "name": "MyApi" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.CfnRestApi", + "version": "0.0.0" + } + }, + "CloudWatchRole": { + "id": "CloudWatchRole", + "path": "test-apigateway-access-logs-firehose/MyApi/CloudWatchRole", + "children": { + "ImportCloudWatchRole": { + "id": "ImportCloudWatchRole", + "path": "test-apigateway-access-logs-firehose/MyApi/CloudWatchRole/ImportCloudWatchRole", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-apigateway-access-logs-firehose/MyApi/CloudWatchRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "apigateway.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "Account": { + "id": "Account", + "path": "test-apigateway-access-logs-firehose/MyApi/Account", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Account", + "aws:cdk:cloudformation:props": { + "cloudWatchRoleArn": { + "Fn::GetAtt": [ + "MyApiCloudWatchRole2BEC1A9C", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.CfnAccount", + "version": "0.0.0" + } + }, + "Deployment": { + "id": "Deployment", + "path": "test-apigateway-access-logs-firehose/MyApi/Deployment", + "children": { + "Resource": { + "id": "Resource", + "path": "test-apigateway-access-logs-firehose/MyApi/Deployment/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Deployment", + "aws:cdk:cloudformation:props": { + "description": "Automatically created by the RestApi construct", + "restApiId": { + "Ref": "MyApi49610EDF" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.CfnDeployment", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.Deployment", + "version": "0.0.0" + } + }, + "DeploymentStage.prod": { + "id": "DeploymentStage.prod", + "path": "test-apigateway-access-logs-firehose/MyApi/DeploymentStage.prod", + "children": { + "Resource": { + "id": "Resource", + "path": "test-apigateway-access-logs-firehose/MyApi/DeploymentStage.prod/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Stage", + "aws:cdk:cloudformation:props": { + "accessLogSetting": { + "destinationArn": { + "Fn::GetAtt": [ + "MyStream", + "Arn" + ] + }, + "format": "{\"requestId\":\"$context.requestId\",\"sourceIp\":\"$context.identity.sourceIp\",\"method\":\"$context.httpMethod\",\"callerAccountId\":\"$context.identity.accountId\",\"ownerAccountId\":\"$context.accountId\",\"userContext\":{\"sub\":\"$context.authorizer.claims.sub\",\"email\":\"$context.authorizer.claims.email\"},\"clientCertPem\":\"$context.identity.clientCert.clientCertPem\",\"subjectDN\":\"$context.identity.clientCert.subjectDN\",\"issunerDN\":\"$context.identity.clientCert.issuerDN\",\"serialNumber\":\"$context.identity.clientCert.serialNumber\",\"validityNotBefore\":\"$context.identity.clientCert.validity.notBefore\",\"validityNotAfter\":\"$context.identity.clientCert.validity.notAfter\"}" + }, + "deploymentId": { + "Ref": "MyApiDeploymentECB0D05E81594d6748b4b291f993111a5070d710" + }, + "restApiId": { + "Ref": "MyApi49610EDF" + }, + "stageName": "prod" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.CfnStage", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.Stage", + "version": "0.0.0" + } + }, + "Endpoint": { + "id": "Endpoint", + "path": "test-apigateway-access-logs-firehose/MyApi/Endpoint", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnOutput", + "version": "0.0.0" + } + }, + "Default": { + "id": "Default", + "path": "test-apigateway-access-logs-firehose/MyApi/Default", + "children": { + "GET": { + "id": "GET", + "path": "test-apigateway-access-logs-firehose/MyApi/Default/GET", + "children": { + "Resource": { + "id": "Resource", + "path": "test-apigateway-access-logs-firehose/MyApi/Default/GET/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::ApiGateway::Method", + "aws:cdk:cloudformation:props": { + "authorizationType": "NONE", + "httpMethod": "GET", + "integration": { + "type": "MOCK" + }, + "resourceId": { + "Fn::GetAtt": [ + "MyApi49610EDF", + "RootResourceId" + ] + }, + "restApiId": { + "Ref": "MyApi49610EDF" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.CfnMethod", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.Method", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.ResourceBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_apigateway.RestApi", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "test-apigateway-access-logs-firehose/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "test-apigateway-access-logs-firehose/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "apigateway-access-logs-firehose": { + "id": "apigateway-access-logs-firehose", + "path": "apigateway-access-logs-firehose", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "apigateway-access-logs-firehose/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "apigateway-access-logs-firehose/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "apigateway-access-logs-firehose/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "apigateway-access-logs-firehose/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "apigateway-access-logs-firehose/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-apigateway/test/integ.restapi.access-log-firehose.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.ts new file mode 100644 index 0000000000000..b0783206bcfb0 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-apigateway/test/integ.restapi.access-log-firehose.ts @@ -0,0 +1,65 @@ +import * as iam from 'aws-cdk-lib/aws-iam'; +import * as firehose from 'aws-cdk-lib/aws-kinesisfirehose'; +import * as s3 from 'aws-cdk-lib/aws-s3'; +import * as cdk from 'aws-cdk-lib'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import * as apigateway from 'aws-cdk-lib/aws-apigateway'; + +class RestApiAccessLogFirehoseTest extends cdk.Stack { + constructor(scope: cdk.App, id: string) { + super(scope, id); + + const testFormat = apigateway.AccessLogFormat.custom(JSON.stringify({ + requestId: apigateway.AccessLogField.contextRequestId(), + sourceIp: apigateway.AccessLogField.contextIdentitySourceIp(), + method: apigateway.AccessLogField.contextHttpMethod(), + callerAccountId: apigateway.AccessLogField.contextCallerAccountId(), + ownerAccountId: apigateway.AccessLogField.contextOwnerAccountId(), + userContext: { + sub: apigateway.AccessLogField.contextAuthorizerClaims('sub'), + email: apigateway.AccessLogField.contextAuthorizerClaims('email'), + }, + clientCertPem: apigateway.AccessLogField.contextIdentityClientCertPem(), + subjectDN: apigateway.AccessLogField.contextIdentityClientCertSubjectDN(), + issunerDN: apigateway.AccessLogField.contextIdentityClientCertIssunerDN(), + serialNumber: apigateway.AccessLogField.contextIdentityClientCertSerialNumber(), + validityNotBefore: apigateway.AccessLogField.contextIdentityClientCertValidityNotBefore(), + validityNotAfter: apigateway.AccessLogField.contextIdentityClientCertValidityNotAfter(), + })); + + const destinationBucket = new s3.Bucket(this, 'Bucket', { + removalPolicy: cdk.RemovalPolicy.DESTROY, + autoDeleteObjects: true, + }); + + const deliveryStreamRole = new iam.Role(this, 'Role', { + assumedBy: new iam.ServicePrincipal('firehose.amazonaws.com'), + }); + + const stream = new firehose.CfnDeliveryStream(this, 'MyStream', { + deliveryStreamName: 'amazon-apigateway-delivery-stream', + s3DestinationConfiguration: { + bucketArn: destinationBucket.bucketArn, + roleArn: deliveryStreamRole.roleArn, + }, + }); + + const api = new apigateway.RestApi(this, 'MyApi', { + cloudWatchRole: true, + deployOptions: { + accessLogDestination: new apigateway.FirehoseLogDestination(stream), + accessLogFormat: testFormat, + }, + }); + api.root.addMethod('GET'); + } +} + +const app = new cdk.App(); + +const stack = new RestApiAccessLogFirehoseTest(app, 'test-apigateway-access-logs-firehose'); +new IntegTest(app, 'apigateway-access-logs-firehose', { + testCases: [stack], +}); + +app.synth(); diff --git a/packages/aws-cdk-lib/aws-apigateway/README.md b/packages/aws-cdk-lib/aws-apigateway/README.md index d9380f01c9fd3..fc3af88c46443 100644 --- a/packages/aws-cdk-lib/aws-apigateway/README.md +++ b/packages/aws-cdk-lib/aws-apigateway/README.md @@ -1218,10 +1218,10 @@ Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-log ```ts // production stage -const prdLogGroup = new logs.LogGroup(this, "PrdLogs"); +const prodLogGroup = new logs.LogGroup(this, "PrdLogs"); const api = new apigateway.RestApi(this, 'books', { deployOptions: { - accessLogDestination: new apigateway.LogGroupLogDestination(prdLogGroup), + accessLogDestination: new apigateway.LogGroupLogDestination(prodLogGroup), accessLogFormat: apigateway.AccessLogFormat.jsonWithStandardFields(), }, }); @@ -1308,6 +1308,34 @@ const api = new apigateway.RestApi(this, 'books', { }); ``` +To write access log files to a Firehose delivery stream destination use the `FirehoseLogDestination` class: + +```ts +const destinationBucket = new s3.Bucket(this, 'Bucket'); +const deliveryStreamRole = new iam.Role(this, 'Role', { + assumedBy: new iam.ServicePrincipal('firehose.amazonaws.com'), +}); + +const stream = new firehose.CfnDeliveryStream(this, 'MyStream', { + deliveryStreamName: 'amazon-apigateway-delivery-stream', + s3DestinationConfiguration: { + bucketArn: destinationBucket.bucketArn, + roleArn: deliveryStreamRole.roleArn, + }, +}); + +const api = new apigateway.RestApi(this, 'books', { + deployOptions: { + accessLogDestination: new apigateway.FirehoseLogDestination(stream), + accessLogFormat: apigateway.AccessLogFormat.jsonWithStandardFields(), + }, +}); +``` + +**Note:** The delivery stream name must start with `amazon-apigateway-`. + +> Visit [Logging API calls to Kinesis Data Firehose](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-logging-to-kinesis.html) for more details. + ## Cross Origin Resource Sharing (CORS) [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism diff --git a/packages/aws-cdk-lib/aws-apigateway/lib/access-log.ts b/packages/aws-cdk-lib/aws-apigateway/lib/access-log.ts index ea40681f7b60c..c445fbc71450b 100644 --- a/packages/aws-cdk-lib/aws-apigateway/lib/access-log.ts +++ b/packages/aws-cdk-lib/aws-apigateway/lib/access-log.ts @@ -1,4 +1,5 @@ import { IStage } from './stage'; +import * as firehose from '../../aws-kinesisfirehose'; import { ILogGroup } from '../../aws-logs'; /** @@ -38,6 +39,26 @@ export class LogGroupLogDestination implements IAccessLogDestination { } } +/** + * Use a Firehose delivery stream as a custom access log destination for API Gateway. + */ +export class FirehoseLogDestination implements IAccessLogDestination { + constructor(private readonly stream: firehose.CfnDeliveryStream) { + } + + /** + * Binds this destination to the Firehose delivery stream. + */ + public bind(_stage: IStage): AccessLogDestinationConfig { + if (!this.stream.deliveryStreamName?.startsWith('amazon-apigateway-')) { + throw new Error(`Firehose delivery stream name for access log destination must begin with 'amazon-apigateway-', got '${this.stream.deliveryStreamName}'`); + } + return { + destinationArn: this.stream.attrArn, + }; + } +} + /** * $context variables that can be used to customize access log pattern. */ diff --git a/packages/aws-cdk-lib/aws-apigateway/lib/stage.ts b/packages/aws-cdk-lib/aws-apigateway/lib/stage.ts index f7b37ef0a2a39..093a526eb2509 100644 --- a/packages/aws-cdk-lib/aws-apigateway/lib/stage.ts +++ b/packages/aws-cdk-lib/aws-apigateway/lib/stage.ts @@ -40,7 +40,7 @@ export interface StageOptions extends MethodDeploymentOptions { readonly stageName?: string; /** - * The CloudWatch Logs log group. + * The CloudWatch Logs log group or Firehose delivery stream where to write access logs. * * @default - No destination */ diff --git a/packages/aws-cdk-lib/aws-apigateway/test/stage.test.ts b/packages/aws-cdk-lib/aws-apigateway/test/stage.test.ts index 95034a37deb24..572626ef50550 100644 --- a/packages/aws-cdk-lib/aws-apigateway/test/stage.test.ts +++ b/packages/aws-cdk-lib/aws-apigateway/test/stage.test.ts @@ -1,4 +1,5 @@ import { Template } from '../../assertions'; +import * as firehose from '../../aws-kinesisfirehose'; import * as logs from '../../aws-logs'; import * as cdk from '../../core'; import * as apigateway from '../lib'; @@ -360,6 +361,70 @@ describe('stage', () => { }); }); + test('if only the custom log destination firehose delivery stream is set', () => { + // GIVEN + const stack = new cdk.Stack(); + const api = new apigateway.RestApi(stack, 'test-api', { cloudWatchRole: false, deploy: false }); + const deployment = new apigateway.Deployment(stack, 'my-deployment', { api }); + api.root.addMethod('GET'); + + // WHEN + const testDeliveryStream = new firehose.CfnDeliveryStream(stack, 'MyStream', { + deliveryStreamName: 'amazon-apigateway-delivery-stream', + }); + new apigateway.Stage(stack, 'my-stage', { + deployment, + accessLogDestination: new apigateway.FirehoseLogDestination(testDeliveryStream), + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Stage', { + AccessLogSetting: { + DestinationArn: { + 'Fn::GetAtt': [ + 'MyStream', + 'Arn', + ], + }, + Format: '$context.identity.sourceIp $context.identity.caller $context.identity.user [$context.requestTime] "$context.httpMethod $context.resourcePath $context.protocol" $context.status $context.responseLength $context.requestId', + }, + StageName: 'prod', + }); + }); + + test('if the custom log destination firehose delivery stream and format is set', () => { + // GIVEN + const stack = new cdk.Stack(); + const api = new apigateway.RestApi(stack, 'test-api', { cloudWatchRole: false, deploy: false }); + const deployment = new apigateway.Deployment(stack, 'my-deployment', { api }); + api.root.addMethod('GET'); + + // WHEN + const testDeliveryStream = new firehose.CfnDeliveryStream(stack, 'MyStream', { + deliveryStreamName: 'amazon-apigateway-delivery-stream', + }); + const testFormat = apigateway.AccessLogFormat.jsonWithStandardFields(); + new apigateway.Stage(stack, 'my-stage', { + deployment, + accessLogDestination: new apigateway.FirehoseLogDestination(testDeliveryStream), + accessLogFormat: testFormat, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::ApiGateway::Stage', { + AccessLogSetting: { + DestinationArn: { + 'Fn::GetAtt': [ + 'MyStream', + 'Arn', + ], + }, + Format: '{"requestId":"$context.requestId","ip":"$context.identity.sourceIp","user":"$context.identity.user","caller":"$context.identity.caller","requestTime":"$context.requestTime","httpMethod":"$context.httpMethod","resourcePath":"$context.resourcePath","status":"$context.status","protocol":"$context.protocol","responseLength":"$context.responseLength"}', + }, + StageName: 'prod', + }); + }); + describe('access log check', () => { test('fails when access log format does not contain `contextRequestId()` or `contextExtendedRequestId()', () => { // GIVEN @@ -500,6 +565,25 @@ describe('stage', () => { accessLogFormat: testFormat, })).toThrow(/Access log format is specified without a destination/); }); + + test('fails if firehose delivery stream name does not start with amazon-apigateway-', () => { + // GIVEN + const stack = new cdk.Stack(); + const api = new apigateway.RestApi(stack, 'test-api', { cloudWatchRole: false, deploy: false }); + const deployment = new apigateway.Deployment(stack, 'my-deployment', { api }); + api.root.addMethod('GET'); + + // WHEN + const testDeliveryStream = new firehose.CfnDeliveryStream(stack, 'MyStream', { + deliveryStreamName: 'invalid', + }); + expect(() => { + new apigateway.Stage(stack, 'my-stage', { + deployment, + accessLogDestination: new apigateway.FirehoseLogDestination(testDeliveryStream), + }); + }).toThrow(/Firehose delivery stream name for access log destination must begin with 'amazon-apigateway-', got 'invalid'/); + }); }); test('default throttling settings', () => { diff --git a/packages/aws-cdk-lib/rosetta/aws_apigateway/default.ts-fixture b/packages/aws-cdk-lib/rosetta/aws_apigateway/default.ts-fixture index c5c06c6bb459e..6dfd84b974e43 100644 --- a/packages/aws-cdk-lib/rosetta/aws_apigateway/default.ts-fixture +++ b/packages/aws-cdk-lib/rosetta/aws_apigateway/default.ts-fixture @@ -7,6 +7,7 @@ import * as lambda from 'aws-cdk-lib/aws-lambda'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as s3 from 'aws-cdk-lib/aws-s3'; import * as ec2 from 'aws-cdk-lib/aws-ec2'; +import * as firehose from 'aws-cdk-lib/aws-kinesisfirehose'; import * as logs from 'aws-cdk-lib/aws-logs'; import * as stepfunctions from 'aws-cdk-lib/aws-stepfunctions'; import * as sagemaker from 'aws-cdk-lib/aws-sagemaker'; From 88a4619461e29f9fc9bde8051c374fbdc219c67b Mon Sep 17 00:00:00 2001 From: Otavio Macedo <288203+otaviomacedo@users.noreply.github.com> Date: Wed, 15 Nov 2023 09:52:00 +0000 Subject: [PATCH 6/8] chore: workflow to update the list of regions for `AWS::CDK::Metadata` (#27981) Steps: 1. Get the list of regions from our single source of truth. 2. Convert that list into the TypeScript code that should be the content of `packages/aws-cdk-lib/region-info/build-tools/metadata.ts`. 3. Create a PR if there were any changes. The workflow is triggered every day at 00:00. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .github/workflows/update-metadata-regions.yml | 78 +++++++++++++++++++ scripts/update-metadata-regions.js | 26 +++++++ 2 files changed, 104 insertions(+) create mode 100644 .github/workflows/update-metadata-regions.yml create mode 100644 scripts/update-metadata-regions.js diff --git a/.github/workflows/update-metadata-regions.yml b/.github/workflows/update-metadata-regions.yml new file mode 100644 index 0000000000000..8292423c7db40 --- /dev/null +++ b/.github/workflows/update-metadata-regions.yml @@ -0,0 +1,78 @@ +name: Update Metadata Regions +on: + workflow_dispatch: + schedule: + - cron: "0 0 * * *" + +jobs: + update-regions: + name: Update Regions + runs-on: ubuntu-latest + steps: + - name: Download regions + env: + URL: https://d3mqmgkwnwa8vm.cloudfront.net/regions.json + id: download + run: | + response=$(curl $URL) + echo "REGIONS=${response}" >> "$GITHUB_OUTPUT" + + status=$(curl -s -o /dev/null -w "%{http_code}" $URL) + echo "STATUS=${status}" >> "$GITHUB_OUTPUT" + - uses: actions/checkout@v3 + - uses: actions/github-script@v7 + if: ${{ steps.download.outputs.STATUS == 200 }} + env: + REGIONS: ${{ steps.download.outputs.REGIONS }} + with: + script: | + const script = require('./scripts/update-metadata-regions.js') + script() + - name: Create Patch + run: |- + git add . + git diff --patch --staged > ${{ runner.temp }}/update-spec.patch + - name: Upload Patch + uses: actions/upload-artifact@v3 + with: + name: update-spec.patch + path: ${{ runner.temp }}/update-spec.patch + + pr: + name: Create Pull Request + needs: update-regions + permissions: + contents: write + pull-requests: write + runs-on: ubuntu-latest + steps: + - name: Check Out + uses: actions/checkout@v4 + + - name: Download patch + uses: actions/download-artifact@v3 + with: + name: update-spec.patch + path: ${{ runner.temp }} + + - name: Apply patch + run: '[ -s ${{ runner.temp }}/update-spec.patch ] && git apply ${{ runner.temp }}/update-spec.patch || echo "Empty patch. Skipping."' + + - name: Make Pull Request + uses: peter-evans/create-pull-request@v5 + with: + # Git commit details + branch: automation/region-update + author: aws-cdk-automation + commit-message: |- + feat(region-info): update Metadata regions + Update the list of regions where the CDK deploys the `AWS::CDK::Metadata` resource. + # Pull Request details + title: "feat(region-info): update Metadata regions" + body: |- + Update the list of regions where the CDK deploys the `AWS::CDK::Metadata` resource. + labels: contribution/core,dependencies,auto-approve,pr-linter/exempt-integ-test,pr-linter/exempt-readme,pr-linter/exempt-test + team-reviewers: aws-cdk-team + # Github prevents further Github actions to be run if the default Github token is used. + # Instead use a privileged token here, so further GH actions can be triggered on this PR. + token: ${{ secrets.PROJEN_GITHUB_TOKEN }} diff --git a/scripts/update-metadata-regions.js b/scripts/update-metadata-regions.js new file mode 100644 index 0000000000000..dbab69148f720 --- /dev/null +++ b/scripts/update-metadata-regions.js @@ -0,0 +1,26 @@ +module.exports = () => { + const fs= require('fs'); + const regions = JSON.parse(process.env.REGIONS); + const content = generateFileContent(regions); + const path = './packages/aws-cdk-lib/region-info/build-tools/metadata.ts'; + fs.writeFileSync(path, content); +} + +function generateFileContent(regions) { + const template = `/* +* Do not edit this file manually. To prevent misconfiguration, this file +* should only be modified by an automated GitHub workflow, that ensures +* that the regions present in this list correspond to all the regions +* where we have the AWS::CDK::Metadata handler deployed. +* +* See: https://github.com/aws/aws-cdk/issues/27189 +*/ + +export const AWS_CDK_METADATA = new Set([ +$REGIONS +]); +`; + + const list = regions.sort().map(r => ` '${r}',`).join('\n'); + return template.replace('$REGIONS', list); +} \ No newline at end of file From db21fefc2dc76eb4ff306fa41652ab6a6cc95e42 Mon Sep 17 00:00:00 2001 From: J11522 <60687512+J11522@users.noreply.github.com> Date: Wed, 15 Nov 2023 14:26:17 +0100 Subject: [PATCH 7/8] docs(lambda-nodejs): fix default runtime docs (#27984) With https://github.com/aws/aws-cdk/pull/26763 the default runtime was reverted from NODEJS_18_X to NODEJS_16_X This PR reflects this in the docs of the NodejsFunctionProps ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- packages/aws-cdk-lib/aws-lambda-nodejs/lib/function.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/aws-cdk-lib/aws-lambda-nodejs/lib/function.ts b/packages/aws-cdk-lib/aws-lambda-nodejs/lib/function.ts index 6df32bf9dc31f..9dbc15420aee7 100644 --- a/packages/aws-cdk-lib/aws-lambda-nodejs/lib/function.ts +++ b/packages/aws-cdk-lib/aws-lambda-nodejs/lib/function.ts @@ -38,7 +38,7 @@ export interface NodejsFunctionProps extends lambda.FunctionOptions { * The runtime environment. Only runtimes of the Node.js family are * supported. * - * @default Runtime.NODEJS_18_X + * @default `Runtime.NODEJS_LATEST` if the `@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion` feature flag is enabled, otherwise `Runtime.NODEJS_16_X` */ readonly runtime?: lambda.Runtime; From 514f7551c53dec0b30198b650e253cfa2dccbc0f Mon Sep 17 00:00:00 2001 From: Otavio Macedo <288203+otaviomacedo@users.noreply.github.com> Date: Wed, 15 Nov 2023 15:13:07 +0000 Subject: [PATCH 8/8] chore: new prlint rule to protect the metadata.ts file against manual changes (#28007) Only automated changes to the `packages/aws-cdk-lib/region-info/build-tools/metadata.ts` file are allowed. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- tools/@aws-cdk/prlint/lint.ts | 16 ++++++++++-- tools/@aws-cdk/prlint/test/lint.test.ts | 34 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/tools/@aws-cdk/prlint/lint.ts b/tools/@aws-cdk/prlint/lint.ts index 06d7ec6ab5093..a3ded02249f4c 100644 --- a/tools/@aws-cdk/prlint/lint.ts +++ b/tools/@aws-cdk/prlint/lint.ts @@ -567,6 +567,11 @@ export class PullRequestLinter { testRuleSet: [{ test: noCliChanges }], }); + validationCollector.validateRuleSet({ + exemption: (pr) => pr.user?.login === 'aws-cdk-automation', + testRuleSet: [{ test: noMetadataChanges }], + }) + await this.deletePRLinterComment(); try { await this.communicateResult(validationCollector); @@ -732,13 +737,13 @@ function validateTitleScope(pr: GitHubPr): TestResult { /** * Check that the PR is not opened from main branch of author's fork - * + * * @param pr github pr * @returns test result */ function validateBranch(pr: GitHubPr): TestResult { const result = new TestResult(); - + if (pr.head && pr.head.ref) { result.assessFailure(pr.head.ref === 'main', PR_FROM_MAIN_ERROR); } @@ -766,6 +771,13 @@ function noCliChanges(pr: GitHubPr, files: GitHubFile[]): TestResult { ); } +function noMetadataChanges(_pr: GitHubPr, files: GitHubFile[]): TestResult { + const result = new TestResult(); + const condition = files.some(file => file.filename === 'packages/aws-cdk-lib/region-info/build-tools/metadata.ts'); + result.assessFailure(condition, 'Manual changes to the metadata.ts file are not allowed.'); + return result; +} + require('make-runnable/custom')({ printOutputFrame: false, }); diff --git a/tools/@aws-cdk/prlint/test/lint.test.ts b/tools/@aws-cdk/prlint/test/lint.test.ts index 9952537a8ff35..330c32dee3a49 100644 --- a/tools/@aws-cdk/prlint/test/lint.test.ts +++ b/tools/@aws-cdk/prlint/test/lint.test.ts @@ -1010,6 +1010,40 @@ describe('integration tests required on features', () => { expect(mockAddLabel.mock.calls).toEqual([]); }); }); + + describe('metadata file changed', () => { + const files: linter.GitHubFile[] = [{ + filename: 'packages/aws-cdk-lib/region-info/build-tools/metadata.ts', + }]; + + test('with aws-cdk-automation author', async () => { + const pr = { + title: 'chore: Update regions', + number: 1234, + labels: [], + user: { + login: 'aws-cdk-automation' + }, + }; + + const prLinter = configureMock(pr, files); + await expect(prLinter.validatePullRequestTarget(SHA)).resolves; + }); + + test('with another author', async () => { + const pr = { + title: 'chore: Update regions', + number: 1234, + labels: [], + user: { + login: 'johndoe', + }, + }; + + const prLinter = configureMock(pr, files); + await expect(prLinter.validatePullRequestTarget(SHA)).rejects.toThrow(); + }); + }); }); function configureMock(pr: Subset, prFiles?: linter.GitHubFile[]): linter.PullRequestLinter {