forked from clan/clan-infra
first commit
This commit is contained in:
commit
b5a991b631
5
.envrc.private-template
Normal file
5
.envrc.private-template
Normal file
@ -0,0 +1,5 @@
|
||||
# https://app.netlify.com/user/applications#personal-access-tokens
|
||||
export NETLIFY_TOKEN=<your-netlify-token>
|
||||
|
||||
# https://console.hetzner.cloud/projects/2447141/security/tokens
|
||||
export HCLOUD_TOKEN=<your-hetzner-token>
|
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
# secrets
|
||||
.envrc.private
|
||||
.terraform.lock.hcl
|
||||
|
||||
# git is our backup
|
||||
*.tfstate.backup
|
7
.sops.yaml
Normal file
7
.sops.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
keys:
|
||||
- &joerg age17n64ahe3wesh8l8lj0zylf4nljdmqn28hvqns2g7hgm9mdkhlsvsjuvkxz
|
||||
creation_rules:
|
||||
- path_regex: targets/.*/terraform.tfstate.sops$
|
||||
key_groups:
|
||||
- age:
|
||||
- *joerg
|
111
flake.lock
Normal file
111
flake.lock
Normal file
@ -0,0 +1,111 @@
|
||||
{
|
||||
"nodes": {
|
||||
"disko": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1687968164,
|
||||
"narHash": "sha256-L9jr2zCB6NIaBE3towusjGBigsnE2pMID8wBGkYbTS4=",
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"rev": "8002e7cb899bc2a02a2ebfb7f999fcd7c18b92a1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "disko",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-parts": {
|
||||
"inputs": {
|
||||
"nixpkgs-lib": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1688466019,
|
||||
"narHash": "sha256-VeM2akYrBYMsb4W/MmBo1zmaMfgbL4cH3Pu8PGyIwJ0=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "8e8d955c22df93dbe24f19ea04f47a74adbdc5ec",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1688322751,
|
||||
"narHash": "sha256-eW62dC5f33oKZL7VWlomttbUnOTHrAbte9yNUNW8rbk=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0fbe93c5a7cac99f90b60bdf5f149383daaa615f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"disko": "disko",
|
||||
"flake-parts": "flake-parts",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"srvos": "srvos",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
}
|
||||
},
|
||||
"srvos": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1688384426,
|
||||
"narHash": "sha256-iUhJ2JYCyzioI/G0mqgDoSH3U0fcFhm6ShmMcB0dYyY=",
|
||||
"owner": "numtide",
|
||||
"repo": "srvos",
|
||||
"rev": "c9fa5cf4b6014807655bf8356b3cddc86f741b7a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "srvos",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"treefmt-nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1688026376,
|
||||
"narHash": "sha256-qJmkr9BWDpqblk4E9/rCsAEl39y2n4Ycw6KRopvpUcY=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "df3f32b0cc253dfc7009b7317e8f0e7ccd70b1cf",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
49
flake.nix
Normal file
49
flake.nix
Normal file
@ -0,0 +1,49 @@
|
||||
{
|
||||
description = "Dependencies to deploy a clan";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||
treefmt-nix.url = "github:numtide/treefmt-nix";
|
||||
treefmt-nix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
disko.url = "github:nix-community/disko";
|
||||
disko.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
srvos.url = "github:numtide/srvos";
|
||||
# Use the version of nixpkgs that has been tested to work with SrvOS
|
||||
srvos.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
outputs = inputs@{ flake-parts, ... }:
|
||||
flake-parts.lib.mkFlake { inherit inputs; } ({ lib, ... }: {
|
||||
systems = lib.systems.flakeExposed;
|
||||
imports = [
|
||||
inputs.treefmt-nix.flakeModule
|
||||
./targets/flake-module.nix
|
||||
./modules/flake-module.nix
|
||||
];
|
||||
perSystem = { config, pkgs, inputs', ... }: {
|
||||
treefmt = {
|
||||
projectRootFile = "flake.nix";
|
||||
programs.terraform.enable = true;
|
||||
programs.nixpkgs-fmt.enable = true;
|
||||
};
|
||||
packages.default = pkgs.mkShell {
|
||||
packages = [
|
||||
pkgs.bashInteractive
|
||||
pkgs.sops
|
||||
(pkgs.terraform.withPlugins (p: [
|
||||
p.namecheap
|
||||
p.netlify
|
||||
p.hcloud
|
||||
p.null
|
||||
p.external
|
||||
p.local
|
||||
]))
|
||||
];
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
2
git-agecrypt.toml
Normal file
2
git-agecrypt.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[config]
|
||||
"targets/admins/terraform.tfstate" = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKbBp2dH2X3dcU1zh+xW3ZsdYROKpJd3n13ssOP092qE joerg@turingmachine"]
|
13
modules/flake-module.nix
Normal file
13
modules/flake-module.nix
Normal file
@ -0,0 +1,13 @@
|
||||
{ inputs, ... }: {
|
||||
flake.nixosModules = {
|
||||
hcloud.imports = [
|
||||
inputs.srvos.nixosModules.server
|
||||
inputs.srvos.nixosModules.hardware-hetzner-cloud
|
||||
./single-disk.nix
|
||||
];
|
||||
|
||||
web01.imports = [
|
||||
./web01.nix
|
||||
];
|
||||
};
|
||||
}
|
45
modules/single-disk.nix
Normal file
45
modules/single-disk.nix
Normal file
@ -0,0 +1,45 @@
|
||||
{ self, ... }:
|
||||
let
|
||||
partitions = {
|
||||
grub = {
|
||||
name = "grub";
|
||||
size = "1M";
|
||||
flags = [ "bios_grub" ];
|
||||
};
|
||||
esp = {
|
||||
name = "ESP";
|
||||
size = "500MB";
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
};
|
||||
};
|
||||
root = {
|
||||
name = "root";
|
||||
size = "100%";
|
||||
bootable = true;
|
||||
content = {
|
||||
type = "filesystem";
|
||||
# We use xfs because it has support for compression and has a quite good performance for databases
|
||||
format = "xfs";
|
||||
mountpoint = "/";
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
self.inputs.disko.nixosModules.disko
|
||||
];
|
||||
disko.devices = {
|
||||
disk.sda = {
|
||||
type = "disk";
|
||||
device = "/dev/sda";
|
||||
content = {
|
||||
type = "gpt";
|
||||
inherit partitions;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
1
modules/web01.nix
Normal file
1
modules/web01.nix
Normal file
@ -0,0 +1 @@
|
||||
{ ... }: { }
|
16
targets/admins/apply.sh
Executable file
16
targets/admins/apply.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
rm -f .terraform.lock.hcl
|
||||
TFSTATE=$(mktemp)
|
||||
if [[ -f "terraform.tfstate.sops" ]]; then
|
||||
sops -d terraform.tfstate.sops > "$TFSTATE"
|
||||
fi
|
||||
toplevel=$(git rev-parse --show-toplevel)
|
||||
backupdir=$toplevel/.git/terraform/$(basename "$(dirname "$0")")
|
||||
cleanup() {
|
||||
sops -e "$TFSTATE" > terraform.tfstate.sops && rm -f "$TFSTATE"
|
||||
}
|
||||
trap "cleanup" EXIT
|
||||
terraform init -backup="$backupdir" -state-out="$TFSTATE"
|
||||
terraform apply -backup="$backupdir" -state-out="$TFSTATE"
|
2
targets/admins/recipents.txt
Normal file
2
targets/admins/recipents.txt
Normal file
@ -0,0 +1,2 @@
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKbBp2dH2X3dcU1zh+xW3ZsdYROKpJd3n13ssOP092qE joerg@turingmachine
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDIb3uuMqE/xSJ7WL/XpJ6QOj4aSmh0Ga+GtmJl3CDvljGuIeGCKh7YAoqZAi051k5j6ZWowDrcWYHIOU+h0eZCesgCf+CvunlXeUz6XShVMjyZo87f2JPs2Hpb+u/ieLx4wGQvo/Zw89pOly/vqpaX9ZwyIR+U81IAVrHIhqmrTitp+2FwggtaY4FtD6WIyf1hPtrrDecX8iDhnHHuGhATr8etMLwdwQ2kIBx5BBgCoiuW7wXnLUBBVYeO3II957XP/yU82c+DjSVJtejODmRAM/3rk+B7pdF5ShRVVFyB6JJR+Qd1g8iSH+2QXLUy3NM2LN5u5p2oTjUOzoEPWZo7lykZzmIWd/5hjTW9YiHC+A8xsCxQqs87D9HK9hLA6udZ6CGkq4hG/6wFwNjSMnv30IcHZzx6IBihNGbrisrJhLxEiKWpMKYgeemhIirefXA6UxVfiwHg3gJ8BlEBsj0tl/HVARifR2y336YINEn8AsHGhwrPTBFOnBTmfA/VnP1NlWHzXCfVimP6YVvdoGCCnAwvFuJ+ZuxmZ3UzBb2TenZZOzwzV0sUzZk0D1CaSBFJUU3oZNOkDIM6z5lIZgzsyKwb38S8Vs3HYE+Dqpkfsl4yeU5ldc6DwrlVwuSIa4vVus4eWD3gDGFrx98yaqOx17pc4CC9KXk/2TjtJY5xmQ==
|
12
targets/admins/terraform.tf
Normal file
12
targets/admins/terraform.tf
Normal file
@ -0,0 +1,12 @@
|
||||
terraform {
|
||||
backend "local" {
|
||||
}
|
||||
}
|
||||
|
||||
module "admin" {
|
||||
source = "../../terraform/admins"
|
||||
ssh_keys = {
|
||||
mic92 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKbBp2dH2X3dcU1zh+xW3ZsdYROKpJd3n13ssOP092qE joerg@turingmachine"
|
||||
lassulus = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDIb3uuMqE/xSJ7WL/XpJ6QOj4aSmh0Ga+GtmJl3CDvljGuIeGCKh7YAoqZAi051k5j6ZWowDrcWYHIOU+h0eZCesgCf+CvunlXeUz6XShVMjyZo87f2JPs2Hpb+u/ieLx4wGQvo/Zw89pOly/vqpaX9ZwyIR+U81IAVrHIhqmrTitp+2FwggtaY4FtD6WIyf1hPtrrDecX8iDhnHHuGhATr8etMLwdwQ2kIBx5BBgCoiuW7wXnLUBBVYeO3II957XP/yU82c+DjSVJtejODmRAM/3rk+B7pdF5ShRVVFyB6JJR+Qd1g8iSH+2QXLUy3NM2LN5u5p2oTjUOzoEPWZo7lykZzmIWd/5hjTW9YiHC+A8xsCxQqs87D9HK9hLA6udZ6CGkq4hG/6wFwNjSMnv30IcHZzx6IBihNGbrisrJhLxEiKWpMKYgeemhIirefXA6UxVfiwHg3gJ8BlEBsj0tl/HVARifR2y336YINEn8AsHGhwrPTBFOnBTmfA/VnP1NlWHzXCfVimP6YVvdoGCCnAwvFuJ+ZuxmZ3UzBb2TenZZOzwzV0sUzZk0D1CaSBFJUU3oZNOkDIM6z5lIZgzsyKwb38S8Vs3HYE+Dqpkfsl4yeU5ldc6DwrlVwuSIa4vVus4eWD3gDGFrx98yaqOx17pc4CC9KXk/2TjtJY5xmQ=="
|
||||
}
|
||||
}
|
20
targets/admins/terraform.tfstate.sops
Normal file
20
targets/admins/terraform.tfstate.sops
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"data": "ENC[AES256_GCM,data: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,iv:MB5og2s7N+cTxZMRdSPtpBwTNeTMoEYnzalIHylYsyI=,tag:/NTdmINyoFot/beul8C9GA==,type:str]",
|
||||
"sops": {
|
||||
"kms": null,
|
||||
"gcp_kms": null,
|
||||
"azure_kv": null,
|
||||
"hc_vault": null,
|
||||
"age": [
|
||||
{
|
||||
"recipient": "age17n64ahe3wesh8l8lj0zylf4nljdmqn28hvqns2g7hgm9mdkhlsvsjuvkxz",
|
||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtYmYvczZrNHEzeTVvaXRH\nbEJGb1lZL2xrMTBOdGlyc0l3RnpHWU1YZTI0CkNEYy9EVEFITFVGOE5Mc2dsZktV\nM2tacVc3RGlqeHlsL2RuMGZQYUtscmsKLS0tIHFGVWRBNGpyNkptV0FRcHpMV1Jk\nSCs4c1lFaFU3WkcrWkQzcktKRkJCdVkKneJko1lw5CkORymxfibErFRb8fJEQl2E\naPNlUCAknCrb+raWClkbXFY1MSCcxrkFV+tx69O8hLaTlGUPnmGAeQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||
}
|
||||
],
|
||||
"lastmodified": "2023-07-04T15:15:37Z",
|
||||
"mac": "ENC[AES256_GCM,data:VMnIZxSc8QKp8s69gCvteTKkrlXP7/AkWamtnbd6SFCbhubpKoY88gyXv9QHLKwqclkKHyz3U9GsnvnEb3OUb8RX21l8bVPwB98OiLcBgd54KlizVVmz8fUDjjQf41PzuSs5LI0QoVKypfphtLjRViptBDPmCDYWk4Q1jEjARgs=,iv:BUgslpHCBnSnBSWUC62U0b0hqIC6l8RPKOeExXHhMgM=,tag:px/qDIZuycqn5NnDJa73ZA==,type:str]",
|
||||
"pgp": null,
|
||||
"unencrypted_suffix": "_unencrypted",
|
||||
"version": "3.7.3"
|
||||
}
|
||||
}
|
25
targets/flake-module.nix
Normal file
25
targets/flake-module.nix
Normal file
@ -0,0 +1,25 @@
|
||||
{ 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);
|
||||
}
|
1
targets/web01/apply.sh
Symbolic link
1
targets/web01/apply.sh
Symbolic link
@ -0,0 +1 @@
|
||||
../admins/apply.sh
|
10
targets/web01/configuration.nix
Normal file
10
targets/web01/configuration.nix
Normal file
@ -0,0 +1,10 @@
|
||||
{ self, ... }: let
|
||||
nixosVars = builtins.fromJSON (builtins.readFile ./nixos-vars.json);
|
||||
in {
|
||||
imports = [
|
||||
self.nixosModules.nixos-wiki
|
||||
self.nixosModules.hcloud
|
||||
];
|
||||
users.users.root.openssh.authorizedKeys.keys = nixosVars.ssh_keys;
|
||||
system.stateVersion = "23.05";
|
||||
}
|
14
targets/web01/terraform.tf
Normal file
14
targets/web01/terraform.tf
Normal file
@ -0,0 +1,14 @@
|
||||
terraform {
|
||||
backend "local" {}
|
||||
}
|
||||
|
||||
module "web01" {
|
||||
source = "../../terraform/web01"
|
||||
domain = "clan.lol"
|
||||
nixos_flake_attr = "web01"
|
||||
nixos_vars_file = "${path.module}/nixos-vars.json"
|
||||
tags = {
|
||||
Terraform = "true"
|
||||
Target = "web01"
|
||||
}
|
||||
}
|
8
terraform/admins/main.tf
Normal file
8
terraform/admins/main.tf
Normal file
@ -0,0 +1,8 @@
|
||||
resource "hcloud_ssh_key" "hcloud" {
|
||||
for_each = var.ssh_keys
|
||||
name = each.key
|
||||
public_key = each.value
|
||||
labels = {
|
||||
"wiki" = "true"
|
||||
}
|
||||
}
|
5
terraform/admins/providers.tf
Normal file
5
terraform/admins/providers.tf
Normal file
@ -0,0 +1,5 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
hcloud = { source = "hetznercloud/hcloud" }
|
||||
}
|
||||
}
|
5
terraform/admins/variables.tf
Normal file
5
terraform/admins/variables.tf
Normal file
@ -0,0 +1,5 @@
|
||||
variable "ssh_keys" {
|
||||
type = map(string)
|
||||
description = "SSH public keys for admin user (name -> key)"
|
||||
}
|
||||
|
18
terraform/web01/dns.tf
Normal file
18
terraform/web01/dns.tf
Normal file
@ -0,0 +1,18 @@
|
||||
resource "netlify_dns_zone" "nixos" {
|
||||
site_id = ""
|
||||
name = var.netlify_dns_zone
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "nixos_wiki_a" {
|
||||
zone_id = netlify_dns_zone.nixos.id
|
||||
hostname = var.domain
|
||||
type = "A"
|
||||
value = hcloud_server.nixos_wiki.ipv4_address
|
||||
}
|
||||
|
||||
resource "netlify_dns_record" "nixos_wiki_aaaa" {
|
||||
zone_id = netlify_dns_zone.nixos.id
|
||||
hostname = var.domain
|
||||
type = "AAAA"
|
||||
value = hcloud_server.nixos_wiki.ipv6_address
|
||||
}
|
39
terraform/web01/main.tf
Normal file
39
terraform/web01/main.tf
Normal file
@ -0,0 +1,39 @@
|
||||
# Record the SSH public key into Hetzner Cloud
|
||||
data "hcloud_ssh_keys" "nixos_wiki" {
|
||||
with_selector = "wiki=true"
|
||||
}
|
||||
|
||||
resource "hcloud_server" "nixos_wiki" {
|
||||
image = "debian-10"
|
||||
keep_disk = true
|
||||
name = "nixos-wiki"
|
||||
server_type = var.server_type
|
||||
ssh_keys = data.hcloud_ssh_keys.nixos_wiki.ssh_keys.*.name
|
||||
backups = false
|
||||
labels = var.tags
|
||||
|
||||
location = var.server_location
|
||||
|
||||
lifecycle {
|
||||
# Don't destroy server instance if ssh keys changes.
|
||||
ignore_changes = [ssh_keys]
|
||||
prevent_destroy = false
|
||||
}
|
||||
}
|
||||
|
||||
module "deploy" {
|
||||
depends_on = [local_file.nixos_vars]
|
||||
source = "github.com/numtide/nixos-anywhere//terraform/all-in-one"
|
||||
nixos_system_attr = ".#nixosConfigurations.${var.nixos_flake_attr}.config.system.build.toplevel"
|
||||
nixos_partitioner_attr = ".#nixosConfigurations.${var.nixos_flake_attr}.config.system.build.diskoNoDeps"
|
||||
target_host = hcloud_server.nixos_wiki.ipv4_address
|
||||
instance_id = hcloud_server.nixos_wiki.id
|
||||
debug_logging = true
|
||||
}
|
||||
|
||||
locals {
|
||||
nixos_vars = {
|
||||
ipv6_address = hcloud_server.nixos_wiki.ipv6_address
|
||||
ssh_keys = data.hcloud_ssh_keys.nixos_wiki.ssh_keys.*.public_key
|
||||
}
|
||||
}
|
18
terraform/web01/nixos_vars.tf
Normal file
18
terraform/web01/nixos_vars.tf
Normal file
@ -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 '${local_file.nixos_vars.filename}'"
|
||||
}
|
||||
# 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 '${local_file.nixos_vars.filename}')"/{hosts,flake-module.nix}
|
||||
EOT
|
||||
on_failure = continue
|
||||
}
|
||||
}
|
7
terraform/web01/providers.tf
Normal file
7
terraform/web01/providers.tf
Normal file
@ -0,0 +1,7 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
netlify = { source = "AegirHealth/netlify" }
|
||||
hcloud = { source = "hetznercloud/hcloud" }
|
||||
local = { source = "hashicorp/local" }
|
||||
}
|
||||
}
|
37
terraform/web01/variables.tf
Normal file
37
terraform/web01/variables.tf
Normal file
@ -0,0 +1,37 @@
|
||||
variable "server_type" {
|
||||
type = string
|
||||
default = "cx21"
|
||||
description = "Hetzner cloud server type"
|
||||
}
|
||||
|
||||
variable "server_location" {
|
||||
type = string
|
||||
default = "hel1"
|
||||
description = "Hetzner cloud server location"
|
||||
}
|
||||
|
||||
variable "netlify_dns_zone" {
|
||||
type = string
|
||||
description = "Netlify DNS zone"
|
||||
}
|
||||
|
||||
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 "domain" {
|
||||
type = string
|
||||
description = "Domain name"
|
||||
}
|
||||
|
||||
variable "tags" {
|
||||
type = map(string)
|
||||
default = {}
|
||||
description = "Tags to add to the server"
|
||||
}
|
Loading…
Reference in New Issue
Block a user