Este documento fornece recomendações básicas de estilo e estrutura para suas configurações do Terraform. Essas recomendações se aplicam a módulos reutilizáveis do Terraform e a configurações raiz.
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.
Seguir uma estrutura de módulos padrão
- Os módulos do Terraform precisam seguir a estrutura padrão do módulo.
- Inicie cada módulo com um arquivo
main.tf
, em que os recursos estão localizados por padrão. - Em todos os módulos, inclua um arquivo
README.md
no formato Markdown. No arquivoREADME.md
, inclua a documentação básica sobre o módulo. - Coloque exemplos em uma pasta
examples/
, com um subdiretório separado para cada exemplo. Para cada exemplo, inclua um arquivoREADME.md
detalhado. - Crie agrupamentos lógicos de recursos com os próprios arquivos e
nomes descritivos, como
network.tf
,instances.tf
ouloadbalancer.tf
.- Evite dar a cada recurso o próprio arquivo. Agrupe recursos
por finalidade compartilhada. Por exemplo, combine
google_dns_managed_zone
egoogle_dns_record_set
emdns.tf
.
- Evite dar a cada recurso o próprio arquivo. Agrupe recursos
por finalidade compartilhada. Por exemplo, combine
- No diretório raiz do módulo, inclua apenas o Terraform
(
*.tf
) e os arquivos de metadados do repositório (comoREADME.md
eCHANGELOG.md
). - Coloque qualquer documentação adicional em um subdiretório
docs/
.
Adotar uma convenção de nomenclatura
Nomeie todos os objetos de configuração usando sublinhados para delimitar várias palavras. Essa prática garante consistência com a convenção de nomenclatura para os tipos de recursos, tipos de fonte de dados e outros valores predefinidos. Essa convenção não se aplica a argumentos de nome.
Recomendação:
resource "google_compute_instance" "web_server" { name = "web-server" }
Não recomendado:
resource "google_compute_instance" "web-server" { name = "web-server" }
Para simplificar referências a um recurso que é o único do tipo (por exemplo, um único balanceador de carga para um módulo inteiro), nomeie o
main
do recurso.- É preciso pensar mais para
se lembrar de
some_google_resource.my_special_resource.id
em vez desome_google_resource.main.id
.
- É preciso pensar mais para
se lembrar de
Para diferenciar os recursos de um mesmo tipo (por exemplo,
primary
esecondary
), forneça nomes de recursos significativos.Os nomes dos recursos precisam estar no singular.
No nome do recurso, não repita o tipo de recurso. Exemplo:
Recomendação:
resource "google_compute_global_address" "main" { ... }
Não recomendado:
resource "google_compute_global_address" "main_global_address" { … }
Use as variáveis com cuidado
- Declare todas as variáveis em
variables.tf
. - Dê nomes descritivos às variáveis que sejam relevantes para o uso ou
propósito:
- Entradas, variáveis locais e saídas que representam valores numéricos,
como tamanhos de disco ou de RAM, precisam ser nomeados com
unidades (como
ram_size_gb
). As APIs do Google Cloud não têm unidades padrão. Portanto, a nomeação de variáveis com unidades deixa a unidade de entrada esperada clara para os administradores de configuração. - Para unidades de armazenamento, use prefixos de unidade binária (poderes de 1.024):
kibi
,mebi
,gibi
. Para todas as outras unidades de medida, use prefixos de unidade decimal (capacidades de 1.000):kilo
,mega
,giga
. Esse uso corresponde ao uso no Google Cloud. - Para simplificar a lógica condicional, dê nomes positivos às variáveis booleanas (por exemplo,
enable_external_access
).
- Entradas, variáveis locais e saídas que representam valores numéricos,
como tamanhos de disco ou de RAM, precisam ser nomeados com
unidades (como
- As variáveis precisam ter descrições. As descrições são incluídas automaticamente na documentação gerada automaticamente de um módulo publicado. As descrições adicionam mais contexto aos novos desenvolvedores que nomes descritivos não podem fornecer.
- Dê tipos definidos às variáveis.
- Quando apropriado, forneça valores padrão:
- No caso de variáveis que tenham valores independentes de ambiente (como tamanho do disco), forneça valores padrão.
- Para variáveis que tenham valores específicos do ambiente (como
project_id
), não forneça valores padrão. Dessa forma, o módulo de chamada precisa fornecer valores significativos.
- Use padrões vazios para variáveis (como strings ou listas vazias) somente quando deixar a variável vazia é uma preferência válida que as APIs subjacentes não rejeitam.
- Tenha bom senso ao usar variáveis. Apenas parametrize valores que
precisam variar para cada instância ou ambiente. Ao decidir se quer expor uma variável, verifique se você tem um caso de uso concreto para alterá-la. Se houver apenas uma pequena chance de que uma variável seja necessária,
não a exponha.
- Adicionar uma variável com um valor padrão é compatível com versões anteriores.
- A remoção de uma variável é incompatível com versões anteriores.
- Nos casos em que um literal é reutilizado em vários lugares, é possível usar um valor local sem expô-lo como uma variável.
Expor saídas
- Organize todas as saídas em um arquivo
outputs.tf
. - Forneça descrições significativas para todas as saídas.
- Descrições de saída do documento no arquivo
README.md
. Gerar descrições automaticamente na confirmação com ferramentas como terraform-docs. - Mostra todos os valores úteis que os módulos raiz podem precisar para consultar ou compartilhar. Especialmente para módulos de código aberto ou muito usados, exponha todas as saídas que têm potencial de consumo.
Não transmita saídas diretamente por meio de variáveis de entrada, porque isso impede que elas sejam adicionadas corretamente ao gráfico de dependência. Para garantir que as dependências implícitas sejam criadas, verifique se a saída tem atributos de referência de recursos. Em vez de referenciar diretamente uma variável de entrada para uma instância, transmita o atributo conforme mostrado aqui:
Recomendação:
output "name" { description = "Name of instance" value = google_compute_instance.main.name }
Não recomendado:
output "name" { description = "Name of instance" value = var.name }
Usar fontes de dados
- Coloque fontes de dados ao lado dos recursos que fazem referência a elas. Por exemplo, se você estiver buscando uma imagem para usar na inicialização de uma instância, coloque-a ao lado da instância em vez de coletar os recursos de dados no próprio arquivo.
- Se o número de fontes de dados ficar grande, mova-as para um
arquivo
data.tf
dedicado. - Para buscar dados relativos ao ambiente atual, use a interpolação de variáveis ou recursos.
Limitar o uso de scripts personalizados
- Use scripts somente quando necessário. O estado dos recursos criados
por scripts não é contabilizado ou gerenciado pelo Terraform.
- Evite scripts personalizados, se possível. Use-os somente quando os recursos do Terraform não forem compatíveis com o comportamento desejado.
- Todos os scripts personalizados precisam ter um motivo claramente documentado para um plano de suspensão de uso atual e idealmente.
- O Terraform pode chamar scripts personalizados por meio de provisionamentos, incluindo o provisionamento local-exec.
- Coloque scripts personalizados chamados pelo Terraform em um diretório
scripts/
.
Incluir scripts auxiliares em um diretório separado
- Organize scripts auxiliares que não são chamados pelo Terraform em um
diretório
helpers/
. - Documente os scripts auxiliares no arquivo
README.md
com explicações e invocações de exemplo. - Se os scripts auxiliares aceitarem argumentos, forneça verificação de argumentos e
saída de
--help
.
Colocar arquivos estáticos em um diretório separado
- Os arquivos estáticos referenciados pelo Terraform, mas não executados (como
scripts de inicialização carregados em instâncias do Compute Engine) precisam ser organizados
em um diretório
files/
. - Coloque arquivos longos do HereDocs em arquivos externos, separados dos arquivos HCL.
Faça referência a eles com a
função
file()
. - Para arquivos lidos com a função
templatefile
do Terraform, use a extensão de arquivo.tftpl
.- Os modelos precisam ser colocados em um diretório
templates/
.
- Os modelos precisam ser colocados em um diretório
Proteger recursos com estado
Para recursos com estado, como bancos de dados, verifique se a proteção contra exclusão está ativada. Exemplo:
resource "google_sql_database_instance" "main" {
name = "primary-instance"
settings {
tier = "D0"
}
lifecycle {
prevent_destroy = true
}
}
Usar a formatação integrada
Todos os arquivos do Terraform precisam estar em conformidade com os padrões de terraform fmt
.
Limitação da complexidade das expressões
- Limite a complexidade de expressões interpoladas individuais. Se muitas funções forem necessárias em uma única expressão, considere dividi-la em várias expressões usando valores locais.
- Nunca tenha mais de uma operação ternária em uma única linha. Em vez disso, use vários valores locais para criar a lógica.
Usar count
para valores condicionais
Para instanciar um recurso condicionalmente, use o
meta-argumento count
.
Exemplo:
variable "readers" {
description = "..."
type = list
default = []
}
resource "resource_type" "reference_name" {
// Do not create this resource if the list of readers is empty.
count = length(var.readers) == 0 ? 0 : 1
...
}
Tenha moderação ao usar variáveis especificadas pelo usuário para definir a variável count
para recursos. Se um atributo de recurso for fornecido para essa variável (como
project_id
) e esse recurso ainda não existir, o Terraform não poderá
gerar um plano. Em vez disso, o Terraform informa o erro
value of count cannot be computed
.
Nesses casos, use uma variável enable_x
separada para calcular a
lógica condicional.
Usar for_each
para recursos iterados
Se você quiser criar várias cópias de um recurso com base em um recurso de entrada,
use o
meta-argumento
for_each
.
Publicar módulos em um registro
Módulos reutilizáveis: publique módulos reutilizáveis em um registro de módulos.
Módulos de código aberto: publique módulos de código aberto no Registro do Terraform.
Módulos privados: publique módulos particulares em um registro particular.
A seguir
- Saiba mais sobre as práticas recomendadas ao usar módulos reutilizáveis.
- Saiba mais sobre as práticas recomendadas ao usar módulos raiz do Terraform.