> ## 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.

# Amazon RDS for MySQL

> AWS RDS MySQL 8.4 instance with configurable size, storage, backups, maintenance, monitoring, and network

Qovery creates it in the AWS account of the environment's cluster, as a [Blueprint](https://www.qovery.com/docs/configuration/blueprints.md) service in one of your environments.

| | |
| - | - |
| Catalog name | `aws-rds-mysql` |
| Category | Databases & Caches |
| Provider | AWS |
| Engine | terraform |
| Major versions (latest release) | `8` (3.5.1) |
| Source | [AWS/mysql/8](https://github.com/Qovery/service-catalog/tree/AWS/mysql/8/3.5.1/AWS/mysql/8) |

> [!TIP]
>
> **New to this?** You don't need to know Kubernetes or Terraform. Qovery sets up Amazon RDS for MySQL in your cloud account and manages it for you: you fill in a form, or paste the prompt below into your coding agent. The values it publishes, listed under Outputs, reach your other services as environment variables. Qovery tells you when a newer version of the Blueprint is available. Check the requirements in the Reference section before you start, and try it first in a development environment.

## Create it

> [tab] Console
>
> 1. Open the environment, then **New service** › **Blueprint**.
> 2. Find **Amazon RDS for MySQL** in the catalog and pick the major version.
> 3. Fill in the variables. Required ones are marked; the others use their defaults.
> 4. Create the service, and deploy it now or later.

> [tab] CLI and API
>
> List the catalog to get the latest tag, then create the service from it. `qovery api` signs the requests with your CLI session.
>
> ```bash theme={null}
> ORG_ID="REPLACE_WITH_ORGANIZATION_ID"
> ENV_ID="REPLACE_WITH_ENVIRONMENT_ID"
>
> qovery api "organization/$ORG_ID/blueprint/catalog" | jq '.. | objects | select(.name? == "aws-rds-mysql")'
>
> cat > blueprint.json <<'EOF'
> {
>   "name": "aws-rds-mysql",
>   "tag": "AWS/mysql/8/3.5.1",
>   "icon": "app://qovery-console/mysql",
>   "variables": [
>     {
>       "name": "db_name",
>       "value": "REPLACE_WITH_DB_NAME"
>     },
>     {
>       "name": "instance_class",
>       "value": "REPLACE_WITH_INSTANCE_CLASS"
>     },
>     {
>       "name": "allocated_storage",
>       "value": "REPLACE_WITH_ALLOCATED_STORAGE"
>     }
>   ],
>   "spec_overrides": {
>     "engine_version": "1.13.3"
>   }
> }
> EOF
> BLUEPRINT_ID=$(qovery api "environment/$ENV_ID/blueprint" --method POST --input - < blueprint.json | jq -r .id)
> rm blueprint.json   # it can hold secret values
> qovery api "blueprint/$BLUEPRINT_ID/deploy" --method POST
> qovery api "blueprint/$BLUEPRINT_ID"   # status of the latest deployment
> ```
>
> Replace each `REPLACE_WITH_` value. Add optional variables to `variables` the same way.

> [tab] Coding agent
>
> Paste this into Claude Code, Cursor, Codex or another coding agent with the [Qovery agent skills](https://www.qovery.com/docs/getting-started/quickstart/agent-skills.md) installed (`curl -fsSL https://skill.qovery.com/install.sh | bash`).
>
> ```text Prompt wrap theme={null}
> Add the Qovery Blueprint Amazon RDS for MySQL (aws-rds-mysql) to one of my Qovery environments and deploy it. Ask me for db_name, instance_class and allocated_storage.
> Ask me before deploying to a production environment.
> Docs: https://www.qovery.com/docs/configuration/blueprints/aws-rds-mysql.md
> ```

You don't add any file to your repository. Qovery creates the Blueprint from the Console or the API.

## Variables and outputs

Generated from `qbm.yml` at `AWS/mysql/8/3.5.1`, the manifest the Console form is built from.

> [accordion] All 32 variables
>
> | Name | Type | Required | Default | Secret | Description |
> | - | - | - | - | - | - |
> | `db_name` | string | Yes | | | Letters, digits, underscores; must start with a letter; max 64 chars. No hyphens. |
> | `db_username` | string | | | | Leave empty to use qoveryadmin. Letters, digits, underscores, starting with a letter, max 32; not admin, rdsadmin or mysql. |
> | `db_password` | string | | | Yes | Leave empty and Qovery generates one (adopted: its current password). 8–128 chars, no /, @, ", spaces; edits rotate it (adopted: needs manage\_db\_password). |
> | `manage_db_password` | bool | | `false` | | Adopted instances only, one-way: once on, keep it on. Turning it on applies db\_password, so it must match the instance's current one. |
> | `port` | number | | `3306` | | Min 1150 (RDS reserves lower ports). |
> | `instance_class` | string | Yes | `db.t3.micro` | | RDS instance class |
> | `allocated_storage` | number | Yes | `20` | | GiB. Min 20; max 65536 (gp2: 16384). |
> | `storage_type` | string | | `gp3` | | EBS storage type |
> | `storage_encrypted` | bool | | `true` | | Encrypt storage at rest |
> | `disk_iops` | number | | `0` | | Only for io1/io2, or gp3 at ≥400 GiB. 0 lets AWS choose. |
> | `multi_az` | bool | | `false` | | Enable Multi-AZ deployment |
> | `publicly_accessible` | bool | | `false` | | Expose the database to the public internet |
> | `db_subnet_group_name` | string | | | | Leave empty — derived from the cluster's DB subnet group. Set it only on a user-provided VPC. |
> | `security_group_ids` | string | | | | Leave empty — derived from the cluster's workers security group. Set it (comma-separated ids) only on a user-provided VPC. |
> | `apply_changes_now` | bool | | `false` | | Apply changes immediately instead of waiting for the next maintenance window |
> | `allow_major_version_upgrade` | bool | | `false` | | Allow major engine version upgrades on apply |
> | `auto_minor_version_upgrade` | bool | | `true` | | Automatically apply minor version upgrades during the maintenance window |
> | `preferred_maintenance_window` | string | | `Tue:02:00-Tue:04:00` | | UTC, format ddd:hh24:mi-ddd:hh24:mi. |
> | `preferred_backup_window` | string | | `00:00-01:00` | | Daily, UTC, format hh24:mi-hh24:mi. |
> | `backup_retention_period` | number | | `7` | | Days to retain automated backups (0 disables) |
> | `skip_final_snapshot` | bool | | `false` | | Off keeps a final snapshot on deletion, billed until deleted. Turn on for throwaway instances. |
> | `delete_automated_backups` | bool | | `false` | | Delete automated backups with the instance. Off keeps them backup\_retention\_period days; turn on for throwaway ones. |
> | `copy_tags_to_snapshot` | bool | | `true` | | Propagate instance tags to snapshots |
> | `performance_insights_enabled` | bool | | `false` | | Enable RDS Performance Insights |
> | `performance_insights_retention_period` | number | | `7` | | Retention in days. Only used when performance\_insights\_enabled is true. |
> | `ca_cert_identifier` | string | | `rds-ca-rsa2048-g1` | | CA certificate identifier used by the DB instance |
> | `monitoring_interval` | number | | `0` | | Enhanced monitoring interval in seconds (0 disables) |
> | `monitoring_role_arn` | string | | | | For enhanced monitoring. Required when monitoring\_interval > 0. |
> | `option_group_name` | string | | | | Empty = AWS default. |
> | `deletion_protection` | bool | | `false` | | Prevent the database from being deleted via TF or the API |
> | `iam_database_authentication_enabled` | bool | | `false` | | Enable IAM database authentication |
> | `dedicated_log_volume` | bool | | `false` | | Provision a dedicated EBS volume for database logs (RDS feature) |

Outputs become environment variables that other services in the environment can use. By default Qovery also creates an alias for each output, prefixed with the Blueprint's name; see [Aliases Qovery creates for outputs](https://www.qovery.com/docs/configuration/environment-variables.md#aliases-qovery-creates-for-outputs) for the naming rules and the cases where no alias is created.

> [accordion] All 10 outputs
>
> | Name | Secret | Description |
> | - | - | - |
> | `db_identifier` | | RDS instance identifier (what AWS console shows as the instance name) |
> | `db_endpoint` | | RDS instance endpoint (host:port) |
> | `db_address` | | RDS instance hostname |
> | `db_port` | | RDS instance port |
> | `db_name` | | Database name |
> | `db_username` | | Master username |
> | `db_password` | Yes | Master password (generated when the input was left empty) |
> | `db_resource_id` | | RDS internal resource ID (used in IAM DB auth ARNs) |
> | `db_arn` | | RDS instance ARN |
> | `db_engine_version_actual` | | Engine version actually running (may include the minor AWS chose) |

> [!WARNING]
>
> Secret variables and outputs are encrypted and masked in Qovery, but Terraform can also keep their values, and values derived from them, in its state. With the Qovery-managed state backend (the default), Qovery stores the state. If you use your own backend, protect it and keep state files out of version control.

## Reference

From the Blueprint's [README](https://github.com/Qovery/service-catalog/blob/AWS/mysql/8/3.5.1/AWS/mysql/8/README.md).

Creates an AWS RDS MySQL 8.4 instance with configurable instance class, storage, backups, maintenance window, monitoring, and network settings. Storage is encrypted by default.

A dedicated parameter group is attached with `log_bin_trust_function_creators = 1` so the master user can create triggers/stored procedures without superuser privileges.

The RDS identifier is derived from `db_name` by lowercasing and replacing underscores with hyphens (AWS requirement). The actual MySQL database name is kept as provided.

### Variables

#### Required

| Name | Type | Sensitive | Description |
| - | - | - | - |
| `db_name` | string | | MySQL database name. Letters, digits, underscores only; must start with a letter; max 64 chars. Hyphens are not allowed. |
| `instance_class` | string | | RDS instance class. Default suggestion: `db.t3.micro`. |
| `allocated_storage` | number | | Allocated storage in GiB (min 20; max 65536 for gp3/io1/io2, but gp2 caps at 16384) |

Available instance classes: every RDS instance class Qovery offers for native managed PostgreSQL and MySQL — the `db.t3`, `db.t4g`, `db.m5`–`db.m8g`, `db.r5`–`db.r8g` (including `db.r5b`), `db.x2g`, `db.x2idn` and `db.x2iedn` families, with their Graviton (`g`), Intel (`i`), local-storage (`d`) and network-optimized (`n`) variants. `db.c6gd` is left out because RDS offers it only for Multi-AZ DB clusters. The full list is in `qbm.yml`.

#### Credentials

Both are optional — omit them and Qovery supplies the values, the way native managed
databases did. In the console, leaving the field blank omits it. Through the API or
Terraform, omit the variable rather than sending an empty string: the platform rejects an
empty variable value.

| Name | Type | Sensitive | Default | Description |
| - | - | - | - | - |
| `db_username` | string | | `qoveryadmin` | Leave empty to use qoveryadmin, the login used by native managed databases. To set your own: letters, digits, underscores; must start with a letter; max 32 chars (MySQL limit). Reserved names not allowed: admin, rdsadmin, mysql. |
| `db_password` | string | yes | *generated* | Leave empty when creating a database and Qovery generates a 32-character alphanumeric password; when adopting an existing instance this must carry the current master password of that instance, because RDS never returns it. To set your own: 8–128 chars, must not contain /, @, ", or spaces. Changing it rotates the master password on the live instance (adopted instances: only once `manage_db_password` is true). |
| `manage_db_password` | bool | | `false` | Adopted instances only, and one-way: once true, leave it true. Switching it on applies `db_password` to the instance, so confirm that value is the one the instance already has. Changing `db_password` then rotates it. An instance this blueprint created always owns its password. |

Changing `db_password` rotates the live instance's master password: the value is sent as a
write-only argument, triggered by a version derived from the password itself, so a change
reaches RDS and an unchanged password sends nothing.

An adopted instance does not take part until `manage_db_password` is set to true. That keeps
its import plan clean, and it has a consequence worth stating plainly: **while the flag is
false, editing `db_password` changes what the blueprint publishes without changing anything on
the instance.** Consumers pick up a credential RDS will reject. On an adopted instance, either
set the flag before touching the password, or do not touch the password at all.

Setting the flag is itself a write. Until then the version that triggers the send is null in
state, so switching it to true moves that value and applies `db_password` to the instance —
harmless when the two already agree, and an overwrite of the live password when they do not.
Confirm the stored password is the one the instance actually has before opting in.

A rotation also obeys `apply_changes_now`. Left false, RDS defers the password change to the
maintenance window while the new value is published immediately — consumers redeployed in
between cannot connect. Set `apply_changes_now` when you rotate.

Adoption (`import_identifier` set) requires both explicitly. `username` is `ForceNew` on
`aws_db_instance`, so a defaulted value would plan a replacement and destroy the live
database; and RDS never returns the master password, so a generated one would be published
as the credential without ever being applied.

#### Instance & storage

| Name | Type | Default | Description |
| - | - | - | - |
| `port` | number | `3306` | Database port |
| `storage_type` | string | `gp3` | EBS storage type: `gp2`, `gp3`, `io1`, `io2` |
| `storage_encrypted` | bool | `true` | Encrypt storage at rest |
| `disk_iops` | number | `0` | Provisioned IOPS. Only meaningful with io1/io2 (always) or gp3 (≥400 GiB). 0 lets AWS choose the default. |

#### Network

| Name | Type | Default | Description |
| - | - | - | - |
| `multi_az` | bool | `false` | Enable Multi-AZ deployment |
| `publicly_accessible` | bool | `false` | Expose the database to the public internet |
| `db_subnet_group_name` | string | | Leave empty — derived from the Qovery cluster's DB subnet group. Set it only on a cluster with a user-provided VPC, where that lookup finds nothing. |
| `security_group_ids` | string | | Leave empty — derived from the Qovery cluster's workers security group. Set it (comma-separated ids) only on a cluster with a user-provided VPC, where that lookup finds nothing. |

By default the instance is attached to the Qovery cluster network: the DB subnet group created at cluster bootstrap (named after the cluster VPC id) and the cluster workers security group, so pods in the cluster can reach the database out of the box. On clusters deployed into an existing VPC (user-provided network), the `ClusterId` tag lookup may not resolve; set `db_subnet_group_name` and `security_group_ids` explicitly in that case.

#### Maintenance & upgrades

| Name | Type | Default | Description |
| - | - | - | - |
| `apply_changes_now` | bool | `false` | Apply changes immediately |
| `allow_major_version_upgrade` | bool | `false` | Allow major engine version upgrades on apply |
| `auto_minor_version_upgrade` | bool | `true` | Auto-apply minor version upgrades during maintenance |
| `preferred_maintenance_window` | string | `Tue:02:00-Tue:04:00` | Maintenance window (UTC), `ddd:hh24:mi-ddd:hh24:mi` |

#### Backups

| Name | Type | Default | Description |
| - | - | - | - |
| `preferred_backup_window` | string | `00:00-01:00` | Daily backup window (UTC), `hh24:mi-hh24:mi` |
| `backup_retention_period` | number | `7` | Days to retain backups (0–35). `0` disables. |
| `skip_final_snapshot` | bool | `false` | Skip final snapshot on deletion |
| `delete_automated_backups` | bool | `false` | Delete automated backups when the instance is deleted. Default keeps them for `backup_retention_period` days; set true for throwaway instances |
| `copy_tags_to_snapshot` | bool | `true` | Propagate instance tags to snapshots |

Deleting the service keeps a final snapshot and the automated backups by default, and both keep
costing storage until deleted by hand: the snapshot indefinitely, the backups for
`backup_retention_period` days. For a throwaway or test instance, set both `skip_final_snapshot` and
`delete_automated_backups` to `true`. The final snapshot is named
`<cluster name>-<db name>-<YYYYMMDDhhmmss>`: `db_name` lowercased with `_` turned into `-`, the
UTC time the name was stamped, and any character AWS rejects removed (prefixed `snap-` if the
result does not start with a letter). It is stamped once at creation, so successive
create/destroy cycles of the same name do not collide.

#### Monitoring

| Name | Type | Default | Description |
| - | - | - | - |
| `performance_insights_enabled` | bool | `false` | Enable RDS Performance Insights |
| `performance_insights_retention_period` | number | `7` | Performance Insights retention in days. Only used when `performance_insights_enabled` is true. Valid: 7, 731, or a multiple of 31. |
| `monitoring_interval` | number | `0` | Enhanced monitoring interval in seconds (0 disables). Allowed values: 0, 1, 5, 10, 15, 30, 60. |
| `monitoring_role_arn` | string | | IAM role ARN for enhanced monitoring. Required when `monitoring_interval > 0`. |
| `ca_cert_identifier` | string | `rds-ca-rsa2048-g1` | CA certificate identifier |

#### Misc

| Name | Type | Default | Description |
| - | - | - | - |
| `option_group_name` | string | | Optional option group name. Empty = AWS default. |
| `deletion_protection` | bool | `false` | Prevent deletion via TF/API |
| `iam_database_authentication_enabled` | bool | `false` | Enable IAM DB authentication |
| `dedicated_log_volume` | bool | `false` | Provision a dedicated EBS volume for database logs |

### Outputs

| Name | Sensitive | Description |
| - | - | - |
| `db_identifier` | | RDS instance identifier (AWS console instance name) |
| `db_endpoint` | | RDS instance endpoint (host:port) |
| `db_address` | | RDS instance hostname |
| `db_port` | | RDS instance port |
| `db_name` | | Database name |
| `db_username` | | Master username |
| `db_password` | yes | Master password (generated when the input was left empty) |
| `db_resource_id` | | RDS internal resource ID (used in IAM DB auth ARNs) |
| `db_arn` | | RDS instance ARN |
| `db_engine_version_actual` | | Engine version actually running (incl. AWS-chosen minor) |

#### Upgrading from an earlier blueprint version

Read this before repointing a deployment at this version.

* An adopted instance now keeps running its exact live version (for example `8.0.x`) instead of
  having `engine_version` ignored. Nothing is sent to AWS for an instance whose version is unchanged.
* Deleting now keeps a final snapshot and the automated backups for services **created** on this
  version. An existing service does not change behaviour: Qovery stores every variable default when
  the service is created, so repointing it here keeps `skip_final_snapshot = true` and
  `delete_automated_backups = true`. To keep a snapshot and backups on delete, set both to `false`
  on the service. The upgrade itself adds `time_static.created` and, with those set to `false`,
  updates `skip_final_snapshot`, `delete_automated_backups` and `final_snapshot_identifier` in
  place — Terraform-only arguments, nothing is sent to AWS and the instance is not rebooted.
* For an instance this blueprint created, and for an adopted instance already opted in with
  `manage_db_password`, the first apply writes the master password once. Old state carries no record of
  what was last sent, so the value Qovery holds is applied. An instance whose password was rotated
  outside Terraform — which earlier versions of this document told you to do — is reset to the
  Qovery-held value, and applications using the out-of-band password stop connecting. Make the two agree
  before you upgrade. An adopted instance left at `manage_db_password = false` is not touched: nothing is
  sent, and an out-of-band rotation survives.
* `manage_db_password` is one-way. Setting it back to false after an adopted instance has been handed
  over leaves Terraform with a change AWS rejects as "no modifications were requested".
* Terraform moves from 1.9.7 to 1.13.3, and `1.9.7` is no longer an accepted override. State written by
  1.13.3 cannot be read by 1.9.7, so a deployment cannot be repointed at an earlier blueprint version
  once it has applied.

### Lifecycle ignore\_changes

On the primary instance, `engine_version` is no longer ignored. Terraform requests the exact
version held in the internal `engine_version` variable, which Qovery sets on every deploy to the
live version, so an adopted `8.0.x` instance stays on `8.0.x`. With `auto_minor_version_upgrade`
enabled, AWS may still move the running minor forward; the next deploy then requests that newer
version, so Terraform never tries to go back. Read replicas inherit the primary's version.

A bare `"8.4"` is never sent to a live instance, because AWS resolves it to the region's default
minor, which upgrades an older minor and is refused on a newer one. Without the variable, an
existing instance keeps its live version (read through the `aws_db_instance` data source) and only
a new instance gets `8.4`.

A few attributes remain ignored:

* `password` — the master password moved to the write-only `password_wo`; ignoring the plain attribute stops the value left in older state reading as a removal.
* `enabled_cloudwatch_logs_exports` — list type, not yet supported by the qbm.yml schema.
* `max_allocated_storage` — will turn into a managed input when the storage autoscale feature is added.

Note: `parameter_group_name` is **not** ignored — the blueprint owns its parameter group.

### Required AWS IAM permissions

The credentials used to deploy this blueprint must allow the actions below. The RDS actions target instances in any region you deploy to; EC2 read actions are needed so Terraform can look up the default VPC, subnets, and security groups when none are explicitly configured.

```json theme={null}
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "rds:CreateDBInstance",
        "rds:DeleteDBInstance",
        "rds:ModifyDBInstance",
        "rds:DescribeDBInstances",
        "rds:CreateDBParameterGroup",
        "rds:DeleteDBParameterGroup",
        "rds:ModifyDBParameterGroup",
        "rds:DescribeDBParameterGroups",
        "rds:DescribeDBParameters",
        "rds:DescribeDBSubnetGroups",
        "rds:DescribeDBSecurityGroups",
        "rds:AddTagsToResource",
        "rds:RemoveTagsFromResource",
        "rds:ListTagsForResource"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeVpcs",
        "ec2:DescribeSubnets",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeAvailabilityZones"
      ],
      "Resource": "*"
    }
  ]
}
```

When `monitoring_interval > 0`, the supplied `monitoring_role_arn` must be assumable by RDS (`monitoring.rds.amazonaws.com` trust relationship) and grant the `AmazonRDSEnhancedMonitoringRole` managed policy.


## Related topics

- [Blueprints](https://www.qovery.com/docs/configuration/blueprints.md)
- [Amazon RDS for PostgreSQL](https://www.qovery.com/docs/configuration/blueprints/aws-rds-postgresql.md)
- [Create a Database](https://www.qovery.com/docs/getting-started/guides/getting-started/connect-database.md)
- [Databases](https://www.qovery.com/docs/configuration/database.md)
- [Disaster Recovery](https://www.qovery.com/docs/configuration/disaster-recovery.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.