Authentication and Credentials
Understanding AWS credentials in ACK
When an ACK service controller communicates with an AWS service API, the controller uses a set of AWS Credentials.
This document explains the process by which these credentials are determined by the ACK service controller and how ACK users can configure the ACK service controller to use a particular set of credentials.
Background
Each ACK service controller uses the aws-sdk-go
library to call
the AWS service APIs.
When initiating communication with an AWS service API, the ACK controller
creates a new aws-sdk-go
Session
object. This Session
object is automatically configured during construction by code in the
aws-sdk-go
library that looks for credential information in the
following places, in this specific order:
If the
AWS_PROFILE
environment variable is set, find that specified profile in the configured credentials file and use that profile’s credentials.If the
AWS_ACCESS_KEY_ID
andAWS_SECRET_ACCESS_KEY
environment variables are both set, these values are used byaws-sdk-go
to set the AWS credentials.If the
AWS_WEB_IDENTITY_TOKEN_FILE
environment variable is set,aws-sdk-go
will load the credentials from the JSON web token (JWT) present in the file pointed to by this environment variable. Note that this environment variable is set to the value/var/run/secrets/eks.amazonaws.com/serviceaccount/token
by the IAM Roles for Service Accounts (IRSA) pod identity webhook and the contents of this file are automatically rotated by the webhook with temporary credentials.If there is a credentials file present at the location specified in the
AWS_SHARED_CREDENTIALS_FILE
environment variable (or$HOME/.aws/credentials
if empty),aws-sdk-go
will load the “default” profile present in the credentials file.
Configuring credentials
There are multiple ways in which you can configure an ACK service controller to use a particular set of AWS credentials:
- Web identity token file (recommended)
- Shared credentials file
- Access key and secret access key environment variables (not recommended)
Use a web identity token file (recommended)
Our recommended approach for configuring the AWS credentials that an ACK service controller will use to communicate with AWS services is to use the IAM Roles for Service Accounts (IRSA) functionality provided by the IAM Pod Identity Webhook and OIDC connector.
Using IRSA means that you only need to configure the IAM Role that is associated with the Kubernetes Service Account of the ACK service controller’s Kubernetes Pod. The Pod Identity Webhook will be responsible for automatically injecting and periodically rotating the web identity token file into your ACK service controller’s Pod.
Learn how to configure IRSA.
Use a shared credentials file
If you are not using IAM Roles for Service Accounts (IRSA) or are running in an environment where IRSA isn’t feasible (such as running KinD clusters within Kubernetes Pods using Docker-in-Docker), you can choose to instruct the ACK service controller to use AWS credentials found in a shared credentials file.
When using a shared credentials file, the ACK service controller will need read access to a known credentials file location.
If you do not set the AWS_SHARED_CREDENTIALS_FILE
environment variable, the
controller will look for a readable file at $HOME/.aws/credentials
.
Practically, this means that the Deployment
spec you use to deploy the ACK
service controller should have a volume mount that mounts a
readonly file containing the credentials file.
Let’s assume you have stored your local AWS credentials file content in a
Kubernetes Secret
named aws-creds
:
CREDS_CONTENT=$(cat ~/.aws/credentials)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: aws-creds
type: Opaque
stringData:
credentials-file: |
$CREDS_CONTENT
EOF
You would want to mount a readonly volume into the Deployment
for your ACK
service controller. Here’s how you might do this for a sample ACK controller:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ack-s3-controller
spec:
replicas: 1
template:
spec:
containers:
- command:
- ./bin/controller
image: controller:latest
name: controller
ports:
- name: http
containerPort: 8080
resources:
limits:
cpu: 100m
memory: 300Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: aws-creds
mountPath: "/root/.aws/credentials"
readOnly: true
volumes:
- name: aws-creds
secret:
secretName: aws-creds
You can instruct the service controller to use a specific profile within the
shared credentials file by setting the AWS_PROFILE
environment variable for
the Pod
:
env:
- name: AWS_PROFILE
value: my-profile
Use access key and secret access key environment variables (not recommended)
Finally, you can choose to manually set the AWS_ACCESS_KEY_ID
,
AWS_SECRET_ACCESS_KEY
and optionally the AWS_SESSION_TOKEN
environment
variables on the ACK service controller’s Pod
:
kubectl -n ack-system set env deployment/ack-s3-controller \
AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID" \
AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" \
AWS_SESSION_TOKEN="$AWS_SESSION_TOKEN"