Skip to content

Easy, automated, repeatable state migrations for Terraform

License

Notifications You must be signed in to change notification settings

sirech/terragrate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

terragrate

Crate version linux-release macos-release License

terragrate helps doing state migrations in terraform. It is inspired by database migration tools like Flyway.

Getting started

Prerequisites

You'll need to install terraform and set it up. At least terraform state list should work for terragrate to be any useful.

Installation

Download the latest release for your OS and put it in your PATH. Running terragrate alone will print the detailed help.

Usage

Why terragrate?

Let's assume I have a resource like this in terraform:

resource "docker_network" "network" {
  name     = "public_network"
}

I have provisioned the resource, which is identified as public_network.docker_network.network in the state.

During a refactoring, we extract this resource to a module called network to make it more reusable. Now we will use it a bit differently:

module "public_network" {
  source = "./network"
  name   = "public_network"
}

If we run terraform apply, it will try to destroy the old resource and create a new one. Even though it's the exact same entity, the new id is called module.public_network.docker_network.network.

This is fine for a toy example like this, but it makes no sense to reprovision a complete database just because of this!

The typical approach to fix this is by migrating the state with the terraform state commands by hand. This is error-prone and untraceable.

Using terragrate

Instead, I propose using a migration reflected in code. Let's define the move_to_module.json migration, and store it together with the infrastructure code:

{
  "name": "move to module",
  "description": "Convert network to module",
  "transformations": [
    {
      "kind": "MV",
      "matcher": "public_network",
      "replacement": "module.public_network"
    }
  ]
}

I can use that migration and feed it my current state with this:

terraform state list | terragrate --state - --migration move_to_module.json tf

This will output the list of terraform commands needed to migrate the state properly, in this case:

terraform state mv module.public_network.docker_network.network module.module.public_network.docker_network.network

By keeping the migration in your repository, you can known which migrations have been applied thus far. An automated script is much less likely to leave your state in an undefined situation.

Transformation types

The following transformations are supported:

Current limitations

  • As of today, terragrate does not offer a way of automatically running migrations in case your state is out of date.
  • Right now, terragrate assumes that you call terraform directly. It doesn't support something like terragrunt

License

See LICENSE

Roadmap

See the open issues for a list of proposed features (and known issues).

About

Easy, automated, repeatable state migrations for Terraform

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages