Como usar o Gruntwork para módulos Terraform corporativos reutilizáveis

1. Introdução ao Gruntwork e sua proposta de valor corporativo

1.1. O problema da reutilização em infraestrutura como código (IaC) em escala

Empresas que adotam Terraform em escala rapidamente enfrentam um problema crítico: a duplicação de código. Equipes diferentes criam módulos similares para VPC, EKS, RDS, cada um com suas próprias convenções, níveis de segurança e qualidade. O resultado é uma infraestrutura inconsistente, difícil de auditar e propensa a erros de configuração. O Gruntwork surge como resposta a esse desafio, oferecendo uma biblioteca de módulos Terraform testados em produção e prontos para uso corporativo.

1.2. O que é o Gruntwork: biblioteca, padrões e práticas de produção

Gruntwork é uma plataforma que fornece mais de 300 módulos Terraform prontos para produção, cobrindo desde serviços fundamentais (VPC, IAM, RDS) até soluções complexas (Kubernetes, CI/CD, segurança). Cada módulo segue padrões rigorosos de nomenclatura, documentação e testes, permitindo que equipes de infraestrutura adotem práticas de engenharia de software — versionamento semântico, testes automatizados, revisão de código — em seus pipelines de infraestrutura.

1.3. Comparação com módulos Terraform públicos e abordagens caseiras

Diferente de módulos públicos no Terraform Registry, que muitas vezes carecem de manutenção consistente ou cobertura de testes, os módulos Gruntwork são mantidos profissionalmente, com atualizações regulares e suporte a breaking changes documentado. Comparado a abordagens caseiras, o Gruntwork elimina o custo de desenvolver e testar internamente cada módulo, reduzindo o tempo de entrega de semanas para horas.

2. Estrutura e organização dos módulos Gruntwork

2.1. O padrão de módulos aninhados e a separação por serviço

Cada módulo Gruntwork segue uma estrutura consistente. Por exemplo, o módulo terraform-aws-vpc contém submódulos para sub-redes públicas/privadas, NAT gateways, VPC endpoints e flow logs. A separação por serviço permite que você componha infraestruturas complexas combinando módulos menores e reutilizáveis.

terraform-aws-vpc/
├── modules/
│   ├── vpc-baseline/
│   ├── vpc-peering/
│   └── vpc-flow-logs/
├── examples/
├── test/
└── variables.tf

2.2. Convenções de nomenclatura, entradas e saídas padronizadas

Todos os módulos Gruntwork seguem convenções rígidas. Variáveis usam snake_case, com descrições obrigatórias e valores padrão seguros. Outputs seguem o mesmo padrão, facilitando a composição entre módulos. Um exemplo típico de variável:

variable "vpc_name" {
  description = "Nome da VPC, usado para tagging e naming"
  type        = string
  default     = "main"
}

variable "enable_nat_gateway" {
  description = "Habilitar NAT Gateway para sub-redes privadas"
  type        = bool
  default     = true
}

2.3. Como versionar e gerenciar dependências entre módulos Gruntwork

O Gruntwork utiliza versionamento semântico (MAJOR.MINOR.PATCH). Módulos dependentes referenciam versões específicas via source URLs. Para gerenciar dependências em escala, recomenda-se usar um arquivo versions.tf centralizado:

