stack/Makefile

182 lines
5.3 KiB
Makefile

include $(PWD)/src/toolchain/Makefile
include $(PWD)/src/make/tools.mk
BACKEND_TF := $(wildcard infra/backend/*.tf)
MAIN_TF := $(wildcard infra/main/*.tf)
ENVIRONMENT := production
REGION := sfo3
ROOT_DIR := $(shell pwd)
# TODO: automatically determine
TERRAFORM := $(ROOT_DIR)/out/tofu.linux-x86_64
SOPS := $(ROOT_DIR)/out/sops.linux-x86_64
KEYS := \
6B61ECD76088748C70590D55E90A401336C8AAA9 \
88823A75ECAA786B0FF38B148E401478A3FBEF72 \
3D7C8D39E8C4DF771583D3F0A8A091FD346001CA \
F4BF5C81EC78A5DD341C91EEDC4B7D1F52E0BA4D
EXTRA_ARGS :=
.DEFAULT_GOAL :=
.PHONY: default
default: \
toolchain \
tools \
apply
.PHONY:
clean:
rm -rf $(CACHE_DIR)
.PHONY:
credentials: \
$(CACHE_DIR)/secrets/credentials.tfvars
.PHONY:
shell: toolchain tools
$(call toolchain," \
HOST_OS=linux \
HOST_ARCH=x86_64 \
PREFIX=.local \
XDG_CONFIG_HOME=/home/build/.config \
make -f src/make/tools.mk tools-install \
&& PS1='build@distrust-stack\\$$ ' bash --norc \
",--interactive)
$(KEY_DIR)/%.asc:
$(call fetch_pgp_key,$(basename $(notdir $@)))
$(OUT_DIR)/website/.well-known/matrix/client \
$(OUT_DIR)/website/.well-known/matrix/server:
mkdir -p $(OUT_DIR)/website/.well-known/matrix
cp -R \
$(SRC_DIR)/well-known/matrix/* \
$(OUT_DIR)/website/.well-known/matrix/
$(OUT_DIR)/website/.well-known/openpgpkey:
$(call toolchain," \
sq wkd \
generate $(OUT_DIR)/website distrust.co \
<(cat $(patsubst %,$(KEY_DIR)/%.asc,$(KEYS))) \
")
$(CACHE_DIR)/website/index.html: \
$(CACHE_DIR)/website/.well-known/openpgpkey \
$(CACHE_DIR)/website/.well-known/matrix/server \
$(CACHE_DIR)/website/.well-known/matrix/client
$(call toolchain," \
cd $(SRC_DIR)/website \
&& jekyll build \
&& cp -R _site/* /home/build/out/website/ \
")
infra/backend/.terraform: \
$(TERRAFORM) \
$(BACKEND_TF)
$(SOPS) exec-env secrets/$(ENVIRONMENT).enc.env '\
env -C infra/backend $(TERRAFORM) init -upgrade \
'
$(SOPS) exec-env secrets/$(ENVIRONMENT).enc.env '\
env -C infra/backend $(TERRAFORM) refresh \
-var environment=$(ENVIRONMENT) \
-var namespace=$(ENVIRONMENT) \
-var region=$(REGION) \
-state $(ENVIRONMENT).tfstate \
'
infra/main/.terraform: | \
$(TERRAFORM) \
config/$(ENVIRONMENT).tfbackend \
$(MAIN_TF)
$(SOPS) exec-env secrets/$(ENVIRONMENT).enc.env '\
env -C infra/main $(TERRAFORM) init -upgrade \
-backend-config="../../config/$(ENVIRONMENT).tfbackend" \
'
$(SOPS) exec-env secrets/$(ENVIRONMENT).enc.env '\
env -C infra/main $(TERRAFORM) refresh \
-var environment=$(ENVIRONMENT) \
-var namespace=$(ENVIRONMENT) \
-var region=$(REGION) \
-state $(ENVIRONMENT).tfstate \
'
infra/backend/$(ENVIRONMENT).tfstate: \
$(TERRAFORM) \
$(SOPS) \
infra/backend/.terraform
$(SOPS) exec-env secrets/$(ENVIRONMENT).enc.env '\
env -C infra/backend \
$(TERRAFORM) apply \
-var environment=$(ENVIRONMENT) \
-var namespace=$(ENVIRONMENT) \
-var region=$(REGION) \
-state $@ \
'
config/$(ENVIRONMENT).tfbackend: | \
$(TERRAFORM) \
$(SOPS) \
# File is not committed and this has no shared state
$(MAKE) infra/backend/$(ENVIRONMENT).tfstate
$(SOPS) exec-env secrets/$(ENVIRONMENT).enc.env '\
env -C infra/backend \
$(TERRAFORM) \
output -state $(ENVIRONMENT).tfstate \
> $@ \
'
$(SOPS) exec-env secrets/$(ENVIRONMENT).enc.env '\
env -C infra/backend \
$(TERRAFORM) refresh \
-var environment=$(ENVIRONMENT) \
-var namespace=$(ENVIRONMENT) \
-var region=$(REGION) \
-state $(ENVIRONMENT).tfstate \
'
.PHONY:
apply: \
$(TERRAFORM) \
$(SOPS) \
infra/main/.terraform
$(call maybe_decrypt_secret,secrets/$(ENVIRONMENT).talosconfig,infra/main/talos/talosconfig)
$(call maybe_decrypt_secret,secrets/$(ENVIRONMENT).kubeconfig,infra/main/talos/kubeconfig)
$(call maybe_decrypt_secret,secrets/$(ENVIRONMENT).controlplane.yaml,infra/main/talos/controlplane.yaml)
$(call maybe_decrypt_secret,secrets/$(ENVIRONMENT).worker.yaml,infra/main/talos/worker.yaml)
$(SOPS) exec-env secrets/$(ENVIRONMENT).enc.env '\
env -C infra/main \
$(TERRAFORM) apply \
-var environment=$(ENVIRONMENT) \
-var namespace=$(ENVIRONMENT) \
-var region=$(REGION) \
$(EXTRA_ARGS) '
$(call maybe_encrypt_secret,infra/main/talos/talosconfig,secrets/$(ENVIRONMENT).talosconfig)
$(call maybe_encrypt_secret,infra/main/talos/kubeconfig,secrets/$(ENVIRONMENT).kubeconfig)
$(call maybe_encrypt_secret,infra/main/talos/controlplane.yaml,secrets/$(ENVIRONMENT).controlplane.yaml)
$(call maybe_encrypt_secret,infra/main/talos/worker.yaml,secrets/$(ENVIRONMENT).worker.yaml)
$(CACHE_DIR)/secrets:
mkdir -p $@
# Note: Decryption MUST reset the mod time to avoid encryption/decryption loops
# Encrypt if:
# - Both files exist, local is newer than remote
# - Only local exists
define maybe_encrypt_secret
test \( -f $(1) -a -f $(2) -a $(1) -nt $(2) \) -o \
\( -f $(1) -a ! -f $(2) \) && \
$(SOPS) --encrypt $(1) > $(2) || true
endef
# Only decrypt when local files don't exist
# Unfortunately, this means we can't decrypt if the secrets update. We can't
# do that because otherwise it creates a loop. The secrets update, therefore we
# decrypt secrets, but because the modtime of the decrypted secrets is newer
# than the encrypted secrets, we want to reencrypt encrypted secrets.
define maybe_decrypt_secret
test -f $(1) -a ! -f $(2) && \
mkdir -p `dirname $(2)` && \
$(SOPS) --decrypt $(1) > $(2) && \
touch -d 1970-01-01 $(2) || \
true
endef