Terraform部署Azure函数时存储账户访问失败及IP限制问题排查
问题分析与解决方案
首先解决StorageAccountNotFound报错
这个错误大概率并非真的找不到存储账户,而是由以下原因导致:
- 存储账户名称不符合Azure规范:Azure存储账户名称必须为3-24个字符,仅包含小写字母和数字。检查
${var.azure_pre}的值是否为小写,拼接后的账户名(如${var.azure_pre}soxcompwrk)长度是否合规。 - Terraform执行机器IP未被存储账户允许:你设置了存储账户
network_rules的default_action = "Deny",仅允许子网访问,但Terraform从本地/CI机器执行时,该机器的公网IP不在允许列表中,Azure会返回404以隐藏存储账户存在性。 - 子网未启用Storage服务端点:存储账户无法识别来自子网的流量,需要在子网配置中开启
Microsoft.Storage服务端点。
你的疑问解答
1. 当前方案是否正确?是否需要用azurerm_storage_account_network_rules?
- 方案方向正确:通过VNet+NSG控制函数入站IP,将函数和存储部署到子网并限制存储访问,符合安全需求。
- 不需要单独使用
azurerm_storage_account_network_rules:你在azurerm_storage_account内使用network_rules块的写法完全合法,这是内嵌式配置,比单独的resource更简洁,功能一致。 - 遗漏的基础要点:
- 必须将Terraform执行机器的IP添加到存储账户的允许列表(否则Terraform无法操作存储账户)。
- 子网需要启用Storage服务端点,否则存储账户无法识别子网流量。
- NSG入站规则需修改为仅允许特定IP访问443,当前规则允许所有IP,不符合你的需求。
2. virtual_network_subnet_ids = [azurerm_subnet.subnet.id]的写法是否正确?
写法本身正确,但缺少子网服务端点配置,需要在子网中添加service_endpoints = ["Microsoft.Storage"],否则存储账户无法接受来自该子网的流量。
代码修正关键点
1. 修正子网配置(添加服务端点)
resource "azurerm_subnet" "subnet" { name = "subnet-${var.azure_pre}-zzz-sox" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.vnet.name address_prefixes = ["10.0.2.0/24"] # 添加Storage服务端点 service_endpoints = ["Microsoft.Storage"] }
2. 给存储账户添加Terraform执行IP的允许规则
在每个存储账户的network_rules块中添加ip_rules(替换为你的执行机器公网IP):
resource "azurerm_storage_account" "filestorage" { name = "${var.azure_pre}soxcompwrk" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location account_tier = "Standard" account_replication_type = "LRS" network_rules { default_action = "Deny" virtual_network_subnet_ids = [azurerm_subnet.subnet.id] # 添加Terraform执行机器的IP ip_rules = ["x.x.x.x/32"] } }
3. 修正NSG入站规则(限制特定IP)
resource "azurerm_network_security_group" "securitygroup" { name = "nsg-${var.azure_pre}-zzz-sox" location = azurerm_resource_group.rg.location resource_group_name = azurerm_resource_group.rg.name security_rule { name = "AllowHttpsInbound" priority = 100 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "443" # 替换为你允许的特定IP/IP段 source_address_prefix = "192.168.1.1/32" destination_address_prefix = "*" } # 其余规则保持不变 }
4. 函数应用添加VNet路由配置
在azurerm_linux_function_app的app_settings中添加:
app_settings = { # 其他配置... "WEBSITE_VNET_ROUTE_ALL" = "1" }
内容的提问来源于stack exchange,提问作者Scott S
相关产品推荐
相关产品推荐

