Convenções de nomenclatura

Convenções gerais

Não deve haver razão alguma para não seguir pelo menos essas convenções :)
Esteja ciente de que os recursos reais da núvem geralmente têm restrições em nomes permitidos. Alguns recursos, por exemplo, não podem conter travessões, alguns devem ser em caixa de camelo (mais conhecido como CamelCase). As convenções neste livro referem-se aos próprios nomes do Terraform.
  1. 1.
    Utilize _ (subtraço) ao invés do - (traço) em todo o lugar (nomes de recursos, nomes de fontes de dados, nomes de variáveis, outputs, etc.).
  2. 2.
    Prefira usar letras minúsculas e números (mesmo que o UTF-8 seja suportado).

Argumentos de recursos e fontes de dados

  1. 1.
    Não repita a categoria de recurso no nome do recurso (não parcialmente, nem completamente):
    resource "aws_route_table" "public" {}
    resource "aws_route_table" "public_route_table" {}
    resource "aws_route_table" "public_aws_route_table" {}
  2. 2.
    O nome do recurso deve ser nomeado this se não houver mais um nome descritivo e geral disponível ou se o módulo de recurso criar um único recurso desse tipo (por exemplo, no módulo AWS VPC há um único recurso do tipo aws_nat_gateway e vários recursos do tupoaws_route_table, então aws_nat_gatewaydeve ser nomeado this e aws_route_table deve ter nomes mais descritivos - como private, public, database).
  3. 3.
    Sempre utilize substantivos singulares para nomes.
  4. 4.
    Utilize - em valores de argumentos e em locais onde o valor será exposto a um humano (por exemplo, no nome de DNS da instância RDS).
  5. 5.
    Inclua o(s) argumento(s) count / for_each no bloco de recurso ou fonte de dados como o primeiro argumento na parte superior e separe por uma nova linha depois dele.
  6. 6.
    Inclua o argumento tags, se suportadas pelo recurso, como o último argumento real, seguido por depends_on e lifecycle, se necessário. Estes devem ser separados por uma única linha vazia.
  7. 7.
    Ao utilizar condições em um argumento count / for_each , prefira valores boleanos (true / false) em vez de usar length ou outras expressões.

Exemplos de código de resource

Uso do count / for_each

main.tf
1
resource "aws_route_table" "public" {
2
count = 2
3
4
vpc_id = "vpc-12345678"
5
# ... argumentos restantes omitidos
6
}
7
8
resource "aws_route_table" "private" {
9
for_each = toset(["one", "two"])
10
11
vpc_id = "vpc-12345678"
12
# ... argumentos restantes omitidos
13
}
Copied!
main.tf
1
resource "aws_route_table" "public" {
2
vpc_id = "vpc-12345678"
3
count = 2
4
5
# ... argumentos restantes omitidos
6
}
Copied!

Colocação das tags

main.tf
1
resource "aws_nat_gateway" "this" {
2
count = 2
3
4
allocation_id = "..."
5
subnet_id = "..."
6
7
tags = {
8
Name = "..."
9
}
10
11
depends_on = [aws_internet_gateway.this]
12
13
lifecycle {
14
create_before_destroy = true
15
}
16
}
Copied!
main.tf
1
resource "aws_nat_gateway" "this" {
2
count = 2
3
4
tags = "..."
5
6
depends_on = [aws_internet_gateway.this]
7
8
lifecycle {
9
create_before_destroy = true
10
}
11
12
allocation_id = "..."
13
subnet_id = "..."
14
}
Copied!

Condições com o count

outputs.tf
1
resource "aws_nat_gateway" "that" { # Perfeito
2
count = var.create_public_subnets ? 1 : 0
3
}
4
5
resource "aws_nat_gateway" "this" { # Bom
6
count = length(var.public_subnets) > 0 ? 1 : 0
7
}
Copied!

Variáveis

  1. 1.
    Não reinvente a roda em módulos de recursos: use name, description, e valor default para variáveis conforme definido na seção “Referência de argumento” para o recurso com o qual você está trabalhando.
  2. 2.
    O suporte para validação em variáveis é bastante limitado (por exemplo, não pode acessar outras variáveis ou fazer pesquisas). Planeje de acordo porque em muitos casos esse recurso é inútil.
  3. 3.
    Use a forma plural em um nome de variável quando o tipo for list(...) ou map(...).
  4. 4.
    Chaves de ordem em um bloco variável como: description, type, default, validation.
  5. 5.
    Sempre inclua description em todas as variáveis, mesmo que você julgue ser óbvio (você precisará disso, no futuro).
  6. 6.
    Prefira usar tipos simples (number, string, list(...), map(...), any) sobre tipos específicos como object(), a menos que você precise ter restrições estritas em cada chave.
  7. 7.
    Use tipos específicos como map(map(string)) se todos os elementos do mapa tiverem o mesmo tipo (ex. string) ou podem ser convertidos para ele (ex. number pode ser convertido para string).
  8. 8.
    Use tipo any para desabilitar a validação de tipo a partir de uma determinada profundidade ou quando vários tipos devem ser suportados.
  9. 9.
    O valor {} às vezes é um mapa, mas às vezes é um objeto. Use tomap(...) para criar um mapa porque não há como criar um objeto.

Outputs

Torne os outputs consistentes e compreensíveis fora de seu escopo (quando um usuário está usando um módulo, deve ser óbvio que tipo e atributo do valor ele retorna).
  1. 1.
    O nome do output deve descrever a propriedade que ela contém e ser menos livre do que você normalmente desejaria.
  2. 2.
    Uma boa estrutura para o nome do output parece com {name}_{type}_{attribute}, onde:
    1. 1.
      {name} um nome de recurso ou fonte de dados sem um prefixo de provedor. O {name} do aws_subnet é subnet, para oaws_vpc é vpc.
    2. 2.
      {type} é um tipo de fontes de recursos.
    3. 3.
      {attribute} é um atributo retornado pelo output.
  3. 3.
    Se o output estiver retornando um valor com funções de interpolação e vários recursos, {name} e {type} devem ser o mais genéricos possível (this como prefixo deve ser omisso). Veja exemplos.
  4. 4.
    Se o valor retornado for uma lista, deve ter um nome no plural. Veja exemplos.
  5. 5.
    Sempre inclua description para todos os outputs mesmo que você julgue que ser óbvio.
  6. 6.
    Evite definir o argumento sensitive, a menos que você controle totalmente o uso desse output em todos os locais em todos os módulos.
  7. 7.
    Prefira try() (disponível desde o Terraform 0.13) ao invés de element(concat(...)) (abordagem herdada para a versão anterior a 0.13).

Exemplos de código do output

Retorne no máximo um ID do security-group:
outputs.tf
1
output "security_group_id" {
2
description = "The ID of the security group"
3
value = try(aws_security_group.this[0].id, aws_security_group.name_prefix[0].id, "")
4
}
Copied!
Quando há vários recursos do mesmo tipo, this deve ser omisso no nome do output:
outputs.tf
1
output "this_security_group_id" {
2
description = "The ID of the security group"
3
value = element(concat(coalescelist(aws_security_group.this.*.id, aws_security_group.web.*.id), [""]), 0)
4
}
Copied!

Use o nome no plural se o valor de retorno for uma lista

outputs.tf
1
output "rds_cluster_instance_endpoints" {
2
description = "A list of all cluster instance endpoints"
3
value = aws_rds_cluster_instance.this.*.endpoint
4
}
Copied!