AWS Security ChangesHomeSearch

AWS eks: ACK migration: Capability Role IAM permissions and coexistence

Service: eks · 2026-10-09 · Documentation medium

File: eks/latest/userguide/ack-comparison.md · Type: iam

Summary

Expands the self-managed ACK to managed capability migration guide with a recommended 'coexist' approach using disabledServices, explicit guidance to grant the IAM Capability Role permissions equivalent to self-managed controllers before enabling a service, warnings about AccessDenied reconciliation failures, CRD overwrite risk, tag-prefix changes, and restructures the lease-based handover as an alternative.

Security assessment

The added text documents how the ACK managed capability authenticates via a dedicated IAM Capability Role and the `capabilities.eks.amazonaws.com` service principal, instructing users to grant the role permissions equivalent to their self-managed controllers before enabling a service. This is security-relevant IAM/permissions guidance (avoiding AccessDenied reconciliation failures and staged, per-service permission grants) rather than a fix for a specific vulnerability or incident, so it is documentation of a security-relevant feature/best practice, not incident remediation.

Evidence

+Before you enable a service in the capability, grant the IAM Capability Role permissions that are equivalent to the permissions that your self-managed controller for that service uses today. The capability authenticates with a dedicated Capability Role through the `capabilities.eks.amazonaws.com` service principal, rather than through the mechanism your self-managed controllers use today, such as IRSA or EKS Pod Identity (see [Configure ACK permissions](./ack-permissions.html)). If the Capability Role is missing permissions, the capability adopts your resources. It then fails to reconcile them and logs `AccessDenied` errors.

Diff

