O plano Consumption do Azure Functions é gratuito até certo uso, mas tem uma limitação que pega muita gente de surpresa: não suporta integração de VNet regional. Se sua function precisa chamar um banco de dados privado, um storage atrás de Private Endpoint ou qualquer recurso que só existe dentro de uma VNet, o Consumption não consegue. É preciso o plano Elastic Premium.
Primeiro artigo da parte PaaS da série: como configurar o Azure Functions Premium com Terraform, com integração de VNet regional de verdade, e confirmar via CLI que a conexão está realmente ativa.
Segurança: a chave de acesso do Storage Account usada pela Function App é sensível. Nunca insira IDs de subscription, senhas ou chaves diretamente nos comandos — use TF_VAR_*, um arquivo .tfvars fora do Git, ou o Azure Key Vault.
Sumário
- Pré-requisitos
- Por que Premium e não Consumption
- VNet com subnet delegada
- Elastic Premium e a Function App
- terraform plan e apply
- Testando de verdade: integração de VNet ativa
- Custo
- Conclusão
- Referências oficiais
Pré-requisitos
Antes de configurar o Azure Functions Premium com Terraform, você vai precisar do Azure CLI autenticado (az login), do Terraform >= 1.5 e de permissão de Contributor na subscription. O provider usado é o azurerm ~> 4.0.
az account show --query "{name:name, id:id}" -o table
Azure Functions Premium: por que não Consumption
A diferença chave está toda na integração de rede. O plano Consumption é serverless de verdade: escala a zero e cobra por execução. É justamente isso que impede a integração de VNet regional, porque não há uma instância dedicada que mantenha uma conexão de rede persistente com a VNet. O Azure Functions Premium (plano Elastic Premium) resolve isso mantendo instâncias sempre disponíveis (com escala automática), o que também habilita VNet, mais memória e menos cold start.

VNet com subnet delegada
A integração de VNet regional do Azure Functions usa o mesmo mecanismo do App Service: uma subnet delegada a Microsoft.Web/serverFarms. Sem essa delegação, o Azure recusa a associação:
module "rg" {
source = "../../terraform-resource-group-modules"
resource_type = "rg"
project_name = "blog-castilho-functions"
environment = "prod"
location = var.location
tags = var.tags
}
module "vnet" {
source = "../../terraform-virtual-network-modules"
name = "vnet-functions-blog-castilho"
resource_group_name = module.rg.name
location = var.location
address_space = [var.vnet_address_space]
subnets = [
{
key = "functions"
name = "snet-functions"
address_prefixes = [var.functions_subnet_prefix]
delegation = {
name = "functions-delegation"
service_delegation_name = "Microsoft.Web/serverFarms"
service_delegation_actions = ["Microsoft.Network/virtualNetworks/subnets/action"]
}
},
]
tags = var.tags
}
Cada bloco usa um módulo reutilizável da série. Os endereços vêm do variables.tf: a VNet usa 10.100.0.0/16 e a subnet delegada às Functions, 10.100.1.0/24. O código completo, com os módulos, está no GitHub, no link do fim do artigo.
Elastic Premium e a Function App
No Azure Functions Premium, o plano EP1 (o menor tier Elastic Premium) hospeda a Function App, que se conecta à subnet delegada via virtual_network_subnet_id. O módulo liga o vnet_route_all_enabled sempre que a subnet é informada, e é ele que faz todo o tráfego de saída passar pela VNet. Sem ele, só o tráfego destinado a IPs privados usaria a integração, e chamadas de saída pra internet continuariam saindo direto:
resource "random_string" "storage_suffix" {
length = 8
special = false
upper = false
}
module "storage_functions" {
source = "../../terraform-storage-modules"
name = "stfuncsblog${random_string.storage_suffix.result}"
resource_group_name = module.rg.name
location = var.location
tags = var.tags
}
module "functions" {
source = "../../terraform-functions-modules"
name = "func-blog-castilho-${random_string.storage_suffix.result}"
plan_name = "plan-functions-blog-castilho"
resource_group_name = module.rg.name
location = var.location
sku_name = "EP1"
storage_account_name = module.storage_functions.storage_account_name
storage_account_access_key = module.storage_functions.primary_access_key
subnet_id = module.vnet.subnets["functions"].id
node_version = "20"
tags = var.tags
}
terraform plan e apply
terraform init -backend-config=backend.hcl
terraform plan -out=tfplan.out
terraform apply tfplan.out
O ambiente completo do Azure Functions Premium cria 7 recursos: Resource Group, VNet + subnet delegada, Storage Account, App Service Plan EP1 e a Function App. Achado real: na primeira tentativa, o plano EP1 falhou com Unauthorized — “Current Limit (EP1 VMs): 0” — porque a subscription usada não tinha cota de EP1 na região eastus. A solução foi trocar de região (centralus), não esperar ou pedir aumento de cota, já que o objetivo aqui era validar o padrão, não uma região específica.
Outro detalhe real: logo depois da Function App ser criada, o provider tentou ler as “Sticky Settings” dela e recebeu um 404 . A leitura aconteceu antes de a réplica do Azure Resource Manager propagar o recurso recém-criado. É uma race condition conhecida do provider azurerm, não um erro de configuração; rodar o apply de novo resolve, porque na segunda vez o recurso já existe de fato.
Testando de verdade: integração de VNet ativa
No Azure Functions Premium, a prova de que a integração de VNet está de fato ativa — não só declarada no Terraform — é consultar a Function App diretamente:
az functionapp vnet-integration list \
--name func-blog-castilho-<sufixo> \
--resource-group rg-blog-castilho-functions-prod
# [
# {
# "name": "snet-functions",
# "vnetResourceId": ".../virtualNetworks/vnet-functions-blog-castilho/subnets/snet-functions"
# }
# ]

