Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it possible to use modules from Terraform Registry #311

Closed
antonbabenko opened this issue Oct 7, 2017 · 64 comments · Fixed by #1767
Closed

Make it possible to use modules from Terraform Registry #311

antonbabenko opened this issue Oct 7, 2017 · 64 comments · Fixed by #1767
Labels
enhancement New feature or request

Comments

@antonbabenko
Copy link
Contributor

Correct me if I am wrong, but it is not possible to download modules from Terraform Registry.

terragrunt = {
  terraform {
    source = "terraform-aws-modules/ec2-instance/aws"
  }
}

Error

Copying configuration from "file:///tmp/terragrunt-infrastructure-live-example/non-prod/us-east-1/qa/mysql/terraform-aws-modules/ec2-instance/aws"...
Error copying source module: error downloading 'file:///tmp/terragrunt-infrastructure-live-example/non-prod/us-east-1/qa/mysql/terraform-aws-modules/ec2-instance/aws': source path error: stat /tmp/terragrunt-infrastructure-live-example/non-prod/us-east-1/qa/mysql/terraform-aws-modules/ec2-instance/aws: no such file or directory

terragrunt version v0.13.7

@brikis98
Copy link
Member

brikis98 commented Oct 7, 2017

We use terraform init (with the -from-module param) under the hood to download modules, so if that doesn't work, you should probably file the bug with the Terraform repo itself.

@antonbabenko
Copy link
Contributor Author

-from-module parameter is composed incorrectly before it is passed to terraform init, and, yes it is not supported in Terraform.

When using git as a source, it is set to:

-from-module=git::ssh://git@github.com/gruntwork-io/terragrunt-infrastructure-modules-example.git?ref=v0.0.1

When using local directory as well as terraform registry:

-from-module=file:///tmp/terragrunt-infrastructure-live-example/non-prod/us-east-1/qa/mysql/terraform-aws-modules/ec2-instance/aws

Terraform understands if a directory is not present then it looks into the Terraform registry. Similar logic has to be implemented in Terragrunt when creating -from-module argument once Terraform has support for registry sources I think.

@antonbabenko
Copy link
Contributor Author

How to use Terragrunt with Terraform Registry modules without rewriting them to git URLs?

@brikis98
Copy link
Member

brikis98 commented Oct 8, 2017

-from-module parameter is composed incorrectly before it is passed to terraform init,

We use HashiCorp's go-getter library to format URLs. Maybe the newer version supports registry URLs?

How to use Terragrunt with Terraform Registry modules without rewriting them to git URLs?

No way to do so now AFAIK

@brikis98 brikis98 added enhancement New feature or request help wanted labels Oct 8, 2017
@antonbabenko
Copy link
Contributor Author

AFAIK Terraform 0.11 will have better support for the registry, and for now, I will use git URLs. Thank you!

@ghost
Copy link

ghost commented Oct 31, 2017

How can you use git urls to the registry modules when those modules don't include the

terraform {
  backend "s3" {}
}

provider "aws" {
  region = "${var.region}"
}

parts that are necessary to use a module within terragrunt?

I tried defining a module in my modules repo, but that doesn't seem to work. I have prod/vpc/main.tf which looks like this:

terraform {
  backend "s3" {}
}

provider "aws" {
  region = "${var.region}"
}

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = "${var.name}"

  cidr = "${var.cidr}"

  azs                 = ["${var.azs}"]
  private_subnets     = ["${var.private_subnets}"]
  public_subnets      = ["${var.public_subnets}"]
  database_subnets    = ["${var.database_subnets}"]
  elasticache_subnets = ["${var.elasticache_subnets}"]
  
  create_database_subnet_group = "${var.create_database_subnet_group}"
  
  enable_nat_gateway = "${var.enable_nat_gateway}"
  
  enable_s3_endpoint       = "${var.enable_s3_endpoint}"
  enable_dynamodb_endpoint = "${var.enable_dynamodb_endpoint}"
} 

But when I try to do any terragrunt commands, it blows up with errors. So it seems like there is no way to use the module repository with terragrunt? Doesn't that pretty much defeat the purpose of terragrunt and its emphasis on DRY when I have to completely duplicate the code in a repository module in my own module in order to use terragrunt?

@antonbabenko
Copy link
Contributor Author

@sgendler-stem I have just published the minimalistic code I use for this: https://gist.github.com/antonbabenko/2ca1225589c7c6d42f476f97d779d4ff

@brikis98
Copy link
Member

But when I try to do any terragrunt commands, it blows up with errors.

What errors?

@antonbabenko
Copy link
Contributor Author

The error @sgendler-stem is referring to was probably related to file named main.tf which is overwritten with the one you provide, but this is just a guess. :)

@brikis98
Copy link
Member

to file named main.tf which is overwritten with the one you provide

What do you mean? Terragrunt doesn't "provide" any main.tf files...

@antonbabenko
Copy link
Contributor Author

It is not a problem of Terragrunt, but how files are named in main.tf (prod/vpc/main.tf) and the one provided by Terraform VPC module. Point 2

@brikis98
Copy link
Member

Sorry, still not entirely following. Are you saying that @sgendler-stem has a main.tf file in the local folder that includes terraform-aws-modules/vpc/aws as a module and a terraform.tfvars file that sets the source param also to terraform-aws-modules/vpc/aws?

If so, then yes, one of the main.tf files would override the other. The solution, of course, is to either (a) put the local main.tf file into a separate folder/repo and point the source param in terraform.tfvars to that folder/repo or (b) not use Terragrunt at all and just directly run init, plan, and apply on the local main.tf.

@ghost
Copy link

ghost commented Oct 31, 2017 via email

@brikis98
Copy link
Member

If I'm understanding the comment stream here, I guess terragrunt/terraform is pulling everything into a single directory structure somewhere and one vpc/main.tf file is overwriting the other rather than co-existing with it.

That depends on how you have Terragrunt configured. What does your terraform.tfvars file contain? What is your directory structure?

It's things like the devops VPC with VPN access and connections to all other environments, and a fully functional CI/CD pipeline which are more complex and time-consuming to automate.

The IAC library has code to set up VPCs, OpenVPN, and Jenkins, which will save you a bunch of time, but it's the Ref Arch that ties all those pieces together into an end-to-end solution, which is also a big time saver. Whether the Ref Arch make sense for you depends on your needs, so feel free to email me if you want more info!

