gpt4 book ai didi

azure - 使用 Terraform 从 Azure 上的应用程序服务的出站 IP 进行 MySQL 防火墙规则

转载 作者:行者123 更新时间:2023-12-03 00:57:53 27 4
gpt4 key购买 nike

我正在使用 Terraform 将应用部署到 Azure,包括 MySQL 服务器和应用服务,并且希望将数据库访问限制为仅限应用服务。应用程序服务有一个出站 IP 列表,因此我认为我需要在数据库上为这些创建防火墙规则。我发现在 Terraform 中,我无法使用 countfor_each 动态创建这些规则,因为事先不知道该值。

我们还考虑过对计数进行硬编码,但 Azure 文档未确认 IP 数量。有了这个,并且在 stackoverflow 评论中看到不同的数字后,我担心该数字可能会在某个时候发生变化并破坏 future 的部署。

输出错误建议使用 -target 作为解决方法,但 Terraform 文档明确建议不要这样做,因为存在潜在风险。

有什么解决方案的建议吗?是否有解决方法,或者是否有其他更适合的方法?

到目前为止我使用的非功能代码可以更好地了解我正在尝试做什么:

...
locals {
appIps = split(",", azurerm_app_service.appService.outbound_ip_addresses)
}

resource "azurerm_mysql_firewall_rule" "appFirewallRule" {

count = length(appIps)

depends_on = [azurerm_app_service.appService]
name = "appService-${count.index}"
resource_group_name = "myResourceGroup"
server_name = azurerm_mysql_server.databaseServer.name
start_ip_address = local.appIps[count.index]
end_ip_address = local.appIps[count.index]
}
...

这会返回错误:


Error: Invalid count argument

on main.tf line 331, in resource "azurerm_mysql_firewall_rule" "appFirewallRule":
331: count = length(local.appIps)

The "count" value depends on resource attributes that cannot be determined
until apply, so Terraform cannot predict how many instances will be created.
To work around this, use the -target argument to first apply only the
resources that the count depends on.

最佳答案

我在那里进行了更深入的研究,我认为我有一个至少对我有用的解决方案:)

这里问题的核心是必须分两步完成整个事情(我们不可能还不知道 countfor_each 的参数值>)。它可以通过显式的命令式逻辑或操作来解决(例如使用 -target 一次或注释掉然后取消注释)。此外,它不是声明性的,也不适合通过 CI/CD 实现自动化(我使用的是 Terraform Cloud,而不是本地环境)。

所以我只是使用 Terraform 资源来完成此操作,唯一的“命令”模式是触发管道(或本地运行)两次。

检查我的代码片段:

data "azurerm_resources" "web_apps_filter" {
resource_group_name = var.rg_system_name
type = "Microsoft.Web/sites"
required_tags = {
ProvisionedWith = "Terraform"
}
}

data "azurerm_app_service" "web_apps" {
count = length(data.azurerm_resources.web_apps_filter.resources)

resource_group_name = var.rg_system_name
name = data.azurerm_resources.web_apps_filter.resources[count.index].name
}

data "azurerm_resources" "func_apps_filter" {
resource_group_name = var.rg_storage_name
type = "Microsoft.Web/sites"
required_tags = {
ProvisionedWith = "Terraform"
}
}

data "azurerm_app_service" "func_apps" {
count = length(data.azurerm_resources.func_apps_filter.resources)

resource_group_name = var.rg_storage_name
name = data.azurerm_resources.func_apps_filter.resources[count.index].name
}

locals {
# flatten ensures that this local value is a flat list of IPs, rather
# than a list of lists of IPs.
# distinct ensures that we have only uniq IPs

web_ips = distinct(flatten([
for app in data.azurerm_app_service.web_apps : [
split(",", app.possible_outbound_ip_addresses)
]
]))

func_ips = distinct(flatten([
for app in data.azurerm_app_service.func_apps : [
split(",", app.possible_outbound_ip_addresses)
]
]))
}

resource "azurerm_postgresql_firewall_rule" "pgfr_func" {
for_each = toset(local.web_ips)

name = "web_app_ip_${replace(each.value, ".", "_")}"
resource_group_name = var.rg_storage_name
server_name = "${var.project_abbrev}-pgdb-${local.region_abbrev}-${local.environment_abbrev}"
start_ip_address = each.value
end_ip_address = each.value
}

resource "azurerm_postgresql_firewall_rule" "pgfr_web" {
for_each = toset(local.func_ips)

name = "func_app_ip_${replace(each.value, ".", "_")}"
resource_group_name = var.rg_storage_name
server_name = "${var.project_abbrev}-pgdb-${local.region_abbrev}-${local.environment_abbrev}"
start_ip_address = each.value
end_ip_address = each.value
}

最重要的部分是 azurerm_resources 资源 - 我使用它来过滤我的资源组中已存在的 Web 应用程序(并由自动化管理)。我正在该列表上执行数据库防火墙规则,下一个 terraform 运行时,当新创建的 Web 应用程序存在时,它还会将最后创建的 Web 应用程序列入白名单。

有趣的是 IP 过滤 - 其中很多都是重复的。

关于azure - 使用 Terraform 从 Azure 上的应用程序服务的出站 IP 进行 MySQL 防火墙规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64971807/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com