Terraform: Explicit passing of providers to grandchild modules not working

Created on 21 Feb 2018  ยท  3Comments  ยท  Source: hashicorp/terraform

Terraform Version

Terraform v0.11.3

Terraform Configuration Files

# main.tf
# The root provider
provider aws {
  region = "eu-west-1"
}

provider aws {
  region = "ap-southeast-2"
  alias  = "sydney"
}

provider aws {
  region = "us-west-2"
  alias  = "portland"
}

resource aws_ssm_parameter "root" {
  name  = "root"
  type  = "String"
  value = "derp"
}

resource aws_ssm_parameter "portland" {
  provider = "aws.portland"
  name     = "portland"
  type     = "String"
  value    = "derp"
}

resource aws_ssm_parameter "sydney" {
  provider = "aws.sydney"
  name     = "sydney"
  type     = "String"
  value    = "derp"
}

output root_arn {
  value = "${aws_ssm_parameter.root.arn}"
}

output portland_arn {
  value = "${aws_ssm_parameter.portland.arn}"
}

output sydney_arn {
  value = "${aws_ssm_parameter.sydney.arn}"
}

module "a" {
  source = "./modules/a"

  providers = {
    aws          = "aws"
    aws.portland = "aws.portland"
    aws.sydney   = "aws.sydney"
  }
}

output a_root_arn {
  value = "${module.a.root_arn}"
}

output a_portland_arn {
  value = "${module.a.portland_arn}"
}

output a_sydney_arn {
  value = "${module.a.sydney_arn}"
}

output b_root_arn {
  value = "${module.a.b_root_arn}"
}

output b_portland_arn {
  value = "${module.a.b_portland_arn}"
}

output b_sydney_arn {
  value = "${module.a.b_sydney_arn}"
}
# modules/a/main.tf
resource aws_ssm_parameter "root" {
  name  = "a.root"
  type  = "String"
  value = "derp"
}

resource aws_ssm_parameter "portland" {
  provider = "aws.portland"
  name     = "a.portland"
  type     = "String"
  value    = "derp"
}

resource aws_ssm_parameter "sydney" {
  provider = "aws.sydney"
  name     = "a.sydney"
  type     = "String"
  value    = "derp"
}

output root_arn {
  value = "${aws_ssm_parameter.root.arn}"
}

output portland_arn {
  value = "${aws_ssm_parameter.portland.arn}"
}

output sydney_arn {
  value = "${aws_ssm_parameter.sydney.arn}"
}

module "b" {
  source = "../b"

  providers = {
    aws          = "aws"
    aws.portland = "aws.portland"
    aws.sydney   = "aws.sydney"
  }
}

output b_root_arn {
  value = "${module.b.root_arn}"
}

output b_portland_arn {
  value = "${module.b.portland_arn}"
}

output b_sydney_arn {
  value = "${module.b.sydney_arn}"
}
# modules/b/main.tf
resource aws_ssm_parameter "root" {
  name  = "b.root"
  type  = "String"
  value = "derp"
}

resource aws_ssm_parameter "portland" {
  provider = "aws.portland"
  name     = "b.portland"
  type     = "String"
  value    = "derp"
}

resource aws_ssm_parameter "sydney" {
  provider = "aws.sydney"
  name     = "b.sydney"
  type     = "String"
  value    = "derp"
}

output root_arn {
  value = "${aws_ssm_parameter.root.arn}"
}

output portland_arn {
  value = "${aws_ssm_parameter.portland.arn}"
}

output sydney_arn {
  value = "${aws_ssm_parameter.sydney.arn}"
}

Debug Output


N/A

Crash Output


N/A

Expected Behavior


Providers are explicitly passed from root module to module A to module B and we can therefore create resources in module B

Actual Behavior

2018/02/21 15:26:46 [ERROR] 3 problems:

- module "b": cannot pass non-existent provider "aws"
- module "b": cannot pass non-existent provider "aws.portland"
- module "b": cannot pass non-existent provider "aws.sydney"

Steps to Reproduce

terraform init

Additional Context


There are other issues on the grandchild topic, but I believe they all related to implicit inheritance so I opened this one on explicit inheritance.

References

enhancement

Most helpful comment

Hi @sjauld,

Sorry that this is still a bit confusing. Once we get the new configuration framework in place We're going to revisit the structure of the providers a bit more.

In the documentation for modules within providers, we mention that a configuration must have what we refer to as "proxy configuration blocks" for the providers it wants to receive. In order to make this system a bit more flexible and work with existing modules, I added the ability to allow passing a provider into a module with no corresponding block for that provider (#16619). However in order for the receiving module to pass on the provider again, it will still require a block in the configuration to reference.

What the "a" module needs is empty configuration blocks for the 3 providers, like so:

provider "aws" {
}

provider "aws" {
  alias  = "sydney"
}

provider "aws" {
  alias  = "portland"
}

Since the module is already using the providers by name, there's no additional coupling caused by requiring the empty "proxy" configuration blocks. This still can cause issues when modules want to set version constraints, which is what we're going to cover in #16835.

All 3 comments

Hi @sjauld,

Sorry that this is still a bit confusing. Once we get the new configuration framework in place We're going to revisit the structure of the providers a bit more.

In the documentation for modules within providers, we mention that a configuration must have what we refer to as "proxy configuration blocks" for the providers it wants to receive. In order to make this system a bit more flexible and work with existing modules, I added the ability to allow passing a provider into a module with no corresponding block for that provider (#16619). However in order for the receiving module to pass on the provider again, it will still require a block in the configuration to reference.

What the "a" module needs is empty configuration blocks for the 3 providers, like so:

provider "aws" {
}

provider "aws" {
  alias  = "sydney"
}

provider "aws" {
  alias  = "portland"
}

Since the module is already using the providers by name, there's no additional coupling caused by requiring the empty "proxy" configuration blocks. This still can cause issues when modules want to set version constraints, which is what we're going to cover in #16835.

Ah, thanks @jbardin!

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings