Skip to content

Amazon Web Services

This guide explains how RunWhen Local discovers AWS resources and EKS clusters using the native AWS SDK, and how you can control discovery scope, level-of-detail (LoD), and authentication. Each configuration option is followed by a brief rationale so you can decide whether it is relevant to your environment.

RunWhen Local uses the native awsapi backend by default — AWS Cloud Control API + boto3, which removes the CloudQuery binary requirement. The legacy CloudQuery-based backend remains available as a fallback (awsIndexerBackend: cloudquery). Both backends produce the same registry shape, so generation rules and SLX templates do not change when switching.


Choosing a discovery backend

Two backends are available, selected by the top-level awsIndexerBackend key:

awsIndexerBackend: awsapi # default; use "cloudquery" for the legacy path
BackendDescription
awsapi (default)Native AWS Cloud Control API + boto3. No CloudQuery binary requirement.
cloudquery (legacy)Runs the CloudQuery AWS plugin against the configured account(s). Set awsIndexerBackend: cloudquery to opt back in.

EKS Cluster Discovery

When using AWS credentials to discover Kubernetes resources in EKS clusters, configure clusters under eksClusters in the cloudConfig.aws block. This follows the same pattern as Azure AKS and GCP GKE clusters.

Explicit configuration

List each EKS cluster explicitly when autoDiscover is false or omitted:

cloudConfig:
kubernetes: null # Do not use generic kubernetes config for EKS
aws:
region: us-east-1
useWorkloadIdentity: true # or other auth method
eksClusters:
autoDiscover: false
clusters:
- name: my-eks-cluster
server: https://ABC123.gr7.us-east-1.eks.amazonaws.com
region: us-east-1
- name: prod-eks-cluster
server: https://XYZ456.gr7.us-west-2.eks.amazonaws.com
region: us-west-2

Auto-discovery

Enable autoDiscover: true to automatically discover all EKS clusters in the configured region(s):

cloudConfig:
aws:
region: us-east-1
useWorkloadIdentity: true
eksClusters:
autoDiscover: true
discoveryConfig:
regions:
- us-east-1
- us-west-2

Benefits of auto-discovery:

  • No need to manually list each cluster
  • Automatically picks up new clusters
  • Can be combined with explicit cluster configurations
  • Useful for development/testing environments

Auto-discovery uses the configured AWS credentials to call eks:ListClusters and eks:DescribeCluster APIs in the specified regions. Ensure the IAM permissions include these actions.


AWS Resource Discovery

AWS discovery builds up an inventory of cloud resources (EC2 instances, S3 buckets, RDS databases, and more) that should be matched with troubleshooting commands. The native awsapi backend discovers at least the authenticated account; credentials can come from the ambient credential chain (instance profile / IRSA / Pod Identity), so explicit keys are not required.


Authentication

Multiple authentication methods are available. RunWhen Local evaluates authentication methods in the following priority order:

  1. Explicit Access Keys — Credentials specified directly in workspaceInfo.yaml
  2. Kubernetes Secret — Credentials stored in a Kubernetes secret (via awsSecretName)
  3. Workload Identity — EKS IRSA or EKS Pod Identity
  4. Assume Role — IAM role assumption (can be combined with other methods)
  5. Default Credential Chainboto3 default credential provider chain

For a complete implementation guide to EKS Workload Identity (IRSA / Pod Identity), see EKS Workload Identity.

Method 1: Explicit Access Keys

Provide AWS credentials directly in the workspaceInfo.yaml:

cloudConfig:
aws:
region: us-east-1
awsAccessKeyId: AKIA...
awsSecretAccessKey: ...
awsSessionToken: ... # Optional, for temporary credentials

Store credentials securely. Consider using Kubernetes secrets or IAM roles instead of embedding credentials directly in configuration files.

For codebundle access, explicit credentials should be stored in a Kubernetes secret and referenced via the custom section:

cloudConfig:
aws:
region: us-east-1
awsAccessKeyId: AKIA...
awsSecretAccessKey: ...
custom:
aws_credentials_secret_name: aws-explicit-credentials
Terminal window
kubectl create secret generic aws-explicit-credentials \
--from-literal=awsAccessKeyId=AKIA... \
--from-literal=awsSecretAccessKey=... \
--namespace runwhen-local

Method 2: Kubernetes Secret

Store credentials in a Kubernetes secret and reference it in your configuration:

cloudConfig:
aws:
region: us-east-1
awsSecretName: aws-credentials
Terminal window
kubectl create secret generic aws-credentials \
--from-literal=awsAccessKeyId=AKIA... \
--from-literal=awsSecretAccessKey=... \
--from-literal=region=us-east-1 \
--namespace runwhen-local

Method 3: Workload Identity

RunWhen Local supports two types of EKS workload identity:

IRSA (IAM Roles for Service Accounts)

For EKS clusters with IRSA configured, RunWhen Local can use the pod’s service account to authenticate:

