Skip to content

Instantly share code, notes, and snippets.

@dirsigler
Created May 17, 2021 08:26
Show Gist options
  • Save dirsigler/6181476c124539539dca6e3ca89e3474 to your computer and use it in GitHub Desktop.
Save dirsigler/6181476c124539539dca6e3ca89e3474 to your computer and use it in GitHub Desktop.
Terraform Style Guide

Terraform Style Guide

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.

Table of Contents

Code Layout

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}"
  }
}

Modules

Variables

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

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.

Comments

Only comment what is necessary.

Single line comments: # or //.

Multi-line comments: /* followed by */.

Labels

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment