Gallery
Department hub
Share
Explore
Code readability

icon picker
Terraform

info
This is a sample page to show how subpages can connect to other pages. Clear out this sample info to flesh it out with your team’s resources, or turn it into something new!

Background

We use as the tool of choice for infrastructure as code, all of our Terraform files are located in the repository. This style guide is a list of dos and don’ts for writing Terraform files.

Lint / Auto-format

terraform has a fmt subcommand that formats Terraform (.tf) files, but you likely won’t need to run it manually, as we have a pre-commit git hook that automatically runs terraform fmt on all the staged .tf files for you.
If you use VSCode, there is also a that can automatically format Terraform files on save.

Terraform Style Rules

We follow , which are enforced by terraform fmt. Our additional style rules below are not currently enforced, but should be followed to keep the code base tidy.

Indentation

Indent blocks with 2 spaces.
Exception:
Heredoc strings (<<EOT blocks), when it is not possible to use indented heredoc strings (<<-EOT blocks).

Line Length

Maximum line length is 120 characters.
Exception:
Description strings in variable and output blocks, where single line strings are preferred.

Comments

Use # for comments, do not use // or /**/.

Naming

Use snake_case, with all lower case letters and numbers, do not use kebab-case, camelCase, or PascalCase. This applies to all resoruces, data, variables and outputs.

Terraform Language Rules

Files and Directories

Each directory should contain the following files:
README.md: briefly describle the purpose of the directory, include example inputs and outputs, etc.
main.tf: the main logic.
variables.tf: all variable blocks, these are the inputs.
outputs.tf: all output blocks.
versions.tf: the version requirements for Terraform and its providers.
versions.tf files in tf/modules must not define provider versions, only specify a minimum version (e.g. version = ">= 1.0.0").
locals.tf(optional): local variables that are shared across multiple .tf files in the same directory.
others (optional): if main.tf becomes too large, different portions can be split out into separate .tf files, Terraform will automatically combile all .tf files in a directory during execution.

Resources and Data

Naming

A resource or data name should be descriptive and not contain the resource or data type, even partially.
If there is only one resource or data of a type, it should be named this.
Use singular nouns.
resource "aws_vpc" "this" { ... }

resource "aws_iam_role" "admin" { ... }

resource "aws_iam_role" "read_only" { ... }
resource "aws_iam_role" "admin_aws_iam_role" { ... }

resource "aws_iam_role" "read_only_role" { ... }

resource "aws_iam_role" "admins" { ... }

Structure

If supported, count / for_each should be at the top of the block, separated from the rest of the block with an empty line.
If supported, tags should be at the end of the block, followed by depends_on and lifecycle, if necessary, separated from the rest of the block, and from each other, with an empty line.
For each resource type, the ordering of fields inside the block should be consistent.
resource "aws_rds_cluster_instance" "secondary" {
count = var.enable_secondary_rds_cluster_instance ? 1 : 0

...<aws_rds_cluster_instance arguments>...

tags = {
...
}

depends_on = [
aws_rds_cluster_instance.secondary
]

lifecycle {
prevent_destroy = true
}
}

Variables

All variables must be defined in variables.tf.
Each variable must have a meaningful description.
Each variable must have a type, even if it is a string type, avoid using any whenever possible.
Include units for numeric type variables whenever possible (e.g. ram_size_gb, time_secs).
Use plural names for list or map variables.
Use sensible defaults, but do not provide defaults for environment specific variables, so the parent module must provide a meaningful value.
Use names for bool type variables (e.g. enable_caching)

Outputs

All outputs must be defined in outputs.tf.
Each output must have a meaningful description.
Use plural names for outputs that are lists (e.g. rds_cluster_instance_endpoints).
An output should generally be named {name}_{type}_{attribute} (e.g. admin_iam_role_arn).

Share
 
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.