最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

azure - Pass CLI command output into Terraform for_each expression - Stack Overflow

programmeradmin3浏览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 == "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

发布评论

评论列表(0)

  1. 暂无评论