

 **Help improve this page** 

To contribute to this user guide, choose the **Edit this page on GitHub** link that is located in the right pane of every page.

# Deploy AWS resources from Kubernetes with AWS Controllers for Kubernetes (ACK)
<a name="ack"></a>

 AWS Controllers for Kubernetes (ACK) lets you define and manage AWS service resources directly from Kubernetes. With AWS Controllers for Kubernetes (ACK), you can manage workload resources and cloud infrastructure using Kubernetes custom resources, right alongside your application workloads using familiar Kubernetes APIs and tools.

With EKS Capabilities, ACK is fully managed by AWS, eliminating the need to install, maintain, and scale ACK controllers on your clusters.

## How ACK Works
<a name="_how_ack_works"></a>

ACK translates Kubernetes custom resource specifications into AWS API calls. When you create, update, or delete a Kubernetes custom resource representing an AWS service resource, ACK makes the required AWS API calls to create, update, or delete the AWS resource.

Each AWS resource supported by ACK has its own custom resource definition (CRD) that defines the Kubernetes API schema for specifying its configuration. For example, ACK provides CRDs for S3 including buckets, bucket policies, and other S3 resources.

ACK continuously reconciles the state of your AWS resources with the desired state defined in your Kubernetes custom resources. If a resource drifts from its desired state, ACK detects this and takes corrective action to bring it back into alignment. Changes to Kubernetes resources are immediately reflected in AWS resource state, while passive drift detection and remediation of upstream AWS resource changes can take as long as 10 hours (the resync period), but will typically occur much sooner.

 **Example S3 Bucket resource manifest** 

```
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
  name: my-ack-bucket
spec:
  name: my-unique-bucket-name
```

When you apply this custom resource to your cluster, ACK creates an Amazon S3 bucket in your account if it does not yet exist. Subsequent changes to this resource, for example specifying a non-default storage tier or adding a policy, will be applied to the S3 resource in AWS. When this resource is deleted from the cluster, the S3 bucket in AWS is deleted by default.

## Benefits of ACK
<a name="_benefits_of_ack"></a>

ACK provides Kubernetes-native AWS resource management, allowing you to manage AWS resources using the same Kubernetes APIs and tools you use for your applications. This unified approach simplifies your infrastructure management workflow by eliminating the need to switch between different tools or learn separate infrastructure-as-code systems. You define your AWS resources declaratively in Kubernetes manifests, enabling GitOps workflows and infrastructure as code practices that integrate seamlessly with your existing development processes.

ACK continuously reconciles the desired state of your AWS resources with their actual state, correcting drift and ensuring consistency across your infrastructure. This continuous reconciliation means that imperative out-of-band changes to AWS resources are automatically reverted to match your declared configuration, maintaining the integrity of your infrastructure as code. You can configure ACK to manage resources across multiple AWS accounts and regions, enabling complex multi-account architectures with no additional tooling.

For organizations migrating from other infrastructure management tools, ACK supports resource adoption, allowing you to bring existing AWS resources under ACK management without recreating them. ACK also provides read-only resources for AWS resource observation without modification access, and annotations to optionally retain AWS resources even when the Kubernetes resource is deleted from the cluster.

To learn more and get started with the EKS Capability for ACK, see [ACK concepts](ack-concepts.md) and [ACK considerations for EKS](ack-considerations.md).

## Supported AWS Services
<a name="supported_shared_aws_services"></a>

ACK supports a wide range of AWS services, including but not limited to:
+ Amazon EC2
+ Amazon S3
+ Amazon RDS
+ Amazon DynamoDB
+ Amazon ElastiCache
+ Amazon EKS
+ Amazon SQS
+ Amazon SNS
+  AWS Lambda
+  AWS IAM

