Deploying for high availability
This page describes how to run the enterprise-store charm with multiple units for high availability, fronted by the haproxy charm which terminates client TLS at the edge and load-balances across the units.
It applies to both deployment modes: first deploy the charm as described in the Proxy mode or Offline mode guide, then add the haproxy integration and scale out as shown here. The snippets below show only the haproxy-specific parts, to be combined with the base deployment.
TLS options
If the registered store uses https, TLS can be handled in two ways:
- Let the charm terminate TLS, by setting the enterprise-store
certificate/private_keyconfig options (or set both toselfsignedfor a self-signed certificate). This is suitable for a single-unit deployment. - Put the haproxy charm in front of it via the
haproxy-routeinterface, in which case haproxy terminates TLS at the edge and the enterprise-store is served over plain HTTP behind it. This is the recommended option for a multi-unit, highly available deployment.
Fronting with HAProxy
The charm can be placed behind the haproxy charm (channel 2.8/stable) using
the haproxy-route interface. In this mode haproxy terminates client TLS at the
edge and the enterprise-store snap is served over plain HTTP behind it. The snap
honours the X-Forwarded-Proto header, so it still advertises https:// URLs
to clients.
Two constraints apply when fronting with haproxy:
- The registration bundle’s
domainmust be haproxy’s public hostname, and haproxy’s edge certificate must cover that hostname. Clients connect to whateverdomainis in the bundle. - Do not set the enterprise-store
certificate/private_keyconfig options while related viahaproxy-route. The haproxy charm owns TLS termination in this mode so setting them is contradictory. In the case these charm configs are set, the integration of thehaproxy-routewill unset them at the snap level and the stalecertificate/private_keyconfigs will need to be unset manually.
Scaling out
The charm supports multiple units for high availability; deploy with
num_units / units greater than one, or scale later:
juju add-unit enterprise-store
Configuration, certificate and snap changes are coordinated across units through
the rollingops-peers peer relation so that at most one unit restarts its
services at a time. See the upgrading page for more detail on rolling
operations.
Deploy with the Juju CLI
In addition to the base deployment, deploy haproxy with a certificate provider, relate both, and scale the enterprise-store to multiple units:
juju deploy haproxy --channel 2.8/stable
juju deploy self-signed-certificates
juju integrate haproxy:certificates self-signed-certificates
juju integrate enterprise-store:haproxy-route haproxy:haproxy-route
juju add-unit enterprise-store -n 2
Deploy with a Juju bundle
Add the haproxy-specific applications and relations to your deployment bundle, and set the enterprise-store to multiple units:
applications:
haproxy:
charm: haproxy
channel: 2.8/stable
num_units: 1
self-signed-certificates:
charm: self-signed-certificates
num_units: 1
enterprise-store:
num_units: 3
relations:
- - haproxy:certificates
- self-signed-certificates:certificates
- - enterprise-store:haproxy-route
- haproxy:haproxy-route
Deploy with Terraform
Add the haproxy-specific resources to the module containing your base
deployment. They reference the enterprise-store application and the model
defined there (replace <model> with your model resource name):
resource "juju_application" "self-signed-certificates" {
name = "self-signed-certificates"
model_uuid = juju_model.<model>.uuid
charm {
name = "self-signed-certificates"
}
}
resource "juju_application" "haproxy" {
name = "haproxy"
model_uuid = juju_model.<model>.uuid
charm {
name = "haproxy"
channel = "2.8/stable"
}
}
resource "juju_integration" "haproxy-self-signed" {
model_uuid = juju_model.<model>.uuid
application {
name = juju_application.haproxy.name
endpoint = "certificates"
}
application {
name = juju_application.self-signed-certificates.name
endpoint = "certificates"
}
}
resource "juju_integration" "haproxy-route" {
model_uuid = juju_model.<model>.uuid
application {
name = juju_application.haproxy.name
endpoint = "haproxy-route"
}
application {
name = juju_application.enterprise-store.name
endpoint = "haproxy-route"
}
}
Set units = 3 (or higher) on the enterprise-store application in your base
deployment to run multiple units behind haproxy.