admin管理员组

文章数量:1352869

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 == "microsoftwork/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.

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 == "microsoftwork/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.

Share Improve this question edited Apr 1 at 4:07 Vinay B 2,7262 gold badges3 silver badges12 bronze badges Recognized by Microsoft Azure Collective asked Mar 31 at 21:55 Gabriel KellyGabriel Kelly 871 silver badge6 bronze badges 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 – Vinay B Commented Apr 1 at 4:17
  • That worked, thanks! – Gabriel Kelly Commented Apr 1 at 19:37
Add a comment  | 

1 Answer 1

Reset to default 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/terraform/language/meta-arguments/for_each

本文标签: azurePass CLI command output into Terraform foreach expressionStack Overflow