Skip to content

Commit f7f67be

Browse files
committed
also support sudo password in terraform
1 parent 754a9f0 commit f7f67be

File tree

10 files changed

+78
-39
lines changed

10 files changed

+78
-39
lines changed

docs/cli.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Options:
2121
* --env-password
2222
set a password used by ssh-copy-id, the password should be set by
2323
the environment variable SSHPASS. Additionally, sudo password can be set
24-
via SUDO_PASSWORD environment variable for remote sudo operations
24+
via SUDO_PASSWORD environment variable for remote sudo operations
2525
(only supported with sudo, not doas)
2626
* -s, --store-paths <disko-script> <nixos-system>
2727
set the store paths to the disko-script and nixos-system directly

docs/reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Options:
4242
* --env-password
4343
set a password used by ssh-copy-id, the password should be set by
4444
the environment variable SSHPASS. Additionally, sudo password can be set
45-
via SUDO_PASSWORD environment variable for remote sudo operations
45+
via SUDO_PASSWORD environment variable for remote sudo operations
4646
(only supported with sudo, not doas)
4747
* -s, --store-paths <disko-script> <nixos-system>
4848
set the store paths to the disko-script and nixos-system directly

src/nixos-anywhere.sh

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -430,28 +430,15 @@ runSsh() {
430430

431431
# Helper function to authenticate sudo with password if needed
432432
maybeSudo() {
433-
# Early return if no command provided and no sudo password
434-
if [[ $# -eq 0 && -z ${SUDO_PASSWORD} ]]; then
435-
return
436-
fi
437-
438-
# Use 'true' as default command if none provided but we have sudo password
439-
local cmd=("${@:-true}")
440-
441433
if [[ -n ${SUDO_PASSWORD} ]] && [[ ${maybeSudoCommand} == "sudo" ]]; then
442434
# If debug is enabled and we have a sudo password, warn about potential issues
443-
444435
# Use sudo with password authentication - pipe password to all sudo commands
445436
printf "printf %%s %q | sudo -S " "$SUDO_PASSWORD"
446-
printf '%q ' "${cmd[@]}"
437+
# Restore debug state if it was enabled
447438
elif [[ -n ${maybeSudoCommand} ]]; then
448439
printf '%s ' "${maybeSudoCommand}"
449-
printf '%q ' "${cmd[@]}"
450-
else
451-
# No sudo command needed (e.g., already root after kexec)
452-
printf '%q ' "${cmd[@]}"
453440
fi
454-
echo
441+
# No output if no sudo needed (e.g., already root after kexec)
455442
}
456443

457444
# Test and cache sudo password if needed
@@ -547,7 +534,7 @@ buildStoreUrl() {
547534
# Use password authentication for nix-daemon
548535
remoteProgram="sh -c $(urlEncode "$(printf %s "$(printf '%q' "$SUDO_PASSWORD")" | sudo -S nix-daemon)")"
549536
else
550-
remoteProgram="${maybeSudoCommand},nix-daemon"
537+
remoteProgram="${maybeSudoCommand} nix-daemon"
551538
fi
552539

553540
if [[ $storeUrl == *"?"* ]]; then
@@ -752,7 +739,7 @@ generateHardwareConfig() {
752739
fi
753740
754741
step "Generating hardware-configuration.nix using nixos-facter"
755-
runSshNoTty -o ConnectTimeout=10 "$(maybeSudo nixos-facter)" >"$hardwareConfigPath"
742+
runSshNoTty -o ConnectTimeout=10 "$(maybeSudo)nixos-facter" >"$hardwareConfigPath"
756743
;;
757744
nixos-generate-config)
758745
step "Generating hardware-configuration.nix using nixos-generate-config"
@@ -806,10 +793,10 @@ runKexec() {
806793
local remoteCommandTemplate
807794
remoteCommandTemplate="
808795
set -eu ${enableDebug}
809-
$(maybeSudo rm -rf /root/kexec)
810-
$(maybeSudo mkdir -p /root/kexec)
796+
$(maybeSudo)rm -rf /root/kexec
797+
$(maybeSudo)mkdir -p /root/kexec
811798
%TAR_COMMAND%
812-
$(maybeSudo TMPDIR=/root/kexec setsid --wait /root/kexec/kexec/run --kexec-extra-flags "$kexecExtraFlags")
799+
$(maybeSudo)TMPDIR=/root/kexec setsid --wait /root/kexec/kexec/run${kexecExtraFlags:+ --kexec-extra-flags \"$kexecExtraFlags\"}
813800
"
814801
815802
# Define upload commands
@@ -870,7 +857,7 @@ runDisko() {
870857
local diskoScript=$1
871858
for path in "${!diskEncryptionKeys[@]}"; do
872859
step "Uploading ${diskEncryptionKeys[$path]} to $path"
873-
runSsh "$(maybeSudo sh) -c $(printf '%q' "umask 077; mkdir -p $(dirname "$path"); cat > $path")" <"${diskEncryptionKeys[$path]}"
860+
runSsh "$(maybeSudo)sh -c $(printf '%q' "umask 077; mkdir -p $(dirname "$path"); cat > $path")" <"${diskEncryptionKeys[$path]}"
874861
done
875862
if [[ -n ${diskoScript} ]]; then
876863
nixCopy --to "ssh-ng://$sshConnection" "$diskoScript"
@@ -887,7 +874,7 @@ runDisko() {
887874
fi
888875
889876
step Formatting hard drive with disko
890-
runSsh "$(maybeSudo "$diskoScript")"
877+
runSsh "$(maybeSudo)$diskoScript"
891878
}
892879
893880
nixosInstall() {
@@ -912,12 +899,12 @@ nixosInstall() {
912899
step Copying extra files
913900
tar -C "$extraFiles" -cpf- . | runSsh "${maybeSudoCommand} tar -C /mnt -xf- --no-same-owner"
914901
915-
runSsh "$(maybeSudo chmod 755 /mnt)" # tar also changes permissions of /mnt
902+
runSsh "$(maybeSudo)chmod 755 /mnt" # tar also changes permissions of /mnt
916903
fi
917904
918905
if [[ ${#extraFilesOwnership[@]} -gt 0 ]]; then
919-
# shellcheck disable=SC2016
920-
printf "%s\n" "${!extraFilesOwnership[@]}" "${extraFilesOwnership[@]}" | pr -2t | runSsh 'while read file ownership; do '"$(maybeSudo chown -R \$ownership \"/mnt/\$file\")"'; done'
906+
# shellcheck disable=SC2016,SC2086
907+
printf "%s\n" "${!extraFilesOwnership[@]}" "${extraFilesOwnership[@]}" | pr -2t | runSsh "while read file ownership; do $(maybeSudo)chown -R \$ownership /mnt/\$file; done"
921908
fi
922909
923910
step Installing NixOS
@@ -929,27 +916,27 @@ export PATH="\$PATH:/run/current-system/sw/bin"
929916
930917
if [ ! -d "/mnt/tmp" ]; then
931918
# needed for installation if initrd-secrets are used
932-
$(maybeSudo mkdir -p /mnt/tmp)
933-
$(maybeSudo chmod 777 /mnt/tmp)
919+
$(maybeSudo)mkdir -p /mnt/tmp
920+
$(maybeSudo)chmod 777 /mnt/tmp
934921
fi
935922
936923
if [ ${copyHostKeys-n} = "y" ]; then
937924
# NB we copy host keys that are in turn copied by kexec installer.
938-
$(maybeSudo mkdir -m 755 -p /mnt/etc/ssh)
925+
$(maybeSudo)mkdir -m 755 -p /mnt/etc/ssh
939926
for p in /etc/ssh/ssh_host_*; do
940927
# Skip if the source file does not exist (i.e. glob did not match any files)
941928
# or the destination already exists (e.g. copied with --extra-files).
942929
if [ ! -e "\$p" ] || [ -e "/mnt/\$p" ]; then
943930
continue
944931
fi
945-
$(maybeSudo cp -a '$p' '/mnt/$p')
932+
$(maybeSudo)cp -a "\$p" "/mnt/\$p"
946933
done
947934
fi
948935
# https://stackoverflow.com/a/13864829
949936
if [ ! -z ${NIXOS_NO_CHECK+0} ]; then
950937
export NIXOS_NO_CHECK
951938
fi
952-
$(maybeSudo nixos-install --no-root-passwd --no-channel-copy --system "$nixosSystem")
939+
$(maybeSudo)nixos-install --no-root-passwd --no-channel-copy --system "$nixosSystem"
953940
SSH
954941
955942
}
@@ -959,11 +946,11 @@ nixosReboot() {
959946
runSsh sh <<SSH
960947
if command -v zpool >/dev/null && [ "\$(zpool list)" != "no pools available" ]; then
961948
# we always want to export the zfs pools so people can boot from it without force import
962-
$(maybeSudo umount -Rv /mnt/)
963-
$(maybeSudo swapoff -a)
964-
$(maybeSudo zpool export -a || true)
949+
$(maybeSudo)umount -Rv /mnt/
950+
$(maybeSudo)swapoff -a
951+
$(maybeSudo)zpool export -a || true
965952
fi
966-
$(maybeSudo nohup sh -c 'sleep 6 && reboot') >/dev/null &
953+
$(maybeSudo)nohup sh -c 'sleep 6 && reboot' >/dev/null &
967954
SSH
968955
969956
step Waiting for the machine to become unreachable due to reboot

terraform/all-in-one.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ module "deploy" {
2828
# debug_logging = true
2929
# build the closure on the remote machine instead of locally
3030
# build_on_remote = true
31+
# Optional: SSH password for initial installation
32+
# install_pass = "your-ssh-password"
33+
# Optional: Sudo password for remote operations during installation
34+
# install_sudo_pass = "your-sudo-password"
3135
# script is below
3236
extra_files_script = "${path.module}/decrypt-ssh-secrets.sh"
3337
disk_encryption_key_scripts = [{
@@ -139,7 +143,7 @@ locals {
139143
resource "local_file" "nixos_vars" {
140144
content = jsonencode(local.nixos_vars) # Converts variables to JSON
141145
filename = local.nixos_vars_file # Specifies the output file path
142-
file_permission = "600"
146+
file_permission = "600"
143147
144148
# Automatically adds the generated file to Git
145149
provisioner "local-exec" {

terraform/all-in-one/main.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ module "install" {
2727
target_user = local.install_user
2828
target_host = var.target_host
2929
target_port = local.install_port
30+
target_pass = var.install_pass
31+
target_sudo_pass = var.install_sudo_pass
3032
nixos_partitioner = module.partitioner-build.result.out
3133
nixos_system = module.system-build.result.out
3234
ssh_private_key = var.install_ssh_key

terraform/all-in-one/variables.tf

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,17 @@ variable "install_bootloader" {
149149
description = "Install/re-install the bootloader"
150150
default = false
151151
}
152+
153+
variable "install_pass" {
154+
type = string
155+
description = "Password used to connect to the target_host during installation"
156+
default = null
157+
sensitive = true
158+
}
159+
160+
variable "install_sudo_pass" {
161+
type = string
162+
description = "Sudo password for remote sudo operations during installation. Only supported with sudo, not doas."
163+
default = null
164+
sensitive = true
165+
}

terraform/install.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ module "install" {
3434
nixos_system = module.system-build.result.out
3535
nixos_partitioner = module.disko.result.out
3636
target_host = local.ipv4
37+
# Optional: SSH password authentication
38+
# target_pass = "your-ssh-password"
39+
# Optional: Sudo password for remote operations
40+
# target_sudo_pass = "your-sudo-password"
3741
}
3842
```
3943

terraform/install/main.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ locals {
1212
target_host = var.target_host
1313
target_port = var.target_port
1414
target_pass = var.target_pass
15+
target_sudo_pass = var.target_sudo_pass
1516
extra_files_script = var.extra_files_script
1617
build_on_remote = var.build_on_remote
1718
flake = var.flake

terraform/install/run-nixos-anywhere.sh

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ args=()
1313

1414
if [[ ${input[debug_logging]} == "true" ]]; then
1515
set -x
16-
declare -p input
16+
# Print input variables but filter out sensitive passwords
17+
for key in "${!input[@]}"; do
18+
if [[ $key == *"pass"* ]]; then
19+
echo "input[$key]='[FILTERED]'"
20+
else
21+
echo "input[$key]='${input[$key]}'"
22+
fi
23+
done
1724
args+=("--debug")
1825
fi
1926
if [[ ${input[kexec_tarball_url]} != "null" ]]; then
@@ -40,9 +47,22 @@ args+=(--phases "${input[phases]}")
4047
if [[ ${input[ssh_private_key]} != null ]]; then
4148
export SSH_PRIVATE_KEY="${input[ssh_private_key]}"
4249
fi
50+
if [[ ${input[target_pass]} != null || ${input[target_sudo_pass]} != null ]]; then
51+
args+=("--env-password")
52+
fi
53+
# Temporarily disable debug output when exporting sensitive variables
54+
if [[ ${input[debug_logging]} == "true" ]]; then
55+
set +x
56+
fi
4357
if [[ ${input[target_pass]} != null ]]; then
4458
export SSHPASS=${input[target_pass]}
45-
args+=("--env-password")
59+
fi
60+
if [[ ${input[target_sudo_pass]} != null ]]; then
61+
export SUDO_PASSWORD=${input[target_sudo_pass]}
62+
fi
63+
# Re-enable debug output if it was enabled
64+
if [[ ${input[debug_logging]} == "true" ]]; then
65+
set -x
4666
fi
4767

4868
tmpdir=$(mktemp -d)

terraform/install/variables.tf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ variable "target_pass" {
4141
default = null
4242
}
4343

44+
variable "target_sudo_pass" {
45+
type = string
46+
description = "Sudo password for remote sudo operations on target_host. Only supported with sudo, not doas."
47+
default = null
48+
sensitive = true
49+
}
50+
4451
variable "ssh_private_key" {
4552
type = string
4653
description = "Content of private key used to connect to the target_host"

0 commit comments

Comments
 (0)