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/terraform.linux-x86_64 SOPS := $(ROOT_DIR)/out/sops.linux-x86_64 KEYS := \ 6B61ECD76088748C70590D55E90A401336C8AAA9 \ 88823A75ECAA786B0FF38B148E401478A3FBEF72 \ 3D7C8D39E8C4DF771583D3F0A8A091FD346001CA \ F4BF5C81EC78A5DD341C91EEDC4B7D1F52E0BA4D .DEFAULT_GOAL := .PHONY: default default: \ toolchain \ tools \ $(patsubst %,$(KEY_DIR)/%.asc,$(KEYS)) \ $(CACHE_DIR)/website/.well-known/openpgpkey \ 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 \ ' 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" \ ' 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 ../../$< \ > $@ \ ' .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) \ ' $(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