Create files from nixos-wiki-infra
parent
0c54ab6bef
commit
7e20cace41
|
@ -0,0 +1 @@
|
|||
HCLOUD_TOKEN="your_token_here"
|
|
@ -3,3 +3,5 @@
|
|||
*.env
|
||||
*.tfstate
|
||||
*.tfstate.backup
|
||||
*.tfstate.*.backup
|
||||
.terraform.lock.hcl
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
# This file is maintained automatically by "tofu init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.opentofu.org/hashicorp/external" {
|
||||
version = "2.3.4"
|
||||
hashes = [
|
||||
"h1:i0CiDzSau8J/NcGlv6A3luRuYkqbnuO2c+XVrJ6YOoA=",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.opentofu.org/hashicorp/null" {
|
||||
version = "3.2.3"
|
||||
hashes = [
|
||||
"h1:tIPswUCP63F9jN+FulrFOJfVriHAMtLUPEkalbwa+Ys=",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.opentofu.org/hetznercloud/hcloud" {
|
||||
version = "1.49.1"
|
||||
constraints = "~> 1.45"
|
||||
hashes = [
|
||||
"h1:dyK3/rOb8IJOM0trh328NovbYb+Rz33qui2/fg85hU8=",
|
||||
]
|
||||
}
|
|
@ -4,15 +4,9 @@ This is an experimental configuration for my Hetzner VPS using OpenTofu and Nix.
|
|||
|
||||
## How to use
|
||||
|
||||
In the `terraform` directory, copy `secret.tfvars.example` to `secret.tfvars` and fill in the values.
|
||||
Copy `.env.example` to `.env` and fill in the values.
|
||||
|
||||
To generate a token with Hetzner, go to the project and click `Security -> API Tokens`.
|
||||
|
||||
Run `nix develop` to access a shell where OpenTofu is accessible.
|
||||
|
||||
## Aliases
|
||||
|
||||
The following aliases in the development shell include the secrets file automatically.
|
||||
|
||||
- `tofu-plan` - run in `terraform` directory
|
||||
- `tofu-apply` - run in `terraform` directory
|
||||
|
|
23
flake.lock
23
flake.lock
|
@ -60,7 +60,28 @@
|
|||
"inputs": {
|
||||
"disko": "disko",
|
||||
"flake-parts": "flake-parts",
|
||||
"nixpkgs": "nixpkgs"
|
||||
"nixpkgs": "nixpkgs",
|
||||
"srvos": "srvos"
|
||||
}
|
||||
},
|
||||
"srvos": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1740012831,
|
||||
"narHash": "sha256-u6Y5ttXBuQ+tyyCei07QnbNL6Gydv55OpoGh4fXzTqg=",
|
||||
"owner": "numtide",
|
||||
"repo": "srvos",
|
||||
"rev": "f6ddf92bc61e021ea05c971a055624509ffac429",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "srvos",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
17
flake.nix
17
flake.nix
|
@ -7,32 +7,41 @@
|
|||
|
||||
disko.url = "github:nix-community/disko";
|
||||
disko.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
srvos.url = "github:numtide/srvos";
|
||||
srvos.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
outputs = inputs@{ flake-parts, ... }:
|
||||
outputs = inputs@{ flake-parts, nixpkgs, ... }:
|
||||
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
];
|
||||
|
||||
imports = [
|
||||
./targets/flake-module.nix
|
||||
./modules/flake-module.nix
|
||||
];
|
||||
perSystem = { system, pkgs, ... }:
|
||||
let
|
||||
tofuPkg = pkgs.opentofu.withPlugins (p: [
|
||||
pkgs.terraform-providers.hcloud
|
||||
pkgs.terraform-providers.null
|
||||
pkgs.terraform-providers.external
|
||||
pkgs.terraform-providers.local
|
||||
]);
|
||||
in {
|
||||
devShells.default = pkgs.mkShell {
|
||||
buildInputs = [
|
||||
tofuPkg
|
||||
pkgs.terraform-ls
|
||||
pkgs.hcloud
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
alias tofu-plan="tofu plan -var-file=secret.tfvars"
|
||||
alias tofu-apply="tofu apply -var-file=secret.tfvars"
|
||||
set -a
|
||||
source ./.env
|
||||
set +a
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
flake.nixosModules = {
|
||||
hcloud.imports = [
|
||||
inputs.srvos.nixosModules.server
|
||||
inputs.srvos.nixosModules.hardware-hetzner-cloud
|
||||
./single-disk.nix
|
||||
];
|
||||
};
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
{ self, ... }:
|
||||
let
|
||||
partitions = {
|
||||
boot = {
|
||||
size = "1M";
|
||||
type = "EF02"; # for grub MBR
|
||||
};
|
||||
esp = {
|
||||
size = "500M";
|
||||
type = "EF00"; # for grub MBR
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
size = "100%";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "btrfs";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
self.inputs.disko.nixosModules.disko
|
||||
];
|
||||
disko.devices = {
|
||||
disk.sda = {
|
||||
type = "disk";
|
||||
device = "/dev/sda";
|
||||
content = {
|
||||
type = "gpt";
|
||||
inherit partitions;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
rm -f .terraform.lock.hcl
|
||||
tofu init
|
||||
tofu apply "$@"
|
|
@ -0,0 +1,6 @@
|
|||
module "vpn" {
|
||||
source = "../../terraform/admins"
|
||||
ssh_keys = {
|
||||
sudoer777 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJWUVBj2uBVfXGjWwXmOTQmqP1oc2ZfDtylhTEox6JBm ssh@sudoer777.dev"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
{ 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
|
||||
);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
rm -f .terraform.lock.hcl
|
||||
tofu init
|
||||
tofu apply "$@"
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
self,
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
nixosVars = builtins.fromJSON (builtins.readFile ./nixos-vars.json);
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
self.nixosModules.hcloud
|
||||
];
|
||||
users.users.root.openssh.authorizedKeys.keys = nixosVars.ssh_keys;
|
||||
system.stateVersion = "23.11";
|
||||
|
||||
networking = {
|
||||
hostName = "vpn";
|
||||
};
|
||||
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings.PasswordAuthentication = false;
|
||||
};
|
||||
|
||||
boot.supportedFilesystems = ["btrfs"];
|
||||
environment.systemPackages = [pkgs.btrfs-progs];
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
||||
nixBuild() {
|
||||
if command -v nom -v &>/dev/null; then
|
||||
nom build "$@"
|
||||
else
|
||||
nix build "$@"
|
||||
fi
|
||||
}
|
||||
nixBuild .#nixosConfigurations.vpn.config.system.build.toplevel -L
|
||||
if ! nixos-rebuild switch --flake .#vpn --target-host root@vpn; then
|
||||
nixos-rebuild switch --flake .#vpn --target-host root@vpn
|
||||
fi
|
|
@ -0,0 +1 @@
|
|||
{"ipv6_address":"2a01:4ff:1f0:ce35::1","ssh_keys":["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJWUVBj2uBVfXGjWwXmOTQmqP1oc2ZfDtylhTEox6JBm ssh@sudoer777.dev"]}
|
|
@ -0,0 +1,17 @@
|
|||
module "vpn" {
|
||||
source = "../../terraform/nixos-vpn"
|
||||
nixos_flake_attr = "vpn"
|
||||
nixos_vars_file = "${path.module}/nixos-vars.json"
|
||||
tags = {
|
||||
Terraform = "true"
|
||||
Target = "vpn"
|
||||
}
|
||||
}
|
||||
|
||||
output "ipv4_address" {
|
||||
value = module.vpn.ipv4_address
|
||||
}
|
||||
|
||||
output "ipv6_address" {
|
||||
value = module.vpn.ipv6_address
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
# This file is maintained automatically by "tofu init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.opentofu.org/hashicorp/external" {
|
||||
version = "2.3.4"
|
||||
hashes = [
|
||||
"h1:i0CiDzSau8J/NcGlv6A3luRuYkqbnuO2c+XVrJ6YOoA=",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.opentofu.org/hashicorp/null" {
|
||||
version = "3.2.3"
|
||||
hashes = [
|
||||
"h1:tIPswUCP63F9jN+FulrFOJfVriHAMtLUPEkalbwa+Ys=",
|
||||
]
|
||||
}
|
||||
|
||||
provider "registry.opentofu.org/hetznercloud/hcloud" {
|
||||
version = "1.49.1"
|
||||
constraints = "~> 1.45"
|
||||
hashes = [
|
||||
"h1:dyK3/rOb8IJOM0trh328NovbYb+Rz33qui2/fg85hU8=",
|
||||
]
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
resource "hcloud_ssh_key" "hcloud" {
|
||||
for_each = var.ssh_keys
|
||||
name = each.key
|
||||
public_key = each.value
|
||||
labels = {
|
||||
"wiki" = "true"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
hcloud = { source = "hetznercloud/hcloud" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
variable "ssh_keys" {
|
||||
type = map(string)
|
||||
description = "SSH public keys for admin user (name -> key)"
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
hcloud = {
|
||||
source = "hetznercloud/hcloud"
|
||||
version = "~> 1.45"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "hcloud_token" {
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
provider "hcloud" {
|
||||
token = var.hcloud_token
|
||||
}
|
||||
|
||||
resource "hcloud_ssh_key" "main" {
|
||||
name = "my-ssh-key"
|
||||
public_key = file("~/.ssh/id_ed25519.pub")
|
||||
}
|
||||
|
||||
resource "hcloud_server" "vpn" {
|
||||
name = "vpn"
|
||||
image = "debian-12"
|
||||
server_type = "cpx11"
|
||||
location = "hil"
|
||||
ssh_keys = [hcloud_ssh_key.main.id]
|
||||
|
||||
//provisioner "local-exec" {
|
||||
// command = "sleep 120"
|
||||
//}
|
||||
|
||||
//provisioner "remote-exec" {
|
||||
// connection {
|
||||
// type = "ssh"
|
||||
// user = "root"
|
||||
// host = self.ipv4_address
|
||||
// // private_key = file("~/.ssh/id_ed25519")
|
||||
// agent = true
|
||||
// }
|
||||
// inline = [
|
||||
// "curl https://raw.githubusercontent.com/elitak/NixOS-infect/master/NixOS-infect | PROVIDER=hetznercloud Nix_CHANNEL=NixOS-Unstable bash 2>&1 | tee /tmp/infect. log",
|
||||
// ]
|
||||
//}
|
||||
}
|
||||
|
||||
module "deploy" {
|
||||
//depends_on = [local_file.nixos_vars]
|
||||
source = "github.com/numtide/nixos-anywhere//terraform/all-in-one"
|
||||
nixos_system_attr = ".#nixosConfigurations.vpn.config.system.build.toplevel"
|
||||
nixos_partitioner_attr = ".#nixosConfigurations.vpn.config.system.build.diskoScript"
|
||||
target_host = hcloud_server.vpn.ipv4_address
|
||||
instance_id = hcloud_server.vpn.id
|
||||
//extra_files_script = "${path.module}/decrypt-age-keys.sh"
|
||||
//extra_environment = {
|
||||
// SOPS_FILE = var.sops_file
|
||||
//}
|
||||
debug_logging = true
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
data "hcloud_ssh_keys" "nixos_vpn" {
|
||||
//with_selector = "vpn=true"
|
||||
}
|
||||
|
||||
resource "hcloud_server" "nixos_vpn" {
|
||||
name = "nixos-vpn"
|
||||
image = "debian-12"
|
||||
keep_disk = true
|
||||
server_type = var.server_type
|
||||
location = var.server_location
|
||||
ssh_keys = data.hcloud_ssh_keys.nixos_vpn.ssh_keys.*.name
|
||||
backups = false
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [ssh_keys]
|
||||
prevent_destroy = true
|
||||
}
|
||||
}
|
||||
|
||||
module "deploy" {
|
||||
depends_on = [local_file.nixos_vars]
|
||||
source = "github.com/numtide/nixos-anywhere//terraform/all-in-one"
|
||||
nixos_system_attr = ".#nixosConfigurations.vpn.config.system.build.toplevel"
|
||||
nixos_partitioner_attr = ".#nixosConfigurations.vpn.config.system.build.diskoScriptNoDeps"
|
||||
target_host = hcloud_server.nixos_vpn.ipv4_address
|
||||
instance_id = hcloud_server.nixos_vpn.id
|
||||
debug_logging = true
|
||||
}
|
||||
|
||||
locals {
|
||||
nixos_vars = {
|
||||
ipv6_address = hcloud_server.nixos_vpn.ipv6_address
|
||||
ssh_keys = data.hcloud_ssh_keys.nixos_vpn.ssh_keys.*.public_key
|
||||
}
|
||||
}
|
||||
|
||||
output "ipv4_address" {
|
||||
value = hcloud_server.nixos_vpn.ipv4_address
|
||||
}
|
||||
|
||||
output "ipv6_address" {
|
||||
value = hcloud_server.nixos_vpn.ipv6_address
|
||||
}
|
|
@ -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 '${var.nixos_vars_file}'"
|
||||
}
|
||||
# also pro-actively add hosts and flake-module.nix to git so nix can find it.
|
||||
provisioner "local-exec" {
|
||||
interpreter = ["bash", "-c"]
|
||||
command = <<EOT
|
||||
git add "$(dirname '${var.nixos_vars_file}')"/{hosts,flake-module.nix}
|
||||
EOT
|
||||
on_failure = continue
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
terraform {
|
||||
required_providers {
|
||||
hcloud = { source = "hetznercloud/hcloud" }
|
||||
local = { source = "hashicorp/local" }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
variable "server_type" {
|
||||
type = string
|
||||
default = "cpx11"
|
||||
description = "Hetzner cloud server type"
|
||||
}
|
||||
|
||||
variable "server_location" {
|
||||
type = string
|
||||
default = "hil"
|
||||
description = "Hetzner cloud server location"
|
||||
}
|
||||
|
||||
variable "nixos_vars_file" {
|
||||
type = string
|
||||
description = "File to write NixOS configuration variables to"
|
||||
}
|
||||
|
||||
variable "nixos_flake_attr" {
|
||||
type = string
|
||||
description = "NixOS configuration flake attribute"
|
||||
}
|
||||
|
||||
variable "tags" {
|
||||
type = map(string)
|
||||
default = {}
|
||||
description = "Tags to add to the server"
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
hcloud_token = "your_token_here"
|
Loading…
Reference in New Issue