Skip to content

Commit

Permalink
Sync docs from Discourse
Browse files Browse the repository at this point in the history
  • Loading branch information
github-actions[bot] committed Jan 17, 2025
1 parent 342c175 commit 479bbc6
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 25 deletions.
179 changes: 179 additions & 0 deletions docs/how-to/h-deploy-tls-vip-access.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
# Deploy for external TLS VIP access

This guide goes over an example deployment of PostgreSQL, PgBouncer and HAcluster that require external TLS/SSL access via [Virtual IP (VIP)](https://en.wikipedia.org/wiki/Virtual_IP_address).

It combines the following guides, where you can find more detailed information:
* [PostgreSQL | Tutorial > Enable TLS](/t/9699)
* [PostgreSQL | How to connect from outside the local network](/t/15802)
* [PgBouncer | How to connect from outside the local network](https://charmhub.io/pgbouncer/docs/h-external-access?channel=1/stable)

## Summary
* [Requirements](#requirements)
* [Design](#design)
* [Deploy components](#deploy-components)
* [Check connectivity](#check-connectivity)
* [(Optional) Add monitoring](#optional-add-monitoring)
* [High availability](#high-availability)

---

## Requirements

Although Canonical does not prescribe how you should set up your environment, we can provide recommendations. Consider [contacting us](/t/11863) for support with your use-case.

The basic requirements to follow along with this example setup are the following:

* A fully deployed and running Juju machine environment
* See the [PostgreSQL Tutorial](/t/9709) for a quick setup with Multipass
* See the official [Juju deployment guide](https://juju.is/docs/juju/tutorial#deploy) for more details
* A spare virtual IP address for [hacluster](/t/15741?channel=1/stable#using-a-virtual-ip-to-connect-to-pgbouncer)
* See the PgBouncer guide: [How to use a VIP to connect to PgBouncer](https://charmhub.io/pgbouncer/docs/h-external-access?channel=1/stable)
* DNS record pointing to VIP above (`my-tls-example-db.local` is used as an example here)

## Design

[note type=caution]
This setup applicable for VM/machine charms only. **Do NOT use it for K8s deployments!**
[/note]

![PostgreSQL TLS VIP|631x562](upload://fIN24xhTTX1Hy1aszs7Os413Y0m.png)

This setup deploys the following components:

* The [`postgresql`](https://charmhub.io/postgresql) charm (3 units, as a single cluster).
* The [`self-signed-certificates`](https://charmhub.io/self-signed-certificates) charm as the TLS provider.
* Note that this is not suitable for production deployments. See the guide: [Security with X.509 certificates](https://charmhub.io/topics/security-with-x-509-certificates).
* The [`data-integrator`](https://charmhub.io/data-integrator) charm as a [principal](https://juju.is/docs/sdk/charm-taxonomy#heading--principal-charms) charm for the [subordinated](https://juju.is/docs/sdk/charm-taxonomy#heading--subordinate-charms) charms below (3 units for high availability):
* The latest [`pgbouncer`](https://charmhub.io/pgbouncer?channel=1/stable) charm as a load-balancer and connection pooler (3 units).
* The [`hacluster`](https://charmhub.io/hacluster) charm for VIP handling (3 units are the minimum for HA).
* (optional) The COS [`grafana-agent`](https://charmhub.io/grafana-agent) charm for `Monitoring` purposes.

## Deploy components

Create a Juju model if you haven't already:
```shell
juju add-model my-external-tls-db
```
Deploy `postgresql` and `self-signed-certificates`:
```shell
juju deploy postgresql -n 3
juju deploy self-signed-certificates
juju integrate postgresql self-signed-certificates
```
Deploy `pgbouncer` from the `1/stable` channel and configure it with your VIP:
```shell
juju deploy pgbouncer --channel 1/stable --config vip=10.20.30.40
juju integrate pgbouncer postgresql
juju integrate pgbouncer self-signed-certificates
```
Deploy `data-integrator` with 3 units and configure the database name of your choice. In this example, we use `mytestdb`:
```shell
juju deploy data-integrator -n 3 --config database-name=mytestdb
juju integrate data-integrator pgbouncer
```
Deploy `hacluster`:
```shell
juju deploy hacluster
juju integrate hacluster pgbouncer
juju integrate hacluster:juju-info data-integrator
```

Example `juju status` output:
```shell
Model Controller Cloud/Region Version SLA Timestamp
my-external-tls-db lxd localhost/localhost 3.5.5 unsupported 12:53:35+01:00

App Version Status Scale Charm Channel Rev Exposed Message
data-integrator active 3 data-integrator latest/stable 78 no
hacluster 2.1.2 active 3 hacluster 2.4/stable 131 no Unit is ready and clustered
pgbouncer 1.21.0 active 3 pgbouncer 1/stable 396 no VIP: 10.78.217.100
postgresql 14.12 active 3 postgresql 14/stable 468 no
self-signed-certificates active 1 self-signed-certificates latest/stable 155 no

Unit Workload Agent Machine Public address Ports Message
data-integrator/0 active idle 4 10.78.217.30
hacluster/3 active idle 10.78.217.30 Unit is ready and clustered
pgbouncer/0* active idle 10.78.217.30 6432/tcp VIP: 10.78.217.100
data-integrator/1 active idle 5 10.78.217.132
hacluster/2 active idle 10.78.217.132 Unit is ready and clustered
pgbouncer/1 active idle 10.78.217.132 6432/tcp
data-integrator/2* active idle 6 10.78.217.93
hacluster/1* active idle 10.78.217.93 Unit is ready and clustered
pgbouncer/2 active idle 10.78.217.93 6432/tcp
postgresql/0 active idle 0 10.78.217.254 5432/tcp
postgresql/1 active idle 1 10.78.217.245 5432/tcp
postgresql/2* active idle 2 10.78.217.192 5432/tcp Primary
self-signed-certificates/0* active idle 3 10.78.217.79

Machine State Address Inst id Base AZ Message
0 started 10.78.217.254 juju-318984-0 ubuntu@22.04 Running
1 started 10.78.217.245 juju-318984-1 ubuntu@22.04 Running
2 started 10.78.217.192 juju-318984-2 ubuntu@22.04 Running
3 started 10.78.217.79 juju-318984-3 ubuntu@22.04 Running
4 started 10.78.217.30 juju-318984-4 ubuntu@22.04 Running
5 started 10.78.217.132 juju-318984-5 ubuntu@22.04 Running
6 started 10.78.217.93 juju-318984-6 ubuntu@22.04 Running
```

## Check connectivity

To test the connection to PostgreSQL via TLS, first get the credentials via `data-integrator`:
```shell
juju run data-integrator/leader get-credentials
```
```shell
...
postgresql:
data: '{"database": "mytestdb", "external-node-connectivity": "true", "requested-secrets":
"[\"username\", \"password\", \"tls\", \"tls-ca\", \"uris\"]"}'
database: mytestdb
endpoints: 10.78.217.100:6432
password: V7kHqHyapIphkUS0cHoOtP3j
subordinated: "true"
uris: postgresql://relation_id_9:V7kHqHyapIphkUS0cHoOtP3j@10.78.217.100:6432/mytestdb
username: relation_id_9
version: "14.12"
```

Now use the received credentials (`uris`) to connect PostgreSQL (via TLS/SSL):
```shell
> psql postgresql://relation_id_9:V7kHqHyapIphkUS0cHoOtP3j@10.78.217.100:6432/mytestdb
psql (14.15 (Ubuntu 14.15-0ubuntu0.22.04.1), server 14.12 (Ubuntu 14.12-0ubuntu0.22.04.1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

mytestdb=> select now();
now
-------------------------------
2025-01-14 11:51:04.646245+00
(1 row)
```
Ensure your DNS records points to the virtual IP and that it is routable/reachable from outside of your network to connect using DNS:
```shell
psql postgresql://relation_id_9:V7kHqHyapIphkUS0cHoOtP3j@my-tls-example-db.local:6432/mytestdb
```
## (Optional) Add monitoring
Consider adding the [Canonical Observability Stack (COS)](https://charmhub.io/topics/canonical-observability-stack) to your setup for monitoring, alert rules, logs, and tracing.
>See: [PostgreSQL | How to enable monitoring](/t/10600), [PgBouncer | How to enable monitoring](/t/12308).
## High availability
[note type=caution]
In production environments, deploy different units into separate availability zones (AZ).
See: [How to deploy > Multi-AZ](/t/15749)
[/note]
At this point, Juju is responsible for the health of the clusters/applications:
* The PostgreSQL charm will restart the workload if PostgreSQL is not healthy.
* The Juju agent will restart the unit/vm/container if it is no longer reachable/healthy (in the same AZ).
* The Juju controller will make sure Juju agent is up and running and charm is healthy.
* The HACluster charm will make sure the VIP is always reachable and routes to a single PgBouncer.
* PgBouncer will balance incoming connections and makes sure write traffic goes to the primary PostgreSQL unit.
* The TLS operator (in this example, the `self-signed-certificates` charm) is responsible for providing all components with signed ready-to-use TLS artifacts.
## Troubleshooting
[Contact us](/t/11863) if you have any issues with this setup or would like help with a different use-case.
28 changes: 15 additions & 13 deletions docs/how-to/h-enable-tls.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,27 @@ If you're using `juju 2.9`, check the [`juju 3.0` Release Notes](https://juju.is

# How to enable TLS encryption

This guide will show how to enable TLS using the [`self-signed-certificates` operator](https://github.com/canonical/self-signed-certificates-operator) as an example.
This guide will show how to enable TLS/SSL on a PostgreSQL cluster using the [`self-signed-certificates` operator](https://github.com/canonical/self-signed-certificates-operator) as an example.

[note type="caution"]
**[Self-signed certificates](https://en.wikipedia.org/wiki/Self-signed_certificate) are not recommended for a production environment.**
This guide assumes everything is deployed within the same network and Juju model.

Check [this guide](/t/11664) for an overview of the TLS certificate charms available.
[/note]
> See also: [How to deploy for external TLS access](/t/16576)
## Summary
* Enable TLS
* Disable TLS
* Manage certificates
* Check certificates in use
* Update keys
* Check certificates in use
* Update keys
---

## Enable TLS

[note type="caution"]
**[Self-signed certificates](https://en.wikipedia.org/wiki/Self-signed_certificate) are not recommended for a production environment.**

Check [this guide about X.509 certificates](/t/11664) for an overview of all the TLS certificate charms available.
[/note]

First, deploy the TLS charm:
```shell
juju deploy self-signed-certificates
Expand All @@ -35,19 +38,18 @@ juju integrate self-signed-certificates postgresql
```

## Disable TLS
You can disable TLS by removing the integration.
Disable TLS by removing the integration.
```shell
juju remove-relation self-signed-certificates postgresql
```

## Manage certificates
### Check certificates in use
To check the certificates in use by PostgreSQL, you can run:
## Check certificates in use
To check the certificates in use by PostgreSQL, run
```shell
openssl s_client -starttls postgres -connect <leader_unit_IP>:<port> | grep issuer
```

### Update keys
## Update keys
Updates to private keys for certificate signing requests (CSR) can be made via the `set-tls-private-key` action. Note that passing keys to external/internal keys should *only be done with* `base64 -w0`, *not* `cat`.

With three replicas, this schema should be followed:
Expand Down
16 changes: 11 additions & 5 deletions docs/how-to/h-external-access.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
# How to connect DB from outside of DB LAN
# How to connect from outside the local network

This page summarizes resources for setting up deployments where an external application must connect to a PostgreSQL database from outside the local area network.

## External application (non-Juju)

[u]Use case[/u]: the client application is a non-Juju application outside of Juju / DB LAN.
**Use case**: The client application is a non-Juju application outside of the local area network where Juju and the database are running.

There are many possible ways to connect the Charmed PostgreSQL database from outside of the LAN where the database cluster is located. The available options are heavily dependent on the cloud/hardware/virtualization in use.

One of the possible options is to use [virtual IP addresses (VIP)](https://en.wikipedia.org/wiki/Virtual_IP_address) which the charm PgBouncer provides with assistance from the charm/interface `hacluster`. Please follow the [PgBouncer documentation](https://charmhub.io/pgbouncer/docs/h-external-access?channel=1/stable) for such configuration.

There are many possible ways to connect the Charmed PostgreSQL database from outside of the LAN the DB cluster is located. The available options are heavily depend on the cloud/hardware/virtualization in use. One of the possible options is to use [virtual IP addresses (VIP)](https://en.wikipedia.org/wiki/Virtual_IP_address) which the charm PgBouncer provides with assist of the charm/interface `hacluster`. Please follow the [PgBouncer documentation](https://charmhub.io/pgbouncer/docs/h-external-access?channel=1/stable) for such configuration.
> See also: [How to deploy for external TLS VIP access](/t/16576).
## External relation (Juju)

[u]Use case[/u]: the client application is a Juju application outside of DB deployment (e.g. hybrid Juju deployment with different VM clouds/controllers).
**Use case**: The client application is a Juju application outside the database deployment (e.g. hybrid Juju deployment with different VM clouds/controllers).

In this case the the cross-controllers-relation is necessary. Please [contact](/t/11863) Data team to discuss the possible option for your use case.
In this case, a cross-controller relation is necessary. Please [contact](/t/11863) the Data team to discuss possible options for your use case.
5 changes: 3 additions & 2 deletions docs/how-to/h-restore-backup.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ To restore a backup that was made from a *different* cluster, (i.e. cluster migr
- [Configured settings for S3 storage](/t/charmed-postgresql-how-to-configure-s3/9681?channel=14/stable)
- [Existing backups in your S3 storage](/t/charmed-postgresql-how-to-create-and-list-backups/9683?channel=14/stable)
- [Point-in-time recovery](#point-in-time-recovery) requires the following PostgreSQL charm revisions:
- 334+ for `arm64`
- 33+ for `amd64`
- 467+ for `arm64`
- 468+ for `amd64`

## Summary
* [List backups](#list-backups)
Expand Down Expand Up @@ -81,6 +81,7 @@ juju run postgresql/leader restore restore-to-time="YYYY-MM-DDTHH:MM:SSZ"
Your restore will then be in progress.

It’s also possible to restore to the latest point from a specific timeline by passing the ID of a backup taken on that timeline and `restore-to-time=latest` when requesting a restore:

```shell
juju run postgresql/leader restore restore-to-time=latest
```
1 change: 1 addition & 0 deletions docs/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ PostgreSQL is a trademark or registered trademark of PostgreSQL Global Developme
| 3 | h-deploy-multi-az | [Multi-AZ](/t/15749) |
| 3 | h-deploy-terraform | [Terraform](/t/14916) |
| 3 | h-deploy-airgapped | [Air-gapped](/t/15746) |
| 3 | h-deploy-tls-vip-access | [TLS VIP access](/t/16576) |
| 2 | h-integrate | [Integrate with another application](/t/9687) |
| 2 | h-external-access | [External access](/t/15802) |
| 2 | h-scale | [Scale replicas](/t/9689) |
Expand Down
6 changes: 2 additions & 4 deletions docs/reference/r-revision-517-518.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ Due to the newly added support for `arm64` architecture, the PostgreSQL charm no

## Highlights

* Upgraded PostgreSQL from v.14.12 → v.14.13 ([PR #633](https://github.com/canonical/postgresql-operator/pull/633))
* Check the official [PostgreSQL release notes](https://www.postgresql.org/docs/release/14.13/)
* Added timeline management to point-in-time recovery (PITR) ([PR #629](https://github.com/canonical/postgresql-operator/pull/629)) ([DPE-5561](https://warthogs.atlassian.net/browse/DPE-5561))
* Added pgAudit plugin/extension ([PR #612](https://github.com/canonical/postgresql-operator/pull/612)) ([DPE-5248](https://warthogs.atlassian.net/browse/DPE-5248))
* Observability stack (COS) improvements
Expand Down Expand Up @@ -72,10 +74,6 @@ Due to the newly added support for `arm64` architecture, the PostgreSQL charm no
* Increase linting rules ([PR #649](https://github.com/canonical/postgresql-operator/pull/649)) ([DPE-5324](https://warthogs.atlassian.net/browse/DPE-5324))
[/details]

## Known limitations
...
<TODO>

## Requirements and compatibility
* (no change) Minimum Juju 2 version: `v.2.9.49`
* (no change) Minimum Juju 3 version: `v.3.4.3`
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/t-set-up.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ All necessary components have been pre-installed inside VM already, like LXD and

<a href="#heading--juju"><h2 id="heading--juju"> Set up Juju </h2></a>

Let's bootstrap Juju to use the local LXD controller:
Let's bootstrap Juju to use the local LXD controller. We will call it “overlord”, but you can give it any name you’d like:
```shell
juju bootstrap localhost overlord
```
Expand Down

0 comments on commit 479bbc6

Please sign in to comment.