Move Synapse on hcloud and deploy it with Terraform + NixOs

This commit is contained in:
Paul-Henri Froidmont 2021-07-15 13:38:22 +02:00
parent 8d543677c9
commit c76ade9c29
14 changed files with 396 additions and 37 deletions

2
.envrc Normal file
View file

@ -0,0 +1,2 @@
use flake
export SOPS_PGP_FP="3AC6F170F01133CE393BCD94BE948AFD7E7873BE"

1
.gitignore vendored
View file

@ -8,3 +8,4 @@ terraform.tfstate.backup
.environment
.tmp
terraform.tfvars
.direnv

115
backend1.nix Normal file
View file

@ -0,0 +1,115 @@
{ modulesPath, pkgs, lib, config, ... }:
let
fqdn =
let
join = hostName: domain: hostName + lib.optionalString (domain != null) ".${domain}";
in join "matrix" config.networking.domain;
in {
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
boot.loader.grub.device = "/dev/sda";
fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; };
# Set NIX_PATH to be the same as the Terraform module
# nix.nixPath = [ "nixpkgs=${pkgs}" ];
boot.cleanTmpDir = true;
networking.hostName = "backend1";
networking.domain = "banditlair.com";
networking.firewall.allowPing = true;
networking.firewall.allowedTCPPorts = [ 80 443 ];
services.openssh.enable = true;
users.users.root.openssh.authorizedKeys.keyFiles = [
./ssh_keys/phfroidmont-desktop.pub
];
security.acme.email = "letsencrypt.account@banditlair.com";
security.acme.acceptTerms = true;
services.nginx = {
enable = true;
# only recommendedProxySettings and recommendedGzipSettings are strictly required,
# but the rest make sense as well
recommendedTlsSettings = true;
recommendedOptimisation = true;
recommendedGzipSettings = true;
recommendedProxySettings = true;
virtualHosts = {
# This host section can be placed on a different host than the rest,
# i.e. to delegate from the host being accessible as ${config.networking.domain}
# to another host actually running the Matrix homeserver.
"${config.networking.domain}" = {
enableACME = true;
forceSSL = true;
locations."= /.well-known/matrix/server".extraConfig =
let
# use 443 instead of the default 8448 port to unite
# the client-server and server-server port for simplicity
server = { "m.server" = "${fqdn}:443"; };
in ''
add_header Content-Type application/json;
return 200 '${builtins.toJSON server}';
'';
locations."= /.well-known/matrix/client".extraConfig =
let
client = {
"m.homeserver" = { "base_url" = "https://${fqdn}"; };
"m.identity_server" = { "base_url" = "https://vector.im"; };
};
# ACAO required to allow element-web on any URL to request this json file
in ''
add_header Content-Type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '${builtins.toJSON client}';
'';
};
# Reverse proxy for Matrix client-server and server-server communication
${fqdn} = {
enableACME = true;
forceSSL = true;
# Or do a redirect instead of the 404, or whatever is appropriate for you.
# But do not put a Matrix Web client here! See the Element web section below.
locations."/".extraConfig = ''
return 404;
'';
# forward all Matrix API calls to the synapse Matrix homeserver
locations."/_matrix" = {
proxyPass = "http://[::1]:8008"; # without a trailing /
};
};
};
};
services.matrix-synapse = {
enable = true;
server_name = config.networking.domain;
listeners = [
{
port = 8008;
bind_address = "::1";
type = "http";
tls = false;
x_forwarded = true;
resources = [
{
names = [ "client" "federation" ];
compress = false;
}
];
}
];
database_type = "psycopg2";
database_args = {
host = "fake"; # This section is overriden in deploy_nixos keys
};
extraConfigFiles = [ "/var/keys/synapse-extra-config.yaml" ];
};
users.users.matrix-synapse.extraGroups = [ "keys" ];
}

View file

@ -2,28 +2,33 @@ terraform {
backend "http" {
}
required_providers {
// hcloud = {
// source = "hetznercloud/hcloud"
// version = "1.24.1"
// }
hcloud = {
source = "hetznercloud/hcloud"
version = "1.24.1"
}
hetznerdns = {
source = "timohirt/hetznerdns"
version = ">= 1.1.1"
}
sops = {
source = "carlpett/sops"
version = "~> 0.5"
}
}
}
//variable "hcloud_token" {}
//
//provider "hcloud" {
// token = var.hcloud_token
//}
//
//resource "hcloud_ssh_key" "phfroidmont-desktop" {
// name = "phfroidmont-desktop"
// public_key = file("ssh_keys/phfroidmont-desktop.pub")
//}
variable "hcloud_token" {}
provider "hcloud" {
token = var.hcloud_token
}
resource "hcloud_ssh_key" "phfroidmont-desktop" {
name = "phfroidmont-desktop"
public_key = file("ssh_keys/phfroidmont-desktop.pub")
}
variable "hetznerdns_token" {}

