Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F49007820
D4207.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
15 KB
Referenced Files
None
Subscribers
None
D4207.id.diff
View Options
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
Details
Attached
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.id.diff (15 KB)
Attached To
Mode
D4207: Wrap tofu or terraform command to manage encrypted state
Attached
Detach File
Event Timeline
Log In to Comment