All skills
microsoft avatar

/azure-app-onboard

@b8a1c66
by microsoftmicrosoft/skills3.1k stars
351

End-to-end orchestrator: from a business idea, app idea, or existing app to running Azure deployment with cost estimates and pre-deploy approval. Analyzes your app, auto-detects the right Azure services, scaffolds infrastructure code, and deploys — tailored to your app, not a template. Handles moving existing apps to Azure without rewriting or with minimal changes. WHEN: bring your app to Azure, plan my app, cost to run, is my code ready to deploy, deploy my app to the cloud, deploy all my services, what Azure services do I need, plan my Azure deployment, deploy my new app to Azure, one-click deploy, I have an app and want it on Azure, migrate my app to Azure, help me get started, build an app, no code yet, starter project. DO NOT USE FOR: use azd for deployment(use azure-deploy), optimizing existing costs (use cost-optimization), code readiness checks only (use azure-app-onboard-prereq).

Use this Skill: https://skilld.dev/gh/microsoft/skills/azure-app-onboard

This session only. Nothing lands on disk.

scaffoldreferencesbicep-app-service.md

≈1.3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Bicep — App Service Patterns

App Service-specific Bicep patterns. For shared patterns (skeleton, naming, tags, security defaults, data modules), see bicep-patterns.md.

Module Template

Standard App Service module with managed identity and SCM/FTP auth disabled. Use this as the base for ALL App Service resources.

param location string
param tags object
param appServicePlanId string
param appServiceName string

resource appService 'Microsoft.Web/sites@2023-12-01' = {
  name: appServiceName
  location: location
  tags: tags
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    serverFarmId: appServicePlanId
    httpsOnly: true
    siteConfig: {
      minTlsVersion: '1.2'
      ftpsState: 'Disabled'
    }
  }
}

// SCM basic auth — enabled in IaC for deploy convenience. Deploy phase re-disables via REST API after code upload.
resource scmAuth 'Microsoft.Web/sites/basicPublishingCredentialsPolicies@2023-12-01' = {
  parent: appService
  name: 'scm'
  properties: {
    allow: true
  }
}

// ⛔ MANDATORY — disable FTP basic auth
resource ftpAuth 'Microsoft.Web/sites/basicPublishingCredentialsPolicies@2023-12-01' = {
  parent: appService
  name: 'ftp'
  properties: {
    allow: false
  }
}

output appServiceId string = appService.id
output principalId string = appService.identity.principalId

⛔ Every App Service module MUST include: (1) identity: { type: 'SystemAssigned' }, (2) scm basicPublishingCredentialsPolicies with allow: true (IaC sets enabled for deploy convenience — deploy phase re-disables via REST API after code upload), (3) ftp basicPublishingCredentialsPolicies with allow: false. Missing any of these → self-review L1 FLAGGED.

Native Module Deploy Strategy

When prepare-plan.json.deployStrategy exists with codeDeployPattern: "startup-install", apply these patterns to the App Service Bicep:

resource appService 'Microsoft.Web/sites@2023-12-01' = {
  name: appServiceName
  location: location
  tags: tags
  properties: {
    serverFarmId: appServicePlan.id
    httpsOnly: true
    siteConfig: {
      linuxFxVersion: 'NODE|${nodeVersion}' // ⛔ Use exact version tag (18-lts, 20-lts) — NEVER tilde (~18). Tilde works for WEBSITE_NODE_DEFAULT_VERSION but NOT linuxFxVersion.
      ftpsState: 'Disabled'
      minTlsVersion: '1.2'
      // Startup command: Oryx build is primary, this is the safety-net fallback.
      // Runs npm install only if node_modules doesn't exist (Oryx missed it).
      // MUST be inline — never a .sh file (Windows CRLF → bash exit code 2).
      appCommandLine: '${deployStrategy.startupCommand}'
      appSettings: [
        // Primary: tell Oryx to run npm install during zip deploy
        { name: 'SCM_DO_BUILD_DURING_DEPLOYMENT', value: 'true' }
        { name: 'ENABLE_ORYX_BUILD', value: 'true' }
        // Extended timeout for native module compilation (max 1800, default 230)
        { name: 'WEBSITES_CONTAINER_START_TIME_LIMIT', value: '1800' }
        // App-specific settings
        { name: 'NODE_ENV', value: 'production' }
      ]
    }
  }
}

Rules:

  • ⛔ Inline appCommandLine only — never generate a .sh startup script file. Files created on Windows have CRLF line endings → bash exit code 2 on Linux
  • ⛔ Entry point from manifest — read package.json.scripts.start or .main, never hardcode index.js
  • ⛔ WEBSITES_CONTAINER_START_TIME_LIMIT = 1800 (the maximum). Native compilation takes 2-5 min; Python with scipy can take longer
  • When deployStrategy is absent (no native modules), do NOT set appCommandLine — let Oryx use its default startup
  • ⛔ Never prefix startup with cd /home/site/wwwroot — Oryx extracts build output to a temp directory and sets the working directory automatically. Hardcoding cd /home/site/wwwroot causes MODULE_NOT_FOUND / Could not import because the app files aren't there

Self-review check (L2 Pattern): If hasNativeModules == true, verify Bicep has BOTH appCommandLine and WEBSITES_CONTAINER_START_TIME_LIMIT. If prereq-output.json.initCommands[] has required: true entries, verify appCommandLine includes them before the app start command. FLAGGED if either check fails.

F1/D1 Free Tier — No Managed Identity

⛔ F1/D1 does NOT support managed identity (causes OOM / deployment failure). When the plan SKU is F1 or D1:

  • Omit identity: { type: 'SystemAssigned' } from the App Service resource
  • Do NOT use @Microsoft.KeyVault() in app settings — KV references require managed identity
  • Instead: Pass secrets as @secure() params from the KV module's @secure() output. The KV module generates the secret value and outputs it securely; main.bicep passes it to the App Service module as a @secure() param
  • Do NOT output principalId — it doesn't exist without identity

Identity Output — SystemAssigned vs UserAssigned

⛔ appService.identity.principalId only exists for SystemAssigned identity. When using UserAssigned, output the managed identity MODULE's principalId instead — identity.principalId is undefined and causes DeploymentOutputEvaluationFailed. F1/D1 App Service: no identity (OOM), so no principalId output.

Source: SKILL.md on GitHub

No alerts3d3 checks · Risk SAFE
  • Gen Agent Trust Hub3d

    This skill provides a comprehensive end-to-end orchestrator for deploying applications to Azure. It incorporates several security-focused patterns, such as secrets management via Azure Key Vault, managed identity integration, and robust preflight validation. There are some security considerations, such as a surface for indirect prompt injection during workspace analysis and broad default firewall rules, but these are managed through explicit user approval gates and documented trade-offs.

  • Socket3d

    No alerts

  • Snyk3d

    Risk: LOW · No issues

Signed by skilld at b8a1c66. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated last week
metadata
{
  "author": "Microsoft",
  "version": "1.2.4"
}

README badge

README badge for microsoft/skills/azure-app-onboard