forked from Fediversity/Fediversity
176 lines
5.1 KiB
HCL
176 lines
5.1 KiB
HCL
variable "domain" {
|
|
type = string
|
|
default = "fediversity.net"
|
|
}
|
|
|
|
variable "mastodon" {
|
|
type = object({
|
|
enable = bool
|
|
})
|
|
default = {
|
|
enable = false
|
|
}
|
|
}
|
|
|
|
variable "pixelfed" {
|
|
type = object({
|
|
enable = bool
|
|
})
|
|
default = {
|
|
enable = false
|
|
}
|
|
}
|
|
|
|
variable "peertube" {
|
|
type = object({
|
|
enable = bool
|
|
})
|
|
default = {
|
|
enable = false
|
|
}
|
|
}
|
|
|
|
variable "initialUser" {
|
|
type = object({
|
|
displayName = string
|
|
username = string
|
|
email = string
|
|
# TODO: mark (nested) credentials as sensitive
|
|
# https://discuss.hashicorp.com/t/is-it-possible-to-mark-an-attribute-of-an-object-as-sensitive/24649/2
|
|
password = string
|
|
})
|
|
default = {
|
|
displayName = "Testy McTestface"
|
|
username = "test"
|
|
email = "test@test.com"
|
|
password = "testtest"
|
|
}
|
|
}
|
|
|
|
variable "ssh_private_key_file" {
|
|
type = string
|
|
description = "Path to private key used to connect to the target_host"
|
|
default = ""
|
|
}
|
|
|
|
variable "deploy_environment" {
|
|
type = map(string)
|
|
description = "Extra environment variables to be set during deployment."
|
|
default = {}
|
|
}
|
|
|
|
locals {
|
|
system = "x86_64-linux"
|
|
pins = jsondecode(file("${path.module}/.npins.json"))
|
|
peripheral_configs = {
|
|
garage = "test01"
|
|
}
|
|
application_configs = {
|
|
mastodon = {
|
|
cfg = var.mastodon
|
|
hostname = "test06"
|
|
}
|
|
pixelfed = {
|
|
cfg = var.pixelfed
|
|
hostname = "test04"
|
|
}
|
|
peertube = {
|
|
cfg = var.peertube
|
|
hostname = "test05"
|
|
}
|
|
}
|
|
peripherals = { for name, inst in local.peripheral_configs : name => {
|
|
hostname = inst
|
|
cfg = {
|
|
enable = anytrue([for _, app in local.application_configs: app.cfg.enable])
|
|
}
|
|
}
|
|
}
|
|
applications = { for name, inst in local.application_configs : name => merge(inst, {
|
|
# depends_on = [for name in local.peripheral_configs : module.deploy[name]]
|
|
})
|
|
}
|
|
}
|
|
|
|
# FIXME settle for pwd when in /nix/store?
|
|
# FIXME calculate separately to reduce false positives
|
|
data "external" "hash" {
|
|
program = ["echo", "{\"hash\":\"$(nix-hash ..)\"}"]
|
|
}
|
|
|
|
# merge instantiate/deploy, cuz i don't want 24+s instantiates when nothing changed.
|
|
# terraform-nixos separates these to only deploy if instantiate changed.
|
|
# FIXME find a better solution for this. current considerations were:
|
|
# - `resource null_resource` cannot have outputs, while we want info from the instantiation (unless built on host?).
|
|
# - `data external` always runs, which is undesirable for steps like deploy/instantiation.
|
|
# FIXME null_resource docs recommend terraform_data over null_resource
|
|
resource "null_resource" "deploy_nixos" {
|
|
for_each = {for name, inst in merge(
|
|
local.peripherals,
|
|
local.applications,
|
|
) : name => inst if inst.cfg.enable}
|
|
|
|
triggers = data.external.hash.result
|
|
|
|
provisioner "local-exec" {
|
|
working_dir = path.root
|
|
environment = merge(var.deploy_environment, {
|
|
NIX_PATH = join(":", [for name, path in local.pins : "${name}=${path}"]),
|
|
})
|
|
# TODO: refactor back to command="ignoreme" interpreter=concat([]) to protect sensitive data from error logs?
|
|
# TODO: build on target?
|
|
command = <<-EOF
|
|
set -euo pipefail
|
|
|
|
# INSTANTIATE
|
|
command=(
|
|
nix-instantiate
|
|
--expr
|
|
'let
|
|
os = import <nixpkgs/nixos> {
|
|
system = "${local.system}";
|
|
configuration = {
|
|
terraform = builtins.fromJSON "${replace(jsonencode({
|
|
domain = var.domain
|
|
hostname = each.value.hostname
|
|
initialUser = var.initialUser
|
|
}), "\"", "\\\"")}";
|
|
imports = [
|
|
${path.root}/options.nix
|
|
${path.root}/shared.nix
|
|
${path.root}/${each.key}.nix
|
|
# FIXME: get VM details from TF
|
|
${path.root}/../infra/test-machines/${each.value.hostname}
|
|
];
|
|
};
|
|
};
|
|
in {
|
|
substituters = builtins.concatStringsSep " " os.config.nix.binaryCaches;
|
|
trusted_public_keys = builtins.concatStringsSep " " os.config.nix.binaryCachePublicKeys;
|
|
drv_path = os.config.system.build.toplevel.drvPath;
|
|
out_path = os.config.system.build.toplevel;
|
|
}'
|
|
)
|
|
"$${command[@]}" -A out_path
|
|
json="$("$${command[@]}" --eval --strict --json)"
|
|
|
|
# DEPLOY
|
|
declare substituters trusted_public_keys drv_path
|
|
eval "export $(echo $json | jaq -r 'to_entries | map("\(.key)=\(.value)") | @sh')"
|
|
host="root@${each.value.hostname}.abundos.eu" # FIXME: #24
|
|
buildArgs=(
|
|
--option extra-binary-caches https://cache.nixos.org/
|
|
--option substituters $substituters
|
|
--option trusted-public-keys $trusted_public_keys
|
|
)
|
|
sshOpts=(
|
|
-o StrictHostKeyChecking=no
|
|
-o BatchMode=yes
|
|
-o "IdentityFile='${var.ssh_private_key_file}'"
|
|
)
|
|
outPath=$(nix-store --realize "$drv_path" "$${buildArgs[@]}")
|
|
NIX_SSHOPTS="$${sshOpts[*]}" nix-copy-closure --to "$host" "$outPath" --gzip --use-substitutes
|
|
ssh "$${sshOpts[@]}" "$host" "nix-env --profile /nix/var/nix/profiles/system --set $outPath; $outPath/bin/switch-to-configuration switch"
|
|
EOF
|
|
}
|
|
}
|