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.
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
Session object. This
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:
AWS_PROFILEenvironment variable is set, find that specified profile in the configured credentials file and use that profile’s credentials.
AWS_SECRET_ACCESS_KEYenvironment variables are both set, these values are used by
aws-sdk-goto set the AWS credentials.
AWS_WEB_IDENTITY_TOKEN_FILEenvironment variable is set,
aws-sdk-gowill 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/tokenby 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_FILEenvironment variable (or
aws-sdk-gowill load the “default” profile present in the credentials file.
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
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
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
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_SECRET_ACCESS_KEY and optionally the
variables on the ACK service controller’s
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"