From 07973eb19a762334d9cab8cbb45d0313b937149c Mon Sep 17 00:00:00 2001 From: Jose Armesto Date: Mon, 27 Oct 2025 17:28:54 +0100 Subject: [PATCH 1/8] Add Crossplane IAM roles, policies, and instance profiles for worker nodes --- CHANGELOG.md | 4 + helm/cluster-aws/README.md | 1 - helm/cluster-aws/templates/_aws_cluster.tpl | 4 +- helm/cluster-aws/templates/_control_plane.tpl | 2 +- .../templates/_karpenter_machine_pools.tpl | 4 +- helm/cluster-aws/templates/_machine_pools.tpl | 5 +- helm/cluster-aws/templates/required.yaml | 1 - .../workers-crossplane-iam-role.yaml | 119 ++++++++++++++++++ helm/cluster-aws/values.schema.json | 6 - helm/cluster-aws/values.yaml | 1 - 10 files changed, 127 insertions(+), 20 deletions(-) create mode 100644 helm/cluster-aws/templates/workers-crossplane-iam-role.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index e3bf545bb..622b713f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add Crossplane IAM Roles, policies and instance profiles for the worker nodes. Instead of having an IAM Role per node pool, now we'll use the same for all node pools. *This change will roll the worker nodes*. + ### Changed - Tidy up dependencies on `azs-getter`. diff --git a/helm/cluster-aws/README.md b/helm/cluster-aws/README.md index 7471afd41..2d5f5b439 100644 --- a/helm/cluster-aws/README.md +++ b/helm/cluster-aws/README.md @@ -32,7 +32,6 @@ Properties within the `.global.providerSpecific` object | `global.providerSpecific.irsaCrossplane` | **Use Crossplane to provision IRSA infrastructure** - Defaults to true. Crossplane will adopt all the resources created by IRSA Operator. If set to false, the IRSA Operator will take over the infrastructure again.|**Type:** `[boolean]`
**Default:** `true`| | `global.providerSpecific.nodePoolAmi` | **Amazon machine image (AMI) for node pools** - If specified, this image will be used to provision EC2 instances for node pools.|**Type:** `[string]`
| | `global.providerSpecific.nodeTerminationHandlerEnabled` | **Use the AWS Node Termination Handler app** - Defaults to true. Whether or not to enable the Auto Scaling Groups lifecycle hooks and use the node-termination-handler app (NTH) to manage the termination of EC2 instances.|**Type:** `[boolean]`
**Default:** `true`| -| `global.providerSpecific.reducedInstanceProfileIamPermissionsForWorkers` | **Use reduced IAM permissions on worker nodes instance profile** - Defaults to true. If something breaks, this can temporarily be disabled in order to bring certain IAM permissions (e.g. EC2) back for the worker nodes' IAM instance profile. Applications must use [IRSA](https://docs.giantswarm.io/tutorials/access-management/iam-roles-for-service-accounts/) to authenticate with the AWS API instead of falling back to the instance profile.|**Type:** `[boolean]`
**Default:** `true`| | `global.providerSpecific.region` | **Region**|**Type:** `[string]`
| ### Apps diff --git a/helm/cluster-aws/templates/_aws_cluster.tpl b/helm/cluster-aws/templates/_aws_cluster.tpl index ae16f7f48..1a888c890 100644 --- a/helm/cluster-aws/templates/_aws_cluster.tpl +++ b/helm/cluster-aws/templates/_aws_cluster.tpl @@ -258,8 +258,6 @@ spec: controlPlaneIAMInstanceProfile: control-plane-{{ include "resource.default.name" $ }} name: {{ include "aws-region" . }}-capa-{{ include "resource.default.name" $ }} nodesIAMInstanceProfiles: - {{- range $name, $value := .Values.global.nodePools | default .Values.cluster.providerIntegration.workers.defaultNodePools }} - - nodes-{{ $name }}-{{ include "resource.default.name" $ }} - {{- end }} + - {{ include "resource.default.name" $ }}-worker region: {{ include "aws-region" . }} {{ end }} diff --git a/helm/cluster-aws/templates/_control_plane.tpl b/helm/cluster-aws/templates/_control_plane.tpl index 5084a5a40..c91f4b9e7 100644 --- a/helm/cluster-aws/templates/_control_plane.tpl +++ b/helm/cluster-aws/templates/_control_plane.tpl @@ -31,7 +31,7 @@ nonRootVolumes: rootVolume: size: {{ .Values.global.controlPlane.rootVolumeSizeGB }} type: gp3 -iamInstanceProfile: control-plane-{{ include "resource.default.name" $ }} +iamInstanceProfile: {{ include "resource.default.name" $ }}-control-plane {{- if .Values.global.controlPlane.additionalSecurityGroups }} additionalSecurityGroups: {{- toYaml .Values.global.controlPlane.additionalSecurityGroups | nindent 2 }} diff --git a/helm/cluster-aws/templates/_karpenter_machine_pools.tpl b/helm/cluster-aws/templates/_karpenter_machine_pools.tpl index 02a3d7206..636695b13 100644 --- a/helm/cluster-aws/templates/_karpenter_machine_pools.tpl +++ b/helm/cluster-aws/templates/_karpenter_machine_pools.tpl @@ -7,9 +7,6 @@ metadata: labels: giantswarm.io/machine-pool: {{ include "resource.default.name" $ }}-{{ $name }} {{- include "labels.common" $ | nindent 4 }} - {{- if $.Values.global.providerSpecific.reducedInstanceProfileIamPermissionsForWorkers }} - alpha.aws.giantswarm.io/reduced-instance-permissions-workers: "true" - {{- end }} app.kubernetes.io/version: {{ $.Chart.Version | quote }} name: {{ include "resource.default.name" $ }}-{{ $name }} namespace: {{ $.Release.Namespace }} @@ -38,6 +35,7 @@ spec: volumeType: gp3 deleteOnTermination: true instanceProfile: nodes-{{ $name }}-{{ include "resource.default.name" $ }} + instanceProfile: {{ include "resource.default.name" $ }}-worker metadataOptions: {{- if eq $.Values.global.connectivity.cilium.ipamMode "eni" }} httpPutResponseHopLimit: 2 diff --git a/helm/cluster-aws/templates/_machine_pools.tpl b/helm/cluster-aws/templates/_machine_pools.tpl index e71b5ef1a..96a21447a 100644 --- a/helm/cluster-aws/templates/_machine_pools.tpl +++ b/helm/cluster-aws/templates/_machine_pools.tpl @@ -7,9 +7,6 @@ metadata: labels: giantswarm.io/machine-pool: {{ include "resource.default.name" $ }}-{{ $name }} {{- include "labels.common" $ | nindent 4 }} - {{- if $.Values.global.providerSpecific.reducedInstanceProfileIamPermissionsForWorkers }} - alpha.aws.giantswarm.io/reduced-instance-permissions-workers: "true" - {{- end }} {{- if eq $.Values.global.connectivity.cilium.ipamMode "eni" }} alpha.aws.giantswarm.io/ipam-mode: "eni" {{- end }} @@ -50,7 +47,7 @@ spec: {{- else }} {{- include "imageLookupParameters" $ | nindent 4 }} {{- end }} - iamInstanceProfile: nodes-{{ $name }}-{{ include "resource.default.name" $ }} + iamInstanceProfile: {{ include "resource.default.name" $ }}-worker instanceType: {{ $value.instanceType | default "r6i.xlarge" }} rootVolume: size: {{ $value.rootVolumeSizeGB | default 8 }} diff --git a/helm/cluster-aws/templates/required.yaml b/helm/cluster-aws/templates/required.yaml index 53e451c4a..571c640cb 100644 --- a/helm/cluster-aws/templates/required.yaml +++ b/helm/cluster-aws/templates/required.yaml @@ -3,4 +3,3 @@ {{- $_ := required "global.connectivity.cilium.ipamMode is required" .Values.global.connectivity.cilium.ipamMode }} {{- $_ := required "global.connectivity.network.pods.cidrBlocks is required" .Values.global.connectivity.network.pods.cidrBlocks }} {{- $_ := required "You must provide an existing organization name in .global.metadata.organization" .Values.global.metadata.organization }} -{{- $_ := required "global.providerSpecific.reducedInstanceProfileIamPermissionsForWorkers is required" $.Values.global.providerSpecific.reducedInstanceProfileIamPermissionsForWorkers }} diff --git a/helm/cluster-aws/templates/workers-crossplane-iam-role.yaml b/helm/cluster-aws/templates/workers-crossplane-iam-role.yaml new file mode 100644 index 000000000..a16c544dd --- /dev/null +++ b/helm/cluster-aws/templates/workers-crossplane-iam-role.yaml @@ -0,0 +1,119 @@ +--- +apiVersion: iam.aws.upbound.io/v1beta1 +kind: Role +metadata: + name: {{ include "resource.default.name" $ }}-worker + labels: + {{- include "labels.common" $ | nindent 4 }} + app.kubernetes.io/version: {{ .Chart.Version | quote }} +spec: + forProvider: + assumeRolePolicy: | + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com" + }, + "Action": "sts:AssumeRole" + } + ] + } + tags: + managed-by: "cluster-aws" + giantswarm.io/cluster: {{ include "resource.default.name" $ }} + giantswarm.io/installation: {{ .Values.global.managementCluster }} + {{- if .Values.global.providerSpecific.additionalResourceTags -}}{{- toYaml .Values.global.providerSpecific.additionalResourceTags | nindent 4 }}{{- end}} + providerConfigRef: + name: {{ include "resource.default.name" $ }} +--- +apiVersion: iam.aws.upbound.io/v1beta1 +kind: RolePolicy +metadata: + name: {{ include "resource.default.name" $ }}-worker + labels: + {{- include "labels.common" $ | nindent 4 }} + app.kubernetes.io/version: {{ .Chart.Version | quote }} +spec: + forProvider: + roleRef: + name: {{ include "resource.default.name" $ }}-worker + policy: | + { + "Version": "2012-10-17", + "Statement": [ + {{- if eq .Values.global.connectivity.cilium.ipamMode "eni" }} + { + "Action": [ + "ec2:AssignPrivateIpAddresses", + "ec2:AttachNetworkInterface", + "ec2:CreateNetworkInterface", + "ec2:CreateTags", + "ec2:DeleteNetworkInterface", + "ec2:DescribeInstances", + "ec2:DescribeInstanceTypes", + "ec2:DescribeNetworkInterfaces", + "ec2:DescribeRouteTables", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSubnets", + "ec2:DescribeTags", + "ec2:DescribeVpcs", + "ec2:ModifyNetworkInterfaceAttribute", + "ec2:UnassignPrivateIpAddresses" + ], + "Resource": "*", + "Effect": "Allow" + }, + {{- end }} + { + "Action": [ + "ecr:BatchCheckLayerAvailability", + "ecr:BatchGetImage", + "ecr:DescribeRepositories", + "ecr:GetAuthorizationToken", + "ecr:GetDownloadUrlForLayer", + "ecr:GetRepositoryPolicy", + "ecr:ListImages" + ], + "Resource": "*", + "Effect": "Allow" + } + ] + } + providerConfigRef: + name: {{ include "resource.default.name" $ }} +--- +apiVersion: iam.aws.upbound.io/v1beta1 +kind: InstanceProfile +metadata: + name: {{ include "resource.default.name" $ }}-worker + labels: + {{- include "labels.common" $ | nindent 4 }} + app.kubernetes.io/version: {{ .Chart.Version | quote }} +spec: + forProvider: + tags: + managed-by: "cluster-aws" + giantswarm.io/cluster: {{ include "resource.default.name" $ }} + giantswarm.io/installation: {{ .Values.global.managementCluster }} + {{- if .Values.global.providerSpecific.additionalResourceTags -}}{{- toYaml .Values.global.providerSpecific.additionalResourceTags | nindent 4 }}{{- end}} + providerConfigRef: + name: {{ include "resource.default.name" $ }} +--- +apiVersion: iam.aws.upbound.io/v1beta1 +kind: RolePolicyAttachment +metadata: + name: {{ include "resource.default.name" $ }}-worker + labels: + {{- include "labels.common" $ | nindent 4 }} + app.kubernetes.io/version: {{ .Chart.Version | quote }} +spec: + forProvider: + roleRef: + name: {{ include "resource.default.name" $ }}-worker + instanceProfileRef: + name: {{ include "resource.default.name" $ }}-worker + providerConfigRef: + name: {{ include "resource.default.name" $ }} diff --git a/helm/cluster-aws/values.schema.json b/helm/cluster-aws/values.schema.json index 330c2abc5..1c35468e1 100644 --- a/helm/cluster-aws/values.schema.json +++ b/helm/cluster-aws/values.schema.json @@ -2433,12 +2433,6 @@ "description": "Defaults to true. Whether or not to enable the Auto Scaling Groups lifecycle hooks and use the node-termination-handler app (NTH) to manage the termination of EC2 instances.", "default": true }, - "reducedInstanceProfileIamPermissionsForWorkers": { - "type": "boolean", - "title": "Use reduced IAM permissions on worker nodes instance profile", - "description": "Defaults to true. If something breaks, this can temporarily be disabled in order to bring certain IAM permissions (e.g. EC2) back for the worker nodes' IAM instance profile. Applications must use [IRSA](https://docs.giantswarm.io/tutorials/access-management/iam-roles-for-service-accounts/) to authenticate with the AWS API instead of falling back to the instance profile.", - "default": true - }, "region": { "type": "string", "title": "Region" diff --git a/helm/cluster-aws/values.yaml b/helm/cluster-aws/values.yaml index 82857e2cf..e6492b49a 100644 --- a/helm/cluster-aws/values.yaml +++ b/helm/cluster-aws/values.yaml @@ -401,6 +401,5 @@ global: httpTokens: required irsaCrossplane: true nodeTerminationHandlerEnabled: true - reducedInstanceProfileIamPermissionsForWorkers: true release: {} internal: {} From dcaf0db7ee0e3993fd2a338fcf1284c30a2712be Mon Sep 17 00:00:00 2001 From: Jose Armesto Date: Tue, 28 Oct 2025 16:33:40 +0100 Subject: [PATCH 2/8] Add crossplane IAM Roles for control plane nodes --- .../crossplane-iam-role-control-plane.yaml | 186 ++++++++++++++++++ ...e.yaml => crossplane-iam-role-worker.yaml} | 2 +- 2 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 helm/cluster-aws/templates/crossplane-iam-role-control-plane.yaml rename helm/cluster-aws/templates/{workers-crossplane-iam-role.yaml => crossplane-iam-role-worker.yaml} (97%) diff --git a/helm/cluster-aws/templates/crossplane-iam-role-control-plane.yaml b/helm/cluster-aws/templates/crossplane-iam-role-control-plane.yaml new file mode 100644 index 000000000..1cc17cab6 --- /dev/null +++ b/helm/cluster-aws/templates/crossplane-iam-role-control-plane.yaml @@ -0,0 +1,186 @@ +--- +apiVersion: iam.aws.upbound.io/v1beta1 +kind: Role +metadata: + name: {{ include "resource.default.name" $ }}-control-plane + labels: + {{- include "labels.common" $ | nindent 4 }} + app.kubernetes.io/version: {{ .Chart.Version | quote }} +spec: + forProvider: + assumeRolePolicy: | + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": "ec2.amazonaws.com{{- if hasPrefix "cn-" .Values.awsRegion }}.cn{{- end }}" + }, + "Action": "sts:AssumeRole" + } + ] + } + tags: + managed-by: "cluster-aws" + giantswarm.io/cluster: {{ include "resource.default.name" $ }} + giantswarm.io/installation: {{ .Values.global.managementCluster }} + {{- if .Values.global.providerSpecific.additionalResourceTags -}}{{- toYaml .Values.global.providerSpecific.additionalResourceTags | nindent 4 }}{{- end}} + providerConfigRef: + name: {{ include "resource.default.name" $ }} +--- +apiVersion: iam.aws.upbound.io/v1beta1 +kind: RolePolicy +metadata: + name: {{ include "resource.default.name" $ }}-control-plane + labels: + cluster.x-k8s.io/cluster-name: {{ include "resource.default.name" $ }} +spec: + forProvider: + roleRef: + name: {{ include "resource.default.name" $ }}-control-plane + policy: | + { + "Version": "2012-10-17", + "Statement": [ + { + "Action": "elasticloadbalancing:*", + "Resource": "*", + "Effect": "Allow" + }, + { + "Action": [ + "autoscaling:DescribeAutoScalingGroups", + "autoscaling:DescribeAutoScalingInstances", + "autoscaling:DescribeTags", + "autoscaling:DescribeLaunchConfigurations", + "ec2:DescribeLaunchTemplateVersions" + ], + "Resource": "*", + "Effect": "Allow" + }, + { + "Action": [ + "ecr:GetAuthorizationToken", + "ecr:BatchCheckLayerAvailability", + "ecr:GetDownloadUrlForLayer", + "ecr:GetRepositoryPolicy", + "ecr:DescribeRepositories", + "ecr:ListImages", + "ecr:BatchGetImage" + ], + "Resource": "*", + "Effect": "Allow" + }, + { + "Action": [ + "ec2:AssignPrivateIpAddresses", + "ec2:AttachNetworkInterface", + "ec2:CreateNetworkInterface", + "ec2:DeleteNetworkInterface", + "ec2:DescribeInstances", + "ec2:DescribeInstanceTypes", + "ec2:DescribeTags", + "ec2:DescribeNetworkInterfaces", + "ec2:DetachNetworkInterface", + "ec2:ModifyNetworkInterfaceAttribute", + "ec2:UnassignPrivateIpAddresses" + ], + "Resource": "*", + "Effect": "Allow" + }, + { + "Action": [ + "autoscaling:DescribeAutoScalingGroups", + "autoscaling:DescribeLaunchConfigurations", + "autoscaling:DescribeTags", + "ec2:DescribeAvailabilityZones", + "ec2:DescribeInstances", + "ec2:DescribeImages", + "ec2:DescribeRegions", + "ec2:DescribeRouteTables", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSubnets", + "ec2:DescribeVolumes", + "ec2:CreateSecurityGroup", + "ec2:CreateTags", + "ec2:CreateVolume", + "ec2:ModifyInstanceAttribute", + "ec2:ModifyVolume", + "ec2:AttachVolume", + "ec2:DescribeVolumesModifications", + "ec2:AuthorizeSecurityGroupIngress", + "ec2:CreateRoute", + "ec2:DeleteRoute", + "ec2:DeleteSecurityGroup", + "ec2:DeleteVolume", + "ec2:DetachVolume", + "ec2:RevokeSecurityGroupIngress", + "ec2:DescribeVpcs", + "elasticloadbalancing:AddTags", + "elasticloadbalancing:AttachLoadBalancerToSubnets", + "elasticloadbalancing:ApplySecurityGroupsToLoadBalancer", + "elasticloadbalancing:CreateLoadBalancer", + "elasticloadbalancing:CreateLoadBalancerPolicy", + "elasticloadbalancing:CreateLoadBalancerListeners", + "elasticloadbalancing:ConfigureHealthCheck", + "elasticloadbalancing:DeleteLoadBalancer", + "elasticloadbalancing:DeleteLoadBalancerListeners", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeLoadBalancerAttributes", + "elasticloadbalancing:DetachLoadBalancerFromSubnets", + "elasticloadbalancing:DeregisterInstancesFromLoadBalancer", + "elasticloadbalancing:ModifyLoadBalancerAttributes", + "elasticloadbalancing:RegisterInstancesWithLoadBalancer", + "elasticloadbalancing:SetLoadBalancerPoliciesForBackendServer", + "elasticloadbalancing:AddTags", + "elasticloadbalancing:CreateListener", + "elasticloadbalancing:CreateTargetGroup", + "elasticloadbalancing:DeleteListener", + "elasticloadbalancing:DeleteTargetGroup", + "elasticloadbalancing:DescribeListeners", + "elasticloadbalancing:DescribeLoadBalancerPolicies", + "elasticloadbalancing:DescribeTargetGroups", + "elasticloadbalancing:DescribeTargetHealth", + "elasticloadbalancing:ModifyListener", + "elasticloadbalancing:ModifyTargetGroup", + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:SetLoadBalancerPoliciesOfListener", + "iam:CreateServiceLinkedRole", + "kms:DescribeKey" + ], + "Resource": [ + "*" + ], + "Effect": "Allow" + }, + { + "Action": [ + "secretsmanager:GetSecretValue", + "secretsmanager:DeleteSecret" + ], + "Resource": "arn:*:secretsmanager:*:*:secret:aws.cluster.x-k8s.io/*", + "Effect": "Allow" + } + ] + } + providerConfigRef: + name: {{ include "resource.default.name" $ }} +--- +apiVersion: iam.aws.upbound.io/v1beta1 +kind: InstanceProfile +metadata: + name: {{ include "resource.default.name" $ }}-control-plane + labels: + {{- include "labels.common" $ | nindent 4 }} + app.kubernetes.io/version: {{ .Chart.Version | quote }} +spec: + forProvider: + role: {{ include "resource.default.name" $ }}-control-plane + tags: + managed-by: "cluster-aws" + giantswarm.io/cluster: {{ include "resource.default.name" $ }} + giantswarm.io/installation: {{ .Values.global.managementCluster }} + {{- if .Values.global.providerSpecific.additionalResourceTags -}}{{- toYaml .Values.global.providerSpecific.additionalResourceTags | nindent 4 }}{{- end}} + providerConfigRef: + name: {{ include "resource.default.name" $ }} diff --git a/helm/cluster-aws/templates/workers-crossplane-iam-role.yaml b/helm/cluster-aws/templates/crossplane-iam-role-worker.yaml similarity index 97% rename from helm/cluster-aws/templates/workers-crossplane-iam-role.yaml rename to helm/cluster-aws/templates/crossplane-iam-role-worker.yaml index a16c544dd..368f553f8 100644 --- a/helm/cluster-aws/templates/workers-crossplane-iam-role.yaml +++ b/helm/cluster-aws/templates/crossplane-iam-role-worker.yaml @@ -15,7 +15,7 @@ spec: { "Effect": "Allow", "Principal": { - "Service": "ec2.amazonaws.com" + "Service": "ec2.amazonaws.com{{- if hasPrefix "cn-" .Values.awsRegion }}.cn{{- end }}" }, "Action": "sts:AssumeRole" } From 2e07c334c6ddb997a69b3813c4781e4dd2ac1d6e Mon Sep 17 00:00:00 2001 From: Jose Armesto Date: Tue, 28 Oct 2025 16:33:40 +0100 Subject: [PATCH 3/8] Add crossplane IAM Roles for control plane nodes --- helm/cluster-aws/templates/_aws_cluster.tpl | 2 +- .../crossplane-iam-role-control-plane.yaml | 19 +++++++++++++- .../templates/crossplane-iam-role-worker.yaml | 25 ++++++++++--------- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/helm/cluster-aws/templates/_aws_cluster.tpl b/helm/cluster-aws/templates/_aws_cluster.tpl index 1a888c890..a7c54ee61 100644 --- a/helm/cluster-aws/templates/_aws_cluster.tpl +++ b/helm/cluster-aws/templates/_aws_cluster.tpl @@ -255,7 +255,7 @@ spec: {{- end }} sshKeyName: ssh-key s3Bucket: - controlPlaneIAMInstanceProfile: control-plane-{{ include "resource.default.name" $ }} + controlPlaneIAMInstanceProfile: {{ include "resource.default.name" $ }}-control-plane name: {{ include "aws-region" . }}-capa-{{ include "resource.default.name" $ }} nodesIAMInstanceProfiles: - {{ include "resource.default.name" $ }}-worker diff --git a/helm/cluster-aws/templates/crossplane-iam-role-control-plane.yaml b/helm/cluster-aws/templates/crossplane-iam-role-control-plane.yaml index 1cc17cab6..bdec694f2 100644 --- a/helm/cluster-aws/templates/crossplane-iam-role-control-plane.yaml +++ b/helm/cluster-aws/templates/crossplane-iam-role-control-plane.yaml @@ -15,7 +15,7 @@ spec: { "Effect": "Allow", "Principal": { - "Service": "ec2.amazonaws.com{{- if hasPrefix "cn-" .Values.awsRegion }}.cn{{- end }}" + "Service": "ec2.amazonaws.com{{- if hasPrefix "cn-" (include "aws-region" .) }}.cn{{- end }}" }, "Action": "sts:AssumeRole" } @@ -168,6 +168,23 @@ spec: name: {{ include "resource.default.name" $ }} --- apiVersion: iam.aws.upbound.io/v1beta1 +kind: RolePolicyAttachment +metadata: + name: {{ include "resource.default.name" $ }}-control-plane + labels: + {{- include "labels.common" $ | nindent 4 }} + app.kubernetes.io/version: {{ .Chart.Version | quote }} +spec: + forProvider: + roleRef: + name: {{ include "resource.default.name" $ }}-control-plane + policyArnRef: + name: {{ include "resource.default.name" $ }}-control-plane + providerConfigRef: + name: {{ include "resource.default.name" $ }} + +--- +apiVersion: iam.aws.upbound.io/v1beta1 kind: InstanceProfile metadata: name: {{ include "resource.default.name" $ }}-control-plane diff --git a/helm/cluster-aws/templates/crossplane-iam-role-worker.yaml b/helm/cluster-aws/templates/crossplane-iam-role-worker.yaml index 368f553f8..95475aec4 100644 --- a/helm/cluster-aws/templates/crossplane-iam-role-worker.yaml +++ b/helm/cluster-aws/templates/crossplane-iam-role-worker.yaml @@ -15,7 +15,7 @@ spec: { "Effect": "Allow", "Principal": { - "Service": "ec2.amazonaws.com{{- if hasPrefix "cn-" .Values.awsRegion }}.cn{{- end }}" + "Service": "ec2.amazonaws.com{{- if hasPrefix "cn-" (include "aws-region" .) }}.cn{{- end }}" }, "Action": "sts:AssumeRole" } @@ -86,7 +86,7 @@ spec: name: {{ include "resource.default.name" $ }} --- apiVersion: iam.aws.upbound.io/v1beta1 -kind: InstanceProfile +kind: RolePolicyAttachment metadata: name: {{ include "resource.default.name" $ }}-worker labels: @@ -94,16 +94,15 @@ metadata: app.kubernetes.io/version: {{ .Chart.Version | quote }} spec: forProvider: - tags: - managed-by: "cluster-aws" - giantswarm.io/cluster: {{ include "resource.default.name" $ }} - giantswarm.io/installation: {{ .Values.global.managementCluster }} - {{- if .Values.global.providerSpecific.additionalResourceTags -}}{{- toYaml .Values.global.providerSpecific.additionalResourceTags | nindent 4 }}{{- end}} + roleRef: + name: {{ include "resource.default.name" $ }}-worker + policyArnRef: + name: {{ include "resource.default.name" $ }}-worker providerConfigRef: name: {{ include "resource.default.name" $ }} --- apiVersion: iam.aws.upbound.io/v1beta1 -kind: RolePolicyAttachment +kind: InstanceProfile metadata: name: {{ include "resource.default.name" $ }}-worker labels: @@ -111,9 +110,11 @@ metadata: app.kubernetes.io/version: {{ .Chart.Version | quote }} spec: forProvider: - roleRef: - name: {{ include "resource.default.name" $ }}-worker - instanceProfileRef: - name: {{ include "resource.default.name" $ }}-worker + role: {{ include "resource.default.name" $ }}-worker + tags: + managed-by: "cluster-aws" + giantswarm.io/cluster: {{ include "resource.default.name" $ }} + giantswarm.io/installation: {{ .Values.global.managementCluster }} + {{- if .Values.global.providerSpecific.additionalResourceTags -}}{{- toYaml .Values.global.providerSpecific.additionalResourceTags | nindent 4 }}{{- end}} providerConfigRef: name: {{ include "resource.default.name" $ }} From 0a5d219a8be358488b14cd9d8a1d00f2ac6df9ae Mon Sep 17 00:00:00 2001 From: Jose Armesto Date: Wed, 29 Oct 2025 16:02:44 +0100 Subject: [PATCH 4/8] Improve changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 490c7ef6b..f20d5c99f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Add node-problem-detector-app, disabled by default. -- Add Crossplane IAM Roles, policies and instance profiles for the worker nodes. Instead of having an IAM Role per node pool, now we'll use the same for all node pools. *This change will roll the worker nodes*. +- Add Crossplane IAM Roles, policies and instance profiles for worker and control plane nodes. Instead of having an IAM Role per node pool, now we'll use the same for all node pools. *This change will roll the nodes*. ### Changed From f84812f87c0a745043eac05773b16b8e1dc1ebb5 Mon Sep 17 00:00:00 2001 From: Jose Armesto Date: Mon, 3 Nov 2025 11:41:41 +0100 Subject: [PATCH 5/8] Pass worker role to karpenter-crossplane-resources app --- .../templates/karpenter-crossplane-resources-helmrelease.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/helm/cluster-aws/templates/karpenter-crossplane-resources-helmrelease.yaml b/helm/cluster-aws/templates/karpenter-crossplane-resources-helmrelease.yaml index ca41363a3..7d9eb889e 100644 --- a/helm/cluster-aws/templates/karpenter-crossplane-resources-helmrelease.yaml +++ b/helm/cluster-aws/templates/karpenter-crossplane-resources-helmrelease.yaml @@ -30,6 +30,8 @@ spec: upgrade: remediation: retries: -1 + values: + workersIamRole: arn:{{ include "aws-partition" $ }}:iam::{{ include "aws-account-id" $ }}:role/{{ include "resource.default.name" $ }}-worker valuesFrom: - kind: ConfigMap name: {{ include "resource.default.name" $ }}-crossplane-config From 3994379d03217714122009b0e2326996d47d20ed Mon Sep 17 00:00:00 2001 From: Jose Armesto Date: Mon, 3 Nov 2025 11:48:45 +0100 Subject: [PATCH 6/8] Fix changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b7db2255..819429951 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,12 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- *This change will roll the nodes* Add Crossplane IAM Roles, policies and instance profiles for worker and control plane nodes. Instead of having an IAM Role per node pool, now we'll use the same for all node pools. + ## [6.4.0] - 2025-10-28 ### Added - Add node-problem-detector-app, disabled by default. -- Add Crossplane IAM Roles, policies and instance profiles for worker and control plane nodes. Instead of having an IAM Role per node pool, now we'll use the same for all node pools. *This change will roll the nodes*. ### Changed From 5c54db8bff20d5e42da1f59d383cd702530900e3 Mon Sep 17 00:00:00 2001 From: Jose Armesto Date: Mon, 3 Nov 2025 11:50:55 +0100 Subject: [PATCH 7/8] Add mention to 'reducedInstanceProfileIamPermissionsForWorkers' --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 819429951..e17eabe07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - *This change will roll the nodes* Add Crossplane IAM Roles, policies and instance profiles for worker and control plane nodes. Instead of having an IAM Role per node pool, now we'll use the same for all node pools. + +### Removed + +- Removed `reducedInstanceProfileIamPermissionsForWorkers` value, as that's the default behavior now. ## [6.4.0] - 2025-10-28 From 6e2e9a226279d990c5f726a7fedbc0daf0864079 Mon Sep 17 00:00:00 2001 From: Jose Armesto Date: Mon, 3 Nov 2025 11:52:31 +0100 Subject: [PATCH 8/8] Remove duplicated field --- helm/cluster-aws/templates/_karpenter_machine_pools.tpl | 1 - 1 file changed, 1 deletion(-) diff --git a/helm/cluster-aws/templates/_karpenter_machine_pools.tpl b/helm/cluster-aws/templates/_karpenter_machine_pools.tpl index 636695b13..954e14ca1 100644 --- a/helm/cluster-aws/templates/_karpenter_machine_pools.tpl +++ b/helm/cluster-aws/templates/_karpenter_machine_pools.tpl @@ -34,7 +34,6 @@ spec: volumeSize: {{ $value.logVolumeSizeGB | default 30}}Gi volumeType: gp3 deleteOnTermination: true - instanceProfile: nodes-{{ $name }}-{{ include "resource.default.name" $ }} instanceProfile: {{ include "resource.default.name" $ }}-worker metadataOptions: {{- if eq $.Values.global.connectivity.cilium.ipamMode "eni" }}