> ## Documentation Index
> Fetch the complete documentation index at: https://www.qovery.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Use AWS IAM Roles with Qovery

> Grant AWS IAM permissions to applications without managing credentials

This tutorial demonstrates how to grant AWS IAM permissions to applications, containers, or jobs deployed through Qovery. This approach eliminates credential management by automatically rotating tokens through AWS's identity service.

## Prerequisites

* A Qovery cluster running on AWS EKS
* Basic knowledge of AWS IAM and Kubernetes
* Access to AWS Console and Qovery Console

## Step 1: Create an Application Requiring S3 Permissions

First, deploy a simple Debian container that will need S3 access:

* Deploy a Debian container with 1 instance and 128MB memory
* You can also use existing applications, containers, or jobs

### Get Kubernetes Namespace Name

1. Access your container variables and locate `QOVERY_KUBERNETES_NAMESPACE_NAME`
2. This value represents the namespace where the container runs

<Frame>
  <img src="https://mintcdn.com/qovery/9CNZQIdUELQe9KKR/images/aws-iam-assume-role/debian_namespace.png?fit=max&auto=format&n=9CNZQIdUELQe9KKR&q=85&s=47b5e46984f7b3a1aa6093ad51f35ee7" alt="Get Kubernetes namespace from container variables" width="2784" height="1830" data-path="images/aws-iam-assume-role/debian_namespace.png" />
</Frame>

***

## Step 2: Configure OIDC Provider

\###Get Cluster OIDC Provider URL

1. Navigate to your AWS EKS cluster Overview section
2. Copy the OpenID Connect provider URL

<Frame>
  <img src="https://mintcdn.com/qovery/8nBiaMjqzLDdT7sp/images/aws-iam-assume-role/eks_oidc.png?fit=max&auto=format&n=8nBiaMjqzLDdT7sp&q=85&s=bc32d3c8fca814ad709da3e8356561f2" alt="EKS OIDC provider URL" width="907" height="469" data-path="images/aws-iam-assume-role/eks_oidc.png" />
</Frame>

### Create Identity Provider

1. In AWS IAM, access the **Identity providers** section
2. Select **OpenID Connect** provider type
3. Paste the provider URL
4. Click **Get thumbprint**
5. Add `sts.amazonaws.com` as **Audience**
6. Create the provider

<Frame>
  <img src="https://mintcdn.com/qovery/8nBiaMjqzLDdT7sp/images/aws-iam-assume-role/oidc_connect.png?fit=max&auto=format&n=8nBiaMjqzLDdT7sp&q=85&s=8a9f25164a700c929e1f889edf394272" alt="Create OIDC identity provider" width="837" height="1105" data-path="images/aws-iam-assume-role/oidc_connect.png" />
</Frame>

***

## Step 3: Configure AWS IAM Roles

### Create a Role

1. In IAM Roles section, select **Create role**
2. Choose **Web identity** as Trusted entity type
3. Set **Identity provider** and **Audience** to `sts.amazonaws.com`

<Frame>
  <img src="https://mintcdn.com/qovery/8nBiaMjqzLDdT7sp/images/aws-iam-assume-role/role_create_step1.png?fit=max&auto=format&n=8nBiaMjqzLDdT7sp&q=85&s=61a6e1d36600c18e30f175fb84cd3f61" alt="Create IAM role step 1" width="808" height="731" data-path="images/aws-iam-assume-role/role_create_step1.png" />
</Frame>

### Add Role Permissions

1. Select the desired policy (example uses `AmazonS3ReadOnlyAccess`)
2. Set role name and description
3. Proceed to creation

### Configure Trusted Entities

