英文:
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" ### 缺少 " ###
}
}
希望对您有所帮助
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论