Generated banner for Azure Prepare
Generated logo for Azure Prepare

Azure Prepare

MicrosoftOfficialCreated by Microsoft

  • Skill
  • Workflow
  • Cloud and DevOps
  • MIT
  • Medium risk
  • Has scripts

From the author

Prepare azd-based Azure projects for deployment: generates azure.yaml, infrastructure (Bicep/Terraform), and Dockerfiles for the Azure Developer CLI (azd) workflow. USE ONLY when the user explicitly wants to use azd as the deployment tool, or the project already has an azure.yaml file. DO NOT USE FOR: non-azd deployments, Python App Service code-only deploys (use python-appservice-deploy), or cross-cloud migration (use azure-cloud-migrate). WHEN: prepare app for azd, create azure.yaml, set up azd infrastructure, modernize app for Azure with azd, deploy with azd, function app, timer trigger, service bus trigger, event-driven function, managed identity, generate Bicep, generate Terraform, create and deploy to Azure.
— the description by Microsoft

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

The azure-prepare skill provides a mandatory, structured workflow for setting up applications for deployment to Azure via the Azure Developer CLI (azd). It enforces a plan-first approach, requiring the creation of a deployment plan file before any infrastructure generation or configuration occurs. The skill guides users through analyzing their workspace, selecting appropriate deployment recipes (Bicep or Terraform), and configuring necessary Azure services, while ensuring security best practices are followed. It acts as the initial phase in a three-part deployment pipeline: prepare, validate, and deploy.

What it does

  • Generates azure.yaml configuration files for azd-based projects.
  • Creates infrastructure-as-code templates using Bicep or Terraform.
  • Enforces a mandatory .azure/deployment-plan.md file to track project state.
  • Integrates with specialized skills for specific technologies like Azure Functions or API Management.
  • Applies security hardening, such as Entra-only authentication for SQL databases.
  • Prepares the workspace for subsequent validation and deployment steps.

When to use it

  • When you need to prepare a new or existing project for deployment to Azure using azd.
  • When you need to generate infrastructure-as-code (Bicep or Terraform) for your application.
  • When you are modernizing an existing application to run on Azure.
  • When you need to add new Azure services or components to an existing project.

Advantages

  • Ensures consistent deployment configurations across projects.
  • Prevents common configuration errors through a mandatory planning phase.
  • Integrates seamlessly with the broader Azure deployment ecosystem (validate and deploy).
  • Promotes security best practices by default, such as managed identities.
  • Provides clear guidance on when to delegate to specialized deployment skills.

Usage examples

“I want to deploy my new web application to Azure using azd.”
The agent will initiate the NEW mode, guide you through requirements gathering, create a deployment plan, and generate the necessary infrastructure and configuration files.
“Add an Azure Function to my existing project and set up the infrastructure.”
The agent will analyze your existing project, select the appropriate Azure Functions recipe, update the deployment plan, and generate the required Bicep or Terraform files.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/microsoft/azure-prepare/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip azure-prepare.zip -d .agents/skills

Documentation by Microsoft

Azure Prepare

AUTHORITATIVE GUIDANCE — MANDATORY COMPLIANCE

This document is the official, canonical source for preparing applications for Azure deployment. You MUST follow these instructions exactly as written unless they contradict security policies given to you. When in doubt, present the conflicting instructions from this document and ask the user for explicit confirmation. Do not improvise, infer, or substitute steps.


Triggers

Activate this skill when user wants to:

  • Create a new application

  • Add services or components to an existing app

  • Make updates or changes to existing application

  • Modernize or migrate an application

  • Set up Azure infrastructure

  • Deploy to Azure or host on Azure

  • Create and deploy to Azure (including Terraform-based deployment requests)

