AzureAppServiceSkill azure-app-service

Azure App Service是一个完全托管的平台,用于构建、部署和监控各种Web应用程序、REST API和移动后端服务。支持多种编程语言,并集成了DevOps、安全性和高可用性功能。

Azure 0 次安装 0 次浏览 更新于 3/3/2026

name: azure-app-service description: 通过自动扩展、部署槽、SSL/TLS和监控部署和管理Azure App Service中的Web应用程序。用于在Azure上托管Web应用程序。

Azure App Service

概览

Azure App Service提供了一个完全托管的平台,用于构建和托管Web应用程序、REST API和移动后端。支持多种编程语言,集成了DevOps、安全性和高可用性。

使用场景

  • Web应用程序(ASP.NET、Node.js、Python、Java)
  • REST API和微服务
  • 移动应用后端
  • 静态网站托管
  • 需要扩展的生产应用程序
  • 需要自动扩展的应用程序
  • 多区域部署
  • 容器化应用程序

实施示例

1. 使用Azure CLI创建App Service

# 登录Azure
az login

# 创建资源组
az group create --name myapp-rg --location eastus

# 创建App Service计划
az appservice plan create \
  --name myapp-plan \
  --resource-group myapp-rg \
  --sku P1V2 \
  --is-linux

# 创建Web应用程序
az webapp create \
  --resource-group myapp-rg \
  --plan myapp-plan \
  --name myapp-web \
  --deployment-container-image-name nodejs:18

# 配置应用程序设置
az webapp config appsettings set \
  --resource-group myapp-rg \
  --name myapp-web \
  --settings \
    NODE_ENV=production \
    PORT=8080 \
    DATABASE_URL=postgresql://... \
    REDIS_URL=redis://...

# 启用仅HTTPS
az webapp update \
  --resource-group myapp-rg \
  --name myapp-web \
  --https-only true

# 配置自定义域名
az webapp config hostname add \
  --resource-group myapp-rg \
  --webapp-name myapp-web \
  --hostname www.example.com

# 创建部署槽
az webapp deployment slot create \
  --resource-group myapp-rg \
  --name myapp-web \
  --slot staging

# 交换槽
az webapp deployment slot swap \
  --resource-group myapp-rg \
  --name myapp-web \
  --slot staging

# 获取发布配置文件
az webapp deployment list-publish-profiles \
  --resource-group myapp-rg \
  --name myapp-web \
  --query "[0].publishUrl"

2. Terraform App Service配置

# app-service.tf
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.0"
    }
  }
}

provider "azurerm" {
  features {}
}

variable "environment" {
  default = "prod"
}

variable "location" {
  default = "eastus"
}

# 资源组
resource "azurerm_resource_group" "main" {
  name     = "myapp-rg-${var.environment}"
  location = var.location
}

# App Service计划
resource "azurerm_service_plan" "main" {
  name                = "myapp-plan-${var.environment}"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  os_type             = "Linux"
  sku_name            = "P1V2"

  tags = {
    environment = var.environment
  }
}

# 日志分析工作区
resource "azurerm_log_analytics_workspace" "main" {
  name                = "myapp-logs-${var.environment}"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  sku                 = "PerGB2018"

  retention_in_days = 30
}

# 应用程序见解
resource "azurerm_application_insights" "main" {
  name                = "myapp-insights-${var.environment}"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  application_type    = "web"

  retention_in_days      = 30
  workspace_id           = azurerm_log_analytics_workspace.main.id
}

# Web应用程序
resource "azurerm_linux_web_app" "main" {
  name                = "myapp-web-${var.environment}"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  service_plan_id     = azurerm_service_plan.main.id

  https_only = true

  app_settings = {
    WEBSITES_ENABLE_APP_SERVICE_STORAGE = false
    DOCKER_ENABLE_CI                    = true
    APPINSIGHTS_INSTRUMENTATIONKEY      = azurerm_application_insights.main.instrumentation_key
    APPLICATIONINSIGHTS_CONNECTION_STRING = azurerm_application_insights.main.connection_string
    NODE_ENV                            = "production"
    PORT                                = "8080"
  }

  site_config {
    always_on                   = true
    http2_enabled               = true
    minimum_tls_version         = "1.2"
    websockets_enabled          = false
    application_stack {
      node_version = "18-lts"
    }

    cors {
      allowed_origins = ["https://example.com"]
    }
  }

  identity {
    type = "SystemAssigned"
  }

  tags = {
    environment = var.environment
  }
}

# 部署槽(暂存)
resource "azurerm_linux_web_app_slot" "staging" {
  name            = "staging"
  app_service_id  = azurerm_linux_web_app.main.id
  service_plan_id = azurerm_service_plan.main.id

  https_only = true

  app_settings = {
    WEBSITES_ENABLE_APP_SERVICE_STORAGE = false
    NODE_ENV                            = "staging"
    PORT                                = "8080"
  }

  site_config {
    always_on           = true
    http2_enabled       = true
    minimum_tls_version = "1.2"

    application_stack {
      node_version = "18-lts"
    }
  }

  identity {
    type = "SystemAssigned"
  }
}

