AWS Authentication via IRSA
This guide explains how to configure a Firefly self-hosted runner on EKS to authenticate with AWS using IAM Roles for Service Accounts (IRSA). With IRSA, Terraform running inside the runner can access AWS resources (state backend, provider APIs) without static credentials.
Prerequisites
1. EKS Cluster with OIDC Provider
Your EKS cluster must have an OpenID Connect (OIDC) provider configured. Verify with:
aws eks describe-cluster --name <cluster-name> \
--query "cluster.identity.oidc.issuer" --output text2. IAM Role
Create an IAM role that:
Has a trust policy allowing the Kubernetes service account to assume it via
sts:AssumeRoleWithWebIdentityHas permissions for the S3 state backend and any AWS resources Terraform will manage
Configuration
Runner Image
Update the runner to an image that includes IRSA credential forwarding. Use latest or pin a specific tag:
repository:
tag: "latest" # or a specific version tagHelm Chart
Update to the latest version of the ci-runner-worker chart:
Helm Values
Annotate the service account with the IAM role ARN:
The EKS webhook uses this annotation to automatically inject the projected token volume, volumeMounts, and AWS_ROLE_ARN / AWS_WEB_IDENTITY_TOKEN_FILE env vars into all containers in the pod. No manual volume or volumeMount configuration is required.
Workspace Variables
Set the following as environment variables on the workspace in the Firefly UI:
AWS_DEFAULT_REGION
Target AWS region (e.g. eu-west-1)
AWS_REGION
Target AWS region (e.g. eu-west-1)
Terraform Configuration
No special provider configuration is needed. The AWS SDK automatically detects the IRSA env vars and calls sts:AssumeRoleWithWebIdentity:
Cross-Account Terraform Execution with IRSA on Self-Hosted Runners
Firefly self-hosted runners support IAM Roles for Service Accounts (IRSA) for authenticating Terraform operations across multiple AWS accounts — without requiring a dedicated runner in each account.
How It Works
The setup relies on IAM role chaining, where the runner's service account role assumes a role in a target account. This is standard Terraform behavior using the S3 backend's role_arn configuration.
Configuration Steps
In the Helm chart, define the IAM role ARN (Role A) under
.Values.serviceAccount.annotations. This role must reside in the same AWS account as the Firefly runners.In
providers.tf, setterraform.backend.s3.role_arnto a role in the target AWS account (Role B).Ensure the appropriate cross-account trust is in place: Role A must have permission to assume Role B (via its IAM policy), and Role B's trust policy must allow Role A to assume it.
Once configured, terraform plan and other operations execute against the target AWS account by design — eliminating the need to deploy a runner in every account.
Limitations
EKS only. IRSA is an EKS-specific feature. This approach does not work on other Kubernetes distributions (GKE, AKS, vanilla k8s). Alternative authentication methods (static credentials via workspace variables) are needed there.
Single AWS account per runner. The IRSA role is bound to the runner's service account. All Terraform workspaces executed by that runner assume the same IAM role.
Token expiry. The projected token has a default expiration of 24 hours. Kubelet automatically refreshes it before expiry, however, long-running Terraform operations that exceed the token's remaining lifetime may fail mid-operation.
Last updated
Was this helpful?