Rules

  1. Plan first — MANDATORY — You MUST physically write an initial .azure/deployment-plan.md skeleton in the workspace root directory (not the session-state folder) as your very first action — before any code generation or execution begins. Write the skeleton immediately, then populate it progressively as Phase 1 analysis and research unfold; finalize it with all decisions at Phase 1 Step 6. This file must exist on disk throughout. azure-validate and azure-deploy depend on it and will fail without it. Do not skip or defer this step.

  2. Get approval — Present plan to user before execution

  3. Research before generating — Load references and invoke related skills

  4. Update plan progressively — Mark steps complete as you go

  5. Validate before deploy — Invoke azure-validate before azure-deploy

  6. Confirm Azure context — Use ask_user for subscription and location per Azure Context

  7. ❌ Destructive actions require ask_user — Global Rules

  8. ⛔ NEVER delete user project or workspace directories — When adding features to an existing project, MODIFY existing files. azd init -t <template> is for NEW projects only; do NOT run azd init -t in an existing workspace. Plain azd init (without a template argument) may be used in existing workspaces when appropriate. File deletions within a project (e.g., removing build artifacts or temp files) are permitted when appropriate, but NEVER delete the user's project or workspace directory itself. See Global Rules.

  9. Scope: preparation only — This skill generates infrastructure code and configuration files. Deployment execution (azd up, azd deploy, terraform apply) is handled by the azure-deploy skill, which provides built-in error recovery and deployment verification.

  10. ⛔ SQL Server Bicep: NEVER generate administratorLogin or administratorLoginPassword — not in direct properties, not in conditional/ternary branches, not anywhere in the file. Always use Entra-only authentication (azureADOnlyAuthentication: true) unconditionally. See references/services/sql-database/bicep.md.

  11. Remove stale template IaC after conversion — If you converted Bicep templates from the selected azd template into Terraform templates, remove the Bicep templates that were introduced by that azd template and are now fully replaced by Terraform equivalents. Do not remove user-authored Bicep files. Only remove those template-provided Bicep files after the Terraform IaC is complete and Terraform has been selected as the deployment path. Before handing off to azure-validate skill, keep only the IaC templates required by the chosen deployment path.


❌ PLAN-FIRST WORKFLOW — MANDATORY

YOU MUST CREATE A PLAN BEFORE DOING ANY WORK

  1. STOP — Do not generate any code, infrastructure, or configuration yet

  2. CREATE SKELETON - Write an initial .azure/deployment-plan.md skeleton to disk immediately (before any code generation or execution begins), then populate it progressively as Phase 1 steps 1-5 reveal details; finalize it at Step 6

  3. CONFIRM — Present the completed plan to the user and get approval

  4. EXECUTE — Only after approval, execute the plan step by step

The .azure/deployment-plan.md file is the source of truth for this workflow and for azure-validate and azure-deploy skills. Without it, those skills will fail.

⚠️ CRITICAL: .azure/deployment-plan.md must be WRITTEN TO DISK inside the workspace root (e.g., <workspace-root>/.azure/deployment-plan.md), not in the session-state folder. Use a file-write tool to create this file. This is the deployment plan artifact read by azure-validate and azure-deploy. You MUST create this file — do not proceed without it. ⚠️ CRITICAL: You must create the file with the name .azure/deployment-plan.md as is. You must not use other names such as .azure/plan.md.

⛔ Critical: Skipping the plan file creation will cause azure-validate and azure-deploy to fail. This requirement has no exceptions.


❌ STEP 0: Specialized Technology Check — MANDATORY FIRST ACTION

BEFORE starting Phase 1, check if the user's prompt OR workspace codebase matches a specialized technology that has a dedicated skill with tested templates. If matched, invoke that skill FIRST — then resume azure-prepare for validation and deployment.

Check 1: Prompt keywords
Prompt keywordsInvoke FIRST
Python + App Service (e.g., "deploy Python to App Service", "Flask on Azure App Service", "publish Python web app to App Service")python-appservice-deploy
Lambda, AWS Lambda, migrate AWS, migrate GCP, Lambda to Functions, migrate from AWS, migrate from GCPazure-cloud-migrate
Azure Functions, function app, serverless function, timer trigger, HTTP trigger, func newStay in azure-prepare — prefer Azure Functions templates in Step 4; for plan choice/cold starts see hosting-plans.md and cold-start.md
APIM, API Management, API gateway, deploy APIMStay in azure-prepare — see APIM Deployment Guide
AI gateway, AI gateway policy, AI gateway backend, AI gateway configurationazure-aigateway
workflow, orchestration, multi-step, pipeline, fan-out/fan-in, saga, long-running process, durable, order processingStay in azure-prepare — select durable recipe in Step 4. MUST load durable.md, DTS reference, and DTS Bicep patterns.

