If existing environments are recreated in Terraform, the resources already exist. Therefore, the resources must be transferred to the Statefile for management by Terraform. The output for a Terraform apply is: already exists - to be managed via Terraform this resource needs to be imported into the State. if the import has not yet been carried out. The import can be done using the terraform import command, where only the identifier from the Terraform files and the resource ID in Azure must be specified.

However, if there are many resources, it can be difficult to find the right resources in the output. One way to make it easier to process may be to redirect the output to a log file and then output it using regular expressions.

Export in Log-File

To redirect Terraform output to a file, the following environment variables must be set according to the debugging instructions:

$env:TF_LOG = "INFO"
$env:TF_LOG_PATH = "c:\tmp\tflog.txt"

In addition to the console output, the output is in the log file. It has the following structure:

...
2024-06-26T14:36:17.356+0200 [INFO]  Starting apply for azurerm_virtual_network.spoke1
2024-06-26T14:36:17.358+0200 [INFO]  Starting apply for azurerm_private_dns_zone.pzaks
2024-06-26T14:36:17.358+0200 [INFO]  Starting apply for azurerm_virtual_network.hub
2024-06-26T14:36:17.769+0200 [ERROR] provider.terraform-provider-azurerm_v3.80.0_x5.exe: Response contains error diagnostic: tf_proto_version=5.4 @caller=github.com/hashicorp/terraform-plugin-go@v0.19.0/tfprotov5/internal/diag/diagnostics.go:58 tf_req_id=d0ddc35b-2ce0-3d9b-5e1a-66997487f574 tf_rpc=ApplyResourceChange @module=sdk.proto diagnostic_detail="" diagnostic_severity=ERROR tf_provider_addr=provider diagnostic_summary="A resource with the ID \"/subscriptions/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/resourceGroups/rg-tzuehlke-privateaks/providers/Microsoft.Network/privateDnsZones/privatelink.swedencentral.azmk8s.io\" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for \"azurerm_private_dns_zone\" for more information." tf_resource_type=azurerm_private_dns_zone timestamp="2024-06-26T14:36:17.769+0200"
2024-06-26T14:36:17.774+0200 [ERROR] vertex "azurerm_private_dns_zone.pzaks" error: A resource with the ID "/subscriptions/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/resourceGroups/rg-tzuehlke-privateaks/providers/Microsoft.Network/privateDnsZones/privatelink.swedencentral.azmk8s.io" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_private_dns_zone" for more information.
2024-06-26T14:36:17.789+0200 [ERROR] provider.terraform-provider-azurerm_v3.80.0_x5.exe: Response contains error diagnostic: diagnostic_detail="" diagnostic_summary="A resource with the ID \"/subscriptions/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/resourceGroups/rg-tzuehlke-privateaks/providers/Microsoft.Network/virtualNetworks/vnet-hub-tzuehlke\" 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." tf_proto_version=5.4 diagnostic_severity=ERROR tf_req_id=d4f32ad5-7372-3b24-c741-cb2ec68bf7ee tf_rpc=ApplyResourceChange @caller=github.com/hashicorp/terraform-plugin-go@v0.19.0/tfprotov5/internal/diag/diagnostics.go:58 @module=sdk.proto tf_provider_addr=provider tf_resource_type=azurerm_virtual_network timestamp="2024-06-26T14:36:17.789+0200"
2024-06-26T14:36:17.791+0200 [ERROR] vertex "azurerm_virtual_network.hub" error: A resource with the ID "/subscriptions/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/resourceGroups/rg-tzuehlke-privateaks/providers/Microsoft.Network/virtualNetworks/vnet-hub-tzuehlke" 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.
2024-06-26T14:36:18.049+0200 [ERROR] provider.terraform-provider-azurerm_v3.80.0_x5.exe: Response contains error diagnostic: @module=sdk.proto diagnostic_detail="" diagnostic_summary="A resource with the ID \"/subscriptions/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/resourceGroups/rg-tzuehlke-privateaks/providers/Microsoft.Network/virtualNetworks/vnet-tzuehlke-spoke1\" 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." tf_proto_version=5.4 tf_provider_addr=provider tf_req_id=3191d5fb-d420-0b5f-4fb5-e32d4bf7db1e diagnostic_severity=ERROR tf_resource_type=azurerm_virtual_network @caller=github.com/hashicorp/terraform-plugin-go@v0.19.0/tfprotov5/internal/diag/diagnostics.go:58 tf_rpc=ApplyResourceChange timestamp="2024-06-26T14:36:18.048+0200"
2024-06-26T14:36:18.053+0200 [ERROR] vertex "azurerm_virtual_network.spoke1" error: A resource with the ID "/subscriptions/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa/resourceGroups/rg-tzuehlke-privateaks/providers/Microsoft.Network/virtualNetworks/vnet-tzuehlke-spoke1" 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.

In the example shown, two networks (spoke1 👉 line 10, hub 👉 line 8) are deployed, but both networks already exist and need to be imported.

Extract existing Resources

The file can now be checked with regular expressions and the output can be prepared directly for the import command. The following PowerShell script is used for this:

[CmdletBinding()]
param (
[parameter(Mandatory = $true)]
  [ValidateNotNullOrEmpty()]
  [String]
  $LogFile
)

$fileContent = Get-Content $LogFile
$regexresults = [regex]::Matches($fileContent, '(?<=ERROR..vertex \")[a-zA-Z\d\-\/\|_\.]+|[a-zA-Z\d\-\/\|_\.]+(?=\" already exists)')
for($i=0; $i -le $regexresults.Count-1; $i+=2){
    Write-Output "terraform import $($regexresults[$i].Value) $($regexresults[$i+1].Value)"
}

The script produces the following output: