DevTools

Cheatsheet Terraform

Infraestrutura como código para provisionar cloud e serviços

Voltar às linguagens
Terraform
34 cards encontrados
Categorias:
Versões:

CLI


5 cards
Inicializar
terraform init
terraform init -upgrade
terraform init -backend=false

Inicializar diretório e providers.

Output e inspeção
terraform output
terraform output ip_publico
terraform show
terraform state list

Ver outputs e estado atual.

Plan e Apply
terraform plan
terraform plan -out=plano.tfplan
terraform apply
terraform apply plano.tfplan
terraform apply -auto-approve

Prever e aplicar mudanças.

Destruir
terraform destroy
terraform destroy -target=aws_instance.web
terraform destroy -auto-approve

Remover toda a infraestrutura.

Formatação e validação
terraform fmt
terraform fmt -check
terraform validate
terraform plan -detailed-exitcode

Formatar e validar código.

HCL e Blocos


4 cards
Estrutura de ficheiros
main.tf       # recursos principais
variables.tf  # variáveis de input
outputs.tf    # outputs
providers.tf  # configuração providers
terraform.tfvars # valores
modules/      # módulos reutilizáveis

Organização de projeto.

Tipos de dados
string  = "texto"
number  = 42
bool    = true
list    = ["a", "b", "c"]
map     = { key = "value" }
object  = { name = "x", port = 80 }
tuple   = [1, "dois", true]

Tipos disponíveis em HCL.

Expressões
var.nome
local.config
resource.tipo.nome.atributo
data.tipo.nome.atributo
module.nome.output
terraform.workspace

Referências a valores.

Blocos dinâmicos
dynamic "ingress" {
  for_each = var.ports
  content {
    from_port   = ingress.value
    to_port     = ingress.value
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Gerar blocos repetidos.

Resources


5 cards
Definir recurso
resource "aws_instance" "web" {
  ami           = "ami-12345"
  instance_type = "t3.micro"

  tags = {
    Name = "Servidor Web"
  }
}

Criar recurso de infraestrutura.

Lifecycle
resource "aws_instance" "web" {
  # ...
  lifecycle {
    create_before_destroy = true
    prevent_destroy       = true
    ignore_changes       = [tags]
  }
}

Controlar ciclo de vida.

Data sources
data "aws_ami" "ubuntu" {
  most_recent = true
  owners     = ["099720109477"]

  filter {
    name   = "name"
    values = ["ubuntu-*-22.04-*"]
  }
}

Ler dados existentes.

Dependências
resource "aws_instance" "app" {
  # dependência implícita
  subnet_id = aws_subnet.main.id

  # dependência explícita
  depends_on = [aws_iam_role.app]
}

Ordem de criação.

for_each e count
resource "aws_instance" "servers" {
  for_each = toset(["web", "api", "db"])
  instance_type = "t3.micro"
  tags = { Name = each.value }
}

resource "aws_subnet" "sub" {
  count = 3
  cidr_block = "10.0.${count.index}.0/24"
}

Criar múltiplas instâncias.

Variáveis e Outputs


4 cards
Definir variáveis
variable "instance_type" {
  description = "Tipo de instância"
  type        = string
  default     = "t3.micro"
}

variable "ports" {
  type = list(number)
  default = [80, 443]
}

Inputs do módulo/projeto.

Validation
variable "env" {
  type = string
  validation {
    condition = contains(
      ["dev", "staging", "prod"],
      var.env)
    error_message = "Env inválido."
  }
}

Validar inputs.

Outputs
output "ip_publico" {
  description = "IP do servidor"
  value       = aws_instance.web.public_ip
}

output "config" {
  value      = aws_instance.web
  sensitive = true
}

Exportar valores.

Locals
locals {
  nome_projeto = "minha-app"
  tags_comuns = {
    Project = local.nome_projeto
    Env     = var.ambiente
  }
  subnets = [
    for i in range(3) :
    "10.0.${i}.0/24"
  ]
}

Valores calculados internos.

Módulos


4 cards
Usar módulo
module "vpc" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "5.0.0"

  name = "minha-vpc"
  cidr = "10.0.0.0/16"
  azs  = ["eu-west-1a", "eu-west-1b"]
}

Usar módulo do registry.

Módulo local
module "app" {
  source = "./modules/app"

  nome          = "web"
  instance_type = "t3.small"
  subnet_id     = module.vpc.private_subnets[0]
}

Módulo local personalizado.

Criar módulo
# modules/app/main.tf
variable "nome" { type = string }
variable "instance_type" { type = string }

resource "aws_instance" "this" {
  instance_type = var.instance_type
}

output "id" {
  value = aws_instance.this.id
}

Estrutura de um módulo.

Fontes de módulos
source = "./modules/local"
source = "terraform-aws-modules/vpc/aws"
source = "github.com/user/repo//dir"
source = "s3::https://s3-eu-west-1.amazonaws.com/bucket/modulo.zip"
source = "git::https://github.com/user/repo.git?ref=v1.0"

Origens disponíveis.

State


4 cards
Comandos de state
terraform state list
terraform state show aws_instance.web
terraform state mv old new
terraform state rm aws_instance.web
terraform state pull > backup.json

Gerir o estado.

Backend remoto (S3)
terraform {
  backend "s3" {
    bucket          = "meu-tf-state"
    key            = "prod/terraform.tfstate"
    region          = "eu-west-1"
    dynamodb_table  = "tf-locks"
    encrypt         = true
  }
}

Estado partilhado com locking.

Importar recursos
terraform import aws_instance.web i-12345

# ou com bloco import (TF 1.5+):
import {
  to = aws_instance.web
  id = "i-12345"
}

Adotar recursos existentes.

Refresh e taint
terraform refresh
terraform apply -refresh-only
terraform taint aws_instance.web
terraform untaint aws_instance.web

Sincronizar e marcar para recriar.

Providers


4 cards
Configurar provider
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "eu-west-1"
}

Definir provider e versão.

Múltiplos providers
provider "aws" {
  region = "eu-west-1"
}

provider "aws" {
  alias  = "us"
  region = "us-east-1"
}

resource "aws_instance" "dr" {
  provider = aws.us
}

Usar várias regiões/contas.

Versão do Terraform
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    aws    = { version = "~> 5.0" }
    random = { version = "~> 3.5" }
  }
}

Fixar versões.

Providers comuns
hashicorp/aws
hashicorp/azurerm
hashicorp/google
hashicorp/kubernetes
hashicorp/helm
hashicorp/null   (provisioners)
hashicorp/random

Providers populares.

Avançado


4 cards
Workspaces
terraform workspace list
terraform workspace new staging
terraform workspace select prod
terraform workspace show

# usar em código:
name = "${terraform.workspace}-app"

Ambientes isolados.

Funções úteis
join("-", ["a", "b"])     # "a-b"
lookup(map, key, default)
merge(map1, map2)
length(list)
format("%s-%s", a, b)
try(expr, fallback)
coalesce(a, b, c)

Funções de manipulação.

Provisioners
resource "aws_instance" "web" {
  # ...
  provisioner "remote-exec" {
    inline = [
      "sudo apt update",
      "sudo apt install -y nginx"
    ]
  }
  connection {
    type        = "ssh"
    user        = "ubuntu"
    private_key = file("~/.ssh/id_rsa")
  }
}

Executar após criação.

Boas práticas
# • Usar remote state com locking
# • Módulos pequenos e reutilizáveis
# • Variáveis com description e type
# • terraform fmt + validate no CI
# • Nunca commitar .tfstate
# • Usar versões fixas de providers
# • Separar por ambiente (workspaces ou dirs)

Recomendações de uso.