Using the resource ID from a for_each resource block - azure

I've created a Terraform template that creates 2 route tables and 2 subnets using the for_each command. I am trying to associate the route tables to the two subnets, however I am struggling to do so because I don't know how to obtain the ID for the route tables and subnets as the details are not in a variable, and I'm not sure how to get that information and use it. Please may someone provide assistance?
Thank you
Main Template
# SUBNETS DEPLOYMENT
resource "azurerm_subnet" "subnets" {
depends_on = [azurerm_virtual_network.vnet]
for_each = var.subnets
resource_group_name = var.rg.name
virtual_network_name = var.vnet.config.name
name = each.value.subnet_name
address_prefixes = each.value.address_prefixes
}
# ROUTE TABLE DEPLOYMENT
resource "azurerm_route_table" "rt" {
depends_on = [azurerm_virtual_network.vnet]
for_each = var.rt
name = each.value.route_table_name
resource_group_name = var.rg.name
location = var.rg.location
disable_bgp_route_propagation = true
route = [ {
address_prefix = each.value.address_prefix
name = each.value.route_name
next_hop_in_ip_address = each.value.next_hop_ip
next_hop_type = each.value.next_hop_type
} ]
}
# ROUTE TABLE ASSOICATION
resource "azurerm_subnet_route_table_association" "rt_assoication" {
subnet_id = azurerm_subnet.subnets.id
route_table_id = azurerm_route_table.rt.id
}
Variables
# SUBNET VARIBALES
variable "subnets" {
description = "subnet names and address prefixes"
type = map(any)
default = {
subnet1 = {
subnet_name = "snet-001"
address_prefixes = ["172.17.208.0/28"]
}
subnet2 = {
subnet_name = "snet-002"
address_prefixes = ["172.17.208.32/27"]
}
}
}
# ROUTE TABLES VARIABLES
variable "rt" {
description = "variable for route tables."
type = map(any)
default = {
rt1 = {
route_table_name = "rt1"
address_prefix = "0.0.0.0/0"
route_name = "udr-azure-firewall"
next_hop_ip = "10.0.0.0"
next_hop_type = "VirtualAppliance"
}
rt2 = {
route_table_name = "rt2"
address_prefix = "0.0.0.0/0"
route_name = "udr-azure-firewall"
next_hop_ip = "10.0.0.0"
next_hop_type = "VirtualAppliance"
}
}
}
The error I get when I run terraform plan is:
│ Error: Missing resource instance key
│
│ on modules\vnet\main.tf line 74, in resource "azurerm_subnet_route_table_association" "rt_assoication":
│ 74: subnet_id = azurerm_subnet.subnets.id
│
│ Because azurerm_subnet.subnets has "for_each" set, its attributes must be accessed on specific instances.
│
│ For example, to correlate with indices of a referring resource, use:
│ azurerm_subnet.subnets[each.key]
╵
╷
│ Error: Missing resource instance key
│
│ on modules\vnet\main.tf line 75, in resource "azurerm_subnet_route_table_association" "rt_assoication":
│ 75: route_table_id = azurerm_route_table.rt.id
│
│ Because azurerm_route_table.rt has "for_each" set, its attributes must be accessed on specific instances.
│
│ For example, to correlate with indices of a referring resource, use:
│ azurerm_route_table.rt[each.key]

Looks like you are almost there, update the following in the subnet-route table association block, it should work:
# ROUTE TABLE ASSOICATION
resource "azurerm_subnet_route_table_association" "rt_assoication" {
subnet_id = azurerm_subnet.subnets[each.key].id
route_table_id = azurerm_route_table.rt[each.key].id
}

Related

Problem referencing aws_nat_gateway within route table

