Search code examples
azureterraformterraform-provider-azure

Deploy and Destroy resources using terraform apply - based on the condition


We are working on the concept of destroying and deploying resources based on the conditions . We can also avoid destroying few critical resources using terraform apply based on count. But i am failing in the usage of this . If possible can you help me out here .

Sample terraform code is provided below

variable "delete_resources" {
  description = "Set this to true to delete resources or false to keep them"
  type        = bool
  default     = true
}
        
locals {
  resource_count = var.delete_resources ? 0 : 1
}

resource "azurerm_resource_group" "example-express-rg" {
  count    = local.resource_count
  name     = "example-vnet-rg"
  location = "West Europe"
}

resource "azurerm_virtual_network" "vnettest" {
  count               = local.resource_count
  name                = "example-vnet"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example-express-rg[count.index].location
  resource_group_name = azurerm_resource_group.example-express-rg[count.index].name
}
        
resource "azurerm_subnet" "gateway_subnet" {
  count               = local.resource_count
  name                = "GatewaySubnet"
  resource_group_name = azurerm_resource_group.example-express-rg[count.index].name
  virtual_network_name = azurerm_virtual_network.vnettest[count.index].name
  address_prefixes    = ["10.0.1.0/24"]
}
        
resource "azurerm_public_ip" "publicip" {
  count               = local.resource_count
  name                = "example-public-ip"
  location            = azurerm_resource_group.example-express-rg[count.index].location
  resource_group_name = azurerm_resource_group.example-express-rg[count.index].name
  allocation_method   = "Static"
  sku                 = "Standard"
}
        
resource "azurerm_resource_group" "expressrg" {
  count    = local.resource_count
  name     = "exprtTest"
  location = "West Europe"
}
    
resource "azurerm_express_route_circuit" "expressr" {
  name                  = "expressRoute1"
  resource_group_name   = azurerm_resource_group.expressrg[count.index].name
  location              = azurerm_resource_group.expressrg[count.index].location
  service_provider_name = "Equinix"
  peering_location      = "Singapore"
  bandwidth_in_mbps     = 1000
    
  sku {
    tier   = "Standard"
    family = "MeteredData"
  }
    
  tags = {
    Purpose = "Core Infra Network"
    ResorceOwner = "Cloud Connectivity Team"
  }
    
  lifecycle {
    prevent_destroy = true
  }
}
    
resource "azurerm_virtual_network_gateway" "example" {
  count               = local.resource_count
  name                = "testgw"
  location            = azurerm_resource_group.example-express-rg[count.index].location
  resource_group_name = azurerm_resource_group.example-express-rg[count.index].name
  type                = "ExpressRoute"
  vpn_type            = "PolicyBased"
  sku                 = "Standard"
    
  ip_configuration {
    name                          = "vnetGatewayConfig"
    public_ip_address_id          = azurerm_public_ip.publicip[count.index].id
    private_ip_address_allocation = "Dynamic"
    subnet_id                     = azurerm_subnet.gateway_subnet[count.index].id
  }
    
  tags = {
    Purpose = "CNetwork"
    ResorceOwner = "CTeam"
  }
}

Solution

  • Deploy and Destroy resources using terraform apply - based on the condition

    The requirement of destroy the set of resources from the available resources while using count condition is not possible when you provide the same default input i.e., destroy true for all the resources.

    When you're using count condition and provisioned a list of resources and while destroying you specifically need to save few, we need provide the different input to each resource based on the requirement.

    Update the configuration such that you provided the different input to each resource so that we can protect the resource from deletion. This updated configuration is need when the requirement was like above mentioned.

    Configruation:

    variable "delete_resources" {
    description = "Set this to true to delete resources or false to keep them"
    type        = bool
    default     = true
    }
    
    locals {
    resource_count       = var.delete_resources ? 0 : 1
    protected_count      = 1 
    }
    
    
    resource "azurerm_resource_group" "expressrgvk" {
    count    = local.resource_count
    name     = "vinay-vnet-rg"
    location = "West Europe"
    }
    
    
    resource "azurerm_resource_group" "expressrg" {
    count    = local.protected_count
    name     = "exprtTest"
    location = "West Europe"
    
    }
    
    
    resource "azurerm_express_route_circuit" "expressr" {
    count                = local.protected_count
    name                 = "expressRoute1"
    resource_group_name  = azurerm_resource_group.expressrg[0].name
    location             = azurerm_resource_group.expressrg[0].location
    service_provider_name = "Equinix"
    peering_location      = "Singapore"
    bandwidth_in_mbps     = 1000
    
    sku {
      tier   = "Standard"
      family = "MeteredData"
    }
    
    
    }
    
    resource "azurerm_virtual_network" "vnettest" {
    count               = local.resource_count
    name                = "vinay-vnet"
    address_space       = ["10.0.0.0/16"]
    location            = azurerm_resource_group.expressrgvk[count.index].location
    resource_group_name = azurerm_resource_group.expressrgvk[count.index].name
    }
    
    resource "azurerm_subnet" "gateway_subnet" {
    count                = local.resource_count
    name                 = "GatewaySubnet"
    resource_group_name  = azurerm_resource_group.expressrgvk[count.index].name
    virtual_network_name = azurerm_virtual_network.vnettest[count.index].name
    address_prefixes     = ["10.0.1.0/24"]
    }
    
    resource "azurerm_public_ip" "publicip" {
    count               = local.resource_count
    name                = "vinay-public-ip"
    location            = azurerm_resource_group.expressrgvk[count.index].location
    resource_group_name = azurerm_resource_group.expressrgvk[count.index].name
    allocation_method   = "Static"
    sku                 = "Standard"
    }
    
    resource "azurerm_virtual_network_gateway" "example" {
    count               = local.resource_count
    name                = "testgw"
    location            = azurerm_resource_group.expressrgvk[count.index].location
    resource_group_name = azurerm_resource_group.expressrgvk[count.index].name
    type                = "ExpressRoute"
    vpn_type            = "PolicyBased"
    sku                 = "Standard"
    
    ip_configuration {
      name                          = "vnetGatewayConfig"
      public_ip_address_id          = azurerm_public_ip.publicip[count.index].id
      private_ip_address_allocation = "Dynamic"
      subnet_id                     = azurerm_subnet.gateway_subnet[count.index].id
    }
    }
    
    

    Here you can see that different count inputs results in different outcomes like resource count resources as getting deleted and protected count resources as protected.

    Deployment:

    Out of 7 resources we are able to protect the critical resources and rest resources got deleted

    I consider these two resources as critical in my case.

    Refer:

    https://developer.hashicorp.com/terraform/language/meta-arguments/count

    https://registry.terraform.io/providers/hashicorp/azurerm/2.93.1/docs/resources/virtual_network_gateway