From 614c4b1aa6c17ea03919a583e5056039f876eb39 Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Sat, 25 Jul 2026 18:19:38 +1000 Subject: [PATCH] Route consul API hostname to the HTTP API (8500) (#282) Phase 2 of the consul migration: expose the HTTP API (not just the UI) at consul.k8s.syd1.au.unkin.net, now rebased onto main post-#280 (ACLs enabled). - Adds a consul-http ClusterIP service targeting the server pods on 8500 (API + UI share the port, so the UI stays reachable at /ui/) - Repoints the consul and consul-svc HTTPRoutes from consul-ui:80 to consul-http:8500 - Documents ACL-authenticated access in apps/base/consul/README.md: token from kv/kubernetes/namespace/consul/default/bootstrap-acl-token (VSO-synced), X-Consul-Token curl and consul CLI usage, UI token login, and the prefer-vault-minted-tokens note Verification post-merge (ACLs are live, so authenticated): CONSUL_HTTP_TOKEN=$(vault kv get -field=token kv/kubernetes/namespace/consul/default/bootstrap-acl-token) && curl -H "X-Consul-Token: $CONSUL_HTTP_TOKEN" https://consul.k8s.syd1.au.unkin.net/v1/status/leader Rollback: revert the HTTPRoute backends to consul-ui:80. Reviewed-on: https://git.unkin.net/unkin/argocd-apps/pulls/282 Co-authored-by: Ben Vincent Co-committed-by: Ben Vincent --- apps/base/consul/README.md | 30 +++++++++++++++++++++++++++++ apps/base/consul/httproute.yaml | 8 ++++---- apps/base/consul/kustomization.yaml | 1 + apps/base/consul/service.yaml | 25 ++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 apps/base/consul/README.md create mode 100644 apps/base/consul/service.yaml diff --git a/apps/base/consul/README.md b/apps/base/consul/README.md new file mode 100644 index 0000000..9e2e691 --- /dev/null +++ b/apps/base/consul/README.md @@ -0,0 +1,30 @@ +# consul (k8s) + +Consul server cluster (DC `au-syd1`), deployed via the HashiCorp helm chart with +ACLs enabled (`default_policy: deny`, parity with the VM cluster). + +## API access (ACL auth) + +The HTTP API and UI are served on port 8500 behind the gateway at +`https://consul.k8s.syd1.au.unkin.net` (and `https://consul.service.consul`). +With ACLs enabled, requests beyond the anonymous policy require a token: + +```bash +# management (bootstrap) token — seeded from Vault, synced by VSO into the +# consul-bootstrap-acl-token secret; same value as the VM cluster's +# initial_management token: +CONSUL_HTTP_TOKEN=$(vault kv get -field=token kv/kubernetes/namespace/consul/default/bootstrap-acl-token) + +curl -H "X-Consul-Token: $CONSUL_HTTP_TOKEN" https://consul.k8s.syd1.au.unkin.net/v1/status/leader + +# consul CLI: +CONSUL_HTTP_ADDR=https://consul.k8s.syd1.au.unkin.net CONSUL_HTTP_TOKEN=$CONSUL_HTTP_TOKEN consul members +``` + +The UI at the same hostname exposes an ACL login (top right) — paste a token. +Anonymous requests get the anonymous-token policy only (reads for DNS/service +discovery; no writes, no ACL/token APIs). + +Prefer short-lived tokens minted by Vault's consul secrets engine over the +management token for day-to-day use; the terraform-* CI roles already work this +way. diff --git a/apps/base/consul/httproute.yaml b/apps/base/consul/httproute.yaml index 34e4f95..8e83bce 100644 --- a/apps/base/consul/httproute.yaml +++ b/apps/base/consul/httproute.yaml @@ -46,8 +46,8 @@ spec: - backendRefs: - group: "" kind: Service - name: consul-ui - port: 80 + name: consul-http + port: 8500 weight: 1 matches: - path: @@ -74,8 +74,8 @@ spec: - backendRefs: - group: "" kind: Service - name: consul-ui - port: 80 + name: consul-http + port: 8500 weight: 1 matches: - path: diff --git a/apps/base/consul/kustomization.yaml b/apps/base/consul/kustomization.yaml index 217d383..bfc5f94 100644 --- a/apps/base/consul/kustomization.yaml +++ b/apps/base/consul/kustomization.yaml @@ -6,5 +6,6 @@ resources: - namespace.yaml - gateway.yaml - httproute.yaml + - service.yaml - vaultauth.yaml - vaultstaticsecret.yaml diff --git a/apps/base/consul/service.yaml b/apps/base/consul/service.yaml new file mode 100644 index 0000000..9737123 --- /dev/null +++ b/apps/base/consul/service.yaml @@ -0,0 +1,25 @@ +--- +# ClusterIP service targeting the consul server pods' HTTP API (8500). +# The HashiCorp chart only ships consul-ui (also 8500 via the server pods) +# and the headless consul-server; this named service gives the Gateway a +# stable API backend. Consul serves both the HTTP API and the UI (at /ui/) +# on this same port, so routing the API hostname here preserves the UI too. +apiVersion: v1 +kind: Service +metadata: + name: consul-http + namespace: consul + labels: + app.kubernetes.io/name: consul + app.kubernetes.io/instance: consul +spec: + type: ClusterIP + selector: + app: consul + component: server + release: consul + ports: + - name: http + port: 8500 + protocol: TCP + targetPort: 8500