无法在现有Azure VNet子网部署Internal APIM(stv2)的问题求助
在现有Azure虚拟网络(VNet)子网中部署Internal类型的stv2版API Management(APIM)网关,由于服务需部署在虚拟网络内且启用可用性区域,因此必须指定公网IP。相关基础设施(VNet、子网、Function APP等)已由其他团队搭建完成,但部署时触发400错误,请求解决。
数据块代码
data "azurerm_resource_group" "rg" { name = "azdlgleuw-rg-sharatapigw-001" } data "azurerm_virtual_network" "virtualnetwork" { name = "azdlgleuw-vnet-sharatapigw-001" resource_group_name = data.azurerm_resource_group.rg.name } data "azurerm_subnet" "apisubnet" { name = "azdlgleuw-snet-sharatapigw-001" resource_group_name = data.azurerm_resource_group.rg.name virtual_network_name = data.azurerm_virtual_network.virtualnetwork.name }
公网IP资源代码
resource "azurerm_public_ip" "api-pip" { allocation_method = "Static" location = data.azurerm_resource_group.rg.location name = "azdlgleuw-pip-publicip-001" resource_group_name = data.azurerm_resource_group.rg.name sku = "Standard" zones = [1,2,3] sku_tier = "Regional" idle_timeout_in_minutes = 4 ip_version = "IPv4" domain_name_label = "azure-api-sharatapigw-001" }
API Management资源创建代码
resource "azurerm_api_management" "apim" { name = "azdlgleuw-apim-apimngname-001" resource_group_name = data.azurerm_resource_group.rg.name location = data.azurerm_resource_group.rg.location publisher_name = "sharat" publisher_email = "abc@xyz.com" virtual_network_type = "Internal" sku_name = "Developer_1" virtual_network_configuration { subnet_id = data.azurerm_subnet.apisubnet.id } public_ip_address_id = azurerm_public_ip.api-pip.id } resource "azurerm_api_management_api" "sharatapimgmntapi" { name = "azdlgleuw-apim-apimgmntapi-001" resource_group_name = data.azurerm_resource_group.rg.name api_management_name = azurerm_api_management.apim.name revision = "1" display_name = "sharat-api" path = "extranet/v1" protocols = ["https"] import { content_format = "openapi" content_value = file("${path.module}/openapi.yaml") } } resource "azurerm_api_management_api_policy" "example" { api_name = azurerm_api_management_api.sharatapimgmntapi.name api_management_name = azurerm_api_management.apim.name resource_group_name = data.azurerm_resource_group.rg.name xml_content = <<XML <policies> <inbound> <base /> <set-backend-service base-url="https://azure-api-sharatapigw-001.azurewebsites.net/api" /> </inbound> </policies> XML }
错误信息(翻译后)
错误:创建/更新服务(订阅:"xxxxxxxxxxxxxx"
│ 资源组名称:"azdlgleuw-rg-sharatapigw-001"
│ 服务名称:"azure-api-sharatapigw-001"):执行CreateOrUpdate时遇到意外状态码400(400错误请求),错误信息:InvalidParameters:无效参数:在配置了虚拟网络类型为Internal的API管理服务部署中,将subnetResourceId更新为/subscriptions/xxxxxxxx/resourceGroups/azdlgleuw-rg-sharatapigw-001/providers/Microsoft.Network/virtualNetworks/azdlgleuw-vnet-sharatapigw-001/subnets/azdlgleuw-snet-sharatapigw-001时,位于West Europe区域的公网IP地址属性必须与/subscriptions/xxxxxxxxxxxxx/resourceGroups/azdlgleuw-rg-sharatapigw-001/providers/Microsoft.Network/publicIPAddresses/azdlgleuw-pip-publicip-001不同,且不能与任何现有区域(西欧)的公网IP匹配,因为我们需要创建新部署以避免停机。
解决方案
1. 排查资源名称冲突
错误信息中提到的服务名称azure-api-sharatapigw-001与代码中定义的APIM实例名称azdlgleuw-apim-apimngname-001不一致,需:
- 登录Azure门户,检查目标资源组中是否存在名为
azure-api-sharatapigw-001的APIM残留实例,若存在则删除该实例; - 若Terraform状态文件中存在该实例的记录,运行
terraform state rm azurerm_api_management.<实例名>清理状态。
2. 更换新的公网IP
Azure要求在变更Internal类型APIM的子网配置时,必须使用全新的公网IP来创建新部署单元,避免服务停机。操作步骤:
- 修改公网IP资源的名称(例如改为
azdlgleuw-pip-apim-new-001),同时更新domain_name_label避免冲突; - 更新APIM资源中
public_ip_address_id的引用,指向新创建的公网IP。
修正后的公网IP代码示例:
resource "azurerm_public_ip" "api-pip-new" { allocation_method = "Static" location = data.azurerm_resource_group.rg.location name = "azdlgleuw-pip-apim-new-001" resource_group_name = data.azurerm_resource_group.rg.name sku = "Standard" zones = [1,2,3] sku_tier = "Regional" idle_timeout_in_minutes = 4 ip_version = "IPv4" domain_name_label = "azure-api-sharatapigw-new-001" }
修正后的APIM资源引用:
resource "azurerm_api_management" "apim" { # 其他配置保持不变 public_ip_address_id = azurerm_public_ip.api-pip-new.id }
3. 验证子网合规性
确认APIM专用子网满足以下要求:
- 子网未部署其他任何Azure资源;
- 子网地址空间至少为
/24(256个IP地址),APIM需要多个内部IP用于组件部署。
4. 执行部署
完成上述修改后,依次运行以下命令:
terraform plan terraform apply
内容的提问来源于stack exchange,提问作者Sharat Bhaskar

