diff --git a/1password/secrets.json b/1password/secrets.json index 70c0ac7..223cce1 100644 --- a/1password/secrets.json +++ b/1password/secrets.json @@ -74,10 +74,5 @@ "name": "longhorn-encryption", "namespace": "longhorn-system", "itemPath": "vaults/Lab/items/longhorn-encryption" - }, - { - "name": "longhorn-backup", - "namespace": "longhorn-system", - "itemPath": "vaults/Lab/items/longhorn-backup" } ] diff --git a/main.ts b/main.ts index 0ac3b91..caa17b7 100644 --- a/main.ts +++ b/main.ts @@ -42,6 +42,18 @@ class Homelab extends TerraformStack { }, }); + new Manifest(this, "namespace", { + provider: kubernetes, + manifest: { + kind: "Namespace", + apiVersion: "v1", + metadata: { + name: "homelab", + }, + spec: {}, + }, + }); + new Manifest(this, "core-dns", { provider: kubernetes, manifest: { @@ -128,6 +140,7 @@ class Homelab extends TerraformStack { users: ["shahab", "budget-tracker"], primaryUser: "shahab", initSecretName: "postgres-password", + backupR2EndpointURL: `https://${env.ACCOUNT_ID}.r2.cloudflarestorage.com`, }); new RedisCluster(this, "redis-cluster", { diff --git a/nixos/master/disko-config.nix b/nixos/master/disko-config.nix index d12e051..3e371ca 100644 --- a/nixos/master/disko-config.nix +++ b/nixos/master/disko-config.nix @@ -24,7 +24,12 @@ content = { name = "crypted"; type = "luks"; - askPassword = true; + passwordFile = "/tmp/secret.key"; + settings = { + allowDiscards = true; + crypttabExtraOpts = + [ "fido2-device=auto" "token-timeout=10" ]; + }; content = { type = "filesystem"; format = "ext4"; diff --git a/nixos/master/flake.nix b/nixos/master/flake.nix index 0032a96..8d12de3 100644 --- a/nixos/master/flake.nix +++ b/nixos/master/flake.nix @@ -4,8 +4,10 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05"; # Disko - disko.url = "github:nix-community/disko"; - disko.inputs.nixpkgs.follows = "nixpkgs"; + disko = { + url = "github:nix-community/disko"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = { nixpkgs, disko, ... }: let diff --git a/postgres/index.ts b/postgres/index.ts index b597027..30fb828 100644 --- a/postgres/index.ts +++ b/postgres/index.ts @@ -17,6 +17,7 @@ type PostgresClusterOptions = { initSecretName: string; certManagerApiVersion: string; version: string; + backupR2EndpointURL: string; }; export class PostgresCluster extends Construct { @@ -34,6 +35,44 @@ export class PostgresCluster extends Construct { namespace: options.namespace, }); + const destinationPath = "s3://homelab-backups/"; + + const endpointURL = options.backupR2EndpointURL; + const barmanConfiguration = { + destinationPath, + endpointURL, + s3Credentials: { + accessKeyId: { + name: "cloudflare-r2-token", + key: "access_key", + }, + secretAccessKey: { + name: "cloudflare-r2-token", + key: "secret_key", + }, + }, + }; + + new Manifest(this, "r2-backup-store", { + provider: kubernetes, + manifest: { + apiVersion: "barmancloud.cnpg.io/v1", + kind: "ObjectStore", + metadata: { + namespace: options.namespace, + name: "r2-postgres-backup-store-homelab", + }, + spec: { + configuration: { + ...barmanConfiguration, + wal: { + compression: "gzip", + }, + }, + }, + }, + }); + const { certManagerApiVersion } = options; const certNames = { @@ -273,6 +312,7 @@ export class PostgresCluster extends Construct { new Manifest(this, "postgres-cluster", { provider: kubernetes, + fieldManager: { forceConflicts: true }, manifest: { apiVersion: "postgresql.cnpg.io/v1", kind: "Cluster", @@ -296,14 +336,59 @@ export class PostgresCluster extends Construct { "hostssl sameuser all all cert", ], }, + plugins: [ + { + name: "barman-cloud.cloudnative-pg.io", + enabled: true, + isWALArchiver: true, + parameters: { + barmanObjectName: "r2-postgres-backup-store", + }, + }, + ], enableSuperuserAccess: false, bootstrap: { - initdb: { + recovery: { + source: "clusterBackup", database: "postgres", + owner: options.primaryUser, secret: { name: options.initSecretName, }, - postInitSQL: [`CREATE USER ${options.primaryUser} SUPERUSER;`], + }, + }, + externalClusters: [ + { + name: "clusterBackup", + plugin: { + name: "barman-cloud.cloudnative-pg.io", + parameters: { + barmanObjectName: "r2-postgres-backup-store", + serverName: "postgres-cluster", + }, + }, + }, + ], + managed: { + services: { + disabledDefaultServices: ["ro", "r"], + additional: [ + { + selectorType: "rw", + serviceTemplate: { + metadata: { + name: "postgres-cluster", + annotations: { + "external-dns.alpha.kubernetes.io/hostname": + "postgres.dogar.dev", + }, + }, + spec: { + type: "LoadBalancer", + }, + }, + }, + ], }, }, storage: {