The nat_gateway_id argument in the last resource below is busted. I've been staring at the sun for too long, though, and the issue isn't jumping out at me.
resource "aws_eip" "nat_gateway_ip" {
for_each = aws_subnet.public
vpc = true
}
}
# Create NAT gateways in public subnets
resource "aws_nat_gateway" "private" {
for_each = aws_subnet.public
allocation_id = aws_eip.nat_gateway_ip[each.key].id
subnet_id = each.value.id
}
# Create Route tables and default routes
resource "aws_route_table" "private" {
for_each = toset([ "test", "prod"])
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.private[each.key].id
}
}
The resulting error is:
nat_gateway_id = aws_nat_gateway.private[each.key].id
│ ├────────────────
│ │ aws_nat_gateway.private is object with 2 attributes
│ │ each.key is "test"
│
│ The given key does not identify an element in this collection value.

Terraform on Azure - I am trying to call the results of a for_each block in one resource in another resource

Terraform on Azure - I am trying to call the results of a for_each block in one resource in another resource.
I have gone through the following & cant seem to be able to wrap my head around the logic.
https://stackoverflow.com/questions/71646136/terraform-reference-a-for-each-resource-from-another-for-each-resource
https://stackoverflow.com/questions/68571073/for-each-loop-in-resource-block-terraform
I have 2 resource blocks [I have added the locals file ]
# Local Variables
#
locals {
# Create a flattened list for resource groups in multiple regions
multi_region_rg = flatten([
for rg_key, rg in var.multiple_resource_groups : [
for region_key, region in var.regions : {
rg_name = var.environment != "" ? format("%s-rg-%s-%s-%s", var.tenant, rg_key, var.environment, region.code) : format("%s-rg-%s-%s", var.tenant, rg_key, region.code)
region_name = region.name
}
]
])
}
# Local Variables
#
locals {
# Create a flattened list for resource groups in multiple regions
multi_region_vnet = flatten([
for vnet_key, vnet in var.multiple_vnets : [
for region_key, region in var.regions : {
vnet_name = var.environment != "" ? format("%s-rg-%s-%s-%s", var.tenant, vnet_key, var.environment, region.code) : format("%s-rg-%s-%s", var.tenant, vnet_key, region.code)
region_name = region.name
virtual_network_address_space = vnet.address_space
}
]
])
}
TFVARS file
# Global tags
global_tags = { "ManagedBy" = "Terraform" }
# Map of regions for deployment of resource groups
regions = {
region1 = { name = "australiaeast", code = "ae" },
region2 = { name = "australiasoutheast", code = "ase" }
}
# Tenant
tenant = "cubem_"
# Map of resource groups
# NOTE: Use short names or aliases for resource groups as the code will generate the resource group name as per the following format:
# <tenant>-rg-<resource_group_alias>-<environment>-<region_code>
multiple_resource_groups = {
connectivity = {
tags = {
CostCenter = "NETWORKS",
Department = "Network Services"
}
}
}
###################################### Vnet Values #######################
# Map of resource groups
# NOTE: Use short names or aliases for resource groups as the code will generate the resource group name as per the following format:
# <tenant>-rg-<resource_group_alias>-<environment>-<region_code>
multiple_vnets = {
vnetx = { address_space = ["10.1.0.0/24"] },
}
# Create 2 resource groups in 2 regions [1 in each region]
#
resource "azurerm_resource_group" "rg" {
for_each = {
for k, v in local.multi_region_rg : v.rg_name => v
}
name = each.key
location = each.value.region_name
}
# Create 2 vnets in 2 regions [1 in each region]
#
resource "azurerm_virtual_network" "vnet" {
for_each = {
for k, v in local.multi_region_vnet : v.vnet_name => v
}
name = each.key
location = each.value.region_name
address_space = each.value.virtual_network_address_space
resource_group_name = azurerm_resource_group.rg[each.key] #Im trying to call the results of the resource group block above
}
These blocks work well when they are run independently but I want to have the ability to run them concurrently so that the vnets gets deployed into the resource groups that are created.
If I use this line resource_group_name = azurerm_resource_group.rg[each.key] its throwing this error
PS C:\PycharmProjects\terraform-projects\my_azure_connectivity_ref_repo\hub-and-spoke\modules\vnet> terraform plan
╷
│ Error: Invalid index
│
│ on main.tf line 69, in resource "azurerm_virtual_network" "vnet":
│ 69: resource_group_name = azurerm_resource_group.rg[each.key]
│ ├────────────────
│ │ azurerm_resource_group.rg is object with 2 attributes
│ │ each.key is "rg-vnetx-ae"
│
│ The given key does not identify an element in this collection value.
╵
╷
│ Error: Invalid index
│
│ on main.tf line 69, in resource "azurerm_virtual_network" "vnet":
│ 69: resource_group_name = azurerm_resource_group.rg[each.key]
│ ├────────────────
│ │ azurerm_resource_group.rg is object with 2 attributes
│ │ each.key is "rg-vnetx-ase"
│
│ The given key does not identify an element in this collection value.
╵
PS C:\PycharmProjects\terraform-projects\my_azure_connectivity_ref_repo\hub-and-spoke\modules\vnet>
There are two issues in your resource "azurerm_virtual_network" "vnet" definition in the resource_group_name attribute.
[each.key] in azurerm_resource_group.rg[each.key] expression does not exists. here [each.key] is the vnet name actually coming from for_each = { for k, v in local.multi_region_vnet : v.vnet_name => v} which is not available in the resource azurerm_resource_group.rg
> { for k, v in local.multi_region_vnet : v.vnet_name => v }
{
"test-rg-vnet_key-dev-ae" = {
"region_name" = "australiaeast"
"virtual_network_address_space" = [
"10.1.0.0/24",
]
"vnet_name" = "test-rg-vnet_key-dev-ae"
}
"test-rg-vnet_key-dev-ase" = {
"region_name" = "australiasoutheast"
"virtual_network_address_space" = [
"10.1.0.0/24",
]
"vnet_name" = "test-rg-vnet_key-dev-ase"
}
}
The other issue also lies in the resource_group_name attribute of vnet resource with the reference. in spite of azurerm_resource_group.rg[$(expression)] should be azurerm_resource_group.rg[$(expression)].name
Hence, You have to adjust either of your resources with a standard key which is common for both resource_group and vnet. I have done it in the resource group with location/region as it is required in both of the resources.
Hence the correct code addressing both the above issues would be.
## key is now region_name in azurerm_resource_group ##
resource "azurerm_resource_group" "rg" {
for_each = {
for k, v in local.multi_region_rg : v.region_name => v
}
name = each.value.rg_name
location = each.key
}
resource "azurerm_virtual_network" "vnet" {
for_each = {
for k, v in local.multi_region_vnet : v.vnet_name => v
}
name = each.key
location = each.value.region_name
address_space = each.value.virtual_network_address_space
resource_group_name = azurerm_resource_group.rg[(each.value.region_name)].name
}
Code In Action
➜ random_local_tests git:(main) ✗ terraform apply -auto-approve
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# azurerm_resource_group.rg["australiaeast"] will be created
+ resource "azurerm_resource_group" "rg" {
+ id = (known after apply)
+ location = "australiaeast"
+ name = "test-rg-vnet_key-dev-ae"
}
# azurerm_resource_group.rg["australiasoutheast"] will be created
+ resource "azurerm_resource_group" "rg" {
+ id = (known after apply)
+ location = "australiasoutheast"
+ name = "test-rg-vnet_key-dev-ase"
}
# azurerm_virtual_network.vnet["test-rg-vnet_key-dev-ae"] will be created
+ resource "azurerm_virtual_network" "vnet" {
+ address_space = [
+ "10.1.0.0/24",
]
+ dns_servers = (known after apply)
+ guid = (known after apply)
+ id = (known after apply)
+ location = "australiaeast"
+ name = "test-rg-vnet_key-dev-ae"
+ resource_group_name = "test-rg-vnet_key-dev-ae"
+ subnet = (known after apply)
}
# azurerm_virtual_network.vnet["test-rg-vnet_key-dev-ase"] will be created
+ resource "azurerm_virtual_network" "vnet" {
+ address_space = [
+ "10.1.0.0/24",
]
+ dns_servers = (known after apply)
+ guid = (known after apply)
+ id = (known after apply)
+ location = "australiasoutheast"
+ name = "test-rg-vnet_key-dev-ase"
+ resource_group_name = "test-rg-vnet_key-dev-ase"
+ subnet = (known after apply)
}
Plan: 4 to add, 0 to change, 0 to destroy.
azurerm_resource_group.rg["australiaeast"]: Creating...
azurerm_resource_group.rg["australiasoutheast"]: Creating...
azurerm_resource_group.rg["australiaeast"]: Creation complete after 5s [id=/subscriptions/xxxxxxxxxxxx/resourceGroups/test-rg-vnet_key-dev-ae]
azurerm_resource_group.rg["australiasoutheast"]: Creation complete after 6s [id=/subscriptions/xxxxxxxxxxxx/resourceGroups/test-rg-vnet_key-dev-ase]
azurerm_virtual_network.vnet["test-rg-vnet_key-dev-ae"]: Creating...
azurerm_virtual_network.vnet["test-rg-vnet_key-dev-ase"]: Creating...
azurerm_virtual_network.vnet["test-rg-vnet_key-dev-ase"]: Still creating... [10s elapsed]
azurerm_virtual_network.vnet["test-rg-vnet_key-dev-ae"]: Still creating... [10s elapsed]
azurerm_virtual_network.vnet["test-rg-vnet_key-dev-ae"]: Creation complete after 18s [id=/subscriptions/xxxxxxxxxxxx/resourceGroups/test-rg-vnet_key-dev-ae/providers/Microsoft.Network/virtualNetworks/test-rg-vnet_key-dev-ae]
azurerm_virtual_network.vnet["test-rg-vnet_key-dev-ase"]: Creation complete after 19s [id=/subscriptions/xxxxxxxxxxxx/resourceGroups/test-rg-vnet_key-dev-ase/providers/Microsoft.Network/virtualNetworks/test-rg-vnet_key-dev-ase]
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
Hope it helps.
And additional info which is not relevant here too much I have used static values instead of some variables.
rg_name = var.environment != "" ? format("%s-rg-%s-%s-%s", "test", "vnet_key", var.environment, region.code) : format("%s-rg-%s-%s", "test", "vnet_key", region.code)
vnet_name = var.environment != "" ? format("%s-rg-%s-%s-%s", "test", "vnet_key", var.environment, region.code) : format("%s-rg-%s-%s", "test", "vnet_key", region.code)

