Skip to content

Infrastructure: Terraform

Terraform logo

The infrastructure will be controlled using Terraform, rather than via any GUI or direct CLI usage as this ensures that any changes to the infrastructure will be recorded in the repository and hence the infrastructure can be recreated at any time. To install Terraform,

Run this command any location

brew install terraform

which installed 0.13.5.

As with the frontend and backend we'll separate the infrastructure code into a infrastructure folder,

tozo
├── backend
│   └── ...
├── frontend
│   └── ...
└── infrastructure

Secrets management

Ansible logo

Terraform needs accress to, and the ability to store, secrets in order to correctly manage the infrastructure. Storing these secrets directly in the repository is a security risk as anyone who can access the repository has access to the secrets. To avoid this I use Ansible-vault to encrypt the secrets and Terraform's state.

First lets install Ansible-vault using pip, (pip is available after you install Python),

Run this command in infrastructure/

pip install ansible-vault

which can be used to encrypt any files that contain secrets with only the encrypted files should be committed to the repository and shared with others. Ansible-vault requires a password/encryption-key to run, which you should keep safe and only share with people who need to use Terraform. We'll store this password in infrastructure/.ansible-vault and inform ansible it is stored there by adding the following to infrastructure/ansible.cg,

[defaults]
vault_password_file = .ansible-vault

Terraform saves its state including secrets in terraform.tfstate and terraform.tfstate.backup so these will need to be encrypted. We will also use a secrets.auto.tfvars file to store all the secrets used as variables in the Terraform scripts. This file is automatically read by Terraform whenever you issue a Terraform command. So it must also be encrypted,

Run these commands in infrastructure/

ansible-vault encrypt secrets.auto.tfvars --output=secrets.auto.tfvars.vault
ansible-vault encrypt terraform.tfstate --output=terraform.tfstate.vault

and to decrypt,

Note

This commands won't work at yet as we haven't created the infrastructure/secrets.auto.tfvars and terraform hasn't created a infrastructure/terraform.tfstate file.

Run these commands in infrastructure/

ansible-vault decrypt secrets.auto.tfvars.vault --output=secrets.auto.tfvars
ansible-vault decrypt terraform.tfstate.vault --output=terraform.tfstate

For further protection and peace of mind I add the following to a .gitignore file in the infrastructure folder,

.ansible-vault
secrets.auto.tfvars
terraform.tfstate
*.backup
.terraform.lock.hcl
.terraform/

to ensure that I never accidentally commit these secrets to the repository.