All AWS services listed as Generally Available upstream are supported by the EKS Capability for ACK. Refer to the [full list of AWS services supported](https://aws-controllers-k8s.github.io/community/docs/community/services/) for details.

## Integration with Other EKS Managed Capabilities
<a name="_integration_with_other_eks_managed_capabilities"></a>

ACK integrates with other EKS Managed Capabilities.
+  **Argo CD**: Use Argo CD to manage the deployment of ACK resources across multiple clusters, enabling GitOps workflows for your AWS infrastructure.
  + ACK extends the benefits of GitOps when paired with ArgoCD, but ACK does not require integration with git.
+  **kro (Kube Resource Orchestrator)**: Use kro to compose complex resources from ACK resources, creating higher-level abstractions that simplify resource management.
  + You can create composite custom resources with kro that define both Kubernetes resources and AWS resources. Team members can use these custom resources to quickly deploy complex applications.

## Getting Started with ACK
<a name="_getting_started_with_ack"></a>

To get started with the EKS Capability for ACK:

1. Create and configure an IAM Capability Role with the necessary permissions for ACK to manage AWS resources on your behalf.

1.  [Create an ACK capability resource](create-ack-capability.md) on your EKS cluster through the AWS Console, AWS CLI, or your preferred infrastructure as code tool.

1. Apply Kubernetes custom resources to your cluster to start managing your AWS resources in Kubernetes.

# Create an ACK capability
<a name="create-ack-capability"></a>

This chapter explains how to create an ACK capability on your Amazon EKS cluster.

## Prerequisites
<a name="_prerequisites"></a>

Before creating an ACK capability, ensure you have:
+ An Amazon EKS cluster
+ An IAM Capability Role with permissions for ACK to manage AWS resources
+ Sufficient IAM permissions to create capability resources on EKS clusters
+ The appropriate CLI tool installed and configured, or access to the EKS Console

For instructions on creating the IAM Capability Role, see [Amazon EKS capability IAM role](capability-role.md).

**Important**  
ACK is an infrastructure management capability that grants the ability to create, modify, and delete AWS resources. This is an admin-scoped capability that should be carefully controlled. Anyone with permission to create Kubernetes resources in your cluster can effectively create AWS resources through ACK, subject to the IAM Capability Role permissions. The IAM Capability Role you provide determines which AWS resources ACK can create and manage. For guidance on creating an appropriate role with least-privilege permissions, see [Amazon EKS capability IAM role](capability-role.md) and [Security considerations for EKS Capabilities](capabilities-security.md).

## Choose your tool
<a name="_choose_your_tool"></a>

You can create an ACK capability using the AWS Management Console, AWS CLI, or eksctl:
+  [Create an ACK capability using the Console](ack-create-console.md) - Use the Console for a guided experience
+  [Create an ACK capability using the AWS CLI](ack-create-cli.md) - Use the AWS CLI for scripting and automation
+  [Create an ACK capability using eksctl](ack-create-eksctl.md) - Use eksctl for a Kubernetes-native experience

## What happens when you create an ACK capability
<a name="_what_happens_when_you_create_an_ack_capability"></a>

When you create an ACK capability:

1. EKS creates the ACK capability service and configures it to monitor and manage resources in your cluster

1. Custom Resource Definitions (CRDs) are installed in your cluster

1. An access entry is automatically created for your IAM Capability Role with capability-specific access entry policies that grant baseline Kubernetes permissions (see [Security considerations for EKS Capabilities](capabilities-security.md))

1. The capability assumes the IAM Capability Role you provide

1. ACK begins watching for its custom resources in your cluster

1. The capability status changes from `CREATING` to `ACTIVE` 

Once active, you can create ACK custom resources in your cluster to manage AWS resources.

**Note**  
The automatically created access entry includes the `AmazonEKSACKPolicy` which grants ACK permissions to manage AWS resources. Some ACK resources that reference Kubernetes secrets (such as RDS databases with passwords) require additional access entry policies. To learn more about access entries and how to configure additional permissions, see [Security considerations for EKS Capabilities](capabilities-security.md).

## Next steps
<a name="_next_steps"></a>

After creating the ACK capability:
+  [ACK concepts](ack-concepts.md) - Understand ACK concepts and get started with AWS resources
+  [ACK concepts](ack-concepts.md) - Learn about reconciliation, field exports, and resource adoption patterns
+  [Configure ACK permissions](ack-permissions.md) - Configure IAM permissions and multi-account patterns

# Create an ACK capability using the Console
<a name="ack-create-console"></a>

This topic describes how to create an AWS Controllers for Kubernetes (ACK) capability using the AWS Management Console.

## Create the ACK capability
<a name="_create_the_ack_capability"></a>

1. Open the Amazon EKS console at https://console.aws.amazon.com/eks/home\$1/clusters.

1. Select your cluster name to open the cluster detail page.

1. Choose the **Capabilities** tab.

1. In the left navigation, choose ** AWS Controllers for Kubernetes (ACK)**.

1. Choose **Create AWS Controllers for Kubernetes capability**.

1. For **IAM Capability Role**:
   + If you already have an IAM Capability Role, select it from the dropdown
   + If you need to create a role, choose **Create admin role** 

     This opens the IAM console in a new tab with pre-populated trust policy and the `AdministratorAccess` managed policy. You can unselect this policy and add other permissions if you prefer.

     After creating the role, return to the EKS console and the role will be automatically selected.
**Important**  
The suggested `AdministratorAccess` policy grants broad permissions and is intended to streamline getting started. For production use, replace this with a custom policy that grants only the permissions needed for the specific AWS services you plan to manage with ACK. For guidance on creating least-privilege policies, see [Configure ACK permissions](ack-permissions.md) and [Security considerations for EKS Capabilities](capabilities-security.md).

1. Choose **Create**.

The capability creation process begins.

## Verify the capability is active
<a name="_verify_the_capability_is_active"></a>

1. On the **Capabilities** tab, view the ACK capability status.

1. Wait for the status to change from `CREATING` to `ACTIVE`.

1. Once active, the capability is ready to use.

For information about capability statuses and troubleshooting, see [Working with capability resources](working-with-capabilities.md).

## Verify custom resources are available
<a name="_verify_custom_resources_are_available"></a>

After the capability is active, verify that ACK custom resources are available in your cluster.

 **Using the console** 

1. Navigate to your cluster in the Amazon EKS console

1. Choose the **Resources** tab

1. Choose **Extensions** 

1. Choose **CustomResourceDefinitions** 

You should see a number of CRDs listed for AWS resources.

 **Using kubectl** 

```
kubectl api-resources | grep services.k8s.aws
```

You should see a number of APIs listed for AWS resources.

**Note**  
The capability for AWS Controllers for Kubernetes will install a number of CRDs for a variety of AWS resources.

## Next steps
<a name="_next_steps"></a>
+  [ACK concepts](ack-concepts.md) - Understand ACK concepts and get started
+  [Configure ACK permissions](ack-permissions.md) - Configure IAM permissions for other AWS services
+  [Working with capability resources](working-with-capabilities.md) - Manage your ACK capability resource

# Create an ACK capability using the AWS CLI
<a name="ack-create-cli"></a>

This topic describes how to create an AWS Controllers for Kubernetes (ACK) capability using the AWS CLI.

## Prerequisites
<a name="_prerequisites"></a>
+  ** AWS CLI** – Version `2.12.3` or later. To check your version, run `aws --version`. For more information, see [Installing](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) in the AWS Command Line Interface User Guide.
+  ** `kubectl` ** – A command line tool for working with Kubernetes clusters. For more information, see [Set up `kubectl` and `eksctl`](install-kubectl.md).

## Step 1: Create an IAM Capability Role
<a name="_step_1_create_an_iam_capability_role"></a>

Create a trust policy file:

```
cat > ack-trust-policy.json << 'EOF'
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "capabilities.eks.amazonaws.com"
      },
      "Action": [
        "sts:AssumeRole",
        "sts:TagSession"
      ]
    }
  ]
}
EOF
```

Create the IAM role:

```
aws iam create-role \
  --role-name ACKCapabilityRole \
  --assume-role-policy-document file://ack-trust-policy.json
```

Attach the `AdministratorAccess` managed policy to the role:

```
aws iam attach-role-policy \
  --role-name ACKCapabilityRole \
  --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
```

**Important**  
The suggested `AdministratorAccess` policy grants broad permissions and is intended to streamline getting started. For production use, replace this with a custom policy that grants only the permissions needed for the specific AWS services you plan to manage with ACK. For guidance on creating least-privilege policies, see [Configure ACK permissions](ack-permissions.md) and [Security considerations for EKS Capabilities](capabilities-security.md).

## Step 2: Create the ACK capability
<a name="_step_2_create_the_ack_capability"></a>

Create the ACK capability resource on your cluster. Replace *region-code* with the AWS Region that your cluster is in and replace *my-cluster* with the name of your cluster.

```
aws eks create-capability \
  --region region-code \
  --cluster-name my-cluster \
  --capability-name my-ack \
  --type ACK \
  --role-arn arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):role/ACKCapabilityRole \
  --delete-propagation-policy RETAIN
```

The command returns immediately, but the capability takes some time to become active as EKS creates the required capability infrastructure and components. EKS will install the Kubernetes Custom Resource Definitions related to this capability in your cluster as it is being created.

**Note**  
If you receive an error that the cluster doesn’t exist or you don’t have permissions, verify:  
The cluster name is correct
Your AWS CLI is configured for the correct region
You have the required IAM permissions

## Step 3: Verify the capability is active
<a name="_step_3_verify_the_capability_is_active"></a>

Wait for the capability to become active. Replace *region-code* with the AWS Region that your cluster is in and replace *my-cluster* with the name of your cluster.

```
aws eks describe-capability \
  --region region-code \
  --cluster-name my-cluster \
  --capability-name my-ack \
  --query 'capability.status' \
  --output text
```

The capability is ready when the status shows `ACTIVE`. Don’t continue to the next step until the status is `ACTIVE`.

You can also view the full capability details:

```
aws eks describe-capability \
  --region region-code \
  --cluster-name my-cluster \
  --capability-name my-ack
```

## Step 4: Verify custom resources are available
<a name="_step_4_verify_custom_resources_are_available"></a>

After the capability is active, verify that ACK custom resources are available in your cluster:

```
kubectl api-resources | grep services.k8s.aws
```

You should see a number of APIs listed for AWS resources.

**Note**  
The capability for AWS Controllers for Kubernetes will install a number of CRDs for a variety of AWS resources.

## Next steps
<a name="_next_steps"></a>
+  [ACK concepts](ack-concepts.md) - Understand ACK concepts and get started
+  [Configure ACK permissions](ack-permissions.md) - Configure IAM permissions for other AWS services
+  [Working with capability resources](working-with-capabilities.md) - Manage your ACK capability resource

# Create an ACK capability using eksctl
<a name="ack-create-eksctl"></a>

This topic describes how to create an AWS Controllers for Kubernetes (ACK) capability using eksctl.

**Note**  
The following steps require eksctl version `0.220.0` or later. To check your version, run `eksctl version`.

## Step 1: Create an IAM Capability Role
<a name="_step_1_create_an_iam_capability_role"></a>

Create a trust policy file:

```
cat > ack-trust-policy.json << 'EOF'
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "capabilities.eks.amazonaws.com"
      },
      "Action": [
        "sts:AssumeRole",
        "sts:TagSession"
      ]
    }
  ]
}
EOF
```

Create the IAM role:

```
aws iam create-role \
  --role-name ACKCapabilityRole \
  --assume-role-policy-document file://ack-trust-policy.json
```

Attach the `AdministratorAccess` managed policy to the role:

```
aws iam attach-role-policy \
  --role-name ACKCapabilityRole \
  --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
```

**Important**  
The suggested `AdministratorAccess` policy grants broad permissions and is intended to streamline getting started. For production use, replace this with a custom policy that grants only the permissions needed for the specific AWS services you plan to manage with ACK. For guidance on creating least-privilege policies, see [Configure ACK permissions](ack-permissions.md) and [Security considerations for EKS Capabilities](capabilities-security.md).

**Important**  
This policy grants permissions for S3 bucket management with `"Resource": "*"`, which allows operations on all S3 buckets.  
For production use: \$1 Restrict the `Resource` field to specific bucket ARNs or name patterns \$1 Use IAM condition keys to limit access by resource tags \$1 Grant only the minimum permissions needed for your use case  
For other AWS services, see [Configure ACK permissions](ack-permissions.md).

Attach the policy to the role:

```
aws iam attach-role-policy \
  --role-name ACKCapabilityRole \
  --policy-arn arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):policy/ACKS3Policy
```

## Step 2: Create the ACK capability
<a name="_step_2_create_the_ack_capability"></a>

Create the ACK capability using eksctl. Replace *region-code* with the AWS Region that your cluster is in and replace *my-cluster* with the name of your cluster.

```
eksctl create capability \
  --cluster [.replaceable]`my-cluster` \
  --region [.replaceable]`region-code` \
  --name ack \
  --type ACK \
  --role-arn arn:aws:iam::$(aws sts get-caller-identity --query Account --output text):role/ACKCapabilityRole \
  --ack-service-controllers s3
```

**Note**  
The `--ack-service-controllers` flag is optional. If omitted, ACK enables all available controllers. For better performance and security, consider enabling only the controllers you need. You can specify multiple controllers: `--ack-service-controllers s3,rds,dynamodb` 

The command returns immediately, but the capability takes some time to become active.

## Step 3: Verify the capability is active
<a name="_step_3_verify_the_capability_is_active"></a>

Check the capability status:

```
eksctl get capability \
  --cluster [.replaceable]`my-cluster` \
  --region [.replaceable]`region-code` \
  --name ack
```

The capability is ready when the status shows `ACTIVE`.

## Step 4: Verify custom resources are available
<a name="_step_4_verify_custom_resources_are_available"></a>

After the capability is active, verify that ACK custom resources are available in your cluster:

```
kubectl api-resources | grep services.k8s.aws
```

You should see a number of APIs listed for AWS resources.

**Note**  
The capability for AWS Controllers for Kubernetes will install a number of CRDs for a variety of AWS resources.

## Next steps
<a name="_next_steps"></a>
+  [ACK concepts](ack-concepts.md) - Understand ACK concepts and get started
+  [Configure ACK permissions](ack-permissions.md) - Configure IAM permissions for other AWS services
+  [Working with capability resources](working-with-capabilities.md) - Manage your ACK capability resource

# ACK concepts
<a name="ack-concepts"></a>

ACK manages AWS resources through Kubernetes APIs by continuously reconciling the desired state in your manifests with the actual state in AWS. When you create or update a Kubernetes custom resource, ACK makes the necessary AWS API calls to create or modify the corresponding AWS resource, then monitors it for drift and updates the Kubernetes status to reflect the current state. This approach lets you manage infrastructure using familiar Kubernetes tools and workflows while maintaining consistency between your cluster and AWS.

This topic explains the fundamental concepts behind how ACK manages AWS resources through Kubernetes APIs.

## Getting started with ACK
<a name="_getting_started_with_ack"></a>

After creating the ACK capability (see [Create an ACK capability](create-ack-capability.md)), you can start managing AWS resources using Kubernetes manifests in your cluster.

As an example, create this S3 bucket manifest in `bucket.yaml`, choosing your own unique bucket name.

```
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
  name: my-test-bucket
  namespace: default
spec:
  name: my-unique-bucket-name-12345
```

Apply the manifest:

```
kubectl apply -f bucket.yaml
```

Check the status:

```
kubectl get bucket my-test-bucket
kubectl describe bucket my-test-bucket
```

Verify the bucket was created in AWS:

```
aws s3 ls | grep my-unique-bucket-name-12345
```

Delete the Kubernetes resource:

```
kubectl delete bucket my-test-bucket
```

Verify the bucket was deleted from AWS:

```
aws s3 ls | grep my-unique-bucket-name-12345
```

The bucket should no longer appear in the list, demonstrating that ACK manages the full lifecycle of AWS resources.

For more information on getting started with ACK, see [Getting Started with ACK](https://aws-controllers-k8s.github.io/community/docs/user-docs/getting-started/).

## Resource lifecycle and reconciliation
<a name="_resource_lifecycle_and_reconciliation"></a>

ACK uses a continuous reconciliation loop to ensure your AWS resources match the desired state defined in your Kubernetes manifests.

 **How reconciliation works**:

1. You create or update a Kubernetes custom resource (for example, an S3 Bucket)

1. ACK detects the change and compares the desired state with the actual state in AWS 

1. If they differ, ACK makes AWS API calls to reconcile the difference

1. ACK updates the resource status in Kubernetes to reflect the current state

1. The loop repeats continuously, typically every few hours

Reconciliation is triggered when you create a new Kubernetes resource, update an existing resource’s `spec`, or when ACK detects drift in AWS from manual changes made outside ACK. Additionally, ACK performs periodic reconciliation with a resync period of 10 hours. Changes to Kubernetes resources trigger immediate reconciliation, while passive drift detection of upstream AWS resource changes occurs during the periodic resync.

When working through the getting started example above, ACK performs these steps:

1. Checks if bucket exists in AWS 

1. If not, calls `s3:CreateBucket` 

1. Updates Kubernetes status with bucket ARN and state

1. Continues monitoring for drift

To learn more about how ACK works, see [ACK Reconciliation](https://aws-controllers-k8s.github.io/community/docs/user-docs/reconciliation/).

## Status conditions
<a name="_status_conditions"></a>

ACK resources use status conditions to communicate their state. Understanding these conditions helps you troubleshoot issues and understand resource health.
+  **Ready**: Indicates the resource is ready to be consumed (standardized Kubernetes condition).
+  **ACK.ResourceSynced**: Indicates the resource spec matches the AWS resource state.
+  **ACK.Terminal**: Indicates an unrecoverable error has occurred.
+  **ACK.Adopted**: Indicates the resource was adopted from an existing AWS resource rather than created new.
+  **ACK.Recoverable**: Indicates a recoverable error that may resolve without updating the spec.
+  **ACK.Advisory**: Provides advisory information about the resource.
+  **ACK.LateInitialized**: Indicates whether late initialization of fields is complete.
+  **ACK.ReferencesResolved**: Indicates whether all `AWSResourceReference` fields have been resolved.
+  **ACK.IAMRoleSelected**: Indicates whether an IAMRoleSelector has been selected to manage this resource.

Check resource status:

```
# Check if resource is ready
kubectl get bucket my-bucket -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}'

# Check for terminal errors
kubectl get bucket my-bucket -o jsonpath='{.status.conditions[?(@.type=="ACK.Terminal")]}'
```

Example status:

```
status:
  conditions:
  - type: Ready
    status: "True"
    lastTransitionTime: "2024-01-15T10:30:00Z"
  - type: ACK.ResourceSynced
    status: "True"
    lastTransitionTime: "2024-01-15T10:30:00Z"
  - type: ACK.Terminal
    status: "True"
  ackResourceMetadata:
    arn: arn:aws:s3:::my-unique-bucket-name
    ownerAccountID: "111122223333"
    region: us-west-2
```

To learn more about ACK status and conditions, see [ACK Conditions](https://aws-controllers-k8s.github.io/community/docs/user-docs/conditions/).

## Deletion policies
<a name="_deletion_policies"></a>

ACK’s deletion policy controls what happens to AWS resources when you delete the Kubernetes resource.

 **Delete (default)** 

The AWS resource is deleted when you delete the Kubernetes resource: This is the default behavior.

```
# No annotation needed - this is the default
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
  name: temp-bucket
spec:
  name: temporary-bucket
```

Deleting this resource deletes the S3 bucket in AWS.

 **Retain** 

The AWS resource is kept when you delete the Kubernetes resource:

```
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
  name: important-bucket
  annotations:
    services.k8s.aws/deletion-policy: "retain"
spec:
  name: production-data-bucket
```

Deleting this resource removes it from Kubernetes but leaves the S3 bucket in AWS.

The `retain` policy is useful for production databases that should outlive the Kubernetes resource, shared resources used by multiple applications, resources with important data that shouldn’t be accidentally deleted, or temporary ACK management where you adopt a resource, configure it, then release it back to manual management.

To learn more about ACK deletion policy, see [ACK Deletion Policy](https://aws-controllers-k8s.github.io/community/docs/user-docs/deletion-policy/).

## Resource adoption
<a name="_resource_adoption"></a>

Adoption allows you to bring existing AWS resources under ACK management without recreating them.

When to use adoption:
+ Migrating existing infrastructure to ACK management
+ Recovering orphaned AWS resources in case of accidental resource deletion in Kubernetes
+ Importing resources created by other tools (CloudFormation, Terraform)

How adoption works:

```
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
  name: existing-bucket
  annotations:
    services.k8s.aws/adoption-policy: "adopt-or-create"
spec:
  name: my-existing-bucket-name
```

When you create this resource:

1. ACK checks if a bucket with that name exists in AWS 

1. If found, ACK adopts it (no API calls to create)

1. ACK reads the current configuration from AWS 

1. ACK updates the Kubernetes status to reflect the actual state

1. Future updates reconcile the resource normally

Once adopted, resources are managed like any other ACK resource, and deleting the Kubernetes resource will delete the AWS resource unless you use the `retain` deletion policy.

When adopting resources, the AWS resource must already exist and ACK needs read permissions to discover it. The `adopt-or-create` policy adopts the resource if it exists, or creates it if it doesn’t. This is useful when you want a declarative workflow that works whether the resource exists or not.

To learn more about ACK resource adoption, see [ACK Resource Adoption](https://aws-controllers-k8s.github.io/community/docs/user-docs/adopted-resource/).

## Cross-account and cross-region resources
<a name="_cross_account_and_cross_region_resources"></a>

ACK can manage resources in different AWS accounts and regions from a single cluster.

 **Cross-region resource annotations** 

You can specify the region of an AWS resource using an annotation:

```
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
  name: eu-bucket
  annotations:
    services.k8s.aws/region: eu-west-1
spec:
  name: my-eu-bucket
```

You can also specify the region of all AWS resources created in a given namespace:

 **Namespace annotations** 

Set a default region for all resources in a namespace:

```
apiVersion: v1
kind: Namespace
metadata:
  name: production
  annotations:
    services.k8s.aws/default-region: us-west-2
```

Resources created in this namespace use this region unless overridden with a resource-level annotation.

 **Cross-account** 

Use IAM Role Selectors to map specific IAM roles to namespaces:

```
apiVersion: services.k8s.aws/v1alpha1
kind: IAMRoleSelector
metadata:
  name: target-account-config
spec:
  arn: arn:aws:iam::444455556666:role/ACKTargetAccountRole
  namespaceSelector:
    names:
      - production
```

Resources created in the mapped namespace automatically use the specified role.

To learn more about IAM Role Selectors, see [ACK Cross-Account Resource Management](https://aws-controllers-k8s.github.io/docs/guides/cross-account). For cross-account configuration details, see [Configure ACK permissions](ack-permissions.md).

## Error handling and retry behavior
<a name="_error_handling_and_retry_behavior"></a>

ACK automatically handles transient errors and retries failed operations.

Retry strategy:
+ Transient errors (rate limiting, temporary service issues, insufficient permissions) trigger automatic retries
+ Exponential backoff prevents overwhelming AWS APIs
+ Maximum retry attempts vary by error type
+ Permanent errors (invalid parameters, resource name conflicts) don’t retry

Check resource status for error details using `kubectl describe`:

```
kubectl describe bucket my-bucket
```

Look for status conditions with error messages, events showing recent reconciliation attempts, and the `message` field in status conditions explaining failures. Common errors include insufficient IAM permissions, resource name conflicts in AWS, invalid configuration values in the `spec`, and exceeded AWS service quotas.

For troubleshooting common errors, see [Troubleshoot issues with ACK capabilities](ack-troubleshooting.md).

## Resource composition with kro
<a name="_resource_composition_with_kro"></a>

For composing and connecting multiple ACK resources together, use the EKS Capability for kro (Kube Resource Orchestrator). kro provides a declarative way to define groups of resources, passing configuration between resources to manage complex infrastructure patterns simply.

For detailed examples of creating custom resource compositions with ACK resources, see [kro concepts](kro-concepts.md) 

## Next steps
<a name="_next_steps"></a>
+  [ACK considerations for EKS](ack-considerations.md) - EKS-specific patterns and integration strategies

# Configure ACK permissions
<a name="ack-permissions"></a>

ACK requires IAM permissions to create and manage AWS resources on your behalf. This topic explains how IAM works with ACK and provides guidance on configuring permissions for different use cases.

## How IAM works with ACK
<a name="_how_iam_works_with_ack"></a>

ACK uses IAM roles to authenticate with AWS and perform actions on your resources. There are two ways to provide permissions to ACK:

 **Capability Role**: The IAM role you provide when creating the ACK capability. This role is used by default for all ACK operations.

 **IAM Role Selectors**: Additional IAM roles that can be mapped to specific namespaces or resources. These roles override the Capability Role for resources in their scope.

When ACK needs to create or manage a resource, it determines which IAM role to use:

1. Check if an IAMRoleSelector matches the resource’s namespace

1. If a match is found, assume that IAM role

1. Otherwise, use the Capability Role

This approach enables flexible permission management from simple single-role setups to complex multi-account, multi-team configurations.

## Getting started: Simple permission setup
<a name="_getting_started_simple_permission_setup"></a>

For development, testing, or simple use cases, you can add all necessary service permissions directly to the Capability Role.

This approach works well when:
+ You’re getting started with ACK
+ All resources are in the same AWS account
+ A single team manages all ACK resources
+ You trust all ACK users to have the same permissions

## Production best practice: IAM Role Selectors
<a name="_production_best_practice_iam_role_selectors"></a>

For production environments, use IAM Role Selectors to implement least-privilege access and namespace-level isolation.

When using IAM Role Selectors, the Capability Role only needs `sts:AssumeRole` and `sts:TagSession` permissions to assume the service-specific roles. You don’t need to add any AWS service permissions (like S3 or RDS) to the Capability Role itself—those permissions are granted to the individual IAM roles that the Capability Role assumes.

 **Choosing between permission models**:

Use **direct permissions** (adding service permissions to the Capability Role) when:
+ You’re getting started and want the simplest setup
+ All resources are in the same account as your cluster
+ You have administrative, cluster-wide permission requirements
+ All teams can share the same permissions

Use **IAM Role Selectors** when:
+ Managing resources across multiple AWS accounts
+ Different teams or namespaces need different permissions
+ You need fine-grained access control per namespace
+ You want to follow least-privilege security practices

You can start with direct permissions and migrate to IAM Role Selectors later as your requirements grow.

 **Why use IAM Role Selectors in production:** 
+  **Least privilege**: Each namespace gets only the permissions it needs
+  **Team isolation**: Team A cannot accidentally use Team B’s permissions
+  **Easier auditing**: Clear mapping of which namespace uses which role
+  **Cross-account support**: Required for managing resources in multiple accounts
+  **Separation of concerns**: Different services or environments use different roles

### Basic IAM Role Selector setup
<a name="_basic_iam_role_selector_setup"></a>

 **Step 1: Create a service-specific IAM role** 

Create an IAM role with permissions for specific AWS services:

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:*"
      ],
      "Resource": "*"
    }
  ]
}
```

Configure the trust policy to allow the Capability Role to assume it:

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:role/ACKCapabilityRole"
      },
      "Action": ["sts:AssumeRole", "sts:TagSession"]
    }
  ]
}
```

 **Step 2: Grant AssumeRole permission to Capability Role** 

Add permission to the Capability Role to assume the service-specific role:

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["sts:AssumeRole", "sts:TagSession"],
      "Resource": "arn:aws:iam::111122223333:role/ACK-S3-Role"
    }
  ]
}
```

 **Step 3: Create IAMRoleSelector** 

Map the IAM role to a namespace:

```
apiVersion: services.k8s.aws/v1alpha1
kind: IAMRoleSelector
metadata:
  name: s3-namespace-config
