Teamwork – sharing Terraform infrastructure state

You probably work with a team, and now you're using Terraform to manage your infrastructure, you'll face an issue: how does your team work together on infrastructure-as-code? There're many answers to that, and one crucial question to address is: how is transmitted or synchronized the Terraform state?

We'll see here how we can share the state using Git (a version control system where developers can store code), AWS S3 (an Amazon Web Services storage system using HTTP) or Consul (a tool for service discovery and a key-value store), chosen among many other solutions.

Getting ready

To step through this recipe, you will need the following:

  • A working Terraform installation
  • An AWS account with an SSH key configured in Terraform (refer to the Chapter 2, Provisioning IaaS with Terraform recipes)
  • A working Docker installation for the Consul simulation solution (optional)
  • An Internet connection

How to do it…

Let's start by having an initial infrastructure running (a single virtual machine for this example). Here's an aws_instance resource in instances.tf for a CoreOS stable release taken from previous recipes:

resource "aws_instance" "coreos" {
  count                       = "${var.cluster_size}"
  ami                         = "${var.aws_coreos_ami}"
  instance_type               = "${var.aws_instance_type}"
  key_name                    = "${aws_key_pair.admin_key.key_name}"
  associate_public_ip_address = true

  tags {
    Name = "coreos_${count.index+1}"
  }
}

Here are example variables in variables.tf; feel free to adapt them:

variable "aws_coreos_ami" {
  default = "ami-85097ff6"
}

variable "cluster_size" {
  default     = "1"
  description = "Number of nodes in the cluster"
}

variable "aws_instance_type" {
  default     = "t2.micro"
  description = "Instance type"
}

Terraform stores its state by default in a file named terraform.tfstate, with a backup file named terraform.tfstate.backup:

$ ls terraform.tfstate*
terraform.tfstate        terraform.tfstate.backup

Sharing with Git

The simplest of all options is to share the state file using Git: you're already supposed to version your infrastructure code! Go and create an account somewhere. GitHub (https://github.com) doesn't have free private repositories, but GitLab (https://gitlab.com) or BitBucket (https://bitbucket.org) do. Follow the instructions to have your Git repository locally working.

Now, add the tfstate files:

$ git add *.tfstate*

Commit the files:

$ git commit -m "initial state creating the infrastructure"
[master (root-commit) 6f7e2ba] initial state creating the infrastructure
 2 files changed, 193 insertions(+)
 create mode 100644 terraform.tfstate
 create mode 100644 terraform.tfstate.backup

Push the commit:

$ git push

Now your coworkers absolutely need to pull the changes before applying any action, or calamity might follow soon:

coworker@host $ git pull

Sharing remotely with S3

Sharing the state file through Git works, to some extent. You'll end up someday in a situation where someone forgets to push or pull. Merging conflicts in a state file is really not something nice to do.

One solution to stop thinking about it is using S3 to share the state file and use the remote state feature of Terraform.

Start by creating an S3 bucket just for that, in s3.tf, with versioning enabled (so you can roll back to a previous version of the infrastructure):

resource "aws_s3_bucket" "tfstate" {
  bucket = "iacbook-tfstate"

  versioning {
    enabled = true
  }

  tags {
    Name = "IAC Book TFState Bucket"
  }
}

Let's terraform apply this S3 bucket, and move on to the remote configuration with our information:

$ terraform remote config -backend=s3 -backend-config="bucket=iacbook-tfstate" -backend-config="key=terraform.tfstate"
Remote state management enabled
Remote state configured and pulled.   

You can now see the terraform state file in the S3 browser:

Sharing remotely with S3

Now make any change to the infrastructure, such as adding a new S3 bucket, to see the file change in action:

resource "aws_s3_bucket" "bucket" {
  bucket = "iacbook-bucket"

  tags {
    Name = "IAC Book Bucket"
  }
}

After a terraform apply, simply push the changes:

$ terraform remote push
State successfully pushed!

See the history in the S3 browser:

Sharing remotely with S3

The coworker has to configure their environment and pull the information:

coworker@host $ terraform remote config -backend=s3 -backend-config="bucket=iacbook-tfstate" -backend-config="key=terraform.tfstate"
Initialized blank state with remote state enabled!
Remote state configured and pulled.

A local copy is now residing in the .terraform folder:

$ head .terraform/terraform.tfstate

Sharing remotely with Consul

A very nice way to share the state file is by using Consul, a powerful key/value storage from Hashicorp (http://consul.io/). Using Consul to store the Terraform states makes it easier to work with a team, as there's only a single replicated state. No risk of using an old state file if we forgot to synchronize our git repository.

Configuring a proper Consul in cluster for production is out of the scope of this book, but if you don't have a Consul cluster at hand to try this out, here's a way to quickly have one, using Docker and a Consul image:

$ docker run -it --rm -p 8400:8400 -p 8500:8500 -p 8600:53/udp -h node1 progrium/consul -server -bootstrap

Now let's configure our Terraform remote for Consul, and name it terraform/my_customer, so we can manage multiple customers simultaneously:

$ terraform remote config -backend=consul -backend-config="path=terraform/my_customer"
Remote state management enabled
Remote state configured and pulled.

Job done! Your coworkers can now push and pull from the Consul source! In a production Consul cluster, it means replicated and synchronized states on each node, with added privacy.

Other state sharing options

There're many other ways to share the state, such as on Azure, using OpenStack Swift, any kind of HTTP server supporting REST, CoreOS's own etcd key-value store, Google Cloud storage, or Atlas, the commercial solution by Hashicorp.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.61.170