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

# AWS Database Connections

Learn how to configure secure connections to AWS-managed databases using IAM authentication, Secrets Manager, and best practices for production deployments.

## Prerequisites: IAM Role Setup

Use attached IAM roles for secure, key-free authentication on EC2 instances. This eliminates the need to manage access keys.

References: [IAM roles for EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html) | [IAM best practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) | [Using instance profiles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-ec2_instance-profiles.html)

### Create IAM Role

1. Go to [IAM Console → Roles](https://console.aws.amazon.com/iam/home#/roles)
2. Click **Create role**
3. Select trusted entity type: **AWS service** → **EC2**
4. Attach policies as needed:
   * For RDS IAM authentication - see [RDS/Aurora section](#rdsaurora-with-iam-authentication)
   * For Secrets Manager access - see [AWS Secrets Manager section](#aws-secrets-manager)
5. Name the role: `bytebase-instance-role`

### Attach IAM Role to EC2

**New EC2 Instance:**

1. Launch instance in [EC2 Console](https://console.aws.amazon.com/ec2/)
2. In **Advanced details** → **IAM instance profile**: Select `bytebase-instance-role`

**Existing EC2 Instance:**

1. Select instance → **Actions** → **Security** → **Modify IAM role**
2. Select `bytebase-instance-role` → **Update IAM role**

Deploy Bytebase on your EC2 instance - credentials are provided automatically through the instance metadata service.

### Alternative: IAM User with Access Keys

<Warning>
  Use only when running Bytebase outside AWS. See [why to use IAM roles instead of access keys](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html#access-keys-alternatives).
</Warning>

1. Create an IAM user with required policies
2. Generate access keys
3. Set environment variables:
   ```bash theme={null}
   -e AWS_ACCESS_KEY_ID=xxx
   -e AWS_SECRET_ACCESS_KEY=yyy
   -e AWS_REGION=us-east-1
   ```

Reference: [Managing access keys](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)

## RDS/Aurora with IAM Authentication

<Note>
  Prerequisites: [IAM role](#prerequisites-iam-role-setup) with RDS connect permissions.
</Note>

References: [IAM database authentication](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html) | [Connecting with IAM](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.Connecting.html)

### Step 1: Configure RDS/Aurora Instance

1. In [RDS Console](https://console.aws.amazon.com/rds/), modify your instance
2. Enable **IAM database authentication** under Database authentication options
3. Save changes (SSL is enabled by default)

Reference: [Enabling IAM authentication](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.Enabling.html)

### Step 2: Grant Database Connect Permission

Add this policy to your IAM role to allow RDS IAM authentication:

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "rds-db:connect",
      "Resource": "arn:aws:rds-db:REGION:ACCOUNT_ID:dbuser:DB_RESOURCE_ID/bytebase"
    }
  ]
}
```

Replace `REGION`, `ACCOUNT_ID`, and `DB_RESOURCE_ID` with your values. Find DB\_RESOURCE\_ID in RDS console → Configuration tab. For easier setup, you can use wildcards: `arn:aws:rds-db:*:*:dbuser:*/*`

Reference: [IAM policy examples](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html)

### Step 3: Create Database User

**MySQL/Aurora MySQL:**

```sql theme={null}
CREATE USER 'bytebase'@'%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
ALTER USER 'bytebase'@'%' REQUIRE SSL;
GRANT ALL PRIVILEGES ON *.* TO 'bytebase'@'%';
```

**PostgreSQL/Aurora PostgreSQL:**

```sql theme={null}
CREATE USER bytebase;
GRANT rds_iam TO bytebase;
-- Grant appropriate permissions
```

References: [MySQL](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.DBAccounts.html#UsingWithRDS.IAMDBAuth.DBAccounts.MySQL) | [PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.DBAccounts.html#UsingWithRDS.IAMDBAuth.DBAccounts.PostgreSQL)

### Step 4: Connect from Bytebase

1. Click **New Instance** in Bytebase

2. Configure basic connection:
   * **Host:** Your RDS endpoint
   * **Port:** 3306 (MySQL) or 5432 (PostgreSQL)
   * **Username:** `bytebase`
   * **Authentication:** Select `AWS RDS IAM`

3. Configure AWS credentials:
   * **Credential Source:** Select **Default** (recommended for same-account connections)
     * Automatically uses EC2 instance profile or environment variables
     * **Database Region:** Select your RDS region (e.g., `us-east-1`)
     * **Database:** Your database name

4. Test and save the connection

<Info>
  For same-account connections on EC2, always use **Default** credential source. Bytebase automatically uses the instance profile to authenticate. Use **Specific Credentials** only for cross-account scenarios.
</Info>

## Cross-Account IAM Authentication

<Info>
  Available in Bytebase version 3.12.1 and later
</Info>

Connect to RDS databases in different AWS accounts using IAM role assumption. This allows Bytebase running in Account A to authenticate to databases in Accounts B, C, D, etc.

### Prerequisites

* Bytebase running with an IAM role (EC2 instance profile or ECS task role)
* Target RDS instances have IAM authentication enabled
* Cross-account trust relationships configured

### Step 1: Create Target Account Role

In each target AWS account (where databases reside):

1. Go to [IAM Console → Roles](https://console.aws.amazon.com/iam/home#/roles)

2. Click **Create role**

3. Select trusted entity: **Another AWS account**

4. Enter the source account ID (where Bytebase runs)

5. Optionally add an External ID for additional security

6. Name the role: `bytebase-target-db-role`

7. After creating the role, add an inline policy for RDS access:

   * Go to the **Permissions** tab
   * Click **Add permissions** → **Create inline policy**
   * Switch to **JSON** view and paste:

   ```json theme={null}
   {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Effect": "Allow",
         "Action": "rds-db:connect",
         "Resource": "arn:aws:rds-db:REGION:ACCOUNT_ID:dbuser:DB_RESOURCE_ID/bytebase"
       }
     ]
   }
   ```

   <Note>
     For production, replace with specific values. Find your DB\_RESOURCE\_ID in RDS Console → your database → Configuration tab
   </Note>

8. Note the role ARN: `arn:aws:iam::TARGET_ACCOUNT:role/bytebase-target-db-role`

### Step 2: Configure Trust Relationship (Target Account)

In the target account, configure the trust policy for `bytebase-target-db-role`:

1. Go to the role in IAM Console
2. Select **Trust relationships** tab
3. Click **Edit trust policy**
4. Update with this policy (replace with your source account details):

   ```json theme={null}
   {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "AWS": "arn:aws:iam::SOURCE_ACCOUNT:role/bytebase-instance-role"
         },
         "Action": "sts:AssumeRole",
         "Condition": {
           "StringEquals": {
             "sts:ExternalId": "your-external-id"  // Optional but recommended
           }
         }
       }
     ]
   }
   ```

### Step 3: Grant AssumeRole Permission (Source Account)

In the source account (where Bytebase runs), add permission to assume the target role:

1. Go to your `bytebase-instance-role` in IAM Console

2. Click **Add permissions** → **Create inline policy**

3. Switch to **JSON** view and paste:

   ```json theme={null}
   {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Effect": "Allow",
         "Action": "sts:AssumeRole",
         "Resource": [
           "arn:aws:iam::ACCOUNT_B:role/bytebase-target-db-role",
           "arn:aws:iam::ACCOUNT_C:role/bytebase-target-db-role"
         ]
       }
     ]
   }
   ```

4. Name the policy: `AssumeTargetRoles`

5. Replace `ACCOUNT_B`, `ACCOUNT_C` with your target account IDs

### Step 4: Configure Database User

Ensure the target RDS instance has:

1. **IAM authentication enabled** (RDS Console → Modify → Database authentication options)
2. **A database user configured for IAM auth**

**For PostgreSQL:**

```sql theme={null}
CREATE USER bytebase;
GRANT rds_iam TO bytebase;
-- Grant necessary permissions
```

**For MySQL:**

```sql theme={null}
CREATE USER 'bytebase'@'%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
ALTER USER 'bytebase'@'%' REQUIRE SSL;
-- Grant necessary permissions
```

### Step 5: Configure Cross-Account Connection

1. Click **New Instance** in Bytebase

2. Configure basic connection:
   * **Host:** RDS endpoint in target account
   * **Port:** 3306 (MySQL) or 5432 (PostgreSQL)
   * **Username:** `bytebase`
   * **Authentication:** Select `AWS RDS IAM`

3. Configure AWS credentials:
   * **Credential Source:** Select **Specific Credentials** (required for cross-account)
     * **Access Key ID:** Leave empty (uses EC2 instance profile)
     * **Secret Access Key:** Leave empty (uses EC2 instance profile)
     * **Session Token:** Leave empty
     * **Role ARN:** `arn:aws:iam::TARGET_ACCOUNT:role/bytebase-target-db-role`
     * **External ID:** Optional security string (if configured in trust policy)
     * **Database Region:** Select target RDS region
     * **Database:** Your database name

4. Test and save the connection

<Note>
  **Important:** For cross-account access, always use **Specific Credentials**. Leave Access Key ID, Secret Access Key, and Session Token empty when using EC2 instance profile - only provide the Role ARN. Use **Default** credential source only for same-account connections.
</Note>

How it works:

1. Bytebase uses the EC2 instance profile credentials
2. Assumes the specified role in the target account
3. Generates RDS IAM authentication tokens using the assumed role
4. Connects to the database using the token

### Example Setup

**Scenario:** Bytebase in Account A (123456789012) connecting to RDS in Account B (987654321098)

**Account B - Create role with trust relationship:**

Configure the trust policy to allow the source account's role to assume this role:

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/bytebase-instance-role"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "your-secure-external-id"
        }
      }
    }
  ]
}
```

**Account A - Allow Bytebase to assume the role:**

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": "arn:aws:iam::987654321098:role/bytebase-target-db-role"
    }
  ]
}
```

<Note>
  Need to test cross-account authentication but only have one AWS account? See our guide on [testing cross-account authentication in a single account](/get-started/connect/aws-cross-account).
</Note>

## DynamoDB

DynamoDB connects via the AWS SDK, so region and credentials are read from the **Bytebase host environment**, not the instance form. The Host and Port fields do not apply and can be left blank.

### Step 1: Configure AWS Credentials and Region

Bytebase reads from the AWS default credential chain, in order:

1. Environment variables (recommended for Docker/Kubernetes):
   ```bash theme={null}
   -e AWS_REGION=us-west-1
   -e AWS_ACCESS_KEY_ID=xxx
   -e AWS_SECRET_ACCESS_KEY=yyy
   ```
2. `~/.aws/credentials` and `~/.aws/config`
3. EC2 instance profile or EKS IRSA when Bytebase runs in AWS

Reference: [AWS SDK credential resolution](https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html)

### Step 2: Grant DynamoDB Permissions

Attach this policy to the IAM role or user (scope `Resource` to specific table ARNs in production):

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:ListTables",
        "dynamodb:DescribeTable",
        "dynamodb:ExecuteStatement",
        "dynamodb:ExecuteTransaction"
      ],
      "Resource": "*"
    }
  ]
}
```

### Step 3: Add the Instance in Bytebase

1. Click **New Instance** → select **DynamoDB**.
2. Leave **Host or Socket** and **Port** blank.
3. Click **Test Connection**, then save.

<Note>
  After sync, the database appears as `{aws-account-id}-{region}` (e.g. `123456789012-us-west-1`). Each Bytebase DynamoDB instance covers one AWS region — configure separate instances for additional regions.
</Note>

### Troubleshooting

* **`Invalid Configuration: Missing Region`** — Set `AWS_REGION` (or `AWS_DEFAULT_REGION`) on the Bytebase host and restart.
* **`NoCredentialProviders` / `failed to retrieve credentials`** — No credentials found. Set `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY`, mount `~/.aws/credentials`, or attach an instance role.
* **`AccessDenied` on `ListTables`** — IAM identity is missing the actions in Step 2.
* **`failed to get caller identity`** — Credentials are missing or invalid; re-check the values from Step 1.

## AWS Secrets Manager

Store database passwords securely in AWS Secrets Manager instead of Bytebase.

<Note>
  Prerequisites: [IAM role](#prerequisites-iam-role-setup) with Secrets Manager permissions.
</Note>

### Step 1: Grant Secrets Manager Access

Add this policy to your IAM role to read secrets:

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue",
        "secretsmanager:DescribeSecret"
      ],
      "Resource": "arn:aws:secretsmanager:REGION:ACCOUNT_ID:secret:SECRET_NAME-*"
    }
  ]
}
```

Replace `REGION`, `ACCOUNT_ID`, and `SECRET_NAME` with your values. For easier setup, you can use wildcards: `arn:aws:secretsmanager:*:*:secret:*`

Reference: [Secrets Manager IAM permissions](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_identity-based-policies.html)

### Step 2: Create Secret

1. Go to [AWS Secrets Manager Console](https://console.aws.amazon.com/secretsmanager/)
2. Click **Store a new secret**
3. Select **Other type of secret**
4. Add key/value pair: Key = `DB_PASSWORD`, Value = your password
5. Name the secret (e.g., `bytebase-db-password`)
6. Complete creation and note the ARN

Reference: [Creating secrets](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html)

### Step 3: Configure in Bytebase

1. In your database instance settings, find the password field
2. Click the key icon to use external secret
3. Select **AWS Secrets Manager**
4. Enter:
   * **Secret Name:** Your secret name from Step 2
   * **Secret Key:** `DB_PASSWORD`
5. Test connection and save

## Database-Specific Configuration

For specific database types running on AWS, see their configuration guides:

<Tabs>
  <Tab title="PostgreSQL on RDS">
    <PostgreSQLConfig />
  </Tab>

  <Tab title="Aurora PostgreSQL">
    See the PostgreSQL configuration above, with IAM authentication enabled as described in this guide.
  </Tab>

  <Tab title="Aurora MySQL">
    Follow the MySQL configuration with IAM authentication enabled as described in this guide.
  </Tab>
</Tabs>

## Best Practices

1. **Use IAM Roles over Access Keys**: Always prefer IAM roles when running on EC2
2. **Enable SSL/TLS**: All AWS database services support encrypted connections
3. **Use Secrets Manager**: Centralize password management with automatic rotation
4. **Follow Least Privilege**: Grant only necessary permissions to IAM roles
5. **Monitor Access**: Use CloudTrail to audit database access patterns

## Troubleshooting

### Connection Timeout

* Verify security group rules allow traffic on database port
* Check VPC routing and subnet configuration
* Ensure database is publicly accessible or use VPN/bastion host

### IAM Authentication Failed

* Verify IAM role has correct `rds-db:connect` permissions
* Check database user was created with correct authentication method
* Ensure SSL is enabled for the connection

### Secrets Manager Access Denied

* Verify IAM role has `secretsmanager:GetSecretValue` permission
* Check secret ARN matches the policy resource
* Ensure secret exists in the correct region
