Relative paths in terragrunt modules


#1

Hi Folks.

I’ve been using terragrunt for a few weeks now and getting to grips with its very powerful features :slight_smile:

I have a question about using relative paths to other modules in a terrarunt module. I have an example below. I am using the preferred layout as described in terraform up and running. I have a modules repo that contains some “standard” terraform modules. And some terragrunt modules that bring several modules together to keep my code DRY. These terragrunt modules are deployed per AWS account and I pass a handful of variables that differ between accounts.

provider "aws" {
  version = "~> 1.14"
  region  = "${var.aws_region}"
}

terraform {
  backend "s3" {}
}

# Compute the available AZs in the current region
data "aws_availability_zones" "available" {}

module "module_with_git_source" {
  source = "git@github.com:org/repo.git//rds_instance?ref=v0.6.53"
}

module "module_with_absolute_path" {
  source = "/Users/me/code/modules/s3_bucket"
}
# Will not work
module "module_with_relative_path" {
  source = "../s3_bucket"
}

So typically I use git source for modules. Absolute paths won’t work for other developers obviously. So my question is how do I handle a relative path in a terragrunt module. Where module foo and bar are both in the same modules repo and I want foo to use the local copy of bar. It obviously fails when terragrunt copies everything to the temp directory

The --terragrunt-source helps me to work on a local copy of a terragrunt module. But the issue I have is using local copies of modules it includes. What I have started doing is pushing them to GitHub and tagging them as pre-release or hard coding an absolute path as the source but this is not very friendly.

Am I missing something obvious. Is there a pattern to help with this?

Thanks!


#2

@conzy, I ran into this recently and ended up using the absolute path during my development. I think this issue is covered in https://github.com/gruntwork-io/terragrunt#important-gotcha-working-with-relative-file-paths. Although, they may be referring to terragrunt modules themselves, I believe the reason is the same.

I believe, once terragrunt moves the terragrunt module files (the ones sourced in tfvars) into the temporary directory, it then evaluates the module source of those files which breaks for relative paths. I just accept this and hope that my development of the “standard” modules don’t have to change much after initial development. YMMV


#3

Not sure how I missed this question originally, but the solution is to use a double-slash in the source and --terragrunt-source URLs. Then relative paths will work just fine. e.g.,

terragrunt apply --terragrunt-source /foo/modules//my-module

Search the docs for “double-slash”; it’s mentioned several times.


#4

Oh. Maybe I misunderstood the question. My understanding was that he was developing a terragrunt module and a terraform module that it depends on which live in different directories. So my scenario is that I have ~/work where infrastructure-modules and module-custom lives. So if I pass --terragrunt-source ~/work/infrastructure-modules//terragrunt-module but terragrunt-module needs to access my local development version of module-custom, I have to specify the absolute path of module-custom inside terragrunt-module. Does that make sense?

My latest experience came when trying to add aurora to my infrastructure-modules at the same time as adding monitoring_internal to the module-data-storage/modules/aurora.


#5

Ah, yes, if you have a structure like terraform.tfvars -> infra-modules/data-storage/aurora/main.tf -> module-data-storage/modules/aurora, and you are making changes in the very last one, then currently you’d have to use an absolute path in the source URL of the main.tf in infra-modules, as Terragrunt knows nothing of the source paths used within your code.


#6

Thanks guys. I kind of figured this out by accident right after posting. I was under the impression that the double slash notation was only for use with the terragrunt plan-all functionality. But that can be used with terragrunt plan also which solves my problem as I presume under the hood its pulling my entire “modules” repo into the temp dir so the relative paths work.

So just incase it helps others and to ensure I am doing it right. My “live” repo has a terraform.tfvars file per environemnt like this:

terragrunt = {
  terraform {
    source = "git@github.com:my-org/my-modules.git//terragrunt_module_foo?ref=v0.6.54"
  }

  # Include all settings from the root terraform.tfvars file
  include = {
    path = "${find_in_parent_folders()}"
  }
}

aws_region = "eu-west-1"

That terragrunt module looks like this:

provider "aws" {
  region  = "${var.aws_region}"
  version = "~> 1.14"
}

terraform {
  backend "s3" {}
}

data "aws_caller_identity" "current" {}

# I pass in state from my VPC module which is a terragrunt module also
data "terraform_remote_state" "network" {
  backend = "s3"

  config {
    bucket = "${var.tfstate_global_bucket}"
    key    = "${var.tfstate_network_key}"
    region = "eu-west-1"
  }
}

# Some terraform module A
module "a_terraform_module" {
  source = "../my_module"
  name   = "foo"
}

# Some terraform module B
module "another_terraform_module" {
  source = "../cool_module"
  name   = "bar"
}

A you can see it has relative paths to other modules and it works fine. I can see how if these modules were in a different repo / local path it would not work

Thanks for the help