In modern cloud-native applications, pods often need to interact with external services, such as AWS S3. To enable secure and efficient communication, we typically employ service accounts. This blog post will guide you through creating a service account and configuring your pod to leverage it for accessing AWS services.
Prerequisites:
- An EKS cluster with nodes running in AWS.
- AWS CLI installed and configured with sufficient permissions to create IAM roles and policies.
Table of Contents
Understanding Service Accounts
A service account is a special type of account within a Kubernetes cluster that pods can use to authenticate with other services. It’s analogous to a user account, but instead of representing a human user, it means a pod or a group of pods.
Step 1: Enable IAM Roles for Service Accounts on EKS
- Associate IAM OIDC Provider with Your EKS Cluster
First, verify if your EKS cluster has an IAM OIDC provider. This provider allows EKS to validate the IAM role for each pod using OpenID Connect (OIDC).
aws eks describe-cluster --name <your-cluster-name> --query "cluster.identity.oidc.issuer" --output text
If this returns an OIDC URL, your cluster is already associated with an OIDC provider. Otherwise, create one using:
aws eks update-cluster-config --name <your-cluster-name> --region <your-region> --resources-vpc-config endpointPublicAccess=true
Create the OIDC Identity Provider
eksctl utils associate-iam-oidc-provider --region <your-region> --cluster <your-cluster-name> --approve
Step 2: Create an IAM Policy for S3 Access
Next, create an IAM policy that grants necessary permissions to access S3. For example, you might need to list and read objects in an S3 bucket.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::<your-bucket-name>",
"arn:aws:s3:::<your-bucket-name>/*"
]
}
]
}
Save the above JSON to a file, say s3-access-policy.json
.
Then create the policy:
aws iam create-policy --policy-name S3AccessPolicy --policy-document file://s3-access-policy.json
Note down the ARN of the created policy, as you’ll need it to attach to the IAM role.
Step 3: Create an IAM Role for the Kubernetes Service Account
Define a Trust Relationship
This allows the Kubernetes service account to assume the IAM role. Replace <eks-cluster-id>
with the cluster’s OIDC issuer URL and <namespace>
and <service-account-name>
with the actual values you will use for the namespace and service account:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<account-id>:oidc-provider/<eks-cluster-id>"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"<eks-cluster-id>:sub": "system:serviceaccount:<namespace>:<service-account-name>"
}
}
}
]
}
Create the Role
Create the IAM role with this trust policy, and attach the S3 policy to the role.
aws iam create-role --role-name EKS_S3_Access_Role --assume-role-policy-document file://trust-policy.json
Attach the S3 Policy
aws iam attach-role-policy --role-name EKS_S3_Access_Role --policy-arn <policy-arn>
Step 4: Create a Kubernetes Service Account and Link It to the IAM Role
Create the Kubernetes Service Account
Define the service account in your cluster’s namespace. This YAML configuration links the service account with the IAM role you created.
apiVersion: v1
kind: ServiceAccount
metadata:
name: s3-access-sa
namespace: default
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<account-id>:role/EKS_S3_Access_Role
Apply the YAML configuration to create the service account:
kubectl apply -f service-account.yaml
Step 5: Update Pod Specification to Use the Service Account
Update your pod specification to use this new service account. Here’s an example pod configuration:
apiVersion: v1
kind: Pod
metadata:
name: s3-access-pod
namespace: default
spec:
serviceAccountName: s3-access-sa
containers:
- name: app-container
image: amazon/aws-cli
command: ["sh", "-c", "aws s3 ls s3://<your-bucket-name>"]
Deploy the pod, and it should inherit the permissions from the IAM role associated with the service account.
Conclusion
With the service account and secret configured, you can now use the AWS SDK within your pod’s container to interact with AWS services. For example, to use the AWS SDK for Java, you would include the necessary dependencies in your application and configure the SDK to use the environment variables.
Best Practices:
- Least Privilege Principle: Grant the service account only the necessary permissions to perform its tasks.
- Secret Rotation: Regularly rotate your AWS credentials and update the Kubernetes secret.
- Secure Communication: Use HTTPS to communicate with AWS services.
- Error Handling: Implement robust error handling and logging to identify and troubleshoot issues.
- Security Audits: Regularly review and audit your service account configurations and permissions.
By following these steps and best practices, you can securely configure your pods to access AWS services, ensuring efficient and reliable communication.