How to install and configure Landscape for high-availability deployments¶
See also: Juju documentation
You can create a scalable, high availability (HA) deployment of Landscape Server with Juju. The result is a Juju-managed deployment of Landscape Server and the other services it depends on.
You can follow the manual bundle approach below, or use the Landscape Scalable Terraform product module instead: it manages the same HA architecture reproducibly, and its inputs/outputs are documented in the module reference.
Important
This guide covers both the 26.04 deployment approach and the older pre-26.04 deployment approach. The 26.04 version integrates directly with the external HAProxy charm (2.8/stable) using the haproxy-route interface, replacing the older reverseproxy interface. For new deployments, use the 26.04 approach. For existing deployments, see How to migrate to Landscape 26.04 LTS (charm).
The Charmhub landscape-scalable bundle does not currently publish a 26.04/* track, so 26.04 (and later) bundle deployments require a custom bundle such as the one shown in this guide.
Architecture overview¶
Select your Landscape Server version:
Starting with the 26.04 version, Landscape Server uses the following architecture:
Landscape Server units for the application
HAProxy charm (
2.8/stable) for load balancing via thehaproxy-routeinterfacePostgreSQL 14+ for the database (using the modern
databaserelation, backed by thepostgresql_clientinterface)RabbitMQ Server for message queuing
Self-signed certificates charm (or other TLS provider) integrated with HAProxy
Debarchive charm for repository mirroring, integrated with Landscape Server (
debarchiverelation) and PostgreSQLLandscape Task Handler charm for offloaded task processing, integrated with Landscape Server (
task-handlerrelation), PostgreSQL (task-db), the TLS certificates provider, and HAProxy over thegrpc-haproxy-route/haproxy-route-tcpinterface
HAProxy sits in front of all Landscape Server units and routes traffic to the appropriate service endpoints.
flowchart TD
Client([Client])
TLS[TLS Provider]
subgraph model[Juju model]
HAProxy["HAProxy<br/>2.8/stable"]
LS0[landscape-server/0]
LS1[landscape-server/1]
LS2[landscape-server/2]
PG[(PostgreSQL)]
RMQ[RabbitMQ Server]
DA[landscape-debarchive]
TH[landscape-task-handler]
end
TLS -- certificates --> HAProxy
TLS -- certificates --> TH
Client -- HTTPS --> HAProxy
HAProxy -- haproxy-route --> LS0
HAProxy -- haproxy-route --> LS1
HAProxy -- haproxy-route --> LS2
LS0 & LS1 & LS2 --- PG
LS0 & LS1 & LS2 --- RMQ
LS0 -- debarchive --> DA
DA --- PG
HAProxy -- debarchive-haproxy-route --> DA
LS0 -- task-handler --> TH
TH --- PG
HAProxy -- grpc-haproxy-route --> TH
The older approach uses:
External HAProxy charm for load balancing
PostgreSQL 14 for the database (using the legacy
pgsqlinterface)RabbitMQ Server for message queuing
Separate HAProxy units for traffic management
flowchart TD
Client([Client])
subgraph model[Juju model]
HAProxy["HAProxy<br/>latest/stable"]
LS0[landscape-server/0]
LS1[landscape-server/1]
LS2[landscape-server/2]
PG[(PostgreSQL 14)]
RMQ[RabbitMQ Server]
end
Client -- HTTPS --> HAProxy
HAProxy -- reverseproxy --> LS0
HAProxy -- reverseproxy --> LS1
HAProxy -- reverseproxy --> LS2
LS0 & LS1 & LS2 --- PG
LS0 & LS1 & LS2 --- RMQ
Prerequisites¶
Before you can deploy Landscape with Juju, you need to:
Attach your Ubuntu Pro token to each machine that will host Landscape Server components. For guidance, see How to attach your Ubuntu Pro subscription.
These steps prepare your environment to deploy machine charms with Juju and integrate them using relations.
Note
For improved database performance and scalability in high-load deployments, consider using PgBouncer as a connection pooler between Landscape Server and PostgreSQL. PgBouncer integrates via the Landscape Server charm’s database relation endpoint, which uses the underlying postgresql_client interface. This requires recent Landscape Server charm revisions with postgresql_client support. See PgBouncer integration with Landscape Server for more information.
Deployment approach selection¶
Choose the appropriate deployment approach based on your needs, then follow that section:
For new deployments: Use the 26.04 deployment (recommended)
For existing deployments: Continue with the pre-26.04 deployment or migrate using How to migrate to Landscape 26.04 LTS (charm)
26.04 deployment (recommended)¶
This section covers deploying Landscape Server with the external HAProxy charm introduced in version 26.04.
Create a Juju model¶
juju add-model landscape-ha
Deploy with a custom bundle file¶
For the 26.04 deployment, you’ll create a custom bundle file that includes all the necessary components.
Step 1: Create the bundle file¶
Create a file named landscape-ha-26.04.yaml with the following content:
description: Landscape Scalable
applications:
postgresql:
channel: 16/stable
charm: ch:postgresql
num_units: 3
options:
plugin_plpython3u_enable: true
plugin_ltree_enable: true
plugin_intarray_enable: true
plugin_debversion_enable: true
plugin_pg_trgm_enable: true
experimental_max_connections: 500
base: ubuntu@24.04
rabbitmq-server:
channel: latest/edge
charm: ch:rabbitmq-server
num_units: 3
options:
consumer-timeout: 259200000
landscape-server:
charm: ch:landscape-server
channel: 26.04/stable
num_units: 3
options:
landscape_ppa: ppa:landscape/self-hosted-26.04
root_url: https://landscape.example.com/
base: ubuntu@24.04
haproxy:
charm: ch:haproxy
channel: 2.8/stable
num_units: 1
constraints: arch=amd64
self-signed-certificates:
charm: ch:self-signed-certificates
channel: 1/stable
num_units: 1
constraints: arch=amd64
landscape-debarchive:
charm: ch:landscape-debarchive
channel: latest/stable
num_units: 1
base: ubuntu@24.04
landscape-task-handler:
charm: ch:landscape-task-handler
channel: latest/stable
num_units: 1
options:
task-handler-snap-channel: latest/stable
base: ubuntu@24.04
relations:
- [landscape-server:inbound-amqp, rabbitmq-server]
- [landscape-server:outbound-amqp, rabbitmq-server]
- [landscape-server:database, postgresql:database]
- [haproxy:certificates, self-signed-certificates:certificates]
- [haproxy:receive-ca-certs, self-signed-certificates:send-ca-cert]
- [landscape-server:appserver-haproxy-route, haproxy:haproxy-route]
- [landscape-server:pingserver-haproxy-route, haproxy:haproxy-route]
- [landscape-server:message-server-haproxy-route, haproxy:haproxy-route]
- [landscape-server:api-haproxy-route, haproxy:haproxy-route]
- [landscape-server:package-upload-haproxy-route, haproxy:haproxy-route]
- [landscape-server:repository-haproxy-route, haproxy:haproxy-route]
- [landscape-debarchive:database, postgresql:database]
- [landscape-debarchive:debarchive-haproxy-route, haproxy:haproxy-route]
- [landscape-server:debarchive, landscape-debarchive:landscape-server]
- [landscape-task-handler:task-db, postgresql:database]
- [landscape-task-handler:landscape-server, landscape-server:task-handler]
- [landscape-task-handler:certificates, self-signed-certificates:certificates]
- [landscape-task-handler:grpc-haproxy-route, haproxy:haproxy-route-tcp]
Note
This example bundle uses PostgreSQL 16 (PostgreSQL 14+ also works) over the database relation, backed by the postgresql_client interface. Adjust the root_url option to match your domain name, see Step 5: Access Landscape below for why setting a real hostname matters. The hostagent messenger and Ubuntu installer attach HAProxy relations are omitted here since they’re optional, only add them if you enable the matching landscape-server config options. landscape-debarchive (Debarchive) provides repository mirroring and landscape-task-handler offloads background task processing to a dedicated unit; both are required.
Step 2: Deploy the bundle¶
juju deploy ./landscape-ha-26.04.yaml
Step 3: Monitor the deployment¶
Watch the deployment progress:
juju status --watch 3s
Once everything is installed and settled, the Status for every application will be active:
App Version Status Scale Charm Channel Rev
haproxy active 1 haproxy 2.8/stable 485
landscape-debarchive active 1 landscape-debarchive latest/stable 2
landscape-server active 3 landscape-server 26.04/stable 505
landscape-task-handler active 1 landscape-task-handler latest/stable 3
postgresql 16.11 active 3 postgresql 16/stable 1047
rabbitmq-server 3.12.1 active 3 rabbitmq-server latest/edge 252
self-signed-certificates active 1 self-signed-certificates 1/stable 22
Step 4: Configure license file¶
Set your Landscape license:
juju config landscape-server "license_file=$(cat your-license-file)"
Step 5: Access Landscape¶
HAProxy routes traffic based on the hostname configured in the haproxy-route relation, not by IP address alone, so you must connect using the hostname set in root_url (via DNS, or curl --resolve/a /etc/hosts entry for testing) — connecting directly to the HAProxy unit’s IP with no matching Host header returns HAProxy’s default page, not Landscape. If you omit root_url, the landscape-server charm falls back to using its leader unit’s IP address as the routing hostname instead, which is impractical to connect with directly; setting root_url to a real hostname is strongly recommended even for testing. Use juju status to find the HAProxy unit IP address to point that hostname at.
Important
This same hostname resolution requirement also applies internally: the outbox component running on the landscape-server units connects to the Task Handler’s gRPC server through HAProxy’s grpc-haproxy-route/haproxy-route-tcp passthrough, using the same hostname. If that hostname doesn’t resolve on the landscape-server units (for example, when deploying locally without a real domain), add an /etc/hosts entry on those units pointing the hostname at the HAProxy unit’s IP address. This dependency is one-directional: outbox (on landscape-server) connects to Task Handler, but Task Handler never needs to resolve or connect back to landscape-server.
Optional: Replace self-signed certificates with a valid certificate¶
If you deployed the example bundle above, it includes self-signed certificates (suitable for testing). For production, replace them with a valid certificate, such as one from Let’s Encrypt:
juju remove-application self-signed-certificates
juju deploy lego --channel 4/stable
juju config lego server="https://acme-v02.api.letsencrypt.org/directory"
juju config lego email="admin@example.com"
juju config lego plugin="http"
juju integrate haproxy:certificates lego:certificates
juju integrate haproxy:receive-ca-certs lego:send-ca-cert
Prerequisites:
Domain in
root_urlmust resolve to the HAProxy unit IPPort 80 must be accessible for ACME HTTP-01 challenge validation
Valid email for certificate notifications
For more details, see the lego charm documentation.
Optional: External Load Balancer with Cross-Model Integration (LBaaS)¶
For production deployments requiring an external load balancer in a separate infrastructure layer, you can deploy HAProxy in a separate Juju model and connect it to Landscape Server using cross-model relations (also known as LBaaS - Load Balancer as a Service).
This approach is useful when:
You want to manage your load balancer infrastructure separately from application deployments
You need a dedicated load balancer shared across multiple applications
You want to isolate load balancer lifecycle from application lifecycle
Step 1: Create a separate model for the load balancer¶
juju add-model lbaas
juju switch lbaas
Step 2: Deploy HAProxy and TLS certificates in the LBaaS model¶
Deploy HAProxy:
juju deploy haproxy --channel 2.8/stable
juju expose haproxy
Deploy the TLS certificates provider:
juju deploy lego --channel 4/stable
juju config lego server="https://acme-v02.api.letsencrypt.org/directory"
juju config lego email="admin@example.com"
juju config lego plugin="http"
Wait for both applications to become active:
juju wait-for application haproxy --query='status=="active"'
juju wait-for application lego --query='status=="active"'
Integrate HAProxy with the TLS certificates provider:
juju integrate haproxy:certificates lego:certificates
juju integrate haproxy:receive-ca-certs lego:send-ca-cert
Step 3: Create a cross-model offer¶
juju offer haproxy:haproxy-route,haproxy-route-tcp
This creates a single offer exposing both the haproxy-route and haproxy-route-tcp endpoints, which can be consumed from other Juju models. haproxy-route-tcp is needed for landscape-task-handler (required), and also if you enable the optional hostagent messenger or Ubuntu installer attach services on landscape-server.
Step 4: Consume the HAProxy offer and integrate Landscape Server¶
Switch back to your Landscape Server model:
juju switch landscape-ha
Consume the HAProxy offer from the lbaas model:
juju consume admin/lbaas.haproxy lbaas-haproxy
Integrate Landscape Server’s route endpoints directly with the external HAProxy:
juju integrate landscape-server:appserver-haproxy-route lbaas-haproxy:haproxy-route
juju integrate landscape-server:pingserver-haproxy-route lbaas-haproxy:haproxy-route
juju integrate landscape-server:message-server-haproxy-route lbaas-haproxy:haproxy-route
juju integrate landscape-server:api-haproxy-route lbaas-haproxy:haproxy-route
juju integrate landscape-server:package-upload-haproxy-route lbaas-haproxy:haproxy-route
juju integrate landscape-server:repository-haproxy-route lbaas-haproxy:haproxy-route
Integrate Debarchive’s debarchive-haproxy-route endpoint the same way, so it’s reachable through the external HAProxy:
juju integrate landscape-debarchive:debarchive-haproxy-route lbaas-haproxy:haproxy-route
Integrate landscape-task-handler’s gRPC route with the haproxy-route-tcp endpoint of the same offer:
juju integrate landscape-task-handler:grpc-haproxy-route lbaas-haproxy:haproxy-route-tcp
If you enable the optional hostagent messenger or Ubuntu installer attach services on landscape-server, integrate their HAProxy endpoints with lbaas-haproxy:haproxy-route-tcp the same way, after enabling the matching charm config.
Important
The outbox component on the landscape-server units reaches Task Handler through this HAProxy route by hostname, not by IP. If that hostname doesn’t resolve on the landscape-server units (for example, testing locally without a real domain), add an /etc/hosts entry there pointing it at the external HAProxy’s IP address.
Wait for the deployment to complete:
juju wait-for application landscape-server --query='status=="active"'
Step 5: Configure DNS and access¶
Get the HAProxy public IP address:
juju switch lbaas
juju status haproxy --format=json | jq -r '.applications.haproxy.units | to_entries[0].value["public-address"]'
Configure your DNS to point your hostname (matching root_url) to this IP address.
Access Landscape via: https://landscape.example.com/
flowchart TD
Client([Client])
subgraph lbaas[Juju model: lbaas]
HAProxy["HAProxy<br/>2.8/stable"]
TLS[lego / TLS provider]
end
subgraph landscape-ha[Juju model: landscape-ha]
LS0[landscape-server/0]
LS1[landscape-server/1]
LS2[landscape-server/2]
PG[(PostgreSQL)]
RMQ[RabbitMQ Server]
end
TLS -- certificates --> HAProxy
Client -- HTTPS --> HAProxy
HAProxy -- "haproxy-route (cross-model)" --> LS0
HAProxy -- "haproxy-route (cross-model)" --> LS1
HAProxy -- "haproxy-route (cross-model)" --> LS2
LS0 & LS1 & LS2 --- PG
LS0 & LS1 & LS2 --- RMQ
Pre-26.04 deployment¶
Warning
This deployment approach is deprecated. For new deployments, use the 26.04 approach described above. For existing deployments, consider migrating using How to migrate to Landscape 26.04 LTS (charm).
This section covers the older deployment approach using the external HAProxy charm. This approach is maintained for existing deployments only.
Deploy the charm bundle¶
See also: Landscape Scalable bundle on Charmhub
You can deploy the Landscape Scalable charm bundle using one of two main methods. The methods are:
Deploy the bundle with the default configuration, then customize the configuration
Download the bundle configuration, customize it, then deploy it
This guide describes both methods.
Option 1: Deploy with the default configuration¶
Once you have a Juju machine cloud configured, deploying the charm bundle with the default configuration is relatively straightforward.
Step 1: Create a Juju model¶
juju add-model landscape-self-hosted
Step 2: Deploy landscape-scalable¶
You can deploy the landscape-scalable charm bundle directly.
juju deploy landscape-scalable
It will take some time for the bundle to finish deploying. You can watch the deployment progress with juju status:
juju status --watch 3s
--watch refreshes the status periodically. This example is set to refresh every three seconds.
You can also check the status at any time without --watch:
juju status
At first, the juju status output will indicate that all units are waiting for machines to become available:
Model Controller Cloud/Region Version SLA Timestamp
landscape-self-hosted localhost-localhost localhost/localhost 3.5.5 unsupported 15:12:31-08:00
App Version Status Scale Charm Channel Rev Exposed Message
haproxy waiting 0/1 haproxy latest/stable 75 yes waiting for machine
landscape-server waiting 0/1 landscape-server latest/stable 124 no waiting for machine
postgresql waiting 0/1 postgresql 14/stable 468 no waiting for machine
rabbitmq-server waiting 0/1 rabbitmq-server 3.9/stable 188 no waiting for machine
Unit Workload Agent Machine Public address Ports Message
haproxy/0 waiting allocating 0 waiting for machine
landscape-server/0 waiting allocating 1 waiting for machine
postgresql/0 waiting allocating 2 waiting for machine
rabbitmq-server/0 waiting allocating 3 waiting for machine
Machine State Address Inst id Base AZ Message
0 pending pending ubuntu@22.04
1 pending pending ubuntu@22.04
2 pending pending ubuntu@22.04
3 pending pending ubuntu@22.04
Once everything is installed and settled, the Status for every application will be active:
Model Controller Cloud/Region Version SLA Timestamp
landscape-self-hosted localhost-localhost localhost/localhost 3.5.5 unsupported 15:28:30-08:00
App Version Status Scale Charm Channel Rev Exposed Message
haproxy active 1 haproxy latest/stable 75 yes Unit is ready
landscape-server active 1 landscape-server latest/stable 124 no Unit is ready
postgresql 14.12 active 1 postgresql 14/stable 468 no
rabbitmq-server 3.9.27 active 1 rabbitmq-server 3.9/stable 188 no Unit is ready
Unit Workload Agent Machine Public address Ports Message
haproxy/0* active idle 0 10.76.244.244 80,443/tcp Unit is ready
landscape-server/0* active idle 1 10.76.244.6 Unit is ready
postgresql/0* active idle 2 10.76.244.26 5432/tcp Primary
rabbitmq-server/0* active idle 3 10.76.244.71 5672,15672/tcp Unit is ready
Machine State Address Inst id Base AZ Message
0 started 10.76.244.244 juju-dded29-0 ubuntu@22.04 Running
1 started 10.76.244.6 juju-dded29-1 ubuntu@22.04 Running
2 started 10.76.244.26 juju-dded29-2 ubuntu@22.04 Running
3 started 10.76.244.71 juju-dded29-3 ubuntu@22.04 Running
Step 3: Add application units¶
The following commands add two additional units of Landscape Server, PostgreSQL, RabbitMQ, and HAProxy. Execute these commands to create your high availability deployment with three units of each service.
juju add-unit landscape-server -n 2
juju add-unit postgresql -n 2
juju add-unit rabbitmq-server -n 2
juju add-unit haproxy -n 2
The charms for each application handle relationships between the units. The unit indicated with an asterisk (*) in the juju status output is the current leader unit.
After the new units are given machines and the charm installation and setup is complete, the result is a high availability deployment:
Model Controller Cloud/Region Version SLA Timestamp
landscape-self-hosted localhost-localhost localhost/localhost 3.5.5 unsupported 15:49:11-08:00
App Version Status Scale Charm Channel Rev Exposed Message
haproxy active 3 haproxy latest/stable 75 yes Unit is ready
landscape-server active 3 landscape-server latest/stable 124 no Unit is ready
postgresql 14.12 active 3 postgresql 14/stable 468 no
rabbitmq-server 3.9.27 active 3 rabbitmq-server 3.9/stable 188 no Unit is ready
Unit Workload Agent Machine Public address Ports Message
haproxy/0* active idle 0 10.76.244.244 80,443/tcp Unit is ready
haproxy/1 active idle 6 10.76.244.204 80,443/tcp Unit is ready
haproxy/2 active idle 7 10.76.244.41 80,443/tcp Unit is ready
landscape-server/0* active idle 1 10.76.244.6 Unit is ready
landscape-server/1 active idle 4 10.76.244.192 Unit is ready
landscape-server/2 active idle 5 10.76.244.237 Unit is ready
postgresql/0* active idle 2 10.76.244.26 5432/tcp Primary
postgresql/1 active idle 8 10.76.244.43 5432/tcp
postgresql/2 active idle 9 10.76.244.32 5432/tcp
rabbitmq-server/0* active idle 3 10.76.244.71 5672,15672/tcp Unit is ready and clustered
rabbitmq-server/1 active idle 10 10.76.244.98 5672,15672/tcp Unit is ready and clustered
rabbitmq-server/2 active idle 11 10.76.244.45 5672,15672/tcp Unit is ready and clustered
Machine State Address Inst id Base AZ Message
0 started 10.76.244.244 juju-dded29-0 ubuntu@22.04 Running
1 started 10.76.244.6 juju-dded29-1 ubuntu@22.04 Running
2 started 10.76.244.26 juju-dded29-2 ubuntu@22.04 Running
3 started 10.76.244.71 juju-dded29-3 ubuntu@22.04 Running
4 started 10.76.244.192 juju-dded29-4 ubuntu@22.04 Running
5 started 10.76.244.237 juju-dded29-5 ubuntu@22.04 Running
6 started 10.76.244.204 juju-dded29-6 ubuntu@22.04 Running
7 started 10.76.244.41 juju-dded29-7 ubuntu@22.04 Running
8 started 10.76.244.43 juju-dded29-8 ubuntu@22.04 Running
9 started 10.76.244.32 juju-dded29-9 ubuntu@22.04 Running
10 started 10.76.244.98 juju-dded29-10 ubuntu@22.04 Running
11 started 10.76.244.45 juju-dded29-11 ubuntu@22.04 Running
You now have Landscape Server set up for a high-availability deployment. Next, you need to set up your clients by installing the Landscape Client charm on each client, and configuring them with the juju config command. You may also need to change your SSL certificate configuration. See the Configure SSL certificates (pre-26.04 deployments only) section in this guide for more information.
Option 2: Customize the configuration before deployment¶
If you would rather do all of your configuration up-front and then let Juju orchestrate everything during deployment, you can download the charm bundle’s YAML file and customize it.
Step 1: Download the landscape-scalable charm bundle¶
juju download landscape-scalable
You’ll get output similar to:
Fetching bundle "landscape-scalable" revision 37 using "stable" channel and base "amd64/ubuntu/22.04"
Install the "landscape-scalable" bundle with:
juju deploy ./landscape-scalable_r37.bundle
Then, unzip it:
unzip ./landscape-scalable_r37.bundle
You’ll get output similar to:
Archive: ./landscape-scalable_r37.bundle
inflating: bundle.yaml
inflating: README.md
inflating: manifest.yaml
Step 2: Edit the bundle.yaml file¶
You need to increase the num_units for each application to turn your deployment into a high availability deployment. In this example, we set each service to num_units: 3. This means there will be three units of each Landscape Server, HAProxy, PostgreSQL, and RabbitMQ.
description: Landscape Scalable
name: landscape-scalable
series: jammy
docs: https://discourse.charmhub.io/t/landscape-charm-bundles/10638
applications:
haproxy:
charm: ch:haproxy
channel: stable
revision: 75
num_units: 3
expose: true
options:
default_timeouts: queue 60000, connect 5000, client 120000, server 120000
global_default_bind_options: no-tlsv10
services: ""
ssl_cert: SELFSIGNED
landscape-server:
charm: ch:landscape-server
channel: stable
revision: 124
num_units: 3
constraints: mem=4096
options:
landscape_ppa: ppa:landscape/self-hosted-24.04
postgresql:
charm: ch:postgresql
channel: 14/stable
revision: 468
num_units: 3
options:
plugin_plpython3u_enable: true
plugin_ltree_enable: true
plugin_intarray_enable: true
plugin_debversion_enable: true
plugin_pg_trgm_enable: true
experimental_max_connections: 500
constraints: mem=2048
rabbitmq-server:
charm: ch:rabbitmq-server
channel: 3.9/stable
revision: 188
num_units: 3
options:
consumer-timeout: 259200000
relations:
- [landscape-server, rabbitmq-server]
- [landscape-server, haproxy]
- [landscape-server:db, postgresql:db-admin]
Step 3: Deploy the bundle.yaml file¶
juju deploy ./bundle.yaml
It will take some time for the bundle to finish deploying, you can watch the deployment progress with juju status:
juju status --watch 3s
--watch refreshes the status periodically. This example is set to refresh every three seconds.
You can also check the status at any time without --watch:
juju status
At first, the juju status output will indicate that all units are waiting for machines to become available:
Model Controller Cloud/Region Version SLA Timestamp
landscape-self-hosted localhost-localhost localhost/localhost 3.5.5 unsupported 16:20:40-08:00
App Version Status Scale Charm Channel Rev Exposed Message
haproxy waiting 0/3 haproxy latest/stable 75 yes waiting for machine
landscape-server waiting 0/3 landscape-server latest/stable 124 no waiting for machine
postgresql waiting 0/3 postgresql 14/stable 468 no waiting for machine
rabbitmq-server waiting 0/3 rabbitmq-server 3.9/stable 188 no waiting for machine
Unit Workload Agent Machine Public address Ports Message
haproxy/0 waiting allocating 0 waiting for machine
haproxy/1 waiting allocating 1 waiting for machine
haproxy/2 waiting allocating 2 waiting for machine
landscape-server/0 waiting allocating 3 waiting for machine
landscape-server/1 waiting allocating 4 waiting for machine
landscape-server/2 waiting allocating 5 waiting for machine
postgresql/0 waiting allocating 6 waiting for machine
postgresql/1 waiting allocating 7 waiting for machine
postgresql/2 waiting allocating 8 waiting for machine
rabbitmq-server/0 waiting allocating 9 waiting for machine
rabbitmq-server/1 waiting allocating 10 waiting for machine
rabbitmq-server/2 waiting allocating 11 waiting for machine
Machine State Address Inst id Base AZ Message
0 pending pending ubuntu@22.04
1 pending pending ubuntu@22.04
2 pending pending ubuntu@22.04
3 pending pending ubuntu@22.04
4 pending pending ubuntu@22.04
5 pending pending ubuntu@22.04
6 pending pending ubuntu@22.04
7 pending pending ubuntu@22.04
8 pending pending ubuntu@22.04
9 pending pending ubuntu@22.04
10 pending pending ubuntu@22.04
11 pending pending ubuntu@22.04
Once everything is installed and settled, the Status for every application will be active:
Model Controller Cloud/Region Version SLA Timestamp
landscape-self-hosted localhost-localhost localhost/localhost 3.5.5 unsupported 16:30:52-08:00
App Version Status Scale Charm Channel Rev Exposed Message
haproxy active 3 haproxy latest/stable 75 yes Unit is ready
landscape-server active 3 landscape-server latest/stable 124 no Unit is ready
postgresql 14.12 active 3 postgresql 14/stable 468 no
rabbitmq-server 3.9.27 active 3 rabbitmq-server 3.9/stable 188 no Unit is ready
Unit Workload Agent Machine Public address Ports Message
haproxy/0* active idle 0 10.76.244.87 80,443/tcp Unit is ready
haproxy/1 active idle 1 10.76.244.102 80,443/tcp Unit is ready
haproxy/2 active idle 2 10.76.244.250 80,443/tcp Unit is ready
landscape-server/0* active idle 3 10.76.244.17 Unit is ready
landscape-server/1 active idle 4 10.76.244.212 Unit is ready
landscape-server/2 active idle 5 10.76.244.170 Unit is ready
postgresql/0* active idle 6 10.76.244.112 5432/tcp Primary
postgresql/1 active idle 7 10.76.244.166 5432/tcp
postgresql/2 active idle 8 10.76.244.165 5432/tcp
rabbitmq-server/0* active idle 9 10.76.244.14 5672,15672/tcp Unit is ready and clustered
rabbitmq-server/1 active idle 10 10.76.244.237 5672,15672/tcp Unit is ready and clustered
rabbitmq-server/2 active idle 11 10.76.244.179 5672,15672/tcp Unit is ready and clustered
Machine State Address Inst id Base AZ Message
0 started 10.76.244.87 juju-be1fab-0 ubuntu@22.04 Running
1 started 10.76.244.102 juju-be1fab-1 ubuntu@22.04 Running
2 started 10.76.244.250 juju-be1fab-2 ubuntu@22.04 Running
3 started 10.76.244.17 juju-be1fab-3 ubuntu@22.04 Running
4 started 10.76.244.212 juju-be1fab-4 ubuntu@22.04 Running
5 started 10.76.244.170 juju-be1fab-5 ubuntu@22.04 Running
6 started 10.76.244.112 juju-be1fab-6 ubuntu@22.04 Running
7 started 10.76.244.166 juju-be1fab-7 ubuntu@22.04 Running
8 started 10.76.244.165 juju-be1fab-8 ubuntu@22.04 Running
9 started 10.76.244.14 juju-be1fab-9 ubuntu@22.04 Running
10 started 10.76.244.237 juju-be1fab-10 ubuntu@22.04 Running
11 started 10.76.244.179 juju-be1fab-11 ubuntu@22.04 Running
You now have Landscape Server set up for a high-availability deployment. Next, you need to set up your clients by installing the Landscape Client charm on each client, and configuring them with the juju config command. You may also need to change your SSL certificate configuration. See the Configure SSL certificates (pre-26.04 deployments only) section in this guide for more information.
Configure SSL certificates (pre-26.04 deployments only)¶
Warning
This section applies only to pre-26.04 deployments using the external HAProxy charm. For 26.04 deployments, see the TLS certificates configuration in the 26.04 deployment section above.
For pre-26.04 deployments with external HAProxy charm¶
The older HAProxy charm uses self-signed SSL certificates by default. Landscape Clients and your browser won’t trust this certificate.
Option 1: Manual certificate configuration
If you have a valid SSL certificate:
juju config haproxy ssl_cert="$(base64 fullchain.pem)" ssl_key="$(base64 privkey.pem)"
Option 2: Let’s Encrypt with certbot
If your Landscape instance has a public IP and your FQDN resolves to it:
# On a machine with port 80 accessible
sudo certbot certonly --standalone -d $FQDN --non-interactive --agree-tos --email admin@example.com
This produces fullchain.pem and privkey.pem files:
juju config haproxy ssl_cert="$(base64 /etc/letsencrypt/live/$FQDN/fullchain.pem)" \
ssl_key="$(base64 /etc/letsencrypt/live/$FQDN/privkey.pem)"
Note
Certificate renewal must be handled manually for pre-26.04 deployments. Consider migrating to 26.04 for automatic certificate management via the tls-certificates interface.