⚠️ Check the user's prompt text — not just existing code. Critical for greenfield projects with no codebase to scan. See full routing table.

After the specialized skill completes, resume azure-prepare at Phase 1 Step 4 (Select Recipe) for remaining infrastructure, validation, and deployment.


Phase 1: Planning (BLOCKING — Complete Before Any Execution)

Create .azure/deployment-plan.md by completing these steps. Do NOT generate any artifacts until the plan is approved.

#ActionReference
0If the prompt matches a specialized technology with a dedicated skill, invoke that skill firstspecialized-routing.md
1Analyze Workspace — Determine mode: NEW, MODIFY, or MODERNIZEanalyze.md
2Gather Requirements — Classification, scale, budgetrequirements.md
3Scan Codebase — Identify components, technologies, dependenciesscan.md
4Select Recipe — Choose AZD (default), AZCLI, Bicep, or Terraformrecipe-selection.md
5Plan Architecture — Select stack + map components to Azure servicesarchitecture.md
6Finalize Plan (MANDATORY) - Use a file-write tool to finalize .azure/deployment-plan.md with all decisions from steps 1-5. Update the skeleton written at the start of Phase 1 with the complete content. The file must be fully populated before you present the plan to the user.plan-template.md
7Present Plan — Show plan to user and ask for approval.azure/deployment-plan.md
8Destructive actions require ask_userGlobal Rules

❌ STOP HERE — Do NOT proceed to Phase 2 until the user approves the plan.


Phase 2: Execution (Only After Plan Approval)

Execute the approved plan. Update .azure/deployment-plan.md status after each step.

#ActionReference
1Research Components — Load service references + invoke related skillsresearch.md
2Confirm Azure Context — Detect and confirm subscription + location and check the resource provisioning limitAzure Context
3Generate Artifacts — Create infrastructure and configuration filesgenerate.md
4Harden Security — Apply security best practicessecurity.md
5Functional Verification — Verify the app works (UI + backend), locally if possiblefunctional-verification.md
6⛔ Update Plan (MANDATORY before hand-off) — Use the edit tool to change the Status in .azure/deployment-plan.md to Ready for Validation. You MUST complete this edit BEFORE invoking azure-validate. Do NOT skip this step..azure/deployment-plan.md
7⛔ MANDATORY Hand Off — Invoke azure-validate skill. Your preparation work is done. Do NOT run azd up, azd deploy, or any deployment command directly — all deployment execution is handled by azure-deploy after azure-validate completes. PREREQUISITE: Step 6 must be completed first — .azure/deployment-plan.md status must say Ready for Validation.—

Outputs

ArtifactLocation
Plan.azure/deployment-plan.md
Infrastructure./infra/
AZD Configazure.yaml (AZD only)
Dockerfilessrc/<component>/Dockerfile

SDK Quick References


Next

⛔ MANDATORY NEXT STEP — DO NOT SKIP

After completing preparation, you MUST invoke azure-validate before any deployment attempt. Do NOT skip validation. Do NOT go directly to azure-deploy. Do NOT run azd up or any deployment command directly. The workflow is:

azure-prepare → azure-validate → azure-deploy

⛔ BEFORE invoking azure-validate, you MUST use the edit tool to update .azure/deployment-plan.md status to Ready for Validation. If the plan status has not been updated, the validation will fail.

This applies to ALL deployment scenarios including containerized apps, Container Apps, App Service, Azure Functions, static sites, and any other Azure target. No exceptions.

Skipping validation leads to deployment failures. Be patient and follow the complete workflow for the highest success outcome.

→ Update plan status to Ready for Validation, then invoke azure-validate

Files

references/aspire.md

.NET Aspire Projects

⛔ CRITICAL - READ THIS FIRST

For .NET Aspire projects, NEVER manually create azure.yaml or infra/ files. Always use azd init --from-code which auto-detects the AppHost and generates everything correctly.