A lista retornando a subnet snet-functions confirma que a associação foi aceita pelo Azure — se a integração tivesse falhado silenciosamente (o que pode acontecer se a subnet não estiver corretamente delegada), essa consulta voltaria vazia.
Custo
No Azure Functions Premium, o plano EP1 cobra proporcionalmente por hora (algo em torno de US$ 0,20/h) — não é gratuito como boa parte dos artigos de Network desta série, mas sai bem mais barato que VPN Gateway ou DDoS Protection Standard. Se a function precisar de um IP de saída fixo, associe um Azure NAT Gateway à subnet delegada: com o tráfego todo roteado pela VNet, a saída passa por ele. Depois de validar, destrua o ambiente:
terraform destroy
Conclusão
O Azure Functions Premium com integração de VNet regional resolve um problema real do plano Consumption: acesso a recursos privados. O ponto que mais exige atenção não é o Terraform em si, que se resume à subnet delegada, ao virtual_network_subnet_id e ao vnet_route_all_enabled. É garantir cota de EP1 na região escolhida: vale checar antes de aplicar ou ter um plano B de região em mãos. E se, em vez de consumir, você precisar expor uma aplicação sua para outra VNet sem peering, o caminho é o Private Link Service.
Esse artigo sobre Azure Functions Premium abre a parte PaaS da série, que continua com Container Apps, API Management e Service Bus.
Referências oficiais
- Azure Functions Premium plan — Microsoft Learn
- Regional VNet Integration — Microsoft Learn
- azurerm_linux_function_app — Terraform Registry
Interessado em saber mais sobre artigos relacionados a Microsoft Azure CLIQUE AQUI
🚀 Vamos nos conectar?
Não perca nenhuma oportunidade! Cadastre-se nas minhas redes e no canal do YouTube para receber conteúdos de TI, Cloud, Azure, AWS, Kubernetes e DevOps em primeira mão.
Dica: no Facebook, todos os artigos do blog são publicados automaticamente. Vale a pena curtir!
💬 Dúvidas ou problemas?
Com o intuito de ajudar a comunidade, caso você tenha dúvidas ou encontre problemas na execução dos comandos deste artigo, deixe um comentário abaixo. Responderei o mais breve possível!
Muito obrigado pela visita e até o próximo post!
Jefferson Castilho Especialista em Cloud & DevOps.Este guia técnico é exclusivo do Blog do Castilho. Explore mais conteúdos sobre Cloud e DevOps.