Terraform

Terraform is an open-source infrastructure as code software tool that enables you to safely and predictably create, change, and improve infrastructure.

Install terraform: https://developer.hashicorp.com/terraform/downloads

Getting started

terraform init
terraform workspace list
terraform workspace select <workspace>
terraform validate
terraform state list
terraform plan
terraform apply
terraform show
terraform destroy

Debug

terraform console
terraform import aws_<resource>.<name> arn:aws....
terraform state show
terraform state rm aws_<resource>.<name>
TF_LOG=<TRACE|DEBUG|INFO|WARN|ERROR>
TF_LOG_PATH=./tf.log
validation {
   condition = <https://developer.hashicorp.com/terraform/language/expressions/custom-conditions#condition-expressions>
   error_message = "Some message to display"
}

Best Practices

Googles Best Practices

  • Use explicit versions instead of latest or ~> ..
  • Add a Readme.md to each project and module
  • Stay DRY
  • Use descriptive names
  • Plan locally apply from VCS
  • Use workspaces to separate network, middleware, application with read access to upper layer

Git

! Do not commit state files to VCS

Run terraform fmt -recursive before commit.

Add .gitignore:

**/.terraform/*
*.tfstate
*.tfstate.*
*override.tf.*
.terraformrc
terraform.rc
.terraform.lock.hcl

Structure

-- SERVICE-DIRECTORY/
   -- modules/
      -- <service-name>/
         -- main.tf
         -- variables.tf
         -- outputs.tf
         -- provider.tf
         -- README
   -- environments/
      -- dev/
         -- backend.tf
         -- main.tf
      -- prod/
         -- backend.tf
         -- main.tf

! Only use workspaces to keep multiple versions of the same infrastructure like dev,prod or feature based

Separate variables by workspace:

vars.tf # Var definition and defaults for default workspace
workspace1.tfvars
workspace2.tfvars

Use workspace interpolation

terraform workspace select <workspace>
terraform plan -var-file="$(terraform workspace show).tfvars"

State

JFrog Remote State and Locking Provider

terraform {
  backend “remote” {
    hostname = “my_artifactory_domain.org”
    organization = “backend repository name”
    workspaces {
          prefix = “my-prefix-”   
    }
  }
}

Resolve state drift

In the first place terraform makes the assumption of a 1-to-1 mapping of the real world and its state.

This assumption can break in the real world. For example if a service goes down or due to some other automation or manual interactions.

With unchanged sources a terraform plan should result in no actions required.

If there are actions and you know the current sources should definitely match the current state one can follow:

Graph

terraform graph | dot -Tsvg > graph.svg

AWS

https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html

  • Disable root access keys
  • Add MFA device to root account
  • Add admin group and user
  • Use the least privilege model

Generate SSH Key

resource "aws_key_pair" "ssh_keys" {
  for_each = {
    key_name1: "ssh-rsa ..."
  }

  key_name   = each.key
  public_key = each.value
}

Policies

https://docs.aws.amazon.com/IAM/latest/UserGuide/what-is-access-analyzer.html

https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_testing-policies.html

  • Deny always wins over Allow

EKS

Check https://calculator.aws/#/addService

aws eks --region eu-central1 update-kubeconfig --name cluster1
kubectl get svc

VPC

Do not overlap cidr_clocks with other sites or accounts

Internet Gateway

Route Table

ip route add 0.0.0.0 via internet gateway

Subnet

Route Table Association

Security Group

EC2 Instance