How to add VPC-CIDR authorization rule in VPN - terraform

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

mulitple json file as inputs throws error for building dashboard

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...

Handling list of maps in for loop in terraform

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]

how to use list(string) in terraform

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...)

Dynamic block of lifecycle_rule not working in terraform 1.0.6

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.

Separate structure for variables.tf gets "Object, known only after apply"

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/..."
}

Resources