How to add module's(vpc) output of vpc-cidr to vpn's authorization rule.
Tried the below way
cat modules/vpn/vpn.tf
...
resource "aws_ec2_client_vpn_authorization_rule" "vpn_vpc_cidr" {
client_vpn_endpoint_id = aws_ec2_client_vpn_endpoint.vaya-vpn.id
target_network_cidr = var.cidr-vpc
authorize_all_groups = true
}
cat main.tf
module "vpn" {
source = "./modules/vpn"
acm_vpn_server = module.acm_cert.acm_vpn_server
vpc_id = module.vpc.vpc_id
# private_subnet_ids = module.vpc.private_subnet_ids
subnet_ids = module.vpc.subnet_ids
cidr-vpc = module.vpc.cidr-vpc
cidr-subnets = module.vpc.cidr-subnets
env = var.env
}
But getting the below error
╷
│ Error: Unsupported attribute
│
│ on main.tf line 79, in module "vpn":
│ 79: cidr-vpc = module.vpc.cidr-vpc
│ ├────────────────
│ │ module.vpc is a object
│
│ This object does not have an attribute named "cidr-vpc".
Related
My main.tf looks like this, Im trying to pass mulitple json files as input into the dashboard resource but running into an error
locals{
json_file = fileset(path.module, "dash/*.json")
json_data = {
for files in local.json_file : files => jsondecode(file(files))
}
}
resource "google_monitoring_dashboard" "dashboards" {
for_each = local.json_data
project = var.monitoring_project
dashboard_json = local.json_data
}
I get the following error
│ Error: Incorrect attribute value type
│
│ on dashboard.tf line 12, in resource "google_monitoring_dashboard" "usecase_dashboards":
│ 12: dashboard_json = local.json_data
│ ├────────────────
│ │ local.json_data is object with 1 attribute "dash/airflow-dashboard.json"
│
│ Inappropriate value for attribute "dashboard_json": string required.
Finally figured it out
locals{
json_file = fileset(path.module, "dash/*.json")
}
resource "google_monitoring_dashboard" "usecase_dashboards" {
for_each = local.json_file
project = var.monitoring_project
dashboard_json =file(each.key)
}
Thanks #marko-e, Your comments provided the hint...
I have the following locals file. I need to get the child and parent names separately in for each in terraform.
locals:
{
l3_crm:
[
{ parent: "crm", child: ["crm-sap", "crm-sf"] },
{ parent: "fin", child: ["fin-mon"] },
]
}
For the following ou creation code in aws, parent_id needs the parent name from the locals and ou_name needs the corresponding child name iterated.
module "l3_crm" {
source = "./modules/ou"
for_each = { for idx, val in local.l3_crm : idx => val }
ou_name = [each.value.child]
parent_id = module.l2[each.key.parent].ou_ids[0]
depends_on = [module.l2]
ou_tags = var.l2_ou_tags
}
I get the following error:
│ Error: Unsupported attribute
│
│ on main.tf line 30, in module "l3_rnd":
│ 30: parent_id = module.l2[each.key.parent].ou_ids[0]
│ ├────────────────
│ │ each.key is a string, known only after apply
│
│ This value does not have any attributes.
╵
Let me know what I am doing wrong in for loop.
I tried this as well:
module "l3_rnd" {
source = "./modules/ou"
for_each = { for parent, child in local.l3_crm : parent => child }
ou_name = [each.value]
parent_id = module.l2[each.key].ou_ids[0]
depends_on = [module.l2]
ou_tags = var.l2_ou_tags
}
with the local.tf:
locals {
l3_crm = [
{ "rnd" : ["crm-sap", "crm-sf"] },
{ "trade" : ["fin-mon"] }
]
}
I get these errors:
╷
│ Error: Invalid value for module argument
│
│ on main.tf line 28, in module "l3_crm":
│ 28: ou_name = [each.value]
│
│ The given value is not suitable for child module variable "ou_name" defined
│ at modules\ou\variables.tf:1,1-19: element 0: string required.
╵
╷
│ Error: Invalid value for module argument
│
│ on main.tf line 28, in module "l3_crm":
│ 28: ou_name = [each.value]
│
│ The given value is not suitable for child module variable "ou_name" defined
│ at modules\ou\variables.tf:1,1-19: element 0: string required.
╵
╷
│ Error: Invalid index
│
│ on main.tf line 29, in module "l3_crm":
│ 29: parent_id = module.l2[each.key].ou_ids[0]
│ ├────────────────
│ │ each.key is "1"
│ │ module.l2 is object with 2 attributes
│
│ The given key does not identify an element in this collection value.
╵
╷
│ Error: Invalid index
│
│ on main.tf line 29, in module "l3_crm":
│ 29: parent_id = module.l2[each.key].ou_ids[0]
│ ├────────────────
│ │ each.key is "0"
│ │ module.l2 is object with 2 attributes
│
│ The given key does not identify an element in this collection value.
╵
time=2022-11-11T13:24:15Z level=error msg=Hit multiple errors:
Hit multiple errors:
exit status 1
With your current structure you can reconstruct the map in your meta-argument like:
for_each = { for l3_crm in local.l3_crm : l3_crm.parent => l3_crm.child }
to access the values of each key in the list element and reconstruct to a map of parent keys and child values.
You can also optimize the structure like:
l3_crm:
[
{ "crm" = ["crm-sap", "crm-sf"] },
{ "fin" = ["fin-mon"] },
]
and then:
for_each = { for parent, child in local.l3_crm : parent => child }
where you cannot simply convert to a set type with toset because set(map) is not allowed as an argument value type.
Either way the references are updated fully accordingly:
ou_name = [each.key]
parent_id = module.l2[each.value].ou_ids[0]
I'm trying to use list(string) for azure event grid event types. I used to pass all the inputs using tfvars file. and use locals to get data from it.
Below is how the tfvars looks like.
grid_configuration = {
grid1 = {
name = "testgridsiai"
rg-name = "sai-india"
location = "uksouth"
is_storage_grid = true
source_storage_account = "apmapplicationstorages"
topic_subscription = [
{
is_sink_queue = true
is_sink_eventhub = true
storage_account_name = "apmapplicationstorages"
storage_account_queue_name = "asset-data"
storage_account_queue_name_subscription_name = "store"
event_hub_name = "input"
event_hub_namespace_name = "SIAI-EH-NEW-APMS"
event_hub_subscription_name = "event-test"
event_types = ["Microsoft.Storage.BlobCreated","Microsoft.Storage.BlobDeleted"]
}
]
}
}
and below is the terraform configuration
locals {
grid_topics = { for e in var.grid_configuration : e.name => e }
subscriptions = { for hc in flatten([for h in var.grid_configuration :
[for c in h.topic_subscription : {
is_sink_queue = c.is_sink_queue
is_sink_eventhub = c.is_sink_eventhub
storage_account_name = c.storage_account_name
storage_account_queue_name = c.storage_account_queue_name
event_hub_name = c.event_hub_name
grid_name = h.name
location = h.location
rg-name = h.rg-name
storage_account_queue_name_subscription_name = c.storage_account_queue_name_subscription_name
event_hub_namespace_name = c.event_hub_namespace_name
event_hub_subscription_name = c.event_hub_subscription_name
event_types = c.event_types
}]]) : format("%s.%s.%s.%s.%s.%s.%s.%s.%s.%s.%s", hc.is_sink_queue, hc.is_sink_eventhub, hc.storage_account_name, hc.storage_account_queue_name, hc.event_hub_name, hc.grid_name, hc.rg-name, hc.location, hc.event_hub_namespace_name, hc.event_hub_subscription_name, hc.event_types) => hc }
}
resource "azurerm_eventgrid_system_topic_event_subscription" "example" {
for_each = { for k, v in local.subscriptions : k => v if v.is_sink_queue }
name = each.value.storage_account_queue_name_subscription_name
system_topic = each.value.grid_name
resource_group_name = each.value.rg-name
storage_queue_endpoint {
storage_account_id = data.azurerm_storage_account.example[each.key].id
queue_name = each.value.storage_account_queue_name
}
included_event_types = [each.value.event_types]
depends_on = [azurerm_eventgrid_system_topic.example]
}
and below is the error
│ Error: Error in function call
│
│ on event-grid/main.tf line 18, in locals:
│ 18: }]]) : format("%s.%s.%s.%s.%s.%s.%s.%s.%s.%s.%s", hc.is_sink_queue, hc.is_sink_eventhub, hc.storage_account_name, hc.storage_account_queue_name, hc.event_hub_name, hc.grid_name, hc.rg-name, hc.location, hc.event_hub_namespace_name, hc.event_hub_subscription_name, hc.event_types) => hc }
│ ├────────────────
│ │ hc.event_hub_name is "input"
│ │ hc.event_hub_namespace_name is "SIAI-EH-NEW-APMS"
│ │ hc.event_hub_subscription_name is "event-test2"
│ │ hc.event_types is list of string with 2 elements
│ │ hc.grid_name is "testgridsiai"
│ │ hc.is_sink_eventhub is true
│ │ hc.is_sink_queue is true
│ │ hc.location is "uksouth"
│ │ hc.rg-name is "sai-india"
│ │ hc.storage_account_name is "apmapplicationstorages"
│ │ hc.storage_account_queue_name is "channel-data"
│
│ Call to function "format" failed: unsupported value for "%s" at 30: string required.
I understood that I needed to use formatlist() instead of format(). Can someone throw some light on it.
Just add ...:
format("%s.%s.%s.%s.%s.%s.%s.%s.%s.%s.%s", hc.is_sink_queue, hc.is_sink_eventhub, hc.storage_account_name, hc.storage_account_queue_name, hc.event_hub_name, hc.grid_name, hc.rg-name, hc.location, hc.event_hub_namespace_name, hc.event_hub_subscription_name, hc.event_types...)
The following block within a google_cloud_storage resource
dynamic "lifecycle_rule" {
for_each = var.bucket_lifecycle_rule
content {
condition {
age = lifecycle_rule.age
with_state = lifecycle_rule.with_state
}
action {
type = lifecycle_rule.type
storage_class = lifecycle_rule.storage_class
}
}
}
with the following variable declaration
variable "bucket_lifecycle_rule" {
description = "Lifecycle rules"
type = list(object({
age = string
with_state = string
type = string
storage_class = string
}))
default = [
{
age = 30
with_state = "ANY"
type = "SetStorageClass"
storage_class = "COLDLINE"
},
{
age = 120
with_state = "ANY"
type = "Delete"
storage_class = ""
},
]
}
errors out as follows:
│ Error: Unsupported attribute
│
│ on main.tf line 18, in resource "google_storage_bucket" "my_bucket":
│ 18: age = lifecycle_rule.age
│
│ This object does not have an attribute named "age".
╵
╷
│ Error: Unsupported attribute
│
│ on main.tf line 19, in resource "google_storage_bucket" "my_bucket":
│ 19: with_state = lifecycle_rule.with_state
│
│ This object does not have an attribute named "with_state".
╵
╷
│ Error: Unsupported attribute
│
│ on main.tf line 22, in resource "google_storage_bucket" "my_bucket":
│ 22: type = lifecycle_rule.type
│
│ This object does not have an attribute named "type".
╵
╷
│ Error: Unsupported attribute
│
│ on main.tf line 23, in resource "google_storage_bucket" "my_bucket":
│ 23: storage_class = lifecycle_rule.storage_class
│
│ This object does not have an attribute named "storage_class".
why is that?
You have to reference the properties from your objects with value:
dynamic "lifecycle_rule" {
for_each = var.bucket_lifecycle_rule
content {
condition {
age = lifecycle_rule.value.age
with_state = lifecycle_rule.value.with_state
}
action {
type = lifecycle_rule.value.type
storage_class = lifecycle_rule.value.storage_class
}
}
}
In the Terraform docs there is a note about this:
The iterator object has two attributes:
key is the map key or list element index for the current element. If
the for_each expression produces a set value then key is identical to value and should not be used.
value is the value of the current element.
I have recently separated terraform files from it's variable file as per below structure
(root)
| main.tf
| users.tf
| roles.tf
├── Configuration (folder)
├──── azure-pipelines.yml
├──── .gitignore
├──── variables.tf
and since then I am getting bellow error messages
│ Error: Unsupported attribute
│
│ on main.tf line 77, in resource "azurerm_key_vault_secret" "primary_account_storage_access_key":
│ 77: name = "${module.variables.storage-account_name}-access-key"
│ ├────────────────
│ │ module.variables is a object, known only after apply
│
│ This object does not have an attribute named "storage-account_name".
╵
╷
│ Error: Unsupported attribute
│
│ on main.tf line 78, in resource "azurerm_key_vault_secret" "primary_account_storage_access_key":
│ 78: value = module.variables.storage-access_key
│ ├────────────────
│ │ module.variables is a object, known only after apply
│
│ This object does not have an attribute named "storage-access_key".
╵
This is how problematic resource "primary_account_storage_access_key" is defined
resource "azurerm_key_vault_secret" "primary_account_storage_access_key" {
depends_on = [azurerm_key_vault_access_policy.terraform_sp_access]
key_vault_id = data.azurerm_key_vault.azvault.id
name = "${module.variables.storage-account_name}-access-key"
value = module.variables.storage-access_key
}
Module is defined as below:
module "variables" {
source = "./Configuration"
}
I have no issue with utilizing the same module in other resources placed in the same file (main.tf)
terraform {
backend "azurerm" {
resource_group_name = module.variables.storage-resource_group_name
storage_account_name = module.variables.storage-storage_account_name
container_name = module.variables.storage-container_name
key = module.variables.storage-key
}
}
Found articles here on the site focusing on the error suggesting
"splat" operator with "toset" / "one" function, however that did not help:
name = "${toset(module.variables[*].storage-account_name)}-access-key"
value = toset(module.variables[*].storage-access_key)
name = "${one(module.variables[*].storage-account_name)}-access-key"
value = one(module.variables[*].storage-access_key)
Content of variables.tf what child module variables uses:
variable "storage-resource_group_name" {
type = string
default = "Reporting-HFM-integration-rg"
}
variable "storage-account_name" {
type = string
default = "reportinghfmintegration"
}
variable "storage-container_name" {
type = string
default = "tfstate-blob"
}
variable "storage-key" {
type = string
default = "terraform.tfstate"
}
variable "storage-access_key" {
type = string
default = "u3K..."
}
variable "keyVault-name" {
type = string
default = "se-dataplat-dwvault-prod"
}
variable "keyVault-resource_group_name" {
type = string
default = "AzureDataPlatform-dwtools-prod-rg"
}
variable "keyVault-id" {
type = string
default = "/subscriptions/23a89ca1-9743-4b3b-b5ff-41cea9985deb/resourceGroups/..."
}