Skip to main content

AWSProvider

The AWSProvider resource configures AWS credentials and settings that other resources use to interact with AWS.

Overview

Every AWS resource managed by Infra Operator must reference an AWSProvider. The provider handles:

  • AWS credentials (static or IRSA)
  • Region configuration
  • Custom endpoint (for LocalStack testing)
  • Default tags applied to all resources

Quick Start

Example:

apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: AWSProvider
metadata:
name: aws-production
namespace: infra-operator
spec:
region: us-east-1
# IRSA: No credentials needed, uses ServiceAccount annotations
defaultTags:
ManagedBy: infra-operator
Environment: production

Using Static Credentials

Example:

apiVersion: v1
kind: Secret
metadata:
name: aws-credentials
namespace: infra-operator
type: Opaque
stringData:
AWS_ACCESS_KEY_ID: "AKIAIOSFODNN7EXAMPLE"
AWS_SECRET_ACCESS_KEY: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
---
apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: AWSProvider
metadata:
name: aws-production
namespace: infra-operator
spec:
region: us-east-1
credentialsSecret:
name: aws-credentials
namespace: infra-operator
defaultTags:
ManagedBy: infra-operator

Using LocalStack (Development/Testing)

Example:

apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: AWSProvider
metadata:
name: localstack
namespace: infra-operator
spec:
region: us-east-1
endpoint: http://localstack.default.svc.cluster.local:4566
credentialsSecret:
name: aws-credentials
namespace: infra-operator
defaultTags:
ManagedBy: infra-operator
Environment: localstack

Specification

Required Fields

FieldTypeDescription
spec.regionstringAWS region (e.g., us-east-1, eu-west-1)

Optional Fields

FieldTypeDefaultDescription
spec.credentialsSecretobject-Reference to Secret with AWS credentials
spec.endpointstring-Custom AWS endpoint (for LocalStack)
spec.roleARNstring-IAM Role ARN for cross-account access
spec.defaultTagsobject-Tags applied to all resources

CredentialsSecret

Example:

spec:
credentialsSecret:
name: aws-credentials # Secret name
namespace: infra-operator # Secret namespace

The Secret must contain:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY

Optionally:

  • AWS_SESSION_TOKEN (for temporary credentials)

Status Fields

FieldTypeDescription
status.readybooleanProvider is configured and ready
status.accountIDstringAWS Account ID
status.regionstringConfigured AWS region
status.lastSyncTimestringLast successful AWS API call

IRSA Configuration

For production EKS deployments, use IRSA (IAM Roles for Service Accounts):

1. Create IAM Role

Command:

# Get OIDC Provider
export CLUSTER_NAME=my-cluster
export AWS_REGION=us-east-1
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)

OIDC_PROVIDER=$(aws eks describe-cluster \
--name $CLUSTER_NAME \
--region $AWS_REGION \
--query "cluster.identity.oidc.issuer" \
--output text | sed -e "s/^https:\/\///")

# Create trust policy
cat > trust-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::${AWS_ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"${OIDC_PROVIDER}:sub": "system:serviceaccount:infra-operator:infra-operator",
"${OIDC_PROVIDER}:aud": "sts.amazonaws.com"
}
}
}
]
}
EOF

# Create role
aws iam create-role \
--role-name infra-operator-role \
--assume-role-policy-document file://trust-policy.json

2. Attach Policies

Command:

# Attach managed policies or create custom ones
aws iam attach-role-policy \
--role-name infra-operator-role \
--policy-arn arn:aws:iam::aws:policy/AmazonVPCFullAccess

aws iam attach-role-policy \
--role-name infra-operator-role \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess

# Add more policies as needed for your resources

3. Annotate ServiceAccount

Command:

kubectl annotate serviceaccount infra-operator \
-n infra-operator \
eks.amazonaws.com/role-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:role/infra-operator-role

Multi-Account Setup

For managing resources across multiple AWS accounts:

Example:

# Account A (Primary)
apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: AWSProvider
metadata:
name: account-a
spec:
region: us-east-1
credentialsSecret:
name: account-a-credentials
---
# Account B (Secondary)
apiVersion: aws-infra-operator.runner.codes/v1alpha1
kind: AWSProvider
metadata:
name: account-b
spec:
region: us-east-1
roleARN: arn:aws:iam::222222222222:role/infra-operator-cross-account
credentialsSecret:
name: account-a-credentials # Use primary credentials to assume role

Best Practices

Best Practices
  • Use IRSA in production — Never use static credentials in production, leverage IAM Roles for Service Accounts
  • Apply least-privilege IAM policies — Only grant permissions that the operator actually needs
  • Rotate credentials regularly — If using static credentials, implement regular rotation
  • Use separate providers per environment — Keep dev/staging/prod isolated with different providers
  • One provider per AWS account/region — Use descriptive names like aws-prod-us-east-1, aws-dev-eu-west-1
  • Apply consistent default tags — Set ManagedBy, Environment tags at provider level for all resources

Troubleshooting

Provider Not Ready

Command:

# Check provider status
kubectl describe awsprovider aws-production

# Check operator logs
kubectl logs -n infra-operator deploy/infra-operator --tail=100

# Verify credentials Secret exists
kubectl get secret aws-credentials -n infra-operator

Invalid Credentials

Command:

# Test credentials manually
export AWS_ACCESS_KEY_ID=$(kubectl get secret aws-credentials -n infra-operator -o jsonpath='{.data.AWS_ACCESS_KEY_ID}' | base64 -d)
export AWS_SECRET_ACCESS_KEY=$(kubectl get secret aws-credentials -n infra-operator -o jsonpath='{.data.AWS_SECRET_ACCESS_KEY}' | base64 -d)

aws sts get-caller-identity

IRSA Not Working

Command:

# Check ServiceAccount annotations
kubectl get sa infra-operator -n infra-operator -o yaml

# Verify OIDC provider is configured
aws eks describe-cluster --name $CLUSTER_NAME --query "cluster.identity.oidc"

# Check IAM role trust policy
aws iam get-role --role-name infra-operator-role --query "Role.AssumeRolePolicyDocument"