feat: initial version of the full setup
This commit is contained in:
5
.envrc
Normal file
5
.envrc
Normal file
@@ -0,0 +1,5 @@
|
||||
export DIRENV_WARN_TIMEOUT=20s
|
||||
|
||||
eval "$(devenv direnvrc)"
|
||||
|
||||
use flake --no-pure-eval
|
||||
19
.gitignore
vendored
Normal file
19
.gitignore
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Direnv & Devenv
|
||||
.direnv
|
||||
.envrc.local
|
||||
.devenv
|
||||
.devenv.flake.nix
|
||||
|
||||
# should be Terranix .nix files instead
|
||||
*.tf
|
||||
*.tfvars
|
||||
*.tfstate*
|
||||
.terraform*
|
||||
|
||||
# Outputs
|
||||
config.tf.json
|
||||
nixos-template
|
||||
|
||||
# Possibly sensitive for public repo
|
||||
infra/ips.nix
|
||||
infra/constants.nix
|
||||
51
README.md
Normal file
51
README.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# NixOS x Proxmox infra configuration with Terranix
|
||||
|
||||
This repository allows to manage LXC containers on Proxmox.
|
||||
|
||||
It's supposed to be used from an host where `nixos-rebuild` is available.
|
||||
|
||||
=> Uses `nix-community/generators` to build a LXC template with a base NixOS container
|
||||
=> Uses `terranix` to build the infra definition and `opentofu` to deploy it on Proxmox
|
||||
=> Uses `nixos-rebuild` to deploy the configuration on the container
|
||||
|
||||
My main objective was to have a "light" definition for the containers and to be able to use Nix to factorize configuration.
|
||||
|
||||
# Usage
|
||||
|
||||
## Prepare the infra constants
|
||||
-> `cp infra/constants.nix.template infra/constants.nix`
|
||||
-> adapt `infra/constants.nix` to match your needs
|
||||
-> touch `infra/ips.nix`
|
||||
-> remove both these files from `.gitignore` and `git add` them.
|
||||
|
||||
## Build NixOS template
|
||||
-> modify `infra/lxc-template.nix` as needed
|
||||
-> run `build-template`
|
||||
-> template available in `nixos-template/tarball/`
|
||||
(.tar.xz to be uploaded to Proxmox)
|
||||
TODO Script the Proxmox Template upload if possible.
|
||||
|
||||
## Prepare Terraform
|
||||
-> create a user/role etc on Proxmox (see [the provider documentation](https://registry.terraform.io/providers/Telmate/proxmox/latest/docs))
|
||||
-> `cp terraform.tfvars.example terraform.tfvars`
|
||||
-> edit `terraform.tfvars` to fill in values
|
||||
-> adapt the terraform base config as needed in `infra/main.nix`
|
||||
-> run `tofu init`
|
||||
|
||||
## Adapt NixOS / Terraform modules building
|
||||
-> edit `lib/containers.nix` to change how a container definition is translated to TF / NixOS config (in particular check the template name)
|
||||
|
||||
## Create containers definitions
|
||||
-> `cp containers/lxc-cont.nix.template containers/lxc-#NAME#.nix`
|
||||
-> edit `containers/lxc-#NAME#.nix` as needed
|
||||
-> run `build-terraform-json`
|
||||
-> run `tofu plan` and review the plan
|
||||
-> run `tofu apply`, hopefully without errors
|
||||
-> run `deploy #NAME#`
|
||||
|
||||
## Update container
|
||||
-> edit `containers/lxc-#NAME#.nix` as needed
|
||||
-> if the container specs have changed, do all as above
|
||||
-> otherwise you can just run `deploy #NAME#`
|
||||
|
||||
|
||||
381
flake.lock
generated
Normal file
381
flake.lock
generated
Normal file
@@ -0,0 +1,381 @@
|
||||
{
|
||||
"nodes": {
|
||||
"cachix": {
|
||||
"inputs": {
|
||||
"devenv": [
|
||||
"devenv"
|
||||
],
|
||||
"flake-compat": [
|
||||
"devenv"
|
||||
],
|
||||
"git-hooks": [
|
||||
"devenv",
|
||||
"git-hooks"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"devenv",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1752264895,
|
||||
"narHash": "sha256-1zBPE/PNAkPNUsOWFET4J0cjlvziH8DOekesDmjND+w=",
|
||||
"owner": "cachix",
|
||||
"repo": "cachix",
|
||||
"rev": "47053aef762f452e816e44eb9a23fbc3827b241a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"ref": "latest",
|
||||
"repo": "cachix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"devenv": {
|
||||
"inputs": {
|
||||
"cachix": "cachix",
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-parts": "flake-parts",
|
||||
"git-hooks": "git-hooks",
|
||||
"nix": "nix",
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1761091275,
|
||||
"narHash": "sha256-SIiugXvSuI2WFedt1NyDj8yHsSDntsO/JWKyEZ+mI50=",
|
||||
"owner": "cachix",
|
||||
"repo": "devenv",
|
||||
"rev": "a795c32dc826b51d12706f27fb344f966bb2b084",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "devenv",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1747046372,
|
||||
"narHash": "sha256-CIVLLkVgvHYbgI2UpXvIIBJ12HWgX+fjA8Xf8PUmqCY=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "9100a0f413b0c601e0533d1d94ffd501ce2e7885",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"devenv",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1756770412,
|
||||
"narHash": "sha256-+uWLQZccFHwqpGqr2Yt5VsW/PbeJVTn9Dk6SHWhNRPw=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "4524271976b625a4a605beefd893f270620fd751",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts_2": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"terranix",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1736143030,
|
||||
"narHash": "sha256-+hu54pAoLDEZT9pjHlqL9DNzWz0NbUn8NEAHP7PQPzU=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "b905f6fc23a9051a6e1b741e1438dbfc0634c6de",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"generators": {
|
||||
"inputs": {
|
||||
"nixlib": "nixlib",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1751903740,
|
||||
"narHash": "sha256-PeSkNMvkpEvts+9DjFiop1iT2JuBpyknmBUs0Un0a4I=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixos-generators",
|
||||
"rev": "032decf9db65efed428afd2fa39d80f7089085eb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixos-generators",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"git-hooks": {
|
||||
"inputs": {
|
||||
"flake-compat": [
|
||||
"devenv",
|
||||
"flake-compat"
|
||||
],
|
||||
"gitignore": "gitignore",
|
||||
"nixpkgs": [
|
||||
"devenv",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1758108966,
|
||||
"narHash": "sha256-ytw7ROXaWZ7OfwHrQ9xvjpUWeGVm86pwnEd1QhzawIo=",
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"rev": "54df955a695a84cd47d4a43e08e1feaf90b1fd9b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"repo": "git-hooks.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gitignore": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"devenv",
|
||||
"git-hooks",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709087332,
|
||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "gitignore.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix": {
|
||||
"inputs": {
|
||||
"flake-compat": [
|
||||
"devenv",
|
||||
"flake-compat"
|
||||
],
|
||||
"flake-parts": [
|
||||
"devenv",
|
||||
"flake-parts"
|
||||
],
|
||||
"git-hooks-nix": [
|
||||
"devenv",
|
||||
"git-hooks"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"devenv",
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-23-11": [
|
||||
"devenv"
|
||||
],
|
||||
"nixpkgs-regression": [
|
||||
"devenv"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1758763079,
|
||||
"narHash": "sha256-Bx1A+lShhOWwMuy3uDzZQvYiBKBFcKwy6G6NEohhv6A=",
|
||||
"owner": "cachix",
|
||||
"repo": "nix",
|
||||
"rev": "6f0140527c2b0346df4afad7497baa08decb929f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"ref": "devenv-2.30.5",
|
||||
"repo": "nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixlib": {
|
||||
"locked": {
|
||||
"lastModified": 1736643958,
|
||||
"narHash": "sha256-tmpqTSWVRJVhpvfSN9KXBvKEXplrwKnSZNAoNPf/S/s=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"rev": "1418bc28a52126761c02dd3d89b2d8ca0f521181",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixpkgs.lib",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1758532697,
|
||||
"narHash": "sha256-bhop0bR3u7DCw9/PtLCwr7GwEWDlBSxHp+eVQhCW9t4=",
|
||||
"owner": "cachix",
|
||||
"repo": "devenv-nixpkgs",
|
||||
"rev": "207a4cb0e1253c7658c6736becc6eb9cace1f25f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "cachix",
|
||||
"ref": "rolling",
|
||||
"repo": "devenv-nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1736657626,
|
||||
"narHash": "sha256-FWlPMUzp0lkQBdhKlPqtQdqmp+/C+1MBiEytaYfrCTY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "2f9e2f85cb14a46410a1399aa9ea7ecf433e422e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1760878510,
|
||||
"narHash": "sha256-K5Osef2qexezUfs0alLvZ7nQFTGS9DL2oTVsIXsqLgs=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "5e2a59a5b1a82f89f2c7e598302a9cacebb72a67",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1728956102,
|
||||
"narHash": "sha256-J8zo+UYNjHATsxn2/ROl8iaji2RgLm+sG7b3VcD36YM=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "3d85bae2431f20ab1ac5cf14d03d314dffe629af",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"devenv": "devenv",
|
||||
"flake-utils": "flake-utils",
|
||||
"generators": "generators",
|
||||
"nixpkgs": "nixpkgs_3",
|
||||
"terranix": "terranix"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"systems_2": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"terranix": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts_2",
|
||||
"nixpkgs": "nixpkgs_4",
|
||||
"systems": "systems_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1757278723,
|
||||
"narHash": "sha256-hTMi6oGU+6VRnW9SZZ+muFcbfMEf2ajjOp7Z2KM5MMY=",
|
||||
"owner": "terranix",
|
||||
"repo": "terranix",
|
||||
"rev": "924573fa6587ac57b0d15037fbd2d3f0fcdf17fb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "terranix",
|
||||
"repo": "terranix",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
138
flake.nix
Normal file
138
flake.nix
Normal file
@@ -0,0 +1,138 @@
|
||||
{
|
||||
description = "Infrastructure LXC + Terraform + NixOS via Flakes";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
generators.url = "github:nix-community/nixos-generators";
|
||||
terranix.url = "github:terranix/terranix";
|
||||
devenv.url = "github:cachix/devenv";
|
||||
};
|
||||
|
||||
nixConfig = {
|
||||
extra-trusted-public-keys = "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=";
|
||||
extra-substituters = "https://devenv.cachix.org";
|
||||
};
|
||||
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
flake-utils,
|
||||
generators,
|
||||
terranix,
|
||||
devenv,
|
||||
...
|
||||
}@inputs:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
lib = pkgs.lib;
|
||||
|
||||
containersMapping = import ./infra/ips.nix;
|
||||
|
||||
containers = import ./lxc { inherit pkgs containersMapping; };
|
||||
|
||||
lxc-def = import ./infra/lxc-template.nix;
|
||||
|
||||
infra = import ./infra/constants.nix;
|
||||
|
||||
nixosConfigurations = lib.mapAttrs (
|
||||
_: def:
|
||||
nixpkgs.lib.nixosSystem {
|
||||
inherit system;
|
||||
modules = [ def.nixosModule ];
|
||||
}
|
||||
) containers;
|
||||
|
||||
terraformCfg = import ./infra;
|
||||
|
||||
terraformResources = {
|
||||
resource.proxmox_lxc = lib.mapAttrs (_: def: def.terraformResource) containers;
|
||||
};
|
||||
|
||||
in
|
||||
{
|
||||
packages.${system} = {
|
||||
lxc-template = generators.nixosGenerate {
|
||||
system = "x86_64-linux";
|
||||
modules = [ lxc-def ];
|
||||
format = "proxmox-lxc";
|
||||
};
|
||||
|
||||
terraform-json = terranix.lib.terranixConfiguration {
|
||||
inherit system;
|
||||
modules = [
|
||||
terraformResources
|
||||
terraformCfg
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
nixosConfigurations = nixosConfigurations;
|
||||
|
||||
devShells.${system}.default = devenv.lib.mkShell {
|
||||
inherit inputs pkgs;
|
||||
modules = [
|
||||
(
|
||||
{ pkgs, config, ... }:
|
||||
{
|
||||
languages.opentofu.enable = true;
|
||||
|
||||
scripts.build-template.exec = ''
|
||||
nix build .#lxc-template -o nixos-template
|
||||
echo 'Template should be available at nixos-template/tarball/*.tar.xz'
|
||||
'';
|
||||
|
||||
scripts.build-terraform-json.exec = ''
|
||||
nix build .#terraform-json -o config.tf.json
|
||||
echo 'Terraform build available as config.tf.json'
|
||||
'';
|
||||
|
||||
scripts.add-lxc.exec = ''
|
||||
if ! [[ "$2" =~ ^[0-9]+$ ]]; then
|
||||
echo "Error: invalid container ID '$2', should be a number" && exit
|
||||
fi
|
||||
if ! [ -f infra/ips.nix ]; then
|
||||
echo "{" > infra/ips.nix
|
||||
echo "}" >> infra/ips.nix
|
||||
fi
|
||||
if ! [[ -z "`grep "[^0-9]$2[^0-9]" infra/ips.nix`" ]]; then
|
||||
echo "Error: container ID '$2' already used" && exit
|
||||
fi
|
||||
if [ -f lxc/$1.nix ]; then
|
||||
echo "Error: container definition '$1' already exists" && exit
|
||||
fi
|
||||
sed -i "s#}# $1 = $2;#" infra/ips.nix
|
||||
echo "}" >> infra/ips.nix
|
||||
cp lxc/container.nix.template lxc/$1.nix
|
||||
git add lxc/$1.nix
|
||||
echo "Entry added to infra/ips.nix"
|
||||
echo "Container template copied to lxc/$1.nix, please edit it"
|
||||
'';
|
||||
|
||||
scripts.deploy-lxc.exec = ''
|
||||
if [ -f lxc/$1.nix ]; then
|
||||
CONTID=`grep -E "$1 ?=" infra/ips.nix | cut -d '=' -f 2 | grep -o '\<[0-9]*\>' `
|
||||
echo "Redeploying LXC on container '$1' ('$CONTID')"
|
||||
nixos-rebuild switch --flake .#$1 --target-host root@${infra.ip_prefix}$CONTID
|
||||
echo "Done."
|
||||
else
|
||||
echo "Error: Container definition 'lxc/$1.nix' not found!"
|
||||
fi
|
||||
'';
|
||||
|
||||
enterShell = ''
|
||||
echo "Helper commands available:"
|
||||
echo ""
|
||||
echo "'build-template' to build the Proxmox LXC NixOS template"
|
||||
echo "'build-terraform-json' to build the Terraform config.tf.json file to apply"
|
||||
echo "'add-lxc' to prepare the template for a LXC container"
|
||||
echo "'deploy-lxc' to deploy a container configuration using nixos-rebuild"
|
||||
'';
|
||||
}
|
||||
)
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
19
infra/constants.nix.template
Normal file
19
infra/constants.nix.template
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
# Centralizes the IP to the gateway for the containers.
|
||||
gateway_ip = "10.0.0.1";
|
||||
|
||||
# Builders for IP addresses, given a container id.
|
||||
ip_prefix = "10.0.0.";
|
||||
cidr = "24";
|
||||
build_ip = id: "${ip_prefix}${toString id}";
|
||||
build_ip_cidr = id: "${ip_prefix}${toString id}/${cidr}";
|
||||
|
||||
# Your deployer's host
|
||||
master_public_ssh_key = "ssh-ed25519 [...] me@here";
|
||||
|
||||
# Default timezone for the containers
|
||||
default_tz = "UTC";
|
||||
|
||||
# NixOS template build name => see `ls nixos-template/tarball/`
|
||||
nixos_template_name = "nixos-image-lxc-proxmox-25.11pre-git-x86_64-linux";
|
||||
}
|
||||
21
infra/default.nix
Normal file
21
infra/default.nix
Normal file
@@ -0,0 +1,21 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
terraform.required_providers = {
|
||||
proxmox = {
|
||||
source = "Telmate/proxmox";
|
||||
version = "~> 2.9.11";
|
||||
};
|
||||
};
|
||||
|
||||
provider.proxmox = {
|
||||
pm_api_url = "\${var.pm_api_url}";
|
||||
pm_api_token_id = "\${var.pm_api_token_id}";
|
||||
pm_api_token_secret = "\${var.pm_api_token_secret}";
|
||||
pm_tls_insecure = false;
|
||||
};
|
||||
|
||||
variable.pm_api_url.type = "string";
|
||||
variable.pm_api_token_id.type = "string";
|
||||
variable.pm_api_token_secret.type = "string";
|
||||
variable.pve_node.type = "string";
|
||||
}
|
||||
57
infra/lxc-template.nix
Normal file
57
infra/lxc-template.nix
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
let
|
||||
infra = import ./constants.nix;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/virtualisation/proxmox-lxc.nix")
|
||||
];
|
||||
|
||||
boot.isContainer = true;
|
||||
|
||||
systemd.suppressedSystemUnits = [
|
||||
"dev-mqueue.mount"
|
||||
"sys-kernel-debug.mount"
|
||||
"sys-fs-fuse-connections.mount"
|
||||
];
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim
|
||||
openssl
|
||||
coreutils
|
||||
];
|
||||
services.openssh.enable = true;
|
||||
services.chrony = {
|
||||
enable = true;
|
||||
enableNTS = true;
|
||||
servers = [ "time.cloudflare.com" ];
|
||||
};
|
||||
nix.settings = {
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
auto-optimise-store = true;
|
||||
};
|
||||
nix.gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
options = "--delete-older-than 7d";
|
||||
};
|
||||
|
||||
time.timeZone = infra.default_tz;
|
||||
|
||||
users.users.root = {
|
||||
openssh.authorizedKeys.keys = [
|
||||
infra.master_public_ssh_key
|
||||
];
|
||||
};
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
|
||||
system.stateVersion = "25.11";
|
||||
}
|
||||
69
lib/containers.nix
Normal file
69
lib/containers.nix
Normal file
@@ -0,0 +1,69 @@
|
||||
{ def, ... }:
|
||||
let
|
||||
infra = import ../infra/constants.nix;
|
||||
|
||||
hostname = def.hostname;
|
||||
memory = def.memory or 512;
|
||||
cores = def.cores or 1;
|
||||
container_id = def.container_id;
|
||||
disk = def.disk or "4G";
|
||||
swap = def.swap or null; # TODO: Implement
|
||||
services = def.services or { };
|
||||
open_ports = def.open_ports or [ ];
|
||||
other_packages = def.other_packages or [ ];
|
||||
etc = def.etc or { };
|
||||
logging_enabled = def.logging.enable or false; # TODO: Implement
|
||||
logging_metrics_enabled = def.logging.metrics.enable or false;
|
||||
extraModules = def.extraModules or [ ];
|
||||
template = def.template or infra.nixos_template_name;
|
||||
unprivileged = def.unprivileged or true;
|
||||
tags = def.tags or "";
|
||||
in
|
||||
{
|
||||
terraformResource = {
|
||||
hostname = hostname;
|
||||
memory = memory;
|
||||
cores = cores;
|
||||
ostemplate = "local:vztmpl/${template}.tar.xz";
|
||||
unprivileged = unprivileged;
|
||||
password = "changeme";
|
||||
features.nesting = true;
|
||||
target_node = "\${var.pve_node}";
|
||||
network = {
|
||||
name = "eth0";
|
||||
bridge = "vmbr0";
|
||||
ip = infra.build_ip_cidr container_id;
|
||||
gw = infra.gateway_ip;
|
||||
type = "veth";
|
||||
};
|
||||
rootfs = {
|
||||
storage = "local-lvm";
|
||||
size = disk;
|
||||
};
|
||||
vmid = container_id;
|
||||
tags = "terraform;${tags}";
|
||||
};
|
||||
|
||||
nixosModule =
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
imports = [
|
||||
../infra/lxc-template.nix
|
||||
]
|
||||
++ extraModules;
|
||||
networking.hostName = hostname;
|
||||
networking.firewall.allowedTCPPorts = open_ports;
|
||||
services = services;
|
||||
environment.etc = etc;
|
||||
environment.systemPackages = other_packages;
|
||||
# logging things...
|
||||
# # logs configuration ...
|
||||
# # environment.etc."alloy/config.alloy" = '' loki blabla '';
|
||||
# # environment.etc."alloy/metrics.alloy" = '' prometheus blabla '';
|
||||
# #
|
||||
# # -> services.alloy.extraFlags = [
|
||||
# # "--server.http.listen-addr=127.0.0.1:12346"
|
||||
# # "--disable-reporting"
|
||||
# # ]
|
||||
};
|
||||
}
|
||||
41
lxc/container.nix.template
Normal file
41
lxc/container.nix.template
Normal file
@@ -0,0 +1,41 @@
|
||||
{ pkgs, containersMapping, ... }:
|
||||
let
|
||||
infra = import ../infra/constants.nix;
|
||||
in
|
||||
{
|
||||
# OPTIONAL int cores: number of CPU (default = 1)
|
||||
cores = 2;
|
||||
|
||||
# OPTIONAL int memory: RAM memory (default 512)
|
||||
memory = 512;
|
||||
|
||||
# OPTIONAL string disk: disk space (default "4G") - beware, NixOS is greedy
|
||||
disk = "4G";
|
||||
|
||||
# OPTIONAL string swap: swap space (default null)
|
||||
swap = null;
|
||||
|
||||
# OPTIONAL list of int ports: ports to open (TCP tho) (default [])
|
||||
ports = [ 80 ];
|
||||
|
||||
# OPTIONAL submodule services: services to be passed to the NixOS Module (default {})
|
||||
services = {
|
||||
nginx.enable = true;
|
||||
};
|
||||
|
||||
# OPTIONAL list of pkgs other_packages: packages to add to eenvironment.systemPackages (default [])
|
||||
other_packages = [ pkgs.hello ];
|
||||
|
||||
# OPTIONAL submodule etc: files contents to pass to eenvironment.etc
|
||||
etc."alloy/log-myservice.alloy" = ''
|
||||
# logger_ip = ${infra.build_ip containersMapping.grafana}
|
||||
# prometheus = ${infra.build_ip containersMapping.prometheus}
|
||||
'';
|
||||
|
||||
# OPTIONAL bool logging.enable: whether to enable the Alloy configuration (=> Loki)
|
||||
# Need further configuration in etc."alloy/log-myservice.alloy"
|
||||
logging.enable = true;
|
||||
|
||||
# OPTIONAL bool logging.metrics.enable: whether to enable the Alloy metrics configuration (=> Prometheus)
|
||||
logging.metrics.enable = true;
|
||||
}
|
||||
36
lxc/default.nix
Normal file
36
lxc/default.nix
Normal file
@@ -0,0 +1,36 @@
|
||||
{ pkgs, containersMapping, ... }:
|
||||
let
|
||||
lib = pkgs.lib;
|
||||
|
||||
containerBuild = import ../lib/containers.nix;
|
||||
|
||||
containersFiles = builtins.readDir ./.;
|
||||
|
||||
containers = lib.filterAttrs (_: v: v != null) (
|
||||
lib.mapAttrs (
|
||||
name: type:
|
||||
if type == "regular" && name != "default.nix" && lib.hasSuffix ".nix" name then
|
||||
import ./${name} { inherit containersMapping pkgs; }
|
||||
else
|
||||
null
|
||||
) containersFiles
|
||||
);
|
||||
|
||||
cleanedName = lib.listToAttrs (lib.mapAttrsToList (name: def: mkContainer name def) containers);
|
||||
|
||||
mkContainer =
|
||||
name: raw_def:
|
||||
let
|
||||
hostname = lib.removeSuffix ".nix" name;
|
||||
def = raw_def // {
|
||||
hostname = hostname;
|
||||
container_id = containersMapping.${hostname};
|
||||
};
|
||||
result = containerBuild { inherit def; };
|
||||
in
|
||||
{
|
||||
name = hostname;
|
||||
value = result;
|
||||
};
|
||||
in
|
||||
cleanedName
|
||||
4
terraform.tfvars.example
Normal file
4
terraform.tfvars.example
Normal file
@@ -0,0 +1,4 @@
|
||||
pm_api_url = "https://proxmox:8006/api2/json"
|
||||
pm_api_token_id = "terraform@pve"
|
||||
pm_api_token_secret = "secr3t"
|
||||
pve_node = "proxmox"
|
||||
Reference in New Issue
Block a user