如何通过Terraform为Azure App Service配置NAT网关实现静态出站IP
问题背景
我正在开发一个ASP.NET Core Web API,计划部署为Azure App Service。该API需与Binance交互,而Binance要求填写与API密钥关联的IP地址。研究Azure静态IP相关内容后,我发现可使用NAT网关获取静态出站IP,这正是对接Binance所需的,但配置过程中遇到了困难。以下是目前的配置操作,现提出以下技术问题:
- 能否验证我是否正确配置了用于静态出站IP的NAT网关?
- 我看到有示例使用专用端点在虚拟网络内路由Azure App Service与Azure SQL Database之间的流量,我是否应该在当前配置中采用这种方式?请详细说明。
- 是否建议将资源划分到不同子网(例如prod-eastus-linuxapp-snet和prod-eastus-sqlserver-snet)?
- 如何从技术上确认配置生效?理论上它应该能正常工作。
当前Terraform配置
resource "azurerm_service_plan" "asp" { name = "${local.basename}-asp" resource_group_name = module.resource_group.name location = var.location os_type = "Linux" sku_name = "S1" } resource "azurerm_linux_web_app" "app" { name = "${local.basename}-app" resource_group_name = module.resource_group.name location = var.location service_plan_id = azurerm_service_plan.asp.id site_config { vnet_route_all_enabled = true # WEBSITE_VNET_ROUTE_ALL } tags = var.tags } resource "azurerm_virtual_network" "vnet" { name = "${local.basename}-vnet" resource_group_name = module.resource_group.name location = var.location address_space = ["10.0.0.0/16"] tags = var.tags } resource "azurerm_subnet" "snet" { name = "${local.basename}-linuxapp-snet" resource_group_name = module.resource_group.name virtual_network_name = azurerm_virtual_network.vnet.name address_prefixes = ["10.0.1.0/24"] delegation { name = "delegation" service_delegation { name = "Microsoft.Web/serverFarms" actions = ["Microsoft.Network/virtualNetworks/subnets/action"] } } } resource "azurerm_subnet_nat_gateway_association" "example" { subnet_id = azurerm_subnet.snet.id nat_gateway_id = azurerm_nat_gateway.ng.id } resource "azurerm_public_ip" "pip" { name = "${local.basename}-pip" resource_group_name = module.resource_group.name location = var.location allocation_method = "Static" sku = "Standard" tags = var.tags } resource "azurerm_nat_gateway" "ng" { name = "${local.basename}-ng" resource_group_name = module.resource_group.name location = var.location sku_name = "Standard" idle_timeout_in_minutes = 10 tags = var.tags } resource "azurerm_nat_gateway_public_ip_association" "association" { nat_gateway_id = azurerm_nat_gateway.ng.id public_ip_address_id = azurerm_public_ip.pip.id } resource "azurerm_app_service_virtual_network_swift_connection" "example" { app_service_id = azurerm_linux_web_app.app.id subnet_id = azurerm_subnet.snet.id }
问题解答
1. NAT网关配置验证
从你的Terraform配置来看,核心逻辑符合静态出站IP的要求:
- 启用了
vnet_route_all_enabled = true,确保App Service所有出站流量都走虚拟网络路由,这是NAT网关生效的关键前提 - 创建了标准SKU的静态公网IP,并正确关联到NAT网关
- 完成了NAT网关与App Service子网的关联
- 通过
azurerm_app_service_virtual_network_swift_connection实现了App Service到子网的快速集成
额外注意:你的服务计划是S1 SKU(标准层),支持VNet集成和NAT网关,满足功能前提;子网委派权限配置正确,符合Microsoft.Web/serverFarms的要求。整体配置无明显错误。
2. 是否需要使用专用端点连接Azure SQL Database?
是否采用取决于你的安全需求和架构复杂度容忍度:
建议使用的场景
- 要求完全隔离公网访问:专用端点让SQL Database仅在虚拟网络内可见,避免暴露公网IP,符合严格合规要求
- 提升数据传输安全性:流量完全在Azure骨干网络内传输,不经过公网,降低数据泄露风险
- 已有VNet集成基础:你的App Service已经接入VNet,添加专用端点的配置成本较低
可以不使用的场景
- 对配置复杂度敏感:专用端点需要额外配置独立子网(不能与App Service子网共用,且不能有委派)、私有DNS解析,增加了维护成本
- 基础安全需求已满足:如果已经通过SQL防火墙规则限制了NAT网关的静态IP访问,且合规要求不严格,公网连接也能满足需求
总结:若项目对数据安全有较高要求,建议采用专用端点;若追求配置简洁,现有NAT网关的静态IP已可满足基础安全限制。
3. 是否建议划分不同子网?
强烈建议按资源类型划分独立子网,原因如下:
- 安全隔离:不同子网可通过网络安全组(NSG)单独配置出入站规则,比如App Service子网仅允许出站到Binance和SQL,SQL子网仅允许来自App Service子网的入站流量,精细化控制风险
- 避免配置冲突:部分Azure服务对子网有特殊要求(比如专用端点需要未委派的子网),分开部署可避免权限或规则冲突
- 扩展性与维护性:独立子网的地址空间互不干扰,后续扩容时不会出现地址冲突;按资源类型划分的子网架构更清晰,便于后续排查问题和维护
你示例中的子网划分方式(prod-eastus-linuxapp-snet和prod-eastus-sqlserver-snet)是合理的生产环境最佳实践。
4. 如何验证配置生效?
可通过以下技术手段确认:
方法1:查看App Service出站IP
进入Azure门户的App Service资源,在网络->出站流量中,检查是否仅显示NAT网关的静态公网IP(此时App Service默认的出站IP会被NAT网关IP替代)
方法2:直接测试出站IP
- 在App Service中部署一个接口,调用第三方IP查询服务返回当前出站IP,验证是否等于NAT网关的静态IP
- 通过Kudu控制台执行命令:
curl icanhazip.com,直接查看出站IP
方法3:验证Binance连接
将NAT网关的静态IP添加到Binance API密钥的IP白名单,测试API调用是否成功。若成功,说明出站IP已正确生效
方法4:查看监控与日志
- 查看NAT网关的监控指标(比如出站数据包数),确认有流量通过NAT网关转发
- 启用App Service的网络日志,检查出站请求的源IP是否为NAT网关的静态IP
内容的提问来源于stack exchange,提问作者nop
相关产品推荐
相关产品推荐