spec:
  arn: arn:aws:iam::111122223333:role/ACK-S3-Role
  namespaceSelector:
    names:
      - s3-resources
```

 **Step 4: Create resources in the mapped namespace** 

Resources in the `s3-resources` namespace automatically use the specified role:

```
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
  name: my-bucket
  namespace: s3-resources
spec:
  name: my-production-bucket
```

## Multi-account management
<a name="_multi_account_management"></a>

Use IAM Role Selectors to manage resources across multiple AWS accounts.

 **Step 1: Create cross-account IAM role** 

In the target account (444455556666), create a role that trusts the source account’s Capability Role:

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111122223333:role/ACKCapabilityRole"
      },
      "Action": ["sts:AssumeRole", "sts:TagSession"]
    }
  ]
}
```

Attach service-specific permissions to this role.

 **Step 2: Grant AssumeRole permission** 

In the source account (111122223333), allow the Capability Role to assume the target account role:

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["sts:AssumeRole", "sts:TagSession"],
      "Resource": "arn:aws:iam::444455556666:role/ACKTargetAccountRole"
    }
  ]
}
```

 **Step 3: Create IAMRoleSelector** 

Map the cross-account role to a namespace:

```
apiVersion: services.k8s.aws/v1alpha1
kind: IAMRoleSelector
metadata:
  name: production-account-config
