17

When Terraform run task executes in azure devops release pipeline I get an error "A resource with the ID already exists". The resource exists in Azure but why it is complaining about the resource if this already exists. This should ignore this part. Please help what I need to add in my code that will fix this error! Am I just using this bugging terraform tool for deploying azure resource? Terraform help is terrible!!!

resource "azurerm_resource_group" "test_project" {
  name = "${var.project_name}-${var.environment}-rg"
  location = "${var.location}"
  tags = {  
    application = "${var.project_name}" 
  }
}
Techprofile
  • 187
  • 1
  • 1
  • 3
  • Related: [Using Terraform to import existing resources on Azure](https://stackoverflow.com/q/47439848/55075) – kenorb May 30 '20 at 17:24

4 Answers4

22

Terraform is designed to allow you to manage only a subset of your infrastructure with a particular Terraform configuration, in case either some objects are managed by another tool or in case you've decomposed your infrastructure to be managed by many separate configurations that cooperate to produce the desired result.

As part of that design, Terraform makes a distinction between an object existing in the remote system and that object being managed by the current Terraform configuration. Where technical constraints of an underlying API allow it, Terraform providers will avoid implicitly taking ownership of something that was not created by that specific Terraform configuration. The error message you saw here is the Azure provider's implementation of that, where it pre-checks to make sure the name you give it is unique so that it won't overwrite (and thus take implicit ownership of) an object created elsewhere.

To proceed here you have two main options, depending on your intended goal:

  • If this object was formerly managed by some other system and you now want to manage it exclusively with this Terraform configuration, you can tell Terraform to associate the existing object with the resource block you've written and thus behave as if that object were originally created by that resource block:

    terraform import azurerm_resource_group.test_project /subscriptions/YOUR-SUBSCRIPTION-ID/resourceGroups/PROJECTNAME-ENVIRONMENTNAME-rg
    

    After you run terraform import you must ensure that whatever was previously managing that object will no longer associate with it. This object is now owned by this Terraform configuration and must not be changed by any other system.

  • If this object is managed by some other system and you wish to continue managing it that way then you can instead use a data block to retrieve information about that existing object to use elsewhere in your configuration without Terraform taking ownership:

    data "azurerm_resource_group" "example" {
      name = "${var.project_name}-${var.environment}-rg"
    }
    

    If you needed the resource group's location name elsewhere in your module, for example, you could use data.azurerm_resource_group.example.location to access it. If you wanted to make any later changes to this resource group, you would continue to do that using whichever other system is considered the owner of it in your environment.

The main difference between these two approaches is how Terraform will record the object in state snapshots. terraform import causes Terraform to create a binding between the resource configuration you wrote and the remote object whose id you gave on the command line, which is henceforth indistinguishable to Terraform from it having created that object and recorded the binding itself in the first place. For a data resource, Terraform just reads the data about the existing object and saves a cache of it in the state so it can determine if the value has changed on a future run; it will never plan to make any modifications to an object used with a data block.

Martin Atkins
  • 62,420
  • 8
  • 120
  • 138
2

Try to delete the .terraform local folder to clean the cache, then run terraform init again and retry running the pipeline.

KingJac
  • 94
  • 9
1

For my future self: Today I stumbled across this same problem, because I renamed some resources, and terraform could not track them. I found out about terraform state mv ... which gives you the ability to rename resources in your state file, so that it can track remote resources. Really useful.

Geiser
  • 1,054
  • 1
  • 12
  • 28
-2

Run command:

terraform init -upgrade 
  • 2
    Remember that Stack Overflow isn't just intended to solve the immediate problem, but also to help future readers find solutions to similar problems, which requires understanding the underlying code. This is especially important for members of our community who are beginners, and not familiar with the syntax. Given that, **can you [edit] your answer to include an explanation of what you're doing** and why you believe it is the best approach? – Tyler2P Aug 12 '23 at 10:53