Melhores práticas para módulos raiz

Este documento fornece diretrizes e recomendações a serem consideradas ao usar módulos raiz.

As configurações raiz, ou módulos raiz, são os diretórios de trabalho de onde você executa a CLI do Terraform. Verifique se as configurações raiz estão de acordo com os padrões a seguir (e com as diretrizes anteriores do Terraform, quando aplicável). As recomendações explícitas para módulos raiz substituem as diretrizes gerais.

Este guia não é uma introdução ao Terraform. Para uma introdução ao uso do Terraform com o Google Cloud, consulte Primeiros passos com o Terraform.

Minimizar o número de recursos em cada módulo raiz

É importante evitar que uma única configuração raiz fique muito grande, com muitos recursos armazenados no mesmo diretório e estado. Todos os recursos em uma configuração raiz específica são atualizados sempre que o Terraform é executado. Isso pode causar lentidão na execução se muitos recursos estiverem incluídos em um único estado. Uma regra geral: não inclua mais de 100 recursos (e, de preferência, apenas algumas dezenas) em um único estado.

Use diretórios separados para cada app.

Para gerenciar aplicativos e projetos de maneira independente, coloque recursos em cada aplicativo e projeto nos próprios diretórios do Terraform. Um serviço pode representar um aplicativo específico ou um serviço comum, como uma rede compartilhada. Aninhe todo o código do Terraform para um serviço específico em um diretório (incluindo subdiretórios).

Dividir aplicativos em subdiretórios específicos do ambiente

Ao implantar serviços no Google Cloud, divida a configuração do Terraform do serviço em dois diretórios de nível superior: um diretório modules que contém a configuração real do serviço e um diretório environments que contém as configurações raiz de cada ambiente.

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

      -- qa/
         -- backend.tf
         -- main.tf

      -- prod/
         -- backend.tf
         -- main.tf

Usar diretórios de ambiente

Para compartilhar código entre ambientes, faça referência aos módulos. Normalmente, pode ser um módulo de serviço que inclua a configuração base compartilhada do Terraform para o serviço. Nos módulos de serviço, codifique entradas comuns e exija apenas entradas específicas do ambiente como variáveis.

Cada diretório do ambiente precisa conter os seguintes arquivos:

  • Um arquivo backend.tf que declara o local do estado do backend do Terraform (normalmente, Cloud Storage)
  • Um arquivo main.tf que instancia o módulo de serviço

Cada diretório de ambiente (dev, qa, prod) corresponde a um espaço de trabalho do Terraform e implanta uma versão do serviço nesse ambiente. Esses espaços de trabalho isolam recursos específicos do ambiente nos próprios contextos. Use apenas o espaço de trabalho padrão.

Não é recomendado ter vários espaços de trabalho da CLI em um ambiente pelos seguintes motivos:

  • Pode ser difícil inspecionar a configuração em cada espaço de trabalho.
  • Não é recomendado ter um único back-end compartilhado para vários espaços de trabalho porque ele se torna um único ponto de falha se for usado para separação de ambiente.
  • Embora a reutilização de código seja possível, dificulta a leitura do código, que precisa ser alternado com base na variável atual do espaço de trabalho (por exemplo, terraform.workspace == "foo" ? this : that).

Para ver mais informações, consulte os seguintes tópicos:

Expor saídas por estado remoto

Verifique se você está expondo saídas úteis de instâncias de módulo de um módulo raiz.

Por exemplo, o snippet de código a seguir passa pela saída do ID do projeto da instância do módulo de fábrica do projeto como uma saída do módulo raiz.

# Project root module
terraform {
  backend "gcs" {
    bucket  = "BUCKET"
  }
}

module "project" {
  source  = "terraform-google-modules/project-factory/google"
  ...
}

output "project_id" {
  value       = module.project.project_id
  description = "The ID of the created project"
}

Outros ambientes e aplicativos do Terraform podem se referir apenas às saídas raiz no módulo.

Ao usar o estado remoto, é possível referenciar as saídas do módulo raiz. Para permitir o uso por outros aplicativos dependentes para configuração, verifique se você está exportando informações relacionadas aos endpoints de um serviço para o estado remoto.

# Networks root module
data "terraform_remote_state" "network_project" {
  backend = "gcs"

  config = {
    bucket = "BUCKET"
  }
}

module "vpc" {
  source  = "terraform-google-modules/network/google"
  version = "~> 9.0"

  project_id   = data.terraform_remote_state.network_project.outputs.project_id
  network_name = "vpc-1"
  ...
}

Às vezes, por exemplo, ao invocar um módulo de serviço compartilhado a partir de diretórios de ambiente, é adequado exportar novamente todo o módulo filho, da seguinte maneira:

output "service" {
  value       = module.service
  description = "The service module outputs"
}

Fixar em versões secundárias do provedor

Nos módulos raiz, declare cada provedor e fixe em uma versão secundária. Isso permite o upgrade automático para novas versões de patch, mantendo um destino sólido. Para consistência, nomeie o arquivo como versions.tf.

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "~> 4.0.0"
    }
  }
}

Armazenar variáveis em um arquivo tfvars

Para módulos raiz, forneça variáveis usando um arquivo de variáveis .tfvars. Para consistência, nomeie arquivos de variável como terraform.tfvars.

Não especifique variáveis usando opções de linha de comando alternativas var-files ou var='key=val'. As opções da linha de comando são temporárias e fáceis de esquecer. Usar um arquivo de variáveis padrão é mais previsível.

Conferir o arquivo .terraform.lock.hcl

Para módulos raiz, o arquivo de bloqueio de dependência .terraform.lock.hcl precisa ser verificado no controle de origem. Isso permite rastrear e analisar mudanças em seleções de provedores para uma determinada configuração.

A seguir