spec:
  arn: arn:aws:iam::444455556666:role/ACKTargetAccountRole
  namespaceSelector:
    names:
      - production
```

 **Step 4: Create resources** 

Resources in the `production` namespace are created in the target account:

```
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
  name: my-bucket
  namespace: production
spec:
  name: my-cross-account-bucket
```

## Session tags
<a name="_session_tags"></a>

The EKS ACK capability automatically sets session tags on all AWS API requests. These tags enable fine-grained access control and auditing by identifying the source of each request.

### Available session tags
<a name="_available_session_tags"></a>

The following session tags are included with every AWS API call made by ACK:


| Tag Key | Description | 
| --- | --- | 
|   `eks:eks-capability-arn`   |  The ARN of the EKS capability making the request  | 
|   `eks:kubernetes-namespace`   |  The Kubernetes namespace of the resource being managed  | 
|   `eks:kubernetes-api-group`   |  The Kubernetes API group of the resource (for example, `s3.services.k8s.aws`)  | 

### Using session tags for access control
<a name="_using_session_tags_for_access_control"></a>

You can use these session tags in IAM policy conditions to restrict which resources ACK can manage. This provides an additional layer of security beyond namespace-based IAM Role Selectors.

 **Example: Restrict by namespace** 

Allow ACK to create S3 buckets only when the request originates from the `production` namespace:

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:CreateBucket",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:PrincipalTag/eks:kubernetes-namespace": "production"
        }
      }
    }
  ]
}
```

 **Example: Restrict by capability** 

