Skip to main content

Core Concepts

Understanding these ACK-specific concepts will help you effectively manage AWS infrastructure from Kubernetes.

Custom Resource Definitions (CRDs)​

ACK provides a one-to-one mapping between AWS resources and Kubernetes Custom Resource Definitions (CRDs). Each AWS resource type (like an S3 Bucket, DynamoDB Table, or RDS Database) has a corresponding CRD, and the CRD's fields map directly to the AWS resource's attributes.

When you install an ACK controller, it automatically registers CRDs for that service's resources:

# List all CRDs for DynamoDB
kubectl get crds | grep dynamodb

# Output:
# tables.dynamodb.services.k8s.aws
# backups.dynamodb.services.k8s.aws
# globaltables.dynamodb.services.k8s.aws

Each CRD follows this structure:

  • API Version: <service>.services.k8s.aws/<version>
  • Kind: The AWS resource type (e.g., Bucket, Table, DBInstance)
  • Spec: Your desired state - maps closely to AWS API parameters
  • Status: Current state from AWS, read-only and updated by the controller

Because each CRD represents a complete AWS resource, all attributes live in one place. An S3 Bucket CRD includes versioning, encryption, and lifecycle rules together - not as separate CRDs. An IAM Role includes policy attachments directly in its spec - there's no separate "RoleAttachment" resource.

The following examples show this in practice:

apiVersion: iam.services.k8s.aws/v1alpha1
kind: Role
metadata:
name: my-app-role
spec:
name: my-application-role
description: Role for my application
# Policy attachments - directly in the Role spec
# No separate "RoleAttachment" resource needed
policies:
- arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
- arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess
status:
ackResourceMetadata:
arn: arn:aws:iam::123456789012:role/my-application-role
roleID: AROA1234567890EXAMPLE

Controller Architecture​

ACK uses a controller-per-service model. Each AWS service (S3, DynamoDB, RDS, etc.) has its own dedicated controller that manages all resource types for that service.

Controller Architecture

Click to zoom

This architecture means you only install controllers for the services you actually use. If your application needs S3 and DynamoDB, you install just those two controllers. Each controller can be updated independently and scales based on its own workload. This design also improves security: each controller only communicates with a single AWS API endpoint and receives only the IAM permissions it needs - an S3 controller never makes DynamoDB calls and vice versa.

When you install a controller via Helm, it creates a Deployment (the controller process), the CRDs for that service, a ServiceAccount for IAM authentication, and the necessary RBAC permissions.

Reconciliation Loop​

The reconciliation loop is the heart of how ACK works. It continuously ensures your desired state matches actual state.

Reconciliation Loop

Click to zoom

The reconciliation loop triggers when:

  • You create, update, or delete a resource in Kubernetes
  • The periodic sync interval expires (default: 10 hours, configurable per controller)
  • Controller restarts

Drift Detection​

ACK automatically detects drift - when someone modifies an AWS resource outside of Kubernetes (via the AWS Console, CLI, or CloudFormation). During the next reconciliation cycle, ACK brings the resource back to the desired state defined in Kubernetes.

Example:

# Your Kubernetes manifest defines desired state
spec:
tableName: my-table
billingMode: PAY_PER_REQUEST

If someone changes the billing mode to PROVISIONED in the AWS Console, ACK will detect the drift and revert it back to PAY_PER_REQUEST during the next reconciliation. This ensures Kubernetes remains the source of truth for your infrastructure.

Status and Conditions​

Every ACK resource has a Status field that reflects the current state of the AWS resource as reported by AWS APIs. This is read-only and continuously updated by the controller.

status:
# AWS-specific state fields
tableStatus: ACTIVE
itemCount: 42
tableSizeBytes: 12345
creationDateTime: "2024-01-15T10:00:00Z"

# Standard ACK metadata
ackResourceMetadata:
arn: arn:aws:dynamodb:us-west-2:123456789012:table/my-table
ownerAccountID: "123456789012"
region: us-west-2

# Kubernetes conditions
conditions:
- type: Ready
status: "True"
lastTransitionTime: "2024-01-15T10:30:00Z"
reason: ResourceSynced
message: Resource synced successfully

ACK Resource Metadata​

Every ACK resource includes status.ackResourceMetadata with three fields that the controller populates after creating or adopting the AWS resource:

  • arn: The Amazon Resource Name, useful for referencing the resource in IAM policies or other AWS services
  • ownerAccountID: The AWS account that owns the resource
  • region: The AWS region where the resource exists