34
db1.nix Normal file
View file

@ -0,0 +1,34 @@
{ modulesPath, pkgs, ... }:
{
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
boot.loader.grub.device = "/dev/sda";
fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; };
# Set NIX_PATH to be the same as the Terraform module
# nix.nixPath = [ "nixpkgs=${pkgs}" ];
environment.systemPackages = with pkgs; [
htop
];
boot.cleanTmpDir = true;
networking.hostName = "db1";
networking.domain = "banditlair.com";
networking.firewall.allowPing = true;
networking.firewall.interfaces."enp7s0".allowedTCPPorts = [ 5432 ];
services.openssh.enable = true;
users.users.root.openssh.authorizedKeys.keyFiles = [
./ssh_keys/phfroidmont-desktop.pub
];
services.postgresql = {
enable = true;
package = pkgs.postgresql_12;
initialScript = "/var/keys/postgres-init.sql";
enableTCPIP = true;
authentication = ''
host all all 10.0.1.0/24 md5
'';
};
users.users.postgres.extraGroups = [ "keys" ];
}

26
dns.tf
View file

@ -7,35 +7,27 @@ data "hetznerdns_zone" "banditlair_zone" {
name = "banditlair.com"
}
resource "hetznerdns_record" "banditlair_a" {
resource "hetznerdns_record" "banditlair_hcloud_a" {
zone_id = data.hetznerdns_zone.banditlair_zone.id
name = "@"
value = "144.76.18.197"
value = data.hcloud_floating_ip.main_ip.ip_address
type = "A"
ttl = 600
}
resource "hetznerdns_record" "banditlair_cname" {
resource "hetznerdns_record" "banditlair_dedicated_a" {
zone_id = data.hetznerdns_zone.banditlair_zone.id
name = "*"
value = "${data.hetznerdns_zone.banditlair_zone.name}."
type = "CNAME"
value = "144.76.18.197"
type = "A"
ttl = 600
}
resource "hetznerdns_record" "ddns_ns" {
zone_id = data.hetznerdns_zone.banditlair_zone.id
name = "ddns.banditlair.com."
value = "ns.banditlair.com."
type = "NS"
ttl = 3600
}
# Matrix
resource "hetznerdns_record" "matrix_a" {
zone_id = data.hetznerdns_zone.banditlair_zone.id
name = "matrix"
value = hetznerdns_record.banditlair_a.value
value = data.hcloud_floating_ip.main_ip.ip_address
type = "A"
ttl = 600
}
@ -112,7 +104,7 @@ data "hetznerdns_zone" "falbo_zone" {
resource "hetznerdns_record" "falbo_a" {
zone_id = data.hetznerdns_zone.falbo_zone.id
name = "@"
value = hetznerdns_record.banditlair_a.value
value = hetznerdns_record.banditlair_dedicated_a.value
type = "A"
ttl = 600
}
@ -172,7 +164,7 @@ data "hetznerdns_zone" "froidmont_zone" {
resource "hetznerdns_record" "froidmont_a" {
zone_id = data.hetznerdns_zone.froidmont_zone.id
name = "@"
value = hetznerdns_record.banditlair_a.value
value = hetznerdns_record.banditlair_dedicated_a.value
type = "A"
ttl = 600
}
@ -232,7 +224,7 @@ data "hetznerdns_zone" "stb_zone" {
resource "hetznerdns_record" "stb_a" {
zone_id = data.hetznerdns_zone.stb_zone.id
name = "@"
value = hetznerdns_record.banditlair_a.value
value = hetznerdns_record.banditlair_dedicated_a.value
type = "A"
ttl = 600
}

27
flake.lock generated Normal file
View file

@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1626117186,
"narHash": "sha256-KSVWpb03y2QootRxAG4RwTI14RUn1vmz/yRgVlDJRpk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "a7512bb64b1dd693c97b1219c24032d28f20f9e8",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-21.05",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

27
flake.nix Normal file
View file

@ -0,0 +1,27 @@
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-21.05";
outputs = { self, nixpkgs }:
let
pkgs = nixpkgs.legacyPackages.x86_64-linux;
inputs = with pkgs; [
terraform_0_14
sops
];
in {
devShell.x86_64-linux = pkgs.mkShell {
buildInputs = inputs;
};
nixosConfigurations.db1 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ { imports = [ ./db1.nix ]; } ];
};
nixosConfigurations.backend1 = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ { imports = [ ./backend1.nix ]; } ];
};
};
}

114
instances.tf Normal file
View file

