Terraform: Ignore resource if variable set.

Created on 23 Jul 2015  ยท  12Comments  ยท  Source: hashicorp/terraform

We have a couple of extra terraform resources that need creating under certain conditions. For example we use environmental overrides to create a "dev" and a "qa" environment from the same base terraform resources. However the qa environment needs extra security_group_rules set.

Unless this can already be achieved, (if so how?) it would be useful to be able to set an override variable for the qa case which deactivates (or activates) a resource.

I would consider an implementation to be a top-level field available on every resource such as:

ignore => "${var.some_variable}"

Then we can set a default for "some_variable" of 1, and set to 0 as an override for the qa tf.variables file.

Otherwise I can see no way of having optional resources flagged for inclusion under certain circumstances.

Most helpful comment

The current "pattern" for depending on a conditional resource is like this:

resource "example" "conditional" {
  count = "${var.enabled ? 1 : 0}"
}

resource "example" "dependent" {
  argument = "${join("", example.conditional.*.attribute)}"
}

Other variants are possible to set defaults, etc, but "joining" the zero-or-one-element list is how to avoid the issue of referring to the zeroth element when there is no such element.

We'll work on making this smoother in future via more language improvements.

All 12 comments

One way to do this today is to use the count attribute on a resource:

variable "number" {
    default = 1
}

resource "any_resource" "foo" {
    count = "${var.number}"
}

You can set count to 0 to prevent any resources being created at all, so by interpolating it with a variable and conditionally setting it to either 1 or 0 you can control whether or not this single resource gets created.

$ terraform plan -var="number=0"
Refreshing Terraform state prior to plan...


No changes. Infrastructure is up-to-date. This means that Terraform
could not detect any differences between your configuration and
the real physical resources that exist. As a result, Terraform
doesn't need to do anything.

$ terraform plan -var="number=1"
Refreshing Terraform state prior to plan...


The Terraform execution plan has been generated and is shown below.
Resources are shown in alphabetical order for quick scanning. Green resources
will be created (or destroyed and then created if an existing resource
exists), yellow resources are being changed in-place, and red resources
will be destroyed.

Note: You didn't specify an "-out" parameter to save this plan, so when
"apply" is called, Terraform can't guarantee this is what will execute.

+ any_resource.foo


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

Thanks - it feels a bit odd/quirky, but I'll def give it ago :)

There's also a lot of chatter about conditional logic and ignoring resources over in #1604

@apparentlymart's strategy of count = 0 is the correct way to do this today, and @thegedge is correct that #1604 is the home for future improvements

We are using a Jenkins plugin to deploy a service onto AWS instances and created/update 'VERSION' tag for the instance(s). Unfortunately, Terraform deletes this tag unless there's a way to ignore it. Is there a way to ignore just a single tag, e.g. 'VERSION' as opposed to ignoring all tags? I'd really appreciate a response.

Thanks

Won't this method delete those resources rather than ignore them when count = 0?

Unfortunately, from what I've experienced, the count = 0 method proves useless when having a resource that depends on another (e.g. a aws_security_group_rule that obviously depends on a aws_security_group). Putting count = 0 on both the SG and the rule would theoretically not create any of them, except that when running (plan, apply, etc.) on that an error like

Error running plan: 1 error(s) occurred:

* Resource 'aws_security_group.it-sg' does not have attribute 'id' for variable 'aws_security_group.it-sg.id'

is returned.

Although I think there's no way out of this (and hence the count = 0 "solution" works only for "leaf" resources), I'm eager to learn of any potential workarounds for the problem I exposed.
@gtmtech @apparentlymart @thegedge @phinze

I'm having the same problem as @BogdanSorlea, I'm managing a couple of separate environments and some resources aren't required for part of them. So with my current configuration I'm getting an error for the resource that doesn't exist whenever I want to plan/apply anything on one of the aforementioned environments.

@BogdanSorlea Did you ever find a solution to the problem you mentioned in this issue?

The current "pattern" for depending on a conditional resource is like this:

resource "example" "conditional" {
  count = "${var.enabled ? 1 : 0}"
}

resource "example" "dependent" {
  argument = "${join("", example.conditional.*.attribute)}"
}

Other variants are possible to set defaults, etc, but "joining" the zero-or-one-element list is how to avoid the issue of referring to the zeroth element when there is no such element.

We'll work on making this smoother in future via more language improvements.

@apparentlymart can you have a look at this problem https://stackoverflow.com/questions/48306089/how-do-i-make-a-field-optional-inside-a-terraform-resource , would be a great help.

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

franklinwise picture franklinwise  ยท  3Comments

zeninfinity picture zeninfinity  ยท  3Comments

ketzacoatl picture ketzacoatl  ยท  3Comments

rjinski picture rjinski  ยท  3Comments

darron picture darron  ยท  3Comments