Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terraform - conditionally creating a resource within a loop

Is it possible to combine resource creation with a loop (using count) and conditionally skip some resources based on the value of a map?

I know we can do these things separately:

  • use count to create resources in a loop.
  • use the variable/count workaround (in place of an 'if' statement) to conditional create a resource

To illustrate lets say I have a list of maps:

variable "resources" {
  type = "list"
  default = [
    {
      name = "kafka"
      createStorage = true
    },
    {
      name = "elastic"
      createStorage = false
    },
    {
      name = "galera"
      createStorage = true
    }
  ]
}

I can iterate over the over the above list and create three resources using 'count' within the resource:

resource "azurerm_storage_account" "test" {
    name                     = "test${var.environment}${lookup(var.resources[count.index], "name")}sa"
    location                 = "${var.location}"
    resource_group_name      = "test-${var.environment}-vnet-rg"
    account_tier             = "Standard"
    account_replication_type = "GRS"
    enable_blob_encryption   = true

    count  = "${length(var.resources)}"

}

However, I want to also skip creation of a resource where createStorage = false. So in the above example I want to create two storage accounts but the 'elastic' storage account is skipped. Is this possible?

like image 538
Setanta Avatar asked Jan 17 '18 12:01

Setanta


People also ask

How do I add if condition in Terraform?

You simply set the value of the count property of the resource using the If/Else conditional expression to assign the values of either 1 (to deploy the resource) or 0 (to not deploy the resource).

Can we use For_each and count together in Terraform?

When you define a resource block in Terraform, by default, this specifies one resource that will be created. To manage several of the same resources, you can use either count or for_each , which removes the need to write a separate block of code for each one.

How for each loop works in Terraform?

The for_each argument will iterate over a data structure to configure resources or modules with each item in turn. It works best when the duplicate resources need to be configured differently but share the same lifecycle. It is more like any other for_each in any given programming language.

Does Terraform run sequentially?

In the meantime though, a possible workaround is to instruct Terraform Core to perform all operations sequentially. You can use terraform apply -parallelism=1 to tell Terraform to set its own internal semaphore to perform no more than one operation at a time.


1 Answers

In terraform 0.12.x you can filter out the list where createStorage=true and use that for your count expression

variable "resources" {
  type = "list"
  default = [
    {
      name          = "kafka"
      createStorage = true
    },
    {
      name          = "elastic"
      createStorage = false
    },
    {
      name          = "galera"
      createStorage = true
    }
  ]
}

locals {
  resources_to_create = [
    for resource in var.resources :
    resource
    if resource.createStorage
  ]
}

resource "azurerm_storage_account" "test" {
  count = length(local.resources_to_create)

  name                     = "test${var.environment}${lookup(local.resources_to_create[count.index], "name")}sa"
  location                 = var.location
  resource_group_name      = "test-${var.environment}-vnet-rg"
  account_tier             = "Standard"
  account_replication_type = "GRS"
  enable_blob_encryption   = true
}
like image 90
SomeGuyOnAComputer Avatar answered Oct 05 '22 07:10

SomeGuyOnAComputer