Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

Terraform Styling Guide

Linter Settings

It recommended but not required to use VSCode as your IDE. Linting for Terraform is managed by TFLint. Your system must have these linter settings to contribute to the codebase.

Install tflint

brew install tflint

Add these settings to any new Terraform project you create in a file named /.tflint.hcl:

# /.tflint.hcl
config {
  module = true
  force  = true
  disabled_by_default = false

  varfile = ["example1.tfvars", "example2.tfvars"]
  variables = ["foo=bar", "bar=[\"baz\"]"]
}

rule "terraform_naming_convention" {
  format  = "snake_case"
  enabled = true
}

rule "terraform_unused_required_providers" {
  enabled = true
}

plugin "aws" {
  enabled = true
  source  = "github.com/terraform-linters/tflint-ruleset-aws"
}

Required Tags:

The required tags for each project are as follows:

  • owner (Required) - Who is responsible (i.e. who do I slack when things go wrong)
  • project (Required) - The project we’re dealing with
  • environment (Required) - The environment this is being deployed to, i.e. live, dev, staging, etc.

These can be set universally for a project in the provider

# provider.tf

provider "aws" {
  region  = "eu-west-2"
  default_tags {
    tags = {
      owner       = "team-a"
      project     = "example"
      environment = "development"
    }
  }
}

If adding an Auto Scaling Group, please follow the link below for guidance. This is possible thanks to: Default Tags in the Terraform AWS Provider


Naming Conventions

File Names

Every project and module is required to have a main.tf, a variables.tf, provider.tf, and an outputs.tf file. Any other files in the structure should be named after the concept of what the file is doing and not the name of the AWS/Azure/GCP Service.

Examples of this are:

  • If this module creates and manages compute infrastructure such as AWS EC2 instances, name it compute.tf
  • If this manages user permissions with AWS IAM, something such as user_management.tf would be best.

Variable Names

All variables should use snake_case formatting, this will be caught and rejected by the linter if using anything else.

Cloud Resource Names

Rules:

  • Must not include the name of the service (e.g. subnet_a rather than vpc_subnet_a)
  • Must include the environment (e.g. live)
  • Must include project name
  • Must be snake case
  • Should be as descriptive as possible, relating to the function (i.e. gitlab_database rather than just database)

The names should be ordered as follows:

project_environment_function/description

"${var.project}_${var.environment}_function/description"

Examples of correct names:

project_live_gitlab_postgres_db

myproject_staging_public_bastion

platform_live_kubernetes_private_loadbalancer

tech_alpha_elastic_data_node

Module File Names

As described above in the naming conventions, every module is required to have certain files. Use the main.tf file for the overall purpose of the module, extending out to other other files for concepts that distract from the module’s main function. An example of this being that a module that creates a VPC use the main.tf to manage the main VPC creation, but not subnet associations.

Any other files inside the module should be named after the concept of what it is doing and not the name of the AWS/Azure/GCP Service.

Licensing Modules

All modules are created with the Apache 2.0 license. This must not be changed unless specifically instructed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment