agentsclimarketplace

Scaffolding azure bicep infrastructure

Skill alexpizarro/azure-lean-stack-skills/skills/scaffolding-azure-bicep-infrastructure

Generates a subscription-scoped Bicep stack + GitHub Actions workflows for an Azure web app, with opt-in module toggles (SQL, Storage, Observability) and the {org}-{project}-{component}-{env} naming formula. Use when bootstrapping a new Azure project's IaC, adding a Bicep module, or refactoring into the modular-toggle pattern.From its SKILL.md

Install
npx -y skills add alexpizarro/azure-lean-stack-skills --skill scaffolding-azure-bicep-infrastructure

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

6.9 KB, ~1.7k tokens by cl100k_base, as published. Nobody here has run it

Scaffolding Azure Bicep Infrastructure

Generates the Bicep + workflow files for a new Azure web app. Modular by default: every component (SQL, Storage, Observability) is an opt-in boolean toggle on main.bicep, so projects only provision what they actually use.

When to invoke

  • New project: generate infra/, infra/environments/, .github/workflows/
  • Existing project: add a new module or refactor into the modular-toggle pattern

Workflow checklist

Copy this checklist into your response and check items off as you complete them:

Azure Bicep scaffolding:
- [ ] Step 1: Collect inputs (org, project, GitHub repo, components)
- [ ] Step 2: Generate infra/main.bicep with modular toggles
- [ ] Step 3: Generate infra/modules/ (resourceGroup, staticWebApp, sqlServer; add storage/observability/aca if toggled)
- [ ] Step 4: Generate infra/environments/test.parameters.json + prod.parameters.json
- [ ] Step 5: Generate .github/workflows/ (deploy-test.yml, deploy-prod.yml, pr-checks.yml)
- [ ] Step 6: Generate infra/sql/migrations/000_migration_history.sql + 001_create_items_table.sql
- [ ] Step 7: Verify naming consistency — every resource uses {org}-{project}-{component}-{env}
- [ ] Step 8: Run cost-guardrails audit before first deploy (skill: applying-azure-cost-guardrails)

Before starting, collect

  1. org — short org/company prefix (e.g. acme)
  2. project — short app name (e.g. taskapp)
  3. GitHub repo — owner/repo-name
  4. Components needed — SQL? Storage? Observability? FC1? Container Apps?

Files to generate

For a basic SWA + SQL project:

infra/
├── main.bicep
├── environments/
│   ├── test.parameters.json
│   └── prod.parameters.json
├── modules/
│   ├── resourceGroup.bicep
│   ├── staticWebApp.bicep
│   └── sqlServer.bicep
└── sql/migrations/
    ├── 000_migration_history.sql
    └── 001_create_items_table.sql
.github/workflows/
├── deploy-test.yml
└── deploy-prod.yml

Add modules only when their toggle is true.

The modular toggle pattern

main.bicep exposes boolean params for each optional component. Every project provisions the resource group + SWA; everything else is opt-in:

@allowed(['test', 'prod'])
param environment string

param deploySql bool = true
param deployStorage bool = false
param deployObservability bool = false
param deployContainerApp bool = false

module sqlServer 'modules/sqlServer.bicep' = if (deploySql) { ... }
module storage 'modules/storageAccount.bicep' = if (deployStorage) { ... }
module ai 'modules/applicationInsights.bicep' = if (deployObservability) { ... }

Outputs that depend on optional modules use the ! non-null assertion guarded by the boolean:

output appInsightsConnectionString string = deployObservability ? ai!.outputs.connectionString : ''

See references/modular-toggles.md for the complete pattern.

Naming formula

{org}-{project}-{component}-{env} — see references/naming-formula.md.

Set org and project once in infra/environments/{env}.parameters.json and every resource name cascades.

Per-environment SKU selection

Test environments run on free / smallest tiers; prod gets the paid SKU only where needed:

module swa 'modules/staticWebApp.bicep' = {
  params: {
    skuName: environment == 'prod' ? 'Standard' : 'Free'
  }
}

See references/per-env-sku.md.

Critical rules

  • main.bicep is targetScope = 'subscription' — needed so it can create the RG.
  • Modules are RG-scoped — scope: resourceGroup(rgName) + dependsOn: [rg].
  • .parameters.json not .bicepparam — the workflow injects the SQL password via --parameters sqlAdminPassword=... which .bicepparam doesn't support.
  • SWA location is eastasia, hard-coded as var swaLocation = 'eastasia'. Everything else uses location param (defaults australiaeast).
  • SQL connection string never output — construct it inside main.bicep, pass to SWA module as @secure() param.
  • Bicep self-reference for app URLs — use 'https://${swa.properties.defaultHostname}' for APP_BASE_URL; no parameter needed.

Workflow templates

The workflow files in templates/.github/workflows/ include:

  • OIDC login via azure/login@v2
  • Conditional Bicep: git diff checks infra/ paths, skips Bicep + migrations on code-only pushes (saves 3–5 min/run)
  • SWA token fallback: when Bicep is skipped, fetches the SWA deployment token via az staticwebapp secrets list
  • SQL password masked with ::add-mask::

See the deployment workflow files in templates/.github/workflows/ for the complete pattern.

Composes with

Templates included

FilePurpose
templates/infra/main.bicepSubscription-scoped root with modular toggles
templates/infra/modules/resourceGroup.bicepRG creation
templates/infra/modules/staticWebApp.bicepSWA with per-env SKU
templates/infra/modules/sqlServer.bicepSQL Server + Serverless DB
templates/infra/environments/test.parameters.jsonTest env params
templates/infra/environments/prod.parameters.jsonProd env params
templates/.github/workflows/deploy-test.ymlTest deploy workflow
templates/.github/workflows/deploy-prod.ymlProd deploy workflow

What ships with it: 11 files

19.5 KB alongside SKILL.md

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.