# about me
My name is Fabian Schuh and I am the founder of ChainSquad GmbH. I have a Ph.D. in theoretical communications and am full-time in the web2/web3-space since 2015.
# vision
This page serves as a place to gather personal thoughts and expertise made during my time as freelancer and small business owner. Thoughts are my own, leave them to me!
# disclaimer
Nothing in this site is an offer to sell, or the solicitation of an offer to buy, anything.
# Links
/chainsquad

Dealing with secrets, environment variables and GPG conveniently

20 Aug 2021

This article shows how we make use of environment variables and GPG to easily switch between credentials for various deployments. In our particular case, we have various Hashicorp clusters (nomad, consul, vault, …) deployed and need to be able to switch between them conveniently and securly.

Security

Obviously, access credentials to your cloud orchestration has to be kept confidential. As such, we store our credentials encrypted using gpg/gpg.

Environment Variables

At least on Linux, dealing with credentials is most convenient going through environment variables which are read my most of the tools anyhow.

Example

As an example, here is the content of a GPG encrypted file for one of our environments:

TARGET=[staging|prod|infra]
NOMAD_ADDR=https://nomad.staging.example.com
NOMAD_TOKEN=**************************
VAULT_ADDR=https://vault.staging.example.com
VAULT_TOKEN=**************************
CONSUL_HTTP_ADDR=https://consul.staging.example.com
CONSUL_HTTP_AUTH=**************************
MC_HOST_infra=https://username:**************************@minio.staging.example.com
TF_VAR_hcloud_token=**************************

As you can see, we use a variable TARGET to identify which environment we are working with (dev, staging, prod, infra).

The content of the file is encrypted using:

gpg -sear Fabian -o
~/Documents/Encrypted/Environments/staging.example.com.gpg

At this place, let me recommend the vim-plugin jamessan/vim-gnupg which takes care of editing the file afterwards.

Loading Function

For easy loading of your encrypted environment variables, I wrote a shell (zsh) script:

def loadenv() {
  export $(gpg -d ~/Documents/Encrypted/Environments/$1.gpg | xargs -0)
}

Usage

In case i need to load environment, all I need to do is:

loadenv staging.example.com

and i get all the variables loaded and ready to go.

Bonus Material

Since we make heavy use of make, here are a few snippets that are useful in your Makefile:

ifndef NOMAD_TOKEN
$(error NOMAD_TOKEN required!)
endif

ifndef VAULT_TOKEN
$(error VAULT_TOKEN required!)
endif

ifndef TARGET
$(error TARGET ['staging','prod', 'infra'] required!)
endif
.PHONY: tunnel
tunnel:
ifeq ($(TARGET), infra)
		ssh -N -f -L 4646:10.0.4.2:4646 root@machine1
		ssh -N -f -L 8200:10.0.4.2:8200 root@machine1
		ssh -N -f -L 8500:localhost:8500 root@machine1
endif
ifeq ($(TARGET), staging)
		ssh -N -f -L 4646:10.1.0.4:4646 root@machine2
		ssh -N -f -L 8200:10.1.0.2:8200 root@machine2
		ssh -N -f -L 8500:localhost:8500 root@machine2
endif

And for terraform:

set_consul: clean
	CONSUL_ADDRESS="$(CONSUL_ADDRESS)" envsubst < terraform.tf.template > terraform.tf

set_workspace:
	terraform workspace select $(TARGET)

init: set_consul
	terraform init -var-file $(TARGET).tfvars
	([[ -z "`terraform workspace list | grep $(TARGET)`" ]] && terraform workspace new $(TARGET)) || exit 0

plan: set_workspace
	terraform plan -var-file $(TARGET).tfvars

apply: set_workspace
	terraform apply -var-file $(TARGET).tfvars