This is intended to be a guide of Terraform syntax and general best practices.
As Terraform utilises HCL, you may wish to take a detailed look at its syntax guide.
Inspired by The Ruby Style Guide and The Puppet Style Guide.
Indentation should be 2 spaces (soft tabs). No hard tabs.
Attribute assignments (=
) should be aligned for clarity.
// bad
resource "aws_security_group" "main" {
name = "${var.name}"
description = "Security Group ${var.name}"
vpc_id = "${var.vpc_id}"
tags {
Name = "${var.name}"
}
}
// good
resource "aws_security_group" "main" {
name = "${var.name}"
description = "Security Group ${var.name}"
vpc_id = "${var.vpc_id}"
tags {
Name = "${var.name}"
}
}
Variables should be provided in a variables.tf
file at the root of your module.
A description and type should be provided for each declared variable.
When it makes sense, please provide a reasonable default value.
There should be two blank lines between resource definitions.
// bad
variable "vpc_id" {}
// good
variable "vpc_id" {
description = "The VPC this security group will go in"
type = "string"
}
variable "public_subnet_ids" {
description = "List of public subnet IDs"
type = "list"
default = []
}
Variable names should be descriptive. Avoid abbreviations when reasonable. Verbosity is a good thing.
// bad
variable "pub_sub_id" {}
// good
variable "public_subnet_id" {
// definition
}
Boolean variables should follow the idiomatic pattern is_<condition>
// bad
variable "public" {}
// bad
variable "is_public" {
description = "Is the subnet public?"
type = "string"
default = false
}
Terraform resources usually have an ID or some other attribute associated with them. Variables for modules should refer to these attributes and match the actual name as much as possible.
// bad
variable "vpc_cidr" {}
// -- or --
variable "cidr_block" {}
// -- or --
variable "address_range" {}
// good
variable "vpc_cidr_block" {
// the vpc module exports an attribute named "cidr_block"
description = "The CIDR block associated with the VPC"
type = "string"
}
If the variable has a particular unit of measure, feel free to add that in for additional clarity.
// bad
variable "root_disk_size" {}
// good
variable "root_disk_size_in_gb" {
// definition
}
Variable names for lists should somehow indicate that they are a group of things. You know... plural.
// bad
variable "public_subnet_id" {}
// good
variable "public_subnet_ids" {
// definition
}
Outputs should be provided in an outputs.tf
file at the root of your module.
Attributes exported by your modules should follow the same descriptive format as variable names.
Only comment what is necessary.
Single line comments: #
or //
.
Multi-line comments: /*
followed by */
.
All resources should have the following labels assigned to them
label | description |
---|---|
Name | Descriptive name for the resource |
Environment | The environment for the resource - value is usually the name of the child directory under the ./environments/ directory |
Application | The application supported by this resource. VPC and network resources are assigned the value infrastructure |
ManagedBy | Defaults to terraform |