<Tabs>
  <Tab title="Environment-Scoped Role">
    Update the trust policy from:

    ```json theme={null}
    "oidc.eks.eu-west-3.amazonaws.com/id/xxxxxxx:aud": "sts.amazonaws.com"
    ```

    To:

    ```json theme={null}
    "oidc.eks.eu-west-3.amazonaws.com/id/xxxxxxx:sub":
    "system:serviceaccount:kubernetes_namespace:service_account_name"
    ```

    Replace placeholders:

    * `kubernetes_namespace`: Your Qovery environment namespace
    * `service_account_name`: Define a service account name (e.g., `my-s3-role`)
  </Tab>

  <Tab title="Cluster-Scoped Role">
    For On-demand/Clone features, use `StringLike` with wildcard:

    ```json theme={null}
    "Condition": {
        "StringLike": {
            "oidc.eks.eu-west-3.amazonaws.com/id/xxxxxxx:sub":
            "system:serviceaccount:z*:service_account_name"
        }
    }
    ```

    This allows the service account to be used across all namespaces starting with `z`.
  </Tab>
</Tabs>

<Frame>
  <img src="https://mintcdn.com/qovery/8nBiaMjqzLDdT7sp/images/aws-iam-assume-role/role_trusted_entities_default.png?fit=max&auto=format&n=8nBiaMjqzLDdT7sp&q=85&s=bb77022fd74bd62c84b0716a40eb0748" alt="Configure trusted entities" width="1088" height="760" data-path="images/aws-iam-assume-role/role_trusted_entities_default.png" />
</Frame>

Save the **role ARN** for later use.

***

## Step 4: Create a Service Account

### Service Account Manifest

```yaml theme={null}
apiVersion: v1
kind: ServiceAccount
metadata:
  name: $SERVICE_ACCOUNT_NAME
  namespace: $QOVERY_KUBERNETES_NAMESPACE_NAME
  annotations:
    eks.amazonaws.com/role-arn: $AWS_ROLE_ARN
```

### Deploy with Helm

We'll use a Helm chart to deploy the service account:

**Chart Configuration:**

* Helm source: Helm repository
* Chart name: `qovery-sa-helper`
* Version: `0.1.0`

<Frame>
  <img src="https://mintcdn.com/qovery/9CNZQIdUELQe9KKR/images/aws-iam-assume-role/create_sa.png?fit=max&auto=format&n=9CNZQIdUELQe9KKR&q=85&s=47b9c607e5dc090a7badefe0a4b1b1aa" alt="Create service account" width="2784" height="1830" data-path="images/aws-iam-assume-role/create_sa.png" />
</Frame>

**Repository Details:**

1. Repository name: `Qovery Service Account Helper`
2. Kind: `HTTPS`
3. URL: `https://qovery.github.io/create_service_account/`

<Frame>
  <img src="https://mintcdn.com/qovery/9CNZQIdUELQe9KKR/images/aws-iam-assume-role/helm_sa_1.png?fit=max&auto=format&n=9CNZQIdUELQe9KKR&q=85&s=7f907415903e18795b2f2759d42fe969" alt="Helm service configuration" width="2784" height="1830" data-path="images/aws-iam-assume-role/helm_sa_1.png" />
</Frame>

<Frame>
  <img src="https://mintcdn.com/qovery/9CNZQIdUELQe9KKR/images/aws-iam-assume-role/set-helm-repo.png?fit=max&auto=format&n=9CNZQIdUELQe9KKR&q=85&s=827189d14711a5c5d97cfa433bad600c" alt="Set Helm repository" width="2784" height="1830" data-path="images/aws-iam-assume-role/set-helm-repo.png" />
</Frame>

**Override Arguments:**

1. `serviceAccount.name`: Your service account name
2. `awsRoleArn`: Your role ARN

<Frame>
  <img src="https://mintcdn.com/qovery/9CNZQIdUELQe9KKR/images/aws-iam-assume-role/helm_sa_2.png?fit=max&auto=format&n=9CNZQIdUELQe9KKR&q=85&s=0a9245c4fc3a6b5d17c63f6d36912cd6" alt="Override service account name" width="2784" height="1830" data-path="images/aws-iam-assume-role/helm_sa_2.png" />
</Frame>

