Local and Remote State

We start by inspecting the state file. This is how Terraform knows what state it is managing. It's not great that it's just local! If we move/delete it, Terraform will assume it hasn't created any state at all!

It's extremely important not to lose track of Terraform's state.

Let's see some meta files we have in our repository right now. If we run ls command, we'll these new files mixed into the files we created:

1# A lock file you can check into git to
2# help with collaboration
5# A directory with terraform resources
6# such as the aws provider
7# e.g. ".terraform/providers/registry.terraform.io/hashicorp/aws/3.20.0/darwin_amd64", a golang binary
10# Super-important state files, and a backup
11# which is made before any apply/destroy

We see we have some .tfstate files. If we move our state file, and run terraform plan, we'll see that Terraform doesn't know what resources it's managing any longer!

1mv *.tfstate ~/
2terraform plan -var-file variables.tfvars # uh oh!

How do we put our state file(s) into a safe place?

S3 Backends

We want Terraform to save its state somewhere that's not our local machine. This is extremely important for single operators as well as those working in teams.

Losing state means Terraform loses track of the infrastructure that exists. If that is lost, it will try to delete things that shouldn't be deleted or, more likely, create things that already exist.

To accomplish this, we'll create an S3 bucket to save our state. In my case, I name this bucket cloudcasts-terraform-ex and set it up with:

  1. No public permission
  2. Encryption enabled
  3. Deletion protection enabled
  4. Most importantly: Versioning enabled.

You can also use Terraform Cloud for free as a location to save your state.

File cloudcasts.tf

Once we create the S3 bucket, we can update our configuration to make use of it for a backend:

1terraform {
2 required_providers {
3 aws = {
4 source = "hashicorp/aws"
5 version = "~> 3.0"
6 }
7 }
9 # We add in the backend configuration
10 backend "s3" {
11 bucket = "terraform-course-cloudcasts"
12 key = "cloudcasts/terraform.tfstate"
13 region = "us-east-2"
14 profile = "cloudcasts"
15 }

Once that's updated, we can re-initialize Terraform:

1terraform init
2# Choose yes to copy current state to remote

Don't miss out

Sign up to learn when new content is released! Courses are in production now.