diff options
Diffstat (limited to 'users/wpcarro/terraform')
-rw-r--r-- | users/wpcarro/terraform/default.nix | 185 | ||||
-rw-r--r-- | users/wpcarro/terraform/gcp.tf | 79 |
2 files changed, 185 insertions, 79 deletions
diff --git a/users/wpcarro/terraform/default.nix b/users/wpcarro/terraform/default.nix new file mode 100644 index 000000000000..b3c16144a209 --- /dev/null +++ b/users/wpcarro/terraform/default.nix @@ -0,0 +1,185 @@ +{ depot, pkgs, lib, ... }: + +let + inherit (builtins) concatLists concatStringsSep toJSON unsafeDiscardStringContext; + inherit (depot.users) wpcarro; + inherit (pkgs) writeText; + + images = import "${pkgs.path}/nixos/modules/virtualisation/gce-images.nix"; + nixosImage = images."20.09"; +in { + googleCloudVM = { + project, + name, + region, + zone, + configuration, + extraConfig ? {}, + }: let + inherit (configuration.users.users) root; + inherit (configuration.networking) firewall; + + # Convert NixOS-style port numbers to Terraform-style. + asStrings = xs: map toString xs; + asRanges = xs: map (x: "${toString x.from}-${toString x.to}") xs; + + sshKeys = concatStringsSep "\n" + (map (key: "root:${key}") root.openssh.authorizedKeys.keys); + + os = depot.ops.nixos.nixosFor (_: { + imports = [ + "${pkgs.path}/nixos/modules/virtualisation/google-compute-image.nix" + configuration + ]; + + networking.hostName = name; + + fileSystems."/nix" = { + device = "/dev/disk/by-label/google-${name}-disk"; + fsType = "ext4"; + }; + }); + + osRoot = os.config.system.build.toplevel; + osPath = unsafeDiscardStringContext (toString osRoot.outPath); + drvPath = unsafeDiscardStringContext (toString osRoot.drvPath); + in writeText "terraform.tf.json" (toJSON (lib.recursiveUpdate extraConfig { + provider.google = { + inherit project region zone; + }; + + resource.google_compute_instance."${name}" = { + inherit name zone; + machine_type = "e2-standard-2"; + + tags = [ + "http-server" + "https-server" + "${name}-firewall" + ]; + + boot_disk = { + device_name = "boot"; + initialize_params = { + size = 10; + image = "projects/nixos-cloud/global/images/${nixosImage.name}"; + }; + }; + + attached_disk = { + source = "\${google_compute_disk.${name}.id}"; + device_name = "${name}-disk"; + }; + + network_interface = { + network = "default"; + subnetwork = "default"; + access_config = {}; + }; + + # Copy root's SSH keys from the NixOS configuration and expose them to the + # metadata server. + metadata = { + inherit sshKeys; + ssh-keys = sshKeys; + + # NixOS's fetch-instance-ssh-keys.bash relies on these fields being + # available on the metadata server. + ssh_host_ed25519_key = "\${tls_private_key.${name}.private_key_pem}"; + ssh_host_ed25519_key_pub = "\${tls_private_key.${name}.public_key_pem}"; + + # Even though we have SSH access, having oslogin can still be useful for + # troubleshooting in the browser if for some reason SSH isn't working as + # expected. + enable-oslogin = "TRUE"; + }; + + service_account.scopes = ["cloud-platform"]; + }; + + resource.tls_private_key."${name}" = { + algorithm = "ECDSA"; + ecdsa_curve = "P384"; + }; + + resource.google_compute_firewall."${name}" = { + name = "${name}-firewall"; + network = "default"; + + # Read the firewall configuration from the NixOS configuration. + allow = [ + { + protocol = "tcp"; + ports = concatLists [ + (asStrings (firewall.allowedTCPPorts or [])) + (asRanges (firewall.allowedTCPPortRanges or [])) + ]; + } + { + protocol = "udp"; + ports = concatLists [ + (asStrings (firewall.allowedUDPPorts or [])) + (asRanges (firewall.allowedUDPPortRanges or [])) + ]; + } + ]; + source_tags = ["${name}-firewall"]; + }; + + resource.google_compute_disk."${name}" = { + inherit zone; + name = "${name}-disk"; + size = 100; + }; + + resource.null_resource.deploy_nixos = { + triggers = { + # Redeploy when the NixOS configuration changes. + os = "${osPath}"; + # Redeploy when a new machine is provisioned. + machine_id = "\${google_compute_instance.${name}.id}"; + }; + + connection = { + host = "\${google_compute_instance.${name}.network_interface[0].access_config[0].nat_ip}"; + }; + + provisioner = [ + { remote-exec.inline = ["true"]; } + { + local-exec.command = '' + export PATH="${pkgs.openssh}/bin:$PATH" + + scratch="$(mktemp -d)" + function cleanup() { + rm -rf $scratch + } + trap cleanup EXIT + + # write out ssh key + echo -n "''${tls_private_key.${name}.private_key_pem}" > $scratch/id_rsa.pem + chmod 0600 $scratch/id_rsa.pem + + export NIX_SSHOPTS="\ + -o StrictHostKeyChecking=no\ + -o UserKnownHostsFile=/dev/null\ + -o GlobalKnownHostsFile=/dev/null\ + -o IdentityFile=$scratch/id_rsa.pem + " + + nix-build ${drvPath} + nix-copy-closure --to \ + root@''${google_compute_instance.${name}.network_interface[0].access_config[0].nat_ip} \ + ${osPath} --gzip --use-substitutes + ''; + } + { + remote-exec.inline = [ + "nix-env --profile /nix/var/nix/profiles/system --set ${osPath}" + "${osPath}/bin/switch-to-configuration switch" + ]; + } + ]; + }; + })); +} diff --git a/users/wpcarro/terraform/gcp.tf b/users/wpcarro/terraform/gcp.tf deleted file mode 100644 index 03bb721c9d35..000000000000 --- a/users/wpcarro/terraform/gcp.tf +++ /dev/null @@ -1,79 +0,0 @@ -provider "google" { - project = "wpcarros-infrastructure" - region = "us-central1" - zone = "us-central1-a" -} - -data "google_compute_default_service_account" "default" {} - -resource "google_compute_instance" "default" { - name = "diogenes-2" - machine_type = "e2-standard-2" - zone = "us-central1-a" - hostname = "diogenes.wpcarro.dev" - - tags = [ - "http-server", - "https-server", - "diogenes-firewall" - ] - - boot_disk { - device_name = "boot" - - initialize_params { - size = 10 - image = "projects/nixos-cloud/global/images/nixos-image-20-09-3531-3858fbc08e6-x86-64-linux" - } - } - - attached_disk { - source = "diogenes-2-disk" - device_name = "diogenes-2-disk" - } - - network_interface { - network = "default" - subnetwork = "default" - - access_config {} - } - - metadata = { - # sshKeys is deprecated, but the GCE NixOS image relies on it, so we need - # both values: - # - deprecation: https://cloud.google.com/compute/docs/metadata/default-metadata-values - # - NixOS bug: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/virtualisation/fetch-instance-ssh-keys.bash#L14 - ssh-keys = "wpcarro:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJkNQJBXekuSzZJ8+gxT+V1+eXTm3hYsfigllr/ARXkf wpcarro@gmail.com" - sshKeys = "wpcarro:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJkNQJBXekuSzZJ8+gxT+V1+eXTm3hYsfigllr/ARXkf wpcarro@gmail.com" - } - - service_account { - scopes = ["cloud-platform"] - } -} - -resource "google_compute_firewall" "default" { - name = "diogenes-firewall" - network = "default" - - allow { - protocol = "tcp" - ports = ["6698"] - } - - allow { - protocol = "udp" - ports = [ - "60000-61000" # mosh - ] - } - - source_tags = ["diogenes-firewall"] -} - -resource "google_compute_disk" "default" { - name = "diogenes-2-disk" - zone = "us-central1-a" - size = 100 -} \ No newline at end of file |