循环遍历 Terraform 数据源结果以获取 ip_rule 块(azurerm_container_registry)

huangapple go评论68阅读模式
英文:

Loop through a Terraform data source results for ip_rule block (azurerm_container_registry)

问题

以下是您要翻译的内容:

我想循环遍历(循环的)数据源的结果,该数据源获取我的虚拟机IP并将它们添加到Azure容器注册表上的IP规则中。这里的两种方法都不起作用,但我觉得应该有一种接近的方法,但找不到解决方法。数据源工作正常。我只是在使用for_each循环遍历并将IP添加到ACR防火墙时遇到问题。

variable "vmips" {
  type = map(any)
  default = {
    "vm1" = "rg1",
    "vm2" = "rg2"
  } 
}

data "azurerm_public_ip" "vmips" {
  for_each            = var.vmips
  name                = each.key
  resource_group_name = each.value
}

resource "azurerm_container_registry" "acr" {
  name                          = "MyAcR"
  resource_group_name           = "myrg"
  location                      = "uksouth"
  sku                           = "Premium"
  admin_enabled                 = false
  public_network_access_enabled = false

  network_rule_set {
    default_action = "Deny"
    
    ip_rule {
      for_each  = var.vmips
      action    = "Allow"
      ip_range  = data.azurerm_public_ip.vmips[each.key].ip_address
    }
    # or
    dynamic "ip_rule" {
      for_each  = var.vmips
      content {
        action    = "Allow"
        ip_range  = data.azurerm_public_ip.vmips[each.key].ip_address
      }
    }
  }
}
英文:

I want to loop through the results of a (looped) data source that gets my VM IPs and add them to an IP rule on an Azure Container Registry. Neither approach here works but I feel like something close should but can't find a way. The data source is working fine. Its just using for_each to loop through and add the IPs to the ACR firewall that I'm having trouble with.

variable "vmips" {
  type = map(any)
  default = {
    "vm1" = "rg1",
    "vm2" = "rg2
  } 
}

data "azurerm_public_ip" "vmips" {
  for_each            = var.vmips
  name                = each.key
  resource_group_name = each.value
}

resource "azurerm_container_registry" "acr" {
  name                          = "MyAcR"
  resource_group_name           = "myrg"
  location                      = "uksouth"
  sku                           = "Premium"
  admin_enabled                 = false
  public_network_access_enabled = false

  network_rule_set {
    default_action = "Deny"
    
    ip_rule {
      for_each  = var.vmips
      action    = "Allow"
      ip_range  = data.azurerm_public_ip.vmips[each.key].ip_address
    }
    # or
    dynamic "ip_rule" {
      for_each  = var.vmips
      content {
        action    = "Allow"
        ip_range  = data.azurerm_public_ip.vmips[each.key].ip_address
      }
    }
  }
}

答案1

得分: 2

当您使用动态块时,迭代的上下文仅限于块本身。在您的用例中,network_rule_set 只能是一个块,根据文档,而 ip_rule 可以是一个或多个块。

以下代码可用于部署具有多个 ip_rules 的 acr,就像您打算的那样。

variable "vmips" {
  type = map(string)
  default = {
    "vm01" = "stackoverflow-ip-01", ## value can be rg as you intend when using data source.
    "vm02" = "stackoverflow-ip-02", ## value can be rg as you intend when using data source.
  }
}

resource "azurerm_resource_group" "stackoverflow" {
  name     = "stackoverflow-rg"
  location = "West Europe"
}
## I have used normal resource but the data source will be exactly the same with correct referencing.
resource "azurerm_public_ip" "vmips" {
  for_each = var.vmips

  name                = each.value
  resource_group_name = azurerm_resource_group.stackoverflow.name
  location            = azurerm_resource_group.stackoverflow.location
  allocation_method   = "Static"
}

resource "azurerm_container_registry" "acr" {
  name                          = "mymostuniqueacr001" ## has to be globally unique
  resource_group_name           = azurerm_resource_group.stackoverflow.name ## adjust accordingly 
  location                      = azurerm_resource_group.stackoverflow.location ## adjust accordingly 
  sku                           = "Premium"
  admin_enabled                 = false
  public_network_access_enabled = false

  ### This is the interesting section ###
  dynamic "network_rule_set" {
    for_each = length(var.vmips) > 0 ? ["only_one_network_rule_set_is_allowed"] : []

    content {
      default_action = "Deny"

      dynamic "ip_rule" {
        for_each = var.vmips
        content {
          action   = "Allow"
          ip_range = azurerm_public_ip.vmips[ip_rule.key].ip_address
        }
      }
    }
  }
}

动态块的官方文档:https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks

此外,您的变量定义中似乎还存在一个复制粘贴错误。

variable "vmips" {
  type = map(any)
  default = {
    "vm1" = "rg1",
    "vm2" = "rg2" ### 缺少 " ###
  } 
}

希望对您有所帮助 循环遍历 Terraform 数据源结果以获取 ip_rule 块(azurerm_container_registry)

英文:

When you use dynamic blocks the context of iteration is limited to the block itself. In your use case particularly network_rule_set can be only one block as per documentation however, ip_rule can be one or more blocks.

The below code can be used to deploy the acr with multiple ip_rules as you intend.

variable "vmips" {
  type = map(string)
  default = {
    "vm01" = "stackoverflow-ip-01", ## value can be rg as you intend when using data source.
    "vm02" = "stackoverflow-ip-02", ## value can be rg as you intend when using data source.
  }
}

resource "azurerm_resource_group" "stackoverflow" {
  name     = "stackoverflow-rg"
  location = "West Europe"
}
## I have used normal resource but the data source will be exactly the same with correct referencing.
resource "azurerm_public_ip" "vmips" {
  for_each = var.vmips

  name                = each.value
  resource_group_name = azurerm_resource_group.stackoverflow.name
  location            = azurerm_resource_group.stackoverflow.location
  allocation_method   = "Static"
}



resource "azurerm_container_registry" "acr" {
  name                          = "mymostuniqueacr001" ## has to be globally unique
  resource_group_name           = azurerm_resource_group.stackoverflow.name ## adjust accordingly 
  location                      = azurerm_resource_group.stackoverflow.location adjust accordingly 
  sku                           = "Premium"
  admin_enabled                 = false
  public_network_access_enabled = false

### This is the interesting section ###
  dynamic "network_rule_set" {
    for_each = length(var.vmips) > 0 ? ["only_one_network_rule_set_is_allowed"] : []

    content {
      default_action = "Deny"

      dynamic "ip_rule" {
        for_each = var.vmips
        content {
          action   = "Allow"
          ip_range = azurerm_public_ip.vmips[ip_rule.key].ip_address
        }
      }
    }
  }
}

official documentation for dynamic blocks: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks

Apart from that there seems to be a copy-paste error too in your variable definition.

variable "vmips" {
  type = map(any)
  default = {
    "vm1" = "rg1",
    "vm2" = "rg2" ### " is missing ###
  } 
}

Hope it helps 循环遍历 Terraform 数据源结果以获取 ip_rule 块(azurerm_container_registry)

huangapple
  • 本文由 发表于 2023年6月1日 00:25:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76375572.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定