cloudConfig:
aws:
region: us-east-1
useWorkloadIdentity: true

This method automatically uses the AWS_WEB_IDENTITY_TOKEN_FILE and AWS_ROLE_ARN environment variables injected by EKS.

Prerequisites:

  • EKS cluster with OIDC provider configured
  • Service account annotated with IAM role ARN
  • IAM role with trust relationship to the service account

Example service account annotation:

apiVersion: v1
kind: ServiceAccount
metadata:
name: runwhen-local
namespace: runwhen-local
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/RunWhenLocalRole

EKS Pod Identity

EKS Pod Identity is a newer, simpler alternative to IRSA. It’s available in EKS 1.24+ and became GA in 2024.

For EKS clusters with Pod Identity configured:

cloudConfig:
aws:
region: us-east-1
useWorkloadIdentity: true

Pod Identity is automatically detected via the AWS_CONTAINER_CREDENTIALS_FULL_URI environment variable.

Prerequisites:

  • EKS 1.24+ with Pod Identity Agent addon enabled
  • PodIdentityAssociation resource linking service account to IAM role
  • IAM role with trust policy for pods.eks.amazonaws.com

Key differences from IRSA:

  • No OIDC provider required
  • No service account annotations needed
  • Simpler IAM trust policy
  • Uses EKS Pod Identity Agent addon

Method 4: Assume Role

Assume an IAM role using credentials from any of the other authentication methods:

cloudConfig:
aws:
region: us-east-1
assumeRoleArn: arn:aws:iam::123456789012:role/RunWhenDiscoveryRole
assumeRoleExternalId: optional-external-id # Optional
assumeRoleSessionName: runwhen-local # Optional, defaults to 'runwhen-local-session'
assumeRoleDurationSeconds: 3600 # Optional, defaults to 3600 (1 hour)

This is commonly used for:

  • Cross-account access
  • Least privilege access patterns
  • Temporary credential scenarios

Method 5: Default Credential Chain

If no explicit configuration is provided, RunWhen Local uses the boto3 default credential chain:

cloudConfig:
aws:
region: us-east-1

The default chain checks credentials in the following order:

  1. Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN)
  2. Shared credentials file (~/.aws/credentials)
  3. AWS config file (~/.aws/config)
  4. Container credentials (ECS task role)
  5. Instance profile (EC2 instance role)

Combining Authentication Methods

Assume role can be combined with other authentication methods to enable cross-account access:

# Workload Identity (IRSA or Pod Identity) + assume role
cloudConfig:
aws:
region: us-east-1
useWorkloadIdentity: true
assumeRoleArn: arn:aws:iam::TARGET_ACCOUNT:role/DiscoveryRole
# Kubernetes secret + assume role
cloudConfig:
aws:
region: us-east-1
awsSecretName: base-aws-credentials
assumeRoleArn: arn:aws:iam::TARGET_ACCOUNT:role/DiscoveryRole

When using explicit credentials with assume role, the base credentials must also be available in a Kubernetes secret (referenced via custom.aws_credentials_secret_name) so that codebundles can assume the target role at runtime.


IAM Permissions

The AWS credentials used by RunWhen Local require specific IAM permissions to discover resources. At minimum, the following permissions are recommended:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"s3:List*",
"s3:GetBucket*",
"rds:Describe*",
"elasticloadbalancing:Describe*",
"cloudwatch:Describe*",
"cloudwatch:Get*",
"cloudwatch:List*",
"iam:Get*",
"iam:List*",
"eks:ListClusters",
"eks:DescribeCluster"
],
"Resource": "*"
}
]
}

For assume role scenarios, the trust policy must allow the base credentials:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::SOURCE_ACCOUNT:role/BaseRole"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "optional-external-id"
}
}
}
]
}

Level of Detail Configuration

RunWhen Local supports configuring the Level of Detail (LoD) for discovered AWS resources using AWS resource tags. This controls the granularity and number of troubleshooting commands generated for each resource.

Supported tag keys (case-insensitive):

  • lod
  • levelofdetail
  • level-of-detail

Supported values:

  • basic — Minimal set of troubleshooting commands
  • detailed — Comprehensive set of troubleshooting commands

Example AWS resource tag:

Terminal window
aws ec2 create-tags --resources i-1234567890abcdef0 --tags Key=lod,Value=detailed
aws s3api put-bucket-tagging --bucket my-bucket --tagging 'TagSet=[{Key=lod,Value=basic}]'

If no LoD tag is specified, the default value from workspaceInfo.yaml is used:

defaultLOD: detailed # or basic

LoD Resolution Order (Quick Reference)

  1. Namespace annotation config.runwhen.com/lod (Kubernetes namespaces within EKS clusters)
  2. Per-cluster defaultNamespaceLOD / namespaceLODs (EKS clusters)
  3. AWS resource tags (lod / levelofdetail / level-of-detail)
  4. Workspace-level defaultLOD

Configuration Reference

