Fediversity/launch/.terraform/modules/peertube.deploy/terraform/all-in-one.md

20 KiB

All-in-one

Combines the install and nixos-rebuild module in one interface to install NixOS with nixos-anywhere and then keep it up-to-date with nixos-rebuild.

Example

locals {
  ipv4 = "192.0.2.1"
}

module "deploy" {
  source                 = "github.com/nix-community/nixos-anywhere//terraform/all-in-one"
  # with flakes
  nixos_system_attr      = ".#nixosConfigurations.mymachine.config.system.build.toplevel"
  nixos_partitioner_attr = ".#nixosConfigurations.mymachine.config.system.build.diskoScript"
  # without flakes
  # file can use (pkgs.nixos []) function from nixpkgs
  #file                   = "${path.module}/../.."
  #nixos_system_attr      = "config.system.build.toplevel"
  #nixos_partitioner_attr = "config.system.build.diskoScript"

  target_host            = local.ipv4
  # when instance id changes, it will trigger a reinstall
  instance_id            = local.ipv4
  # useful if something goes wrong
  # debug_logging          = true
  # build the closure on the remote machine instead of locally
  # build_on_remote        = true
  # script is below
  extra_files_script     = "${path.module}/decrypt-ssh-secrets.sh"
  disk_encryption_key_scripts = [{
    path   = "/tmp/secret.key"
    # script is below
    script = "${path.module}/decrypt-zfs-key.sh"
  }]
  # Optional, arguments passed to special_args here will be available from a NixOS module in this example the `terraform` argument:
  # { terraform, ... }: {
  #    networking.interfaces.enp0s3.ipv4.addresses = [{ address = terraform.ip;  prefixLength = 24; }];
  # }
  # Note that this will means that your NixOS configuration will always depend on terraform!
  # Skip to `Pass data persistently to the NixOS` for an alternative approach
  #special_args = {
  #  terraform = {
  #    ip = "192.0.2.0"
  #  }
  #}
}

Note: You need to mark scripts as executable (chmod +x)

./decrypt-ssh-secrets.sh

#!/usr/bin/env bash

mkdir -p etc/ssh var/lib/secrets

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"

umask 0177
sops --extract '["initrd_ssh_key"]' --decrypt "$SCRIPT_DIR/secrets.yaml" >./var/lib/secrets/initrd_ssh_key

# restore umask
umask 0022

for keyname in ssh_host_rsa_key ssh_host_rsa_key.pub ssh_host_ed25519_key ssh_host_ed25519_key.pub; do
  if [[ $keyname == *.pub ]]; then
    umask 0133
  else
    umask 0177
  fi
  sops --extract '["'$keyname'"]' --decrypt "$SCRIPT_DIR/secrets.yaml" >"./etc/ssh/$keyname"
done

./decrypt-zfs-key.sh

#!/usr/bin/env bash

set -euo pipefail

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cd "$SCRIPT_DIR"
sops --extract '["zfs-key"]' --decrypt "$SCRIPT_DIR/secrets.yaml"

See also

Pass data persistently to the NixOS

This guide outlines how to pass data from Terraform to NixOS by generating a file during Terraform execution and including it in your NixOS configuration. This approach works well if your Terraform and NixOS configurations are stored in the same Git repository.

Why Use This Method?

This method provides a straightforward way to transfer values from Terraform to NixOS without relying on special_args.

  • Advantages:
    • You can continue to use nix build or nixos-rebuild to evaluate your configuration without interruption. Simplifies configuration management by centralizing state in a single repository.
  • Disadvantages:
    • Deploying new machines requires tracking additional state. Every time Terraform updates the JSON file, you'll need to commit these changes to your repository.

Implementation

Add the following snippet to your Terraform configuration to create and manage a JSON file containing the necessary variables for NixOS. This file will be automatically added to your Git repository, ensuring the data persists.

Assuming you have your terraform and nixos configuration in the same git repository. You can use the following snippet to git add a file generated by terraform during execution to pass data from terraform to NixOS. These changes should be committed afterwards. This is an alternative over using special_args. Advantage: you can still use nix build or nixos-rebuild on your flake to evaluate your configuration. Disadvantage: Deploying new machines also means you need to track additional state and make additional commits whenever terraform updates the json file.

