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

# AWS Deployment Guide

# Dify Enterprise Edition Deployment Guide (AWS)

To ensure a smooth deployment of Dify Enterprise Edition, please follow the infrastructure and configuration instructions below.

***

## Notes

**‼️ Please make sure you have upgraded to version 2.8.0 and completed the migration.**‼️

## 1. Infrastructure Requirements

### Required AWS Services:

* **S3**
* **ECR**

### Supported Authentication Methods:

Dify supports the following two approaches for accessing AWS services:

* **Access Key Mode (AK/SK):** Provide credentials via environment variables
* **IRSA Mode:** IAM Roles for Service Accounts to enable secure and fine-grained access control

***

## 2. Access Key Mode

### Step 1: Prepare Credentials

Create an IAM user with only **S3** and **ECR** permissions. Obtain its Access Key and Secret Key.

### Step 2: Create Kubernetes Secret

```bash theme={null}
kubectl create secret generic image-repo-secret --from-file=<path to .aws/credentials>
```

### Step 3: Update `values.yaml`

```yaml theme={null}
persistence:
  type: "s3"
  s3:
    endpoint: "https://s3.{region_code}.amazonaws.com"
    region: "{region_code}"
    bucketName: "your_bucket_name"
    useAwsS3: true
    useAwsManagedIam: false
    accessKey: "{your access key}"
    secretKey: "{your secret key}"

plugin_daemon:
  enabled: true
  replicas: 1
  apiKey: "dify123456"

plugin_connector:
  apiKey: "dify123456"
  imageRepoSecret: "image-repo-secret"
  imageRepoPrefix: "{account_id}.dkr.ecr.{region}.amazonaws.com/dify-ee"
  imageRepoType: ecr
  ecrRegion: "us-west-2"
```

### Step 4: Configure Plugin Daemon Database

```yaml theme={null}
externalPostgres:
  enabled: true
  address: "rds_address"
  port: "5432"
  credentials:
    plugin_daemon:
      database: "dify_plugin_daemon"
      username: "{user}"
      password: "{password}"
      sslmode: "disable"
    audit:
      database: "audit"
      username: "{user}"
      password: "{password}"
      sslmode: "disable"
```

### Step 5: Upgrade Helm Release

```bash theme={null}
helm upgrade dify dify/dify-ee -n default --version 3.0.0-beta
```

***

## 3. IRSA Mode

Since Access Keys are strictly controlled in enterprise environments, we recommend using AWS Pod Identity (IRSA) for access.

### ✅ Benefits

* Follows AWS security best practices
* Enables fine-grained control over plugin execution environments

### Setup

#### Step 1: Set up IAM role and Service Account

* ##### **Prerequisites**

  * An available AWS Region and EKS cluster.
  * An existing S3 bucket for Dify file storage.
  * `kubectl` is installed and configured locally, and can access the target EKS cluster.
  * AWS CLI is installed and credentials are configured locally.

##### 🚀Option A: Run One-Click Script

​	**‼️The one-click script is for demo and testing purposes only. Please develop your own script to meet your security requirements. You 	can obtain this demo script from the Dify FDE team.**

```
./irsa_one_click.sh
```

##### 🔨Option B: Manually setup

1. **Enable the IAM OIDC provider for your EKS cluster**

   Follow the [official AWS documentation](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html) to associate your EKS cluster with an OIDC identity provider. This step is required before you can use IAM Roles for Service Accounts (IRSA).

2. **Setup IAM Policy**

   | **Item**        | **Example Naming**                                 | **Description**                                       |
   | --------------- | -------------------------------------------------- | ----------------------------------------------------- |
   | S3 Policy Name  | `dify-ee-irsa-<cluster_name>-s3-policy`            | Full access to the specified S3 bucket                |
   | ECR Policy Name | `dify-ee-irsa-<cluster_name>-ecr-policy`           | Full access to ECR and read-only access to CloudTrail |
   | ECR Policy Name | `dify-ee-irsa-<cluster_name>-ecr-pull-only-policy` | Allows pull-only operations from ECR                  |