@ -0,0 +1,114 @@
data "hcloud_image" "nixos_stable" {
with_selector = "nixos=21.05"
}
data "hcloud_floating_ip" "main_ip" {
with_selector = "external=main"
}
data "sops_file" "secrets" {
source_file = "secrets.enc.yml"
}
resource "hcloud_network" "private_network" {
name = "private"
ip_range = "10.0.0.0/16"
}
resource "hcloud_network_subnet" "db_network_subnet" {
type = "cloud"
network_id = hcloud_network.private_network.id
network_zone = "eu-central"
ip_range = "10.0.1.0/24"
}
resource "hcloud_server" "db1" {
name = "db1"
image = data.hcloud_image.nixos_stable.id
server_type = "cpx11"
ssh_keys = [
hcloud_ssh_key.phfroidmont-desktop.id
]
keep_disk = true
location = "hel1"
network {
network_id = hcloud_network.private_network.id
ip = "10.0.1.11"
}
labels = {
type = "db"
}
depends_on = [
hcloud_network_subnet.db_network_subnet
]
}
module "deploy_nixos_db1" {
source = "github.com/phfroidmont/terraform-nixos//deploy_nixos?ref=a8d5d31e59f4ce2677272e4849b122b4afc5a8e4"
nixos_config = "db1"
flake = true
target_host = hcloud_server.db1.ipv4_address
ssh_agent = true
keys = {
"postgres-init.sql" = <<EOT
CREATE ROLE "synapse" WITH LOGIN PASSWORD '${data.sops_file.secrets.data["synapse.db_password"]}';
CREATE DATABASE "synapse" WITH OWNER "synapse"
TEMPLATE template0
LC_COLLATE = "C"
LC_CTYPE = "C";
EOT
}
}
resource "hcloud_server" "backend1" {
name = "backend1"
image = data.hcloud_image.nixos_stable.id
server_type = "cpx21"
ssh_keys = [
hcloud_ssh_key.phfroidmont-desktop.id
]
keep_disk = true
location = "hel1"
network {
network_id = hcloud_network.private_network.id
ip = "10.0.1.1"
}
labels = {
type = "backend"
}
depends_on = [
hcloud_network_subnet.db_network_subnet
]
}
resource "hcloud_floating_ip_assignment" "main" {
floating_ip_id = data.hcloud_floating_ip.main_ip.id
server_id = hcloud_server.backend1.id
}
module "deploy_nixos_backend1" {
source = "github.com/phfroidmont/terraform-nixos//deploy_nixos?ref=a8d5d31e59f4ce2677272e4849b122b4afc5a8e4"
nixos_config = "backend1"
flake = true
target_host = hcloud_server.backend1.ipv4_address
ssh_agent = true
keys = {
"synapse-extra-config.yaml" = <<EOT
database:
name: psycopg2
args:
database: synapse
host: "10.0.1.11"
user: "synapse"
password: "${data.sops_file.secrets.data["synapse.db_password"]}"
macaroon_secret_key: "${data.sops_file.secrets.data["synapse.macaroon_secret_key"]}"
EOT
}
}

7
outputs.tf Normal file
View file

@ -0,0 +1,7 @@
output "db1_public_ip" {
value = hcloud_server.db1.ipv4_address
}
output "backend1_public_ip" {
value = hcloud_server.backend1.ipv4_address
}

View file

@ -30,8 +30,8 @@
tags: [ 'gitlab' ]
- role: nextcloud-docker
tags: [ 'nextcloud' ]
- role: matrix-docker
tags: [ 'matrix' ]
# - role: matrix-docker
# tags: [ 'matrix' ]
- role: torrent-docker
tags: [ 'torrent' ]
- role: monit

View file

@ -13,11 +13,11 @@ docker exec nextcloud_postgres_1 sh -c "pg_dump -U nextcloud nextcloud > /backup
echo 'Dumping S.T.B. wordpress database'
docker exec stb_db_1 sh -c "mysqldump -u stb -p{{stb_mysql_password}} stb > /backups/database.dmp"
echo 'Dumping matrix database'
docker exec matrix_db_1 sh -c "pg_dump -U synapse synapse > /backups/database.dmp"
#echo 'Dumping matrix database'
#docker exec matrix_db_1 sh -c "pg_dump -U synapse synapse > /backups/database.dmp"
echo 'Dumping invidious database'
docker exec invidious_postgres_1 sh -c "pg_dump -U kemal invidious > /backups/database.dmp"
#echo 'Dumping invidious database'
#docker exec invidious_postgres_1 sh -c "pg_dump -U kemal invidious > /backups/database.dmp"
echo 'Copying murmur database'
docker stop murmur_murmur_1

34
secrets.enc.yml Normal file
View file

