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

Terraform does not pass provider options (subscription_id at least) to a child module #28066

Closed
esciara opened this issue Mar 12, 2021 · 6 comments
Labels
bug new new issue not yet triaged

Comments

@esciara
Copy link

esciara commented Mar 12, 2021

It should be possible to pass providers explicitly to modules, but this fails in the example below with the azurerm provider, where the subscription_id is not passed with the provider to the module.

Terraform Version

$ terraform version
Terraform v0.14.8
+ provider registry.terraform.io/hashicorp/azurerm v2.51.0

Terraform Configuration Files

### ./main.tf
provider "azurerm" {
  features {}
}

provider "azurerm" {
  alias           = "other"
  subscription_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"  # <= subscription different from the default subscription
  features {}
}

resource "azurerm_resource_group" "rg_in_default_subscription" {
  name     = "rg-in-default-subscription"
  location = "francecentral"
}

resource "azurerm_resource_group" "rg_in_other_subscription" {
  provider = azurerm.other
  name     = "rg-in-other-subscription"
  location = "francecentral"
}

module "test" {
  source = "./test"
  providers = {
    azurerm.other = azurerm.other
  }
}

data "azurerm_resource_group" "rg_in_default_subscription_2" {
  name       = module.test.rg_in_default_subscription_2_name
  depends_on = [module.test]
}

data "azurerm_resource_group" "rg_in_other_subscription_2" {
  provider   = azurerm.other
  name       = module.test.rg_in_other_subscription_2_name
  depends_on = [module.test]
}
### ./test/main.tf
provider "azurerm" {
  features {}
}

provider "azurerm" {
  alias = "other"
  features {}
}

resource "azurerm_resource_group" "rg_in_default_subscription_2" {
  name     = "rg-in-default-subscription-2"
  location = "francecentral"
}

resource "azurerm_resource_group" "rg_in_other_subscription_2" {
  provider = azurerm.other
  name     = "rg-in-other-subscription-2"
  location = "francecentral"
}

output "rg_in_default_subscription_2_name" {
  value = azurerm_resource_group.rg_in_default_subscription_2.name
}

output "rg_in_other_subscription_2_name" {
  value = azurerm_resource_group.rg_in_other_subscription_2.name
}

Debug Output

N/A

Crash Output

N/A

Expected Behavior

On terraform apply, the data source data.azurerm_resource_group.rg_in_other_subscription_2 should be found and terraform should exit without issues.

Actual Behavior

On terraform apply, output is:

Error: Error: Resource Group "rg-in-other-subscription-2" was not found

  on main.tf line 34, in data "azurerm_resource_group" "rg_in_other_subscription_2":
  34: data "azurerm_resource_group" "rg_in_other_subscription_2" {

And indeed, when looking in the Azure Portal, the resource group rg-in-other-subscription-2 has been created in the default subscription (in my case the subscription set through the azure cli).

Steps to Reproduce

  1. terraform init
  2. terraform apply

Additional Context

N/A

References

N/A

@esciara esciara added bug new new issue not yet triaged labels Mar 12, 2021
@esciara
Copy link
Author

esciara commented Mar 12, 2021

Here is a workaround to do what the providers meta-argument is supposed to do (to my understanding), using a variable:

### replace in ./main.tf
[...]

module "test" {
  source = "./test"
  other_subscription_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"  # <= subscription different from the default subscription
}

[...]
### replace in ./test/main.tf
[...]

variable "other_subscription_id" {
}

provider "azurerm" {
  alias = "other"
  subscription_id = var.other_subscription_id
  features {}
}

[...]

@jbardin
Copy link
Member

jbardin commented Mar 12, 2021

Hi @esciara

Thanks for filing the issue.
The problem here is that you have defined provider configurations within the module itself. Resources within the module will resolve these local provider configurations before looking at providers passed in via the providers meta argument.

The confusing nature of this behavior was made worse by the fact that it occasionally did work, because part of the code path did not expect multiple different provider configurations at that point. The lack of validation here was an oversight, and is fixed by #27739 as part of the 0.15 release.

Thanks!

@jbardin jbardin closed this as completed Mar 12, 2021
@esciara
Copy link
Author

esciara commented Mar 14, 2021

Thanks for your reply @jbardin .

When I remove the provider configurations in the module, I get the following error message:

Error: Provider configuration not present

To work with module.test.azurerm_resource_group.rg_in_other_subscription_2 its
original provider configuration at
module.test.provider["registry.terraform.io/hashicorp/azurerm"].other is
required, but it has been removed. This occurs when a provider configuration
is removed while objects created by that provider still exist in the state.
Re-add the provider configuration to destroy
module.test.azurerm_resource_group.rg_in_other_subscription_2, after which you
can remove the provider configuration again.

So does that mean that it will never work on 0.14? Or am I doing something wrong?

As a note, this error message appears despite having made sure that there are .terraform directory, no .terraform.lock.hcl file and no initial local state file, then perform a terraform init followed by a terraform plan.

@jbardin
Copy link
Member

jbardin commented Mar 15, 2021

@esciara,

In 0.14 you will still ned to use a proxy provider block as a placeholder for the provider name.

@esciara
Copy link
Author

esciara commented Mar 17, 2021

@jbardin Thanks for the link. It made me tic! The problem was that I had a features {} in the module's provider block (which is always added by default by my IDE, so I did not flinch).

So by replacing:

### ./test/main.tf
provider "azurerm" {
  features {}
}

provider "azurerm" {
  alias = "other"
  features {}
}

[...]

with simply:

### ./test/main.tf
provider "azurerm" {
  alias = "other"
}

[...]

It all works.

Thanks.

@ghost
Copy link

ghost commented Apr 12, 2021

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.

@ghost ghost locked as resolved and limited conversation to collaborators Apr 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug new new issue not yet triaged
Projects
None yet
Development

No branches or pull requests

2 participants