hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
42.09k stars 9.47k forks source link

Dynamic block not reflected in terraform plan when for_each argument is known after apply #34933

Closed QBY-MauriceBaerisch closed 3 months ago

QBY-MauriceBaerisch commented 5 months ago

Terraform Version

Terraform v1.7.4
on windows_386
+ provider registry.terraform.io/hashicorp/azurerm v3.0.2

Terraform Configuration Files

# Configure the Azure provider
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.0.2"
    }
  }

  required_version = ">= 1.1.0"
}

provider "azurerm" {
  features {}

  skip_provider_registration = true
}

Debug Output

https://gist.github.com/QBY-MauriceBaerisch/521ff40682bebb6b43f22244063a2509

Expected Behavior

The creation of the nested dns block should be reflected in the terraform plan.

Actual Behavior

The creation of the nested dns block is not reflected in the terraform plan.

According to the terraform plan, the nested dns block will not be created. However, if I run terraform apply, the nested dns block is indeed processed and the servers are added in Azure.

image

Terraform will perform the following actions:

  # azurerm_firewall_policy.example will be created
  + resource "azurerm_firewall_policy" "example" {
      + child_policies           = (known after apply)
      + firewalls                = (known after apply)
      + id                       = (known after apply)
      + location                 = "westeurope"
      + name                     = "example-policy"
      + resource_group_name      = "rg-DynamicBlocks-dev-01"
      + rule_collection_groups   = (known after apply)
      + sku                      = (known after apply)
      + threat_intelligence_mode = "Alert"
    }

  # azurerm_ip_group.example will be created
  + resource "azurerm_ip_group" "example" {
      + cidrs               = [
          + "10.0.0.0/16",
        ]
      + id                  = (known after apply)
      + location            = "westeurope"
      + name                = "example1-ipgroup"
      + resource_group_name = "rg-DynamicBlocks-dev-01"
      + tags                = {
          + "environment" = "dev"
        }
    }

  # azurerm_resource_group.example will be created
  + resource "azurerm_resource_group" "example" {
      + id       = (known after apply)
      + location = "westeurope"
      + name     = "rg-DynamicBlocks-dev-01"
    }

Steps to Reproduce

Using azurerm and the example

resource "azurerm_resource_group" "example" {
  name     = "rg-DynamicBlocks-dev-01"
  location = "westeurope"
}

resource "azurerm_ip_group" "example" {
  name                = "example1-ipgroup"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  cidrs = ["10.0.0.0/16"]

  tags = {
    environment = "dev"
  }
}

resource "azurerm_firewall_policy" "example" {
  name                = "example-policy"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location

  dynamic "dns" {
    for_each = azurerm_ip_group.example.id == null ? [] : [1]
    content {
      servers = ["8.8.8.8"]
    }
  }
}

where the nested dns block should be dynamically created based on the id of the ip group (which is known after apply), you will see that the dynamic block is not shown in the terraform plan.

  1. terraform init
  2. terraform apply

Additional Context

We try to build nested blocks based on variables known after apply. Unfortunately you cannot use the count field for nested blocks, as described in this issue

An issue for the azurerm provider has already been opened and closed. We believe this is an issue with the terraform core.

References

jbardin commented 5 months ago

Hi @QBY-MauriceBaerisch,

Thanks for filing the issue! If you inspect the full json plan output you should be able to see that the dns value is unknown. There does seem to be a bug in the renderer for the CLI output which is not showing that block at all when it's contents are entirely unknown.

Thanks!

ghost commented 4 months ago

Hey,

this doesn't only seem to be a problem with rendering. We had a dynamic block referencing an resource id via input variable which in turn was referencing the id of a resource. We changed that input to another resource and deleted the previous resource entirely. Terraform tried to delete the resource before changing the id in the dynamic block, what resulted in an error.

jbardin commented 3 months ago

@QBY-ThimoLimpert, that sounds like the expected behavior if the resource was not created with create_before_destroy. The standard order of operations would be to delete the old dependency before any updates were applied.

github-actions[bot] commented 2 months ago

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.