diff --git a/packages/@aws-cdk/aws-eks/README.md b/packages/@aws-cdk/aws-eks/README.md index b13d4efa35878..050ea01cfa4d6 100644 --- a/packages/@aws-cdk/aws-eks/README.md +++ b/packages/@aws-cdk/aws-eks/README.md @@ -305,6 +305,7 @@ You may specify one `instanceType` in the launch template or multiple `instanceT > For more details visit [Launch Template Support](https://docs.aws.amazon.com/eks/latest/userguide/launch-templates.html). Graviton 2 instance types are supported including `c6g`, `m6g`, `r6g` and `t4g`. +Graviton 3 instance types are supported including `c7g`. ### Fargate profiles diff --git a/packages/@aws-cdk/aws-eks/lib/cluster.ts b/packages/@aws-cdk/aws-eks/lib/cluster.ts index 3aab173529828..5fd70cd5b1d45 100644 --- a/packages/@aws-cdk/aws-eks/lib/cluster.ts +++ b/packages/@aws-cdk/aws-eks/lib/cluster.ts @@ -2280,8 +2280,9 @@ function nodeTypeForInstanceType(instanceType: ec2.InstanceType) { function cpuArchForInstanceType(instanceType: ec2.InstanceType) { return INSTANCE_TYPES.graviton2.includes(instanceType.toString().substring(0, 3)) ? CpuArch.ARM_64 : - INSTANCE_TYPES.graviton.includes(instanceType.toString().substring(0, 2)) ? CpuArch.ARM_64 : - CpuArch.X86_64; + INSTANCE_TYPES.graviton3.includes(instanceType.toString().substring(0, 3)) ? CpuArch.ARM_64 : + INSTANCE_TYPES.graviton.includes(instanceType.toString().substring(0, 2)) ? CpuArch.ARM_64 : + CpuArch.X86_64; } function flatten(xss: A[][]): A[] { diff --git a/packages/@aws-cdk/aws-eks/lib/instance-types.ts b/packages/@aws-cdk/aws-eks/lib/instance-types.ts index e08b3e43054cd..0d43beacd152f 100644 --- a/packages/@aws-cdk/aws-eks/lib/instance-types.ts +++ b/packages/@aws-cdk/aws-eks/lib/instance-types.ts @@ -3,4 +3,5 @@ export const INSTANCE_TYPES = { inferentia: ['inf1'], graviton: ['a1'], graviton2: ['c6g', 'm6g', 'r6g', 't4g'], + graviton3: ['c7g'], }; diff --git a/packages/@aws-cdk/aws-eks/test/cluster.test.ts b/packages/@aws-cdk/aws-eks/test/cluster.test.ts index 479a9725a993f..bd670b6cc9d61 100644 --- a/packages/@aws-cdk/aws-eks/test/cluster.test.ts +++ b/packages/@aws-cdk/aws-eks/test/cluster.test.ts @@ -1776,6 +1776,50 @@ describe('cluster', () => { }); + test('addNodegroupCapacity with C7g instance type comes with nodegroup with correct AmiType', () => { + // GIVEN + const { stack } = testFixtureNoVpc(); + + // WHEN + new eks.Cluster(stack, 'cluster', { + defaultCapacity: 0, + version: CLUSTER_VERSION, + prune: false, + defaultCapacityInstance: new ec2.InstanceType('c7g.large'), + }).addNodegroupCapacity('ng', { + instanceTypes: [new ec2.InstanceType('c7g.large')], + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::EKS::Nodegroup', { + AmiType: 'AL2_ARM_64', + }); + + }); + + test('addAutoScalingGroupCapacity with C7g instance type comes with nodegroup with correct AmiType', () => { + // GIVEN + const { app, stack } = testFixtureNoVpc(); + + // WHEN + new eks.Cluster(stack, 'cluster', { + defaultCapacity: 0, + version: CLUSTER_VERSION, + prune: false, + }).addAutoScalingGroupCapacity('ng', { + instanceType: new ec2.InstanceType('c7g.large'), + }); + + // THEN + const assembly = app.synth(); + const parameters = assembly.getStackByName(stack.stackName).template.Parameters; + expect(Object.entries(parameters).some( + ([k, v]) => k.startsWith('SsmParameterValueawsserviceeksoptimizedami') && + (v as any).Default.includes('amazon-linux-2-arm64/'), + )).toEqual(true); + + }); + test('EKS-Optimized AMI with GPU support when addAutoScalingGroupCapacity', () => { // GIVEN const { app, stack } = testFixtureNoVpc(); diff --git a/packages/@aws-cdk/aws-eks/test/eks-cluster.integ.snapshot/aws-cdk-eks-cluster-test.template.json b/packages/@aws-cdk/aws-eks/test/eks-cluster.integ.snapshot/aws-cdk-eks-cluster-test.template.json index 4b4c9c2dc1836..281bb1075114d 100644 --- a/packages/@aws-cdk/aws-eks/test/eks-cluster.integ.snapshot/aws-cdk-eks-cluster-test.template.json +++ b/packages/@aws-cdk/aws-eks/test/eks-cluster.integ.snapshot/aws-cdk-eks-cluster-test.template.json @@ -1054,6 +1054,13 @@ ] }, "\\\",\\\"username\\\":\\\"system:node:{{EC2PrivateDNSName}}\\\",\\\"groups\\\":[\\\"system:bootstrappers\\\",\\\"system:nodes\\\"]},{\\\"rolearn\\\":\\\"", + { + "Fn::GetAtt": [ + "ClusterNodegroupextrangarm3NodeGroupRole3A6AB3EC", + "Arn" + ] + }, + "\\\",\\\"username\\\":\\\"system:node:{{EC2PrivateDNSName}}\\\",\\\"groups\\\":[\\\"system:bootstrappers\\\",\\\"system:nodes\\\"]},{\\\"rolearn\\\":\\\"", { "Fn::GetAtt": [ "ClusterNodegroupDefaultCapacityNodeGroupRole55953B04", @@ -2780,6 +2787,93 @@ } } }, + "ClusterNodegroupextrangarm3NodeGroupRole3A6AB3EC": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/AmazonEKSWorkerNodePolicy" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/AmazonEKS_CNI_Policy" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" + ] + ] + } + ] + } + }, + "ClusterNodegroupextrangarm327128311": { + "Type": "AWS::EKS::Nodegroup", + "Properties": { + "ClusterName": { + "Ref": "Cluster9EE0221C" + }, + "NodeRole": { + "Fn::GetAtt": [ + "ClusterNodegroupextrangarm3NodeGroupRole3A6AB3EC", + "Arn" + ] + }, + "Subnets": [ + { + "Ref": "VpcPrivateSubnet1Subnet536B997A" + }, + { + "Ref": "VpcPrivateSubnet2Subnet3788AAA1" + } + ], + "AmiType": "AL2_ARM_64", + "ForceUpdateEnabled": true, + "InstanceTypes": [ + "c7g.large" + ], + "ScalingConfig": { + "DesiredSize": 1, + "MaxSize": 1, + "MinSize": 1 + } + } + }, "ClusterNodegroupextrang2F1FB0D40": { "Type": "AWS::EKS::Nodegroup", "Properties": { @@ -3311,7 +3405,7 @@ }, "/", { - "Ref": "AssetParameters4fe671b3201bc8496c4e58f0d4cc72571feb8450ba22b4f349e735d42c2536dcS3Bucket5F2DC1B8" + "Ref": "AssetParameters5f0eb64dd4fa84d66280c8a6cc10dc6a7fdca93c17dbf354aaa71cde3dd5dedcS3BucketDC78C2FE" }, "/", { @@ -3321,7 +3415,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters4fe671b3201bc8496c4e58f0d4cc72571feb8450ba22b4f349e735d42c2536dcS3VersionKeyA3093C7A" + "Ref": "AssetParameters5f0eb64dd4fa84d66280c8a6cc10dc6a7fdca93c17dbf354aaa71cde3dd5dedcS3VersionKeyFEB3884E" } ] } @@ -3334,7 +3428,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters4fe671b3201bc8496c4e58f0d4cc72571feb8450ba22b4f349e735d42c2536dcS3VersionKeyA3093C7A" + "Ref": "AssetParameters5f0eb64dd4fa84d66280c8a6cc10dc6a7fdca93c17dbf354aaa71cde3dd5dedcS3VersionKeyFEB3884E" } ] } @@ -3356,11 +3450,11 @@ "Arn" ] }, - "referencetoawscdkeksclustertestAssetParameters4b85e8c141d9b886acbf891007402913e39574073ba1f533288a75c9f56082c6S3Bucket21BC7ECERef": { - "Ref": "AssetParameters4b85e8c141d9b886acbf891007402913e39574073ba1f533288a75c9f56082c6S3Bucket5017D348" + "referencetoawscdkeksclustertestAssetParameters2c98a634e36e3f2a1c1a78958953ed173e2c6cf8446c15dabbef67d4e30b33d6S3BucketB0701606Ref": { + "Ref": "AssetParameters2c98a634e36e3f2a1c1a78958953ed173e2c6cf8446c15dabbef67d4e30b33d6S3Bucket60C6EC09" }, - "referencetoawscdkeksclustertestAssetParameters4b85e8c141d9b886acbf891007402913e39574073ba1f533288a75c9f56082c6S3VersionKey31720EE9Ref": { - "Ref": "AssetParameters4b85e8c141d9b886acbf891007402913e39574073ba1f533288a75c9f56082c6S3VersionKeyAC941219" + "referencetoawscdkeksclustertestAssetParameters2c98a634e36e3f2a1c1a78958953ed173e2c6cf8446c15dabbef67d4e30b33d6S3VersionKeyA2A91899Ref": { + "Ref": "AssetParameters2c98a634e36e3f2a1c1a78958953ed173e2c6cf8446c15dabbef67d4e30b33d6S3VersionKey8076CD69" }, "referencetoawscdkeksclustertestAssetParameters8dd02cc4ac473ca5b08800e92edaa31a1a7db4005928021d029c5363584f11b9S3BucketC52CB9E4Ref": { "Ref": "AssetParameters8dd02cc4ac473ca5b08800e92edaa31a1a7db4005928021d029c5363584f11b9S3Bucket40DFAF90" @@ -3386,7 +3480,7 @@ }, "/", { - "Ref": "AssetParameters8b13a8bc3f23044c45d3121e7bb859be3e1e7d45bf46602d8d2d200973e663acS3Bucket5D1456D5" + "Ref": "AssetParametersc902e5341ae59aeb2853811f8e776a14deac1186d0dfb25c1a5bcefbc57ae0d6S3Bucket5B6259EA" }, "/", { @@ -3396,7 +3490,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters8b13a8bc3f23044c45d3121e7bb859be3e1e7d45bf46602d8d2d200973e663acS3VersionKey797A2D02" + "Ref": "AssetParametersc902e5341ae59aeb2853811f8e776a14deac1186d0dfb25c1a5bcefbc57ae0d6S3VersionKeyEF56C46B" } ] } @@ -3409,7 +3503,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters8b13a8bc3f23044c45d3121e7bb859be3e1e7d45bf46602d8d2d200973e663acS3VersionKey797A2D02" + "Ref": "AssetParametersc902e5341ae59aeb2853811f8e776a14deac1186d0dfb25c1a5bcefbc57ae0d6S3VersionKeyEF56C46B" } ] } @@ -3452,11 +3546,11 @@ "ClusterSecurityGroupId" ] }, - "referencetoawscdkeksclustertestAssetParameters02927fd0ce5bb130cbc8d11f17469e74496526efe5186a9ab36e8a8138e9a557S3Bucket8CD406DDRef": { - "Ref": "AssetParameters02927fd0ce5bb130cbc8d11f17469e74496526efe5186a9ab36e8a8138e9a557S3Bucket8513C222" + "referencetoawscdkeksclustertestAssetParametersb7f327b4415410f319943b754edb274645a9d6850369ae4da9ba209858099210S3Bucket9847903ERef": { + "Ref": "AssetParametersb7f327b4415410f319943b754edb274645a9d6850369ae4da9ba209858099210S3Bucket4CC06B47" }, - "referencetoawscdkeksclustertestAssetParameters02927fd0ce5bb130cbc8d11f17469e74496526efe5186a9ab36e8a8138e9a557S3VersionKeyF46DA6ECRef": { - "Ref": "AssetParameters02927fd0ce5bb130cbc8d11f17469e74496526efe5186a9ab36e8a8138e9a557S3VersionKeyDF2A43EA" + "referencetoawscdkeksclustertestAssetParametersb7f327b4415410f319943b754edb274645a9d6850369ae4da9ba209858099210S3VersionKey606283CERef": { + "Ref": "AssetParametersb7f327b4415410f319943b754edb274645a9d6850369ae4da9ba209858099210S3VersionKey26C408F7" }, "referencetoawscdkeksclustertestAssetParametersc6964dbf0c556ec82ce09622e99ad6f6d4e488cdaac0ef9e8492e078ec61ffedS3Bucket1C5C92D4Ref": { "Ref": "AssetParametersc6964dbf0c556ec82ce09622e99ad6f6d4e488cdaac0ef9e8492e078ec61ffedS3Bucket83B8778F" @@ -3575,7 +3669,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParameters5507835727e005832a615aef2a6b437860f432c6cd052d07c0244464aedbe2b2S3Bucket211A9156" + "Ref": "AssetParameters2a0bb2dced0cdd3ae7ccd3bb93e9ac31a9b581360c144953e849dfa36e557581S3Bucket77114819" }, "S3Key": { "Fn::Join": [ @@ -3588,7 +3682,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters5507835727e005832a615aef2a6b437860f432c6cd052d07c0244464aedbe2b2S3VersionKey822D04EC" + "Ref": "AssetParameters2a0bb2dced0cdd3ae7ccd3bb93e9ac31a9b581360c144953e849dfa36e557581S3VersionKey792D800A" } ] } @@ -3601,7 +3695,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters5507835727e005832a615aef2a6b437860f432c6cd052d07c0244464aedbe2b2S3VersionKey822D04EC" + "Ref": "AssetParameters2a0bb2dced0cdd3ae7ccd3bb93e9ac31a9b581360c144953e849dfa36e557581S3VersionKey792D800A" } ] } @@ -3653,7 +3747,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParametersf850d967c52a5f64e6436dc84abdde4d86197f2a0871f5ab27c79647a91d0bf4S3Bucket6F458959" + "Ref": "AssetParametersd3502a9c9ef2e8f5c5638ffe9d263e28c72f912d4a23673b8a77ddfcda6f2a17S3Bucket66931829" }, "S3Key": { "Fn::Join": [ @@ -3666,7 +3760,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersf850d967c52a5f64e6436dc84abdde4d86197f2a0871f5ab27c79647a91d0bf4S3VersionKeyBDD0572E" + "Ref": "AssetParametersd3502a9c9ef2e8f5c5638ffe9d263e28c72f912d4a23673b8a77ddfcda6f2a17S3VersionKey9D91BCFF" } ] } @@ -3679,7 +3773,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParametersf850d967c52a5f64e6436dc84abdde4d86197f2a0871f5ab27c79647a91d0bf4S3VersionKeyBDD0572E" + "Ref": "AssetParametersd3502a9c9ef2e8f5c5638ffe9d263e28c72f912d4a23673b8a77ddfcda6f2a17S3VersionKey9D91BCFF" } ] } @@ -3805,17 +3899,17 @@ "Type": "String", "Description": "Artifact hash for asset \"4288ebb3652acdf2d828b7db7ca44a7162a401ace50ebb4026e84b18a02a06ee\"" }, - "AssetParameters4b85e8c141d9b886acbf891007402913e39574073ba1f533288a75c9f56082c6S3Bucket5017D348": { + "AssetParameters2c98a634e36e3f2a1c1a78958953ed173e2c6cf8446c15dabbef67d4e30b33d6S3Bucket60C6EC09": { "Type": "String", - "Description": "S3 bucket for asset \"4b85e8c141d9b886acbf891007402913e39574073ba1f533288a75c9f56082c6\"" + "Description": "S3 bucket for asset \"2c98a634e36e3f2a1c1a78958953ed173e2c6cf8446c15dabbef67d4e30b33d6\"" }, - "AssetParameters4b85e8c141d9b886acbf891007402913e39574073ba1f533288a75c9f56082c6S3VersionKeyAC941219": { + "AssetParameters2c98a634e36e3f2a1c1a78958953ed173e2c6cf8446c15dabbef67d4e30b33d6S3VersionKey8076CD69": { "Type": "String", - "Description": "S3 key for asset version \"4b85e8c141d9b886acbf891007402913e39574073ba1f533288a75c9f56082c6\"" + "Description": "S3 key for asset version \"2c98a634e36e3f2a1c1a78958953ed173e2c6cf8446c15dabbef67d4e30b33d6\"" }, - "AssetParameters4b85e8c141d9b886acbf891007402913e39574073ba1f533288a75c9f56082c6ArtifactHash62A6950B": { + "AssetParameters2c98a634e36e3f2a1c1a78958953ed173e2c6cf8446c15dabbef67d4e30b33d6ArtifactHashA9858604": { "Type": "String", - "Description": "Artifact hash for asset \"4b85e8c141d9b886acbf891007402913e39574073ba1f533288a75c9f56082c6\"" + "Description": "Artifact hash for asset \"2c98a634e36e3f2a1c1a78958953ed173e2c6cf8446c15dabbef67d4e30b33d6\"" }, "AssetParameters8dd02cc4ac473ca5b08800e92edaa31a1a7db4005928021d029c5363584f11b9S3Bucket40DFAF90": { "Type": "String", @@ -3841,17 +3935,17 @@ "Type": "String", "Description": "Artifact hash for asset \"07a1c6a504be72dba3e9bc5b12cc2b5b0e83ea5c6ba10a4128da5c2180f3f963\"" }, - "AssetParameters02927fd0ce5bb130cbc8d11f17469e74496526efe5186a9ab36e8a8138e9a557S3Bucket8513C222": { + "AssetParametersb7f327b4415410f319943b754edb274645a9d6850369ae4da9ba209858099210S3Bucket4CC06B47": { "Type": "String", - "Description": "S3 bucket for asset \"02927fd0ce5bb130cbc8d11f17469e74496526efe5186a9ab36e8a8138e9a557\"" + "Description": "S3 bucket for asset \"b7f327b4415410f319943b754edb274645a9d6850369ae4da9ba209858099210\"" }, - "AssetParameters02927fd0ce5bb130cbc8d11f17469e74496526efe5186a9ab36e8a8138e9a557S3VersionKeyDF2A43EA": { + "AssetParametersb7f327b4415410f319943b754edb274645a9d6850369ae4da9ba209858099210S3VersionKey26C408F7": { "Type": "String", - "Description": "S3 key for asset version \"02927fd0ce5bb130cbc8d11f17469e74496526efe5186a9ab36e8a8138e9a557\"" + "Description": "S3 key for asset version \"b7f327b4415410f319943b754edb274645a9d6850369ae4da9ba209858099210\"" }, - "AssetParameters02927fd0ce5bb130cbc8d11f17469e74496526efe5186a9ab36e8a8138e9a557ArtifactHash89001C28": { + "AssetParametersb7f327b4415410f319943b754edb274645a9d6850369ae4da9ba209858099210ArtifactHash26556182": { "Type": "String", - "Description": "Artifact hash for asset \"02927fd0ce5bb130cbc8d11f17469e74496526efe5186a9ab36e8a8138e9a557\"" + "Description": "Artifact hash for asset \"b7f327b4415410f319943b754edb274645a9d6850369ae4da9ba209858099210\"" }, "AssetParametersc6964dbf0c556ec82ce09622e99ad6f6d4e488cdaac0ef9e8492e078ec61ffedS3Bucket83B8778F": { "Type": "String", @@ -3877,53 +3971,53 @@ "Type": "String", "Description": "Artifact hash for asset \"d65fbdc11b108e0386ed8577c454d4544f6d4e7960f84a0d2e211478d6324dbf\"" }, - "AssetParameters5507835727e005832a615aef2a6b437860f432c6cd052d07c0244464aedbe2b2S3Bucket211A9156": { + "AssetParameters2a0bb2dced0cdd3ae7ccd3bb93e9ac31a9b581360c144953e849dfa36e557581S3Bucket77114819": { "Type": "String", - "Description": "S3 bucket for asset \"5507835727e005832a615aef2a6b437860f432c6cd052d07c0244464aedbe2b2\"" + "Description": "S3 bucket for asset \"2a0bb2dced0cdd3ae7ccd3bb93e9ac31a9b581360c144953e849dfa36e557581\"" }, - "AssetParameters5507835727e005832a615aef2a6b437860f432c6cd052d07c0244464aedbe2b2S3VersionKey822D04EC": { + "AssetParameters2a0bb2dced0cdd3ae7ccd3bb93e9ac31a9b581360c144953e849dfa36e557581S3VersionKey792D800A": { "Type": "String", - "Description": "S3 key for asset version \"5507835727e005832a615aef2a6b437860f432c6cd052d07c0244464aedbe2b2\"" + "Description": "S3 key for asset version \"2a0bb2dced0cdd3ae7ccd3bb93e9ac31a9b581360c144953e849dfa36e557581\"" }, - "AssetParameters5507835727e005832a615aef2a6b437860f432c6cd052d07c0244464aedbe2b2ArtifactHashCA4A1831": { + "AssetParameters2a0bb2dced0cdd3ae7ccd3bb93e9ac31a9b581360c144953e849dfa36e557581ArtifactHashCE3B38C5": { "Type": "String", - "Description": "Artifact hash for asset \"5507835727e005832a615aef2a6b437860f432c6cd052d07c0244464aedbe2b2\"" + "Description": "Artifact hash for asset \"2a0bb2dced0cdd3ae7ccd3bb93e9ac31a9b581360c144953e849dfa36e557581\"" }, - "AssetParametersf850d967c52a5f64e6436dc84abdde4d86197f2a0871f5ab27c79647a91d0bf4S3Bucket6F458959": { + "AssetParametersd3502a9c9ef2e8f5c5638ffe9d263e28c72f912d4a23673b8a77ddfcda6f2a17S3Bucket66931829": { "Type": "String", - "Description": "S3 bucket for asset \"f850d967c52a5f64e6436dc84abdde4d86197f2a0871f5ab27c79647a91d0bf4\"" + "Description": "S3 bucket for asset \"d3502a9c9ef2e8f5c5638ffe9d263e28c72f912d4a23673b8a77ddfcda6f2a17\"" }, - "AssetParametersf850d967c52a5f64e6436dc84abdde4d86197f2a0871f5ab27c79647a91d0bf4S3VersionKeyBDD0572E": { + "AssetParametersd3502a9c9ef2e8f5c5638ffe9d263e28c72f912d4a23673b8a77ddfcda6f2a17S3VersionKey9D91BCFF": { "Type": "String", - "Description": "S3 key for asset version \"f850d967c52a5f64e6436dc84abdde4d86197f2a0871f5ab27c79647a91d0bf4\"" + "Description": "S3 key for asset version \"d3502a9c9ef2e8f5c5638ffe9d263e28c72f912d4a23673b8a77ddfcda6f2a17\"" }, - "AssetParametersf850d967c52a5f64e6436dc84abdde4d86197f2a0871f5ab27c79647a91d0bf4ArtifactHash4D5DD9E9": { + "AssetParametersd3502a9c9ef2e8f5c5638ffe9d263e28c72f912d4a23673b8a77ddfcda6f2a17ArtifactHash20C52FA1": { "Type": "String", - "Description": "Artifact hash for asset \"f850d967c52a5f64e6436dc84abdde4d86197f2a0871f5ab27c79647a91d0bf4\"" + "Description": "Artifact hash for asset \"d3502a9c9ef2e8f5c5638ffe9d263e28c72f912d4a23673b8a77ddfcda6f2a17\"" }, - "AssetParameters4fe671b3201bc8496c4e58f0d4cc72571feb8450ba22b4f349e735d42c2536dcS3Bucket5F2DC1B8": { + "AssetParameters5f0eb64dd4fa84d66280c8a6cc10dc6a7fdca93c17dbf354aaa71cde3dd5dedcS3BucketDC78C2FE": { "Type": "String", - "Description": "S3 bucket for asset \"4fe671b3201bc8496c4e58f0d4cc72571feb8450ba22b4f349e735d42c2536dc\"" + "Description": "S3 bucket for asset \"5f0eb64dd4fa84d66280c8a6cc10dc6a7fdca93c17dbf354aaa71cde3dd5dedc\"" }, - "AssetParameters4fe671b3201bc8496c4e58f0d4cc72571feb8450ba22b4f349e735d42c2536dcS3VersionKeyA3093C7A": { + "AssetParameters5f0eb64dd4fa84d66280c8a6cc10dc6a7fdca93c17dbf354aaa71cde3dd5dedcS3VersionKeyFEB3884E": { "Type": "String", - "Description": "S3 key for asset version \"4fe671b3201bc8496c4e58f0d4cc72571feb8450ba22b4f349e735d42c2536dc\"" + "Description": "S3 key for asset version \"5f0eb64dd4fa84d66280c8a6cc10dc6a7fdca93c17dbf354aaa71cde3dd5dedc\"" }, - "AssetParameters4fe671b3201bc8496c4e58f0d4cc72571feb8450ba22b4f349e735d42c2536dcArtifactHashBF850100": { + "AssetParameters5f0eb64dd4fa84d66280c8a6cc10dc6a7fdca93c17dbf354aaa71cde3dd5dedcArtifactHashA8FD8CC6": { "Type": "String", - "Description": "Artifact hash for asset \"4fe671b3201bc8496c4e58f0d4cc72571feb8450ba22b4f349e735d42c2536dc\"" + "Description": "Artifact hash for asset \"5f0eb64dd4fa84d66280c8a6cc10dc6a7fdca93c17dbf354aaa71cde3dd5dedc\"" }, - "AssetParameters8b13a8bc3f23044c45d3121e7bb859be3e1e7d45bf46602d8d2d200973e663acS3Bucket5D1456D5": { + "AssetParametersc902e5341ae59aeb2853811f8e776a14deac1186d0dfb25c1a5bcefbc57ae0d6S3Bucket5B6259EA": { "Type": "String", - "Description": "S3 bucket for asset \"8b13a8bc3f23044c45d3121e7bb859be3e1e7d45bf46602d8d2d200973e663ac\"" + "Description": "S3 bucket for asset \"c902e5341ae59aeb2853811f8e776a14deac1186d0dfb25c1a5bcefbc57ae0d6\"" }, - "AssetParameters8b13a8bc3f23044c45d3121e7bb859be3e1e7d45bf46602d8d2d200973e663acS3VersionKey797A2D02": { + "AssetParametersc902e5341ae59aeb2853811f8e776a14deac1186d0dfb25c1a5bcefbc57ae0d6S3VersionKeyEF56C46B": { "Type": "String", - "Description": "S3 key for asset version \"8b13a8bc3f23044c45d3121e7bb859be3e1e7d45bf46602d8d2d200973e663ac\"" + "Description": "S3 key for asset version \"c902e5341ae59aeb2853811f8e776a14deac1186d0dfb25c1a5bcefbc57ae0d6\"" }, - "AssetParameters8b13a8bc3f23044c45d3121e7bb859be3e1e7d45bf46602d8d2d200973e663acArtifactHash1F5B121B": { + "AssetParametersc902e5341ae59aeb2853811f8e776a14deac1186d0dfb25c1a5bcefbc57ae0d6ArtifactHashEB43557F": { "Type": "String", - "Description": "Artifact hash for asset \"8b13a8bc3f23044c45d3121e7bb859be3e1e7d45bf46602d8d2d200973e663ac\"" + "Description": "Artifact hash for asset \"c902e5341ae59aeb2853811f8e776a14deac1186d0dfb25c1a5bcefbc57ae0d6\"" }, "SsmParameterValueawsserviceeksoptimizedami121amazonlinux2recommendedimageidC96584B6F00A464EAD1953AFF4B05118Parameter": { "Type": "AWS::SSM::Parameter::Value", diff --git a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts index 51c55f265586b..248f6c2f714e0 100644 --- a/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts +++ b/packages/@aws-cdk/aws-eks/test/integ.eks-cluster.ts @@ -63,6 +63,8 @@ class EksClusterStack extends Stack { this.assertNodeGroupArm(); + this.assertNodeGroupGraviton3(); + this.assertNodeGroupCustomAmi(); this.assertSimpleManifest(); @@ -244,6 +246,15 @@ class EksClusterStack extends Stack { nodeRole: this.cluster.defaultCapacity ? this.cluster.defaultCapacity.role : undefined, }); } + private assertNodeGroupGraviton3() { + // add a Graviton3 nodegroup + this.cluster.addNodegroupCapacity('extra-ng-arm3', { + instanceType: new ec2.InstanceType('c7g.large'), + minSize: 1, + // reusing the default capacity nodegroup instance role when available + nodeRole: this.cluster.defaultCapacity ? this.cluster.defaultCapacity.role : undefined, + }); + } private assertSpotCapacity() { // spot instances (up to 10) this.cluster.addAutoScalingGroupCapacity('spot', { diff --git a/packages/@aws-cdk/aws-events-targets/README.md b/packages/@aws-cdk/aws-events-targets/README.md index 290c6215e37d8..c17bb37a9118b 100644 --- a/packages/@aws-cdk/aws-events-targets/README.md +++ b/packages/@aws-cdk/aws-events-targets/README.md @@ -94,6 +94,39 @@ const rule = new events.Rule(this, 'rule', { rule.addTarget(new targets.CloudWatchLogGroup(logGroup)); ``` +A rule target input can also be specified to modify the event that is sent to the log group. +Unlike other event targets, CloudWatchLogs requires a specific input template format. + +```ts +import * as logs from '@aws-cdk/aws-logs'; +declare const logGroup: logs.LogGroup; +declare const rule: events.Rule; + +rule.addTarget(new targets.CloudWatchLogGroup(logGroup, { + logEvent: targets.LogGroupTargetInput({ + timestamp: events.EventField.from('$.time'), + message: events.EventField.from('$.detail-type'), + }), +})); +``` + +If you want to use static values to overwrite the `message` make sure that you provide a `string` +value. + +```ts +import * as logs from '@aws-cdk/aws-logs'; +declare const logGroup: logs.LogGroup; +declare const rule: events.Rule; + +rule.addTarget(new targets.CloudWatchLogGroup(logGroup, { + logEvent: targets.LogGroupTargetInput({ + message: JSON.stringify({ + CustomField: 'CustomValue', + }), + }), +})); +``` + ## Start a CodeBuild build Use the `CodeBuildProject` target to trigger a CodeBuild project. diff --git a/packages/@aws-cdk/aws-events-targets/lib/log-group.ts b/packages/@aws-cdk/aws-events-targets/lib/log-group.ts index 18c11cad862db..b12cfc849c69d 100644 --- a/packages/@aws-cdk/aws-events-targets/lib/log-group.ts +++ b/packages/@aws-cdk/aws-events-targets/lib/log-group.ts @@ -2,9 +2,59 @@ import * as events from '@aws-cdk/aws-events'; import * as iam from '@aws-cdk/aws-iam'; import * as logs from '@aws-cdk/aws-logs'; import * as cdk from '@aws-cdk/core'; -import { ArnFormat } from '@aws-cdk/core'; +import { ArnFormat, Stack } from '@aws-cdk/core'; import { LogGroupResourcePolicy } from './log-group-resource-policy'; import { TargetBaseProps, bindBaseTargetConfig } from './util'; +import { RuleTargetInputProperties, RuleTargetInput, EventField, IRule } from '@aws-cdk/aws-events'; + +/** + * Options used when creating a target input template + */ +export interface LogGroupTargetInputOptions { + /** + * The timestamp that will appear in the CloudWatch Logs record + * + * @default EventField.time + */ + readonly timestamp?: any; + + /** + * The value provided here will be used in the Log "message" field. + * + * This field must be a string. If an object is passed (e.g. JSON data) + * it will not throw an error, but the message that makes it to + * CloudWatch logs will be incorrect. This is a likely scenario if + * doing something like: EventField.fromPath('$.detail') since in most cases + * the `detail` field contains JSON data. + * + * @default EventField.detailType + */ + readonly message?: any; +} + +/** + * The input to send to the CloudWatch LogGroup target + */ +export abstract class LogGroupTargetInput { + + /** + * Pass a JSON object to the the log group event target + * + * May contain strings returned by `EventField.from()` to substitute in parts of the + * matched event. + */ + public static fromObject(options?: LogGroupTargetInputOptions): RuleTargetInput { + return RuleTargetInput.fromObject({ + timestamp: options?.timestamp ?? EventField.time, + message: options?.message ?? EventField.detailType, + }); + }; + + /** + * Return the input properties for this input object + */ + public abstract bind(rule: IRule): RuleTargetInputProperties; +} /** * Customize the CloudWatch LogGroup Event Target @@ -16,14 +66,25 @@ export interface LogGroupProps extends TargetBaseProps { * This will be the event logged into the CloudWatch LogGroup * * @default - the entire EventBridge event + * @deprecated use logEvent instead */ readonly event?: events.RuleTargetInput; + + /** + * The event to send to the CloudWatch LogGroup + * + * This will be the event logged into the CloudWatch LogGroup + * + * @default - the entire EventBridge event + */ + readonly logEvent?: LogGroupTargetInput; } /** * Use an AWS CloudWatch LogGroup as an event rule target. */ export class CloudWatchLogGroup implements events.IRuleTarget { + private target?: RuleTargetInputProperties; constructor(private readonly logGroup: logs.ILogGroup, private readonly props: LogGroupProps = {}) {} /** @@ -35,6 +96,17 @@ export class CloudWatchLogGroup implements events.IRuleTarget { const logGroupStack = cdk.Stack.of(this.logGroup); + if (this.props.event && this.props.logEvent) { + throw new Error('Only one of "event" or "logEvent" can be specified'); + } + + this.target = this.props.event?.bind(_rule); + if (this.target?.inputPath || this.target?.input) { + throw new Error('CloudWatchLogGroup targets does not support input or inputPath'); + } + + _rule.node.addValidation({ validate: () => this.validateInputTemplate() }); + if (!this.logGroup.node.tryFindChild(resourcePolicyId)) { new LogGroupResourcePolicy(logGroupStack, resourcePolicyId, { policyStatements: [new iam.PolicyStatement({ @@ -54,8 +126,40 @@ export class CloudWatchLogGroup implements events.IRuleTarget { arnFormat: ArnFormat.COLON_RESOURCE_NAME, resourceName: this.logGroup.logGroupName, }), - input: this.props.event, + input: this.props.event ?? this.props.logEvent, targetResource: this.logGroup, }; } + + /** + * Validate that the target event input template has the correct format. + * The CloudWatchLogs target only supports a template with the format of: + * {"timestamp":