In recent months, I've been working more and more with Terraform, deploying to multiple cloud providers and even combining it with Serverless projects (more on that on the next post).

Terraform allows for infrastructure automation in a way Ansible could only dream of doing.
It's incredibly simple, quite predictable, and works seemlessly with all the major cloud providers.

If you make any changes to your Terraform configuration, and run

terraform apply
Terraform will simply alter your current infrastructure to match your new configuration.
But what if you want multiple deployments of your infrastructure, across different regions?
For this we will be using Terraform Workspaces, with a few added improvements.

Example Terraform config - EC2 Instance

Let's look at the following main.tf
provider "aws" {
  region = "us-east-1"
}

data "aws_ami" "ubuntu" {
    most_recent = true

    filter {
        name   = "name"
        values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"]
    }

    filter {
        name   = "virtualization-type"
        values = ["hvm"]
    }

    owners = ["099720109477"] # Canonical
}

resource "aws_instance" "main_server" {
  ami           = "${data.aws_ami.ubuntu.id}"
  instance_type = "t2.micro"

  tags {
    Name = "exampleInstance-us-east-1"
  }
}
This configuration would create a t2.micro instance on us-east-1.
Let's tweak it a bit and move the region to a variable file.
main.tf:
provider "aws" {
  region = "${var.aws_region}"
}

data "aws_ami" "ubuntu" {
    most_recent = true

    filter {
        name   = "name"
        values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"]
    }

    filter {
        name   = "virtualization-type"
        values = ["hvm"]
    }

    owners = ["099720109477"] # Canonical
}

resource "aws_instance" "main_server" {
  ami           = "${data.aws_ami.ubuntu.id}"
  instance_type = "t2.micro"

  tags {
    Name = "exampleInstance-${var.aws_region}"
  }
}
variables.tf:
variable "aws_region" {
  description = "Selected AWS Region"
}
Now when you run terraform apply it will ask you to specify a region. In order to have multiple deployments of the same configuration, we need to create a new workspace. Let's name it dev:
terraform workspace create dev
Of coures the name dev is arbitrary, you could use whatever you want.
If we try to run terraform apply again, a second instance will be created!

External configuration files

Once your variables start adding up, it gets pretty annoying to fill them in each time you deploy your terraform. You could add them to the command itself as such:
terraform apply -var='aws_region=us-east-1'
But it's much easier to put the environment variables in a file. I name my files WorkspaceName.tfvars
For our example, I have the file dev.tfvars:
aws_region = "us-west-2"
Now you can run the following command:
terraform apply --var-file='dev.tfvars'
But I like to have a single command across all workspaces:
terraform apply --var-file=$(terraform workspace show).tfvars
The command above simply fetches your current workspace and gets the corresponding variable file.
I've created an example repository with all the relevant files.

My next post will review how you could connect Terraform with Serverless deployments.