Sagar Sathyanarayanan
Sagar Sathyanarayanan

Reputation: 127

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?

Upvotes: 0

Views: 1690

Answers (2)

RahulKumarShaw
RahulKumarShaw

Reputation: 4602

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"]
    }
  }
}

enter image description here

Upvotes: 4

Marko E
Marko E

Reputation: 18108

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:

  1. Create an implicit dependency between vnet and subnet
  2. 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

Upvotes: 2

Related Questions