AWS Provider Authentication with EKS Pod Identity¶
This document explains how to authenticate one or more AWS Crossplane providers deployed in an EKS cluster against the same account.
- We assume crossplane is installed in an EKS cluster with the Pod Identity Agent addon and in the crossplane-system namespace
- The role will be crossplane-provider-aws
- We will use the provider-aws service account to authenticate
- We will use namespace managed resources
IAM Role¶
Create a role for crossplane called crossplane-provider-aws, for example.
- With the following trust policy
- With the desired policies depending of what permissions we want to give to crossplane
Some examples you can adapt and review
| Policy name | What manages |
|---|---|
| crossplane-eks | Pod Identity Associations |
| crossplane-iam | Iam policies, roles and attachments |
| crossplane-ec2 | Security Groups and rules |
| crossplane-route53 | Route53 Zones |
| crossplane-efs | Filesystems, Targets and Access Points |
| crossplane-s3 | S3 Bucket creation, deletion and read-only configuration |
| crossplane-secretsmanager | Secrets Manager secrets |
Add the Pod identity agent¶
Go to the eks cluster - Access Tab - Pod Identity associations section and add a pod identity association
IAM role: crossplane-provider-aws
Kubernetes namespace: crossplane-system
Kubernetes service account: the service account specified in the DeploymentRuntimeConfig
Crossplane Configuration¶
The following ProviderConfig in the crossplane-system declares pod identity authentication
apiVersion: aws.m.upbound.io/v1beta1
kind: ProviderConfig
metadata:
name: podidentity
namespace: crossplane-system
spec:
credentials:
source: PodIdentity
Lets create a DeploymentRuntimeConfig that will use the provider-aws service account to authenticate. It must include
apiVersion: pkg.crossplane.io/v1beta1
kind: DeploymentRuntimeConfig
metadata:
name: provider-aws
namespace: crossplane-system
spec:
serviceAccountTemplate:
metadata:
name: provider-aws
Finally ensure your AWS crossplane providers include that DeploymentRuntimeConfig. For example:
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: upbound-provider-aws-ec2
namespace: crossplane-system
spec:
package: xpkg.crossplane.io/crossplane-contrib/provider-aws-ec2:v2.5.0
runtimeConfigRef:
name: provider-aws
How Authentication Works¶
EKS Pod Identity operates at the pod level, not the namespace level. The Pod
Identity Agent injects short-lived AWS credentials into the provider pod via
environment variables (AWS_CONTAINER_CREDENTIALS_FULL_URI,
AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE). The provider pod holds a ClusterRole
allowing it to reconcile managed resources across all namespaces — AWS auth is
entirely a concern of the pod in crossplane-system.
ProviderConfig with source: PodIdentity is a configuration pointer, not a
credential store. In Crossplane v2, the controller looks up the ProviderConfig
in the same namespace as the managed resource — a ProviderConfig in
crossplane-system is invisible to resources in other namespaces, hence the need
to copy it.
Deploying to Another Namespace¶
Copy the ProviderConfig into every namespace that will contain managed resources.
No additional IAM roles, Pod Identity Associations, ServiceAccounts, or RBAC are
required — the actual credential exchange still happens entirely within the provider
pod in crossplane-system:
apiVersion: pkg.crossplane.io/v1beta1
kind: DeploymentRuntimeConfig
metadata:
name: provider-aws
namespace: mynamespace
spec:
serviceAccountTemplate:
metadata:
name: provider-aws