Terraform azure import multiple subnets

92 views Asked by At

I have my azure cloud setup manually. It almost has 5 subnets. Now in order to make it IAAS, I am writing a Terraform code for it. I know, I can import resource by using the command "terraform import azurerm_subnet.mysybnet ". This only imports one subnet. How can I import multiple subnets? For example, if I have subnets with names "vm-subnet", "aks-subnet", "acr-subnet", "nsg-subnet" and "firewall-subnet". How can I import all these subnets in one shot?

My current code is

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "=3.0.0"
    }
  } 
}
    
provider "azurerm" {
  features {}
}
    
resource "azurerm_resource_group" "myrg" {
  name     = "myRG"
  location = "WEST US 2"
}
    
resource "azurerm_virtual_network" "myvnet" {
  name                = "myvnet"
  resource_group_name = azurerm_resource_group.myrg.name
  location            = azurerm_resource_group.myrg.location
  address_space       = ["10.0.0.0/16"]
}
    
#Create subnets within the resource group
resource "azurerm_subnet" "mysubnet" {
  name                 = "acr-subnet"
  address_prefixes     = ["10.0.0.0/24"]
  resource_group_name  = azurerm_resource_group.myrg.name
  virtual_network_name = azurerm_virtual_network.myvnet.name
}
2

There are 2 answers

1
Marko E On BEST ANSWER

Depending on the version of terraform you are using, you can now use import blocks with for_each, which works on the terraform versions >1.7.x. For example:

locals {
  subnets = {
    "acr-subnet"      = ["10.0.0.0/24"]
    "vm-subnet"       = ["10.0.1.0/24"]
    "aks-subnet"      = ["10.0.2.0/24"]
    "nsg-subnet"      = ["10.0.3.0/24"]
    "firewall-subnet" = ["10.0.4.0/24"]
  }
}

import {
  for_each = local.subnets
  to       = azurerm_subnet.mysubnet[each.key]
  # populate the subscription ID with your value
  id       = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myRG/providers/Microsoft.Network/virtualNetworks/myvnet/subnets/${each.key}"
}

resource "azurerm_subnet" "mysubnet" {
  for_each             = local.subnets
  name                 = each.key
  address_prefixes     = each.value
  resource_group_name  = azurerm_resource_group.myrg.name
  virtual_network_name = azurerm_virtual_network.myvnet.name
}
0
Vinay B On

I tried to azure import multiple subnets into the state using terraform and shell scripts and I was able to provision the requirement successfully.

A common requirement is to import multiple resources into a Terraform state at once. You have to import each resource individually.

The problem with your scenario is that terraform import only works for single resources. If you want to import multiple resources of the same kind (such as subnets), you have to run the import command multiple times, giving a different identifier for each resource in your Terraform configuration.

My preexisiting resources in portal

enter image description here

  1. Define the Terraform Configuration for Each Subnet: Before importing, you must have a Terraform resource block for each subnet you wish to import.

  2. Use a Script to Automate the Import Process: Write a shell script (or a script in another language) that runs terraform import for each subnet.

My Terraform configuration:

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "example" {
  name     = "testrg-vk"
  location = "East US" # Change this to your actual location if different
}

resource "azurerm_virtual_network" "example" {
  name                = "testvkvnet"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
}

variable "subnets" {
  description = "A map of subnets"
  type = map(object({
    address_prefixes = list(string)
  }))
  default = {
    "vm-subnet" = {
      address_prefixes = ["10.0.0.0/24"]
    },
    "aks-subnet" = {
      address_prefixes = ["10.0.1.0/24"]
    },
    "acr-subnet" = {
      address_prefixes = ["10.0.2.0/24"]
    },
    "nsg-subnet" = {
      address_prefixes = ["10.0.3.0/24"]
    },
    "firewall-subnet" = {
      address_prefixes = ["10.0.4.0/24"]
    },
  }
}

resource "azurerm_subnet" "example" {
  for_each             = var.subnets
  name                 = each.key
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = each.value.address_prefixes
}

Shell script:

# Define the subscription ID, resource group, and virtual network name
$SubscriptionId = "Subscription ID"
$ResourceGroup = "testrg-vk"
$VNetName = "testvkvnet"

# Subnet names and their corresponding CIDR notation
$subnets = @{
    "vm-subnet" = "10.0.0.0/24"
    "aks-subnet" = "10.0.1.0/24"
    "acr-subnet" = "10.0.2.0/24"
    "nsg-subnet" = "10.0.3.0/24"
    "firewall-subnet" = "10.0.4.0/24"
}

# Loop through each subnet and import it
foreach ($subnet in $subnets.GetEnumerator()) {
    $subnetName = $subnet.Key
    $terraformResource = "azurerm_subnet.example[`"$subnetName`"]"
    $azureResourcePath = "/subscriptions/$SubscriptionId/resourceGroups/$ResourceGroup/providers/Microsoft.Network/virtualNetworks/$VNetName/subnets/$subnetName"
    terraform import $terraformResource $azureResourcePath
}

Before executing the command, make sure both files are in the same directory and follow the steps below.

Step 1:

Run the command terraform init

enter image description here

Step 2:

Now execute the commands

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

&

.\Import-Subnets.ps1

This commands will starts executing the commands inside the shell scripts.

Output:

enter image description here

This step is executed repeatedly until the given list is fully processed.

Step3:

Now run the command terraform state list

enter image description here