Allow actions only from a specific ACK capability:

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:PrincipalTag/eks:eks-capability-arn": "arn:aws:eks:us-west-2:111122223333:capability/my-cluster/ack/my-ack"
        }
      }
    }
  ]
}
```

**Note**  
Session tags are a difference from self-managed ACK, which does not set these tags by default. This enables more granular access control with the managed capability.

## Advanced IAM Role Selector patterns
<a name="_advanced_iam_role_selector_patterns"></a>

For advanced configuration including label selectors, resource-specific role mapping, and additional examples, see [ACK IRSA Documentation](https://aws-controllers-k8s.github.io/community/docs/user-docs/irsa/).

## Next steps
<a name="_next_steps"></a>
+  [ACK concepts](ack-concepts.md) - Understand ACK concepts and resource lifecycle
+  [ACK concepts](ack-concepts.md) - Learn about resource adoption and deletion policies
+  [Security considerations for EKS Capabilities](capabilities-security.md) - Understand security best practices for capabilities

# ACK considerations for EKS
<a name="ack-considerations"></a>

This topic covers important considerations for using the EKS Capability for ACK, including IAM configuration, multi-account patterns, and integration with other EKS capabilities.

## IAM configuration patterns
<a name="_iam_configuration_patterns"></a>

The ACK capability uses an IAM Capability Role to authenticate with AWS. Choose the right IAM pattern based on your requirements.

### Simple: Single Capability Role
<a name="_simple_single_capability_role"></a>

For development, testing, or simple use cases, grant all necessary permissions directly to the Capability Role.

 **When to use**:
+ Getting started with ACK
+ Single-account deployments
+ All resources managed by one team
+ Development and testing environments

 **Example**: Add S3 and RDS permissions to your Capability Role with resource tagging conditions:

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:*"],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestedRegion": ["us-west-2", "us-east-1"]
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": ["rds:*"],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "aws:RequestedRegion": ["us-west-2", "us-east-1"]
        },
      }
    }
  ]
}
```