3. **Setup Role with policy**

   | Item                     | **Example Naming**                          | policy                                                                           |
   | ------------------------ | ------------------------------------------- | -------------------------------------------------------------------------------- |
   | IAM Role - S3            | `DifyEE-Role-<cluster_name>-s3`             | `dify-ee-irsa-<cluster_name>-s3-policy`                                          |
   | IAM Role - S3 + ECR      | `DifyEE-Role-<cluster_name>-s3-ecr`         | `dify-ee-irsa-<cluster_name>-s3-policy` `dify-ee-irsa-<cluster_name>-ecr-policy` |
   | IAM Role - ECR Pull-only | `DifyEE-Role-<cluster_name>-ecr-image-pull` | `dify-ee-irsa-<cluster_name>-ecr-pull-only-policy`                               |

4. **Setup ServiceAccount with IAM Role**

   | Purpose                   | Default Name            | Bound IAM Role                              | Description                                        |
   | ------------------------- | ----------------------- | ------------------------------------------- | -------------------------------------------------- |
   | For dify-api, dify-worker | `dify-api-sa`           | `DifyEE-Role-<cluster_name>-s3`             | Backend services access S3 for file uploads etc.   |
   | For dify-plugin-crd build | `dify-plugin-crd-sa`    | `DifyEE-Role-<cluster_name>-s3-ecr`         | Accesses S3 and operates plugin image repositories |
   | For dify-plugin runtime   | `dify-plugin-runner-sa` | `DifyEE-Role-<cluster_name>-ecr-image-pull` | Pulls plugin images for running plugins            |

#### Step 2: Set Environment Variables

Configure environment variables as per the release notes (e.g., `S3_REGION`, `S3_BUCKET_NAME`).

#### Step 3: Update `values.yaml`

```yaml theme={null}
persistence:
  type: "s3"
  s3:
    endpoint: "https://s3.{region_code}.amazonaws.com"
    region: "{region_code}"
    bucketName: "your_bucket_name"
    useAwsS3: true
    useAwsManagedIam: true

api:
  enabled: true
  replicas: 1
  innerApi:
    enabled: true
    apiKey: "dify123456"
  serverWorkerAmount: 1
  serviceAccountName: "dify-api-sa"

worker:
  enabled: true
  replicas: 1
  serviceAccountName: "dify-api-sa"

plugin_daemon:
  enabled: true
  replicas: 1
  apiKey: "dify123456"

plugin_connector:
  apiKey: "dify123456"
  customServiceAccount: "dify-plugin-build-sa"
  runnerServiceAccount: "dify-plugin-build-run-sa"
  imageRepoPrefix: "{account_id}.dkr.ecr.{region}.amazonaws.com/dify-ee"
  imageRepoType: ecr
  ecrRegion: "us-west-2"
```

#### Step 4: Add Plugin Daemon Database Configuration

```yaml theme={null}
externalPostgres:
  enabled: true
  address: "rds_address"
  port: "5432"
  credentials:
    plugin_daemon:
      database: "dify_plugin_daemon"
      username: "{user}"
      password: "{password}"
      sslmode: "disable"
    audit:
      database: "audit"
      username: "{user}"
      password: "{password}"
      sslmode: "disable"
```

#### Step 5: Follow the release note to Upgrade (Install)

[https://langgenius.github.io/dify-helm/#/pages/3\_0\_0](https://langgenius.github.io/dify-helm/#/pages/3_0_0)

#### **Step 6: Add S3 Permissions to the Custom ServiceAccount for the Application**

ServiceAccount name: `dify-plugin-connector-sa`

```bash theme={null}
kubesctl annotate serviceaccount -n {namespace} dify-plugin-connector-sa eks.amazonaws.com/role-arn={arn_of_IAM_S3}
```

If you used `./irsa_one_click.sh` to create the S3 read/write role, this ARN will appear at the end of the script execution.

#### **Step 7: Restart the Dify Daemon Pod**

```bash theme={null}
kubectl delete pod {dify-plugin-daemon_name}
```

***

## Notes

* ❌ **Redis cluster mode is not supported**
* 🌐 EKS nodes must have internet access or be behind a NAT gateway

***
