You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Terraform为虚拟网络中的Azure容器组配置公网IP访问?

问题解答与Terraform示例

核心结论

不能直接给部署在虚拟网络中的Azure容器组(ACI)绑定azurerm_public_ip——只有未加入VNet的ACI才支持直接分配公网IP。VNet内的ACI只能通过中转组件实现公网访问,最轻量化的方案是用Azure基础负载均衡器(Basic LB)的NAT规则做端口映射,而非直接关联公网IP。

思路误区纠正

  1. 错误认知:VNet内的ACI可以直接绑定公网IP
    • 实际Azure设计中,VNet部署的ACI属于私有网络资源,仅分配私有IP,不支持直接挂载公网IP。
  2. 过度复杂化:优先考虑应用网关而非基础LB
    • 单ACI的公网访问场景,基础LB的NAT规则足够满足需求,成本远低于应用网关,无需过度设计。
  3. 忽略LB依赖配置:以为只需要NAT规则就能转发流量
    • LB必须将ACI加入后端池,同时配置健康探针(哪怕是简单的TCP探针),否则流量无法正常转发。

Terraform示例代码

以下代码实现:创建VNet/子网 → 部署带私有IP的ACI → 创建基础LB+公网IP → 配置NAT规则将公网IP的80端口映射到ACI的80端口

# 配置Azure Provider
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.0"
    }
  }
}

provider "azurerm" {
  features {}
}

# 1. 创建资源组
resource "azurerm_resource_group" "example" {
  name     = "aci-public-access-rg"
  location = "East Asia"
}

# 2. 创建虚拟网络和子网(ACI必须部署到支持ACI的子网,不能有其他资源)
resource "azurerm_virtual_network" "example" {
  name                = "aci-vnet"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
}

resource "azurerm_subnet" "aci_subnet" {
  name                 = "aci-subnet"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.1.0/24"]
  # 子网必须启用ACI服务端点
  service_endpoints    = ["Microsoft.ContainerInstance"]
}

# 3. 创建部署在VNet内的ACI(仅私有IP)
resource "azurerm_container_group" "example" {
  name                = "aci-private"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  ip_address_type     = "Private"
  subnet_id           = azurerm_subnet.aci_subnet.id
  os_type             = "Linux"

  container {
    name   = "nginx"
    image  = "nginx:latest"
    cpu    = "1"
    memory = "1.0"

    ports {
      port     = 80
      protocol = "TCP"
    }
  }
}

# 4. 创建公网IP(用于LB)
resource "azurerm_public_ip" "lb_public_ip" {
  name                = "lb-public-ip"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  allocation_method   = "Static"
  sku                 = "Basic"
}

# 5. 创建基础负载均衡器
resource "azurerm_lb" "example" {
  name                = "aci-lb"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  frontend_ip_configuration {
    name                 = "public-ip-config"
    public_ip_address_id = azurerm_public_ip.lb_public_ip.id
  }
}

# 6. 创建LB后端池(关联ACI的私有IP)
resource "azurerm_lb_backend_address_pool" "example" {
  name            = "aci-backend-pool"
  loadbalancer_id = azurerm_lb.example.id
}

# 7. 将ACI的私有IP加入后端池
resource "azurerm_lb_backend_address_pool_address" "aci_address" {
  backend_address_pool_id = azurerm_lb_backend_address_pool.example.id
  ip_address              = azurerm_container_group.example.ip_address
}

# 8. 创建健康探针(TCP 80端口)
resource "azurerm_lb_probe" "example" {
  name            = "tcp-probe"
  loadbalancer_id = azurerm_lb.example.id
  protocol        = "Tcp"
  port            = 80
  interval_in_seconds = 10
  number_of_probes    = 3
}

# 9. 创建NAT规则:公网IP 80端口 → ACI 80端口
resource "azurerm_lb_nat_rule" "example" {
  name                = "aci-nat-rule"
  loadbalancer_id     = azurerm_lb.example.id
  frontend_ip_configuration_name = "public-ip-config"
  protocol            = "Tcp"
  frontend_port       = 80
  backend_port        = 80
  backend_address_pool_id = azurerm_lb_backend_address_pool.example.id
  probe_id            = azurerm_lb_probe.example.id
}

验证步骤

部署完成后,通过azurerm_public_ip.lb_public_ip.ip_address获取公网IP,在浏览器访问该IP即可看到Nginx默认页面。

内容的提问来源于stack exchange,提问作者Kafkaese

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 04:45:33