<Frame>
  <img src="https://mintcdn.com/qovery/9CNZQIdUELQe9KKR/images/aws-iam-assume-role/helm_sa_3.png?fit=max&auto=format&n=9CNZQIdUELQe9KKR&q=85&s=459377fae26e57314987ddcada7b6c61" alt="Override AWS role ARN" width="3164" height="2070" data-path="images/aws-iam-assume-role/helm_sa_3.png" />
</Frame>

Deploy the Helm service and verify it completes successfully:

<Frame>
  <img src="https://mintcdn.com/qovery/9CNZQIdUELQe9KKR/images/aws-iam-assume-role/helm_sa_logs.png?fit=max&auto=format&n=9CNZQIdUELQe9KKR&q=85&s=02d3441061460f21c45c8406de2b7afc" alt="Service account creation logs" width="2784" height="1830" data-path="images/aws-iam-assume-role/helm_sa_logs.png" />
</Frame>

***

## Step 5: Set Application Service Account

### Configure Service Account

1. Access your application **Advanced settings**
2. Set **Service account** to the created service account name
3. Deploy using the **Deploy now** button

<Frame>
  <img src="https://mintcdn.com/qovery/9CNZQIdUELQe9KKR/images/aws-iam-assume-role/debian_sa.png?fit=max&auto=format&n=9CNZQIdUELQe9KKR&q=85&s=68fbd70d19e4bda9e768e4ac79cb019a" alt="Set service account on application" width="2784" height="1830" data-path="images/aws-iam-assume-role/debian_sa.png" />
</Frame>

### Validate Access

Using Qovery CLI:

```bash theme={null}
$ qovery shell
```

Check AWS environment variables:

```bash theme={null}
$ env | grep AWS
AWS_DEFAULT_REGION=us-east-2
AWS_REGION=us-east-2
AWS_ROLE_ARN=arn:aws:iam::xxxxxx:role/my-s3-role
AWS_WEB_IDENTITY_TOKEN_FILE=/var/run/secrets/eks.amazonaws.com/serviceaccount/token
AWS_STS_REGIONAL_ENDPOINTS=regional
```

Validate S3 access:

```bash theme={null}
$ apt-get update && apt-get -y install awscli
$ aws s3 ls
```

***

## Key Concepts

* **OIDC Integration**: Enables Kubernetes service accounts to assume AWS roles
* **Token Rotation**: Automatic credential rotation without manual management
* **Namespace Scoping**: Restricts role access to specific Kubernetes namespaces
* **Cluster-Wide Availability**: Service accounts accessible by all applications in the same namespace

## Conclusion

Initial setup requires multiple configuration steps across AWS and Kubernetes. Once configured, applying roles to applications becomes straightforward, enabling secure access to AWS services without credential management overhead.

***

## Related Documentation

<CardGroup cols={2}>
  <Card title="AWS EKS Integration" icon="https://mintcdn.com/qovery/Nvnl0g5BHzA0XQmy/images/logos/cloud-providers/aws-icon.svg?fit=max&auto=format&n=Nvnl0g5BHzA0XQmy&q=85&s=12ef689645255696bfa4054d6e3aeaff" href="/configuration/integrations/kubernetes/eks/overview" width="24" height="24" data-path="images/logos/cloud-providers/aws-icon.svg">
    Learn about EKS cluster management
  </Card>

  <Card title="Advanced Settings" icon="sliders" href="/configuration/service-advanced-settings">
    Configure service advanced settings
  </Card>

  <Card title="Environment Variables" icon="key" href="/configuration/environment-variables">
    Manage environment variables and secrets
  </Card>

  <Card title="Helm Services" icon="https://mintcdn.com/qovery/Nvnl0g5BHzA0XQmy/images/logos/helm-icon.svg?fit=max&auto=format&n=Nvnl0g5BHzA0XQmy&q=85&s=f6c259d3ee3123f80e74bcb99c9f6f1d" href="/configuration/helm" width="24" height="24" data-path="images/logos/helm-icon.svg">
    Deploy applications with Helm
  </Card>
</CardGroup>
