From 5c761ddd40ff363bef8315fb3012d310db0c79d0 Mon Sep 17 00:00:00 2001 From: Connor Catlett Date: Wed, 18 Jun 2025 18:00:24 +0000 Subject: [PATCH] Migrate EBS CSI policy to AmazonEBSCSIDriverPolicy managed policy Signed-off-by: Connor Catlett --- pkg/actions/addon/create_test.go | 2 +- pkg/cfn/builder/iam.go | 1 + pkg/cfn/builder/iam_helper.go | 12 +-- pkg/cfn/builder/iam_test.go | 152 ++---------------------------- pkg/cfn/builder/nodegroup_test.go | 8 +- pkg/cfn/builder/statement.go | 136 -------------------------- 6 files changed, 17 insertions(+), 294 deletions(-) diff --git a/pkg/actions/addon/create_test.go b/pkg/actions/addon/create_test.go index d4089810cf..1289af0adf 100644 --- a/pkg/actions/addon/create_test.go +++ b/pkg/actions/addon/create_test.go @@ -979,7 +979,7 @@ var _ = Describe("Create", func() { Expect(rsr).To(BeAssignableToTypeOf(&builder.IAMRoleResourceSet{})) output, err := rsr.(*builder.IAMRoleResourceSet).RenderJSON() Expect(err).NotTo(HaveOccurred()) - Expect(string(output)).To(ContainSubstring("PolicyEBSCSIController")) + Expect(string(output)).To(ContainSubstring("service-role/AmazonEBSCSIDriverPolicy")) rsr.(*builder.IAMRoleResourceSet).OutputRole = "arn:aws:iam::111122223333:role/role-name-1" return nil } diff --git a/pkg/cfn/builder/iam.go b/pkg/cfn/builder/iam.go index 2af2858f73..589e56ad10 100644 --- a/pkg/cfn/builder/iam.go +++ b/pkg/cfn/builder/iam.go @@ -30,6 +30,7 @@ const ( iamPolicyAmazonEC2ContainerRegistryPullOnly = "AmazonEC2ContainerRegistryPullOnly" iamPolicyCloudWatchAgentServerPolicy = "CloudWatchAgentServerPolicy" iamPolicyAmazonSSMManagedInstanceCore = "AmazonSSMManagedInstanceCore" + iamPolicyAmazonEBSCSIDriverPolicy = "service-role/AmazonEBSCSIDriverPolicy" iamPolicyAmazonEKSFargatePodExecutionRolePolicy = "AmazonEKSFargatePodExecutionRolePolicy" ) diff --git a/pkg/cfn/builder/iam_helper.go b/pkg/cfn/builder/iam_helper.go index a3f88b522e..9c9576d737 100644 --- a/pkg/cfn/builder/iam_helper.go +++ b/pkg/cfn/builder/iam_helper.go @@ -65,8 +65,8 @@ func createWellKnownPolicies(wellKnownPolicies api.WellKnownPolicies) ([]managed ) } if wellKnownPolicies.EBSCSIController { - customPolicies = append(customPolicies, - customPolicyForRole{Name: "PolicyEBSCSIController", Statements: ebsStatements()}, + managedPolicies = append(managedPolicies, + managedPolicyForRole{name: iamPolicyAmazonEBSCSIDriverPolicy}, ) } if wellKnownPolicies.EFSCSIController { @@ -125,10 +125,6 @@ func createRole(cfnTemplate cfnTemplate, clusterIAMConfig *api.ClusterIAM, iamCo cfnTemplate.attachAllowPolicy("PolicyAppMeshPreview", refIR, appMeshStatements("appmesh-preview:*")) } - if api.IsEnabled(iamConfig.WithAddonPolicies.EBS) { - cfnTemplate.attachAllowPolicy("PolicyEBS", refIR, ebsStatements()) - } - if api.IsEnabled(iamConfig.WithAddonPolicies.FSX) { cfnTemplate.attachAllowPolicy("PolicyFSX", refIR, fsxStatements()) cfnTemplate.attachAllowPolicy("PolicyServiceLinkRole", refIR, serviceLinkRoleStatements()) @@ -178,6 +174,10 @@ func makeManagedPolicies(iamCluster *api.ClusterIAM, iamConfig *api.NodeGroupIAM managedPolicyNames.Insert(iamPolicyCloudWatchAgentServerPolicy) } + if api.IsEnabled(iamConfig.WithAddonPolicies.EBS) { + managedPolicyNames.Insert(iamPolicyAmazonEBSCSIDriverPolicy) + } + for _, policyARN := range iamConfig.AttachPolicyARNs { parsedARN, err := arn.Parse(policyARN) if err != nil { diff --git a/pkg/cfn/builder/iam_test.go b/pkg/cfn/builder/iam_test.go index 63c337ad32..234ccca257 100644 --- a/pkg/cfn/builder/iam_test.go +++ b/pkg/cfn/builder/iam_test.go @@ -283,20 +283,22 @@ var _ = Describe("template builder for IAM", func() { Expect(t.Description).To(Equal("IAM role for serviceaccount \"default/sa-1\" [created and managed by eksctl]")) - Expect(t.Resources).To(HaveLen(10)) + Expect(t.Resources).To(HaveLen(9)) Expect(t.Outputs).To(HaveLen(1)) Expect(t).To(HaveResource(outputs.IAMServiceAccountRoleName, "AWS::IAM::Role")) Expect(t).To(HaveResourceWithPropertyValue(outputs.IAMServiceAccountRoleName, "AssumeRolePolicyDocument", expectedServiceAccountAssumeRolePolicyDocument)) Expect(t).To(HaveResourceWithPropertyValue(outputs.IAMServiceAccountRoleName, "ManagedPolicyArns", `[ - { + { "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/AmazonEC2ContainerRegistryPowerUser" - } + }, + { + "Fn::Sub": "arn:${AWS::Partition}:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy" + } ]`)) Expect(t).To(HaveOutputWithValue(outputs.IAMServiceAccountRoleName, `{ "Fn::GetAtt": "Role1.Arn" }`)) Expect(t).To(HaveResourceWithPropertyValue("PolicyAWSLoadBalancerController", "PolicyDocument", expectedAWSLoadBalancerControllerPolicyDocument)) - Expect(t).To(HaveResourceWithPropertyValue("PolicyEBSCSIController", "PolicyDocument", expectedEbsPolicyDocument)) }) It("can parse an iamserviceaccount addon template", func() { @@ -744,145 +746,3 @@ const expectedAWSLoadBalancerControllerPolicyDocument = `{ ], "Version": "2012-10-17" }` - -const expectedEbsPolicyDocument = `{ - "Statement": [ - { - "Action": [ - "ec2:CreateSnapshot", - "ec2:AttachVolume", - "ec2:DetachVolume", - "ec2:ModifyVolume", - "ec2:DescribeAvailabilityZones", - "ec2:DescribeInstances", - "ec2:DescribeSnapshots", - "ec2:DescribeTags", - "ec2:DescribeVolumes", - "ec2:DescribeVolumesModifications" - ], - "Effect": "Allow", - "Resource": "*" - }, - { - "Action": [ - "ec2:CreateTags" - ], - "Condition": { - "StringEquals": { - "ec2:CreateAction": [ - "CreateVolume", - "CreateSnapshot" - ] - } - }, - "Effect": "Allow", - "Resource": [ - { - "Fn::Sub": "arn:${AWS::Partition}:ec2:*:*:volume/*" - }, - { - "Fn::Sub": "arn:${AWS::Partition}:ec2:*:*:snapshot/*" - } - ] - }, - { - "Action": [ - "ec2:DeleteTags" - ], - "Effect": "Allow", - "Resource": [ - { - "Fn::Sub": "arn:${AWS::Partition}:ec2:*:*:volume/*" - }, - { - "Fn::Sub": "arn:${AWS::Partition}:ec2:*:*:snapshot/*" - } - ] - }, - { - "Action": [ - "ec2:CreateVolume" - ], - "Condition": { - "StringLike": { - "aws:RequestTag/ebs.csi.aws.com/cluster": "true" - } - }, - "Effect": "Allow", - "Resource": "*" - }, - { - "Action": [ - "ec2:CreateVolume" - ], - "Condition": { - "StringLike": { - "aws:RequestTag/CSIVolumeName": "*" - } - }, - "Effect": "Allow", - "Resource": "*" - }, - { - "Action": [ - "ec2:DeleteVolume" - ], - "Condition": { - "StringLike": { - "ec2:ResourceTag/ebs.csi.aws.com/cluster": "true" - } - }, - "Effect": "Allow", - "Resource": "*" - }, - { - "Action": [ - "ec2:DeleteVolume" - ], - "Condition": { - "StringLike": { - "ec2:ResourceTag/CSIVolumeName": "*" - } - }, - "Effect": "Allow", - "Resource": "*" - }, - { - "Action": [ - "ec2:DeleteVolume" - ], - "Condition": { - "StringLike": { - "ec2:ResourceTag/kubernetes.io/created-for/pvc/name": "*" - } - }, - "Effect": "Allow", - "Resource": "*" - }, - { - "Action": [ - "ec2:DeleteSnapshot" - ], - "Condition": { - "StringLike": { - "ec2:ResourceTag/CSIVolumeSnapshotName": "*" - } - }, - "Effect": "Allow", - "Resource": "*" - }, - { - "Action": [ - "ec2:DeleteSnapshot" - ], - "Condition": { - "StringLike": { - "ec2:ResourceTag/ebs.csi.aws.com/cluster": "true" - } - }, - "Effect": "Allow", - "Resource": "*" - } - ], - "Version": "2012-10-17" -}` diff --git a/pkg/cfn/builder/nodegroup_test.go b/pkg/cfn/builder/nodegroup_test.go index adf8c6fd49..e85a058b29 100644 --- a/pkg/cfn/builder/nodegroup_test.go +++ b/pkg/cfn/builder/nodegroup_test.go @@ -467,11 +467,9 @@ var _ = Describe("Unmanaged NodeGroup Template Builder", func() { ng.IAM.WithAddonPolicies.EBS = aws.Bool(true) }) - It("adds PolicyEBS to the role", func() { - Expect(ngTemplate.Resources).To(HaveKey("PolicyEBS")) - - Expect(ngTemplate.Resources["PolicyEBS"].Properties.Roles).To(HaveLen(1)) - Expect(isRefTo(ngTemplate.Resources["PolicyEBS"].Properties.Roles[0], "NodeInstanceRole")).To(BeTrue()) + It("adds the AmazonEBSCSIDriverPolicy managed policy to the role", func() { + Expect(ngTemplate.Resources["NodeInstanceRole"].Properties.ManagedPolicyArns).To(HaveLen(5)) + Expect(ngTemplate.Resources["NodeInstanceRole"].Properties.ManagedPolicyArns).To(ContainElement(makePolicyARNRef("service-role/AmazonEBSCSIDriverPolicy"))) }) }) diff --git a/pkg/cfn/builder/statement.go b/pkg/cfn/builder/statement.go index 045f5bc45f..52d2937379 100644 --- a/pkg/cfn/builder/statement.go +++ b/pkg/cfn/builder/statement.go @@ -368,142 +368,6 @@ func appMeshStatements(appendAction string) []cft.MapOfInterfaces { } } -func ebsStatements() []cft.MapOfInterfaces { - return []cft.MapOfInterfaces{ - { - "Effect": "Allow", - "Action": []string{ - "ec2:CreateSnapshot", - "ec2:AttachVolume", - "ec2:DetachVolume", - "ec2:ModifyVolume", - "ec2:DescribeAvailabilityZones", - "ec2:DescribeInstances", - "ec2:DescribeSnapshots", - "ec2:DescribeTags", - "ec2:DescribeVolumes", - "ec2:DescribeVolumesModifications", - }, - "Resource": "*", - }, - { - "Effect": "Allow", - "Action": []string{ - "ec2:CreateTags", - }, - "Resource": []*gfnt.Value{ - addARNPartitionPrefix("ec2:*:*:volume/*"), - addARNPartitionPrefix("ec2:*:*:snapshot/*"), - }, - "Condition": cft.MapOfInterfaces{ - "StringEquals": cft.MapOfInterfaces{ - "ec2:CreateAction": []string{ - "CreateVolume", - "CreateSnapshot", - }, - }, - }, - }, - { - "Effect": "Allow", - "Action": []string{ - "ec2:DeleteTags", - }, - "Resource": []*gfnt.Value{ - addARNPartitionPrefix("ec2:*:*:volume/*"), - addARNPartitionPrefix("ec2:*:*:snapshot/*"), - }, - }, - { - "Effect": "Allow", - - "Action": []string{ - - "ec2:CreateVolume", - }, - "Resource": "*", - "Condition": cft.MapOfInterfaces{ - "StringLike": cft.MapOfInterfaces{ - "aws:RequestTag/ebs.csi.aws.com/cluster": "true", - }, - }, - }, - { - "Effect": "Allow", - "Action": []string{ - "ec2:CreateVolume", - }, - "Resource": "*", - "Condition": cft.MapOfInterfaces{ - "StringLike": cft.MapOfInterfaces{ - "aws:RequestTag/CSIVolumeName": "*", - }, - }, - }, - { - "Effect": "Allow", - "Action": []string{ - "ec2:DeleteVolume", - }, - "Resource": "*", - "Condition": cft.MapOfInterfaces{ - "StringLike": cft.MapOfInterfaces{ - "ec2:ResourceTag/ebs.csi.aws.com/cluster": "true", - }, - }, - }, - { - "Effect": "Allow", - - "Action": []string{ - "ec2:DeleteVolume", - }, - "Resource": "*", - "Condition": cft.MapOfInterfaces{ - "StringLike": cft.MapOfInterfaces{ - "ec2:ResourceTag/CSIVolumeName": "*", - }, - }, - }, - { - "Effect": "Allow", - "Action": []string{ - "ec2:DeleteVolume", - }, - "Resource": "*", - "Condition": cft.MapOfInterfaces{ - "StringLike": cft.MapOfInterfaces{ - "ec2:ResourceTag/kubernetes.io/created-for/pvc/name": "*", - }, - }, - }, - { - "Effect": "Allow", - "Action": []string{ - "ec2:DeleteSnapshot", - }, - "Resource": "*", - "Condition": cft.MapOfInterfaces{ - "StringLike": cft.MapOfInterfaces{ - "ec2:ResourceTag/CSIVolumeSnapshotName": "*", - }, - }, - }, - { - "Effect": "Allow", - "Action": []string{ - "ec2:DeleteSnapshot", - }, - "Resource": "*", - "Condition": cft.MapOfInterfaces{ - "StringLike": cft.MapOfInterfaces{ - "ec2:ResourceTag/ebs.csi.aws.com/cluster": "true", - }, - }, - }, - } -} - func serviceLinkRoleStatements() []cft.MapOfInterfaces { return []cft.MapOfInterfaces{ {