Azure Functions Premium com Terraform: Integração de VNet Regional

functions-overview-1024×705.webp functions-overview-150×150.webp functions-overview-300×207.webp functions-overview-768×529.webp functions-overview.webp

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

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.

Arquitetura do Azure Functions Premium com integração de VNet: Function App no plano Elastic Premium saindo pela subnet delegada para recursos privados, NAT Gateway opcional e Storage Account do runtime
Arquitetura do cenário: a Function App no plano Elastic Premium usa a subnet delegada para chegar à VNet. Clique para ampliar.

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"
#   }
# ]
Azure Functions Premium com integração de VNet confirmada, Central US
Function App aplicada de verdade em Central US, plano Elastic Premium

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

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.

Deixe um comentário

Descubra mais sobre Blog do Castilho - Tecnologia | FinOps | DevOps | Cloud

Assine agora mesmo para continuar lendo e ter acesso ao arquivo completo.

Continuar lendo