Skip to main content

Granular IAM Roles

ACK supports using multiple IAM roles with fine-grained control over which role is used for different resources or namespaces. This enables scenarios like managing resources across multiple AWS accounts or using different permission sets within the same account.

Choose Your Method​

The IAM Role Selector uses a cluster-scoped CRD to dynamically map IAM roles to namespaces and resources using Kubernetes label selectors. This is the recommended method for multi-role and cross-account resource management.

Overview​

IAM Role Selector introduces the IAMRoleSelector CRD, which allows cluster administrators to:

  • Define IAM roles that ACK controllers can assume
  • Use namespace selectors (names or label selectors) to control where roles can be used
  • Optionally scope roles to specific API versions or resource kinds
  • Dynamically configure role usage without requiring resource-level annotations

Prerequisites​

  1. Source Account: The AWS account where your ACK controller runs
  2. Target Account: The AWS account where you want to create/manage resources
  3. Cross-account IAM role: A role in the target account that trusts the source account
  4. Feature enabled: IAM Role Selector must be enabled via feature flag when installing ACK

Step 1: Create Cross-Account IAM Role​

In the target account, create an IAM role that trusts the source account's controller role
# In the target account
export SOURCE_ACCOUNT_ROLE_ARN="arn:aws:iam::111111111111:role/ack-controller-role"

# Create trust policy
cat > trust-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "${SOURCE_ACCOUNT_ROLE_ARN}"
},
"Action": "sts:AssumeRole"
}
]
}
EOF

# Create the role
aws iam create-role \
--role-name ACK-CrossAccount-Target \
--assume-role-policy-document file://trust-policy.json

# Attach necessary permissions (example for S3)
aws iam attach-role-policy \
--role-name ACK-CrossAccount-Target \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess

Step 2: Grant AssumeRole Permission to Controller​

In the source account, ensure your ACK controller's IAM role can assume the target role
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::222222222222:role/ACK-CrossAccount-Target"
}
]
}

Step 3: Create IAMRoleSelector Resource​

Create an IAMRoleSelector to map the IAM role to specific namespaces or resources:

Example 1: Map role to specific namespace

apiVersion: services.k8s.aws/v1alpha1
kind: IAMRoleSelector
metadata:
name: production-account-config
spec:
arn: arn:aws:iam::222222222222:role/ACK-CrossAccount-Target
namespaceSelector:
names:
- production

Example 2: Map role using namespace labels

apiVersion: services.k8s.aws/v1alpha1
kind: IAMRoleSelector
metadata:
name: dev-team-config
spec:
arn: arn:aws:iam::222222222222:role/ACK-CrossAccount-Target
namespaceSelector:
names: [] # Empty names array required, matches no specific names
labelSelector:
matchLabels:
environment: development
team: sky-team

Example 3: Map role to specific resource types

apiVersion: services.k8s.aws/v1alpha1
kind: IAMRoleSelector
metadata:
name: s3-buckets-only
spec:
arn: arn:aws:iam::222222222222:role/ACK-CrossAccount-S3
namespaceSelector:
names:
- production
resourceTypeSelector:
- group: s3.services.k8s.aws
version: v1alpha1
kind: Bucket # Only S3 Buckets, not other S3 resources

Example 4: Cluster-wide role for all resources

apiVersion: services.k8s.aws/v1alpha1
kind: IAMRoleSelector
metadata:
name: cluster-wide-config
spec:
arn: arn:aws:iam::222222222222:role/ACK-CrossAccount-Target
# No selectors = matches all namespaces and resources

Step 4: Create Resources​

Once the IAMRoleSelector is configured, simply create resources in the matching namespace:

apiVersion: s3.services.k8s.aws/v1alpha1
kind: Bucket
metadata:
name: cross-account-bucket
namespace: production # Matches IAMRoleSelector
spec:
name: my-bucket-in-target-account

ACK will automatically use the matched IAM role when managing this resource. The resource status will show which selector was used via a condition:

status:
ackResourceMetadata:
arn: arn:aws:s3:::my-bucket-in-target-account
conditions:
- type: ACK.IAMRoleSelected
status: "True"
message: "roleARN: arn:aws:iam::222222222222:role/ACK-CrossAccount-Target, selectorName: production-account-config, selectorResourceVersion: 89424719"

Selection Logic​

  • Multiple selectors can be defined; ACK evaluates all of them for each resource
  • If exactly one IAMRoleSelector matches, that role is used
  • If no IAMRoleSelector matches, the default controller role is used
  • If multiple IAMRoleSelectors match, a conflict occurs and the resource shows an error condition

Conflict Example:

status:
conditions:
- message: |-
Cannot determine which IAMRoleSelector to use.
Conflicting IAMRoleSelectors: [production-account-config, s3-buckets-only]
status: "True"
type: ACK.Recoverable

To resolve conflicts, update or delete one of the conflicting selectors, or make them more specific.

Enabling the Feature​

IAM Role Selector must be enabled via feature flag when installing ACK:

helm install -n ack-system ack-s3-controller \
oci://public.ecr.aws/aws-controllers-k8s/s3-chart \
--set featureGates.IAMRoleSelector=true
CARM Compatibility

Enabling IAM Role Selector disables CARM. These features cannot be used together.

Troubleshooting​

Access Denied Errors​

If you see access denied errors:

  1. Verify trust policy: Ensure the target role trusts the source account's controller role
  2. Check permissions: Confirm the target role has necessary service permissions
  3. AssumeRole permission: Verify the source controller role can call sts:AssumeRole
  4. Role ARN format: Double-check the role ARN syntax

IAMRoleSelector Not Matching​

If resources aren't using the expected role:

  1. Check selectors: Verify namespace names or labels match the selector
  2. Check conflicts: Look for multiple matching selectors in resource status
  3. Feature enabled: Confirm IAMRoleSelector feature flag is set
  4. Namespace labels: Ensure label selectors match actual namespace labels

Check Controller Logs​

kubectl logs -n ack-system deployment/ack-<service>-controller | grep -i "assume"

Look for messages about role assumption failures or selector conflicts.

Best Practices​

  1. Least privilege: Grant only necessary permissions to cross-account roles
  2. External ID: Consider using external IDs for additional security
  3. Clear naming: Use descriptive names for IAMRoleSelector resources
  4. Namespace labels: Use consistent labeling for dynamic namespace selection
  5. Monitoring: Set up CloudTrail to monitor cross-account access
  6. Avoid conflicts: Design selectors to avoid overlapping resource matches

Next Steps​

Built with ♥ by AWS