Failure to follow this causes: "Could not find a part of the path 'infra\main.bicep'" error.

Guidance for preparing .NET Aspire applications for Azure deployment.

📖 For detailed AZD workflow: See recipes/azd/aspire.md

What is .NET Aspire?

.NET Aspire is an opinionated, cloud-ready stack for building observable, production-ready distributed applications. Aspire projects use an AppHost orchestrator to define and configure the application's components, services, and dependencies.

Detection

A .NET Aspire project is identified by:

IndicatorDescription
*.AppHost.csprojAppHost orchestrator project file
Aspire.Hosting packageCore Aspire hosting package reference
Aspire.Hosting.AppHostAlternative Aspire hosting package

Example project structure:

orleans-voting/
├── OrleansVoting.sln
├── OrleansVoting.AppHost/
│   └── OrleansVoting.AppHost.csproj   ← AppHost indicator
├── OrleansVoting.Web/
├── OrleansVoting.Api/
└── OrleansVoting.Grains/

Azure Preparation Workflow

Step 1: Detection

When scanning the codebase (per scan.md), detect Aspire by:

# Check for AppHost project
find . -name "*.AppHost.csproj"

# Or check for Aspire.Hosting package reference
grep -r "Aspire.Hosting" . --include="*.csproj"
⛔ Step 1a: Pre-Check for Custom/Non-Deployable Resources (MANDATORY)

Before running azd init --from-code, scan the AppHost source code to understand whether the app may contain local-only custom resources.

# Find the AppHost project and scan only its source directory
APPHOST_PROJECT=$(find . -name "*.AppHost.csproj" | head -1)
APPHOST_DIR=$(dirname "$APPHOST_PROJECT")
grep -r "ExcludeFromManifest" "$APPHOST_DIR" --include="*.cs" | head -20

PowerShell:

# Find the AppHost project and scan only its source directory
$appHostProject = Get-ChildItem -Recurse -Filter "*.AppHost.csproj" | Select-Object -First 1
$appHostDir = $appHostProject.DirectoryName
Get-ChildItem -Path $appHostDir -Recurse -Filter "*.cs" | Select-String "ExcludeFromManifest" | Select-Object -First 20

This scan is informational. .ExcludeFromManifest() can appear alongside deployable resources, so a positive match does not immediately block deployment. What matters is the final azure.yaml output after azd init --from-code completes:

  • If azd init fails with unsupported resource type → see Step 2 error guidance below.

  • If azd init succeeds but azure.yaml has an empty or missing services section → see Step 4a below.

💡 Why scan early: Knowing that .ExcludeFromManifest() is present gives useful context when azd errors or generates an empty manifest — it confirms the app intentionally targets local development rather than Azure deployment.

Step 2: Initialize with azd

CRITICAL: For Aspire projects, use azd init --from-code -e <environment-name> instead of creating azure.yaml manually.

⚠️ ALWAYS include the -e <environment-name> flag: Without it, azd init will fail in non-interactive environments (agents, CI/CD) with the error: no default response for prompt 'Enter a unique environment name:'

The --from-code flag:

  • Auto-detects the AppHost orchestrator

  • Reads the Aspire service definitions

  • Generates appropriate azure.yaml and infrastructure

  • Works in non-interactive/CI environments when combined with -e flag

# Non-interactive initialization for Aspire projects (REQUIRED for agents)
ENV_NAME="$(basename "$PWD" | tr '[:upper:]' '[:lower:]' | tr ' _' '-')-dev"
azd init --from-code -e "$ENV_NAME"

Why both flags are required:

  • --from-code: Tells azd to detect the AppHost automatically (no "How do you want to initialize?" prompt)

  • -e <name>: Provides environment name upfront (no "Enter environment name:" prompt)

  • Together, they enable fully non-interactive operation essential for automation, agents, and CI/CD pipelines

⛔ If azd init --from-code fails with "unsupported resource type":

