Update infrastructure tooling and configuration
- Rename setup.sh to setup (drop extension for cleaner CLI) - Update ansible.cfg for improved playbook execution - Update .env.example with current environment variables
This commit is contained in:
parent
d36d3db10d
commit
e7b9546f7f
3 changed files with 226 additions and 2 deletions
29
.env.example
29
.env.example
|
|
@ -14,4 +14,31 @@ TF_VAR_object_storage_region=us-east-1
|
|||
|
||||
S3_BUCKET=
|
||||
S3_REGION=us-east-1
|
||||
S3_ENDPOINT=https://us-east-1.linodeobjects.com
|
||||
S3_ENDPOINT=https://us-east-1.linodeobjects.com
|
||||
|
||||
RESTIC_REPOSITORY=
|
||||
RESTIC_AWS_DEFAULT_REGION=us-east-1
|
||||
INFRA_BACKUP_ONCALENDAR=daily
|
||||
RESTIC_KEEP_DAILY=7
|
||||
RESTIC_KEEP_WEEKLY=4
|
||||
RESTIC_KEEP_MONTHLY=6
|
||||
|
||||
ALERTMANAGER_SLACK_CHANNEL=#alerts
|
||||
ALERTMANAGER_SLACK_USERNAME=alertmanager
|
||||
|
||||
AUTHELIA_SMTP_ADDRESS=
|
||||
AUTHELIA_SMTP_USERNAME=
|
||||
AUTHELIA_SMTP_PASSWORD=
|
||||
AUTHELIA_SMTP_SENDER=
|
||||
AUTHELIA_SMTP_IDENTIFIER=
|
||||
AUTHELIA_SMTP_STARTUP_CHECK_ADDRESS=
|
||||
AUTHELIA_NOTIFIER_DISABLE_STARTUP_CHECK=false
|
||||
# AUTHELIA_NOTIFIER_TYPE=filesystem
|
||||
|
||||
# AUTHELIA_USE_POSTFIX=false
|
||||
# POSTFIX_RELAYHOST=
|
||||
# POSTFIX_RELAYHOST_USERNAME=
|
||||
# POSTFIX_RELAYHOST_PASSWORD=
|
||||
# POSTFIX_SMTP_TLS_SECURITY_LEVEL=may
|
||||
# POSTFIX_ALLOWED_SENDER_DOMAINS=
|
||||
# POSTFIX_ALLOW_EMPTY_SENDER_DOMAINS=true
|
||||
|
|
@ -7,4 +7,3 @@ interpreter_python=/usr/bin/python3
|
|||
|
||||
[ssh_connection]
|
||||
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o ControlPath=~/.ansible/cp/ansible-ssh-%%h-%%p-%%r -o StrictHostKeyChecking=accept-new -o IdentitiesOnly=yes
|
||||
|
||||
|
|
|
|||
198
setup
Executable file
198
setup
Executable file
|
|
@ -0,0 +1,198 @@
|
|||
#! /usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
vault_args=()
|
||||
temp_vault_pass_file=""
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: ./setup [--no-ansible] [--no-terraform|--ansible-only] [--] [terraform <args>]
|
||||
|
||||
Defaults:
|
||||
- Runs Terraform (plan/apply) in terraform/
|
||||
- Generates Ansible inventory from Terraform outputs
|
||||
- Runs Ansible playbooks
|
||||
|
||||
Options:
|
||||
--no-ansible Run Terraform only (no Ansible).
|
||||
--no-terraform Skip Terraform; requires existing inventory/hosts.yml.
|
||||
--ansible-only Alias for --no-terraform.
|
||||
--help Show this help.
|
||||
|
||||
Terraform passthrough:
|
||||
./setup -- terraform <cmd> [args]
|
||||
./setup -- <terraform-subcommand> [args]
|
||||
EOF
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
if [[ -n "${temp_vault_pass_file}" ]] && [[ -f "${temp_vault_pass_file}" ]]; then
|
||||
rm -f "${temp_vault_pass_file}"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT
|
||||
ansible_extra_args=()
|
||||
terraform_apply_args=()
|
||||
terraform_passthrough=()
|
||||
|
||||
run_ansible=true
|
||||
run_terraform=true
|
||||
|
||||
if [[ "${1:-}" == "--help" ]] || [[ "${1:-}" == "-h" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "${1:-}" == "--no-ansible" ]]; then
|
||||
run_ansible=false
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ "${1:-}" == "--no-terraform" ]] || [[ "${1:-}" == "--ansible-only" ]]; then
|
||||
run_terraform=false
|
||||
shift
|
||||
fi
|
||||
|
||||
if [[ "${1:-}" == "--" ]]; then
|
||||
shift
|
||||
if [[ "${1:-}" == "terraform" ]]; then
|
||||
shift
|
||||
terraform_passthrough=("$@")
|
||||
else
|
||||
case "${1:-}" in
|
||||
output|state|workspace|providers|version|validate|fmt|taint|untaint|graph|show|console|import)
|
||||
terraform_passthrough=("$@")
|
||||
;;
|
||||
*)
|
||||
terraform_apply_args=("$@")
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -f ".env" ]]; then
|
||||
set -a
|
||||
source .env
|
||||
set +a
|
||||
fi
|
||||
|
||||
if [[ "${run_terraform}" == "true" ]]; then
|
||||
if ! command -v terraform >/dev/null 2>&1; then
|
||||
echo "terraform is required (install terraform or run with --no-terraform)" >&2
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${run_ansible}" == "true" ]]; then
|
||||
if ! command -v ansible-playbook >/dev/null 2>&1; then
|
||||
echo "ansible-playbook is required (install ansible or run with --no-ansible)" >&2
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -f "secrets/vault.yml" ]]; then
|
||||
if ! command -v ansible-vault >/dev/null 2>&1; then
|
||||
echo "ansible-vault is required to read secrets/vault.yml" >&2
|
||||
exit 2
|
||||
fi
|
||||
if [[ -f "secrets/.vault_pass" ]]; then
|
||||
vault_args+=(--vault-password-file "secrets/.vault_pass")
|
||||
elif [[ -f ".vault_pass" ]]; then
|
||||
vault_args+=(--vault-password-file ".vault_pass")
|
||||
else
|
||||
read -rsp "Vault password: " vault_password
|
||||
echo
|
||||
temp_vault_pass_file=$(mktemp)
|
||||
chmod 600 "${temp_vault_pass_file}"
|
||||
printf '%s' "${vault_password}" > "${temp_vault_pass_file}"
|
||||
unset vault_password
|
||||
vault_args+=(--vault-password-file "${temp_vault_pass_file}")
|
||||
fi
|
||||
|
||||
if (( ${#vault_args[@]} )); then
|
||||
vault_plain=$(ansible-vault view secrets/vault.yml "${vault_args[@]}")
|
||||
else
|
||||
vault_plain=$(ansible-vault view secrets/vault.yml)
|
||||
fi
|
||||
while IFS= read -r line; do
|
||||
[[ -z "${line}" ]] && continue
|
||||
[[ "${line}" == "---" ]] && continue
|
||||
[[ "${line}" != TF_VAR_*:* ]] && [[ "${line}" != CF_DNS_API_TOKEN:* ]] && [[ "${line}" != CF_ZONE_API_TOKEN:* ]] && [[ "${line}" != S3_ACCESS_KEY_ID:* ]] && [[ "${line}" != S3_SECRET_ACCESS_KEY:* ]] && continue
|
||||
key="${line%%:*}"
|
||||
value="${line#*:}"
|
||||
value="${value# }"
|
||||
[[ -z "${value}" ]] && continue
|
||||
escaped=$(printf '%q' "${value}")
|
||||
eval "export ${key}=${escaped}"
|
||||
done <<< "${vault_plain}"
|
||||
|
||||
if [[ -z "${TF_VAR_cloudflare_api_token:-}" ]] && [[ -n "${CF_DNS_API_TOKEN:-}" ]]; then
|
||||
export TF_VAR_cloudflare_api_token="${CF_DNS_API_TOKEN}"
|
||||
fi
|
||||
|
||||
if [[ -z "${TF_VAR_cloudflare_zone_id:-}" ]] && [[ -n "${CF_ZONE_API_TOKEN:-}" ]]; then
|
||||
export TF_VAR_cloudflare_zone_id="${CF_ZONE_API_TOKEN}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${run_terraform}" == "true" ]]; then
|
||||
terraform -chdir=terraform init
|
||||
|
||||
if (( ${#terraform_passthrough[@]} )); then
|
||||
terraform -chdir=terraform "${terraform_passthrough[@]}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if (( ${#terraform_apply_args[@]} )); then
|
||||
terraform -chdir=terraform apply "${terraform_apply_args[@]}"
|
||||
else
|
||||
terraform -chdir=terraform plan -out=tfplan
|
||||
terraform -chdir=terraform apply tfplan
|
||||
fi
|
||||
|
||||
rm -f terraform/tfplan
|
||||
|
||||
web_ipv4=$(terraform -chdir=terraform output -raw web_ip)
|
||||
web_ipv6=$(terraform -chdir=terraform output -raw web_ipv6)
|
||||
services_ipv4=$(terraform -chdir=terraform output -raw services_ip)
|
||||
|
||||
ssh_user=${TF_VAR_user:-ansible}
|
||||
|
||||
mkdir -p inventory/host_vars
|
||||
|
||||
cat > inventory/hosts.yml <<EOF
|
||||
all:
|
||||
children:
|
||||
web_hosts:
|
||||
hosts:
|
||||
web:
|
||||
ansible_host: ${web_ipv4}
|
||||
ansible_port: ${TF_VAR_ssh_port:-22}
|
||||
ansible_user: ${ssh_user}
|
||||
services_hosts:
|
||||
hosts:
|
||||
services:
|
||||
ansible_host: ${services_ipv4}
|
||||
ansible_port: ${TF_VAR_ssh_port:-22}
|
||||
ansible_user: ${ssh_user}
|
||||
EOF
|
||||
|
||||
cat > inventory/host_vars/web.yml <<EOF
|
||||
public_ipv4: ${web_ipv4}
|
||||
public_ipv6: ${web_ipv6%%/*}
|
||||
EOF
|
||||
else
|
||||
if [[ ! -f inventory/hosts.yml ]]; then
|
||||
echo "inventory/hosts.yml is missing; run without --no-terraform at least once to generate it" >&2
|
||||
exit 2
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${run_ansible}" == "true" ]]; then
|
||||
if [[ -n "${vault_args+x}" ]] && (( ${#vault_args[@]} )); then
|
||||
ansible_extra_args=("${vault_args[@]}")
|
||||
fi
|
||||
ansible-playbook playbooks/services.yml ${ansible_extra_args[@]+"${ansible_extra_args[@]}"}
|
||||
ansible-playbook playbooks/web.yml ${ansible_extra_args[@]+"${ansible_extra_args[@]}"}
|
||||
fi
|
||||
Loading…
Reference in a new issue