> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-detect-table-modification.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Managed Postgres Terraform reference

> Reference for managing ClickHouse Managed Postgres services with the ClickHouse Terraform provider.

export const galaxyOnClick = eventName => () => {
  try {
    if (typeof window !== "undefined" && window.galaxy && eventName) {
      window.galaxy.track(eventName, {
        interaction: "click"
      });
    }
  } catch (e) {}
};

export const BetaBadge = ({link, galaxyTrack, galaxyEvent}) => {
  if (link) {
    return <a href={link} target="_blank" rel="noopener noreferrer" className="betaBadge" onClick={galaxyTrack && galaxyEvent ? galaxyOnClick(galaxyEvent) : undefined}>
                <Icon />
                <span>Beta</span>
            </a>;
  }
  return <div className="betaBadge">
            <Icon />
            <span>
                Beta feature. 
                <u>
                    <a href="/docs/beta-and-experimental-features#beta-features">
                        Learn more.
                    </a>
                </u>
            </span>
        </div>;
};

ClickHouse Managed Postgres services can be created and managed using the `clickhouse_postgres_service` resource in the [ClickHouse Terraform provider](https://registry.terraform.io/providers/ClickHouse/clickhouse/latest/docs/resources/postgres_service). This page covers provider setup and configuration examples for the resource and its companion data sources.

<Note>
  This resource is in alpha and its behavior may change in future provider versions. It ships in the regular provider build. This page documents provider version **v3.21.0** and later, which changed how credentials are managed; earlier versions behave differently and as of July 31, 2026 no longer work correctly. See the [provider releases](https://github.com/ClickHouse/terraform-provider-clickhouse/releases) for details.
</Note>

<Warning>
  **Upgrade to provider v3.21.0 before July 31, 2026**

  As of **July 31, 2026**, the Managed Postgres API ceased to return the superuser password and connection string in its responses; credentials are returned only when a service is created or its password is reset. Provider versions **v3.21.0 and later** work identically before and after this change. Older provider versions rely on the API echoing credentials: as of July 31, 2026, they no longer populate `connection_string`, and a service created without a declared `password` succeeds while the generated password is never captured anywhere.

  Upgrade before July 31, 2026. Your state migrates automatically on the first plan or apply with v3.21.0. If any of your services rely on a server-generated password (no `password` in configuration), recover it first with `terraform state pull` and declare it, since v3.21.0 requires `password` or `password_wo` for a standard service.
</Warning>

<h2 id="provider-setup">
  Provider setup
</h2>

Add the ClickHouse provider to your Terraform configuration:

```hcl theme={null}
terraform {
  required_providers {
    clickhouse = {
      source  = "ClickHouse/clickhouse"
      version = ">= 3.21.0"
    }
  }
}

provider "clickhouse" {
  organization_id = var.organization_id
  token_key       = var.token_key
  token_secret    = var.token_secret
}
```

See [Managing API keys](/products/cloud/features/admin-features/api/openapi) for instructions on creating an API key to use with the provider.

<h2 id="resource-overview">
  Resource overview
</h2>

The `clickhouse_postgres_service` resource has the following arguments:

| Argument                   | Required                                           | Description                                                                                                                                                                                                                 |
| -------------------------- | -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`                     | Yes                                                | Human-readable name for the service. Immutable — changing it destroys and recreates the service.                                                                                                                            |
| `cloud_provider`           | For a standard create                              | Cloud provider hosting the instance. Currently only `aws` is supported. Omit for a read replica or point-in-time restore (inherited from the source).                                                                       |
| `region`                   | For a standard create                              | Cloud region (for example, `us-east-1`). Omit for a read replica or point-in-time restore (inherited from the source).                                                                                                      |
| `size`                     | For a standard create                              | Instance size (VM SKU), for example `m6gd.large`. Resizable in place. Omit for a point-in-time restore (the restored instance comes up at the backup's size).                                                               |
| `postgres_version`         | No                                                 | Major Postgres version (for example, `18`). Changing the major version destroys and recreates the service.                                                                                                                  |
| `ha_type`                  | No                                                 | High-availability mode: `none`, `async`, or `sync`. See [High availability](#high-availability).                                                                                                                            |
| `password`                 | For a standard create, unless `password_wo` is set | Superuser password, managed from your configuration. Terraform never reads it back from the API. Stored in (sensitive) state. Omit for a read replica (inherited) or a point-in-time restore (kept from the source backup). |
| `password_wo`              | For a standard create, unless `password` is set    | Write-only superuser password: applied to the service but never stored in state. Requires `password_wo_version`; requires Terraform 1.11 or later.                                                                          |
| `password_wo_version`      | With `password_wo`                                 | Version number for `password_wo`. Change it to rotate to the current `password_wo` value.                                                                                                                                   |
| `pg_config`                | No                                                 | Postgres server parameters as a key-value map.                                                                                                                                                                              |
| `pgbouncer_config`         | No                                                 | PgBouncer connection-pooler parameters as a key-value map.                                                                                                                                                                  |
| `tags`                     | No                                                 | Resource tags as a key-value map.                                                                                                                                                                                           |
| `read_replica_of`          | No                                                 | ID of a primary service to replicate. See [Read replicas](#read-replicas). Mutually exclusive with `restore_to_point_in_time`.                                                                                              |
| `restore_to_point_in_time` | No                                                 | Create the service by restoring another service to a point in time. See [Point-in-time restore](#point-in-time-restore). Mutually exclusive with `read_replica_of`.                                                         |

The following attributes are read-only and populated by ClickHouse Cloud after creation: `id`, `state`, `created_at`, `is_primary`, `hostname`, `port`, and `username`. There is no `connection_string` attribute (removed in v3.21.0): build connection URIs from `hostname`, `port`, `username`, and the password you declare, for example `postgres://${username}:${password}@${hostname}:${port}/postgres?sslmode=require`.

<Warning>
  The `password` is stored in plain text in your Terraform state. Protect your state file accordingly, for example with a remote backend using encryption at rest, or use `password_wo` to keep the password out of state entirely.
</Warning>

<h2 id="create-a-service">
  Create a service
</h2>

```hcl theme={null}
resource "clickhouse_postgres_service" "example" {
  name           = "my-postgres"
  cloud_provider = "aws"
  region         = "us-east-1"
  size           = "m6gd.large"
  password       = var.postgres_password

  # High-availability mode — number of standby replicas:
  #   "none"  – primary only, no standby (default)
  #   "async" – 1 standby, asynchronous replication
  #   "sync"  – 2 standbys, synchronous replication
  ha_type = "async"

  tags = {
    environment = "production"
    team        = "data"
  }
}
```

A standard service must declare `password` or `password_wo`. The value must be at least 12 characters with at least one lowercase letter, one uppercase letter, and one digit. `password_wo` (with `password_wo_version`) applies the same password rules but is never stored in state; change `password_wo_version` to rotate. Because the API does not return credentials, Terraform must stay the only writer of the password: a password rotated outside Terraform (console or API) is not detected, and the next Terraform-driven rotation reasserts the declared value.

<h2 id="high-availability">
  High availability
</h2>

The `ha_type` argument controls the number of standby replicas:

| `ha_type` | Standbys            | Replication                                                                   |
| --------- | ------------------- | ----------------------------------------------------------------------------- |
| `none`    | None (primary only) | —                                                                             |
| `async`   | 1 standby           | Asynchronous — writes commit without waiting for the standby                  |
| `sync`    | 2 standbys          | Synchronous — the primary waits for acknowledgement from at least one standby |

`ha_type` is mutable post-create; changing it triggers an HA transition. See [High availability](/products/managed-postgres/high-availability) for details.

<h2 id="read-replicas">
  Read replicas
</h2>

Set `read_replica_of` to the `id` of a primary service to create a streaming read replica. A replica inherits the primary's `cloud_provider`, `region`, `postgres_version`, and superuser — omit those (and `password`):

```hcl theme={null}
resource "clickhouse_postgres_service" "replica" {
  name            = "my-postgres-replica"
  size            = "m6gd.large"
  read_replica_of = clickhouse_postgres_service.example.id
}
```

See [Read replicas](/products/managed-postgres/read-replicas) for details.

<h2 id="point-in-time-restore">
  Point-in-time restore
</h2>

Set `restore_to_point_in_time` to create a service by restoring another service's backup to a point in time. `cloud_provider`, `region`, and `postgres_version` are inherited from the source (omit them); `size` and `ha_type` must be omitted:

```hcl theme={null}
resource "clickhouse_postgres_service" "restored" {
  name = "my-postgres-restored"

  restore_to_point_in_time = {
    source_id      = clickhouse_postgres_service.example.id
    restore_target = "2026-06-01T12:00:00Z"
  }
}
```

The whole block is create-time only: changing `source_id` or `restore_target`, or removing the block, destroys and recreates the service. See [Backup and restore](/products/managed-postgres/backup-and-restore) for details.

<h2 id="data-sources">
  Data sources
</h2>

Three companion data sources let you look up existing services:

```hcl theme={null}
# A single service by ID.
data "clickhouse_postgres_service" "example" {
  id = clickhouse_postgres_service.example.id
}

# All Managed Postgres services in the organization.
data "clickhouse_postgres_services" "all" {}

# The CA certificates for a service, for TLS connections.
data "clickhouse_postgres_service_ca_certificates" "certs" {
  service_id = clickhouse_postgres_service.example.id
}
```

<h2 id="importing-existing-services">
  Importing existing services
</h2>

Existing Managed Postgres services can be imported into Terraform state using the service ID:

```bash theme={null}
terraform import clickhouse_postgres_service.example xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```

Import does not recover the password (the API does not return it). After importing, the first apply rotates the service to the `password` or `password_wo` declared in your configuration.

<h2 id="unsupported-operations">
  Unsupported operations
</h2>

The following are intentionally absent from the resource schema:

* Operational commands (restart, promote, switchover).
* IP allowlists, private endpoints, backup configuration, maintenance windows, customer-managed encryption keys, and BYOC.
* Configurable lifecycle timeouts — there is no `timeouts {}` block.