terraform {
  required_version = ">= 1.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

3. Configuração inicial e integração com o Terraform

3.1. Instalação do Gruntwork CLI e configuração do terraform-baseline

O primeiro passo é instalar o Gruntwork CLI e configurar o módulo terraform-baseline, que estabelece configurações fundamentais como região padrão, tags obrigatórias e políticas de segurança.

# Instalação via script oficial
curl -fsSL https://raw.githubusercontent.com/gruntwork-io/gruntwork-installer/master/bootstrap-gruntwork-installer.sh | bash

# Inicialização do baseline
gruntwork init --module terraform-baseline --version v0.5.0

3.2. Como referenciar módulos Gruntwork a partir de um repositório corporativo

Para usar módulos Gruntwork em seu repositório, utilize a sintaxe de source com referência ao repositório Git e tag específica:

module "vpc" {
  source = "git::git@github.com:gruntwork-io/terraform-aws-vpc.git//modules/vpc-baseline?ref=v0.22.0"

  vpc_name = "production-vpc"
  cidr_block = "10.0.0.0/16"
  # demais variáveis...
}

3.3. Uso de terragrunt como orquestrador para evitar duplicação de código

O Terragrunt, ferramenta complementar ao Gruntwork, permite gerenciar múltiplos módulos com configurações DRY (Don't Repeat Yourself). Um arquivo terragrunt.hcl típico:

terraform {
  source = "git::git@github.com:gruntwork-io/terraform-aws-vpc.git//modules/vpc-baseline?ref=v0.22.0"
}

inputs = {
  vpc_name = local.environment_vars.locals.vpc_name
  cidr_block = "10.0.0.0/16"
}

locals {
  environment_vars = read_terragrunt_config(find_in_parent_folders("env.hcl"))
}

4. Personalização e extensão de módulos Gruntwork

4.1. Sobrescrita de variáveis padrão e uso de locals para adaptação corporativa

Você pode personalizar módulos sem modificá-los diretamente, usando variáveis e locals:

locals {
  common_tags = {
    Environment = var.environment
    ManagedBy   = "Gruntwork"
    CostCenter  = var.cost_center
  }
}

module "vpc" {
  source = "git::git@github.com:gruntwork-io/terraform-aws-vpc.git//modules/vpc-baseline?ref=v0.22.0"
  vpc_name = var.vpc_name
  tags     = local.common_tags
}

4.2. Criação de módulos wrapper que encapsulam múltiplos módulos Gruntwork

Para cenários complexos, crie módulos wrapper que combinam vários módulos Gruntwork:

module "vpc" {
  source = "./modules/vpc-wrapper"
  environment = var.environment
  vpc_cidr    = var.vpc_cidr
}

module "rds" {
  source = "./modules/rds-wrapper"
  vpc_id = module.vpc.vpc_id
  database_name = var.database_name
}

4.3. Como adicionar políticas de compliance e tags obrigatórias sem modificar o upstream

Use o módulo terraform-aws-compliance-policies para aplicar regras de compliance automaticamente:

module "compliance" {
  source = "git::git@github.com:gruntwork-io/terraform-aws-compliance-policies.git//modules/iam-policies?ref=v0.10.0"

  require_encryption_at_rest = true
  require_encryption_in_transit = true
  allowed_regions = ["us-east-1", "eu-west-1"]
}

5. Boas práticas de segurança e governança com Gruntwork

5.1. Utilização dos módulos de segurança prontos para auditoria

Os módulos de segurança do Gruntwork seguem padrões como CIS Benchmarks e NIST. Exemplo de uso do módulo terraform-aws-security:

module "security_groups" {
  source = "git::git@github.com:gruntwork-io/terraform-aws-security.git//modules/security-group-rules?ref=v0.50.0"

  vpc_id = module.vpc.vpc_id
  allow_ssh_from_security_groups = [module.bastion.security_group_id]
}

5.2. Integração com pipelines de CI/CD para validação de mudanças

Configure pipelines que executem terraform plan e terratest antes de aplicar mudanças:

# Exemplo de comando em pipeline CI/CD
gruntwork validate --module-path ./modules/vpc-wrapper
terratest --test-dir ./test --terraform-dir ./environments/prod

5.3. Como aplicar o princípio do menor privilégio usando os padrões Gruntwork

Use o módulo terraform-aws-iam-policies para criar políticas granulares:

module "iam_policies" {
  source = "git::git@github.com:gruntwork-io/terraform-aws-iam-policies.git//modules/iam-policies?ref=v0.40.0"

  allow_ec2_read_only = true
  allow_s3_read_only  = true
  allow_rds_read_only = true
}

6. Gerenciamento de estado remoto e ambientes com Gruntwork

6.1. Configuração de backends S3 e DynamoDB via módulo terraform-aws-state

O módulo terraform-aws-state configura automaticamente o backend remoto:

module "state_backend" {
  source = "git::git@github.com:gruntwork-io/terraform-aws-state.git//modules/state-backend?ref=v0.15.0"

  bucket_name = "my-company-terraform-state"
  dynamodb_table_name = "terraform-locks"
  region = "us-east-1"
}

6.2. Estratégia de workspaces e diretórios por ambiente

Organize seus ambientes com diretórios separados e arquivos de configuração específicos:

environments/
├── dev/
│   └── terragrunt.hcl
├── staging/
│   └── terragrunt.hcl
└── prod/
    └── terragrunt.hcl

6.3. Uso de terragrunt para gerenciar dependências entre módulos em múltiplos ambientes

O Terragrunt permite definir dependências explícitas entre módulos:

dependency "vpc" {
  config_path = "../vpc"
}

dependency "rds" {
  config_path = "../rds"
}

inputs = {
  vpc_id = dependency.vpc.outputs.vpc_id
  rds_endpoint = dependency.rds.outputs.endpoint
}

7. Manutenção, atualização e troubleshooting de módulos Gruntwork

7.1. Como lidar com breaking changes entre versões de módulos Gruntwork

Sempre consulte o changelog oficial antes de atualizar. Use versionamento explícito e teste em ambiente de staging:

# Verificar mudanças entre versões
gruntwork module diff --module terraform-aws-vpc --from v0.21.0 --to v0.22.0

7.2. Estratégia de testes unitários e de integração com terratest

O Terratest é a ferramenta oficial para testar módulos Gruntwork:

package test

import (
    "testing"
    "github.com/gruntwork-io/terratest/modules/terraform"
)

func TestVPCBaseline(t *testing.T) {
    terraformOptions := &terraform.Options{
        TerraformDir: "../examples/vpc-baseline",
    }
    defer terraform.Destroy(t, terraformOptions)
    terraform.InitAndApply(t, terraformOptions)
}

7.3. Logs, debugging e resolução de conflitos de dependências

Para debugging, ative logs detalhados:

export TF_LOG=DEBUG
export GRUNTWORK_LOG_LEVEL=debug
terragrunt apply

Conflitos de dependência geralmente ocorrem devido a versões incompatíveis de providers. Use o comando terraform providers para diagnosticar:

terraform providers
# Verifique se todas as versões são compatíveis

Referências