<a id="how-to-tls-termination-using-a-local-ca"></a>

# How to configure TLS termination using a local CA

This guide shows how to configure TLS termination for Traefik using a self-signed certificate
issued by a stand-in local certificate authority.

#### NOTE
This guide assumes you have a Juju controller bootstrapped on a `k8s` cloud that is ready to use. A typical setup using [snaps](https://snapcraft.io/) can be found in the [Juju docs](https://canonical.com/juju/docs/juju-cli/3.6/howto/manage-your-juju-deployment/set-up-your-juju-deployment-local-testing-and-development/#set-things-up). Follow the instructions there to install Juju and K8s.

## Configure K8s

Follow the [Getting started](https://documentation.ubuntu.com/canonical-kubernetes/latest/snap/tutorial/getting-started/) guide to install and bootstrap `k8s`, then configure the [default load balancer](https://documentation.ubuntu.com/canonical-kubernetes/latest/snap/howto/networking/default-loadbalancer/).

## Deploy the apps

Deploy Traefik, self-signed-certificates to function as a root CA, and Alertmanager, Prometheus, and Grafana, which use Traefik ingress.

First, create a new model:

```bash
juju add-model tls-demo
```

Next, save the following bundle as `tls-demo.yaml`:

```yaml
---
bundle: kubernetes
name: traefik-tls-demo

applications:
  traefik:
    charm: 'traefik-k8s'
    scale: 1
    trust: true
    channel: 'edge'
    options:
      external_hostname: 'demo.local'
  alertmanager:
    charm: 'alertmanager-k8s'
    scale: 1
    trust: true
    channel: 'edge'
  prometheus:
    charm: 'prometheus-k8s'
    scale: 1
    trust: true
    channel: 'edge'
  grafana:
    charm: 'grafana-k8s'
    scale: 1
    trust: true
    channel: 'edge'
  ca:
    charm: 'self-signed-certificates'
    scale: 1
    channel: 'edge'

relations:
- [traefik:ingress-per-unit, prometheus:ingress]
- [traefik:traefik-route, grafana:ingress]
- [traefik:ingress, alertmanager:ingress]
- [traefik:certificates, ca:certificates]
```

Finally, deploy the local bundle:

```bash
juju deploy --trust ./tls-demo.yaml
```

## Reach an application’s endpoint with ingress

### HTTP

First, obtain the ingress URL by using a Traefik action:

```default
juju run traefik/0 show-proxied-endpoints
```

The terminal output should look something like:

```text
Running operation 5 with 1 task
  - task 6 on unit-traefik-0

Waiting for task 6...
proxied-endpoints: '{
  "prometheus/0": {"url": "http://demo.local:80/tls-demo-prometheus-0"},
  "alertmanager": {"url": "http://demo.local:80/tls-demo-alertmanager"}
}'
```

Now obtain Traefik’s IP:

```bash
TRAEFIK_IP=$(\
  juju status --format json traefik \
  | jq -r ".applications.traefik.address"\
)
```

Use the ingress URL with the application’s HTTP API endpoint:

`user@host:~$ ``curl --resolve "demo.local:80:$TRAEFIK_IP" \
>   http://demo.local:80/tls-demo-alertmanager/-/ready`
```text
OK
```

`user@host:~$ ``curl --resolve "demo.local:80:$TRAEFIK_IP" \
>   http://demo.local:80/tls-demo-prometheus-0/-/ready`
```text
Prometheus Server is Ready.
```

### HTTPS

Save the certificate locally:

<!-- TODO avoid literal indexing -->
```bash
juju show-unit --format json traefik/0 \
  | jq -r '."traefik/0"."relation-info"[3]."application-data".certificates' \
  | jq -r '.[1].certificate' \
  > /tmp/local.cert
```

Save Traefik’s IP:

```bash
TRAEFIK_IP=$(\
  juju status --format json traefik \
  | jq -r ".applications.traefik.address"\
)
```

Curl the endpoint:

```bash
curl --resolve demo.local:443:$TRAEFIK_IP \
     --fail-with-body \
     --capath /tmp \
     --cacert /tmp/local.cert \
     https://demo.local/tls-demo-alertmanager/-/ready
```

This should return:

```text
OK
```
