Deployment of Azure order issue Terraform - azure

When deploying Azure resources with Terraform Cloud I'm expierencing an unexpected bahaviour.
It looks like the order of deployment or the wait time between the resources is failing.
The error says that the deployment of the network inteface failed because the subnet is not created.
I already tried to implement the depends_on function, but this doesnt seem to help at all.
# Create a virtual network within the core resource group
resource "azurerm_virtual_network" "avd_default" {
name = "Vnet_${var.prefix}_Core-Prod"
resource_group_name = azurerm_resource_group.avd_default_core_rg.name
location = azurerm_resource_group.avd_default_core_rg.location
address_space = [var.avd_address_space]
}
# Create a Core internal subnet within vNet
resource "azurerm_subnet" "avd_default_core_internal" {
name = "Subnet_${var.prefix}_Core-Prod"
resource_group_name = azurerm_resource_group.avd_default_core_rg.name
virtual_network_name = azurerm_virtual_network.avd_default.name
address_prefixes = [var.core_address_prefixes]
depends_on = [
azurerm_virtual_network.avd_default
]
}
# Create a Core external subnet within vNet
resource "azurerm_subnet" "avd_default_core_external" {
name = "Subnet_${var.prefix}_Internet-Prod"
resource_group_name = azurerm_resource_group.avd_default_core_rg.name
virtual_network_name = azurerm_virtual_network.avd_default.name
address_prefixes = [var.internet_address_prefixes]
depends_on = [
azurerm_virtual_network.avd_default
]
}
# Create the Network interface for DC01
resource "azurerm_network_interface" "avd_default_dc01" {
name = "dc01-nic"
location = azurerm_resource_group.avd_default_core_rg.location
resource_group_name = azurerm_resource_group.avd_default_core_rg.name
dns_servers = [var.private_ip_dc01,"8.8.8.8"]
ip_configuration {
name = "ipconfig1"
subnet_id = azurerm_subnet.avd_default_core_internal.id
private_ip_address_allocation = "Static"
private_ip_address = var.private_ip_dc01
}
depends_on = [
azurerm_subnet.avd_default_core_internal
]
}
# Create DC01 Windows Server 2022
resource "azurerm_windows_virtual_machine" "avd_default_dc01" {
name = "${var.prefix}-dc01"
resource_group_name = azurerm_resource_group.avd_default_core_rg.name
location = azurerm_resource_group.avd_default_core_rg.location
size = var.dc01_vm_size
admin_username = "username"
admin_password = var.dc01_admin_password
network_interface_ids = [azurerm_network_interface.avd_default_dc01.id]
os_disk {
caching = "ReadWrite"
storage_account_type = "StandardSSD_LRS"
disk_size_gb = "128"
}
source_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2022-datacenter-azure-edition"
version = "latest"
}
}
Error written below:
Error: Subnet "Subnet_gro_Core-Prod" (Virtual Network "Vnet_gro_Core-Prod" / Resource Group "RG_gro_Core-Prod") was not found!
with azurerm_subnet_route_table_association.avd_default_wg
on main.tf line 316, in resource "azurerm_subnet_route_table_association" "avd_default_wg":
resource "azurerm_subnet_route_table_association" "avd_default_wg" {
Error: creating Network Interface: (Name "dc01-nic" / Resource Group "RG_gro_Core-Prod"): network.InterfacesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidResourceReference" Message="Resource /subscriptions/xxxb91c5-4fe5-44af-9c98-cdd8e73ee240/resourceGroups/RG_gro_Core-Prod/providers/Microsoft.Network/virtualNetworks/Vnet_gro_Core-Prod/subnets/Subnet_gro_Core-Prod referenced by resource /subscriptions/xxxb91c5-4fe5-44af-9c98-cdd8e73ee240/resourceGroups/RG_gro_Core-Prod/providers/Microsoft.Network/networkInterfaces/dc01-nic was not found. Please make sure that the referenced resource exists, and that both resources are in the same region." Details=[]
with azurerm_network_interface.avd_default_dc01
on main.tf line 78, in resource "azurerm_network_interface" "avd_default_dc01":
resource "azurerm_network_interface" "avd_default_dc01" {
Error: creating Network Interface: (Name "wg-nic-internal" / Resource Group "RG_gro_Watchguard-Prod"): network.InterfacesClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidResourceReference" Message="Resource /subscriptions/xxxb91c5-4fe5-44af-9c98-cdd8e73ee240/resourceGroups/RG_gro_Core-Prod/providers/Microsoft.Network/virtualNetworks/Vnet_gro_Core-Prod/subnets/Subnet_gro_Core-Prod referenced by resource /subscriptions/xxxb91c5-4fe5-44af-9c98-cdd8e73ee240/resourceGroups/RG_gro_Watchguard-Prod/providers/Microsoft.Network/networkInterfaces/wg-nic-internal was not found. Please make sure that the referenced resource exists, and that both resources are in the same region." Details=[]
with azurerm_network_interface.avd_default_wg_internal
on main.tf line 156, in resource "azurerm_network_interface" "avd_default_wg_internal":
resource "azurerm_network_interface" "avd_default_wg_internal" {
Running the terraform deploy command for a second time after this errors it is working as expected.

Related

Subnet not creating

I keep getting this weird error according to me, is there a fix for this.
data "azurerm_resource_group" "rg" {
name = var.resource_group_name
#environment = var.environment
}
resource "azurerm_virtual_network" "vnet" {
name = var.vnet_name
location = var.location
resource_group_name = var.resource_group_name
address_space = var.address_space
}
resource "azurerm_subnet" "subnet" {
name = var.subnet_name
resource_group_name = var.resource_group_name
virtual_network_name = var.vnet_name
address_prefixes = ["10.0.0.0/24"]
service_endpoints = ["Microsoft.Sql"]
delegation {
name = "delegation"
service_delegation {
name = "Microsoft.ContainerInstance/containerGroups"
actions = ["Microsoft.Network/virtualNetworks/subnets/join/action", "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action"]
}
}
}
I keep getting this error
azurerm_subnet.subnet: Creating...
azurerm_virtual_network.vnet: Creating...
azurerm_virtual_network.vnet: Creation complete after 5s [id=/subscriptions/e4da9536-6759-4506-b0cf-10c70facd033/resourceGroups/rg-sagar/providers/Microsoft.Network/virtualNetworks/vnet]
╷
│ Error: creating Subnet: (Name "subnet" / Virtual Network Name "vnet" / Resource Group "rg-sagar"): network.SubnetsClient#CreateOrUpdate: Failure sending request: StatusCode=404 -- Original Error: Code="ResourceNotFound" Message="The Resource 'Microsoft.Network/virtualNetworks/vnet' under resource group 'rg-sagar' was not found. For more details please
go to https://aka.ms/ARMResourceNotFoundFix"│
│ with azurerm_subnet.subnet,
│ on main.tf line 14, in resource "azurerm_subnet" "subnet":
│ 14: resource "azurerm_subnet" "subnet" {
│
Even after the vnet is created, it is unable to create a vnet, any idea how I can make this work
Any idea how to fix this?
You need to use this statement virtual_network_name = azurerm_virtual_network.vnet.name instead of virtual_network_name = var.vnet_name.
Becuause virtual_network_name = var.vnet_name in subnet resource block simultaneously creating subnet and vnet so this is not good fit in azure. Because subnet dependent on Vnet. So Vnet Should create first. So you need to use virtual_network_name = azurerm_virtual_network.vnet.name for using the existing Vnet.
Terraform Code
provider "azurerm" {
features{}
}
data "azurerm_resource_group" "rg" {
name = var.resource_group_name
#environment = var.environment
}
resource "azurerm_virtual_network" "vnet" {
name = var.vnet_name
location = data.azurerm_resource_group.rg.location
resource_group_name = var.resource_group_name
address_space = var.address_space
}
resource "azurerm_subnet" "subnet"{
name = var.subnet_name
resource_group_name = var.resource_group_name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.0.0/24"]
service_endpoints = ["Microsoft.Sql"]
delegation {
name = "delegation"
service_delegation {
name = "Microsoft.ContainerInstance/containerGroups"
actions = ["Microsoft.Network/virtualNetworks/subnets/join/action", "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action"]
}
}
}
I think this question requires a bit more explanation, since there is nothing wrong with the code. Terraform is trying to be smart about the way it creates resources, so it tries to create as much as it can in one run. This is why there is an option called -parallelism:
-parallelism=n Limit the number of parallel resource operations.
Defaults to 10.
This means that when running terraform apply, Terraform will try to run 10 resource operations including resource creation. In your case, it will try to create both the vnet and the subnet resource (parallelism applies in apply, plan and destroy). However, since you are using the same variable in both resources (var.vnet_name), Terraform is not aware that there are dependencies between the two. The way you have structured your code now would work if you were to create the vnet first and add the subnet resource after the vnet is created. Or if you are feeling adventurous you could set the parallelism to 1. Since you probably do not want that, the best way to tell Terraform in which order to create stuff is by using resource dependencies. Terraform has a concept of implicit [1] and explicit [2] dependencies. Dependencies help Terraform decide what needs to be created, based on the graph it creates [3].
There are two options in your case:
Create an implicit dependency between vnet and subnet
Create an explicit dependency between vnet and subnet
As using depends_on (or explicit dependency) is advised only in cases where there is not another way to tell Terraform that two resources are interdependent, the best way to do it is by using the implicit dependency:
data "azurerm_resource_group" "rg" {
name = var.resource_group_name
}
resource "azurerm_virtual_network" "vnet" {
name = var.vnet_name
location = var.location
resource_group_name = var.resource_group_name
address_space = var.address_space
}
resource "azurerm_subnet" "subnet" {
name = var.subnet_name
resource_group_name = var.resource_group_name
virtual_network_name = azurerm_virtual_network.vnet.name # <-- implicit dependency
address_prefixes = ["10.0.0.0/24"]
service_endpoints = ["Microsoft.Sql"]
delegation {
name = "delegation"
service_delegation {
name = "Microsoft.ContainerInstance/containerGroups"
actions = ["Microsoft.Network/virtualNetworks/subnets/join/action", "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action"]
}
}
}
The vnet resource exports some attributes after it is created [4], including the name attribute. This helps with creating the implicit dependency: by referencing a resource and one of the attributes that is available after the resource is created, you are telling Terraform that it first needs to create the vnet and only after it is available it can start with subnet creation.
[1] https://www.terraform.io/language/resources/behavior#resource-dependencies
[2] https://www.terraform.io/language/meta-arguments/depends_on
[3] https://www.terraform.io/internals/graph#resource-graph
[4] https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network#attributes-reference

Can I perform consecutive changes on resource with Terraform?

Sometimes I need to perform several changes to the resource with TF ( within same declaration file ) , for example:
Create Azure VNET/Subnet A
Create Private Endpoint
Change properties of Subnet A from #1
I tried to create same resource with depends_on statement, but it doesn't work.
module.vnet-stage2[1].azurerm_virtual_network.vnet: Creating...
module.vnet-stage2[0].azurerm_virtual_network.vnet: Creating...
╷
│ Error: A resource with the ID "/subscriptions/6fd2b24c-1ffa-43ca-abc1-8127c30dcb39/resourceGroups/PE-TF-RG/providers/Microsoft.Network/virtualNetworks/client-vnet" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_virtual_network" for more information.
│
│ with module.vnet-stage2[0].azurerm_virtual_network.vnet,
│ on ../../modules/vnet/main.tf line 6, in resource "azurerm_virtual_network" "vnet":
│ 6: resource azurerm_virtual_network "vnet" {
│
╵
╷
│ Error: A resource with the ID "/subscriptions/6fd2b24c-1ffa-43ca-abc1-8127c30dcb39/resourceGroups/PE-TF-RG/providers/Microsoft.Network/virtualNetworks/server-vnet" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_virtual_network" for more information.
│
│ with module.vnet-stage2[1].azurerm_virtual_network.vnet,
│ on ../../modules/vnet/main.tf line 6, in resource "azurerm_virtual_network" "vnet":
│ 6: resource azurerm_virtual_network "vnet" {
│
╵
I tried testing your requirement with the below code. It's not possible to change the subnet enforce_private_link_service_network_policies = true to false from the same declaration file.
provider "azurerm" {
features{}
}
data "azurerm_resource_group" "example" {
name = "yourresourcegroup"
}
resource "azurerm_virtual_network" "example" {
name = "example-network"
address_space = ["10.0.0.0/16"]
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
}
resource "azurerm_subnet" "service" {
name = "service"
resource_group_name = data.azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.1.0/24"]
enforce_private_link_service_network_policies = true
}
resource "azurerm_subnet" "endpoint" {
name = "endpoint"
resource_group_name = data.azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.2.0/24"]
enforce_private_link_endpoint_network_policies = true
}
resource "azurerm_public_ip" "example" {
name = "example-pip"
sku = "Standard"
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
allocation_method = "Static"
}
resource "azurerm_lb" "example" {
name = "example-lb"
sku = "Standard"
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
frontend_ip_configuration {
name = azurerm_public_ip.example.name
public_ip_address_id = azurerm_public_ip.example.id
}
}
resource "azurerm_private_link_service" "example" {
name = "example-privatelink"
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
nat_ip_configuration {
name = azurerm_public_ip.example.name
primary = true
subnet_id = azurerm_subnet.service.id
}
load_balancer_frontend_ip_configuration_ids = [
azurerm_lb.example.frontend_ip_configuration.0.id,
]
}
resource "azurerm_private_endpoint" "example" {
name = "example-endpoint"
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
subnet_id = azurerm_subnet.endpoint.id
private_service_connection {
name = "example-privateserviceconnection"
private_connection_resource_id = azurerm_private_link_service.example.id
is_manual_connection = false
}
}
Output:
When you try to change the value to false, you get the below error:
Solution:
You can create Vnet+Subnet first on file and then create private endpoint in another using data sources of the vnet and subnet. After private endpoint is created you can change the properties of subnet by going to the vnet+subnet file.
Or
You can create everything at once then use PowerShell or CLI to change that property of subnet.
Command for CLI:
az network vnet subnet update --disable-private-endpoint-network-policies false --name service --resource-group resourcegroup --vnet-name example-network.
Reference:
Manage network policies for private endpoints - Azure Private Link | Microsoft Docs
Note: enforce_private_link_service_network_policies = true on a subnet is mandatory for creating a private endpoint. After creation you can change to enforce_private_link_service_network_policies = false.

Error on adding a storage share to the Azure storage account

I'm getting the following error on running terraform apply after adding an azurerm_storage_share.
Error: Error checking for existence of existing Storage Share "fileshare"
(Account "sttestforaddingfileshare" / Resource Group "resources"):
shares.Client#GetProperties: Failure responding to request: StatusCode=403
-- Original Error: autorest/azure: Service returned an error.
Status=403 Code="AuthorizationFailure"
Message="This request is not authorized to perform this operation.
\nRequestId:188ae38b-e01a-000b-35b3-a32ea2000000
\nTime:2020-10-16T11:55:16.7337008Z"
I think the reason is most likely that Terraform tries to list existing file shares in the storage account directly accessing the storage account's REST API instead of Azure Resource Manager's REST API.
It failed because there exist firewall rules in place not containing the IP of the host terraform runs on. When I add my laptop's IP to the firewall rules, it works. But it's not the desired behavior.
Do you know any workaround? Any help is appreciated.
My TF configuration is as follows:
provider "azurerm" {
version = "= 2.32.0"
features {}
}
resource "azurerm_resource_group" "rg" {
name = "resources"
location = var.location
}
resource "azurerm_virtual_network" "vnet" {
name = "vnet"
location = var.location
resource_group_name = azurerm_resource_group.rg.name
address_space = ["10.0.0.0/16"]
}
resource "azurerm_subnet" "snet" {
name = "snet"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.vnet.name
address_prefixes = ["10.0.1.0/24"]
service_endpoints = [ "Microsoft.Storage" ]
}
resource "azurerm_storage_account" "storage" {
name = "sttestforaddingfileshare"
resource_group_name = azurerm_resource_group.rg.name
location = var.location
account_tier = "Standard"
account_replication_type = "LRS"
network_rules {
default_action = "Deny"
virtual_network_subnet_ids = [ azurerm_subnet.snet.id ]
bypass = [ "None" ]
}
}
resource "azurerm_storage_share" "file_share" {
name = "fileshare"
storage_account_name = azurerm_storage_account.storage.name
quota = 100
}
You can use the azurerm_storage_account_network_rules resource to define the Network Rules and remove the Network Rules block defined directly on the azurerm_storage_account resource.
Also, you can create your file share via using az CLI instead of the separate resource "azurerm_storage_share"
After my validation, with the
PS D:\Terraform> .\terraform.exe -v
Terraform v0.13.4
+ provider registry.terraform.io/hashicorp/azurerm v2.32.0
It worked when terraform apply and terraform destroy.
resource "azurerm_storage_account" "storage" {
name = "nnnstore1"
resource_group_name = azurerm_resource_group.rg.name
location = var.location
account_tier = "Standard"
account_replication_type = "LRS"
provisioner "local-exec" {
command =<<EOT
az storage share create `
--account-name ${azurerm_storage_account.storage.name} `
--account-key ${azurerm_storage_account.storage.primary_access_key} `
--name ${var.myshare} `
--quota 100
EOT
interpreter = [ "Powershell", "-c"]
}
}
resource "azurerm_storage_account_network_rules" "test" {
resource_group_name = azurerm_resource_group.rg.name
storage_account_name = azurerm_storage_account.storage.name
default_action = "Deny"
virtual_network_subnet_ids = [azurerm_subnet.snet.id]
bypass = ["None"]
}
I recently ran into this issue when attempting to create a storage share for a container group. It was pretty much identical code to yours but with the additional container group.
I came across the issue when deploying the stack as new and I bypassed the error by deploying everything but the storage share component and all references to it.
Then when that was completed I introduced the storage share and redeployed without issue.
Crappy work around but its deployed again.

Terraform/HCL in Azure issues

I am new to HCL and Terraform and have having issues with associating a security group and a backend address pool to the network interface. I am creating 2 network interfaces in a single network interface block:
#Create network interface for 2 VMs
resource "azurerm_network_interface" "FrontNetworkInterface" {
count = 2
name = "niFront${count.index}"
location = azurerm_resource_group.PWSDevResourceGroup.location
resource_group_name = azurerm_resource_group.PWSDevResourceGroup.name
ip_configuration {
name = "ipconfFrontVM"
subnet_id = azurerm_subnet.PWSDevSubnet.id
private_ip_address_allocation = "dynamic"
}
}
I have tried associating in various ways that have produced different errors:
ATTEMPT 1:
#Connect security group to the network interface
resource "azurerm_network_interface_security_group_association" "PWSDevSecurityGroupAssoc" {
network_interface_id = azurerm_network_interface.FrontNetworkInterface.id
network_security_group_id = azurerm_network_security_group.PWSDevSecurityGroup.id
}
#Connect 2 backend ips to the load balancer
resource "azurerm_network_interface_backend_address_pool_association" "BackendIPAssoc" {
network_interface_id = azurerm_network_interface.FrontNetworkInterface.id
ip_configuration_name = "bipa"
backend_address_pool_id = azurerm_lb_backend_address_pool.BackendIpPool.id
}
ERRORS:
Error: Missing resource instance key
on front.tf line 85, in resource "azurerm_network_interface_security_group_association" "PWSDevSecurityGroupAssoc":
85: network_interface_id = azurerm_network_interface.FrontNetworkInterface.id
Because azurerm_network_interface.FrontNetworkInterface has "count" set, its
attributes must be accessed on specific instances.
For example, to correlate with indices of a referring resource, use:
azurerm_network_interface.FrontNetworkInterface[count.index]
Error: Missing resource instance key
on front.tf line 91, in resource "azurerm_network_interface_backend_address_pool_association" "BackendIPAssoc":
91: network_interface_id = azurerm_network_interface.FrontNetworkInterface.id
Because azurerm_network_interface.FrontNetworkInterface has "count" set, its
attributes must be accessed on specific instances.
For example, to correlate with indices of a referring resource, use:
azurerm_network_interface.FrontNetworkInterface[count.index]
ATTEMPT 2/3/4 (Using "[count.index]", "[count.index].id", or "[element(azurerm_network_interface.FrontNetworkInterface.*.id, count.index)]" as described in the previous error):
#Connect security group to the network interface
resource "azurerm_network_interface_security_group_association" "PWSDevSecurityGroupAssoc" {
network_interface_id = azurerm_network_interface.FrontNetworkInterface[count.index]
network_security_group_id = azurerm_network_security_group.PWSDevSecurityGroup.id
}
#Connect 2 backend ips to the load balancer
resource "azurerm_network_interface_backend_address_pool_association" "BackendIPAssoc" {
network_interface_id = azurerm_network_interface.FrontNetworkInterface[count.index]
ip_configuration_name = "bipa"
backend_address_pool_id = azurerm_lb_backend_address_pool.BackendIpPool.id
}
ERROR (Same result for [count.index].id and [element(azurerm_network_interface.FrontNetworkInterface.*.id, count.index)]):
Error: Reference to "count" in non-counted context
on front.tf line 85, in resource "azurerm_network_interface_security_group_association" "PWSDevSecurityGroupAssoc":
85: network_interface_id = azurerm_network_interface.FrontNetworkInterface[count.index]
The "count" object can only be used in "module", "resource", and "data"
blocks, and only when the "count" argument is set.
Error: Reference to "count" in non-counted context
front.tf line 91, in resource "azurerm_network_interface_backend_address_pool_association" "BackendIPAssoc":
network_interface_id = azurerm_network_interface.FrontNetworkInterface[count.index]
The "count" object can only be used in "module", "resource", and "data"
blocks, and only when the "count" argument is set.
Also, I am receiving this error on my azurerm_virtual_machine block:
line 162, in resource "azurerm_virtual_machine" "FrontEndVirtualMachines":
162: admin_ssh_key {
Blocks of type "admin_ssh_key" are not expected here.
I am following what is shown here:
https://learn.microsoft.com/en-us/azure/developer/terraform/create-linux-virtual-machine-with-infrastructure
As you can see, the admin_ssh_key block is provided. I tried using version 2.0 as used in the scripts; however, I experienced the same result.
Thanks for your help!! :)
When referencing a resource created with count you still need to add the .id. See the following example. For more information see this link.
provider "azurerm" {
version = "~>2.23.0"
features {}
}
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "East US"
}
resource "azurerm_virtual_network" "example" {
name = "vnet"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
address_space = ["10.0.0.0/16"]
dns_servers = ["10.0.0.4", "10.0.0.5"]
}
resource "azurerm_subnet" "example" {
name = "example"
resource_group_name = azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.1.0/24"]
}
resource "azurerm_network_interface" "example" {
count = 2
name = format("int%s", count.index)
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
ip_configuration {
name = "ip"
subnet_id = azurerm_subnet.example.id
private_ip_address_allocation = "dynamic"
}
}
resource "azurerm_network_security_group" "example" {
name = "acceptanceTestSecurityGroup1"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
security_rule {
name = "test123"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "*"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
resource "azurerm_network_interface_security_group_association" "secgroup" {
count = length(azurerm_network_interface.example)
network_interface_id = azurerm_network_interface.example[count.index].id
network_security_group_id = azurerm_network_security_group.example.id
}
I will admit that I haven't read the whole story, but it looks like your attempt #2/3/4 was pretty close. Where you use [count.index], you need to specify a count, otherwise there's no count to index. So if you just add count = 2 to those two resource blocks, it should work.
Better yet, either have the 2 as a variable, or use
count = len(azurerm_network_interface.FrontNetworkInterface)
to ensure you don't end up with mismatched numbers when you change the 2 later on.

What is the backend process of a terraform script for associating a Azure NSG

The script given below works fine. But the problem is that when I give Terraform apply the second time it disassociates the NSG from the subnets. And when I apply again it associates to the subnets. Is there any problem with my code or what does this line actually does maybe that will solve my problem.
network_security_group_id =
"${element(azurerm_network_security_group.NetworkSG.*.id,count.index)}"
The below code is my main.tf:
resource "azurerm_subnet" "Subnet" {
count = "${length(var.Subnet_name)}"
name = "${var.Subnet_name[count.index]}"
virtual_network_name = "${azurerm_virtual_network.Vnet.name}"
resource_group_name =
"${azurerm_resource_group.ResourceGroup.name}"
address_prefix =
"${element(var.Subnet_range[var.Subnet_name[count.index]], 0)}"
}
resource "azurerm_network_security_group" "NetworkSG" {
count = "${length(var.Subnet_name)}"
name =
"${element(var.Subnet_range[var.Subnet_name[count.index]], 1)}"
location =
"${azurerm_resource_group.ResourceGroup.location}"
resource_group_name = "${azurerm_resource_group.ResourceGroup.name}"
}
resource "azurerm_subnet_network_security_group_association"
"NetworkSGassociation" {
count= "${length(var.Subnet_name)}"
subnet_id = "${element(azurerm_subnet.Subnet.*.id, count.index)}"
network_security_group_id =
"${element(azurerm_network_security_group.NetworkSG.*.id,count.index)}"
}
Below is my .tfvars file:
Subnet_name= ["SCB-Sub1","SCB-Sub2","SCB-Sub3"]
Subnet_range =
{
SCB-Sub1= ["10.10.0.0/24","SCB-nsg1"]
SCB-Sub2= ["10.10.1.0/24","SCB-nsg2"]
SCB-Sub3= ["10.10.2.0/24","SCB-nsg3"]
}
This is the output I get when I use terraform plan:
azurerm_subnet.Subnet[1]: Modifying... (ID:
/subscriptions/0000-...tualNetworks/SCB_vnet/subnets/SCB-Sub3)
network_security_group_id: "/subscriptions/0000/resourceGroups/SCB-
rg/providers/Microsoft.Network/networkSecurityGroups/SCB-nsg3" => ""

Resources