Why isn't terraform interpolation working?

So my goal is to have write a terraform code to deploy 3 resource groups in AZ dev, uat and prod with each having the following resources.
SQL Database
Key Vault
variable.tf
variable "resource_group_name" {
description = "deafault resource group"
type = list (string)
default = ["Test-dev","Test-uat","Test-prod"]
}
variable "storage_account_name" {
description = "name for storage account"
default = "test-storageact"
}
main.tf
resource "azurerm_resource_group" "resgrp" {
for_each = toset(var.resource_group_name)
name = "${var.resource_group_name}-rg-${each.value}"
location = var.location
tags = {
"Environment" = "${var.env}-${each.value}"
}
}
resource "azurerm_storage_account" "storageact" {
for_each = toset(var.resource_group_name)
name = "${var.storage_account_name}-${each.value}"
resource_group_name = azurerm_resource_group.resgrp["${each.value}"].location
location = azurerm_resource_group.resgrp["${each.value}"].name
account_tier = "Standard"
account_replication_type = "LRS"
tags = {
"Environment" = "${var.env}-${each.value}"
}
}
error message
│ Error: Invalid template interpolation value
│
│ on main.tf line 3, in resource "azurerm_resource_group" "resgrp":
│ 3: name = "${var.resource_group_name}-rg-${each.value}"
│ ├────────────────
│ │ var.resource_group_name is list of string with 3 elements
│
│ on main.tf line 6, in resource "azurerm_resource_group" "resgrp":
│ 6: "Environment" = "${var.env}-${each.value}"
│ ├────────────────
│ │ var.env is map of string with 3 elements
│
│ Cannot include the given value in a string template: string required.
╵
Operation failed: failed running terraform plan (exit 1)
please any help will be greatly appreciated.
i tried using type = map(string) in the variable but still gave me an error.
There are a few problems with the code.
var.resource_group_name is a list containing 3 string elements (by default), and thus the error: var.resource_group_name is list of string with 3 elements explains the problem, and is illustrated below.
The var.env is a map consisting of 3 elements and also being used as a string and fails for the same reason.
resource "azurerm_resource_group" "resgrp" {
for_each = toset(var.resource_group_name)
# var.resource_group_name is actually a list, but it's being
# used as a string here, which will fail.
name = "${var.resource_group_name}-rg-${each.value}"
location = var.location
tags = {
"Environment" = "${var.env}-${each.value}"
}
}
You probably instead want:
resource "azurerm_resource_group" "resgrp" {
for_each = toset(var.resource_group_name)
name = "${each.value}-rg"
location = var.location
tags = {
"Environment" = "${each.value}"
}
}
Additionally, as an alternative to the approach of putting multiple environments in a single resource construct, consider using modules to create reusable infrastructure for your resources and then calling each module for the environment that you're using, this is a best practice when implementing duplicate or near-duplicate infrastructure across multiple environments and allows you some flexibility with naming conventions and other parameters that would differ based upon the environment.
Rough example:
module "test-dev" {
source = "../modules/infrastructure"
environment = "Test-dev"
vm_count = 1
}
module "test-uat" {
source = "../modules/infrastructure"
environment = "Test-dev"
vm_count = 3
}
module "test-prod" {
source = "../modules/infrastructure"
environment = "Test-prod"
account_tier = "Premium"
vm_count = 6
}