diff --git a/eks/latest/userguide/ack-comparison.md b/eks/latest/userguide/ack-comparison.md
index e1d01f5..6f58a75 100644
--- a//eks/latest/userguide/ack-comparison.md
+++ b//eks/latest/userguide/ack-comparison.md
@@ -33 +33,63 @@ For complete ACK documentation and service-specific guides, see the [ACK documen
-You can migrate from self-managed ACK to the managed capability with minimal disruption to your AWS resources. The migration relies on Kubernetes leader election: the self-managed controller and the capability contend for the same lease, so only one of them reconciles a given resource at any time. For this to work, both must share a lease in the same namespace. The capability does not forcibly take the lease from a running self-managed controller, so you control when the handover happens by scaling the self-managed controller down.
+You can migrate from self-managed ACK to the managed capability with minimal disruption to your AWS resources. There are two approaches:
+
+  * Coexist with self-managed controllers (recommended) \- Create the capability with the services that you self-manage turned off, then migrate one service at a time. This is the recommended approach.
+
+  * Lease-based handover \- Create the capability with all services enabled, and use Kubernetes leader election to control when each handover happens.
+
+
+
+
+###### Important
+
+Before you enable a service in the capability, grant the IAM Capability Role permissions that are equivalent to the permissions that your self-managed controller for that service uses today. The capability authenticates with a dedicated Capability Role through the `capabilities.eks.amazonaws.com` service principal, rather than through the mechanism your self-managed controllers use today, such as IRSA or EKS Pod Identity (see [Configure ACK permissions](./ack-permissions.html)). If the Capability Role is missing permissions, the capability adopts your resources. It then fails to reconcile them and logs `AccessDenied` errors.
+
+With the recommended approach, you can grant these permissions one service at a time, because the capability doesn’t adopt resources of a service that is turned off. With the lease-based approach, grant them for every service before you create the capability.
+
+When the capability adopts a resource, it applies its own default resource tags (`eks:` prefixed) in place of the `services.k8s.aws/` tags used by self-managed ACK (see [ACK considerations for EKS](./ack-considerations.html)). Expect a one-time set of tagging API calls against your adopted resources, and update any cost-allocation or policy tooling that keys on the `services.k8s.aws/` tag prefix. This applies to both approaches.
+
+### Coexist with self-managed controllers (recommended)
+
+In this approach, you create the capability with `disabledServices` listing every ACK service that you currently run yourself. The capability doesn’t install custom resource definitions (CRDs) for those services and doesn’t run controllers for them, so it can’t contend with your self-managed controllers or adopt their resources. You then migrate one service at a time, on your own schedule, and you don’t need to change the leader election configuration of your self-managed controllers at all.
+
+The steps use the S3 controller (`ack-s3-controller`) as an example.
+
+  1. Determine which ACK services you currently run self-managed.
+
+  2. Create the ACK capability with those services turned off (see [Create an ACK capability](./create-ack-capability.html)). For example, if you self-manage S3, EC2, and IAM:
+    
+        aws eks create-capability \
+      --region region-code \
+      --cluster-name my-cluster \
+      --capability-name my-ack \
+      --type ACK \
+      --role-arn arn:aws:iam::111122223333:role/ACKCapabilityRole \
+      --delete-propagation-policy RETAIN \
+      --configuration '{"ack": {"disabledServices": ["s3", "ec2", "iam"]}}'
+
+Your self-managed controllers keep reconciling your resources, unaffected.
+
+  3. For the service that you want to migrate, scale its self-managed controller down to zero replicas **before** you turn the service on in the capability:
+    
+        kubectl scale deployment ack-s3-controller \
+      --namespace ack-system --replicas=0
+
+  4. Turn the service on in the capability by removing it from `disabledServices`. Specify the complete list of services that you want to remain turned off. If this service was the only one turned off, specify an empty list:
+    
+        aws eks update-capability \
+      --region region-code \
+      --cluster-name my-cluster \
+      --capability-name my-ack \
+      --configuration '{"ack": {"disabledServices": ["ec2", "iam"]}}'
+
+The capability installs the service’s CRDs, starts its controller, and adopts your existing resources.
+
+  5. Verify that the capability has taken over reconciliation for that service. Confirm that resources report a `Synced` condition of `True` and that the capability is not reporting `AccessDenied` errors.
+
+  6. Remove the self-managed controller for that service:
+    
+        helm uninstall ack-s3-controller --namespace ack-system
+
+  7. Repeat the previous steps for each remaining service.
+
+
+
@@ -37 +99,15 @@ You can migrate from self-managed ACK to the managed capability with minimal dis
-Before you begin, grant the IAM Capability Role permissions that are equivalent to the permissions your self-managed controllers use today. The capability authenticates with a dedicated Capability Role through the `capabilities.eks.amazonaws.com` service principal, rather than through the mechanism your self-managed controllers use today, such as IRSA or EKS Pod Identity (see [Configure ACK permissions](./ack-permissions.html)). If the Capability Role is missing permissions, the capability adopts your resources. It then fails to reconcile them and logs `AccessDenied` errors.
+Scale the self-managed controller down before you turn the service on in the capability. If both run at the same time, both reconcile the same resources, because by default a self-managed controller’s lease and the capability’s lease aren’t in the same namespace. If you would rather not scale down first, configure leader election as described in Lease-based handover so that the two coordinate instead.
+
+###### Note
+
+To roll a service back, add it to `disabledServices` again and scale your self-managed controller back up.
+
+###### Note
+
+When the capability turns a service on, it reconciles that service’s CRDs to the versions that the capability ships. If you installed a newer or modified CRD for that service, the capability updates it, which can overwrite changes that you made. If the difference can’t be applied safely, the capability reports an error for that service and doesn’t reconcile it until the CRD is compatible. If you need to keep a specific CRD version for a service, leave that service in `disabledServices` and continue to manage it yourself.
+
+### Lease-based handover
+
+In this approach, you create the capability with all services enabled and rely on Kubernetes leader election to control the handover: the self-managed controller and the capability contend for the same lease, so only one of them reconciles a given resource at any time. For this to work, both must share a lease in the same namespace. The capability does not forcibly take the lease from a running self-managed controller, so you control when the handover happens by scaling the self-managed controller down.
+
+Use this approach if you need the capability’s controller to be running and waiting before you scale your own controller down, rather than accepting a brief period in which neither reconciles.
@@ -43 +119 @@ Complete the following steps to migrate. The steps use the S3 controller (`ack-s
-Running a controller self-managed alongside the capability is intended as a temporary state during migration, not as a long-term configuration. While both run, an interruption on either side (such as a capability deployment or an upgrade of the self-managed controller) can release the lease and let the other side acquire it, causing reconciliation to switch unexpectedly between them. Complete the migration for each controller rather than running it self-managed alongside the capability indefinitely.
+With this approach, running a controller self-managed alongside the capability is intended as a temporary state during migration, not as a long-term configuration. While both run, an interruption on either side (such as a capability deployment or an upgrade of the self-managed controller) can release the lease and let the other side acquire it, causing reconciliation to switch unexpectedly between them. Complete the migration for each controller rather than running it self-managed alongside the capability indefinitely. To keep a service self-managed for the long term, turn it off in the capability instead, as described in Coexist with self-managed controllers (recommended).
@@ -66,2 +141,0 @@ After you scale the self-managed controller down, the capability acquires the le
-On adoption, the capability applies its own default resource tags (`eks:` prefixed) in place of the `services.k8s.aws/` tags used by self-managed ACK (see [ACK considerations for EKS](./ack-considerations.html)). Expect a one-time set of tagging API calls against your adopted resources, and update any cost-allocation or policy tooling that keys on the `services.k8s.aws/` tag prefix.
-