This error means the AppHost contains custom Aspire resource types that azd cannot process for Azure deployment:

  1. ⛔ Do NOT attempt to fix this error by modifying source code — do not add .ExcludeFromManifest() calls or otherwise patch the AppHost

  2. ⛔ Do NOT proceed with deployment — the application is designed for local development only

  3. ✅ Record a blocker: "AppHost contains custom Aspire resource types (unsupported resource type) that cannot be deployed to Azure"

  4. ✅ Inform the user: this application uses custom Aspire resource authoring patterns intended for local tooling, not cloud deployment

⚠️ Why modifying source code is forbidden: Adding .ExcludeFromManifest() may suppress the error and allow azd init to succeed, but the deployment outcome will not reflect the application's actual intent. The custom resources are deliberately designed to be local-only.

Step 3: Configure Subscription and Location

⛔ CRITICAL: After azd init --from-code completes, you MUST immediately set the user-confirmed subscription and location.

DO NOT skip this step or delay it until validation. The azd init command creates an environment but does NOT inherit the Azure CLI's subscription. If you skip this step, azd will use its own default subscription, which may differ from the user's confirmed choice.

Set the subscription and location immediately after initialization:

# Set the user-confirmed subscription ID
azd env set AZURE_SUBSCRIPTION_ID <subscription-id>

# Set the location
azd env set AZURE_LOCATION <location>

Verify the configuration:

azd env get-values

Confirm that AZURE_SUBSCRIPTION_ID and AZURE_LOCATION match the user's confirmed choices from Azure Context.

Step 4: What azd Generates

azd init --from-code creates:

ArtifactLocationDescription
azure.yamlProject rootService definitions from AppHost
infra/Project rootBicep templates for Azure resources
.azure/Project rootEnvironment configuration
⛔ Step 4a: Validate Generated Output

MANDATORY: After azd init --from-code completes, verify the generated azure.yaml contains deployable services.

# Check if azure.yaml has a non-empty services section
cat azure.yaml

If the services section is empty or missing: The AppHost has no deployable resources. This happens when all resources use .ExcludeFromManifest() (e.g., custom resource demonstrations, local-only tooling). In this case:

  1. ⛔ Do NOT proceed with deployment — there is nothing to deploy

  2. ✅ Keep the plan status in a valid state (for example, leave it as Planning) and record a blocker in the plan body with the reason: "Application contains only custom/demo Aspire resources with no Azure-deployable services"

  3. ✅ Inform the user that this application is designed for local development and cannot be meaningfully deployed to Azure

  4. ⛔ Do NOT manually create Bicep, Dockerfiles, or azure.yaml to work around this — the absence of services is the correct result

Example generated azure.yaml:

name: orleans-voting
# metadata section is auto-generated by azd init --from-code

services:
  web:
    project: ./OrleansVoting.Web
    language: dotnet
    host: containerapp

  api:
    project: ./OrleansVoting.Api
    language: dotnet
    host: containerapp
⛔ Step 4b: Fix Azure Functions Secret Storage (MANDATORY for Aspire + Functions)

MANDATORY: After azd init --from-code succeeds, check if the AppHost contains Azure Functions and fix secret storage configuration.

This step MUST run BEFORE azd up or azd provision. Skipping it causes a runtime failure: Secret initialization from Blob storage failed.

1. Detect Azure Functions in the AppHost:

