# Bicep

> Azure Bicep IaC patterns, parameterization, security, and modular design

- Skill: `yldgio/bicep` (Agent Skill)
- Install (CLI): `npx skillmds add yldgio/bicep`
- Raw SKILL.md: https://api.skillmd.com/api/skills/yldgio/bicep/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: yldgio (https://skillmd.com/u/yldgio)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/yldgio/bicep

---


## Bicep Code Review Rules

### Security (Critical)
- **Input Validation**: Always escape or validate user-provided strings using regex validation or built-in Bicep functions before using them in resource names, tags, and outputs. Outputs must never directly include untrusted input
- **Comment Hygiene**: Never use HTML comments (`<!-- -->`) or expose template variables (e.g., `{{ }}`) in outputs, as these can enable injection or phishing attacks
- Never hardcode secrets, connection strings, or keys
- Use Key Vault references for secrets
- Apply least privilege to managed identities
- Enable diagnostic settings for auditing
- Use private endpoints where available
- Enforce encryption at rest for all supported resources
- Validate Azure Policy compliance for resources
- Check regulatory standards compliance (HIPAA, PCI-DSS, etc.)

### Parameters (Essential)
- Use parameters for values that vary between deployments
- Mark sensitive parameters with `@secure()` decorator
- Provide `@description()` for all parameters
- Use `@allowed()` for constrained values
- Set sensible `@minLength()`, `@maxLength()`, `@minValue()`, `@maxValue()`
- Provide default values where appropriate to reduce required inputs

### Parameters (Advanced)
- Validate complex parameter types with parameter constraints, assertions, or custom validation logic
- Document parameter purpose and expected values
- Consider using parameter files for environment-specific configurations

### Resource Naming (Essential)
- Use consistent naming convention
- Include environment, region, workload in names
- Use `uniqueString()` for globally unique names
- Follow Azure naming rules and restrictions

### Resource Tagging (Essential)
- Tag all resources with standard tags (owner, environment, cost center)
- Use consistent tag naming conventions

### Resource Tagging (Advanced)
- Include tags for governance (compliance, data classification)
- Define required tags in policy and enforce them
- Reference Azure naming documentation for governance tags and enforcement via policies

### Modules
- Break down large templates into modules
- One module per logical resource group
- Use outputs to pass values between modules
- Store shared modules in a registry

### Best Practices
- Use `existing` keyword to reference existing resources
- Use `dependsOn` only when implicit dependencies aren't enough
- Prefer symbolic names over `resourceId()` functions
- Use loops (`for`) instead of copy-paste for similar resources
- Include template metadata block with author, version, and docs
- Use meaningful error messages with `assert()` for validation

### API Version Management
- Avoid deprecated or preview resource API versions unless justified
- Document reasons for using preview features

### Outputs
- Output only values needed by other templates/scripts
- Mark sensitive outputs with `@secure()` (Bicep handles this)
- Include resource IDs for downstream references

### Example Patterns
```bicep
@description('Environment name')
@allowed(['dev', 'staging', 'prod'])
param environment string

@description('SQL admin password')
@secure()
param sqlAdminPassword string

metadata description = 'Azure Storage Account with Key Vault integration'
metadata author = 'Infrastructure Team'
metadata version = '1.0.0'

var baseName = 'myapp-${environment}-${uniqueString(resourceGroup().id)}'
var commonTags = {
  environment: environment
  owner: 'infrastructure-team'
  costCenter: 'IT-001'
}

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: '${baseName}sa'
  location: resourceGroup().location
  tags: commonTags
  sku: { name: 'Standard_LRS' }
  kind: 'StorageV2'
  properties: {
    minimumTlsVersion: 'TLS1_2'
    supportsHttpsTrafficOnly: true
  }
}
```