Creating dynamic block in azurerm_api_management_api terraform

I am trying to create APIs with certain inputs dynamically into an APIM instance in azure. For that I have created a resource azurerm_api_management_api, to which I am going to pass the values like name, version, display name dynamically from a local.tf file. But when I tried, the error was
Error: Unsupported block type
│
│ on api-management\api_management_api.tf line 6, in resource "azurerm_api_management_api" "apim_api":
│ 6: dynamic apiValues{
│
│ Blocks of type "apiValues" are not expected here.
Here is the resource block.
resource "azurerm_api_management_api" "apim_api" {
revision = "1"
resource_group_name = var.resource_group_name
api_management_name = azurerm_api_management.apim.name
dynamic apiValues{
for_each = local.apiDetails
content{
name = apiValues.value.name
display_name = apiValues.value.display_name
path = ""
protocols = ["http","https"]
service_url = "http://spring-boot-redis.azurewebsites.net"
import {
content_format = "openapi-link"
content_value = "./SpringBootRedis.yaml"
}
}
}
}
locals.tf
locals {
apiDetails = [
{
name = "spring-boot-redis"
display_name = "Spring Boot Redis"
}
]
}
Is there any other way to achieve this? As I am planning to put this on an azure pipeline. So that I have to only take care of the API specification and names.
I am unsure why you are attempting to use a dynamic block for a block that does not exist according to the documentation. The error message agrees the block does not exist in the resource schema.
It appears what you are trying to achieve here is multiple resources with a value from a local.apiDetails:
resource "azurerm_api_management_api" "apim_api" {
for_each = local.apiDetails
revision = "1"
resource_group_name = var.resource_group_name
api_management_name = azurerm_api_management.apim.name
name = each.value.name
display_name = each.value.display_name
path = ""
protocols = ["http","https"]
service_url = "http://spring-boot-redis.azurewebsites.net"
import {
content_format = "openapi-link"
content_value = "./SpringBootRedis.yaml"
}
}
The documentation has more information.

Terraform Data source is not picking subnet or resource group properly

I started writing terraform to automate the iac for provisioning VMs in Azure. However I wrote the entire code but am unable to use the existing subnet/vnet/resource group properly.
main.tf
# Configure the Microsoft Azure Provider
provider "azurerm" {
# The "feature" block is required for AzureRM provider 2.x.
# If you're using version 1.x, the "features" block is not allowed.
#version = "~>2.20.0"
features {}
subscription_id = var.subscription_id
tenant_id = var.tenant_id
client_id = var.client_id
client_secret = var.client_secret
}
#terraform {
# backend "azurerm" {
# snapshot = true
#}
#}
# Refer to resource group
data "azurerm_resource_group" "nwrk_group" {
name = var.nwrk_resource_group
}
data "azurerm_resource_group" "resource_group" {
name = var.resource_group
}
# Refer to a subnet
data "azurerm_subnet" "subnet" {
name = var.nwrk_subnet_name
virtual_network_name = var.nwrk_name
resource_group_name = data.azurerm_resource_group.nwrk_group.name
}
# Refer to Network Security Group and rule
data "azurerm_network_security_group" "nwrk_security_group" {
name = var.nwrk_security_grp
resource_group_name = data.azurerm_resource_group.nwrk_group.name
}
module "vm" {
source = "../modules/windows_vm"
node = var.node
node_username = var.node_username
node_password = var.node_password
tags = var.tags
deployment_environment = var.deployment_environment
nwrk_group_location = data.azurerm_resource_group.resource_group.location
nwrk_group_name = data.azurerm_resource_group.resource_group.name
subnet_id = data.azurerm_subnet.subnet.id
nwrk_security_group_id = data.azurerm_network_security_group.nwrk_security_group.id
resource_group_location = data.azurerm_resource_group.resource_group.location
resource_group_name = data.azurerm_resource_group.resource_group.name
}
terraform.tfvars
tags = {
project = "SEPS_Terraform"
environment = "test_tfm"
}
deployment_environment = "DEV"
node_username = "saz76test"
node_password = "SA82nd2"
nwrk_subnet_name = "SUBNET_45_0"
node = {
general_info = {
name = "gateway.test.com"
private_ip = "153.78.51.92"
vm_template = "Standard_B2s"
disk_type = "StandardSSD_LRS"
nwrk_resource_group = "SWS_LAB_36_192"
nwrk_name = "SUB_VNET_36_192"
nwrk_security_group = "N-Untrusted"
nwrk_subnet_name = "SUB_51_0"
}
os_image = {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2019-DataCenter"
version = "latest"
}
storage_disk = {
type = "StandardSSD_LRS"
size = 256
}
}
variables.tf
variable "subscription_id" {
type = string
description = "Azure subscription id to provision infra."
}
variable "tenant_id" {
type = string
description = "Azure subscription tenant id"
}
variable "client_id" {
type = string
description = "App id to authenticate to azure."
}
variable "client_secret" {
type = string
description = "App password to authenticate to azure"
}
variable "resource_group" {
type = string
description = "Resource group in which resources will be added other than network resources"
}
variable "nwrk_resource_group" {
type = string
description = "Resource group for network resources"
}
variable "nwrk_name" {
type = string
description = "VPC network name where the network resources belong to"
}
variable "nwrk_subnet_name" {
type = string
description = "Subnet of the VPC network"
}
variable "nwrk_security_grp" {
type = string
description = "Security group to which the network belong to"
}
variable "tags" {
type = map(string)
description = "Tags to attach to resources"
}
variable "deployment_environment" {
type = string
description = "Environment these VMs belong to"
}
variable "node" {
type = map(map(string))
description = "web node with specifications."
}
variable "node_username" {
type = string
description = "Login username for node"
}
variable "node_password" {
type = string
description = "Login password for node"
}
module_code:
# Create network interface
resource "azurerm_network_interface" "nic" {
name = "${var.node["general_info"]["name"]}_nic"
location = var.nwrk_group_location
resource_group_name = var.nwrk_group_name
ip_configuration {
name = "${var.node["general_info"]["name"]}_nicConfiguration"
subnet_id = var.subnet_id
private_ip_address_allocation = "Static"
private_ip_address = var.node["general_info"]["private_ip"]
}
tags = var.tags
}
# Connect the security group to the network interface
resource "azurerm_network_interface_security_group_association" "example" {
network_interface_id = azurerm_network_interface.nic.id
network_security_group_id = var.nwrk_security_group_id
}
resource "azurerm_windows_virtual_machine" "vm" {
name = var.node["general_info"]["name"]
location = var.resource_group_location
resource_group_name = var.resource_group_name
network_interface_ids = [azurerm_network_interface.nic.id]
size = var.node["general_info"]["vm_template"]
computer_name = var.node["general_info"]["name"]
admin_username = var.node_username
admin_password = var.node_password
os_disk {
name = "${var.node["general_info"]["name"]}-osDisk"
caching = "ReadWrite"
storage_account_type = var.node["general_info"]["disk_type"]
}
source_image_reference {
publisher = var.node["os_image"]["publisher"]
offer = var.node["os_image"]["offer"]
sku = var.node["os_image"]["sku"]
version = var.node["os_image"]["version"]
}
tags = var.tags
}
output "vm_id" {
value = azurerm_windows_virtual_machine.vm.id
}
output "vm_name" {
value = azurerm_windows_virtual_machine.vm.name
}
output "vm_ip_address" {
value = azurerm_network_interface.nic.private_ip_address
}
My code is above one which am trying to execute init working but plan is failing to do. Can someone please help me on this what I am missing. ?? The error is getting like it.
Error :
Warning: Value for undeclared variable
│
│ The root module does not declare a variable named "nwrk_security_group" but a value was found in file "subscription.tfvars". If you meant to use
│ this value, add a "variable" block to the configuration.
│
│ To silence these warnings, use TF_VAR_... environment variables to provide certain "global" settings to all configurations in your organization.
│ To reduce the verbosity of these warnings, use the -compact-warnings option.
╵
╷
│ Warning: Resource targeting is in effect
│
│ You are creating a plan with the -target option, which means that the result of this plan may not represent all of the changes requested by the
│ current configuration.
│
│ The -target option is not for routine use, and is provided only for exceptional situations such as recovering from errors or mistakes, or when
│ Terraform specifically suggests to use it as part of an error message.
╵
╷
│ Error: Error: Subnet "SUBNET_45_0" (Virtual Network "SUB_VNET_36_192" / Resource Group "SWS_LAB_36_192") was not found
│
│ with data.azurerm_subnet.subnet,
│ on main.tf line 31, in data "azurerm_subnet" "subnet":
│ 31: data "azurerm_subnet" "subnet" {
│
╵
╷
│ Error: Error: Network Security Group "NSG" (Resource Group "SWS_LAB_36_192") was not found
│
│ with data.azurerm_network_security_group.nwrk_security_group,
│ on main.tf line 38, in data "azurerm_network_security_group" "nwrk_security_group":
│ 38: data "azurerm_network_security_group" "nwrk_security_group" {
Subscription.tfvars
subscription_id = "fdssssssssssssss"
client_id = "sdsdsdsdsdsdsdsdsdsdsdsd"
client_secret = ".dssssssssssssssssss
tenant_id = "asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdf"
resource_group = "SWS_LAB_36_192"
nwrk_resource_group = "SWS_LAB_36_192"
nwrk_name = "SUB_VNET_36_192"
nwrk_security_group = "N-Untrusted"
There could potentially be many different problems because I am not sure what the outlook of the root module and child modules are, but as per the error you are getting, it seems that the value defined for the variable in the subscription.tfvars is not being declared anywhere and the one that is supposed to be declared is missing, the data source does not return anything, hence there is the error from the child module as well. Currently it is defined as:
variable "nwrk_security_grp" {
type = string
description = "Security group to which the network belong to"
}
If you take a look at the values in subscription.tfvars, there is no nwrk_security_grp, but there is a nwrk_security_group. One option to fix this would probably be to change the name of the variable in the variables.tf:
variable "nwrk_security_group" {
type = string
description = "Security group to which the network belong to"
}
In that case, you would have to adapt the data source to use the new variable name:
data "azurerm_network_security_group" "nwrk_security_group" {
name = var.nwrk_security_group
resource_group_name = data.azurerm_resource_group.nwrk_group.name
}
Alternatively (and probably easier), you can change the name of the variable you are assigning the value to in subscription.tfvars:
nwrk_security_grp = "N-Untrusted" # it was nwrk_security_group
What I would strongly suggest going forward is to keep the naming convention for the variables the same because this way you will get into a lot of issues.

Resources