@ghost
Copy link

ghost commented Oct 31, 2017 via email

@brikis98
Copy link
Member

But then it didn't work, anyway, due to the file name conflict.

Based on your usage, I don't see how there could be a file name conflict. Terragrunt will download the module from your vpc-modules repo into a tmp folder. It will then call terraform init on it, which should result in the VPC module being downloaded from the Terraform registry into a .terraform folder within the tmp folder.

Could you paste the log output from running Terragrunt?

@ghost
Copy link

ghost commented Oct 31, 2017 via email

@brikis98
Copy link
Member

OK, keep us posted!

You may find these two example repos helpful with setting up Terragrunt:

https://github.com/gruntwork-io/terragrunt-infrastructure-live-example
https://github.com/gruntwork-io/terragrunt-infrastructure-modules-example

@ghost
Copy link

ghost commented Nov 2, 2017

I still cannot get ANYTHING terragrunt to function correctly. I seem to be bouncing off as many as a half-dozen separate bugs, so my different attempts to workaround problems always just bang into another bug. I've had emails, phone conversations, purchased the gruntworks library, and read every word of available documentation but I'll be damned if I can get terragrunt to work in even the most basic context. Here's the VERY long email I just sent covering every single variation and the resulting error messages


This email actually maybe encapsulates 4 or 5 separate terraform and terrragrunt bugs, but it is possible that one bug is actually causing a domino effect to all the others. I cannot separate them since I cannot get even the most basic functionality to work when it comes to terragrunt.

$ terragrunt -version
terragrunt version v0.13.15
$ terraform -version
Terraform v0.10.8

When I specify a -terraform-source with the double-slash after the directory that represents the top of my modules repo, I get a warning that terraform was initialized in an empty directory and the path it uses in the logs is then missing the directory name ater the double-slash. If I leave the double-slash off, it actually works correctly, but it also emits a warning about missing double-slash in the terragrunt-source value (ignore the error at the end and look at the paths in the text output):

$ terragrunt init --terragrunt-source ../../../../../stem-infra//vpc_mgmt/
[terragrunt] [/Users/sgendler/src/stem/stem-envs/aws2/us-east-1/_global/vpc_mgmt] 2017/11/01 19:07:27 Running command: terraform --version
[terragrunt] 2017/11/01 19:07:27 Reading Terragrunt config file at /Users/sgendler/src/stem/stem-envs/aws2/us-east-1/_global/vpc_mgmt/terraform.tfvars
[terragrunt] 2017/11/01 19:07:27 Cleaning up existing *.tf files in /var/folders/xr/t6gsrby97350k0r85qr7blzh0000gn/T/terragrunt/1-Fiw_rVrVmzIDHkzOu35z2CQn0/N7YR7JXFv_AHrQ_vUpC9GGTlLbM
[terragrunt] 2017/11/01 19:07:27 Downloading Terraform configurations from file:///Users/sgendler/src/stem/stem-infra into /var/folders/xr/t6gsrby97350k0r85qr7blzh0000gn/T/terragrunt/1-Fiw_rVrVmzIDHkzOu35z2CQn0/N7YR7JXFv_AHrQ_vUpC9GGTlLbM using terraform init
[terragrunt] [/Users/sgendler/src/stem/stem-envs/aws2/us-east-1/_global/vpc_mgmt] 2017/11/01 19:07:27 Backend s3 has not changed.
[terragrunt] [/Users/sgendler/src/stem/stem-envs/aws2/us-east-1/_global/vpc_mgmt] 2017/11/01 19:07:28 Running command: terraform init -backend-config=bucket=stem-terraform-state-bucket -backend-config=key=aws2/us-east-1/_global/vpc_mgmt/terraform.tfstate -backend-config=region=us-west-2 -backend-config=encrypt=true -backend-config=dynamodb_table=terraform-lock-table -lock-timeout=20m -from-module=file:///Users/sgendler/src/stem/stem-infra /var/folders/xr/t6gsrby97350k0r85qr7blzh0000gn/T/terragrunt/1-Fiw_rVrVmzIDHkzOu35z2CQn0/N7YR7JXFv_AHrQ_vUpC9GGTlLbM
Copying configuration from "file:///Users/sgendler/src/stem/stem-infra"...
Terraform initialized in an empty directory!

The directory has no Terraform configuration files. You may begin working
with Terraform immediately by creating Terraform configuration files.
[terragrunt] 2017/11/01 19:07:28 Copying files from /Users/sgendler/src/stem/stem-envs/aws2/us-east-1/_global/vpc_mgmt into /var/folders/xr/t6gsrby97350k0r85qr7blzh0000gn/T/terragrunt/1-Fiw_rVrVmzIDHkzOu35z2CQn0/N7YR7JXFv_AHrQ_vUpC9GGTlLbM/vpc_mgmt
[terragrunt] 2017/11/01 19:07:28 Setting working directory to /var/folders/xr/t6gsrby97350k0r85qr7blzh0000gn/T/terragrunt/1-Fiw_rVrVmzIDHkzOu35z2CQn0/N7YR7JXFv_AHrQ_vUpC9GGTlLbM/vpc_mgmt
[terragrunt] 2017/11/01 19:07:28 Backend s3 has not changed.
[terragrunt] 2017/11/01 19:07:28 Running command: terraform init -backend-config=bucket=stem-terraform-state-bucket -backend-config=key=aws2/us-east-1/_global/vpc_mgmt/terraform.tfstate -backend-config=region=us-west-2 -backend-config=encrypt=true -backend-config=dynamodb_table=terraform-lock-table -lock-timeout=20m
Downloading modules...

Initializing the backend...
Error getting plugins: module root: 
    module mgmt_vpc: required variable "aws_region" not set
    module mgmt_vpc: required variable "vpc_name" not set
[terragrunt] 2017/11/01 19:07:33 exit status 1

If I leave off the double-slash, I get the following output (the same holds true if I use absolute or relative path and if I include a trailing slash or not):

