Agent skill
convert-loose-to-strong-type
Converts loosely typed Bicep parameters using object or array to strongly typed alternatives like string[], user-defined types, or resource-derived types. Use when user mentions type safety, weak typing, object parameters, array parameters, resourceInput, resourceOutput, or asks to improve parameter definitions.
Install this agent skill to your Project
npx add-skill https://github.com/johnlokerse/azure-bicep-github-copilot/tree/main/.github/skills/convert-loose-to-strong-type
SKILL.md
Converting to Strong Types
Replaces loose object and array parameter types with strong alternatives for compile-time validation and autocompletion.
Conversion Workflow
-
Identify loose types
- Search for
param <name> objectandparam <name> arraydeclarations.
- Search for
-
Analyze parameter usage
- Examine how the parameter is used in the template to determine expected structure.
-
Choose conversion strategy
| Pattern | Strategy |
|---|---|
| Array of primitives | string[], int[], bool[] |
| Array with constrained values | ('value1' | 'value2')[] |
| Object matching resource property | resourceInput<'Type@Version'>.properties.X |
| Custom object structure | User-defined type with type keyword |
| Array of objects | User-defined type with [] suffix |
-
Define types and update parameters
- Place type definitions above parameters.
-
Validate
- Run command
bicep build <.bicep file> --stdout --no-restoreto verify syntax and type correctness.
- Run command
Quick Reference
Simple Arrays
// Before
param addresses array
// After
param addresses string[]
Union Types (Constrained Values)
param environments ('dev' | 'staging' | 'prod')[]
param skuName 'Standard_LRS' | 'Premium_LRS'
User-Defined Types
type subnetType = {
name: string
addressPrefix: string
nsgId: string? // Optional property
}
param subnets subnetType[]
Type Best Practices
- Use
?for optional properties:description: string? - Use
@sealed()to prevent extra properties at deployment - Use
@description()on types and properties - Use constraints:
@minLength(),@maxLength(),@minValue(),@maxValue() - Compose complex types from simpler types
MCP Tools
| Tool | Purpose |
|---|---|
Bicep:get_bicep_best_practices |
Current best practices |
Bicep:get_az_resource_type_schema |
Schema for resource-derived types |
Bicep:list_az_resource_types_for_provider |
Available types and API versions |
Bicep:list_avm_metadata |
Metadata for Azure Verified Modules |
Edge Cases
Dynamic objects (unknown keys): Use wildcard { *: string }
Mixed-type arrays: Use union (string | int | bool)[]
Optionality and backwards compatibility: Use optional types ? for new properties
Resource-Derived Types
Use resourceInput<> and resourceOutput<> to derive types directly from Azure resource schemas. Prioritise this approach over custom user-defined types.
Syntax
resourceInput<'<resourceType>@<apiVersion>'> // Writable properties
resourceOutput<'<resourceType>@<apiVersion>'> // Readable properties (includes computed)
When to Use
- Parameter must match resource property structure exactly
- Want to avoid maintaining custom types that mirror resource properties
Examples
Full Properties Block
param storageAccountProps resourceInput<'Microsoft.Storage/storageAccounts@2023-01-01'>.properties = {
accessTier: 'Hot'
minimumTlsVersion: 'TLS1_2'
allowBlobPublicAccess: false
supportsHttpsTrafficOnly: true
}
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: 'mystorageacct'
location: resourceGroup().location
sku: { name: 'Standard_LRS' }
kind: 'StorageV2'
properties: storageAccountProps
}
Output Types
output endpoints resourceOutput<'Microsoft.Storage/storageAccounts@2024-01-01'>.properties.primaryEndpoints
Do not do this
Do not use a type definition for resource-derived types but define them directly in parameters or outputs.
type managedRulesDefinitionType = resourceInput<'Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies@2024-07-01'>.properties.managedRules
type customRulesType = resourceInput<'Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies@2024-07-01'>.properties.customRules
type policySettingsType = resourceInput<'Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies@2024-07-01'>.properties.policySettings
type wafPolicyTagsType = resourceInput<'Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies@2024-07-01'>.tags
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
convert-bicep-to-avm
Converts Bicep resource definitions to Azure Verified Modules (AVM). Use when user asks to convert to AVM, replace resources with modules, use verified modules, or modernize bicep templates.
format-bicep
Format Bicep code for readability and consistency.
run-bicep-in-console
Validates Bicep functions using bicep console with piped input. Use when user asks to test, validate, or run Bicep functions, or wants to verify function behavior with test cases.
obsidian-vault
Search, create, and manage notes in the Obsidian vault with wikilinks and index notes. Use when user wants to find, create, or organize notes in Obsidian.
edit-article
Edit and improve articles by restructuring sections, improving clarity, and tightening prose. Use when user wants to edit, revise, or improve an article draft.
handoff
Compact the current conversation into a handoff document for another agent to pick up.
Didn't find tool you were looking for?