Menu

Virtual Geek

Tales from real IT system administrators world and non-production environment

Importing existing resources into Terraform - Step by Step

When working on already created existing Azure from portal or other scripting tool then managing it using terraform tool can be little bit tedious. I encountered in a situation while working on one of my client's Azure infrastructure, I needed to modify/update existing resources. Here is the view of resource group on Azure ARM portal and on the existing resource group I will update tags using terraform.

Importing already created module Infrastructure into Terraform and update state file

Microsoft Azure Resource group terraform import example tags testing importing existing resource infrastructure plan apply resource id exists parsing error.png

Here is my simple hashicorp terraform HCL language tf file to update resource group tags. Note: there is no tfstate file exists yet.

Microsoft Azure terraform required_providers azurerm hashicorp A resource with the ID subscriptions already exists to be managed via Terraform this resource needs to be imported into the State.png

# We strongly recommend using the required_providers block to set the
# Azure Provider source and version being used
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">=2.99.0"
    }
  }
}

# Configure the Microsoft Azure Provider
provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "rg" {
  name     = "vCloud-lab.com"
  location = "East US"
  tags = {
    owner       = "vjani"
    orgnization = "vcloud-lab.com"
  }
}

When tested the script with terraform init and terraform plan commands, I got that terraform will create a resource, but in actual it should modify/update the existing resource. Any how plan shows tf script is good no errors and it will create services, if no tfstate file exists.

Hashicorp terraform hcl import microsoft azure importing existing infrastructure resource modules resource group tags location failed parse id failed Error parsing Resource ID contained more segments than required.png

terraform plan

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 will be created
  + resource "azurerm_resource_group" "rg" {
      + id       = (known after apply)
      + location = "eastus"
      + name     = "vCloud-lab.com"
      + tags     = {
          + "orgnization" = "vcloud-lab.com"
          + "owner"       = "vjani"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

Next I applied the terraform configuration. After applying its showing me the actual error that resource already exist and it need to be imported first in the tfstate state file.

hashicorp terraform import plan apply --auto-approve error a resource with the id already exists imported into into the state azurerm_resource_group add create plan.png

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 will be created
  + resource "azurerm_resource_group" "rg" {
      + id       = (known after apply)
      + location = "eastus"
      + name     = "vCloud-lab.com"
      + tags     = {
          + "orgnization" = "vcloud-lab.com"
          + "owner"       = "vjani"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.
azurerm_resource_group.rg: Creating...
╷
│ Error: A resource with the ID "/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vCloud-lab.com" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_resource_group" for more information.
│
│   with azurerm_resource_group.rg,
│   on main.tf line 17, in resource "azurerm_resource_group" "rg":
│   17: resource "azurerm_resource_group" "rg" {
│
╵

To import it run the below terraform import command with terraform resource reference in the tf script and id of the resource as shown below. Information will be fetched from azure and file tfstate will be updated with the necessary information and I got message resource is imported successfully.

terraform import azurerm_resource_group.rg /subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vCloud-lab.com

azurerm_resource_group.rg: Importing from ID "/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vCloud-lab.com"...
azurerm_resource_group.rg: Import prepared!
  Prepared azurerm_resource_group for import
azurerm_resource_group.rg: Refreshing state... [id=/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vCloud-lab.com]

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

Microsoft Azure terraform hcl import resource group id subscription terraform tf file main variable refreshing state azurerm tfstate apply configuration hashicorp hcl.png

Next it's time to apply the tf configuration again, this time it is showing correct information update in-place and tags will be updated with 1 change applied.

microsoft azurerm_resource_group rg subscriptions update in-place tags resource import change destroy unchanged attribute hidden unchanged Error parsing Resource ID contained more segments than required.png

terraform apply --auto-approve

azurerm_resource_group.rg: Refreshing state... [id=/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vCloud-lab.com]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # azurerm_resource_group.rg will be updated in-place
  ~ resource "azurerm_resource_group" "rg" {
        id       = "/subscriptions/9e22xxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/vCloud-lab.com"
        name     = "vCloud-lab.com"
      ~ tags     = {
          + "orgnization" = "vcloud-lab.com"
          + "owner"       = "vjani"
        }
        # (1 unchanged attribute hidden)

        # (1 unchanged block hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
azurerm_resource_group.rg: Modifying... [id=/subscriptions/9e22fba3-00a9-447c-b954-a26fec38e029/resourceGroups/vCloud-lab.com]
azurerm_resource_group.rg: Modifications complete after 4s [id=/subscriptions/9e22fba3-00a9-447c-b954-a26fec38e029/resourceGroups/vCloud-lab.com]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

I verified on the azure portal, tags are added.

Microsoft Azure resource group tags subscription terraform init plan import refresh apply --auto-approve Error parsing Resource ID contained more segments than required A resource with the ID already exists.png

Useful Articles
Create an Azure virtual machine scale set and load balancer using Terraform
Azure Terraform fixed Availibility Zones on Virtual Machine Scale Set
Writing and Using Terraform modules
Terraform Using one module variable in another module
Hashicorp Terraform dynamic block with example
Terraform for_each loop on map example
Terraform for_each loop on resource example
Terraform manage similar resources with for_each loop inside modules

Go Back

Comment

Blog Search

Page Views

12063695

Follow me on Blogarama