$ terragrunt init --terragrunt-source ../../../../../stem-infra/vpc_mgmt/
[terragrunt] [/Users/sgendler/src/stem/stem-envs/aws2/us-east-1/_global/vpc_mgmt] 2017/11/01 19:31:37 Running command: terraform --version
[terragrunt] 2017/11/01 19:31:37 Reading Terragrunt config file at /Users/sgendler/src/stem/stem-envs/aws2/us-east-1/_global/vpc_mgmt/terraform.tfvars
[terragrunt] 2017/11/01 19:31:37 WARNING: no double-slash (//) found in source URL /Users/sgendler/src/stem/stem-infra/vpc_mgmt. Relative paths in downloaded Terraform code may not work.
[terragrunt] 2017/11/01 19:31:37 Cleaning up existing *.tf files in /var/folders/xr/t6gsrby97350k0r85qr7blzh0000gn/T/terragrunt/1-Fiw_rVrVmzIDHkzOu35z2CQn0/iZO4VuAlCkzTzqA4H4VI2GwKYAs
[terragrunt] 2017/11/01 19:31:37 Downloading Terraform configurations from file:///Users/sgendler/src/stem/stem-infra/vpc_mgmt into /var/folders/xr/t6gsrby97350k0r85qr7blzh0000gn/T/terragrunt/1-Fiw_rVrVmzIDHkzOu35z2CQn0/iZO4VuAlCkzTzqA4H4VI2GwKYAs using terraform init
[terragrunt] [/Users/sgendler/src/stem/stem-envs/aws2/us-east-1/_global/vpc_mgmt] 2017/11/01 19:31:37 Backend s3 has not changed.
[terragrunt] [/Users/sgendler/src/stem/stem-envs/aws2/us-east-1/_global/vpc_mgmt] 2017/11/01 19:31:38 Running command: terraform init -backend-config=bucket=stem-terraform-state-bucket -backend-config=key=aws2/us-east-1/_global/vpc_mgmt/terraform.tfstate -backend-config=region=us-west-2 -backend-config=encrypt=true -backend-config=dynamodb_table=terraform-lock-table -lock-timeout=20m -from-module=file:///Users/sgendler/src/stem/stem-infra/vpc_mgmt /var/folders/xr/t6gsrby97350k0r85qr7blzh0000gn/T/terragrunt/1-Fiw_rVrVmzIDHkzOu35z2CQn0/iZO4VuAlCkzTzqA4H4VI2GwKYAs
Copying configuration from "file:///Users/sgendler/src/stem/stem-infra/vpc_mgmt"...
Downloading modules...

Initializing the backend...
Error getting plugins: module root: 
    module mgmt_vpc: required variable "vpc_name" not set
    module mgmt_vpc: required variable "aws_region" not set
[terragrunt] 2017/11/01 19:31:41 exit status 1

Meanwhile, if I commit my code in the module repo, push it to origin, and then remove the terragrunt-source directive from the command entirely, I get a completely different error:

In the module repo:

$ git add -A
$ git commit
[develop 25f843b] bugs
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git push
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 390 bytes | 0 bytes/s, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To https://github.com/stems/stem-infra.git
   835d8a4..25f843b  develop -> develop

Now in the live repo:

$ terragrunt init
[terragrunt] [/Users/sgendler/src/stem/stem-envs/aws2/us-east-1/_global/vpc_mgmt] 2017/11/01 19:38:16 Running command: terraform --version
[terragrunt] 2017/11/01 19:38:16 Reading Terragrunt config file at /Users/sgendler/src/stem/stem-envs/aws2/us-east-1/_global/vpc_mgmt/terraform.tfvars
[terragrunt] 2017/11/01 19:38:16 Terraform files in /var/folders/xr/t6gsrby97350k0r85qr7blzh0000gn/T/terragrunt/1-Fiw_rVrVmzIDHkzOu35z2CQn0/a5cQNEi863WkyLAUB3yQSFHlvbM/vpc_mgmt are up to date. Will not download again.
[terragrunt] 2017/11/01 19:38:16 Copying files from /Users/sgendler/src/stem/stem-envs/aws2/us-east-1/_global/vpc_mgmt into /var/folders/xr/t6gsrby97350k0r85qr7blzh0000gn/T/terragrunt/1-Fiw_rVrVmzIDHkzOu35z2CQn0/a5cQNEi863WkyLAUB3yQSFHlvbM/vpc_mgmt
[terragrunt] 2017/11/01 19:38:16 Setting working directory to /var/folders/xr/t6gsrby97350k0r85qr7blzh0000gn/T/terragrunt/1-Fiw_rVrVmzIDHkzOu35z2CQn0/a5cQNEi863WkyLAUB3yQSFHlvbM/vpc_mgmt
[terragrunt] 2017/11/01 19:38:16 Initializing remote state for the s3 backend
[terragrunt] 2017/11/01 19:38:17 Running command: terraform init -backend-config=encrypt=true -backend-config=dynamodb_table=terraform-lock-table -backend-config=bucket=stem-terraform-state-bucket -backend-config=key=aws2/us-east-1/_global/vpc_mgmt/terraform.tfstate -backend-config=region=us-west-2 -lock-timeout=20m
There are some problems with the configuration, described below.

The Terraform configuration must be valid before initialization so that
Terraform can determine which modules and providers need to be installed.

Error: Error parsing /private/var/folders/xr/t6gsrby97350k0r85qr7blzh0000gn/T/terragrunt/1-Fiw_rVrVmzIDHkzOu35z2CQn0/a5cQNEi863WkyLAUB3yQSFHlvbM/vpc_mgmt/main.tf: key '"${var.public_subnets_cidr_blocks}"' expected start of object ('{') or assignment ('=')


[terragrunt] 2017/11/01 19:38:17 exit status 1

It would seem that that error is because Terragrunt is totally failing to see that the file in the module repo has changed. I know it is using the correct branch for 2 reasons - first, I can see the ref in the URL. Second, the vpc_mgmt directory ONLY exists in the develop branch. It hasn't been merged into master. And those are the only 2 branches or tags. So it must be using the correct branch, but it is using an ancient version of the file that I have updated repeatedly over the last several hours while trying to figure this stuff out. When I look at the path in /private/var/folders..., I can see that there is a typo - one that I fixed 5 or 6 commits ago - and yes, I pushed the commits to origin. I even validated them via web browser. So terragrunt is most definitely failing to notice that the template in the module repo has been updated. It doesn't matter how long I wait after the commit before running init - so it isn't an eventual consistency problem.

Additionally, that command you gave me for inclusion in the terraform.tfvars file for setting extra tfvars files is not getting applied when I run terraform init . Which explains why it isn't picking up the aws_region and vpc_name variables, both of which are defined in region.tfvars and env.tfvars, respectively. If I run terragrunt plan without terragrunt init, it complains about missing modules, but I can see that the extra .tfvars files are included in the command. So it would seem that 'init' is, for some reason, not included in the output of get_terraform_commands_that_need_vars() even thought it is clearly a command that does need vars.

My modules repo looks like this:

stem-infra
stem-infra/vpc_mgmt
stem-infra/vpc_mgmt/main.tf
stem-infra/vpc_mgmt/outputs.tf
stem-infra/vpc_mgmt/vars.tf

main.tf looks like this:

terraform {
  backend "s3" {}
}

provider "aws" {
  region = "${var.aws_region}"
}

module mgmt_vpc {
  source = "git@github.com:gruntwork-io/module-vpc.git//modules/vpc-mgmt?ref=v0.3.0"

  cidr_block                    = "${var.cidr_block}"
  public_subnet_cidr_blocks     = ["${var.public_subnet_cidr_blocks}"]
  private_subnet_cidr_blocks    = ["${var.private_subnet_cidr_blocks}"]
  num_nat_gateways              = "${var.num_nat_gateways}"
}

My live repo looks like this:

stem-envs/aws1
stem-envs/aws2
stem-envs/aws2/_global
stem-envs/aws2/account.tfvars
stem-envs/aws2/us-east-1
stem-envs/aws2/us-east-1/_global
stem-envs/aws2/us-east-1/_global/env.tfvars
stem-envs/aws2/us-east-1/_global/vpc_mgmt
stem-envs/aws2/us-east-1/_global/vpc_mgmt/terraform.tfvars
stem-envs/aws2/us-east-1/prod
stem-envs/aws2/us-east-1/prod/vpc_mgmt
stem-envs/aws2/us-east-1/region.tfvars
stem-envs/aws2/us-east-1/staging
stem-envs/aws2/us-east-1/test
stem-envs/README.md
stem-envs/terraform.tfvars

My outermost terraform.tfvars is as follows:

terragrunt = {
  remote_state {
    backend = "s3"

    config {
      bucket = "stem-terraform-state-bucket"
      key    = "${path_relative_to_include()}/terraform.tfstate"
      region = "us-west-2"
      encrypt = true
      dynamodb_table = "terraform-lock-table"
    }
  }

  terraform {
    extra_arguments "common_vars" {
      commands = ["${get_terraform_commands_that_need_vars()}"]

      optional_var_files = [
        "${get_tfvars_dir()}/${find_in_parent_folders("account.tfvars", "skip-account-if-does-not-exist")}",
        "${get_tfvars_dir()}/${find_in_parent_folders("region.tfvars", "skip-region-if-does-not-exist")}",
        "${get_tfvars_dir()}/${find_in_parent_folders("env.tfvars", "skip-env-if-does-not-exist")}",
        "${get_tfvars_dir()}/terraform.tfvars"
      ]
    }

    extra_arguments "retry_lock" {
      commands = ["${get_terraform_commands_that_need_locking()}"]
      arguments = ["-lock-timeout=20m"]
    }
  }
}

The vpc_mgmt/terraform.tfvars file looks like this:

terragrunt = {
  terraform {
    source = "git::ssh://git@github.com/stems/stem-infra.git//vpc_mgmt?ref=develop"
  }
  include {
    path = "${find_in_parent_folders()}"
  }
}

cidr_block = "10.0.0.0/8"

public_subnets_cidr_blocks = {
  AZ-0 = "10.0.1.0/16"
  AZ-1 = "10.0.10.0/16"
  AZ-2 = "10.0.20.0/16"
  AZ-3 = "10.0.30.0/16"
  AZ-4 = "10.0.40.0/16"
  AZ-5 = "10.0.50.0/16"
}

private_subnets_cidr_blocks = {
  AZ-0 = "10.1.1.0/16"
  AZ-1 = "10.1.10.0/16"
  AZ-2 = "10.1.20.0/16"
  AZ-3 = "10.1.30.0/16"
  AZ-4 = "10.1.40.0/16"
  AZ-5 = "10.1.50.0/16"
}

num_nat_gateways = 4

env.tfvars has:

vpc_name = "mgmt"

region.tfvars has:

aws_region = "us-east-1"

And for my final problem, I cannot find any mention, in any documentation anywhere, of a way to pass maps around as variables. How do I do the assignment? I can assign a list like this:

module "my_module" {
  source = "..."
  new_var = ["${var.old_var}"]
}

but

module "my_module" {
  source = "..."
  new_var = {"${var.old_var}"}
}

results in syntax errors. The documentation about variables AND the documentation about modules fails to provide an example of passing a list or a map from a template variable through to a module variable. It looks like maybe your modules just use the list assignment syntax, so maybe casting a list to a map does the correct thing automatically, but some documentation would be nice. Google searches result in old bugs about total inability to pass maps at all, but I think those are out of date. I'd test it and just see what happens but I can't because nothing works - and I have no idea if the reason nothing works is because of the maps. Or, at the very least if maps cannot be passed, there must be standard workaround for converting to strings and then parsing them back out, since I'm sure you cannot build your library without the ability to pass maps at all. It would be nice if such methods were published somewhere. The same goes for any other standard workarounds for functional deficiencies.


I'm starting to be convinced that the problem isn't user error, here, and that there are a whole host of bugs in the current release of terragrunt that actually prevent it from working at all, no matter how it is set up. Maybe it works once it is initialized and working, but it doesn't seem able to accomplish initialization. I sure cannot figure out any way to specify a source, either in terraform.tfvars or in -terragrunt-source, so I cannot work in github AND I cannot work on the local filesystem. I also cannot get terragrunt to recognize changes in the repo, so it would be trivially easy to accidentally push broken or old infrastructure once I did have working config.

Frankly, despite all of my positive feedback earlier today, the fact that I cannot get even the most basic of configuration to actually function after several days of time-wasting, many emails and posts to issues, a 90 minute support call, and reading every piece of documentation that is out there doesn't exactly give me warm and funzzy feelings about using terraform or terragrunt in a production environment. I still have yet to get a single thing to work (and I'm not exactly a novice when it comes to devops and configuration and infrastructure management), whether using publicly available modules or your gruntworks library and whether I use the practices in Evgeniy's book or incorporate some of the changes we discussed today. It just doesn't work, and I'll be damned if I can uncover a reason.

