opticyclic
opticyclic

Reputation: 8156

How do I skip the creation of a Terraform resource?

My Terraform script is set up for a web app in production. As part of that, I have Azure DDoS protection enabled.

However, this is really expensive compared to the rest of the infrastructure. For this reason, I don't want to create it for my development environment.

I run Terraform using Azure pipelines, so I would like to configure the pipeline to optionally not create it, e.g. with a variable in the pipeline.

Is there an option I can pass to Terraform to skip this resource?

Assuming there is such an option and I can skip the DDoS resource, will the creation of the vnet fail in the snippet below if it doesn't exist?

#---------------------------------------
#    DDOS Protection Plan Definition
#---------------------------------------

resource "azurerm_network_ddos_protection_plan" "ddos" {
  name                = var.ddos_plan_name
  location            = var.location
  resource_group_name = azurerm_resource_group.rg.name
}

#---------------------------------------
#            vNet Definition
#---------------------------------------

resource "azurerm_virtual_network" "vnet" {

  name                = lower("${local.vNet_id}-${var.location_id}-${var.env_id}-1")
  resource_group_name = azurerm_resource_group.rg.name
  location            = var.location
  address_space       = var.address_space

  ddos_protection_plan {
    id     = azurerm_network_ddos_protection_plan.ddos.id
    enable = true
  }

  depends_on = [
    azurerm_resource_group.rg
  ]
}

Upvotes: 2

Views: 7869

Answers (3)

rubymonk
rubymonk

Reputation: 143

What you want is a negative -target. And no, it unfortunately doesn't exist.

Only alternative is to -target all resources except the one you one.

It's a sorely missed feature but seems higher minds decided for us we don't want it.

Upvotes: 1

Martin Atkins
Martin Atkins

Reputation: 74729

You can use the count meta-argument to dynamically choose how many instances of a particular resource to create, including possibly choosing to create zero of them, which therefore effectively disables the resource altogether:

variable "enable_ddos_protection" {
  type = bool

  default = true
}

resource "azurerm_network_ddos_protection_plan" "ddos" {
  count = var.enable_ddos_protection ? 1 : 0

  name                = var.ddos_plan_name
  location            = var.location
  resource_group_name = azurerm_resource_group.rg.name
}

Since the number of instances of this resource is now dynamic, azurerm_network_ddos_protection_plan.ddos will appear as a list of objects instead of a single object. Therefore you'll also need to change how you refer to it in the virtual network configuration.

The most direct way to declare that would be to use a dynamic block to tell Terraform to generate one ddos_protection_plan block per instance of that resource, so there will be no blocks of that type if there are no protection plan instances:

resource "azurerm_virtual_network" "vnet" {
  name = lower("${local.vNet_id}-${var.location_id}-${var.env_id}-1")

  resource_group_name = azurerm_resource_group.rg.name
  location            = var.location
  address_space       = var.address_space

  dynamic "ddos_protection_plan" {
    for_each = azurerm_network_ddos_protection_plan.ddos
    content {
      id     = ddos_protection_plan.value.id
      enable = true
    }
  }
}

(I removed the depends_on declaration here because it was redundant with the reference in the resource_group_name argument, but the dynamic block is the main point of this example.)

Upvotes: 3

Marko E
Marko E

Reputation: 18223

The way I would do it is to use the count meta-argument [1]. For example, create a variable with a name create_ddos_protection_plan, set it to be of type bool and by default set it to false:

variable "create_ddos_protection_plan" {
  description = "Whether to create DDoS resource or not."
  type = bool
  
  default = false
}

resource "azurerm_network_ddos_protection_plan" "ddos" {
  count               = var.create_ddos_protection_plan ? 1 : 0
  name                = var.ddos_plan_name
  location            = var.location
  resource_group_name = azurerm_resource_group.rg.name
}

Later on if you decide you want to create it, you can set the value of the variable to true or remove the count meta-argument completely.

The vnet creation would fail if the resource does not exist based on the current setup.


[1] https://www.terraform.io/language/meta-arguments/count

Upvotes: 2

Related Questions