use_snake_case_0nly
All resource or variable names in Terraform code must be written in snake_case
.
This means allowed characters are lowercase alphanumeric characters, with _
separators when needed.
Why ?
Note : Beware that actual cloud resources often have restrictions in allowed names. Some resources, for example, can’t contain dashes, some must be camelCased. The conventions in this document refer to Terraform names themselves.
Avoid stuttering when naming Terraform resources.
resource "aws_route_table" "public" {} # <- 🟢 no stuttering
resource "aws_route_table" "public_route_table" {} # <- 🔴 stuttering
resource "aws_route_table" "public_aws_route_table" {} # <- 🔴 maximum stuttering
Name a resource this
if there is no more descriptive and general name available, or if the resource is part of a module that creates a single resource of this type. For example, in a terraform-google-bucket
module :
resource "google_storage_bucket" "this" {
name = var.name
// ...
}
Name a resource these
if there is no more descriptive and general name available, or if the resource is part of a module that creates multiple resources of this type. For example, in a terraform-google-bucket
module :
resource "google_storage_bucket" "these" {
for_each = toset(var.names)
name = each.value
// ...
}
Resource and module instance names should be singular if they represent only one instance and should be plural in the case you loop over them with for_each
or for
.
module "bucket" {
source = "github.com/padok-team/terraform-google-bucket"
name = "frontend"
}
module "buckets" {
source = "github.com/padok-team/terraform-google-bucket"
for_each = toset([0, 1, 2])
name = "bucket-${each.key}"
}
Variable names for collections (sets, lists and maps) must be plural.
Variable names for maps should reflect the usage of the map. The relationship between the key and values should be obvious based on the name.
locals {
role_by_contributor = {
"arthurb@padok.fr" = "Viewer"
"antoinec@padok.fr" = "Editor"
"benjamins@padok.fr" = "Admin"
}
}
In the example above, role_by_contributor
is much clearer than contributor_roles
.
It also breaks any ambiguity around the number of roles per contributor.
In the example above the name of variable indicates that each contributor has a single role.
If contributors had multiple roles each, the variable name should be roles_by_contributor
.
contributor_roles
is ambiguous about the plurality of roles per contributor.
Avoid repeating yourself within a variable’s name.
variable "s3_storage_bucket_name" # <- 🔴 too precise
variable "bucket" # <- 🔴 not precise enough
variable "bucket_name" # <- 🟢 seems like a good compromise
Always provide a variable’s description, even if it seems obvious to you.
variable "tags" {
description = "A mapping of tags to assign to the resource."
type = map(string)
}
Do not reinvent the wheel when naming variables or writing descriptions. If a variable is consumed by a resource or module directly and you don’t need any sort of abstraction, reuse the variable name from the “Argument Reference” section in the resource’s (or module’s) documentation.
module "bucket" {
source = "github.com/padok-team/terraform-google-bucket"
name = "frontend"
storage_class = local.storage_class
tags = local.tags
}
If your module is abstracting resource variables in any way, you should find a nam that best suits your parameter.
module "private_bucket" {
source = "github.com/padok-team/terraform-google-bucket"
name = local.name
private = true
}
module "public_bucket" {
source = "github.com/padok-team/terraform-google-bucket"
name = local.name
private = false
}
Naming module outputs properly is important for them to be consistent through your codebase, and for them to be understandable outside of their immediate context. From a user’s perspective, it should be trivial what type each attribute has.
If the output is a list its name must be plural.
If the output is a map its name must obviously relates on key / value pairs.
Always provide an output’s description, even if it seems obvious to you.
output "this" {
description = "The AKS resource."
value = data.azurerm_kubernetes_cluster.this
}
Example of a module that instanciates a Function App, a Storage Account and an App Insights. The module is called azurerm-function-app
.
output "this" {
description = "The Function App resource."
value = module.function_app.this
}
output "app_insights" {
description = "The Application Insights resource."
value = module.application_insights.this
}
output "storage_account" {
description = "The Storage Account resource."
value = module.storage_account.this
}