@josh-padnick
Copy link
Contributor

@sgendler-stem Thank you for all the details, and I'm really sorry about the trouble you've been having. We actively maintain Terragrunt, have a battery of automated tests, and an active community of worldwide users, so this level of frustration is surprising.

First, there seem to be several cases where your code is returning Terraform errors, not Terragrunt errors. For example:

Error getting plugins: module root: 
    module mgmt_vpc: required variable "aws_region" not set
    module mgmt_vpc: required variable "vpc_name" not set
Error: Error parsing /private/var/.../vpc_mgmt/main.tf: key '"${var.public_subnets_cidr_blocks}"' expected start of object ('{') or assignment ('=')

are both Terraform errors, and:

new_var = {"${old_var}"}

is invalid HCL syntax.

That being said, it sounds like the temp folder where Terragrunt downloads module files may not be updating correctly, which would definitely be a Terragrunt issue.

Here are some immediate suggestions for a resolution:

  1. First, can you send a ZIP of your entire Terraform config that is failing to support@gruntwork.io? I'd like to repro this issue and see if I can identify the root issue.

  2. On your question regarding how to pass maps in the terraform.tfvars file, keep in mind that this file is pure HCL, and these are just key-value pairs. So here are some examples of valid syntax:

    # string
    new_var = "string"
    
    # boolean
    new_var = true 
    
    # int
    new_var = 0
    
    # list
    new_var = ["bert", "ernie"]
    
    # map
    new_var = {
       key1 = "val1"
       key2 = "Note that only strings are supported for map values"
    }
  3. For the error required variable "aws_region" not set, this suggests that Terraform is missing this var. From our discussion earlier today, I'm assuming you intend to populate this from a region.vars file which is auto-populated by Terragrunt per https://github.com/gruntwork-io/terragrunt#required-and-optional-var-files.

    Can you double-check that your "leaf" terraform.tfvars file is using an include per https://github.com/gruntwork-io/terragrunt#filling-in-remote-state-settings-with-terragrunt? Do you have a region.tfvars file in a parent folder above that terraform.tfvars file? Does the "root" terraform.tfvars file include the syntax shown at https://github.com/gruntwork-io/terragrunt#required-and-optional-var-files?

  4. Finally, one fail-safe way to get Terragrunt to refresh the cache is to use the --terragrunt-source-update option with any terragrunt command. This will flush the cache entirely and re-download everything from scratch. Keep in mind you can also look to see which tmp folder Terragrunt is using and visit it directly on your system to inspect what's there. You can even run terraform commands directly from that directory.

    I'd also encourage you to make use of the --terragrunt-source /local/path/to/module property, which will override whatever is in your source property in terraform.tfvars with the given value. This is especially handy for local development so that you don't have to push to git just to test your code.

