Configuring OIDC Provider with AWS Account to Access S3 Bucket from a Kubernetes Pod Using AWS Management Console
Introduction
Accessing AWS resources securely from applications running in Kubernetes is a common requirement. By using AWS IAM Roles for Service Accounts (IRSA) and OpenID Connect (OIDC), you can grant fine-grained permissions to your Kubernetes pods without hardcoding AWS credentials. This guide will show you how to set up this configuration using the AWS Management Console.
Prerequisites
AWS Account with necessary permissions.
Kubernetes cluster (EKS or self-managed) with version 1.13 or later.
An existing S3 bucket or the ability to create a new one.
Access to the AWS Management Console.
kubectl is configured to manage your Kubernetes cluster.
Step 1: Set Up the OIDC Provider in the AWS Management Console
1.1 Identify the OIDC URL for Your Cluster
If you're using an Amazon EKS cluster, AWS automatically creates an OIDC provider. To find the OIDC URL:
Go to the Amazon EKS service in the AWS Management Console.
Select your cluster from the list.
In the Overview tab, find the Cluster details section. The OIDC provider URL will be listed there.
For self-managed Kubernetes clusters, you'll need to manually retrieve the OIDC URL, usually in the format https://<cluster-dns>/openid/v1/id
.
1.2 Create OIDC Identity Provider
If you're using a self-managed Kubernetes cluster, you'll need to create the OIDC provider manually:
Open the IAM service in the AWS Management Console.
In the left-hand menu, click on Identity providers under Access management.
Click on Add provider.
Select OpenID Connect as the provider type.
Enter the OIDC URL you retrieved earlier.
Add
sts.amazonaws.com
as the Audience.Click Add provider.
Step 2: Create an IAM Role with a Trust Policy
Next, you’ll create an IAM policies, role. This role will have permission to access the S3 bucket.
2.1 Create a New Policy
In the IAM service in the AWS Management Console, click Policies in the left-hand menu.
Click Create Policy.
Select Service as EKS.
Keeping in mind that your bucket is created and at least one file should be there as you can see here
- Choose the JSON Editor and Paste below Policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::Your_bucket_name"
]
}
]
}
2.2 Attach Trust Relationship to the IAM Role
Create an IAM role and attach the below policy to it.
Create a file called
trust-policy.json
Enter the below policy. (Modify accordingly)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<aws_account_id>:oidc-provider/oidc.eks.your-region.amazonaws.com/id/your-cluster-id"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.your-region.amazonaws.com/id/your-cluster-id:sub": "system:serviceaccount:default:s3-access-sa",
"oidc.eks.ap-northeast-1.amazonaws.com/id/F6929AF6CAC1605B0FB86ECA2954A0F1:aud": "sts.amazonaws.com"
}
}
}
]
}
- Create an IAM Role along with the above policy.
aws iam create-role --role-name my-eks-role --assume-role-policy-document file://trust-policy.json
- Go to IAM Roles and go to the Trust Relationships section, then you can see this.
- Attach the Policy that you created earlier.
aws iam attach-role-policy --role-name my-eks-role --policy-arn <arn_of_the_policy>
- Go to the Permissions section in the Roles then you can see that policy
Step 3: Associate IAM Role with Kubernetes Service Account
To allow the Kubernetes service account to assume the IAM role:
In the Kubernetes cluster, we will create a service account and Annotate the service account with the IAM role ARN
Create
service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: s3-access-sa # Name of the service account
namespace: default
annotations:
eks.amazonaws.com/role-arn: <arn_of_your_IAM_role>
kubectl apply -f service-account.yaml
Step 4: Deploy a Pod to Access S3
Create and deploy a pod that uses the service account associated with the IAM role.
4.1 Create a Kubernetes Deployment
Create a deployment YAML file that specifies the service account:
apiVersion: apps/v1
kind: Deployment
metadata:
name: aws-cli-deployment # Name of the deployment
namespace: default # Namespace where the deployment will be created
spec:
replicas: 1 # Number of replicas/pods
selector:
matchLabels:
app: aws-cli-app # Label selector to match pods
template:
metadata:
labels:
app: aws-cli-app # Labels for the pod
spec:
serviceAccountName: s3-access-sa # Specify the service account here
containers:
- name: aws-cli-container
image: amazon/aws-cli:latest # Container image
command: ["sleep", "3600"] # Keeps the container running for testing
Apply the deployment using kubectl
:
kubectl apply -f s3-access-deployment.yaml
4.2 Access the Pod and S3 Bucket
After the pod is running, access the pod and use the AWS CLI to interact with the S3 bucket:
kubectl exec -it <pod-name> -- bash
List the contents of the S3 bucket:
aws s3 ls s3://<bucket-name>/
Conclusion
Using the AWS Management Console, you’ve successfully configured an OIDC provider with your AWS account and set up a Kubernetes pod to securely access an S3 bucket. This method enhances security by eliminating the need for hardcoded credentials and using IAM roles tied to specific Kubernetes service accounts.
References:
https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html
https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html
https://docs.aws.amazon.com/eks/latest/userguide/pod-configuration.html
https://docs.aws.amazon.com/eks/latest/userguide/pod-id-association.html
https://docs.aws.amazon.com/eks/latest/userguide/pod-id-configure-pods.html
###
Subscribe to my newsletter
Read articles from Saurabh Adhau directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Saurabh Adhau
Saurabh Adhau
As a DevOps Engineer, I thrive in the cloud and command a vast arsenal of tools and technologies: ☁️ AWS and Azure Cloud: Where the sky is the limit, I ensure applications soar. 🔨 DevOps Toolbelt: Git, GitHub, GitLab – I master them all for smooth development workflows. 🧱 Infrastructure as Code: Terraform and Ansible sculpt infrastructure like a masterpiece. 🐳 Containerization: With Docker, I package applications for effortless deployment. 🚀 Orchestration: Kubernetes conducts my application symphonies. 🌐 Web Servers: Nginx and Apache, my trusted gatekeepers of the web.