地形循环

时间:2020-02-09 15:57:32

标签: azure loops terraform

我目前正在编写一些Terraform代码,将Azure私有DNS区域部署到Azure中。

我已使用以下代码成功部署了DNS区域:

public function delivery(Request $request) {

    $iid = $request->inv_id;
    $items = DB::table('inventory')
      ->join('products', 'products.id', '=', 'inventory.product_id')
      ->whereIn('inventory.id', $iid)
      ->select('products.*' , 'inventory.id as id1')
      ->get();

    $errors = [];

    foreach($items as $item) {
        if ($item->owner != Auth::user()->id) {
          $errors[] = 'Nu detii acest obiect.';
        }

        if ($item->sold == 1) {
          $errors[] = 'Din pacate acest obiect este vandut.';
        }

        if ($item->on_market == 1) {
          $errors[] = 'Acest obiect este plasat la vanzare pe market.';
        }
    }


    if(!empty($errors)) {

        $back = back();

        foreach($errors as $error) {
          $back = $back->with('error', $error); 
        }
        return $back;
    }

    Inventory::whereIn('id', $iid)
              ->update(['redeemed' => 1]);


    return redirect('/inventory')->with('success', 'Success');
}

我的问题是配置区域和虚拟网络之间的链接。我需要遍历dns_zones列表并有一个嵌套循环,然后嵌套遍历vnet_links列表并在区域上配置vnet链接。

以下解决方案有效,但是它不是很健壮,因为从任何一个列表中删除配置都将使列表的索引编号乱序,从而导致Terraform删除并重新创建配置,这是不可行的:

dns_zones = [
"domain1.com",
"domain2.com",
"domain3.com",
]

resource "azurerm_private_dns_zone" "dns_zones" {
  for_each = toset(var.dns_zones)

  name                = each.value
  resource_group_name = var.resource_group
}

我发现使用下面的setproduct()函数可以创建一个包含要使用的数据的新列表,我打算将其与for_each而不是count一起使用,但无法使用使用toset()函数,因为它只接受字符串列表。

vnet_links = [
    {
    "linkName": "name-of-vnet-link1"
    "vnetId": "vnet--resource-id-placeholder1"
    },{
    "linkName": "name-of-vnet-link2"
    "vnetId": "vnet--resource-id-placeholder2"
    }
]

resource "azurerm_private_dns_zone_virtual_network_link" "vnet_link" {
  count              = length(setproduct(var.dns_zones, var.vnet_links))

  name                  = element(setproduct(var.dns_zones, var.vnet_links)[count.index], 1).linkName
  resource_group_name   = var.resource_group
  private_dns_zone_name = element(setproduct(var.dns_zones, var.vnet_links)[count.index], 0)
  virtual_network_id    = element(setproduct(var.dns_zones, var.vnet_links)[count.index], 1).vnetId
}

现在我有点卡住了。我可以在vnet_links列表中包含区域信息,但是这需要大量重复,这是我想避免的。理想情况下,我希望能够找到一种解决方案,该解决方案不需要对dns_zones列表进行任何更改,并保留带有vnet链接的单独列表。

谢谢!

编辑:

感谢Charles提供了一种格式化数据的方法。除了Charles响应之外,我还需要在for_each循环中创建一个动态映射以使用数据。最终的解决方案如下所示:

setproduct(var.dns_zones, var.vnet_links)

1 个答案:

答案 0 :(得分:0)

对于您的需求,我认为for循环适合您,我假设您希望将区域信息和Vnet链接关联为以下格式:

  {
    "vnet_link" = {
    "linkName": "name-of-vnet-link1"
    "vnetId": "vnet--resource-id-placeholder1"
    }
    "zone" = "domain1.com"
  }

然后,您可以使用for循环将所有可能的关联放入如下所示的列表中:

variable "dns_zones" {
  default = [
    "domain1.com",
    "domain2.com",
    "domain3.com",
  ]
}

variable "vnet_links" {
  default = [
    {
    "linkName": "name-of-vnet-link1"
    "vnetId": "vnet--resource-id-placeholder1"
    },
    {
    "linkName": "name-of-vnet-link2"
    "vnetId": "vnet--resource-id-placeholder2"
    }
  ]
}

locals {
  association = flatten([
    for dns_zone in var.dns_zones: [
      for link in var.vnet_links: {
        zone = dns_zone
        vnet_link = link
      }
    ]
  ])
}

output "association" {
  value = local.association
}

最后,输出将如下所示:

enter image description here

如果还有其他问题,请告诉我。希望这是您想要的解决方案。