Reputation: 1
I am working with a test Terraform Stacks build, creating a resource group and then placing some resources in it. Each resource is created with a separate module, so one for the resource group, another for vnet, subnet, etc. When I reference another component during build, eg the name of the resource group to place a vnet, I'm receiving the error "unsupported attribute - this object does not have an attribute named "resource_group_name"".
# input vars:
location = {
dev = ["eastus2",]
stage = ["eastus2",]
prod = ["centralus","westus"]
}
environment = "dev"
app_name = "app1"
# components.tfstack.hcl:
component "rg" {
for_each = var.location
source = "./modules/rg"
inputs = {
name = "${each.value}-${var.environment}-${var.app_name}-rg"
location = each.value
tags = var.tags
}
providers = {
azurerm = provider.azurerm.this
}
}
component "vnet" {
for_each = var.location
source = "./modules/vnet"
inputs = {
name = "${each.value}-${var.environment}-${var.app_name}-vnet"
location = each.value
resource_group_name = component.rg.resource_group_name
address_space = var.vnet_address_space
tags = var.tags
}
providers = {
azurerm = provider.azurerm.this
}
}
# resource group module:
resource "azurerm_resource_group" "rg" {
name = var.name
location = var.location
tags = var.tags
}
output "resource_group_name" {
value = azurerm_resource_group.rg.name
}
The plan shows the correct resource group name being created and Hashicorp code examples seem to support my syntax. Outputting the "name" property string from the resource group creation module should be referenced with "component.other component name.output string name", am I missing something or doing it wrong?
Upvotes: 0
Views: 352
Reputation: 74219
Your component "rg"
block includes the for_each
argument, which means that component.rg
appears in expressions elsewhere as a map of objects whose keys match the keys in var.location
. To refer to a specific instance of that component you need to select a specific object from that map using the index syntax, with [
]
brackets.
Since you are using the same for_each
in component "vnet"
I assume your intention is to have the vnet
instances matched to the rg
instances where the keys match, in which case you can use each.key
to refer to the key of the current instance of component "vnet"
, and thus find the matching instance of component "rg"
:
resource_group_name = component.rg[each.key].resource_group_name
Because Stacks is relatively new the documentation on these features is not yet as comprehensive as for the traditional Terraform modules language, but for for_each
with components in particular the language design is very similar to how for_each
behaves for module
block in the traditional Terraform language, and so the documentation on referring to instances is also largely relevant to components except that you'd use the prefix component.
instead of the prefix module.
.
Upvotes: 0
Reputation: 2261
Terraform stacks component reference to module output error: "unsupported attribute"
Issue seems to be with the way you declaring the name property in resource group module.
You should used in such a way that the output is refered properly as mentioned module.rg[each.key].resource_group_name
in your vnet module configuration.
Demo configuration:
variable "location" {
type = map(list(string))
default = {
dev = ["eastus2"]
stage = ["eastus2"]
prod = ["centralus", "westus"]
}
}
variable "environment" {
type = string
default = "dev"
}
.
.
module "rg" {
source = "./modules/rg"
for_each = { for k, v in var.location : k => v }
name = "${each.value[0]}-${var.environment}-${var.app_name}-rg"
location = each.value[0]
tags = var.tags
}
module "vnet" {
source = "./modules/vnet"
for_each = { for k, v in var.location : k => v }
name = "${each.value[0]}-${var.environment}-${var.app_name}-vnet"
location = each.value[0]
resource_group_name = module.rg[each.key].resource_group_name
address_space = ["10.0.0.0/16"]
tags = var.tags
}
module/rg:
resource "azurerm_resource_group" "rg" {
name = var.name
location = var.location
tags = var.tags
}
output "resource_group_name" {
value = azurerm_resource_group.rg.name
}
module/vnet:
resource "azurerm_virtual_network" "vnet" {
name = var.name
location = var.location
resource_group_name = var.resource_group_name
address_space = var.address_space
tags = var.tags
}
Deployment:
Refer:
https://developer.hashicorp.com/terraform/language/modules/develop
The for_each Meta-Argument - Configuration Language | Terraform | HashiCorp Developer
Output Values - Configuration Language | Terraform | HashiCorp Developer
Terraform referencing output from another module with for_each - Stack Overflow answered by charles-xu
Upvotes: 0