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| Backend | Description |
|---|---|
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-2Auto-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-2Benefits 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:
- Explicit Access Keys — Credentials specified directly in
workspaceInfo.yaml - Kubernetes Secret — Credentials stored in a Kubernetes secret (via
awsSecretName) - Workload Identity — EKS IRSA or EKS Pod Identity
- Assume Role — IAM role assumption (can be combined with other methods)
- Default Credential Chain —
boto3default 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 credentialsStore 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-credentialskubectl create secret generic aws-explicit-credentials \ --from-literal=awsAccessKeyId=AKIA... \ --from-literal=awsSecretAccessKey=... \ --namespace runwhen-localMethod 2: Kubernetes Secret
Store credentials in a Kubernetes secret and reference it in your configuration:
cloudConfig: aws: region: us-east-1 awsSecretName: aws-credentialskubectl create secret generic aws-credentials \ --from-literal=awsAccessKeyId=AKIA... \ --from-literal=awsSecretAccessKey=... \ --from-literal=region=us-east-1 \ --namespace runwhen-localMethod 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: trueThis 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: v1kind: ServiceAccountmetadata: name: runwhen-local namespace: runwhen-local annotations: eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/RunWhenLocalRoleEKS 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: truePod Identity is automatically detected via the AWS_CONTAINER_CREDENTIALS_FULL_URI environment variable.
Prerequisites:
- EKS 1.24+ with Pod Identity Agent addon enabled
PodIdentityAssociationresource 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-1The default chain checks credentials in the following order:
- Environment variables (
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_SESSION_TOKEN) - Shared credentials file (
~/.aws/credentials) - AWS config file (
~/.aws/config) - Container credentials (ECS task role)
- 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 rolecloudConfig: aws: region: us-east-1 useWorkloadIdentity: true assumeRoleArn: arn:aws:iam::TARGET_ACCOUNT:role/DiscoveryRole# Kubernetes secret + assume rolecloudConfig: aws: region: us-east-1 awsSecretName: base-aws-credentials assumeRoleArn: arn:aws:iam::TARGET_ACCOUNT:role/DiscoveryRoleWhen 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):
lodlevelofdetaillevel-of-detail
Supported values:
basic— Minimal set of troubleshooting commandsdetailed— Comprehensive set of troubleshooting commands
Example AWS resource tag:
aws ec2 create-tags --resources i-1234567890abcdef0 --tags Key=lod,Value=detailedaws 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 basicLoD Resolution Order (Quick Reference)
- Namespace annotation
config.runwhen.com/lod(Kubernetes namespaces within EKS clusters) - Per-cluster
defaultNamespaceLOD/namespaceLODs(EKS clusters) - AWS resource tags (
lod/levelofdetail/level-of-detail) - Workspace-level
defaultLOD
Configuration Reference
| Field | Type | Required | Description |
|---|---|---|---|
region | string | No | AWS region (default: us-east-1) |
awsAccessKeyId | string | No | Explicit access key ID |
awsSecretAccessKey | string | No | Explicit secret access key |
awsSessionToken | string | No | Session token for temporary credentials |
awsSecretName | string | No | Name of Kubernetes secret containing credentials |
useWorkloadIdentity | boolean | No | Enable EKS Workload Identity — IRSA or Pod Identity (default: false) |
assumeRoleArn | string | No | ARN of IAM role to assume |
assumeRoleExternalId | string | No | External ID for role assumption (security best practice) |
assumeRoleSessionName | string | No | Session name for role assumption (default: runwhen-local-session) |
assumeRoleDurationSeconds | integer | No | Duration for assumed role session in seconds (default: 3600, max: 43200) |
eksClusters | object | No | EKS cluster discovery configuration |
eksClusters Configuration
| Field | Type | Required | Description |
|---|---|---|---|
autoDiscover | boolean | No | Automatically discover all EKS clusters (default: false) |
clusters | array | No | List of explicit EKS cluster configurations |
discoveryConfig | object | No | Configuration for auto-discovery (used when autoDiscover=true) |
eksClusters.clusters[] Configuration
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | EKS cluster name |
server | string | Yes | EKS cluster API server endpoint |
region | string | No | Cluster region (defaults to global aws.region) |
eksClusters.discoveryConfig Configuration
| Field | Type | Required | Description |
|---|---|---|---|
regions | array | No | List of regions to discover clusters in |
End-to-End Examples
Single Account Discovery
workspaceName: aws-production-discoveryworkspaceOwnerEmail: devops@example.comdefaultLocation: location-01defaultLOD: detailedcloudConfig: aws: region: us-east-1 awsSecretName: aws-prod-credentialscodeCollections: - repoURL: "https://github.com/runwhen-contrib/aws-c7n-codecollection" branch: "main"Multi-Account Discovery with Assume Role
workspaceName: aws-multi-accountworkspaceOwnerEmail: devops@example.comdefaultLocation: location-01cloudConfig: aws: region: us-east-1 useWorkloadIdentity: true assumeRoleArn: arn:aws:iam::987654321098:role/CrossAccountDiscoveryRole assumeRoleExternalId: secure-external-idcodeCollections: - repoURL: "https://github.com/runwhen-contrib/aws-c7n-codecollection" branch: "main"Development Environment with Local Credentials
workspaceName: aws-developmentworkspaceOwnerEmail: dev@example.comdefaultLocation: location-01cloudConfig: 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-identityworkspaceOwnerEmail: platform@example.comdefaultLocation: location-01defaultLOD: 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
- Verify credentials are valid:
aws sts get-caller-identity --region us-east-1- Check IAM permissions:
aws iam simulate-principal-policy \ --policy-source-arn arn:aws:iam::ACCOUNT:role/ROLE \ --action-names ec2:DescribeInstances s3:ListAllMyBuckets- Verify assume role trust relationships:
aws iam get-role --role-name RunWhenDiscoveryRole- Check RunWhen Local logs:
kubectl logs -n runwhen-local deployment/runwhen-local --tail=100Common 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*, andGet*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- Currently supported source plugin: AWS v23.6.0
- Available resources: See the CloudQuery tables documentation
Both backends produce the same registry shape, so generation rules and SLX templates do not change when switching.