I wish I had a more definitive resolution, but hopefully this gives you some leads. In the meantime, send us your full Terraform config, and we'll try to reproduce your issue. If we can reproduce your bugs, we'll gladly fix those.

Either way, we'll work this through to completion and identify the underlying causes of confusion, which surely will or already have tripped up others. The fact that you reached this level of frustration suggests that Terragrunt perhaps does not provide enough "guard rails" or makes a fundamental assumption that's not clear to the end user, so we'll consider what we can do to avoid those issues.

Thank you for your feedback!

@ghost
Copy link

ghost commented Nov 2, 2017

Unfortunately, there's nothing in your response that I'm not already aware of. The terraform errors are a result of terragrunt errors. For example, since init isn't listed as a command that requires vars, it isn't picking up aws_region and vpc_name. The -from-module flag NEVER includes the module directory, whether I use // or / in the github url OR the terragrunt-source directory specification. I'd love to use -terragrunt-source so I don't have to fight with github for every minor change, but terragrunt-source would have to actually work correctly for me to do that.

I eventually fixed the lack of env.tfvars and region.tfvars by specifying the commands as:

commands = ["${get_terraform_commands_that_need_vars()}", "init"]

in order to add init to the list of commands that need vars - since I cannot use ${concat()} in a terraform.tfvars file, which seemed the more natural way to add items to a list.

Your examples of HCL syntax still don't explain how to assign lists and maps that are already contained in template variables, when trying to pass them to a module. I know I can do this:

var = "value"
var2 = ["value2", "value2"]
var3 = {
  key1 = "value1"
  key2 = "value2"
}

because that's pretty much the sum-total of documentation of how to initialize variables in all terraform and terragrunt docs.

and it seems that if I want to pass a list, I do the following:

var3 = ["${var.list_var}"]

But I picked that up by seeing examples rather than because it seems to be documented anywhere.

So it seemed natural to pass a map by doing the following:

var4 = {"${var.map_var}"}

but that results in a syntax error.

Maybe it's possible that this is perfectly legal (no quotes, so the value is just assigned straight across?)

var3 = ${var.list_var}

but this next variant would surely create a string rather than a list, no? And I have the impression that variable interpolation only happens inside quoted strings, so I'm not sure how this wouldn't result in a string being assigned to var4

var4 = "${var.list_var}"

which implies that the previous (var3) mechanism actually coerces the list to a comma-delimited string and then parses that string when it is passed as the value of a list, since it certainly doesn't seem to create a list of a list, which is what I would otherwise expect. So that leaves me with two assumptions - that I cannot pass a map from a template var to a module var or else that I have to do so by coercing the map to a list of alternating key and value and then parse that back into a map. If ["${var.my_list}"] coerces my_list into a string that gets parsed back into a list, then surely {"${var.my_map}"} would coerce a map into a string and parse it back into a map, right? Except that doesn't seem to be the case since it throws syntax errors. Instead, it seems that maybe coercing a map to a list gives me the alternative key and value list, and then coercing that list to a map does actually get me a map. Fine, I can live with that, but surely that's worth documenting somewhere? The HCL docs provide no clue, since they don't say one word about variable interpolation during assignment - a rather dramatic oversight in a language ostensibly designed for interpolation.

I'm guessing something like this might work:

var5 = {["${var.map_var}"]}

coercing the map to a list and the list to a map.

