Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Terraform 0.12, how to skip creation of resource, if resource name already exists?

I am using Terraform version 0.12. I have a requirement to skip resource creation if resource with the same name already exists.

I did the following for this :

Read the list of custom images,

data "ibm_is_images" "custom_images" { } 

Check if image already exists,

locals {  custom_vsi_image = contains([for x in data.ibm_is_images.custom_images.images: "true" if x.visibility == "private" && x.name == var.vnf_vpc_image_name], "true") }  output "abc" { value="${local.custom_vsi_image}" } 

Create only if image exists is false.

resource "ibm_is_image" "custom_image" {   count            = "${local.custom_vsi_image == true ? 0 : 1}"   depends_on       = ["data.ibm_is_images.custom_images"]   href             = "${local.image_url}"   name             = "${var.vnf_vpc_image_name}"   operating_system = "centos-7-amd64"    timeouts {     create = "30m"     delete = "10m"   } } 

This works fine for the first time with "terraform apply". It finds that the image did not exists, so it creates image.

When I run "terraform apply" for the second time. It is deleting the resource "custom_image" that is created above. Any idea why it is deleting the resource, when it is run for the 2nd time ?

Also, how to create a resource based on some condition(like only when it does not exists) ?

like image 318
Malar Kandasamy Avatar asked Dec 26 '19 17:12

Malar Kandasamy


People also ask

Is it possible to count the number of resources in TerraForm?

It won't actually work in Terraform. To do this in Terraform, you can use the count parameter and a conditional expression on each of the resources: This code contains two aws_iam_user_policy_attachment resources.

What can you define in the terraform resource lifecycle block?

This is yet another thing that you can define in the Terraform resource lifecycle block. By adding the ignore_changes parameter to the lifecycle block, we can tell our Terraform resource definition to ignore any changes to the image field. This makes sure that Terraform does not attempt to reprovision the resource whenever the image changes.

What are terraform resource configurations?

Terraform resource configurations consist of both arguments that set individual properties of the main object being described, and nested blocks which declare zero or more other objects that are modeled as being part of their parent. For example:

Will terraform recreate my resource if I update its file?

The full truth is that yes, Terraform will recreate your resource if you update its.tf file, but that is not the only thing that will cause Terraform to recreate the resource. It will also recreate the resource if anything that your.tf file points to also changes. In my case, I had the following DigitalOcean Resource defitition


1 Answers

In Terraform, you're required to decide explicitly what system is responsible for the management of a particular object, and conversely which systems are just consuming an existing object. There is no way to make that decision dynamically, because that would make the result non-deterministic and -- for objects managed by Terraform -- make it unclear which configuration's terraform destroy would destroy the object.

Indeed, that non-determinism is why you're seeing Terraform in your situation flop between trying to create and then trying to delete the resource: you've told Terraform to only manage that object if it doesn't already exist, and so the first time you run Terraform after it exists Terraform will see that the object is no longer managed and so it will plan to destroy it.


If you goal is to manage everything with Terraform, an important design task is to decide how object dependencies flow within and between Terraform configurations. In your case, it seems like there is a producer/consumer relationship between a system that manages images (which may or may not be a Terraform configuration) and one or more Terraform configurations that consume existing images.

If the images are managed by Terraform then that suggests either that your main Terraform configuration should assume the image does not exist and unconditionally create it -- if your decision is that the image is owned by the same system as what consumes it -- or it should assume that the image does already exist and retrieve the information about it using a data block.

A possible solution here is to write a separate Terraform configuration that manages the image and then only apply that configuration in situations where that object isn't expected to already exist. Then your configuration that consumes the existing image can just assume it exists without caring about whether it was created by the other Terraform configuration or not.

There's a longer overview of this situation in the Terraform documentation section Module Composition, and in particular the sub-section Conditional Creation of Objects. That guide is focused on interactions between modules in a single configuration, but the same underlying principles apply to dependencies between configurations (via data sources) too.

like image 92
Martin Atkins Avatar answered Sep 19 '22 17:09

Martin Atkins