Page MenuHomeDevCentral

D4207.id11034.diff
No OneTemporary

D4207.id11034.diff

diff --git a/roles/core/userland-software/base.sls b/roles/core/userland-software/base.sls
--- a/roles/core/userland-software/base.sls
+++ b/roles/core/userland-software/base.sls
@@ -8,6 +8,20 @@
{% from "map.jinja" import dirs, packages with context %}
+# -------------------------------------------------------------
+# /opt directory
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+{% if salt["node.has"]("zfs:pool") %}
+{% set tank = salt["node.get"]("zfs:pool") %}
+
+{{ tank }}/opt:
+ zfs.filesystem_present:
+ - properties:
+ mountpoint: /opt
+ compression: zstd
+{% endif %}
+
/opt:
file.directory
diff --git a/roles/devserver/userland-software/init.sls b/roles/devserver/userland-software/init.sls
--- a/roles/devserver/userland-software/init.sls
+++ b/roles/devserver/userland-software/init.sls
@@ -21,6 +21,7 @@
- .dev
- .misc
- .notifications
+ - .pefs
- .phabricator
- .psysh
- .tex
diff --git a/roles/devserver/userland-software/misc.sls b/roles/devserver/userland-software/misc.sls
--- a/roles/devserver/userland-software/misc.sls
+++ b/roles/devserver/userland-software/misc.sls
@@ -93,23 +93,6 @@
/etc/make.conf:
file.managed:
- source: salt://roles/devserver/userland-software/files/make.conf
-
-freebsd_kernel_modules:
- pkg.installed:
- - pkgs:
- - pefs-kmod
-
-freebsd_kernel_modules_enable:
- module.wait:
- - name: kmod.load
- - mod: pefs
- - persist: True
- - watch:
- - pkg: freebsd_kernel_modules
-
-/boot/loader.conf.d/pefs.conf:
- file.managed:
- - source: salt://roles/devserver/userland-software/files/pefs.conf
{% endif %}
devserver_software_misc_p2p:
diff --git a/roles/devserver/userland-software/pefs.sls b/roles/devserver/userland-software/pefs.sls
new file mode 100644
--- /dev/null
+++ b/roles/devserver/userland-software/pefs.sls
@@ -0,0 +1,25 @@
+# -------------------------------------------------------------
+# Salt — PEFS
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# License: Trivial work, not eligible to copyright
+# -------------------------------------------------------------
+
+{% if grains["os"] == "FreeBSD" %}
+
+pefs-kmod:
+ pkg.installed
+
+pefs_kernel_modules_enable:
+ module.wait:
+ - name: kmod.load
+ - mod: pefs
+ - persist: True
+ - watch:
+ - pkg: pefs-kmod
+
+/boot/loader.conf.d/pefs.conf:
+ file.managed:
+ - source: salt://roles/devserver/userland-software/files/pefs.conf
+
+{% endif %}
diff --git a/roles/devserver/userland-software/files/port_options b/roles/devserver/userland-software/port_options
rename from roles/devserver/userland-software/files/port_options
rename to roles/devserver/userland-software/port_options
diff --git a/roles/salt-primary/opentofu/config.sls b/roles/salt-primary/opentofu/config.sls
new file mode 100644
--- /dev/null
+++ b/roles/salt-primary/opentofu/config.sls
@@ -0,0 +1,76 @@
+# -------------------------------------------------------------
+# Salt — Provision a salt primary server
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# License: Trivial work, not eligible to copyright
+# -------------------------------------------------------------
+
+# -------------------------------------------------------------
+# ZFS datasets
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+{% if salt["node.has"]("zfs:pool") %}
+{% set tank = salt["node.get"]("zfs:pool") %}
+
+{{ tank }}/opt/terraform:
+ zfs.filesystem_present:
+ - properties:
+ mountpoint: /opt/terraform
+ compression: lz4
+ atime: off
+ recordsize: 128K
+ xattr: sa
+
+{{ tank }}/opt/terraform.enc:
+ zfs.filesystem_present:
+ - properties:
+ mountpoint: /opt/terraform.enc
+ compression: zstd
+{% endif %}
+
+# -------------------------------------------------------------
+# Terraform / OpenTofu non encrypted working directory
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+/opt/terraform:
+ file.directory:
+ - user: deploy
+ - group: ops
+ - mode: 770
+
+/opt/terraform/tf-data:
+ file.directory:
+ - user: deploy
+ - group: ops
+ - mode: 770
+
+# -------------------------------------------------------------
+# Terraform / OpenTofu encrypted directory for states
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+/opt/terraform.enc:
+ file.directory:
+ - user: deploy
+ - group: ops
+ - mode: 770
+
+# Will be mounted from /opt/terraform.enc to /opt/terraform/encrypted
+/opt/terraform/encrypted:
+ file.directory:
+ - user: deploy
+ - group: ops
+ - mode: 770
+
+# -------------------------------------------------------------
+# Wrapper for tofu/terraform/pefs commands
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+/usr/local/bin/initialize-pefs:
+ file.managed:
+ - source: salt://roles/salt-primary/opentofu/files/initialize-pefs.sh
+ - mode: 755
+
+/usr/local/bin/tf:
+ file.managed:
+ - source: salt://roles/salt-primary/opentofu/files/tf.sh
+ - mode: 755
diff --git a/roles/salt-primary/opentofu/files/initialize-pefs.sh b/roles/salt-primary/opentofu/files/initialize-pefs.sh
new file mode 100644
--- /dev/null
+++ b/roles/salt-primary/opentofu/files/initialize-pefs.sh
@@ -0,0 +1,72 @@
+#!/bin/sh
+
+# -------------------------------------------------------------
+# Initialize PEFS
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# License: BSD-2-Clause
+# Description: Set password for Terraform / OpenTofu PEFS
+# Usage: initialize-pefs ops/infra/complector/terraform/pefs /opt/terraform.enc /opt/terraform/encrypted
+# Source file: roles/salt-primary/opentofu/files/initialize-pefs.sh
+# -------------------------------------------------------------
+#
+# <auto-generated>
+# This file is managed by our rOPS SaltStack repository.
+#
+# Changes to this file may cause incorrect behavior
+# and will be lost if the state is redeployed.
+# </auto-generated>
+
+set -e
+
+# -------------------------------------------------------------
+# Parse arguments
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+if [ $# -lt 3 ]; then
+ echo "Usage: $(basename "$0") <Vault key path> <encrypted filesystem> <mount point>" >&2
+ exit 1
+fi
+
+VAULT_PATH=$1
+PEFS_ENC=$2
+PEFS_MOUNT=$3
+
+# -------------------------------------------------------------
+# Ensure user belongs to correct group
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+if ! id -Gn | tr ' ' '\n' | grep -E '^(ops|deploy)$' >/dev/null 2>&1; then
+ echo "error: user must be a member of the ops or deploy group" >&2
+ exit 1
+fi
+
+# -------------------------------------------------------------
+# Mount filesystem
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+if ! sudo -u deploy pefs mount "$PEFS_ENC" "$PEFS_MOUNT"; then
+ echo "Error: Failed to mount PEFS" >&2
+ exit 2
+fi
+
+# -------------------------------------------------------------
+# Ensure unmount PEFS on exit
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+unmount_pefs() {
+ sudo -u deploy pefs unmount "$PEFS_MOUNT" 2>/dev/null || true
+}
+
+trap unmount_pefs EXIT
+
+if [ -f "$PEFS_ENC/.pefs.db" ]; then
+ echo "That directory has already been initialized."
+ exit 4
+fi
+
+# -------------------------------------------------------------
+# Add a new chain element
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+vault kv get -field=password "$VAULT_PATH" | sudo -u deploy pefs addchain -fZ -j - "$PEFS_ENC"
diff --git a/roles/salt-primary/opentofu/files/tf.sh b/roles/salt-primary/opentofu/files/tf.sh
new file mode 100644
--- /dev/null
+++ b/roles/salt-primary/opentofu/files/tf.sh
@@ -0,0 +1,171 @@
+#!/bin/sh
+
+# -------------------------------------------------------------
+# Wrapper to securely manage Terraform state on PEFS
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Project: Nasqueron
+# Usage: tf <mount|unmount|init|plan|apply|state|...> ...
+# License: BSD-2-Clause
+# Source file: roles/salt-primary/opentofu/files/tf.sh
+# -------------------------------------------------------------
+#
+# <auto-generated>
+# This file is managed by our rOPS SaltStack repository.
+#
+# Changes to this file may cause incorrect behavior
+# and will be lost if the state is redeployed.
+# </auto-generated>
+
+set -e
+
+REPO_TF_BASE="/opt/salt/nasqueron-operations/terraform"
+
+TF_ROOT_DIR="/opt/terraform"
+PEFS_ENC="/opt/terraform.enc"
+PEFS_MOUNT="$TF_ROOT_DIR/encrypted"
+
+VAULT_PATH="ops/infra/complector/terraform/pefs"
+
+# -------------------------------------------------------------
+# Ensure user belongs to correct group
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+if ! id -Gn | tr ' ' '\n' | grep -E '^(ops|deploy)$' >/dev/null 2>&1; then
+ echo "error: user must be a member of the ops or deploy group" >&2
+ exit 1
+fi
+
+# -------------------------------------------------------------
+# Handle maintenance commands: mount / unmount
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+if [ "$1" = "mount" ]; then
+ if ! mount | grep -q "${PEFS_ENC} on ${PEFS_MOUNT} (pefs"; then
+ if ! sudo -u deploy pefs mount "$PEFS_ENC" "$PEFS_MOUNT"; then
+ echo "Error: Failed to mount PEFS" >&2
+ exit 2
+ fi
+ else
+ echo "PEFS is already mounted." >&2
+ fi
+
+ if ! sudo -u deploy pefs showkeys -t "$PEFS_MOUNT"; then
+ if ! vault kv get -field=password "$VAULT_PATH" | sudo -u deploy pefs addkey -a aes256-xts -c -j - "$PEFS_MOUNT"; then
+ echo "Error: Failed to add PEFS key using password from Vault at $VAULT_PATH"
+ exit 1
+ fi
+ else
+ echo "PEFS key is already loaded." >&2
+ fi
+ exit 0
+fi
+
+if [ "$1" = "unmount" ] || [ "$1" = "umount" ]; then
+ if mount | grep -q "${PEFS_ENC} on ${PEFS_MOUNT} (pefs"; then
+ sudo -u deploy pefs unmount "$PEFS_MOUNT" || true
+ else
+ echo "PEFS is not mounted." >&2
+ fi
+ exit 0
+fi
+
+# -------------------------------------------------------------
+# Get working directory
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+CURRENT_DIR="$(pwd)"
+
+case "$CURRENT_DIR" in
+ "${REPO_TF_BASE}"/*)
+ # Remove REPO_TF_BASE/ prefix to get the subdirectory name
+ TF_CONFIG="${CURRENT_DIR#"$REPO_TF_BASE/"}"
+
+ # Ensure it's a single top-level directory (no nested slashes like foo/bar)
+ case "$TF_CONFIG" in
+ */*)
+ echo "Error: You must be in a top-level Terraform subdirectory of $REPO_TF_BASE" >&2
+ echo "Current directory: $CURRENT_DIR" >&2
+ exit 1
+ ;;
+ esac
+ ;;
+ *)
+ echo "Error: Must be run from a subdirectory of $REPO_TF_BASE" >&2
+ echo "Current directory: $CURRENT_DIR" >&2
+ exit 1
+ ;;
+esac
+
+# -------------------------------------------------------------
+# Terraform or OpenTofu?
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+STILL_REQUIRE_TERRAFORM="openbao ovh-ops-backups"
+
+is_terraform_config() {
+ for terraform_subdir in $STILL_REQUIRE_TERRAFORM; do
+ [ "$1" = "$terraform_subdir" ] && return 0
+ done
+ return 1
+}
+
+if is_terraform_config "$TF_CONFIG"; then
+ TF=terraform
+else
+ TF=tofu
+fi
+
+# -------------------------------------------------------------
+# Ensure unmount PEFS on exit
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+MOUNTED_BY_US=0
+
+unmount_pefs() {
+ if [ "$MOUNTED_BY_US" -eq 1 ]; then
+ # Attempt to unmount, suppress errors if already unmounted or busy
+ sudo -u deploy pefs unmount "$PEFS_MOUNT" 2>/dev/null || true
+ fi
+}
+
+# Trap EXIT covers normal completion, script errors (exit 1), and signals (SIGINT/SIGTERM)
+trap unmount_pefs EXIT
+
+# -------------------------------------------------------------
+# Mount and decrypt PEFS
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+if ! mount | grep -q "${PEFS_ENC} on ${PEFS_MOUNT} (pefs"; then
+ if ! sudo -u deploy pefs mount "$PEFS_ENC" "$PEFS_MOUNT"; then
+ echo "Error: Failed to mount PEFS" >&2
+ exit 2
+ fi
+ MOUNTED_BY_US=1
+fi
+
+if ! sudo -u deploy pefs showkeys -t "$PEFS_MOUNT"; then
+ if ! vault kv get -field=password "$VAULT_PATH" | sudo -u deploy pefs addkey -a aes256-xts -c -j - "$PEFS_MOUNT"; then
+ echo "Error: Failed to add PEFS key using password from Vault at $VAULT_PATH"
+ exit 1
+ fi
+fi
+
+# -------------------------------------------------------------
+# Ensure Terraform directories exist
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+TF_STATES_DIR="${PEFS_MOUNT}/tf-states/${TF_CONFIG}"
+export TF_DATA_DIR="${TF_ROOT_DIR}/tf-data/${TF_CONFIG}"
+
+# shellcheck disable=SC2174
+mkdir -p -m 770 "$TF_STATES_DIR" "$TF_DATA_DIR"
+
+# -------------------------------------------------------------
+# Call Terraform/OpenTofu
+#
+# Pass all arguments directly to terraform.
+# The script will exit with Terraform's exact exit code,
+# and the trap will unmount PEFS.
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+$TF "$@"
diff --git a/roles/salt-primary/opentofu/init.sls b/roles/salt-primary/opentofu/init.sls
--- a/roles/salt-primary/opentofu/init.sls
+++ b/roles/salt-primary/opentofu/init.sls
@@ -5,11 +5,9 @@
# License: Trivial work, not eligible to copyright
# -------------------------------------------------------------
-opentofu_software:
- pkg.installed:
- - pkgs:
- - opentofu
- - terraform # fallback for providers not compiled for FreeBSD
+include:
+ - .software
+ - roles/devserver/userland-software/pefs
- # Helpers for authentication to Terraform providers
- - ovhcloud-cli
+ # Depends of pefs
+ - .config
diff --git a/roles/salt-primary/opentofu/init.sls b/roles/salt-primary/opentofu/software.sls
copy from roles/salt-primary/opentofu/init.sls
copy to roles/salt-primary/opentofu/software.sls
diff --git a/terraform/openbao/Makefile b/terraform/openbao/Makefile
--- a/terraform/openbao/Makefile
+++ b/terraform/openbao/Makefile
@@ -1,3 +1,4 @@
+TERRAFORM_STATES_DIR=/opt/terraform/encrypted/tf-states/openbao/
TERRAFORM_STATES=terraform.tfstate terraform.tfstate.backup
SALT=sudo -u salt salt
@@ -15,13 +16,15 @@
@echo "[$(AUDIT_DATE)] <$(USER)> Terraform :: Vault :: Full secrets rotation" >> $(AUDIT_LOG)
provision:
- terraform init
- terraform plan
- terraform apply -auto-approve
+ tf init
+ tf plan
+ tf apply -auto-approve
deploy:
$(SALT) windriver state.sls_id /usr/local/etc/secrets/rhyne-wyse.yaml roles/reports/rhyne-wyse/config
$(SALT) windriver state.sls_id /srv/viperserv/.credentials roles/viperserv/eggdrop/config
clean:
- $(RM) $(TERRAFORM_STATES)
+ tf mount
+ cd $(TERRAFORM_STATES_DIR) && $(RM) $(TERRAFORM_STATES)
+ tf unmount
diff --git a/terraform/openbao/providers.tf b/terraform/openbao/providers.tf
--- a/terraform/openbao/providers.tf
+++ b/terraform/openbao/providers.tf
@@ -12,6 +12,10 @@
version = "5.3.0"
}
}
+
+ backend "local" {
+ path = "/opt/terraform/encrypted/tf-states/openbao/terraform.tfstate"
+ }
}
provider "vault" {
diff --git a/terraform/ovh-ops-backups/providers.tf b/terraform/ovh-ops-backups/providers.tf
--- a/terraform/ovh-ops-backups/providers.tf
+++ b/terraform/ovh-ops-backups/providers.tf
@@ -21,6 +21,10 @@
version = ">= 5.11.0"
}
}
+
+ backend "local" {
+ path = "/opt/terraform/encrypted/tf-states/ovh-ops-backups/terraform.tfstate"
+ }
}
# -------------------------------------------------------------

File Metadata

Mime Type
text/plain
Expires
Thu, Sep 10, 22:16 (18 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4077407
Default Alt Text
D4207.id11034.diff (15 KB)

Event Timeline