docs-terraform-guidelines

Terraform design pattern WYSIWYG (What you see is what you get)

Design pattern is a general, reusable solution to a commonly occurring problem within a given context in software design

.
โ”œโ”€โ”€ environment 
โ”‚ย ย  โ”œโ”€โ”€ dev  
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ _settings.tf  
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ output.tf 
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ database.tf # Calls a local database module
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ environment.tf # Calls a local environment module
โ”‚ย ย  โ”œโ”€โ”€ preproduction
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ _settings.tf  
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ output.tf 
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ environment.tf # Calls a local environment module
โ”‚ย ย  โ””โ”€โ”€ production
โ”‚ย ย   ย ย  โ”œโ”€โ”€ _settings.tf  
โ”‚ย ย  ย  ย  โ”œโ”€โ”€ output.tf 
โ”‚ย ย  ย ย   โ”œโ”€โ”€ organisation.tf # Calls aresource directly
โ”‚ย ย  ย ย   โ””โ”€โ”€ environment.tf  # Calls a local environment module
โ”œโ”€โ”€ application 
โ”‚ย ย  โ”œโ”€โ”€ app_1  
|   โ”‚ย ย  โ”œโ”€โ”€ dev  
|   โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ _settings.tf  
|   โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ output.tf 
|   โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ rds.tf 
|   โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ app.tf # Calls a remote app module
|   โ”‚   โ”œโ”€โ”€ preproduction  
|   โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ _settings.tf  
|   โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ output.tf 
|   โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ app.tf # Calls a remote app module
|   โ”‚   โ””โ”€โ”€ production  
|   โ”‚ย ย  ย ย  โ”œโ”€โ”€ _settings.tf  
|   โ”‚ย ย  ย ย  โ”œโ”€โ”€ output.tf 
|   โ”‚ย ย  ย ย  โ””โ”€โ”€ app.tf # Calls a remote app module
โ”‚ย ย  โ”œโ”€โ”€ app_2
โ”‚ย ย  โ””โ”€โ”€ app_3
โ””โ”€โ”€ modules
    โ”œโ”€โ”€ environment
    โ”‚ย ย  โ”œโ”€โ”€ README.md
    โ”‚ย ย  โ”œโ”€โ”€ _settings.tf
    โ”‚ย ย  โ”œโ”€โ”€ bastion.tf
    โ”‚ย ย  โ”œโ”€โ”€ bucket.tf
    โ”‚ย ย  โ”œโ”€โ”€ dns.tf
    โ”‚ย ย  โ”œโ”€โ”€ ip_ranges.tf 
    โ”‚ย ย  โ”œโ”€โ”€ eks.tf
    โ”‚ย ย  โ””โ”€โ”€ variables.tf 
    โ””โ”€โ”€ database

๐Ÿฆฎ Guidelines

Keep it simple stupid.

Donโ€™t put too much thought on the friendly name of files, the point is that a newcomer can easily find code to understand the infrastructure and make modification.

Layers, folders and projects

A layer is a directory in which you use apply/destroy resource on your provider, thus a terraform state.

A folder is used to regroup these layers, and it should be named with a project need in mind (Ex: environments, applications).

A project can host multiple folder to regroup different type of project need.

Size of layer

The size of a layer is important when deciding the segmentation of folder and layers within a project.

The following factors are indication of too large states

Modules

Modules are created for two reasons:

Each file in a module is named with a friendly name (Ex: node_pool, roles, monitoring)

Module can be be located either

Versioning

Versioning of IAC is important to assure the resilience of an infrastructure. It allows you to:

This versioning can be done on several layers:

Files and folder naming

Keep it simple, stupid.

Folders

Files

โš–๏ธ Pros and cons

Pros:

Cons

Examples

Example 1 : Project with a separation per environment, module are in local repository with no versioning

Main repository

.
โ”œโ”€โ”€ environment 
โ”‚   โ”œโ”€โ”€ dev
โ”‚   โ”‚     โ”œโ”€โ”€ layer-1
โ”‚   โ”‚     โ”‚ย ย  โ”œโ”€โ”€ _settings.tf  
โ”‚   โ”‚ ย ย   โ”‚ย ย  โ”œโ”€โ”€ output.tf 
โ”‚   โ”‚ ย ย   โ”‚ย ย  โ”œโ”€โ”€ database.tf # Call local database module
โ”‚   โ”‚  ย   โ”‚ย ย  โ””โ”€โ”€ environment.tf # Call local environment module
โ”‚   โ”‚     โ””โ”€โ”€ layer-2
โ”‚   โ”‚      ย ย  โ”œโ”€โ”€ _settings.tf  
โ”‚   โ”‚    ย   ย  โ”œโ”€โ”€ output.tf 
โ”‚   โ”‚  ย ย    ย  โ””โ”€โ”€ kubernetes.tf # Call local kubernetes module
โ”‚ย ย  โ”œโ”€โ”€ preproduction
โ”‚ย ย  โ””โ”€โ”€ production
โ””โ”€โ”€ modules
    โ”œโ”€โ”€ environment
    โ”‚ย ย  โ”œโ”€โ”€ README.md
    โ”‚ย ย  โ”œโ”€โ”€ _settings.tf
    โ”‚ย ย  โ”œโ”€โ”€ bastion.tf
    โ”‚ย ย  โ”œโ”€โ”€ bucket.tf
    โ”‚ย ย  โ”œโ”€โ”€ dns.tf
    โ”‚ย ย  โ”œโ”€โ”€ ip_ranges.tf 
    โ”‚ย ย  โ”œโ”€โ”€ eks.tf
    โ”‚ย ย  โ””โ”€โ”€ variables.tf 
    โ””โ”€โ”€ database

Example 2 : Project with a separation per application, module are in remote repository with versioning

Main repository

.
โ””โ”€โ”€ apps 
 ย ย  โ”œโ”€โ”€ api_1  
    |   โ”œโ”€โ”€ dev
    โ”‚ย ย  |ย  โ”œโ”€โ”€ _settings.tf  
    โ”‚ย ย  |ย  โ”œโ”€โ”€ output.tf 
    โ”‚ย ย  |ย  โ””โ”€โ”€ app.tf # Call remote module application
    |   โ”œโ”€โ”€ preproduction
    โ”‚ย ย  |ย  โ”œโ”€โ”€ _settings.tf  
    โ”‚ย ย  |ย  โ”œโ”€โ”€ output.tf 
    โ”‚ย ย  |ย  โ””โ”€โ”€ app.tf # Call remote module application
    |   โ””โ”€โ”€ production
    โ”‚ย ย  ย ย  โ”œโ”€โ”€ _settings.tf  
    โ”‚ย ย  ย ย  โ”œโ”€โ”€ output.tf 
    โ”‚ย ย  ย ย  โ”œโ”€โ”€ datadog.tf # Call community module for Datadog
    โ”‚ย ย  ย ย  โ””โ”€โ”€ app.tf # Call remote module application
ย ย   โ”œโ”€โ”€ api_2
ย ย   โ””โ”€โ”€ api_3

Remote module

.
โ””โ”€โ”€ application 
ย ย  โ”œโ”€โ”€ README.md
ย ย  โ”œโ”€โ”€ _settings.tf
ย ย  โ”œโ”€โ”€ bucket.tf
ย ย  โ”œโ”€โ”€ cloudrun.tf
ย ย  โ””โ”€โ”€ variables.tf