APPHOST_DIR=$(dirname "$(find . -name '*.AppHost.csproj' | head -1)")
grep -n "AddAzureFunctionsProject" "$APPHOST_DIR"/*.cs

PowerShell:

$appHostDir = (Get-ChildItem -Recurse -Filter "*.AppHost.csproj" | Select-Object -First 1).DirectoryName
Get-ChildItem -Path $appHostDir -Filter "*.cs" | Select-String "AddAzureFunctionsProject"

If AddAzureFunctionsProject is NOT found → skip this step.

2. Check if AzureWebJobsSecretStorageType is already configured:

grep -n "AzureWebJobsSecretStorageType" "$APPHOST_DIR"/*.cs

PowerShell:

Get-ChildItem -Path $appHostDir -Filter "*.cs" | Select-String "AzureWebJobsSecretStorageType"

If already present → skip this step.

3. Add the environment variable to the Functions builder chain:

Use the edit tool to add .WithEnvironment("AzureWebJobsSecretStorageType", "Files") to the AddAzureFunctionsProject builder chain in the AppHost source file.

Before:

var functions = builder.AddAzureFunctionsProject<Projects.MyFunctions>("functions")
    .WithHostStorage(storage)
    .WithReference(queues);

After:

var functions = builder.AddAzureFunctionsProject<Projects.MyFunctions>("functions")
    .WithHostStorage(storage)
    .WithEnvironment("AzureWebJobsSecretStorageType", "Files")
    .WithReference(queues);

💡 Tip: Place .WithEnvironment(...) immediately after .WithHostStorage(...) for clarity.

⚠️ Why this is required: When Aspire uses WithHostStorage(storage), it configures identity-based storage URIs (e.g., AzureWebJobsStorage__blobServiceUri). Azure Functions' secret/key manager does not support these identity-based URIs — it requires either a connection string or file-based storage. Setting AzureWebJobsSecretStorageType=Files switches to file-system key storage, bypassing the incompatible blob dependency.

See aspire-functions-secrets reference for additional details.

Flags Reference

azd init for Aspire
FlagRequiredDescription
--from-code✅ YesAuto-detect AppHost, no interactive prompts
-e <name>✅ YesEnvironment name (required for non-interactive)
--no-promptOptionalSkip additional confirmations

Complete initialization sequence:

# 1. Initialize the environment
ENV_NAME="$(basename "$PWD" | tr '[:upper:]' '[:lower:]' | tr ' _' '-')-dev"
azd init --from-code -e "$ENV_NAME"

# 2. IMMEDIATELY set the user-confirmed subscription
azd env set AZURE_SUBSCRIPTION_ID <subscription-id>

# 3. Set the location
azd env set AZURE_LOCATION <location>

# 4. Verify configuration
azd env get-values

Common Aspire Samples

SampleRepositoryNotes
orleans-votingdotnet/aspire-samplesOrleans cluster with voting app
AspireYarpdotnet/aspire-samplesYARP reverse proxy
AspireWithDaprdotnet/aspire-samplesDapr integration
eShopdotnet/eShopReference microservices app

Troubleshooting

Error: "no default response for prompt 'Enter a unique environment name:'"

Cause: Missing -e flag when running azd init --from-code in non-interactive environment
Solution: Always include the -e <environment-name> flag

# ❌ Wrong - fails in non-interactive environments (agents, CI/CD)
azd init --from-code

# ✅ Correct - provides environment name upfront
ENV_NAME="$(basename "$PWD" | tr '[:upper:]' '[:lower:]' | tr ' _' '-')-dev"
azd init --from-code -e "$ENV_NAME"

Important: This error typically occurs when:

  • Running in an agent or automation context

  • No TTY is available for interactive prompts

  • The -e flag was omitted

Error: "no default response for prompt 'How do you want to initialize your app?'"

Cause: Missing --from-code flag
Solution: Add --from-code to the azd init command

# ❌ Wrong - requires interactive prompt
azd init -e "my-env"

# ✅ Correct - auto-detects AppHost
azd init --from-code -e "my-env"
No AppHost detected

Symptoms: azd init --from-code doesn't find the AppHost

Solutions:

  1. Verify AppHost project exists: find . -name "*.AppHost.csproj"

  2. Check project builds: dotnet build

  3. Ensure Aspire.Hosting package is referenced in AppHost project

Error: "unsupported resource type" during manifest generation

Symptoms: azd init --from-code fails with output like:

error: unsupported resource type: <custom-resource-type>

or the manifest generation step errors on child resources (e.g., ClockHand, or other custom resource types defined in the AppHost).

Cause: The AppHost contains custom Aspire resource types that azd cannot convert to Azure deployable resources. These custom types are typically:

  • Demonstration resources showing developers how to build Aspire extensions for local tooling

  • Resources that wrap local services without Azure equivalents

  • Custom child resources (e.g., subcomponents of a custom Aspire integration)

Resolution:

  1. ⛔ Do NOT attempt to fix this error by modifying source code — do not add .ExcludeFromManifest() calls or otherwise patch the AppHost

  2. ⛔ Do NOT proceed with deployment — this is a deployment blocker, not a recoverable error

  3. ✅ Record a blocker in the deployment plan: "AppHost contains custom Aspire resource types not supported for Azure deployment (unsupported resource type)"

  4. ✅ Inform the user that this application is designed for local development and cannot be meaningfully deployed to Azure

⚠️ Why this is a hard stop: Custom resource types that produce "unsupported resource type" errors are intentionally not deployable. Adding .ExcludeFromManifest() to suppress the error may allow azd init to succeed, but the resulting deployment would not represent the application's actual functionality.

Azure Functions: Secret initialization from Blob storage failed

Symptoms: Azure Functions app fails at startup with error:

System.InvalidOperationException: Secret initialization from Blob storage failed due to missing both
an Azure Storage connection string and a SAS connection uri.

Cause: When using AddAzureFunctionsProject with WithHostStorage(storage), Aspire configures identity-based storage access (managed identity). However, Azure Functions' internal secret management does not support identity-based URIs and requires file-based secret storage for Container Apps deployments.

Solution: Add AzureWebJobsSecretStorageType=Files environment variable to the Functions resource in the AppHost before running azd up:

var functions = builder.AddAzureFunctionsProject<Projects.ImageGallery_Functions>("functions")
                       .WithReference(queues)
                       .WithReference(blobs)
                       .WaitFor(storage)
                       .WithRoleAssignments(storage, ...)
                       .WithHostStorage(storage)
                       .WithEnvironment("AzureWebJobsSecretStorageType", "Files")  // Required for Container Apps
                       .WithUrlForEndpoint("http", u => u.DisplayText = "Functions App");

💡 Why this is required:

  • WithHostStorage(storage) sets identity-based URIs like AzureWebJobsStorage__blobServiceUri

  • This is correct and secure for runtime storage operations

  • However, Functions' secret/key management doesn't support these URIs

  • File-based secrets are mandatory for Container Apps deployments

⚠️ Important: This is required when:

  • Using AddAzureFunctionsProject in Aspire

  • Using WithHostStorage() with identity-based storage

  • Deploying to Azure Container Apps (the default for Aspire Functions)

Generated Infrastructure Note:

If you need to modify the generated Container Apps infrastructure directly, ensure the Functions container app has this environment variable:

resource functionsContainerApp 'Microsoft.App/containerApps@2024-03-01' = {
  properties: {
    template: {
      containers: [
        {
          env: [
            {
              name: 'AzureWebJobsSecretStorageType'
              value: 'Files'
            }
            // ... other environment variables
          ]
        }
      ]
    }
  }
}
Error: azd uses wrong subscription despite user confirmation

Symptoms: azd provision --preview shows a different subscription than the one the user confirmed

Cause: The AZURE_SUBSCRIPTION_ID was not set immediately after azd init --from-code. The Azure CLI and azd can have different default subscriptions.

Solution: Always set the subscription immediately after initialization:

# After azd init --from-code completes:
azd env set AZURE_SUBSCRIPTION_ID <user-confirmed-subscription-id>
azd env set AZURE_LOCATION <location>

# Verify before proceeding:
azd env get-values

Prevention: Follow the complete initialization sequence in the Flags Reference section above.

References

Next Steps

After azd init --from-code:

  1. Review generated azure.yaml and infra/ files (if present)

  2. Set AZURE_SUBSCRIPTION_ID and AZURE_LOCATION with azd env set

  3. Customize infrastructure as needed

  4. Proceed to azure-validate skill

  5. Deploy with azure-deploy skill

⚠️ Important for Container Apps: If using Aspire with Container Apps, azure-validate will check and help set up required environment variables after provisioning.

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs Python

Security

What our scanner noticed· Medium risk

  • Instructions that use the network
  • Downloads piped into a shell
  • Scripts that your agent may run

This skill includes scripts that your agent may run. Read them before you use it.

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
Microsoft
Publisher
Microsoft (Official)
Source
microsoft/skills · .github/plugins/azure-skills/skills/azure-prepare · commit 0696600
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from .github/plugins/azure-skills/LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced
Also distributed in
microsoft/azure-skills

AutoGineer is not affiliated with or endorsed by Microsoft or Microsoft.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download azure-prepare.zip