Este documento fornece recomendações básicas de estilo e estrutura para as suas configurações do Terraform. Estas recomendações aplicam-se a módulos Terraform reutilizáveis e a configurações raiz.
Este guia não é uma introdução ao Terraform. Para uma introdução à utilização do Terraform com o Google Cloud, consulte o artigo Começar a usar o Terraform.
Siga uma estrutura de módulo padrão
- Os módulos do Terraform têm de seguir a estrutura de módulos padrão.
- Comece cada módulo com um ficheiro
main.tf
, onde os recursos estão localizados por predefinição. - Em cada módulo, inclua um ficheiro
README.md
no formato Markdown. No ficheiroREADME.md
, inclua documentação básica sobre o módulo. - Coloque os exemplos numa pasta
examples/
, com um subdiretório separado para cada exemplo. Para cada exemplo, inclua um ficheiroREADME.md
detalhado. - Crie agrupamentos lógicos de recursos com os seus próprios ficheiros e nomes descritivos, como
network.tf
,instances.tf
ouloadbalancer.tf
.- Evite dar a cada recurso o seu próprio ficheiro. Agrupe os recursos de acordo com
o respetivo objetivo partilhado. Por exemplo, combine
google_dns_managed_zone
egoogle_dns_record_set
emdns.tf
.
- Evite dar a cada recurso o seu próprio ficheiro. Agrupe os recursos de acordo com
o respetivo objetivo partilhado. Por exemplo, combine
- No diretório raiz do módulo, inclua apenas ficheiros de metadados do Terraform (
*.tf
) e do repositório (comoREADME.md
eCHANGELOG.md
). - Coloque qualquer documentação adicional numa subdiretoria
docs/
.
Adote uma convenção de nomenclatura
Dê nomes a todos os objetos de configuração usando carateres de sublinhado para delimitar várias palavras. Esta prática garante a consistência com a convenção de nomenclatura para tipos de recursos, tipos de origens de dados e outros valores predefinidos. Esta convenção não se aplica a argumentos de nome.
Recomendado:
resource "google_compute_instance" "web_server" { name = "web-server" }
Não recomendado:
resource "google_compute_instance" "web-server" { name = "web-server" }
Para simplificar as referências a um recurso que é o único do seu tipo (por exemplo, um único equilibrador de carga para um módulo inteiro), atribua o nome
main
ao recurso.- É preciso um esforço mental adicional para se lembrar de
some_google_resource.my_special_resource.id
em comparação comsome_google_resource.main.id
.
- É preciso um esforço mental adicional para se lembrar de
Para distinguir os recursos do mesmo tipo entre si (por exemplo,
primary
esecondary
), indique nomes de recursos significativos.Torne os nomes de recursos singulares.
No nome do recurso, não repita o tipo de recurso. Por exemplo:
Recomendado:
resource "google_compute_global_address" "main" { ... }
Não recomendado:
resource "google_compute_global_address" "main_global_address" { … }
Use variáveis com cuidado
- Declare todas as variáveis em
variables.tf
. - Atribua às variáveis nomes descritivos relevantes para a respetiva utilização ou
finalidade:
- As entradas, as variáveis locais e as saídas que representam valores numéricos, como os tamanhos do disco ou o tamanho da RAM, têm de ter nomes com unidades (como
ram_size_gb
). Google Cloud As APIs não têm unidades padrão, pelo que a atribuição de nomes às variáveis com unidades torna a unidade de entrada esperada clara para os responsáveis pela manutenção da configuração. - Para unidades de armazenamento, use prefixos de unidades binárias (potências de 1024):
kibi
,mebi
,gibi
. Para todas as outras unidades de medida, use prefixos de unidades decimais (potências de 1000):kilo
,mega
egiga
. Esta utilização corresponde à utilização no âmbito do Google Cloud. - Para simplificar a lógica condicional, atribua nomes positivos às variáveis booleanas, por exemplo,
enable_external_access
.
- As entradas, as variáveis locais e as saídas que representam valores numéricos, como os tamanhos do disco ou o tamanho da RAM, têm de ter nomes com unidades (como
- As variáveis têm de 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 contexto adicional para novos programadores que os nomes descritivos não podem fornecer.
- Atribua tipos definidos às variáveis.
- Quando adequado, forneça valores predefinidos:
- Para variáveis que tenham valores independentes do ambiente (como o tamanho do disco), forneça valores predefinidos.
- Para variáveis que tenham valores específicos do ambiente (como
project_id
), não forneça valores predefinidos. Desta forma, o módulo de chamadas tem de fornecer valores significativos.
- Use predefinições vazias para variáveis (como strings ou listas vazias) apenas quando deixar a variável vazia for uma preferência válida que as APIs subjacentes não rejeitam.
- Seja criterioso na utilização de variáveis. Apenas parametrize valores que
tenham de variar para cada instância ou ambiente. Quando decidir se deve expor uma variável, certifique-se de que tem um exemplo de utilização concreto para alterar essa variável. Se existir apenas uma pequena probabilidade de ser necessária uma variável,
não a exponha.
- A adição de uma variável com um valor predefinido é retrocompatível.
- A remoção de uma variável é incompatível com versões anteriores.
- Nos casos em que um literal é reutilizado em vários locais, pode usar um valor local sem o expor como uma variável.
Exponha resultados
- Organize todas as saídas num ficheiro
outputs.tf
. - Forneça descrições significativas para todos os resultados.
- Documentar as descrições de saída no ficheiro
README.md
. Gere automaticamente descrições no commit com ferramentas como o terraform-docs. - Produzir todos os valores úteis que os módulos raiz possam precisar de consultar ou partilhar. Especialmente para módulos de código aberto ou muito usados, exponha todas as saídas que tenham potencial de consumo.
Não transmita resultados diretamente através de variáveis de entrada, porque isso impede que sejam adicionados corretamente ao gráfico de dependências. Para garantir que são criadas dependências implícitas, certifique-se de que as saídas fazem referência a atributos de recursos. Em vez de fazer referência diretamente a uma variável de entrada para uma instância, transmita o atributo da seguinte forma:
Recomendado:
output "name" { description = "Name of instance" value = google_compute_instance.main.name }
Não recomendado:
output "name" { description = "Name of instance" value = var.name }
Use origens de dados
- Coloque as origens de dados junto aos recursos que lhes fazem referência. Por exemplo, se estiver a obter uma imagem a usar no lançamento de uma instância, coloque-a junto à instância em vez de recolher recursos de dados no respetivo ficheiro.
- Se o número de origens de dados aumentar, pondere movê-las para um ficheiro
data.tf
dedicado. - Para obter dados relativos ao ambiente atual, use a interpolação de variáveis ou recursos.
Limite a utilização de scripts personalizados
- Use scripts apenas quando necessário. O estado dos recursos criados através de scripts não é contabilizado nem gerido pelo Terraform.
- Se possível, evite scripts personalizados. Use-as apenas quando os recursos do Terraform não suportarem o comportamento pretendido.
- Todos os scripts personalizados usados têm de ter um motivo claramente documentado para a sua existência e, idealmente, um plano de descontinuação.
- O Terraform pode chamar scripts personalizados através de aprovisionadores, incluindo o aprovisionador local-exec.
- Coloque scripts personalizados chamados pelo Terraform num diretório
scripts/
.
Inclua scripts auxiliares num diretório separado
- Organize os scripts auxiliares que não são chamados pelo Terraform num diretório
helpers/
. - Documente os scripts auxiliares no ficheiro
README.md
com explicações e invocações de exemplo. - Se os scripts auxiliares aceitarem argumentos, forneça verificação de argumentos e
--help
saída.
Coloque ficheiros estáticos num diretório separado
- Os ficheiros estáticos aos quais o Terraform faz referência, mas que não executa (como scripts de inicialização carregados em instâncias do Compute Engine), têm de ser organizados num diretório
files/
. - Coloque HereDocs longos em ficheiros externos, separados do respetivo HCL.
Faça referência a eles com a
função
file()
. - Para ficheiros lidos através da função Terraform
templatefile
, use a extensão de ficheiro.tftpl
.- Os modelos têm de ser colocados num diretório
templates/
.
- Os modelos têm de ser colocados num diretório
Proteja recursos com estado
Para recursos com estado, como bases de dados, certifique-se de que a proteção contra eliminação está ativada. Por exemplo:
resource "google_sql_database_instance" "main" {
name = "primary-instance"
settings {
tier = "D0"
}
lifecycle {
prevent_destroy = true
}
}
Use a formatação integrada
Todos os ficheiros Terraform têm de estar em conformidade com as normas da terraform fmt
.
Limite a complexidade das expressões
- Limite a complexidade de quaisquer expressões interpoladas individuais. Se precisar de muitas funções numa única expressão, considere dividi-la em várias expressões usando valores locais.
- Nunca tenha mais do que uma operação ternária numa única linha. Em alternativa, use vários valores locais para criar a lógica.
Use count
para valores condicionais
Para instanciar um recurso condicionalmente, use o meta-argumento count
.
Por 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
...
}
Use com moderação as variáveis especificadas pelo utilizador para definir a variável count
para recursos. Se for fornecido um atributo de recurso para essa variável (como project_id
) e esse recurso ainda não existir, o Terraform não pode gerar um plano. Em alternativa, o Terraform comunica o erro
value of count cannot be computed
.
Nestes casos, use uma variável enable_x
separada para calcular a lógica condicional.
Use for_each
para recursos iterados
Se quiser criar várias cópias de um recurso com base num recurso de entrada, use o meta-argumento for_each
.
Publique módulos num registo
Módulos reutilizáveis: publique módulos reutilizáveis num registo de módulos.
Módulos de código aberto: publique módulos de código aberto no Terraform Registry.
Módulos privados: publique módulos privados num registo privado.
O que se segue?
- Saiba mais sobre as práticas recomendadas quando usar módulos reutilizáveis.
- Saiba mais sobre as práticas recomendadas quando usar módulos raiz do Terraform.