# 自动扩展设置
resource "azurerm_monitor_autoscale_setting" "app_service" {
  name                = "app-service-autoscale"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  target_resource_id  = azurerm_service_plan.main.id

  profile {
    name = "default"

    capacity {
      default = 2
      minimum = 1
      maximum = 5
    }

    rule {
      metric_trigger {
        metric_name        = "CpuPercentage"
        metric_resource_id = azurerm_service_plan.main.id
        time_grain         = "PT1M"
        statistic          = "Average"
        time_window        = "PT5M"
        operator           = "GreaterThan"
        threshold          = 75
      }

      scale_action {
        direction = "Increase"
        type      = "ChangeCount"
        value     = 1
        cooldown  = "PT5M"
      }
    }

    rule {
      metric_trigger {
        metric_name        = "CpuPercentage"
        metric_resource_id = azurerm_service_plan.main.id
        time_grain         = "PT1M"
        statistic          = "Average"
        time_window        = "PT5M"
        operator           = "LessThan"
        threshold          = 25
      }

      scale_action {
        direction = "Decrease"
        type      = "ChangeCount"
        value     = 1
        cooldown  = "PT5M"
      }
    }
  }
}

# 诊断设置
resource "azurerm_monitor_diagnostic_setting" "app_service" {
  name               = "app-service-logs"
  target_resource_id = azurerm_linux_web_app.main.id
  log_analytics_workspace_id = azurerm_log_analytics_workspace.main.id

  enabled_log {
    category = "AppServiceHTTPLogs"
  }

  enabled_log {
    category = "AppServiceAntivirusScanAuditLogs"
  }

  metric {
    category = "AllMetrics"
  }
}

# 密钥库用于密钥
resource "azurerm_key_vault" "main" {
  name                = "myappkv${var.environment}"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  tenant_id           = data.azurerm_client_config.current.tenant_id
  sku_name            = "standard"

  access_policy {
    tenant_id = data.azurerm_client_config.current.tenant_id
    object_id = azurerm_linux_web_app.main.identity[0].principal_id

    secret_permissions = [
      "Get",
      "List"
    ]
  }

  tags = {
    environment = var.environment
  }
}

# 密钥库密钥
resource "azurerm_key_vault_secret" "database_url" {
  name         = "database-url"
  value        = "postgresql://user:pass@host/db"
  key_vault_id = azurerm_key_vault.main.id
}

resource "azurerm_key_vault_secret" "api_key" {
  name         = "api-key"
  value        = "your-api-key-here"
  key_vault_id = azurerm_key_vault.main.id
}

data "azurerm_client_config" "current" {}

output "app_url" {
  value = "https://${azurerm_linux_web_app.main.default_hostname}"
}

output "app_insights_key" {
  value     = azurerm_application_insights.main.instrumentation_key
  sensitive = true
}

3. 部署配置

# .github/workflows/deploy.yml
name: 部署到App Service

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: 设置Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: 安装依赖
        run: npm install

      - name: 运行测试
        run: npm test

      - name: 构建
        run: npm run build

      - name: 部署到Azure
        uses: azure/webapps-deploy@v2
        with:
          app-name: myapp-web-prod
          publish-profile: ${{ secrets.AZURE_PUBLISH_PROFILE }}
          package: .

      - name: 交换槽
        uses: azure/CLI@v1
        with:
          azcliversion: 2.0.76
          inlineScript: |
            az webapp deployment slot swap \
              --resource-group myapp-rg-prod \
              --name myapp-web-prod \
              --slot staging

4. 健康检查配置

# 启用健康检查
az webapp config set \
  --resource-group myapp-rg \
  --name myapp-web \
  --generic-configurations HEALTHCHECK_PATH=/health

# 监控健康
az monitor metrics list-definitions \
  --resource /subscriptions/{subscription}/resourceGroups/myapp-rg/providers/Microsoft.Web/sites/myapp-web

最佳实践

✅ DO

  • 使用部署槽进行零停机部署
  • 启用应用程序见解
  • 根据指标配置自动扩展
  • 使用托管身份访问Azure服务
  • 启用仅HTTPS
  • 在密钥库中存储密钥
  • 监控性能指标
  • 实施健康检查

❌ DON’T

  • 在配置中存储密钥
  • 禁用HTTPS
  • 忽略应用程序见解
  • 为生产使用单一实例
  • 直接部署到生产环境
  • 忽略自动扩展配置

监控

  • 应用程序见解用于应用程序指标
  • Azure Monitor用于资源健康
  • Log Analytics用于日志分析
  • 自定义指标和事件
  • 性能计数器和诊断

资源