FieldTypeRequiredDescription
regionstringNoAWS region (default: us-east-1)
awsAccessKeyIdstringNoExplicit access key ID
awsSecretAccessKeystringNoExplicit secret access key
awsSessionTokenstringNoSession token for temporary credentials
awsSecretNamestringNoName of Kubernetes secret containing credentials
useWorkloadIdentitybooleanNoEnable EKS Workload Identity — IRSA or Pod Identity (default: false)
assumeRoleArnstringNoARN of IAM role to assume
assumeRoleExternalIdstringNoExternal ID for role assumption (security best practice)
assumeRoleSessionNamestringNoSession name for role assumption (default: runwhen-local-session)
assumeRoleDurationSecondsintegerNoDuration for assumed role session in seconds (default: 3600, max: 43200)
eksClustersobjectNoEKS cluster discovery configuration

eksClusters Configuration

FieldTypeRequiredDescription
autoDiscoverbooleanNoAutomatically discover all EKS clusters (default: false)
clustersarrayNoList of explicit EKS cluster configurations
discoveryConfigobjectNoConfiguration for auto-discovery (used when autoDiscover=true)

eksClusters.clusters[] Configuration

FieldTypeRequiredDescription
namestringYesEKS cluster name
serverstringYesEKS cluster API server endpoint
regionstringNoCluster region (defaults to global aws.region)

eksClusters.discoveryConfig Configuration

FieldTypeRequiredDescription
regionsarrayNoList of regions to discover clusters in

End-to-End Examples

Single Account Discovery

workspaceName: aws-production-discovery
workspaceOwnerEmail: devops@example.com
defaultLocation: location-01
defaultLOD: detailed
cloudConfig:
aws:
region: us-east-1
awsSecretName: aws-prod-credentials
codeCollections:
- repoURL: "https://github.com/runwhen-contrib/aws-c7n-codecollection"
branch: "main"

Multi-Account Discovery with Assume Role

workspaceName: aws-multi-account
workspaceOwnerEmail: devops@example.com
defaultLocation: location-01
cloudConfig:
aws:
region: us-east-1
useWorkloadIdentity: true
assumeRoleArn: arn:aws:iam::987654321098:role/CrossAccountDiscoveryRole
assumeRoleExternalId: secure-external-id
codeCollections:
- repoURL: "https://github.com/runwhen-contrib/aws-c7n-codecollection"
branch: "main"

Development Environment with Local Credentials

workspaceName: aws-development
workspaceOwnerEmail: dev@example.com
defaultLocation: location-01
cloudConfig:
aws:
region: us-west-2
# Uses default credential chain (AWS CLI profile, environment variables, etc.)
codeCollections:
- repoURL: "https://github.com/runwhen-contrib/aws-c7n-codecollection"
branch: "main"

EKS Workload Identity with Auto-Discovery

workspaceName: aws-eks-workload-identity
workspaceOwnerEmail: platform@example.com
defaultLocation: location-01
defaultLOD: detailed
cloudConfig:
kubernetes: null
aws:
region: us-east-1
useWorkloadIdentity: true
eksClusters:
autoDiscover: true
discoveryConfig:
regions:
- us-east-1
codeCollections:
- repoURL: "https://github.com/runwhen-contrib/aws-c7n-codecollection"
branch: "main"
- repoURL: "https://github.com/runwhen-contrib/rw-cli-codecollection"
branch: "main"

For a complete EKS Workload Identity implementation guide (IAM role setup, trust policies, Helm values, verification), see EKS Workload Identity.


Troubleshooting

Authentication Failures

  1. Verify credentials are valid:
Terminal window
aws sts get-caller-identity --region us-east-1
  1. Check IAM permissions:
Terminal window
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::ACCOUNT:role/ROLE \
--action-names ec2:DescribeInstances s3:ListAllMyBuckets
  1. Verify assume role trust relationships:
Terminal window
aws iam get-role --role-name RunWhenDiscoveryRole
  1. Check RunWhen Local logs:
Terminal window
kubectl logs -n runwhen-local deployment/runwhen-local --tail=100

Common Issues

Error: “Unable to locate credentials”

  • Ensure at least one authentication method is configured
  • Verify Kubernetes secrets are in the correct namespace
  • Check that environment variables are properly set

Error: “AccessDenied” or “UnauthorizedOperation”

  • Review IAM permissions for the credentials or role being used
  • Ensure the IAM policy includes necessary Describe*, List*, and Get* permissions

Error: “AssumeRole failed”

  • Verify the assume role ARN is correct
  • Check the trust policy allows the base credentials to assume the role
  • Validate the external ID matches (if used)
  • Ensure the assume role duration is within acceptable limits

Legacy CloudQuery Backend

If you need the CloudQuery backend (e.g. for resource types not yet covered by the native AWS SDK collectors), set:

awsIndexerBackend: cloudquery

Both backends produce the same registry shape, so generation rules and SLX templates do not change when switching.