This example limits S3 and RDS operations to specific regions and requires RDS resources to have a `ManagedBy: ACK` tag.

### Production: IAM Role Selectors
<a name="_production_iam_role_selectors"></a>

For production environments, use IAM Role Selectors to implement least-privilege access and namespace-level isolation.

 **When to use**:
+ Production environments
+ Multi-team clusters
+ Multi-account resource management
+ Least-privilege security requirements
+ Different services need different permissions

 **Benefits**:
+ Each namespace gets only the permissions it needs
+ Team isolation - Team A cannot use Team B’s permissions
+ Easier auditing and compliance
+ Required for cross-account resource management

For detailed IAM Role Selector configuration, see [Configure ACK permissions](ack-permissions.md).

## Integration with other EKS capabilities
<a name="_integration_with_other_eks_capabilities"></a>

### GitOps with Argo CD
<a name="_gitops_with_argo_cd"></a>

Use the EKS Capability for Argo CD to deploy ACK resources from Git repositories, enabling GitOps workflows for infrastructure management.

 **Considerations**:
+ Store ACK resources alongside application manifests for end-to-end GitOps
+ Organize by environment, service, or resource type based on your team structure
+ Use Argo CD’s automated sync for continuous reconciliation
+ Enable pruning to automatically remove deleted resources
+ Consider hub-and-spoke patterns for multi-cluster infrastructure management

GitOps provides audit trails, rollback capabilities, and declarative infrastructure management. For more on Argo CD, see [Working with Argo CD](working-with-argocd.md).

### Resource composition with kro
<a name="_resource_composition_with_kro"></a>

Use the EKS Capability for kro (Kube Resource Orchestrator) to compose multiple ACK resources into higher-level abstractions and custom APIs.

 **When to use kro with ACK**:
+ Create reusable patterns for common infrastructure stacks (database \$1 backup \$1 monitoring)
+ Build self-service platforms with simplified APIs for application teams
+ Manage resource dependencies and pass values between resources (S3 bucket ARN to Lambda function)
+ Standardize infrastructure configurations across teams
+ Reduce complexity by hiding implementation details behind custom resources

 **Example patterns**:
+ Application stack: S3 bucket \$1 SQS queue \$1 notification configuration
+ Database setup: RDS instance \$1 parameter group \$1 security group \$1 secrets
+ Networking: VPC \$1 subnets \$1 route tables \$1 security groups

kro handles dependency ordering, status propagation, and lifecycle management for composed resources. For more on kro, see [kro concepts](kro-concepts.md).

## Organizing your resources
<a name="_organizing_your_resources"></a>

Organize ACK resources using Kubernetes namespaces and AWS resource tags for better management, access control, and cost tracking.

### Namespace organization
<a name="_namespace_organization"></a>

Use Kubernetes namespaces to logically separate ACK resources by environment (production, staging, development), team (platform, data, ml), or application.

 **Benefits**:
+ Namespace-scoped RBAC for access control
+ Set default regions per namespace using annotations
+ Easier resource management and cleanup
+ Logical separation aligned with organizational structure

### Resource tagging
<a name="_resource_tagging"></a>

The EKS ACK capability automatically applies default tags to all AWS resources it creates. These tags differ from self-managed ACK and provide enhanced traceability.

 **Default tags applied by the capability**:


| Tag Key | Description | 
| --- | --- | 
|   `eks:controller-version`   |  The version of the ACK controller  | 
|   `eks:kubernetes-namespace`   |  The Kubernetes namespace of the ACK resource  | 
|   `eks:kubernetes-resource-name`   |  The name of the Kubernetes resource  | 
|   `eks:kubernetes-api-group`   |  The Kubernetes API group (for example, `s3.services.k8s.aws`)  | 
|   `eks:eks-capability-arn`   |  The ARN of the EKS ACK capability  | 

**Note**  
Self-managed ACK uses different default tags: `services.k8s.aws/controller-version` and `services.k8s.aws/namespace`. The capability’s tags use the `eks:` prefix for consistency with other EKS features.

 **Additional recommended tags**:

