Terraform
Terraform is an infrastructure as code tool that provides a cli workflow to mange cloud services. The configurations are defined as declarative and idempotent text files. The state can be managed in shared state files along with concurrency protection.
To allow for easier development, we also use Terragrunt. Terragrunt is a thin wrapper around terraform that provides:
- automated shared state configuration
- DRY project layout
- cross-account support
Getting started
The Povio Terraform Template has examples for several platforms to get you started.
Requirements
Install terraform and terragrunt
OR
Use docker-compose to have a pinned local version of terraform/terragrunt
version: '3'
services:
terragrunt:
image: alpine/terragrunt:0.15.0
command: bash
environment:
# Use .gitignore-d .env instead of this
#AWS_ACCESS_KEY_ID=
#AWS_SECRET_ACCESS_KEY=
#AWS_DEFAULT_REGION=
#AWS_PROFILE=
volumes:
- ./:/apps
# Use environment instead of this
#- ${HOME}/.aws:/root/.aws
#- ${HOME}/.ssh:/root/.ssh
Prepare IAM users
Add a new IAM user with programmatic access and full AdministratorAccess
and name it something like myapp-terraform
.
This used should not be shared or used in CI.
Populate ./aws/config (aws-cli config) with credentials using the profile myapp
[myapp]
region = us-east-1
aws_access_key_id = []
aws_secret_access_key = []
Init Terragrunt for AWS
# /infrastructure/terragrunt.hcl
# default backend
remote_state {
backend = "s3"
config = {
# the AWS local profile
profile = "myapp"
# the bucket to store the state in
bucket = "myapp-terraform-state"
key = "${path_relative_to_include()}/terraform.tfstate"
region = "us-east-1"
encrypt = true
# the dynamodb table for state locking
dynamodb_table = "myapp-terraform-lock"
}
}
# default provider config
generate "provider" {
path = "provider.tf"
if_exists = "overwrite_terragrunt"
contents = <<EOF
provider "aws" {
# only allow deployment on this accountId for safety reason
allowed_account_ids = ["000000000000"]
region = "us-east-1"
profile = "myapp"
}
terraform {
backend "s3" {}
}
EOF
}
At the time of writing, the S3 bucket created by terragrunt will not enable versioning in the
myapp-terraform-state
bucket - it is advised to do so manually.
Read more about managing Terragrunt code here.
.gitignore
While .terraform.lock.hcl needs to be versioned, .terragrunt-cache
is
reproducible and .terraform/
should be handled by terragrunt.
*.auto.tfvars
.terraform/
.terragrunt-cache