and it is possible that if var6 inside the module is a map type, that simply doing this ```var6 = ["${var.another_map_var}"] will cause the coercion to map to happen correctly when var6 is passed to the module, but again, that kind of coercion and parsing shouldn't be happening without some kind of explanation in a document somewhere - that's an enormous amount of coding by trial and error to figure out since it is far from the most obvious place to start, and for a feature that every single user is likely to get stuck on within their first day of using terragrunt and your library if they follow your suggested best-practices, since every module is going to get called from a template and pretty much every module receives at least one map in an input variable, so this problem must be encountered constantly by new users.

None of the isted tricks seemed to work, incidentally, since I'm setting a map for public and private subnets in my terraform.tfvars file, then in my vpc template's main.tf, I try to pass that to your vpc-mgmt module, but it is apparently not working because I am not picking up the subnets I specify in the map I am passing in. I believe I have tried every variant suggested in this comment, so I still do not see how I can get a map from terraform.tfvars in my live repo to be passed into my template vars and then into my module - the kind of thing I'd have thought might be covered in the first page of documentation for how to use your library, honestly, since absolutely anyone attempting to use it will surely have a structure pretty much identical to mine.

@ghost
Copy link

ghost commented Nov 2, 2017

And for what it is worth, purging all of the source files results in huge delays while I wait 20+ minutes for provider plugins to download from Hashicorp. I'm not sure why those are so slow, but they are. The null provider required 5-10 minutes and each subsequent provider requires 2 or 3 minutes. It's very frustrating and completely eliminates the possibility of doing anything quickly, but I have to do it on every command or else I don't pick up the latest changes from github. It's not a networking problem, as I can pull the zip files from releases.hashicorp.com in a second or less. It's really not clear exactly what it is spending all of that time on.

I can download the aws provider from the server in a half second, but downloading the plugin via terraform/terragrunt requires 10+ minutes.

@ghost
Copy link

ghost commented Nov 2, 2017

Finally, to add to the list of bugs/documentation problems, I included 5 or 6 subnets in my map, under the assumption that it would use 4 of them because that's how many availability zones there are. Instead, it seems to have used the size of my map to generate public and private subnets for imaginary availability zones, even while it didn't actually use the cidr blocks that my map provided for those subnets - public or private. That's a little disappointing.

Here's the bottom section of my plan output:

  + module.mgmt_vpc.aws_subnet.private[5]
      id:                               <computed>
      assign_ipv6_address_on_creation:  "false"
      availability_zone:                "us-east-1f"
      cidr_block:                       "10.120.0.0/13"
      ipv6_cidr_block:                  <computed>
      ipv6_cidr_block_association_id:   <computed>
      map_public_ip_on_launch:          "false"
      tags.%:                           "1"
      tags.Name:                        "mgmt-private-5"
      vpc_id:                           "${aws_vpc.main.id}"

  + module.mgmt_vpc.aws_subnet.public[0]
      id:                               <computed>
      assign_ipv6_address_on_creation:  "false"
      availability_zone:                "us-east-1a"
      cidr_block:                       "10.0.0.0/13"
      ipv6_cidr_block:                  <computed>
      ipv6_cidr_block_association_id:   <computed>
      map_public_ip_on_launch:          "false"
      tags.%:                           "1"
      tags.Name:                        "mgmt-public-0"
      vpc_id:                           "${aws_vpc.main.id}"

  + module.mgmt_vpc.aws_subnet.public[1]
      id:                               <computed>
      assign_ipv6_address_on_creation:  "false"
      availability_zone:                "us-east-1b"
      cidr_block:                       "10.8.0.0/13"
      ipv6_cidr_block:                  <computed>
      ipv6_cidr_block_association_id:   <computed>
      map_public_ip_on_launch:          "false"
      tags.%:                           "1"
      tags.Name:                        "mgmt-public-1"
      vpc_id:                           "${aws_vpc.main.id}"

  + module.mgmt_vpc.aws_subnet.public[2]
      id:                               <computed>
      assign_ipv6_address_on_creation:  "false"
      availability_zone:                "us-east-1c"
      cidr_block:                       "10.16.0.0/13"
      ipv6_cidr_block:                  <computed>
      ipv6_cidr_block_association_id:   <computed>
      map_public_ip_on_launch:          "false"
      tags.%:                           "1"
      tags.Name:                        "mgmt-public-2"
      vpc_id:                           "${aws_vpc.main.id}"

  + module.mgmt_vpc.aws_subnet.public[3]
      id:                               <computed>
      assign_ipv6_address_on_creation:  "false"
      availability_zone:                "us-east-1d"
      cidr_block:                       "10.24.0.0/13"
      ipv6_cidr_block:                  <computed>
      ipv6_cidr_block_association_id:   <computed>
      map_public_ip_on_launch:          "false"
      tags.%:                           "1"
      tags.Name:                        "mgmt-public-3"
      vpc_id:                           "${aws_vpc.main.id}"

  + module.mgmt_vpc.aws_subnet.public[4]
      id:                               <computed>
      assign_ipv6_address_on_creation:  "false"
      availability_zone:                "us-east-1e"
      cidr_block:                       "10.32.0.0/13"
      ipv6_cidr_block:                  <computed>
      ipv6_cidr_block_association_id:   <computed>
      map_public_ip_on_launch:          "false"
      tags.%:                           "1"
      tags.Name:                        "mgmt-public-4"
      vpc_id:                           "${aws_vpc.main.id}"

  + module.mgmt_vpc.aws_subnet.public[5]
      id:                               <computed>
      assign_ipv6_address_on_creation:  "false"
      availability_zone:                "us-east-1f"
      cidr_block:                       "10.40.0.0/13"
      ipv6_cidr_block:                  <computed>
      ipv6_cidr_block_association_id:   <computed>
      map_public_ip_on_launch:          "false"
      tags.%:                           "1"
      tags.Name:                        "mgmt-public-5"
      vpc_id:                           "${aws_vpc.main.id}"

  + module.mgmt_vpc.aws_vpc.main
      id:                               <computed>
      assign_generated_ipv6_cidr_block: "false"
      cidr_block:                       "10.0.0.0/8"
      default_network_acl_id:           <computed>
      default_route_table_id:           <computed>
      default_security_group_id:        <computed>
      dhcp_options_id:                  <computed>
      enable_classiclink:               <computed>
      enable_classiclink_dns_support:   <computed>
      enable_dns_hostnames:             "true"
      enable_dns_support:               "true"
      instance_tenancy:                 "default"
      ipv6_association_id:              <computed>
      ipv6_cidr_block:                  <computed>
      main_route_table_id:              <computed>
      tags.%:                           "1"
      tags.Name:                        "mgmt"

  + module.mgmt_vpc.aws_vpc_endpoint.s3-private
      id:                               <computed>
      cidr_blocks.#:                    <computed>
      policy:                           <computed>
      prefix_list_id:                   <computed>
      route_table_ids.#:                <computed>
      service_name:                     "com.amazonaws.us-east-1.s3"
      vpc_id:                           "${aws_vpc.main.id}"

  + module.mgmt_vpc.aws_vpc_endpoint.s3-public
      id:                               <computed>
      cidr_blocks.#:                    <computed>
      policy:                           <computed>
      prefix_list_id:                   <computed>
      route_table_ids.#:                <computed>
      service_name:                     "com.amazonaws.us-east-1.s3"
      vpc_id:                           "${aws_vpc.main.id}"

  + module.mgmt_vpc.null_resource.vpc_ready
      id:                               <computed>

And here are the subnets that should have been assigned - I know the map must have been passed through correctly, since it does create 6 subnets in a region that only has 4 AZs, but the cidr blocks have no relationship to the cidr blocks in the maps I passed in.

cidr_block = "10.0.0.0/8"

public_subnets_cidr_blocks = {
  AZ-0 = "10.0.1.0/16"
  AZ-1 = "10.0.10.0/16"
  AZ-2 = "10.0.20.0/16"
  AZ-3 = "10.0.30.0/16"
  AZ-4 = "10.0.40.0/16"
  AZ-5 = "10.0.50.0/16"
}

private_subnets_cidr_blocks = {
  AZ-0 = "10.1.1.0/16"
  AZ-1 = "10.1.10.0/16"
  AZ-2 = "10.1.20.0/16"
  AZ-3 = "10.1.30.0/16"
  AZ-4 = "10.1.40.0/16"
  AZ-5 = "10.1.50.0/16"
}

num_nat_gateways = 4

@ghost
Copy link

ghost commented Nov 2, 2017

Caught the typo in my CIDR blocks - but it didn't fix anything in the cidr assignments.

cidr_block = "10.0.0.0/16"

public_subnets_cidr_blocks = {
  AZ-0 = "10.0.1.0/22"
  AZ-1 = "10.0.10.0/22"
  AZ-2 = "10.0.20.0/22"
  AZ-3 = "10.0.30.0/22"
}

private_subnets_cidr_blocks = {
  AZ-0 = "10.0.100.0/22"
  AZ-1 = "10.0.110.0/22"
  AZ-2 = "10.0.120.0/22"
  AZ-3 = "10.0.130.0/22"
}

num_nat_gateways = 4

It turns out that my variable names had a typo in them - subnets shouldn't be plural. Is there a way to get terraform to be strict about variables passed to modules so that if a variable is passed in which is not in the inputs for the module it generates an error rather than silently using defaults?

@josh-padnick
Copy link
Contributor

There are just too many interconnected issues to here respond to them effectively async. I'll PM you with a link and if you're available, we can chat real-time to resolve some of these issues.

@ghost
Copy link

ghost commented Nov 2, 2017

I have everything working, finally. Some were simply typos in variable names (a strict mode would be super helpful here, as the error messages, if they exist at all, are often not that useful).

I worked around 'info' not being in the list of commands that require vars by appending it to the list.

module_map_var = "${var.template_map_var}" in the module block actually seems to do the correct thing, though it took me forever to get things running well enough to determine that since there was no documentation to suggest it and many list examples seemed to indicate that it wouldn't work correctly, since they all use square brackets around the interpolation string.

The --terragrunt-source flag and the source parameter in the module block do appear to be broken - the '//' that is supposed to precede the module name doesn't seem to get handled correctly and it generates warnings about empty directories - but then it does the correct thing under the hood, pulling the whole repo into the 'empty' directory, which results in the correct thing being pulled into the temp dir - but that is perhaps merely a lucky artifact resulting from using a module repo that keeps each module in the root of the repo, so it creates an empty temp dir and then pulls the entire content of the module repo into that empty temp dir. Since that creates a directory called vpc_mgmt as an accident of my naming convention, I seem to get lucky and terraform does the right thing even though the -from-module flag is incorrect in the terraform command, since the directory gets created accidentally. So it is working, but will cease to work as soon as I try to load a template that isn't one level deep inside my module repo or I use a template in a directory that doesn't match the name in the live repo. There are loads of warnings in the output, but at least it accidentally works.

provider downloads are super slow and I don't seem able to trust terragrunt/terraform to correctly detect changes in the module repo, whether using github/ssh or --terragrunt-source override, so I'm forced to suffer the slow downloads by clearing the temp files on every run.

@josh-padnick
Copy link
Contributor

Great to see the issues are resolved.

I have everything working, finally. Some were simply typos in variable names

Ok, glad to see at least some items in here are user error. :)

(a strict mode would be super helpful here, as the error messages, if they exist at all, are often not that useful).

This is a general issue with Terraform (see #14324, #15377, and #15053), though I generally find the errors around missing variables are usually pretty clear. I'm not sure what Terragrunt could really do here...

I worked around 'info' not being in the list of commands that require vars by appending it to the list.

I think you mean terraform init? If you run terraform init --help you'll see that terraform init doesn't actually accept -var flags. Can you provide any additional info on this one? Given the length of this thread, it may be better to open that in a separate GitHub Issue.

module_map_var = "${var.template_map_var}" in the module block actually seems to do the correct thing

Yeah, the syntax for denoting lists and maps is inconsistent in Terraform. I can see how this could lead to some confusion while you're wrestling other issues.

The --terragrunt-source flag and the source parameter in the module block do appear to be broken

This sounds like it could be a Terragrunt issue, although it may be an issue with your template, or with Terraform. Can you paste the output that seems to be behaving strangely? Then we can determine whether this is the root issue that motivated this thread, a separate issue, or a mistake/bug elsewhere.

It may also help to know that we are about to merge #340 to resolve #334. One issue we've seen is that the OS will delete the files in a temp folder, but not the folder itself, which would sometimes confuse Terragrunt.

provider downloads are super slow

I'm not experiencing that on my machine using all the same providers and git repos you are, so I'm not sure how to explain this one.

Next Steps
To keep this thread sane, let's try to focus on the known or suspected Terragrunt-specific issues. For other questions about using Gruntwork packages, it's best if you use our Gruntwork support channel.

Now that you're more familiar with some of the Terraform syntax quirks, it will hopefully be easier to separate Terraform errors from Terragrunt issues.

@ghost
Copy link

ghost commented Nov 2, 2017 via email

@ghost
Copy link

ghost commented Nov 3, 2017 via email

@antonbabenko
Copy link
Contributor Author

Terraform 0.11 is out, and I think it is time for Terragrunt to have support for Terraform Registry URLs and versioning natively:

terragrunt = {
  terraform {
    source = "terraform-aws-modules/vpc/aws"
    version = "v1.2.0"
  }
}

As described in Upgrading to 0.11 Guide:

As a consequence, module source strings like "child" are no longer interpreted as relative paths. Instead, relative paths must be expressed explicitly by beginning the string with either ./ (for a module in a child directory) or ../ (for a module in the parent directory).

@brikis98
Copy link
Member

+1. Anyone up for a PR?

@jeffbyrnes
Copy link

Seems like this has fallen by the wayside. Any chance of some love? I’d love to tackle, but have zero Go chops 😞

@brikis98
Copy link
Member

We'd love to get to it, but there's a long list of feature requests for Terragrunt, and given that this one has a simple workaround (use a Git URL!), it's hard to prioritize it. PRs are welcome though :)

@seanorama
Copy link

@brikis98 while the Git URL works for fetching the modules, they will not work due to Terragrunt's requirement for the following which is not in the modules:

provider "aws" {
  region = "${var.aws_region}"
}

terraform {
  backend "s3" {}
}

Is there a workaround for that? Would be more DRY to not require that in every module.

@antonbabenko
Copy link
Contributor Author

@seanorama I use hooks to copy that file like this:

terragrunt = {
  terraform {
    after_hook "copy_common_main_variables" {
      commands = ["init"]
      execute  = ["cp", "${get_parent_tfvars_dir()}/../common/main_variables.tf", "."]
    }
  }

@seanorama
Copy link

@antonbabenko Perfect.

How do you get around not having a double slash (//) when modules are in the root dir of a git repo? For example:
https://github.com/terraform-aws-modules/terraform-aws-vpc

@antonbabenko
Copy link
Contributor Author

I usually don't need //, like this:

terragrunt = {
  terraform {
    source = "git::git@github.com:terraform-aws-modules/terraform-aws-vpc.git?ref=v1.24.0"
  }
}

@dennybaa
Copy link

dennybaa commented Jun 21, 2018

@antonbabenko Would please tell how do you fix var.name issue (for example in case the vpc module)? It would be nice to have a fancy name calculated from other tfvars, though it's not possible terragrunt :(
Do you explicitly specify the name in terraform.tfvars?

@antonbabenko
Copy link
Contributor Author

Yes, I always have name static in terraform.tfvars. An additional bonus is that I can use data-sources to lookup for that value if necessary because name is known and static.

@ozbillwang
Copy link

ozbillwang commented Nov 26, 2018

@antonbabenko

Any progress to support for Terraform Registry URLs and versioning natively:

#311 (comment)

Currently I have to replace with below codes.

terragrunt = {
  terraform {
    source = "github.com/terraform-aws-modules/terraform-aws-autoscaling?ref=v2.9.0"
    #source = "terraform-aws-modules/autoscaling/aws"
    #version = "v2.9.0"
  }

  include = {
    path = "${find_in_parent_folders()}"
  }
}

@antonbabenko
Copy link
Contributor Author

@ozbillwang I have not made any progress on this.

@chenrui333
Copy link
Contributor

chenrui333 commented Dec 5, 2018

I am actually using something like this:

module "eks" {
  source  														 = "terraform-aws-modules/eks/aws"
  version 														 = "1.7.0"
...
}

It seems working good for me. So sounds like it does support terraform registry now?

@cschroer
Copy link
Contributor

cschroer commented May 7, 2019

We tested with a private registry and latest terragrunt version:

Source:

 terraform {
    source  = "a-private-regisry.example.com/example-organisation/example-module/example-provider"
    version = "~> 1.0"
  }

Error:

Copying configuration from "file:///path/to/source/dir/a-private-regisry.example.com/example-organisation/example-module/example-provider"...
Error copying source module: error downloading 'file:///path/to/source/dir/a-private-regisry.example.com/example-organisation/example-module/example-provider': source path error: stat /path/to/source/dir/a-private-regisry.example.com/example-organisation/example-module/example-provider: no such file or directory

So at least for private registries it doesn't work (yet).

@antonbabenko
Copy link
Contributor Author

@cschroer In your case source should start with https:// or http://. The default is file:// which you are experiencing.

@cschroer
Copy link
Contributor

cschroer commented May 8, 2019

@antonbabenko not when using a module registry imho. See https://www.terraform.io/docs/modules/sources.html#terraform-registry

@brikis98
Copy link
Member

This should now be possible using a generate block.

@antonbabenko
Copy link
Contributor Author

@brikis98 I am not sure how generate block helps with this issue. Could you please describe the potential solution briefly?

@brikis98
Copy link
Member

Whoops, going too quickly, this issue has nothing to do with generate block. Re-opening.

@brikis98 brikis98 reopened this Jun 15, 2020
@antonyfray
Copy link

Is this still being actively worked on?

@yhakbar
Copy link
Contributor

yhakbar commented May 20, 2021

Is this still being worked on? Our team has had to abandon Terragrunt for a project we're starting up because we're integrating Terraform registries.

@ml27299
Copy link

ml27299 commented Jun 18, 2021

Kinda ridiculous that you can't use terraform registry urls, a workaround I came up with is to create a git repo called "terragrunt-proxy", add an empty .tf file (commit/push to the repo), then use the generate block to generate the module using terraform syntax

locals {
   module_version = "0.1.0"
}

terraform {
      source = "git@github.com:terragrunt-proxy.git"
}

generate "main" {
    path = "main.tf"
    if_exists = "overwrite_terragrunt"
    contents = <<EOF
module "my-module" {
  source = "app.terraform.io/org/name/provider"
  version = "${local.module_version}"
}
EOF
}

@ghost
Copy link

ghost commented Jun 28, 2021

Pls terragrunt 🙏

@yorinasub17
Copy link
Contributor

yorinasub17 commented Aug 18, 2021

Initial version that adds support for Terraform Module Registry has been released: https://github.com/gruntwork-io/terragrunt/releases/tag/v0.31.5 (binaries should show up in 15~30 mins)

There are two follow up issues that discuss some limitations of this feature. Please follow those tickets and 👍 if you are interested in those:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

14 participants