skip to Main Content

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

Answers


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

    Login or Signup to reply.
  2. 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
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search