locals {
  nixos_vars_file = "nixos-vars.json" # Path to the JSON file containing NixOS variables
  nixos_vars = {
    ip = "192.0.2.0" # Replace with actual variables
  }
}
resource "local_file" "nixos_vars" {
  content         = jsonencode(local.nixos_vars) # Converts variables to JSON
  filename        = local.nixos_vars_file        # Specifies the output file path
  file_permission = "600"

  # Automatically adds the generated file to Git
  provisioner "local-exec" {
    interpreter = ["bash", "-c"]
    command     = "git add -f '${local.nixos_vars_file}'"
  }
}

After applying the Terraform changes, ensure you commit the updated nixos-vars.json file to your Git repository:

git commit -m "Update NixOS variables from Terraform"

You can import this json file into your configuration like this:

let
  nixosVars = builtins.fromJSON (builtins.readFile ./nixos-vars.json);
in
{
  # Example usage of imported variables
  networking.hostName = "example-machine";
  networking.interfaces.eth0.ipv4.addresses = [
    {
      address = nixosVars.ip;  # Use the IP from nixos-vars.json
      prefixLength = 24;
    }
  ];
}

Requirements

No requirements.

Providers

No providers.

Modules

Name Source Version
install ../install n/a
nixos-rebuild ../nixos-rebuild n/a
partitioner-build ../nix-build n/a
system-build ../nix-build n/a

Resources

No resources.

Inputs

Name Description Type Default Required
debug_logging Enable debug logging bool false no
deployment_ssh_key Content of private key used to deploy to the target_host after initial installation. To ensure maximum security, it is advisable to connect to your host using ssh-agent instead of relying on this variable string null no
disk_encryption_key_scripts Each script will be executed locally. Output of each will be created at the given path to disko during installation. The keys will be not copied to the final system
list(object({
path = string
script = string
}))
[] no
extra_environment Extra environment variables to be set during installation. This can be useful to set extra variables for the extra_files_script or disk_encryption_key_scripts map(string) {} no
extra_files_script A script that should place files in the current directory that will be copied to the targets / directory string null no
file Nix file containing the nixos_system_attr and nixos_partitioner_attr. Use this if you are not using flake string null no
install_port SSH port used to connect to the target_host, before installing NixOS. If null than the value of target_port is used string null no
install_ssh_key Content of private key used to connect to the target_host during initial installation string null no
install_user SSH user used to connect to the target_host, before installing NixOS. If null than the value of target_host is used string null no
instance_id The instance id of the target_host, used to track when to reinstall the machine string null no
kexec_tarball_url NixOS kexec installer tarball url string null no
nix_options the options of nix map(string) {} no
nixos_facter_path Path to which to write a facter.json generated by nixos-facter. string "" no
nixos_generate_config_path Path to which to write a hardware-configuration.nix generated by nixos-generate-config. string "" no
nixos_partitioner_attr Nixos partitioner and mount script i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.diskoNoDeps or just your-evaluated.config.system.build.diskNoDeps. config.system.build.diskNoDeps is provided by the disko nixos module string n/a yes
nixos_system_attr The nixos system to deploy i.e. your-flake#nixosConfigurations.your-evaluated-nixos.config.system.build.toplevel or just your-evaluated-nixos.config.system.build.toplevel if you are not using flakes string n/a yes
no_reboot DEPRECATED: Use phases instead. Do not reboot after installation bool false no
phases Phases to run. See nixos-anywhere --help for more information set(string)
[
"kexec",
"disko",
"install",
"reboot"
]
no
special_args A map exposed as NixOS's specialArgs thru a file. any {} no
build_on_remote Build the closure on the remote machine instead of building it locally and copying it over bool false no
stop_after_disko DEPRECATED: Use phases instead. Exit after disko formatting bool false no
target_host DNS host to deploy to string n/a yes
target_port SSH port used to connect to the target_host after installing NixOS. If install_port is not set than this port is also used before installing. number 22 no
target_user SSH user used to connect to the target_host after installing NixOS. If install_user is not set than this user is also used before installing. string "root" no

Outputs

Name Description
result n/a