Add custom tags for cost allocation, ownership tracking, and organizational purposes:
+ Environment (Production, Staging, Development)
+ Team or department ownership
+ Cost center for billing allocation
+ Application or service name

## Migration from other Infrastructure-as-code tools
<a name="_migration_from_other_infrastructure_as_code_tools"></a>

Many organizations are finding value in standardizing on Kubernetes beyond their workload orchestration. Migrating infrastructure and AWS resource management to ACK allows you to standardize infrastructure management using Kubernetes APIs alongside your application workloads.

 **Benefits of standardizing on Kubernetes for infrastructure**:
+  **Single source of truth**: Manage both applications and infrastructure in Kubernetes, enabling an end-to-end GitOps practice
+  **Unified tooling**: Teams use Kubernetes resources and tooling rather than learning multiple tools and frameworks
+  **Consistent reconciliation**: ACK continuously reconciles AWS resources like Kubernetes does for workloads, detecting and correcting drift compared to imperative tools
+  **Native compositions**: With kro and ACK together, reference AWS resources directly in application and resource manifests, passing connection strings and ARNs between resources
+  **Simplified operations**: One control plane for deployments, rollbacks, and observability across your entire system

ACK supports adopting existing AWS resources without recreating them, enabling zero-downtime migration from CloudFormation, Terraform, or resources external to the cluster.

 **Adopt an existing resource**:

```
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
  name: existing-bucket
  annotations:
    services.k8s.aws/adoption-policy: "adopt-or-create"
spec:
  name: my-existing-bucket-name
```

Once adopted, the resource is managed by ACK and can be updated through Kubernetes manifests. You can migrate incrementally, adopting resources as needed while maintaining existing IaC tools for other resources.

ACK also supports read-only resources. For resources managed by other teams or tools that you want to reference but not modify, combine adoption with the `retain` deletion policy and grant only read IAM permissions. This allows applications to discover shared infrastructure (VPCs, IAM roles, KMS keys) through Kubernetes APIs without risking modifications.

For more on resource adoption, see [ACK concepts](ack-concepts.md).

## Deletion policies
<a name="_deletion_policies"></a>

Deletion policies control what happens to AWS resources when you delete the corresponding Kubernetes resource. Choose the right policy based on the resource lifecycle and your operational requirements.

### Delete (default)
<a name="_delete_default"></a>

The AWS resource is deleted when you delete the Kubernetes resource. This maintains consistency between your cluster and AWS, ensuring resources don’t accumulate.

 **When to use delete**:
+ Development and testing environments where cleanup is important
+ Ephemeral resources tied to application lifecycle (test databases, temporary buckets)
+ Resources that should not outlive the application (SQS queues, ElastiCache clusters)
+ Cost optimization - automatically clean up unused resources
+ Environments managed with GitOps where resource removal from Git should delete the infrastructure

The default delete policy aligns with Kubernetes' declarative model: what’s in the cluster matches what exists in AWS.

### Retain
<a name="_retain"></a>

The AWS resource is kept when you delete the Kubernetes resource. This protects critical data and allows resources to outlive their Kubernetes representation.

 **When to use retain**:
+ Production databases with critical data that must survive cluster changes
+ Long-term storage buckets with compliance or audit requirements
+ Shared resources used by multiple applications or teams
+ Resources being migrated to different management tools
+ Disaster recovery scenarios where you want to preserve infrastructure
+ Resources with complex dependencies that require careful decommissioning

```
apiVersion: rds.services.k8s.aws/v1alpha1
kind: DBInstance
metadata:
  name: production-db
  annotations:
    services.k8s.aws/deletion-policy: "retain"
spec:
  dbInstanceIdentifier: prod-db
  # ... configuration
```

**Important**  
Retained resources continue to incur AWS costs and must be manually deleted from AWS when no longer needed. Use resource tagging to track retained resources for cleanup.

For more on deletion policies, see [ACK concepts](ack-concepts.md).

## Upstream documentation
<a name="_upstream_documentation"></a>