@ -0,0 +1,34 @@
synapse:
db_password: ENC[AES256_GCM,data:hy2BgTsRaZDQZULTW/csmnRy5ZjDEuPqxyuINv0ov5pFzDkozJVL1wut3HgBXjYZ8bqNjS5pCPQtkznw,iv:i41zKGwvPGIEZP0ZjhRaY4UMeOXBovQmLr1e1ewZhV4=,tag:3kKKYouH+lOrNxPJE5ul/Q==,type:str]
macaroon_secret_key: ENC[AES256_GCM,data:6n1gCit2MC8l4VR9DSUR87BB+hY5Oza33423sbV8sNIXmZsPzhyvxaBalK/0TVjLH6Q=,iv:OgHxNG96ZW4+LPZhLAtOD01Wibad6vSX6s4BrPE67YE=,tag:OGIz/ufUwt8/pUMLvoaXtg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2021-07-14T18:42:34Z"
mac: ENC[AES256_GCM,data:Zjwgb3DudxssTIT0BdQbm/FEJmPsNz6412djBGBKC+KpHU/65Cw6WhjX/cR48zO/4OK3nkfJ/MKq9Vv47QLUlcyJwGgRmdBsowjpcqvrG1UMGKd+sg+rQRtDi8AVicSMJ+cnhMtIAsvGzktl+5Xep3tuFZ7stKwdvkIR9LJr2PI=,iv:1mWlZU++GgkeiCI9JUnbUvMxGR+jmWU1Lle6w2ZVJe8=,tag:AE8l0W7x68BM7OpPJmmV0Q==,type:str]
pgp:
- created_at: "2021-07-14T18:02:07Z"
enc: |
-----BEGIN PGP MESSAGE-----
hQIMAy9TuQ4zAbDHAQ/6AjQzGb2sOzHZblU/VEQce+gUebo4otQvMY5sQVl6xmBU
y+JiSRyUy3euGcAdNvkB9fxgNrKB5amaeP2Hte1cjJsy+iBHnmTlPKmBKet6mgJY
0Q1BDZf8oJUsioiHZeDfo3XLEVuIiJ/ek3v6NYPI1lfmkgV6J7oAzTYT30Z57v6C
zah7EcZa1Cr33hC1Ibb6o14Rzf2xgk17/fyXmFNyNnTu6XJxU85g1JDdcMKwRDpQ
y7VE6/nMSN0p2CGUFTuLPg7zfa9e6zDZ7UblXTV5EXPndf1MQ8Ni/AmPdQ8A9rjt
5kP9+Cv2CFfdXW1dgqORkQ9UC8hXdt0N3BR1X0BZWPmQyhODDUdkXndVqNDYUg8q
tXEN1WS66BUUB1nGbSnSa6SLLbMwB5Jle9qf5axJnCmlHLifCq9tGHhGH8h/NGNA
9o59iUV2pJxIaOoye9PQ4jo43J/O19YaRefETO6D5Y8SIXC0zX0IXGY/sEusaZlT
Iz7wEr+dc4Xy38PWzXM8p9u5ixzwYB7q7zt2OBuiiD51zD6TTjn2PUmuyY+uaqhX
KcmbrjGsu/HzcRlmvkVgYgpUqf7AqmaKIwGsSd1On8hpNxQI3/kiJnEjpRW+iqyb
EB7d8KQbpRlxCs5MMU6LznD7zvCeXyy3a0U+CFB+5tp74Wj6kxKpMZl0BYPfMrvS
XgGiTJ0By1L2lJphYxdKFQtoMqOZrr+y7/x/peEclPzKvdvIPHLE3P6HmOfWSJTh
Z6rXZDUtcBvyTEQInP5WJ1l37WiZ3B9LFRPq4Ej/0zrfsJfqmRYPQFJaMucjlNQ=
=eKml
-----END PGP MESSAGE-----
fp: 3AC6F170F01133CE393BCD94BE948AFD7E7873BE
unencrypted_suffix: _unencrypted
version: 3.7.1

View file

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMPhCld0dsDzpdkMvPRdiwd6IX8HF8Mb2V6uQzBl8/syeny8FbZxlZR8gk39RGxNYcLaZ+nA50DS6mOIplXCGdtozfw0Vm+FdITN3apMufWIdobG7Igs1vxKBBbkAb5lwxkEFUCUMzPdCLFHd5zabVH0WE42Be8+hYPLd5W/ikPCOgxRaGwryHHroxRMdkD3PcNE8upSEMdGl51pzgXhO6Fcig8UokOYHxV92SiQ0KEsCbc+oe8e9Gkr7g78tz+6YcTYLY2p2ygR7Vrh/WyTaUVnrNNqL8NIqp+Lc2kVtnqGXHFBJ0Wggaly+AeKWygy+dnOMEGSirhQ6/dUcB/Phz phfroidmont@archdesktop-2017-07-31