★★ 中級

08. Functions / Container Apps

Azure のサーバーレス/コンテナ実行は 3 つの主役: イベント駆動の Azure Functions、HTTP API の Container Apps、フルマネージドな App Service。最初は Container Apps が選択肢として一番万能。

3 つの選択肢

FunctionsContainer AppsApp Service
形態関数(コード)コンテナWeb アプリ(コードまたはコンテナ)
スケール0 → ∞、ms 起動0 → 多数VM ベース
用途イベント駆動、短時間処理API、Web、Worker常時稼働 Web
AWS 対応LambdaApp Runner / ECS FargateElastic Beanstalk
料金呼び出し従量vCPU・メモリ秒App Service Plan 時間

Azure Functions

# Functions 用 Storage Account(必須)
resource "azurerm_storage_account" "functions" {
  name                     = "safuncmyappprd"
  resource_group_name      = azurerm_resource_group.main.name
  location                 = azurerm_resource_group.main.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

# Linux Consumption Plan(従量制)
resource "azurerm_service_plan" "functions" {
  name                = "asp-myapp-functions"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location
  os_type             = "Linux"
  sku_name            = "Y1"   # Consumption
}

resource "azurerm_linux_function_app" "main" {
  name                = "func-myapp-prd"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location

  storage_account_name       = azurerm_storage_account.functions.name
  storage_account_access_key = azurerm_storage_account.functions.primary_access_key
  service_plan_id            = azurerm_service_plan.functions.id

  site_config {
    application_stack {
      node_version = "20"
    }
  }

  app_settings = {
    "FUNCTIONS_WORKER_RUNTIME" = "node"
    "WEBSITE_NODE_DEFAULT_VERSION" = "~20"
  }

  identity {
    type = "SystemAssigned"
  }
}

Container Apps

2026 年現在、Azure でコンテナ Web アプリを動かす 第一候補。Knative ベースで 0 から多数までスケール。

resource "azurerm_log_analytics_workspace" "main" {
  name                = "law-myapp-prd"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location
  sku                 = "PerGB2018"
  retention_in_days   = 30
}

# Container Apps Environment(複数アプリの実行基盤)
resource "azurerm_container_app_environment" "main" {
  name                       = "cae-myapp-prd"
  resource_group_name        = azurerm_resource_group.main.name
  location                   = azurerm_resource_group.main.location
  log_analytics_workspace_id = azurerm_log_analytics_workspace.main.id

  # VNet 統合(プライベートサブネット内で動かす場合)
  infrastructure_subnet_id   = azurerm_subnet.container_apps.id
  internal_load_balancer_enabled = false
}

resource "azurerm_container_app" "api" {
  name                         = "ca-api-prd"
  resource_group_name          = azurerm_resource_group.main.name
  container_app_environment_id = azurerm_container_app_environment.main.id
  revision_mode                = "Single"   # Multi にすると複数 revision 並行

  template {
    container {
      name   = "api"
      image  = "${azurerm_container_registry.main.login_server}/myapp/api:v1.2.0"
      cpu    = 0.5
      memory = "1Gi"

      env {
        name  = "LOG_LEVEL"
        value = "info"
      }
      env {
        name        = "DB_PASSWORD"
        secret_name = "db-password"   # 下の secret から
      }
    }

    min_replicas = 1
    max_replicas = 10

    http_scale_rule {
      name                = "http"
      concurrent_requests = 50
    }
  }

  ingress {
    external_enabled = true
    target_port      = 8080
    traffic_weight {
      latest_revision = true
      percentage      = 100
    }
  }

  secret {
    name  = "db-password"
    value = random_password.db.result
  }

  identity {
    type         = "UserAssigned"
    identity_ids = [azurerm_user_assigned_identity.app.id]
  }

  registry {
    server   = azurerm_container_registry.main.login_server
    identity = azurerm_user_assigned_identity.app.id   # ACR pull に MI を使用
  }
}

ACR (Container Registry)

resource "azurerm_container_registry" "main" {
  name                = "acrmyappprd"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location
  sku                 = "Standard"   # Basic / Standard / Premium
  admin_enabled       = false
}

# Container App 用 MI に AcrPull 付与
resource "azurerm_role_assignment" "acr_pull" {
  scope                = azurerm_container_registry.main.id
  role_definition_name = "AcrPull"
  principal_id         = azurerm_user_assigned_identity.app.principal_id
}

App Service

「常時稼働の Web アプリ・API」に向く。VM の概念が見える分、より細かい制御。

resource "azurerm_service_plan" "web" {
  name                = "asp-web-prd"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location
  os_type             = "Linux"
  sku_name            = "P1v3"   # Production tier
}

resource "azurerm_linux_web_app" "main" {
  name                = "app-myapp-prd"
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location
  service_plan_id     = azurerm_service_plan.web.id

  site_config {
    always_on = true
    application_stack {
      node_version = "20-lts"
    }
  }

  app_settings = {
    "WEBSITES_PORT" = "8080"
  }

  identity {
    type = "SystemAssigned"
  }
}

使い分け

シナリオ推奨
S3 アップロード → サムネ生成Functions(Blob トリガー)
HTTP API(コンテナで配布)Container Apps
非コンテナの Node.js / .NET アプリを常駐App Service
Kubernetes の完全制御が必要AKS