For detailed information on using ACK:
+  [ACK usage guide](https://aws-controllers-k8s.github.io/community/docs/user-docs/usage/) - Creating and managing resources
+  [ACK API reference](https://aws-controllers-k8s.github.io/community/reference/) - Complete API documentation for all services
+  [ACK documentation](https://aws-controllers-k8s.github.io/community/docs/) - Comprehensive user documentation

## Next steps
<a name="_next_steps"></a>
+  [Configure ACK permissions](ack-permissions.md) - Configure IAM permissions and multi-account patterns
+  [ACK concepts](ack-concepts.md) - Understand ACK concepts and resource lifecycle
+  [Troubleshoot issues with ACK capabilities](ack-troubleshooting.md) - Troubleshoot ACK issues
+  [Working with Argo CD](working-with-argocd.md) - Deploy ACK resources with GitOps
+  [kro concepts](kro-concepts.md) - Compose ACK resources into higher-level abstractions

# Troubleshoot issues with ACK capabilities
<a name="ack-troubleshooting"></a>

This topic provides troubleshooting guidance for the EKS Capability for ACK, including capability health checks, resource status verification, and IAM permission issues.

**Note**  
EKS Capabilities are fully managed and run outside your cluster. You don’t have access to controller logs or controller namespaces. Troubleshooting focuses on capability health, resource status, and IAM configuration.

## Capability is ACTIVE but resources aren’t being created
<a name="_capability_is_active_but_resources_arent_being_created"></a>

If your ACK capability shows `ACTIVE` status but resources aren’t being created in AWS, check the capability health, resource status, and IAM permissions.

 **Check capability health**:

You can view capability health and status issues in the EKS console or using the AWS CLI.

 **Console**:

1. Open the Amazon EKS console at https://console.aws.amazon.com/eks/home\$1/clusters.

1. Select your cluster name.

1. Choose the **Observability** tab.

1. Choose **Monitor cluster**.

1. Choose the **Capabilities** tab to view health and status for all capabilities.

 ** AWS CLI**:

```
# View capability status and health
aws eks describe-capability \
  --region region-code \
  --cluster-name my-cluster \
  --capability-name my-ack

# Look for issues in the health section
```

 **Common causes**:
+  **IAM permissions missing**: The Capability Role lacks permissions for the AWS service
+  **Wrong namespace**: Resources created in namespace without proper IAMRoleSelector
+  **Invalid resource spec**: Check resource status conditions for validation errors
+  **API throttling**: AWS API rate limits being hit
+  **Admission webhooks**: Admission webhooks blocking the controller from patching resource status

 **Check resource status**:

```
# Describe the resource to see conditions and events
kubectl describe bucket my-bucket -n default

# Look for status conditions
kubectl get bucket my-bucket -n default -o jsonpath='{.status.conditions}'

# View resource events
kubectl get events --field-selector involvedObject.name=my-bucket -n default
```

 **Verify IAM permissions**:

```
# View the Capability Role's policies
aws iam list-attached-role-policies --role-name my-ack-capability-role
aws iam list-role-policies --role-name my-ack-capability-role

# Get specific policy details
aws iam get-role-policy --role-name my-ack-capability-role --policy-name policy-name
```

## Resources created in AWS but not showing in Kubernetes
<a name="resources_created_in_shared_aws_but_not_showing_in_kubernetes"></a>

ACK only tracks resources it creates through Kubernetes manifests. To manage existing AWS resources with ACK, use the adoption feature.

```
apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
  name: existing-bucket
  annotations:
    services.k8s.aws/adoption-policy: "adopt-or-create"
spec:
  name: my-existing-bucket-name
```

For more on resource adoption, see [ACK concepts](ack-concepts.md).

## Cross-account resources not being created
<a name="_cross_account_resources_not_being_created"></a>

If resources aren’t being created in a target AWS account when using IAM Role Selectors, verify the trust relationship and IAMRoleSelector configuration.

 **Verify trust relationship**:

```
# Check the trust policy in the target account role
aws iam get-role --role-name cross-account-ack-role --query 'Role.AssumeRolePolicyDocument'
```

The trust policy must allow the source account’s Capability Role to assume it.

 **Confirm IAMRoleSelector configuration**:

```
# List IAMRoleSelectors (cluster-scoped)
kubectl get iamroleselector

# Describe specific selector
kubectl describe iamroleselector my-selector
```

 **Verify namespace alignment**:

IAMRoleSelectors are cluster-scoped resources but target specific namespaces. Ensure your ACK resources are in a namespace that matches the IAMRoleSelector’s namespace selector:

```
# Check resource namespace
kubectl get bucket my-cross-account-bucket -n production

# List all IAMRoleSelectors (cluster-scoped)
kubectl get iamroleselector

# Check which namespace the selector targets
kubectl get iamroleselector my-selector -o jsonpath='{.spec.namespaceSelector}'
```

 **Check IAMRoleSelected condition**:

Verify that the IAMRoleSelector was successfully matched to your resource by checking the `ACK.IAMRoleSelected` condition:

```
# Check if IAMRoleSelector was matched
kubectl get bucket my-cross-account-bucket -n production -o jsonpath='{.status.conditions[?(@.type=="ACK.IAMRoleSelected")]}'
```

If the condition is `False` or missing, the IAMRoleSelector’s namespace selector doesn’t match the resource’s namespace. Verify the selector’s `namespaceSelector` matches your resource’s namespace labels.

 **Check Capability Role permissions**:

The Capability Role needs `sts:AssumeRole` and `sts:TagSession` permissions for the target account role:

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["sts:AssumeRole", "sts:TagSession"],
      "Resource": "arn:aws:iam::[.replaceable]`444455556666`:role/[.replaceable]`cross-account-ack-role`"
    }
  ]
}
```

For detailed cross-account configuration, see [Configure ACK permissions](ack-permissions.md).

## Next steps
<a name="_next_steps"></a>
+  [ACK considerations for EKS](ack-considerations.md) - ACK considerations and best practices
+  [Configure ACK permissions](ack-permissions.md) - Configure IAM permissions and multi-account patterns
+  [ACK concepts](ack-concepts.md) - Understand ACK concepts and resource lifecycle
+  [Troubleshooting EKS Capabilities](capabilities-troubleshooting.md) - General capability troubleshooting guidance

# Comparing EKS Capability for ACK to self-managed ACK
<a name="ack-comparison"></a>

The EKS Capability for ACK provides the same functionality as self-managed ACK controllers, but with significant operational advantages. For a general comparison of EKS Capabilities vs self-managed solutions, see [EKS Capabilities considerations](capabilities-considerations.md). This topic focuses on ACK-specific differences.

## Differences from upstream ACK
<a name="_differences_from_upstream_ack"></a>

The EKS Capability for ACK is based on upstream ACK controllers but differs in IAM integration.

 **IAM Capability Role**: The capability uses a dedicated IAM role with a trust policy that allows the `capabilities.eks.amazonaws.com` service principal, not IRSA (IAM Roles for Service Accounts). You can attach IAM policies directly to the Capability Role with no need to create or annotate Kubernetes service accounts or configure OIDC providers. A best practice for production use cases is to configure service permissions using `IAMRoleSelector`. See [Configure ACK permissions](ack-permissions.md) for more details.

 **Session tags**: The managed capability automatically sets session tags on all AWS API requests, enabling fine-grained access control and auditing. Tags include `eks:eks-capability-arn`, `eks:kubernetes-namespace`, and `eks:kubernetes-api-group`. This differs from self-managed ACK, which does not set these tags by default. See [Configure ACK permissions](ack-permissions.md) for details on using session tags in IAM policies.

 **Resource tags**: The capability applies different default tags to AWS resources than self-managed ACK. The capability uses `eks:` prefixed tags (such as `eks:kubernetes-namespace`, `eks:eks-capability-arn`) instead of the `services.k8s.aws/` tags used by self-managed ACK. See [ACK considerations for EKS](ack-considerations.md) for the complete list of default resource tags.

 **Resource compatibility**: ACK custom resources work identically to upstream ACK with no changes to your ACK resource YAML files. The capability uses the same Kubernetes APIs and CRDs, so tools like `kubectl` work the same way. All GA controllers and resources from upstream ACK are supported.

For complete ACK documentation and service-specific guides, see the [ACK documentation](https://aws-controllers-k8s.github.io/community/).

## Migration path
<a name="_migration_path"></a>

You can migrate from self-managed ACK to the managed capability with zero downtime:

1. Update your self-managed ACK controller to use `kube-system` for leader election leases, for example:

   ```
   helm upgrade --install ack-s3-controller \
     oci://public.ecr.aws/aws-controllers-k8s/s3-chart \
     --namespace ack-system \
     --set leaderElection.namespace=kube-system
   ```

   This moves the controller’s lease to `kube-system`, allowing the managed capability to coordinate with it.

1. Create the ACK capability on your cluster (see [Create an ACK capability](create-ack-capability.md))

1. The managed capability recognizes existing ACK-managed AWS resources and takes over reconciliation

1. Gradually scale down or remove self-managed controller deployments:

   ```
   helm uninstall ack-s3-controller --namespace ack-system
   ```

This approach allows both controllers to coexist safely during migration. The managed capability automatically adopts resources previously managed by self-managed controllers, ensuring continuous reconciliation without conflicts.

## Next steps
<a name="_next_steps"></a>
+  [Create an ACK capability](create-ack-capability.md) - Create an ACK capability resource
+  [ACK concepts](ack-concepts.md) - Understand ACK concepts and resource lifecycle
+  [Configure ACK permissions](ack-permissions.md) - Configure IAM and permissions