AWS IAM (Identity & Access Management) service allows AWS services to interact with each other by using roles. Those roles can easily be used to give permissions to your Qovery application, container or job.
It is a secure way to give your application permissions without having to manage credentials. More than that, it rotates the token automatically.
This tutorial will show you how to add AWS IAM roles to your Qovery application, container or job.
Application requiring S3 permissions
In this first step, we will create a simple application that needs AWS permissions to access s3 buckets.
Create an application
We are going to will create a simple container, but you can use an existing one if you want (or an application or job).
Here is a simple Debian container example:
Set only 1 instance and 128MB of memory is enough for this example. Then continue until you have the
Create button, there is nothing more to setup.
Get Kubernetes namespace name
Then in this container (or any application in this environment)
Variables, search for the variable called
QOVERY_KUBERNETES_NAMESPACE_NAME and copy its value somewhere.
It is the Kubernetes namespace name where the container is located.
Configure OIDC provider
Get your Cluster OIDC provider URL
On your AWS console, go to your EKS cluster and
Overview section. Copy the
OpenID Connect provider URL:
Create an Identity provider
On your AWS console, go to
IAM service, then
Identity providers section, and
Add provider button:
- Select the
OpenID Connectprovider type
- Paste the
OpenID Connect provider URLpreviously copied to
- Click on
Get thumbprintbutton, once done the button will change to
- Click on
Configure AWS IAM roles
Create a role
Now we can create a role. In the
IAM service, go to
Roles section, and click on
Create role button.
You have to select the Trusted entity type. For this tutorial, we are going to use the
Web identity type.
Identity provider to the one you just created, and the
sts.amazonaws.com. Then click on the
Select the policy of your choice. For this example, the policy
AmazonS3ReadOnlyAccess will be used to list S3 buckets. Then click on the
To finish, set the role name and description of your choice and click on
Create role button.
Configure trusted entities
Once created, select your freshly created role, go to the
Trust relationships tab, and click on
Edit trust policy button.
Update the policy line regarding the
OIDC condition from:
kubernetes_namespace: with the namespace name (previously copied in step 1)
service_account_name: define a service account name which will be re-use later (ex:
Once done, click on the
Update policy button.
Last element to copy and save somewhere: the role
Create a service account
This step will help you on deploying a service account on your Kubernetes cluster. In case you want to do it manually on the cluster with
kubectl, you just have to push a service account like:
apiVersion: v1kind: ServiceAccountmetadata:name: $SERVICE_ACCOUNT_NAMEnamespace: $QOVERY_KUBERNETES_NAMESPACE_NAMEannotations:eks.amazonaws.com/role-arn: $AWS_ROLE_ARN
On AWS, there are several ways to authenticate to Kubernetes. To make it simple, we are going to use a dedicated IAM user, but you can select the best method for your need.
From your AWS Console, create an IAM user account, get
Access key ID and
Secret access key and save them somewhere.
Qovery helps IAM users to get quick access to the Kubernetes cluster. Simply add this user to the
Create a Lifecycle job
In the same environment than your application, create a
Lifecycle job which will be used to deploy a service account on the Kubernetes cluster:
Here a container
qoveryrd/create-sa:1.0 available on DockerHub made by Qovery is used, but you can fork this repository and update to your needs if you prefer.
Click on the
Continue button and select the
Start event because we want to deploy the service account at the environment start. Then click on the
Continue button, set the resources (128Mb is enough) and click on the
Then add the following environment variables to the
KUBERNETES_VERSION: the version of your Kubernetes cluster which will be used to download kubectl (ex: 1.23.0)
SERVICE_ACCOUNT_NAME: the name of the service account in Kubernetes (the same name you have declared for the role in the
Trusted entitiespolicy section)
AWS_ROLE_ARN: the AWS ARN role you have just created
AWS_ACCESS_KEY_ID: the AWS access key ID of the IAM user you have created (if you decided to use this authentication method)
AWS_SECRET_ACCESS_KEY: the AWS secret access key of the IAM user you have created (if you decided to use this authentication method)
Lifecycle job. Go into the
Variables tab and create a
Variable Alias on
QOVERY_CLOUD_PROVIDER_REGION, name it
AWS_DEFAULT_REGION and scope it to the
You can now run your job by clicking on the
Deploy now button. You should see the following output in your job logs:
-> Ensuring required environment variables are present-> Downloading kubectl version 1.23.0-> Generated service account:apiVersion: v1kind: ServiceAccountmetadata:name: my-s3-rolenamespace: xxxxxxannotations:eks.amazonaws.com/role-arn: arn:aws:iam::xxxxxx:role/my-s3-role-> Getting kubeconfigAdded new context arn:aws:eks:region:id:cluster/cluster-name to /root/.kube/config-> Deploying service accountserviceaccount/aws-permissions created
Set application service account
Set service account
The final step is to set this service account (pointing to the AWS role) to your application. Go into your application
Advanced settings and set the
Service account to the one you have just created:
Deploy your application with the
Deploy now button.
At this stage, the job should have been executed and the service account should be deployed on your Kubernetes cluster, and the Debian container, running.
To validate the AWS role has correctly been deployed, we can connect to the pod, and see if we have the AWS token. We will use the Qovery CLI to connect to our pod:
$ qovery shellQovery: Select organizationOrganization:✔ QoveryQovery: Select projectProject:✔ AWS roles tutorialQovery: Select environmentEnvironment:✔ aws-roleQovery: Select serviceServices:✔ debian
Now we are connected to the pod, we can check the AWS token:
$ env | grep AWSAWS_DEFAULT_REGION=us-east-2AWS_REGION=us-east-2AWS_ROLE_ARN=arn:aws:iam::xxxxxx:role/my-s3-roleAWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/tokenAWS_STS_REGIONAL_ENDPOINTS=regional
Token is here! Let's install the AWS CLI and validate the role access. We should be able to list S3 buckets:
$ apt-get update && apt-get -y install awscli$ aws s3 ls2022-09-23 06:56:38 aws-cloudtrail-logs-qovery...
It works! We have access to S3 buckets using the AWS role.
The first setup phase can be time-consuming. However, once done, applying roles to your applications is very easy and fast. You can now use roles to access any AWS service!