Conditions​

ACK uses standard Kubernetes conditions to communicate resource state. All ACK resources expose these conditions in their Status.Conditions field:

ConditionMeaning
ReadyTop-level condition and ACK's API contract. When Ready is True, all other conditions are in a healthy state and the resource is ready to use
ACK.ResourceSyncedResource in backend AWS service is in sync with the controller
ACK.AdoptedResource has been successfully adopted from an existing AWS resource
ACK.TerminalUnrecoverable error - spec must be updated before sync can continue (e.g., invalid arguments, create-failed state)
ACK.RecoverableRecoverable error that may resolve without updating spec (e.g., transient ServiceUnavailable, AccessDeniedException)
ACK.AdvisoryAdvisory information about the resource (e.g., attempting to modify an immutable field)
ACK.LateInitializedIndicates whether late initialization of fields is complete or in progress
ACK.ReferencesResolvedIndicates whether all AWSResourceReference fields have been resolved
ACK.IAMRoleSelectedIndicates whether an IAMRoleSelector has been selected to manage this resource

You can check conditions to understand resource health:

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

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

Authentication Model​

ACK requires two independent authorization systems:

  1. Kubernetes RBAC - Controls which Kubernetes users can read/write ACK custom resources
  2. AWS IAM - Controls which AWS APIs the controller can call

These systems are independent - the Kubernetes user making kubectl calls has no association with the IAM role used by the controller. Instead, the IAM role is attached to the controller's ServiceAccount via IRSA (IAM Roles for Service Accounts) or PodIdentity.

Authentication Model

Click to zoom

This separation allows you to:

  • Give developers access to manage specific ACK resources in Kubernetes
  • Limit AWS permissions to only what the controller needs
  • Maintain audit trails in both Kubernetes and CloudTrail

See the Permissions Overview for the complete authorization model and Configure IAM Permissions guide for setup instructions.

Spec Fields vs Annotations​

ACK distinguishes between spec fields and annotations, each serving a different purpose:

  • Spec fields declare the desired state of your AWS resource - what the resource should be
  • Annotations modify how ACK behaves when managing that resource - tweaking default operational behavior

Spec fields map directly to AWS API parameters:

spec:
tableName: my-table
billingMode: PAY_PER_REQUEST # Declares what the resource should be

Annotations change controller behavior without affecting the AWS resource:

metadata:
annotations:
services.k8s.aws/region: eu-west-1 # Use different region
services.k8s.aws/deletion-policy: retain # Keep AWS resource on delete

Annotations can tweak behavior like using a different region, enabling Force=true during deletion API calls, adopting existing resources instead of creating new ones, or managing resources across AWS accounts. They can be set on individual resources or at the namespace level for inheritance.

See the Managing Resources guides for detailed usage.

Field References​

Many ACK resources need to reference other resources or sensitive data. Instead of hardcoding values like ARNs or passwords, ACK CRDs provide special reference fields that let you point to other ACK resources or Kubernetes Secrets. This enables you to build resource dependencies while keeping sensitive data secure.

# Reference another ACK resource
apiVersion: ec2.services.k8s.aws/v1alpha1
kind: Subnet
metadata:
name: my-subnet
spec:
vpcRef:
from:
name: my-vpc # Reference a VPC resource

The controller resolves these references at reconciliation time. See the API Reference for available reference fields on each CRD.

For complex resource orchestration and dependencies, we recommend using kro (Kube Resource Orchestrator).

Release Phases​

ACK service controllers go through release phases that indicate their maturity and support level. Each controller is versioned independently using Semantic Versioning (X.Y.Z).

Preview​

Controllers in Preview are under active development.

  • May experience behavioral changes between releases, but the API remains stable
  • Major version is 0.x.x (e.g., 0.1.0, 0.2.5)
  • Bug reports are welcome via GitHub Issues

General Availability (GA)​

Controllers in GA have been tested extensively and are recommended for production use.

  • Major version is 1.x.x or higher (e.g., 1.0.0, 2.1.3)
  • Breaking changes only occur in major version increments
  • Bug reports are prioritized by the maintainer team

Deprecated​

Controllers may be Deprecated when they are scheduled for retirement.

  • Deprecation notices are published in documentation and release notes
  • Continue to receive same support level as GA during the deprecation period
  • Users should plan to migrate to alternatives before support ends
tip

Check the Service Catalog to see each controller's current release phase.

Next Steps​

Now that you understand ACK's core concepts, continue with:

Built with ♥ by AWS