From 49b607129d89674b39fa370e80721548d5fc2d34 Mon Sep 17 00:00:00 2001 From: Guanran Wang Date: Sun, 22 Sep 2024 00:21:30 +0800 Subject: [PATCH] infra: init opentofu --- .envrc | 3 + .sops.yaml | 16 +++-- flake.lock | 54 ++++++++--------- flake.nix | 79 +++++++++++++++++-------- home/applications/ssh/default.nix | 19 ++---- hosts/pek0/anti-feature.nix | 6 +- hosts/tyo0/anti-feature.nix | 4 +- hosts/tyo0/default.nix | 3 + hosts/tyo0/services/prometheus.nix | 8 ++- hosts/vultr/common/default.nix | 39 +++++++++++++ hosts/vultr/common/disko.nix | 59 +++++++++++++++++++ hosts/vultr/common/preservation.nix | 15 +++++ hosts/vultr/sin0/default.nix | 14 +++++ infra/.gitignore | 3 + infra/data.json | 45 +++++++++++++++ infra/modules/vultr/main.tf | 90 +++++++++++++++++++++++++++++ infra/outputs.tf | 3 + infra/secrets.tf | 11 ++++ infra/secrets.yaml | 24 ++++++++ infra/terraform.tfstate | 1 + infra/version.tf | 21 +++++++ infra/vultr.tf | 32 ++++++++++ secrets.yaml | 57 ++++++++++-------- treefmt.nix | 3 + 24 files changed, 507 insertions(+), 102 deletions(-) create mode 100644 hosts/vultr/common/default.nix create mode 100644 hosts/vultr/common/disko.nix create mode 100644 hosts/vultr/common/preservation.nix create mode 100644 hosts/vultr/sin0/default.nix create mode 100644 infra/.gitignore create mode 100644 infra/data.json create mode 100644 infra/modules/vultr/main.tf create mode 100644 infra/outputs.tf create mode 100644 infra/secrets.tf create mode 100644 infra/secrets.yaml create mode 100644 infra/terraform.tfstate create mode 100644 infra/version.tf create mode 100644 infra/vultr.tf diff --git a/.envrc b/.envrc index 3550a30..ef6d677 100644 --- a/.envrc +++ b/.envrc @@ -1 +1,4 @@ use flake +if has sops; then + export TF_ENCRYPTION=$(sops --extract '["tofu"]["encryption"]' -d infra/secrets.yaml) +fi diff --git a/.sops.yaml b/.sops.yaml index 9af5348..4611234 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -4,33 +4,39 @@ keys: # ssh-to-age < /etc/ssh/ssh_host_ed25519_key.pub - &dust age193x79xx8snu82w3t3hax6nruuw57g7pduwnkpvzkzmd7fs5jvfrquqa3sl - &pek0 age174knn6hjtukp32ymcdvjwj6x0j54g7yw02dqfjmua3fkyltwcqrsxccjdk + - &sin0 age1u7srtfpgf83hesmsvtqdqftl8xrjmmp33mlg0aze6ken866ad55qxmzdqd - &tyo0 age1vw4kf5v8cfnhfhvl0eyvqzpvy9hpfv9enffvzyt95tx5mu7s5dxqjqw0fa creation_rules: - - path_regex: hosts/pek0/secrets.yaml$ + - path_regex: ^hosts/pek0/secrets.yaml$ key_groups: - age: - *guanranwang - *pek0 - - path_regex: hosts/tyo0/secrets.yaml$ + - path_regex: ^hosts/tyo0/secrets.yaml$ key_groups: - age: - *guanranwang - *tyo0 - - path_regex: nixos/profiles/sing-box/secrets.yaml$ + - path_regex: ^nixos/profiles/sing-box/secrets.yaml$ key_groups: - age: - *guanranwang - *dust - *pek0 - - path_regex: nixos/profiles/wireless/secrets.yaml$ + - path_regex: ^nixos/profiles/wireless/secrets.yaml$ key_groups: - age: - *guanranwang - *dust - - path_regex: secrets.yaml$ + - path_regex: ^secrets.yaml$ key_groups: - age: - *guanranwang - *dust - *pek0 + - *sin0 - *tyo0 + - path_regex: ^infra/secrets.yaml$ + key_groups: + - age: + - *guanranwang diff --git a/flake.lock b/flake.lock index 7e9771b..a2d1267 100644 --- a/flake.lock +++ b/flake.lock @@ -51,11 +51,11 @@ ] }, "locked": { - "lastModified": 1726396892, - "narHash": "sha256-KRGuT5nGRAOT3heigRWg41tbYpTpapGhsWc+XjnIx0w=", + "lastModified": 1726842196, + "narHash": "sha256-u9h03JQUuQJ607xmti9F9Eh6E96kKUAGP+aXWgwm70o=", "owner": "nix-community", "repo": "disko", - "rev": "51e3a7e51279fedfb6669a00d21dc5936c78a6ce", + "rev": "51994df8ba24d5db5459ccf17b6494643301ad28", "type": "github" }, "original": { @@ -106,11 +106,11 @@ ] }, "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "lastModified": 1726560853, + "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", "type": "github" }, "original": { @@ -146,11 +146,11 @@ ] }, "locked": { - "lastModified": 1726357542, - "narHash": "sha256-p4OrJL2weh0TRtaeu1fmNYP6+TOp/W2qdaIJxxQay4c=", + "lastModified": 1726902823, + "narHash": "sha256-Gkc7pwTVLKj4HSvRt8tXNvosl8RS9hrBAEhOjAE0Tt4=", "owner": "nix-community", "repo": "home-manager", - "rev": "e524c57b1fa55d6ca9d8354c6ce1e538d2a1f47f", + "rev": "14929f7089268481d86b83ed31ffd88713dcd415", "type": "github" }, "original": { @@ -225,11 +225,11 @@ }, "nixos-hardware": { "locked": { - "lastModified": 1725885300, - "narHash": "sha256-5RLEnou1/GJQl+Wd+Bxaj7QY7FFQ9wjnFq1VNEaxTmc=", + "lastModified": 1726905744, + "narHash": "sha256-xyNtG5C+xvfsnOVEamFe9zCCnuNwk93K/TlFC/4DmCI=", "owner": "NixOS", "repo": "nixos-hardware", - "rev": "166dee4f88a7e3ba1b7a243edb1aca822f00680e", + "rev": "b493dfd4a8cf9552932179e56ff3b5819a9b8381", "type": "github" }, "original": { @@ -240,11 +240,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1726365531, - "narHash": "sha256-luAKNxWZ+ZN0kaHchx1OdLQ71n81Y31ryNPWP1YRDZc=", + "lastModified": 1726871744, + "narHash": "sha256-V5LpfdHyQkUF7RfOaDPrZDP+oqz88lTJrMT1+stXNwo=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "9299cdf978e15f448cf82667b0ffdd480b44ee48", + "rev": "a1d92660c6b3b7c26fb883500a80ea9d33321be2", "type": "github" }, "original": { @@ -270,11 +270,11 @@ ] }, "locked": { - "lastModified": 1725513492, - "narHash": "sha256-tyMUA6NgJSvvQuzB7A1Sf8+0XCHyfSPRx/b00o6K0uo=", + "lastModified": 1726745158, + "narHash": "sha256-D5AegvGoEjt4rkKedmxlSEmC+nNLMBPWFxvmYnVLhjk=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "7570de7b9b504cfe92025dd1be797bf546f66528", + "rev": "4e743a6920eab45e8ba0fbe49dc459f1423a4b74", "type": "github" }, "original": { @@ -327,11 +327,11 @@ ] }, "locked": { - "lastModified": 1726382494, - "narHash": "sha256-T7W+ohiXe1IY0yf/PpS4wQItZ0SyRO+/v8kqNpMXlI4=", + "lastModified": 1726885519, + "narHash": "sha256-wrXknshJMRLv91KQD5d7ovUqJ70FlDM7XeG/upSsKgM=", "owner": "oxalica", "repo": "rust-overlay", - "rev": "ff13821613ffe5dbfeb4fe353b1f4bf291d831db", + "rev": "a66e16cb21e4428224925dbf1b66238c727dda0a", "type": "github" }, "original": { @@ -350,11 +350,11 @@ ] }, "locked": { - "lastModified": 1726218807, - "narHash": "sha256-z7CoWbSOtsOz8TmRKDnobURkKfv6nPZCo3ayolNuQGc=", + "lastModified": 1726524647, + "narHash": "sha256-qis6BtOOBBEAfUl7FMHqqTwRLB61OL5OFzIsOmRz2J4=", "owner": "Mic92", "repo": "sops-nix", - "rev": "f30b1bac192e2dc252107ac8a59a03ad25e1b96e", + "rev": "e2d404a7ea599a013189aa42947f66cede0645c8", "type": "github" }, "original": { @@ -385,11 +385,11 @@ ] }, "locked": { - "lastModified": 1725271838, - "narHash": "sha256-VcqxWT0O/gMaeWTTjf1r4MOyG49NaNxW4GHTO3xuThE=", + "lastModified": 1726734507, + "narHash": "sha256-VUH5O5AcOSxb0uL/m34dDkxFKP6WLQ6y4I1B4+N3L2w=", "owner": "numtide", "repo": "treefmt-nix", - "rev": "9fb342d14b69aefdf46187f6bb80a4a0d97007cd", + "rev": "ee41a466c2255a3abe6bc50fc6be927cdee57a9f", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 65d269f..1726b88 100644 --- a/flake.nix +++ b/flake.nix @@ -93,6 +93,13 @@ outputs = inputs: + let + data = builtins.fromJSON (builtins.readFile ./infra/data.json); + specialArgs = { + inherit inputs; + nodes = data.nodes.value; + }; + in inputs.flake-utils.lib.eachDefaultSystem ( system: let @@ -112,6 +119,12 @@ # nix develop devShells.default = pkgs.mkShellNoCC { packages = with pkgs; [ + (opentofu.withPlugins ( + ps: with ps; [ + vultr + sops + ] + )) colmena sops ]; @@ -124,41 +137,57 @@ nixosConfigurations = { "dust" = inputs.nixpkgs.lib.nixosSystem { + inherit specialArgs; system = "x86_64-linux"; modules = [ ./nixos/profiles/core ./hosts/dust ]; - specialArgs = { - inherit inputs; - }; }; } // inputs.self.colmenaHive.nodes; - colmenaHive = inputs.colmena.lib.makeHive { - meta = { - specialArgs = { - inherit inputs; + colmenaHive = inputs.colmena.lib.makeHive ( + { + meta = { + inherit specialArgs; + nixpkgs = import inputs.nixpkgs { + system = "x86_64-linux"; # How does this work? + }; }; - nixpkgs = import inputs.nixpkgs { - system = "x86_64-linux"; # How does this work? + + defaults.imports = [ + ./nixos/profiles/core + ./nixos/profiles/server + ]; + + "tyo0" = { + imports = [ ./hosts/tyo0 ]; + deployment.targetHost = "tyo0.ny4.dev"; }; - }; - defaults.imports = [ - ./nixos/profiles/core - ./nixos/profiles/server - ]; - - "tyo0" = { - imports = [ ./hosts/tyo0 ]; - deployment.targetHost = "tyo0.ny4.dev"; - }; - - "pek0" = { - imports = [ ./hosts/pek0 ]; - deployment.targetHost = "blacksteel"; # thru tailscale - }; - }; + "pek0" = { + imports = [ ./hosts/pek0 ]; + deployment.targetHost = "blacksteel"; # thru tailscale + }; + } + // (builtins.mapAttrs (n: v: { + deployment = { + inherit (v) tags; + targetHost = v.fqdn; + }; + imports = + if (builtins.elem "vultr" v.tags) then + [ + ./hosts/vultr/${n} + ./hosts/vultr/common + { networking.hostName = n; } + ] + # TODO: import aws + else if (builtins.elem "amazon" v.tags) then + [ ./hosts/amazon/${n} ] + else + [ ./hosts/${n} ]; + }) data.nodes.value) + ); }; } diff --git a/home/applications/ssh/default.nix b/home/applications/ssh/default.nix index 04b130e..50c321c 100644 --- a/home/applications/ssh/default.nix +++ b/home/applications/ssh/default.nix @@ -2,19 +2,12 @@ { programs.ssh = { enable = true; - matchBlocks = - let - inherit (config.home) homeDirectory; - serverConfig = { - identityFile = "${homeDirectory}/.ssh/id_github_signing"; - user = "root"; - }; - in - { - "tyo0.ny4.dev" = serverConfig; - "pek0.ny4.dev" = serverConfig // { - hostname = "blacksteel"; - }; + matchBlocks = { + "*.ny4.dev" = { + identityFile = "${config.home.homeDirectory}/.ssh/id_github_signing"; + user = "root"; }; + "pek0.ny4.dev".hostname = "blacksteel"; + }; }; } diff --git a/hosts/pek0/anti-feature.nix b/hosts/pek0/anti-feature.nix index e9ef550..36fa40a 100644 --- a/hosts/pek0/anti-feature.nix +++ b/hosts/pek0/anti-feature.nix @@ -1,10 +1,10 @@ { lib, ... }: { nixpkgs.config = { - allowNonSource = false; + allowNonSource = true; allowNonSourcePredicate = pkg: - lib.elem (lib.getName pkg) [ + (lib.elem (lib.getName pkg) [ "cargo-bootstrap" "go" "minecraft-server" @@ -12,7 +12,7 @@ "rustc-bootstrap-wrapper" "sof-firmware" "temurin-bin" - ]; + ]); allowUnfree = false; allowUnfreePredicate = diff --git a/hosts/tyo0/anti-feature.nix b/hosts/tyo0/anti-feature.nix index 845ef8f..6240ebf 100644 --- a/hosts/tyo0/anti-feature.nix +++ b/hosts/tyo0/anti-feature.nix @@ -17,8 +17,8 @@ allowUnfreePredicate = pkg: lib.elem (lib.getName pkg) [ ]; permittedInsecurePackages = [ - "cinny-4.1.0" - "cinny-unwrapped-4.1.0" + "cinny-4.2.1" + "cinny-unwrapped-4.2.1" ]; }; } diff --git a/hosts/tyo0/default.nix b/hosts/tyo0/default.nix index b3d87ea..0b68f4f 100644 --- a/hosts/tyo0/default.nix +++ b/hosts/tyo0/default.nix @@ -35,6 +35,9 @@ # WORKAROUND: systemd.services."print-host-key".enable = false; + # FIXME: error: builder for '/nix/store/...-ena-2.12.3-6.11.drv' failed with exit code 2 + boot.kernelPackages = lib.mkForce pkgs.linuxPackages_6_10; + ### Secrets sops.secrets = lib.mapAttrs (_name: value: value // { sopsFile = ./secrets.yaml; }) { "sing-box/auth" = { diff --git a/hosts/tyo0/services/prometheus.nix b/hosts/tyo0/services/prometheus.nix index 73a4bfe..6f3a3bd 100644 --- a/hosts/tyo0/services/prometheus.nix +++ b/hosts/tyo0/services/prometheus.nix @@ -2,10 +2,12 @@ lib, pkgs, config, + nodes, ... }: let inherit (config.lib) ports; + targets = lib.mapAttrsToList (_name: node: node.fqdn) nodes; in { services.prometheus = { @@ -36,9 +38,9 @@ in }; static_configs = lib.singleton { targets = [ - "tyo0.ny4.dev" "pek0.ny4.dev" - ]; + "tyo0.ny4.dev" + ] ++ targets; }; } { @@ -52,7 +54,7 @@ in targets = [ "tyo0.ny4.dev" "pek0.ny4.dev" - ]; + ] ++ targets; }; } { diff --git a/hosts/vultr/common/default.nix b/hosts/vultr/common/default.nix new file mode 100644 index 0000000..76ff2bc --- /dev/null +++ b/hosts/vultr/common/default.nix @@ -0,0 +1,39 @@ +{ + inputs, + modulesPath, + lib, + ... +}: +{ + imports = + [ + "${modulesPath}/installer/scan/not-detected.nix" + "${modulesPath}/profiles/qemu-guest.nix" + + ./disko.nix + ./preservation.nix + ] + ++ (with inputs; [ + disko.nixosModules.disko + preservation.nixosModules.preservation + ]); + + # vnc + services.getty.autologinUser = "root"; + + networking = { + useNetworkd = true; + useDHCP = false; + }; + + systemd.network.networks.ethernet = { + matchConfig.Name = [ + "en*" + "eth*" + ]; + DHCP = "yes"; + }; + + boot.loader.grub.enable = true; + boot.loader.grub.devices = lib.mkDefault [ "/dev/vda" ]; +} diff --git a/hosts/vultr/common/disko.nix b/hosts/vultr/common/disko.nix new file mode 100644 index 0000000..6c013aa --- /dev/null +++ b/hosts/vultr/common/disko.nix @@ -0,0 +1,59 @@ +{ inputs, ... }: +let + mountOptions = [ + "compress-force=zstd" + "noatime" + ]; +in +{ + imports = [ inputs.disko.nixosModules.disko ]; + + disko.devices = { + disk.vda = { + type = "disk"; + device = "/dev/vda"; + content = { + type = "gpt"; + partitions = { + boot = { + type = "EF02"; + start = "0"; + end = "+1M"; + }; + root = { + end = "-0"; + content = { + type = "btrfs"; + extraArgs = [ "-f" ]; + subvolumes = { + "/@boot" = { + mountpoint = "/boot"; + inherit mountOptions; + }; + "/@nix" = { + mountpoint = "/nix"; + inherit mountOptions; + }; + "/@persist" = { + mountpoint = "/persist"; + inherit mountOptions; + }; + }; + }; + }; + }; + }; + }; + nodev = { + "/" = { + fsType = "tmpfs"; + mountOptions = [ + "defaults" + "mode=755" + ]; + }; + }; + }; + + fileSystems."/persist".neededForBoot = true; +} diff --git a/hosts/vultr/common/preservation.nix b/hosts/vultr/common/preservation.nix new file mode 100644 index 0000000..840e52d --- /dev/null +++ b/hosts/vultr/common/preservation.nix @@ -0,0 +1,15 @@ +{ lib, ... }: +{ + sops.age.sshKeyPaths = lib.mkForce [ "/persist/etc/ssh/ssh_host_ed25519_key" ]; + + preservation.enable = true; + preservation.preserveAt."/persist" = { + directories = [ "/var" ]; + files = [ + "/etc/ssh/ssh_host_ed25519_key" + "/etc/ssh/ssh_host_ed25519_key.pub" + "/etc/ssh/ssh_host_rsa_key" + "/etc/ssh/ssh_host_rsa_key.pub" + ]; + }; +} diff --git a/hosts/vultr/sin0/default.nix b/hosts/vultr/sin0/default.nix new file mode 100644 index 0000000..2dbe833 --- /dev/null +++ b/hosts/vultr/sin0/default.nix @@ -0,0 +1,14 @@ +{ + system.stateVersion = "24.05"; + + networking.firewall.allowedUDPPorts = [ 443 ]; + networking.firewall.allowedTCPPorts = [ + 80 + 443 + ]; + + services.caddy.enable = true; + services.caddy.settings.apps.http.servers.srv0 = { + listen = [ ":443" ]; + }; +} diff --git a/infra/.gitignore b/infra/.gitignore new file mode 100644 index 0000000..30700b4 --- /dev/null +++ b/infra/.gitignore @@ -0,0 +1,3 @@ +/.terraform +/terraform.tfstate.* +/.terraform.lock.hcl diff --git a/infra/data.json b/infra/data.json new file mode 100644 index 0000000..01694c9 --- /dev/null +++ b/infra/data.json @@ -0,0 +1,45 @@ +{ + "nodes": { + "sensitive": false, + "type": [ + "object", + { + "sin0": [ + "object", + { + "fqdn": "string", + "ipv4": "string", + "ipv6": "string", + "remarks": [ + "object", + { + "city": "string", + "continent": "string", + "country": "string" + } + ], + "tags": [ + "list", + "string" + ] + } + ] + } + ], + "value": { + "sin0": { + "fqdn": "sin0.ny4.dev", + "ipv4": "149.28.143.116", + "ipv6": "2001:19f0:4400:7041:5400:05ff:fe1b:042d", + "remarks": { + "city": "Singapore", + "continent": "Asia", + "country": "SG" + }, + "tags": [ + "vultr" + ] + } + } + } +} diff --git a/infra/modules/vultr/main.tf b/infra/modules/vultr/main.tf new file mode 100644 index 0000000..61175e3 --- /dev/null +++ b/infra/modules/vultr/main.tf @@ -0,0 +1,90 @@ +variable "hostname" { + type = string +} + +variable "fqdn" { + type = string +} + +variable "region" { + type = string +} + +variable "plan" { + type = string +} + +variable "tags" { + type = list(string) +} + +variable "script" { + type = string +} + +terraform { + required_providers { + vultr = { + source = "registry.terraform.io/vultr/vultr" + } + } +} + +resource "vultr_instance" "server" { + region = var.region + plan = var.plan + hostname = var.fqdn + tags = var.tags + label = var.hostname + + os_id = 159 + script_id = var.script + + activation_email = false + ddos_protection = false + enable_ipv6 = true +} + +resource "vultr_reverse_ipv4" "reverse_ipv4" { + instance_id = vultr_instance.server.id + ip = vultr_instance.server.main_ip + reverse = var.fqdn +} + +resource "vultr_reverse_ipv6" "reverse_ipv6" { + instance_id = vultr_instance.server.id + ip = vultr_instance.server.v6_main_ip + reverse = var.fqdn +} + +data "vultr_region" "region" { + filter { + name = "id" + values = [vultr_instance.server.region] + } +} + +output "ipv4" { + value = vultr_reverse_ipv4.reverse_ipv4.ip +} + +output "ipv6" { + value = vultr_reverse_ipv6.reverse_ipv6.ip +} + +output "fqdn" { + value = var.fqdn +} + +output "tags" { + value = var.tags +} + +output "remarks" { + value = { + continent = data.vultr_region.region.continent + country = data.vultr_region.region.country + city = data.vultr_region.region.city + } +} + diff --git a/infra/outputs.tf b/infra/outputs.tf new file mode 100644 index 0000000..8777f24 --- /dev/null +++ b/infra/outputs.tf @@ -0,0 +1,3 @@ +output "nodes" { + value = module.vultr +} diff --git a/infra/secrets.tf b/infra/secrets.tf new file mode 100644 index 0000000..f2c5fb9 --- /dev/null +++ b/infra/secrets.tf @@ -0,0 +1,11 @@ +data "sops_file" "secrets" { + source_file = "secrets.yaml" +} + +locals { + secrets = yamldecode(data.sops_file.secrets.raw) +} + +provider "vultr" { + api_key = local.secrets.vultr.api_key +} diff --git a/infra/secrets.yaml b/infra/secrets.yaml new file mode 100644 index 0000000..2112a6c --- /dev/null +++ b/infra/secrets.yaml @@ -0,0 +1,24 @@ +vultr: + api_key: ENC[AES256_GCM,data:e3ZTVPp/k673qjoHx/ls4HrEv+rYNUsK93DvLbDZwQqZtyrx,iv:jbsJFFV6B+vNXq9AvNWFFnyWoAI+EpZ7olDofFDmd5M=,tag:dCaidJtn1CJka/4lwoVe8g==,type:str] +tofu: + encryption: ENC[AES256_GCM,data:7+K0SYGOURiEbZ4IrOMJYYVWcSlLqxLv+9lZRUH/cH34qZ7CUt8vsSYP7VyRgCVqFr7sETGj1LPliPjJT2yge9HNbbuUnJ0U3RpLytl7z63nOLeSvUU=,iv:WGrozRmPerQ7iPJAqWmBy9XQ6SnOLrcLLwxdoa1ZIWQ=,tag:rcfNqW57WyVc4U0Iy2MHKA==,type:str] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age129yyxyz686qj88ce5v77ahelqqwt6zz94mzzls0ny4hq76psrd9qhc79kq + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTaG5JdXdVVjdNNXlpSVAr + aUlxM3ROaWI3TmhMQVJ2OTB6djUwc2QrYVMwCnZrYVJxdGRFV05TRVlMN2M2NDJS + dkRZbllpQ1JGY1pJeE95TTkxYThpeG8KLS0tIC9TZkdzTFR1ZnArUWhSbUZYUTRE + WmJlc0piL0s1c3dQd25ibFFZUVRjTzAKNh71/iOviUisewtjmAXmJJdq8KfI4S8X + pzEyAoajZIjUfqAnCNxVjxett2bKb2liM/mpO1McOpSRnFe8cOXWMg== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-09-21T16:15:27Z" + mac: ENC[AES256_GCM,data:VNoPXECkdYjeig1Aq3MdILIpzlZS8pZrkiMyY5ay6nsmM6XdtwPGjE+veAGcw/qJ/1PHq8N8Wx5hmgFo0pdX2RQSvou+iWeWq26h33iAxUQ10YPA3tgUTlA6aFeTvmiu4YBR9inuKZ48NIk52vJ64PJXVIoKCyFi525y704Mc9g=,iv:YKTKifp6o1AzmzVCFT3PCaVpkBKUR+Q0w0m09IoeRp0=,tag:lOvBJmJy41NjcvkIJADh3Q==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.0 diff --git a/infra/terraform.tfstate b/infra/terraform.tfstate new file mode 100644 index 0000000..bc8e19c --- /dev/null +++ b/infra/terraform.tfstate @@ -0,0 +1 @@ +{"serial":20,"lineage":"c3bb4ce4-695c-edf3-3636-1ad64a51509c","meta":{"key_provider.pbkdf2.default":"eyJzYWx0IjoiLy9zSUhodjZXcHpuVCt2ZzRUUysxRWl4U0d1ZnpoWFpNcEtHVGNOcGZGVT0iLCJpdGVyYXRpb25zIjo2MDAwMDAsImhhc2hfZnVuY3Rpb24iOiJzaGE1MTIiLCJrZXlfbGVuZ3RoIjozMn0="},"encrypted_data":"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","encryption_version":"v0"} \ No newline at end of file diff --git a/infra/version.tf b/infra/version.tf new file mode 100644 index 0000000..c55a7cc --- /dev/null +++ b/infra/version.tf @@ -0,0 +1,21 @@ +terraform { + required_providers { + vultr = { + source = "registry.terraform.io/vultr/vultr" + } + sops = { + source = "registry.terraform.io/carlpett/sops" + } + } + + encryption { + method "aes_gcm" "default" { + keys = key_provider.pbkdf2.default + } + + state { + method = method.aes_gcm.default + enforced = true + } + } +} diff --git a/infra/vultr.tf b/infra/vultr.tf new file mode 100644 index 0000000..9524caa --- /dev/null +++ b/infra/vultr.tf @@ -0,0 +1,32 @@ +locals { + nodes = { + sin0 = { + region = "sgp" + plan = "vhp-1c-1gb-amd" + tags = ["vultr"] + } + } +} + +resource "vultr_startup_script" "script" { + name = "nixos" + type = "pxe" + script = base64encode(<