Terragrunt: How can I share remote_state infos between modules and stay DRY?

Created on 23 Jul 2019  ยท  5Comments  ยท  Source: gruntwork-io/terragrunt

I have two modules vpc and vpn and I use this remote_state config in my root terragrunt.hcl

root
โ”œโ”€โ”€ modules
โ”‚   โ”œโ”€โ”€ vpc
โ”‚   โ”‚   โ”œโ”€โ”€ backend.tf
โ”‚   โ”‚   โ”œโ”€โ”€ provider.tf
โ”‚   โ”‚   โ””โ”€โ”€ vpc.tf
โ”‚   โ””โ”€โ”€ vpn
โ”‚       โ”œโ”€โ”€ backend.tf
โ”‚       โ”œโ”€โ”€ provider.tf
โ”‚       โ””โ”€โ”€ vpn.tf
โ”œโ”€โ”€ prod
โ”‚   โ”œโ”€โ”€ vpc
โ”‚   โ”‚   โ””โ”€โ”€ terragrunt.hcl
โ”‚   โ””โ”€โ”€ vpn
โ”‚       โ””โ”€โ”€ terragrunt.hcl
โ””โ”€โ”€ terragrunt.hcl
remote_state {
  backend = "s3"
  config = {
  bucket                              = "test-tf-state"
  key                                     = "${path_relative_to_include()}/terraform.tfstate"
  region                                = "eu-central-1"
  encrypt                              = true
  dynamodb_table              = "test-tf-lock-table"
  }   
}
data "terraform_remote_state" "vpc" {
  backend = "s3"
    config = {
    bucket                               = "${var.bucket}"
    key                                     = "${var.key}"
    region                                = "${var.region}"
    encrypt                              = true
    dynamodb_table              = "${var.lock-table}"
    }  
}

In my vpn module I need data from the vpc module, so I have to use data sources from terraform_remote_state. But now I can't access the data from the remote_state and I can't use variables in the remote_state.

What is the best way to stay clean and don't repeat myself?

question

Most helpful comment

Most definitely. I have migrated from terraform_remote_state to dependency block of terragrunt and it works beautifully.

All 5 comments

Here's how I do it with AWS S3:

  • use distinct S3 buckets per environment
  • use root terraform.hcl per env
  • no common terraform.hcl across envs - usually not a problem
# root/prod/terragrunt.hcl
remote_state {
  backend = "s3"

  config = {
    bucket         = "tfstate.prod.example.com"
    region         = "us-west-2"
    key            = "${path_relative_to_include()}/terraform.tfstate"
    encrypt        = true
    dynamodb_table = "terraform-locks"

    s3_bucket_tags = {
      Name      = "Terraform state storage"
      Terraform = "true"
    }

    dynamodb_table_tags = {
      Name      = "Terraform lock table"
      Terraform = "true"
    }
  }
}

inputs = {
  terraform_state_bucket = "tfstate.prod.example.com"
  terraform_state_region = "us-west-2"

  vpc_state_file = "vpc/terraform.tfstate"
  vpn_state_file = "vpn/terraform.tfstate"
}
# root/modules/vpn/data.tf
# VPN module reading VPC module state file

data "terraform_remote_state" "vpc" {
  backend = "s3"

  config = {
    bucket = var.terraform_state_bucket
    region = var.terraform_state_region
    key    = var.vpc_state_file
  }
}

This is the best I could come up with, sadly the remote state part cannot use variables, so you get some variable duplication there.

Sadly I didn't find any way of not having to define the full path to the state files in the bucket, so you need to know your folder structure in the root terragrunt.hcl file. :(

Hi reegnz,

thanks for sharing your approach. That's works for me...
Variables in the remote state part would be great and it would help to improve the DRY approach.

Best regards

Would the new, dependency block system help here? This is an alternative to using remote_state to message pass across modules that was introduced in v0.19.20. You can learn more about it in the current README.

Note that if you want to use this, we rolled out a few bugfixes since then so you will want to use the latest version.

Most definitely. I have migrated from terraform_remote_state to dependency block of terragrunt and it works beautifully.

Hi reegnz can you tell me how you use terragrunt source and structure resolve the above problem i got source file path error and lot of confusion..

Was this page helpful?
0 / 5 - 0 ratings