Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ideal terraform workspace project structure

I'd like to setup Terraform to manage dev/stage/prod environments. The infrastructure is the same in all environments, but there are differences in the variables in every environment.

What does an ideal Terraform project structure look like now that workspaces have been introduced in Terraform 0.10? How do I reference the workspace when naming/tagging infrastructure?

like image 285
mark Avatar asked Aug 16 '17 15:08

mark


People also ask

How do you choose a Terraform workspace?

Switching Between Workspaces We can use “terraform workspace select” to choose a different workspace that already exists. For example, we can switch from “production” workspace to “dev” workspace.

How do you manage Terraform workspaces?

Managing CLI WorkspacesUse the terraform workspace list , terraform workspace new , and terraform workspace delete commands to manage the available workspaces in the current working directory. Use the terraform workspace select command to change the currently selected workspace.

Does Terraform workspaces use same backend?

Important: Terraform workspaces have the constriction that all state files must be stored in the same backend. If you are using a local backend, Terraform will automatically create a subfolder dedicated to each workspace (which will later contain the state file) inside the folder terraform.


2 Answers

I wouldn't recommend using workspaces (previously 'environments') for static environments because they add a fair bit of complexity and are harder to keep track of.

You could get away with using a single folder structure for all environments, use workspaces to separate the environments and then use conditional values based on the workspace to set the differences. In practice (and especially with more than 2 environments leading to nested ternary statements) you'll probably find this difficult to manage.

Instead I'd still advocate for separate folders for every static environment and using symlinks to keep all your .tf files the same across all environments and a terraform.tfvars file to provide any differences at each environment.

I would recommend workspaces for dynamic environments such as short lived review/lab environments as this allows for a lot of flexibility. I'm currently using them to create review environments in Gitlab CI so every branch can have an optionally deployed review environment that can be used for manual integration or exploratory testing.

like image 110
ydaetskcoR Avatar answered Sep 23 '22 00:09

ydaetskcoR


In the old world you might have passed in the var 'environment' when running terraform, which you would interpolate in your .tf files as "${var.environment}".

When using workspaces, there is no need to pass in an environment variable, you just make sure you are in the correct workspace and then interpolate inside your .tf files with "${terraform.workspace}"

As for how you'd manage all of the variables, i'd recommend using a varmap, like so:

variable "vpc_cidr" {
  type = "map"

  default = {
    dev = "172.0.0.0/24"
    preprod = "172.0.0.0/24"
    prod = "172.0.0.0/24"
  }
}

This would then be referenced in a aws_vpc resource using a lookup

"${lookup(var.vpc_cidr, terraform.workspace)}"

The process of creating and selecting workspaces is pretty easy:

terraform workspace
Usage: terraform workspace

  Create, change and delete Terraform workspaces.


Subcommands:

    show      Show the current workspace name.
    list      List workspaces.
    select    Select a workspace.
    new       Create a new workspace.
    delete    Delete an existing workspace.

so to create a new workspace for pre production you'd do the following: terraform workspace new preprod

and if you ran a plan, you'd see that there should be no resources. What this will do in the backend is create a new folder to manage the state for 'preprod'.

like image 29
Matt Childs Avatar answered Sep 22 '22 00:09

Matt Childs