0

I am working on setting up hybrid DNS in my Azure tenant using Terraform and I am running into a problem. I have one DNS forwarding rule set to pass requests to our on-prem DNS server, and I need to link this to some of our virtual networks. This is the portion of my code where I'm doing this:

resource "azurerm_private_dns_resolver_virtual_network_link" "vnet_links" {
  for_each = toset(var.forwarding_linked_vnets)

  dns_forwarding_ruleset_id = azurerm_private_dns_resolver_dns_forwarding_ruleset.forwarding_ruleset.id
  name                      = "${each.value["name"]}-link"
  virtual_network_id        = each.value["id"]
}

The forwarding_linked_vnets variable is declared like this:

variable "forwarding_linked_vnets" {
  type = list(map(string))
}

I want to use the Azure CLI to pull a list of VNET IDs. I wrote up this CLI command to get me all the VNET IDs and names:

az graph query \
    --graph-query 'Resources | where type == "microsoft.network/virtualnetworks" | where location == "westus"' \
    --query "data[*].{name:name, id:id}" \
    -o json 

This specific command is required because I need to filter out VNETs not in our primary region. My question is, how can I get the output of that command into a variable in Terraform? I know I could just pass it through the -var argument when terraform apply is run. However, then I would have to mess around with the CD pipeline which I would really prefer to avoid because it's templated.

2
  • 3
    You can leverage Terraform's external data source to run the Azure CLI command and dynamically retrieve the filtered VNETs into a Terraform variable without modifying the CD pipeline @GabrielKelly Commented Apr 1 at 4:17
  • That worked, thanks! Commented Apr 1 at 19:37

1 Answer 1

0

Pass CLI command output into Terraform for_each expression

Glad to know the workaround shared helps you to achieve in the requirement & Posting the same as the solution so that it would be helpful for the community.

As specified, To achieve the condition to fetch the VNETs directly into your Terraform workflow. Since we can't run perform this in Terraform directly, and you also don’t want to inject -var at runtime, the best approach is to externalize the data into a file, and then use the Terraform external data source to read it.

Create fetch_vnets.py files that execute the CLI command and fetch the VNETs information for you.

Now add terraform external data source

data "external" "vnets" {
  program = ["python3", "${path.module}/fetch_vnets.py"]
}

Parse and Use the Output in Terraform

locals {
  forwarding_linked_vnets = data.external.vnets.result.vnets
}

resource "azurerm_private_dns_resolver_virtual_network_link" "vnet_links" {
  for_each = { for vnet in local.forwarding_linked_vnets : vnet.name => vnet }

  name                      = "${each.key}-link"
  virtual_network_id        = each.value.id
  dns_forwarding_ruleset_id = azurerm_private_dns_resolver_dns_forwarding_ruleset.forwarding_ruleset.id
}

By using this approach, you can now delete or ignore the variable "forwarding_linked_vnets" block in variables as it no longer required.

Refer:

external_external | Data Sources | hashicorp/external | Terraform | Terraform Registry

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.