Commit graph

20 commits

Author SHA1 Message Date
700161ffd0
firewall: open port 80 on asxpio-services
xmpp.asxp.io and conference.asxp.io point at services, so the Let's
Encrypt HTTP challenge for the XMPP certificate arrives there. Only
/.well-known/acme-challenge/ is answered (forwarded to Traefik on ops);
everything else gets a 404.

Assisted-by: Claude:opus-5-5
2026-11-13 07:58:09 +04:00
94bc2d7ee9
dns: add admin.asxp.io
Superuser login for the asxp.io admin moves to admin.asxp.io, which
Traefik only serves to WireGuard and the VPC. The public A record is
there for the Let's Encrypt HTTP challenge, like gf; clients reach it
through split-horizon hosts entries.

Assisted-by: Claude:opus-5-5
2026-11-13 06:54:58 +04:00
85603657c6
terraform: let a record set opt out of change protection
Deleting a protected set takes two applies: first protected = false,
then remove it. Used for gf/AAAA (removed).

Assisted-by: Claude:opus-5-5
2026-11-13 05:15:21 +04:00
d67c629210
terraform: no public IPv6 for gf.asxp.io
Grafana is WireGuard-only; WireGuard clients map the name to the ops
WireGuard address. A public AAAA record made browsers prefer the public
path, where the allowlist answers 403.

Assisted-by: Claude:opus-5-5
2026-11-13 05:13:00 +04:00
984ca66114
terraform: gf.asxp.io for Grafana
Same pattern as traefik.asxp.io: public records to asxpio-ops, so
Traefik gets a Let's Encrypt certificate over HTTP-01, while an IP
allowlist limits it to WireGuard.

Assisted-by: Claude:opus-5-5
2026-11-13 04:59:10 +04:00
967ce9e5f6
terraform: drop the DNS import blocks
Both zones and all record sets are in state now; the import blocks
did their job. A plan without them shows no changes.

Assisted-by: Claude:opus-5-5
2026-11-12 23:23:56 +04:00
32836d5d53 terraform: manage DNS for asxp.io and czsk.it
The zones were edited by hand in the console, and it showed: dozens of
records for servers that no longer existed, a CNAME and a TXT record
missing their trailing dot, and a 24 h default TTL that made today's
XMPP move linger in resolver caches.

Now both zones live in the asxpio project, so describe them here,
adopted with import blocks (the first apply imported 87 and changed
nothing but protection). Our servers' records reference hcloud_server
instead of literal IPs. Every record set is change-protected except
those of the test XMPP servers, and both zones are delete-protected.

Assisted-by: Claude:opus-5-5
2026-11-12 22:46:53 +04:00
718524ffff terraform, ansible: drop the Immich buckets
Immich has not run for months and its photos are now in Google Photos.
asxpio-immich-main and asxpio-immich-repl (about 140 GB each) are
deleted; remove them from Terraform (state too) and from the s3fs
mounts, so nothing recreates or remounts them. The mount on
asxpio-services was taken down and its fstab line removed by hand.

Assisted-by: Claude:opus-5-5
2026-11-12 22:46:44 +04:00
59415515a1 docs: restic backups, XMPP and Xray on services, Fossils retired
Describe the new roles, how to list and restore restic snapshots, and
that the restic password must be kept outside the servers.

Assisted-by: Claude:opus-5-5
2026-11-12 21:03:10 +04:00
bc8cc75a19 terraform: XMPP and Xray ports on services, no Hetzner backups
Open the ports of the XMPP server and Xray, which move to
asxpio-services, and close 25566 with Minecraft Fossils gone.

Turn off Hetzner's server backups on both hosts: restic now backs up
the data to object storage in two regions, and the server backups cost
20% of each server's price. Disabling them deletes the existing backup
images, so apply that part only after restic has a verified snapshot.

Assisted-by: Claude:opus-5-5
2026-11-12 20:57:52 +04:00
0edfda123a docs: S3 traffic costs 1.00 now
Assisted-by: Claude:fable-5-2
2026-11-12 16:24:06 +04:00
e79b5cbfd8 docs: IPv4 addresses cost 0.50 each now
Assisted-by: Claude:fable-5-2
2026-11-12 16:23:29 +04:00
8cd39224b3 docs: current prices, and why the servers must not be recreated
The cost table was a year old. Use the amounts billed now.

Both servers still cost less than the list price for their type
(3.99 against 5.49, 11.99 against 15.99). That price belongs to the
existing server, so say plainly that a reinstall has to happen in
place.

Assisted-by: Claude:fable-5-2
2026-11-12 16:23:18 +04:00
f912e9d955 terraform: require hcloud provider 1.70
With provider 1.54 the plan replaces both servers. Hetzner stopped
returning a server's datacenter, the old provider derived the location
from it, and a location that reads back empty differs from "hel1",
which forces replacement. Only prevent_destroy stood in the way.

Provider 1.70.2 reads the location properly: the same plan then shows
the two firewall updates and nothing else. The lock file is not
tracked, so raise the version constraint to keep the old provider out.

Run terraform init -upgrade once in existing checkouts.

Assisted-by: Claude:fable-5-2
2026-11-12 16:01:58 +04:00
dc0f732d0f terraform: match the servers; open only ports in use
Checked against the Hetzner project:

 - Both servers have daily backups and delete and rebuild protection
   switched on, while the code said backups = false and set no
   protection. An apply would have turned all three off and discarded
   the existing backups. Record them as they are.

 - The firewalls had drifted both ways. Live, asxpio-ops also accepts
   XMPP ports and tcp/5000, and asxpio-services accepts 80, 443, XMPP,
   TURN, Valheim and Factorio ports; none of those services run. The
   code in turn missed tcp/25566, where the second Minecraft server
   listens.

Describe the firewalls as they should be: internal networks, plus the
public ports of services that run. Public SSH to asxpio-services goes
too; sshd and iptables already refuse it from outside the VPN.

This is not applied. The next plan will show the stale ports being
closed and nothing else.

Assisted-by: Claude:fable-5-2
2026-11-12 15:52:29 +04:00
e5322cbac2 terraform: never replace a running server
hcloud replaces a server when user_data, image or ssh_keys change, and
cloud-init only runs at first boot anyway. An edit to cloud-init, like
adding a user, would therefore plan the destruction of a production
machine. Ignore changes to those three attributes and set
prevent_destroy on both servers, so cloud-init describes a rebuild and
nothing else.

Add user zerrtika to cloud-init to match the servers; the user was
created on them by playbook 04.

Assisted-by: Claude:fable-5-2
2026-11-12 06:47:08 +04:00
11b5635115 new ssh pub key 2025-11-09 11:58:51 +02:00
67414814c0 ansible 2025-11-01 22:46:38 +02:00
7974e36c1b terraform fixes 2025-11-01 17:15:18 +02:00
33a12b643f terraform 2025-11-01 13:43:31 +02:00