Open triceam opened 2 years ago
Hi @triceam, I'm not from the Terraform Provider team but I may be able to offer a workaround for that: As far as I know Terraform is not capable of deciding this dynamically during the runtime. You have to decide prior to execution if a resource shall be created or not.
The good news is: There is a pattern for that when you provide a boolean such as you described. We solve this issue in the following way:
1) Provide an input variable, e.g. use_existing_rg
(bool).
2) Create a module for the resource which looks like this:
# Config
terraform {
required_providers {
ibm = {
source = "IBM-Cloud/ibm"
version = ">= 1.18.0"
}
}
required_version = ">= 0.13"
}
# Variables
variable region {
type = string
}
variable name {
type = string
}
variable lookup {
type = bool
default = false
}
variable tags {
type = list(string)
default = []
}
# Resources
data "ibm_resource_group" "lookup" {
count = var.lookup ? 1 : 0
name = var.name
}
resource "ibm_resource_group" "create" {
count = !var.lookup ? 1 : 0
name = var.name
tags = var.tags
}
# Outputs
locals {
result = one(concat(ibm_resource_group.create, data.ibm_resource_group.lookup))
}
output "group" {
value = local.result
}
output "group_id" {
value = local.result.id
}
I like to use a module variable called lookup
. If this is set to true
the module code will use a data source
to look up an existing resource group while setting this to false
will use the resource
to create your resource group. If you set the results in a clever way the rest of the code will not recognize the difference if the resource group was created of looked up. You can simply use module.rg_module.group.id
or module.rg_module.group_id
if your module is called rg_module
.
You would use this module like this:
module "resource_group" {
source = "../modules/resource_group"
region = var.region
name = var.rg_name
lookup = var.use_existing_rg
tags = var.rg_tags
}
This approach works for most of the resources (as long as there is a data source).
I just have a general hint: It is also common to use a unique_id
or a prefix
for resource names. We use this to make it possible to run the same Terraform script on the same account multiple times, each time providing a different prefix
. This way you can prevent name collisions.
module "resource_group" {
source = "../modules/resource_group"
region = var.region
name = format("%s%s", var.prefix, var.rg_name) # Use this variant if the prefix is optional so that it can be left blank). A non-empty prefix must be provided ending with a separator character: mypref-
#name = format("%s-%s", var.prefix, var.rg_name) # Use this variant if the prefix is not optional. The prefix is provided without the separator charater: mypref
lookup = var.use_existing_rg
tags = var.rg_tags
}
Hope this helps.
Kind regards, Enrico | IBM Cloud Solution Engineering team (ICSE)
Community Note
Description
Many resources from the IBM Cloud Terraform provider will fail if a resource already exists that has the same name. Our team has created some fairly complex terraform templates that will create a resource group, activity tracker, service authorizations, plus VPCs & clusters etc... We will often target the same resource group and activity tracker instances, but this means that our automation will only work on clean accounts. You can't re-run the same automation on the same account (With different vars to create separate instances in the same resource group) b/c it will fail. We encounter failures VERY often b/c a resource group, service authorization, access group, or instance of activity tracker already exists.
Can we have a
use_existing_instance
boolean variable (or similar), that if set totrue
will just return data for the existing instance instead of causing terraform execution to fail.We (the ecosystem team) run into this all the time, to the point that we have written a terraform module that calls the IBM Cloud APIs directly inside of a local exec provisioner, so that it handles the case where a RG, access group, service authorization, or activity tracker instance already exists. We don't use the native terraform resource for any of these anymore.
New or Affected Resource(s)