commit b5a991b6316efd660e0aece9e6d39826cacdf087 Author: Jörg Thalheim Date: Tue Jul 4 16:43:31 2023 +0200 first commit diff --git a/.envrc.private-template b/.envrc.private-template new file mode 100644 index 0000000..080548b --- /dev/null +++ b/.envrc.private-template @@ -0,0 +1,5 @@ +# https://app.netlify.com/user/applications#personal-access-tokens +export NETLIFY_TOKEN= + +# https://console.hetzner.cloud/projects/2447141/security/tokens +export HCLOUD_TOKEN= diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f70b473 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# secrets +.envrc.private +.terraform.lock.hcl + +# git is our backup +*.tfstate.backup diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..2b53e28 --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,7 @@ +keys: + - &joerg age17n64ahe3wesh8l8lj0zylf4nljdmqn28hvqns2g7hgm9mdkhlsvsjuvkxz +creation_rules: + - path_regex: targets/.*/terraform.tfstate.sops$ + key_groups: + - age: + - *joerg diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..66cc1e1 --- /dev/null +++ b/flake.lock @@ -0,0 +1,111 @@ +{ + "nodes": { + "disko": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1687968164, + "narHash": "sha256-L9jr2zCB6NIaBE3towusjGBigsnE2pMID8wBGkYbTS4=", + "owner": "nix-community", + "repo": "disko", + "rev": "8002e7cb899bc2a02a2ebfb7f999fcd7c18b92a1", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "disko", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688466019, + "narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1688322751, + "narHash": "sha256-eW62dC5f33oKZL7VWlomttbUnOTHrAbte9yNUNW8rbk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0fbe93c5a7cac99f90b60bdf5f149383daaa615f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "disko": "disko", + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs", + "srvos": "srvos", + "treefmt-nix": "treefmt-nix" + } + }, + "srvos": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688384426, + "narHash": "sha256-iUhJ2JYCyzioI/G0mqgDoSH3U0fcFhm6ShmMcB0dYyY=", + "owner": "numtide", + "repo": "srvos", + "rev": "c9fa5cf4b6014807655bf8356b3cddc86f741b7a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "srvos", + "type": "github" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1688026376, + "narHash": "sha256-qJmkr9BWDpqblk4E9/rCsAEl39y2n4Ycw6KRopvpUcY=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "df3f32b0cc253dfc7009b7317e8f0e7ccd70b1cf", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..c066155 --- /dev/null +++ b/flake.nix @@ -0,0 +1,49 @@ +{ + description = "Dependencies to deploy a clan"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-parts.url = "github:hercules-ci/flake-parts"; + flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; + treefmt-nix.url = "github:numtide/treefmt-nix"; + treefmt-nix.inputs.nixpkgs.follows = "nixpkgs"; + + disko.url = "github:nix-community/disko"; + disko.inputs.nixpkgs.follows = "nixpkgs"; + + srvos.url = "github:numtide/srvos"; + # Use the version of nixpkgs that has been tested to work with SrvOS + srvos.inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = inputs@{ flake-parts, ... }: + flake-parts.lib.mkFlake { inherit inputs; } ({ lib, ... }: { + systems = lib.systems.flakeExposed; + imports = [ + inputs.treefmt-nix.flakeModule + ./targets/flake-module.nix + ./modules/flake-module.nix + ]; + perSystem = { config, pkgs, inputs', ... }: { + treefmt = { + projectRootFile = "flake.nix"; + programs.terraform.enable = true; + programs.nixpkgs-fmt.enable = true; + }; + packages.default = pkgs.mkShell { + packages = [ + pkgs.bashInteractive + pkgs.sops + (pkgs.terraform.withPlugins (p: [ + p.namecheap + p.netlify + p.hcloud + p.null + p.external + p.local + ])) + ]; + }; + }; + }); +} diff --git a/git-agecrypt.toml b/git-agecrypt.toml new file mode 100644 index 0000000..cd4f81c --- /dev/null +++ b/git-agecrypt.toml @@ -0,0 +1,2 @@ +[config] +"targets/admins/terraform.tfstate" = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKbBp2dH2X3dcU1zh+xW3ZsdYROKpJd3n13ssOP092qE joerg@turingmachine"] diff --git a/modules/flake-module.nix b/modules/flake-module.nix new file mode 100644 index 0000000..33e7863 --- /dev/null +++ b/modules/flake-module.nix @@ -0,0 +1,13 @@ +{ inputs, ... }: { + flake.nixosModules = { + hcloud.imports = [ + inputs.srvos.nixosModules.server + inputs.srvos.nixosModules.hardware-hetzner-cloud + ./single-disk.nix + ]; + + web01.imports = [ + ./web01.nix + ]; + }; +} diff --git a/modules/single-disk.nix b/modules/single-disk.nix new file mode 100644 index 0000000..ffb4ea9 --- /dev/null +++ b/modules/single-disk.nix @@ -0,0 +1,45 @@ +{ self, ... }: +let + partitions = { + grub = { + name = "grub"; + size = "1M"; + flags = [ "bios_grub" ]; + }; + esp = { + name = "ESP"; + size = "500MB"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + root = { + name = "root"; + size = "100%"; + bootable = true; + content = { + type = "filesystem"; + # We use xfs because it has support for compression and has a quite good performance for databases + format = "xfs"; + mountpoint = "/"; + }; + }; + }; +in +{ + imports = [ + self.inputs.disko.nixosModules.disko + ]; + disko.devices = { + disk.sda = { + type = "disk"; + device = "/dev/sda"; + content = { + type = "gpt"; + inherit partitions; + }; + }; + }; +} diff --git a/modules/web01.nix b/modules/web01.nix new file mode 100644 index 0000000..c915eb0 --- /dev/null +++ b/modules/web01.nix @@ -0,0 +1 @@ +{ ... }: { } diff --git a/targets/admins/apply.sh b/targets/admins/apply.sh new file mode 100755 index 0000000..1b2fc9e --- /dev/null +++ b/targets/admins/apply.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -euo pipefail + +rm -f .terraform.lock.hcl +TFSTATE=$(mktemp) +if [[ -f "terraform.tfstate.sops" ]]; then + sops -d terraform.tfstate.sops > "$TFSTATE" +fi +toplevel=$(git rev-parse --show-toplevel) +backupdir=$toplevel/.git/terraform/$(basename "$(dirname "$0")") +cleanup() { + sops -e "$TFSTATE" > terraform.tfstate.sops && rm -f "$TFSTATE" +} +trap "cleanup" EXIT +terraform init -backup="$backupdir" -state-out="$TFSTATE" +terraform apply -backup="$backupdir" -state-out="$TFSTATE" diff --git a/targets/admins/recipents.txt b/targets/admins/recipents.txt new file mode 100644 index 0000000..2a7b3dc --- /dev/null +++ b/targets/admins/recipents.txt @@ -0,0 +1,2 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKbBp2dH2X3dcU1zh+xW3ZsdYROKpJd3n13ssOP092qE joerg@turingmachine +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDIb3uuMqE/xSJ7WL/XpJ6QOj4aSmh0Ga+GtmJl3CDvljGuIeGCKh7YAoqZAi051k5j6ZWowDrcWYHIOU+h0eZCesgCf+CvunlXeUz6XShVMjyZo87f2JPs2Hpb+u/ieLx4wGQvo/Zw89pOly/vqpaX9ZwyIR+U81IAVrHIhqmrTitp+2FwggtaY4FtD6WIyf1hPtrrDecX8iDhnHHuGhATr8etMLwdwQ2kIBx5BBgCoiuW7wXnLUBBVYeO3II957XP/yU82c+DjSVJtejODmRAM/3rk+B7pdF5ShRVVFyB6JJR+Qd1g8iSH+2QXLUy3NM2LN5u5p2oTjUOzoEPWZo7lykZzmIWd/5hjTW9YiHC+A8xsCxQqs87D9HK9hLA6udZ6CGkq4hG/6wFwNjSMnv30IcHZzx6IBihNGbrisrJhLxEiKWpMKYgeemhIirefXA6UxVfiwHg3gJ8BlEBsj0tl/HVARifR2y336YINEn8AsHGhwrPTBFOnBTmfA/VnP1NlWHzXCfVimP6YVvdoGCCnAwvFuJ+ZuxmZ3UzBb2TenZZOzwzV0sUzZk0D1CaSBFJUU3oZNOkDIM6z5lIZgzsyKwb38S8Vs3HYE+Dqpkfsl4yeU5ldc6DwrlVwuSIa4vVus4eWD3gDGFrx98yaqOx17pc4CC9KXk/2TjtJY5xmQ== diff --git a/targets/admins/terraform.tf b/targets/admins/terraform.tf new file mode 100644 index 0000000..1f2e7ee --- /dev/null +++ b/targets/admins/terraform.tf @@ -0,0 +1,12 @@ +terraform { + backend "local" { + } +} + +module "admin" { + source = "../../terraform/admins" + ssh_keys = { + mic92 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKbBp2dH2X3dcU1zh+xW3ZsdYROKpJd3n13ssOP092qE joerg@turingmachine" + lassulus = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDIb3uuMqE/xSJ7WL/XpJ6QOj4aSmh0Ga+GtmJl3CDvljGuIeGCKh7YAoqZAi051k5j6ZWowDrcWYHIOU+h0eZCesgCf+CvunlXeUz6XShVMjyZo87f2JPs2Hpb+u/ieLx4wGQvo/Zw89pOly/vqpaX9ZwyIR+U81IAVrHIhqmrTitp+2FwggtaY4FtD6WIyf1hPtrrDecX8iDhnHHuGhATr8etMLwdwQ2kIBx5BBgCoiuW7wXnLUBBVYeO3II957XP/yU82c+DjSVJtejODmRAM/3rk+B7pdF5ShRVVFyB6JJR+Qd1g8iSH+2QXLUy3NM2LN5u5p2oTjUOzoEPWZo7lykZzmIWd/5hjTW9YiHC+A8xsCxQqs87D9HK9hLA6udZ6CGkq4hG/6wFwNjSMnv30IcHZzx6IBihNGbrisrJhLxEiKWpMKYgeemhIirefXA6UxVfiwHg3gJ8BlEBsj0tl/HVARifR2y336YINEn8AsHGhwrPTBFOnBTmfA/VnP1NlWHzXCfVimP6YVvdoGCCnAwvFuJ+ZuxmZ3UzBb2TenZZOzwzV0sUzZk0D1CaSBFJUU3oZNOkDIM6z5lIZgzsyKwb38S8Vs3HYE+Dqpkfsl4yeU5ldc6DwrlVwuSIa4vVus4eWD3gDGFrx98yaqOx17pc4CC9KXk/2TjtJY5xmQ==" + } +} diff --git a/targets/admins/terraform.tfstate.sops b/targets/admins/terraform.tfstate.sops new file mode 100644 index 0000000..70e0287 --- /dev/null +++ b/targets/admins/terraform.tfstate.sops @@ -0,0 +1,20 @@ +{ + "data": "ENC[AES256_GCM,data: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,iv:MB5og2s7N+cTxZMRdSPtpBwTNeTMoEYnzalIHylYsyI=,tag:/NTdmINyoFot/beul8C9GA==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age17n64ahe3wesh8l8lj0zylf4nljdmqn28hvqns2g7hgm9mdkhlsvsjuvkxz", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtYmYvczZrNHEzeTVvaXRH\nbEJGb1lZL2xrMTBOdGlyc0l3RnpHWU1YZTI0CkNEYy9EVEFITFVGOE5Mc2dsZktV\nM2tacVc3RGlqeHlsL2RuMGZQYUtscmsKLS0tIHFGVWRBNGpyNkptV0FRcHpMV1Jk\nSCs4c1lFaFU3WkcrWkQzcktKRkJCdVkKneJko1lw5CkORymxfibErFRb8fJEQl2E\naPNlUCAknCrb+raWClkbXFY1MSCcxrkFV+tx69O8hLaTlGUPnmGAeQ==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2023-07-04T15:15:37Z", + "mac": "ENC[AES256_GCM,data:VMnIZxSc8QKp8s69gCvteTKkrlXP7/AkWamtnbd6SFCbhubpKoY88gyXv9QHLKwqclkKHyz3U9GsnvnEb3OUb8RX21l8bVPwB98OiLcBgd54KlizVVmz8fUDjjQf41PzuSs5LI0QoVKypfphtLjRViptBDPmCDYWk4Q1jEjARgs=,iv:BUgslpHCBnSnBSWUC62U0b0hqIC6l8RPKOeExXHhMgM=,tag:px/qDIZuycqn5NnDJa73ZA==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.7.3" + } +} \ No newline at end of file diff --git a/targets/flake-module.nix b/targets/flake-module.nix new file mode 100644 index 0000000..046dd1c --- /dev/null +++ b/targets/flake-module.nix @@ -0,0 +1,25 @@ +{ lib, self, ... }: +let + entries = builtins.attrNames (builtins.readDir ./.); + configs = builtins.filter (dir: builtins.pathExists (./. + "/${dir}/configuration.nix")) entries; +in +{ + flake.nixosConfigurations = lib.listToAttrs + (builtins.map + (name: + lib.nameValuePair + (builtins.replaceStrings [ "." ] [ "-" ] name) + (lib.nixosSystem { + system = "x86_64-linux"; + # Make flake available in modules + specialArgs = { + self = { + inputs = self.inputs; + nixosModules = self.nixosModules; + }; + }; + + modules = [ (./. + "/${name}/configuration.nix") ]; + })) + configs); +} diff --git a/targets/web01/apply.sh b/targets/web01/apply.sh new file mode 120000 index 0000000..7f6c3ba --- /dev/null +++ b/targets/web01/apply.sh @@ -0,0 +1 @@ +../admins/apply.sh \ No newline at end of file diff --git a/targets/web01/configuration.nix b/targets/web01/configuration.nix new file mode 100644 index 0000000..d9de2fe --- /dev/null +++ b/targets/web01/configuration.nix @@ -0,0 +1,10 @@ +{ self, ... }: let + nixosVars = builtins.fromJSON (builtins.readFile ./nixos-vars.json); +in { + imports = [ + self.nixosModules.nixos-wiki + self.nixosModules.hcloud + ]; + users.users.root.openssh.authorizedKeys.keys = nixosVars.ssh_keys; + system.stateVersion = "23.05"; +} diff --git a/targets/web01/terraform.tf b/targets/web01/terraform.tf new file mode 100644 index 0000000..5875c65 --- /dev/null +++ b/targets/web01/terraform.tf @@ -0,0 +1,14 @@ +terraform { + backend "local" {} +} + +module "web01" { + source = "../../terraform/web01" + domain = "clan.lol" + nixos_flake_attr = "web01" + nixos_vars_file = "${path.module}/nixos-vars.json" + tags = { + Terraform = "true" + Target = "web01" + } +} diff --git a/terraform/admins/main.tf b/terraform/admins/main.tf new file mode 100644 index 0000000..5245e8b --- /dev/null +++ b/terraform/admins/main.tf @@ -0,0 +1,8 @@ +resource "hcloud_ssh_key" "hcloud" { + for_each = var.ssh_keys + name = each.key + public_key = each.value + labels = { + "wiki" = "true" + } +} diff --git a/terraform/admins/providers.tf b/terraform/admins/providers.tf new file mode 100644 index 0000000..0262e22 --- /dev/null +++ b/terraform/admins/providers.tf @@ -0,0 +1,5 @@ +terraform { + required_providers { + hcloud = { source = "hetznercloud/hcloud" } + } +} diff --git a/terraform/admins/variables.tf b/terraform/admins/variables.tf new file mode 100644 index 0000000..f9db1ac --- /dev/null +++ b/terraform/admins/variables.tf @@ -0,0 +1,5 @@ +variable "ssh_keys" { + type = map(string) + description = "SSH public keys for admin user (name -> key)" +} + diff --git a/terraform/web01/dns.tf b/terraform/web01/dns.tf new file mode 100644 index 0000000..c9d7112 --- /dev/null +++ b/terraform/web01/dns.tf @@ -0,0 +1,18 @@ +resource "netlify_dns_zone" "nixos" { + site_id = "" + name = var.netlify_dns_zone +} + +resource "netlify_dns_record" "nixos_wiki_a" { + zone_id = netlify_dns_zone.nixos.id + hostname = var.domain + type = "A" + value = hcloud_server.nixos_wiki.ipv4_address +} + +resource "netlify_dns_record" "nixos_wiki_aaaa" { + zone_id = netlify_dns_zone.nixos.id + hostname = var.domain + type = "AAAA" + value = hcloud_server.nixos_wiki.ipv6_address +} diff --git a/terraform/web01/main.tf b/terraform/web01/main.tf new file mode 100644 index 0000000..ee8b33c --- /dev/null +++ b/terraform/web01/main.tf @@ -0,0 +1,39 @@ +# Record the SSH public key into Hetzner Cloud +data "hcloud_ssh_keys" "nixos_wiki" { + with_selector = "wiki=true" +} + +resource "hcloud_server" "nixos_wiki" { + image = "debian-10" + keep_disk = true + name = "nixos-wiki" + server_type = var.server_type + ssh_keys = data.hcloud_ssh_keys.nixos_wiki.ssh_keys.*.name + backups = false + labels = var.tags + + location = var.server_location + + lifecycle { + # Don't destroy server instance if ssh keys changes. + ignore_changes = [ssh_keys] + prevent_destroy = false + } +} + +module "deploy" { + depends_on = [local_file.nixos_vars] + source = "github.com/numtide/nixos-anywhere//terraform/all-in-one" + nixos_system_attr = ".#nixosConfigurations.${var.nixos_flake_attr}.config.system.build.toplevel" + nixos_partitioner_attr = ".#nixosConfigurations.${var.nixos_flake_attr}.config.system.build.diskoNoDeps" + target_host = hcloud_server.nixos_wiki.ipv4_address + instance_id = hcloud_server.nixos_wiki.id + debug_logging = true +} + +locals { + nixos_vars = { + ipv6_address = hcloud_server.nixos_wiki.ipv6_address + ssh_keys = data.hcloud_ssh_keys.nixos_wiki.ssh_keys.*.public_key + } +} diff --git a/terraform/web01/nixos_vars.tf b/terraform/web01/nixos_vars.tf new file mode 100644 index 0000000..b7a3e22 --- /dev/null +++ b/terraform/web01/nixos_vars.tf @@ -0,0 +1,18 @@ +resource "local_file" "nixos_vars" { + content = jsonencode(local.nixos_vars) + filename = var.nixos_vars_file + file_permission = "600" + + provisioner "local-exec" { + interpreter = ["bash", "-c"] + command = "git add -f '${local_file.nixos_vars.filename}'" + } + # also pro-actively add hosts and flake-module.nix to git so nix can find it. + provisioner "local-exec" { + interpreter = ["bash", "-c"] + command = <