Terraform部署Azure HDInsight Kafka集群遇子网地址前缀错误,如何解决?
问题
尝试使用以下Terraform脚本部署Azure HDInsight Kafka集群:
provider "azurerm" { features {} } resource "azurerm_resource_group" "rg" { name = "my-resource-group" location = "eastus" } resource "azurerm_virtual_network" "virtual_network" { resource_group_name = azurerm_resource_group.rg.name name = "my-vnet" location = "eastus" address_space = ["10.136.82.0/24"] } resource "azurerm_subnet" "subnet" { name = "subnet-3" resource_group_name = "my-resource-group" virtual_network_name = "my-vnet" address_prefixes = ["10.136.82.64/27"] } resource "azurerm_storage_account" "storage_account" { name = "my-storage-account" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location account_tier = "Standard" account_replication_type = "LRS" } resource "azurerm_storage_container" "storage_container" { name = "hdinsight" storage_account_name = azurerm_storage_account.storage_account.name container_access_type = "private" } resource "azurerm_hdinsight_kafka_cluster" "kafka_cluster" { name = "my-hdicluster" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location cluster_version = "4.0" tier = "Standard" component_version { kafka = "2.4" } gateway { username = "my-username" password = "my-password" } storage_account { storage_container_id = azurerm_storage_container.storage_container.id storage_account_key = azurerm_storage_account.storage_account.primary_access_key is_default = true } roles { head_node { virtual_network_id = azurerm_virtual_network.virtual_network.id subnet_id = azurerm_subnet.subnet.id vm_size = "Standard_D3_V2" username = "my-username" password = "my-password" } worker_node { virtual_network_id = azurerm_virtual_network.virtual_network.id subnet_id = azurerm_subnet.subnet.id vm_size = "Standard_D3_V2" username = "my-username" password = "my-password" number_of_disks_per_node = 3 target_instance_count = 3 } zookeeper_node { virtual_network_id = azurerm_virtual_network.virtual_network.id subnet_id = azurerm_subnet.subnet.id vm_size = "Standard_D3_V2" username = "my-username" password = "my-password" } } }
部署前VNET为空,执行以下命令验证:
az network vnet subnet list \ --resource-group my-resource-group \ --vnet-name my-vnet \ --query "[].{Name: name, AddressPrefix: addressPrefix}" \ --output table
输出为空(符合预期),但部署时收到错误:
Error: failure creating HDInsight Kafka Cluster "sccrpoc-hdicluster"
(Resource Group "my-resource-group"): hdinsight.ClustersClient#Create:
Failure sending request: StatusCode=400 -- Original Error: Code="BadRequest"
Message="Address prefix was not valid in the subnet.
Please ensure there is only one ipv4 address prefix in the subnet.
VirtualNetworkId: '/subscriptions/my-subscription/resourceGroups/my-resource-group/providers/Microsoft.Network/virtualNetworks/my-vnet',
SubnetName: '/subscriptions/my-subscription/resourceGroups/my-resource-group/providers/Microsoft.Network/virtualNetworks/my-vnet/subnets/subnet-3'"
需要做出哪些修改才能成功部署?
解决方案
错误提示要求子网仅包含单个IPv4地址前缀,当前配置看似符合要求,但问题出在资源引用方式和子网权限配置上,需做以下两处修改:
1. 修正子网资源的硬编码引用
azurerm_subnet资源中,resource_group_name和virtual_network_name使用了硬编码字符串,可能导致Terraform部署时出现资源依赖顺序或前缀识别异常,修改为动态引用已创建的资源属性:
resource "azurerm_subnet" "subnet" { name = "subnet-3" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.virtual_network.name address_prefixes = ["10.136.82.64/27"] }
2. 为HDInsight服务添加子网权限
Azure HDInsight需要访问子网的权限才能完成集群部署,需在子网中添加服务端点和委派配置:
resource "azurerm_subnet" "subnet" { name = "subnet-3" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.virtual_network.name address_prefixes = ["10.136.82.64/27"] # 添加HDInsight服务端点 service_endpoints = ["Microsoft.HDInsight"] # 委派子网给HDInsight服务 delegation { name = "hdinsight-delegation" service_delegation { name = "Microsoft.HDInsight/clusters" actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"] } } }
修改后的完整脚本
provider "azurerm" { features {} } resource "azurerm_resource_group" "rg" { name = "my-resource-group" location = "eastus" } resource "azurerm_virtual_network" "virtual_network" { resource_group_name = azurerm_resource_group.rg.name name = "my-vnet" location = azurerm_resource_group.rg.location address_space = ["10.136.82.0/24"] } resource "azurerm_subnet" "subnet" { name = "subnet-3" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.virtual_network.name address_prefixes = ["10.136.82.64/27"] service_endpoints = ["Microsoft.HDInsight"] delegation { name = "hdinsight-delegation" service_delegation { name = "Microsoft.HDInsight/clusters" actions = ["Microsoft.Network/virtualNetworks/subnets/join/action"] } } } resource "azurerm_storage_account" "storage_account" { name = "my-storage-account" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location account_tier = "Standard" account_replication_type = "LRS" } resource "azurerm_storage_container" "storage_container" { name = "hdinsight" storage_account_name = azurerm_storage_account.storage_account.name container_access_type = "private" } resource "azurerm_hdinsight_kafka_cluster" "kafka_cluster" { name = "my-hdicluster" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location cluster_version = "4.0" tier = "Standard" component_version { kafka = "2.4" } gateway { username = "my-username" password = "my-password" } storage_account { storage_container_id = azurerm_storage_container.storage_container.id storage_account_key = azurerm_storage_account.storage_account.primary_access_key is_default = true } roles { head_node { virtual_network_id = azurerm_virtual_network.virtual_network.id subnet_id = azurerm_subnet.subnet.id vm_size = "Standard_D3_V2" username = "my-username" password = "my-password" } worker_node { virtual_network_id = azurerm_virtual_network.virtual_network.id subnet_id = azurerm_subnet.subnet.id vm_size = "Standard_D3_V2" username = "my-username" password = "my-password" number_of_disks_per_node = 3 target_instance_count = 3 } zookeeper_node { virtual_network_id = azurerm_virtual_network.virtual_network.id subnet_id = azurerm_subnet.subnet.id vm_size = "Standard_D3_V2" username = "my-username" password = "my-password" } } }
额外注意事项
- 存储账户名称需符合Azure命名规则:仅含小写字母和数字,长度3-24位。
- 密码需符合Azure强密码要求:至少8位,包含大小写字母、数字、特殊字符。
内容的提问来源于stack exchange,提问作者Eugene Goldberg

