From a65075fe7036d898fe61b4adc3d5f2ca28466b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nick=20J=C3=BCttner?= Date: Wed, 8 Nov 2023 15:09:30 +0100 Subject: [PATCH] add IAM role for cluster-autoscaler --- CHANGELOG.md | 2 +- .../awsmachinetemplate_controller_test.go | 1 + controllers/common_test.go | 56 +++++++++++++++++++ pkg/iam/cluster_autoscaler_template.go | 31 ++++++++++ pkg/iam/iam.go | 29 ++++++---- pkg/iam/nodes_template.go | 1 - pkg/iam/template.go | 4 ++ 7 files changed, 112 insertions(+), 12 deletions(-) create mode 100644 pkg/iam/cluster_autoscaler_template.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 71d2366f..6183bf9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Add addition IAM permission for cluster-autoscaler to describe scaling activities. +- Add new IAM role for cluster-autoscaler. ## [0.12.0] - 2023-11-02 diff --git a/controllers/awsmachinetemplate_controller_test.go b/controllers/awsmachinetemplate_controller_test.go index ffe9bad2..dba7c878 100644 --- a/controllers/awsmachinetemplate_controller_test.go +++ b/controllers/awsmachinetemplate_controller_test.go @@ -332,6 +332,7 @@ var _ = Describe("AWSMachineTemplateReconciler", func() { certManagerRoleInfo, ALBControllerRoleInfo, ebsCsiDriverRoleInfo, + clusterAutoscalerRoleInfo, } expectedIAMTags := []*iam.Tag{ diff --git a/controllers/common_test.go b/controllers/common_test.go index 7e499f82..015f106a 100644 --- a/controllers/common_test.go +++ b/controllers/common_test.go @@ -534,3 +534,59 @@ var ebsCsiDriverRoleInfo = RoleInfo{ ReturnRoleArn: "arn:aws:iam::55554444:role/test-cluster-ebs-csi-driver", } + +var clusterAutoscalerRoleInfo = RoleInfo{ + ExpectedName: "test-cluster-cluster-autoscaler-role", + + ExpectedAssumeRolePolicyDocument: `{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Federated": "arn:aws:iam::012345678901:oidc-provider/irsa.test.gaws.gigantic.io" + }, + "Action": "sts:AssumeRoleWithWebIdentity", + "Condition": { + "StringEquals": { + "irsa.test.gaws.gigantic.io:sub": "system:serviceaccount:kube-system:cluster-autoscaler" + } + } + } + ] +} +`, + + ExpectedPolicyName: "control-plane-test-cluster-policy", + ExpectedPolicyDocument: `{ + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "autoscaling:DescribeAutoScalingGroups", + "autoscaling:DescribeAutoScalingInstances", + "autoscaling:DescribeLaunchConfigurations", + "autoscaling:DescribeScalingActivities", + "autoscaling:DescribeTags", + "ec2:DescribeInstanceTypes", + "ec2:DescribeLaunchTemplateVersions", + ], + "Resource": "*", + "Effect": "Allow" + }, + { + "Action": [ + "autoscaling:SetDesiredCapacity", + "autoscaling:TerminateInstanceInAutoScalingGroup", + "ec2:DescribeImages", + "ec2:GetInstanceTypesFromInstanceRequirements", + "eks:DescribeNodegroup" + ], + "Resource": "*", + "Effect": "Allow" + } + ] +}`, + + ReturnRoleArn: "arn:aws:iam::55554444:role/test-cluster-cluster-autoscaler", +} diff --git a/pkg/iam/cluster_autoscaler_template.go b/pkg/iam/cluster_autoscaler_template.go new file mode 100644 index 00000000..a5535e8e --- /dev/null +++ b/pkg/iam/cluster_autoscaler_template.go @@ -0,0 +1,31 @@ +package iam + +const clusterAutoscalerPolicyTemplate = `{ + "Version": "2012-10-17", + "Statement": [ + { + "Action": [ + "autoscaling:DescribeAutoScalingGroups", + "autoscaling:DescribeAutoScalingInstances", + "autoscaling:DescribeLaunchConfigurations", + "autoscaling:DescribeScalingActivities", + "autoscaling:DescribeTags", + "ec2:DescribeInstanceTypes", + "ec2:DescribeLaunchTemplateVersions", + ], + "Resource": "*", + "Effect": "Allow" + }, + { + "Action": [ + "autoscaling:SetDesiredCapacity", + "autoscaling:TerminateInstanceInAutoScalingGroup", + "ec2:DescribeImages", + "ec2:GetInstanceTypesFromInstanceRequirements", + "eks:DescribeNodegroup" + ], + "Resource": "*", + "Effect": "Allow" + } + ] +}` diff --git a/pkg/iam/iam.go b/pkg/iam/iam.go index 11426d1b..d7660b73 100644 --- a/pkg/iam/iam.go +++ b/pkg/iam/iam.go @@ -16,15 +16,16 @@ import ( ) const ( - BastionRole = "bastion" - ControlPlaneRole = "control-plane" // also used as part of finalizer name - NodesRole = "nodes" // also used as part of finalizer name - Route53Role = "route53-role" - KIAMRole = "kiam-role" - IRSARole = "irsa-role" - CertManagerRole = "cert-manager-role" - ALBConrollerRole = "ALBController-Role" - EBSCSIDriverRole = "ebs-csi-driver-role" + BastionRole = "bastion" + ControlPlaneRole = "control-plane" // also used as part of finalizer name + NodesRole = "nodes" // also used as part of finalizer name + Route53Role = "route53-role" + KIAMRole = "kiam-role" + IRSARole = "irsa-role" + CertManagerRole = "cert-manager-role" + ALBConrollerRole = "ALBController-Role" + EBSCSIDriverRole = "ebs-csi-driver-role" + ClusterAutoscalerRole = "cluster-autoscaler-role" IAMControllerOwnedTag = "capi-iam-controller/owned" ClusterIDTag = "sigs.k8s.io/cluster-api-provider-aws/cluster/%s" @@ -157,7 +158,7 @@ func (s *IAMService) ReconcileKiamRole() error { func (s *IAMService) ReconcileRolesForIRSA(awsAccountID string, cloudFrontDomain string) error { s.log.Info("reconciling IAM roles for IRSA") - for _, roleTypeToReconcile := range []string{Route53Role, CertManagerRole, ALBConrollerRole, EBSCSIDriverRole} { + for _, roleTypeToReconcile := range []string{Route53Role, CertManagerRole, ALBConrollerRole, EBSCSIDriverRole, ClusterAutoscalerRole} { var params Route53RoleParams params, err := s.generateRoute53RoleParams(roleTypeToReconcile, awsAccountID, cloudFrontDomain) if err != nil { @@ -457,6 +458,12 @@ func (s *IAMService) DeleteRolesForIRSA() error { return err } + // delete cluster-autoscaler role + err = s.deleteRole(roleName(ClusterAutoscalerRole, s.clusterName)) + if err != nil { + return err + } + s.log.Info("finished deleting IAM roles for IRSA") return nil } @@ -670,6 +677,8 @@ func getServiceAccount(role string) (string, error) { return "aws-load-balancer-controller", nil } else if role == EBSCSIDriverRole { return "ebs-csi-controller-sa", nil + } else if role == ClusterAutoscalerRole { + return "cluster-autoscaler", nil } return "", fmt.Errorf("cannot get service account for specified role - %s", role) diff --git a/pkg/iam/nodes_template.go b/pkg/iam/nodes_template.go index abe35438..1d59494e 100644 --- a/pkg/iam/nodes_template.go +++ b/pkg/iam/nodes_template.go @@ -18,7 +18,6 @@ const nodesTemplate = `{ "autoscaling:DescribeAutoScalingGroups", "autoscaling:DescribeAutoScalingInstances", "autoscaling:DescribeTags", - "autoscaling:DescribeLaunchConfigurations", "autoscaling:DescribeScalingActivities", "ec2:DescribeLaunchTemplateVersions" ], diff --git a/pkg/iam/template.go b/pkg/iam/template.go index b568cfc3..cf2458a7 100644 --- a/pkg/iam/template.go +++ b/pkg/iam/template.go @@ -55,6 +55,8 @@ func getInlinePolicyTemplate(roleType string) string { return ALBControllerPolicyTemplate case EBSCSIDriverRole: return EBSCSIDriverPolicyTemplate + case ClusterAutoscalerRole: + return clusterAutoscalerPolicyTemplate default: return "" } @@ -80,6 +82,8 @@ func getTrustPolicyTemplate(roleType string) string { return trustIdentityPolicyKIAMAndIRSA case EBSCSIDriverRole: return trustIdentityPolicyKIAMAndIRSA + case ClusterAutoscalerRole: + return trustIdentityPolicyKIAMAndIRSA default: return ""