Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Work with multiple environments/variables in Terraform

We're using terraform to spin up our infrastructure within AWS and we have 3 separate environments: Dev, Stage and Prod

Dev : Requires - public, private1a, privatedb and privatedb2 subnets Stage & Prod : Requires - public, private_1a, private_1b, privatedb and privatedb2 subnets

I have main.tf, variables, dev.tfvars, stage.tfvars and prod.tfvars. I'm trying to understand as of how can I use main.tf file that I'm currently using for dev environment and create resources required for stage and prod using .tfvars files.

terraform apply -var-file=dev.tfvars

terraform apply -var-file=stage.tfvars (this should create subnet private_1b in addition to the other subnets)

terraform apply -var-file=prod.tfvars (this should create subnet private_1b in addition to the other subnets)

Please let me know if you need further clarification.

Thanks,

like image 495
Karthik Avatar asked Jul 03 '18 03:07

Karthik


1 Answers

What you are trying to do is indeed the correct approach. You will also have to make use of terraform workspaces.

Terraform starts with a single workspace named "default". This workspace is special both because it is the default and also because it cannot ever be deleted. If you've never explicitly used workspaces, then you've only ever worked on the "default" workspace.

Workspaces are managed with the terraform workspace set of commands. To create a new workspace and switch to it, you can use terraform workspace new; to switch environments you can use terraform workspace select; etc.

In essence this means you will have a workspace for each environment you have.

Lets see with some examples.

I have the following files:

  1. main.tf
  2. variables.tf
  3. dev.tfvars
  4. production.tfvars

main.tf

This file contains the VPC module 9Can be any resource ofc). We call the variables via the var. function:

module "vpc" {
  source          = "modules/vpc"
  cidr_block      = "${var.vpc_cidr_block}"
  subnets_private = "${var.vpc_subnets_private}"
  subnets_public  = "${var.vpc_subnets_public}"
}

variables.tf

This file contains all our variables. Please do not that we do not assign default here, this will make sure we are 100% certain that we are using the variables from the .tfvars files.

variable "vpc_cidr_block" {}

variable "vpc_subnets_private" {
  type = "list"
}

variable "vpc_subnets_public" {
  type = "list"
}

That's basically it. Our .tfvars file will look like this:

dev.tfvars

vpc_cidr_block = "10.40.0.0/16"
vpc_subnets_private = ["10.40.0.0/19", "10.40.64.0/19", "10.40.128.0/19"]
vpc_subnets_public = ["10.40.32.0/20", "10.40.96.0/20", "10.40.160.0/20"]

production.tfvars

vpc_cidr_block = "10.30.0.0/16"
vpc_subnets_private = ["10.30.0.0/19", "10.30.64.0/19", "10.30.128.0/19"]
vpc_subnets_public = ["10.30.32.0/20", "10.30.96.0/20", "10.30.160.0/20"]

If I would like to run terraform for my dev environment, these are the commands I would use (Assuming the workspaces are already created, see Terraform workspace docs):

  1. Select the dev environment: terraform workspace select dev
  2. Run a plan to see the changes: terraform plan -var-file=dev.tfvars -out=plan.out
  3. Apply the changes: terraform apply plan.out

You can replicate this for as many environments as you like.

like image 99
ThomasVdBerge Avatar answered Sep 28 '22 07:09

ThomasVdBerge