ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

Bicep Resource Loops with Dynamic Tagging

Bicep

Goal -- WPM

Ready
Exercise Algorithm Area
1param resourceNamePrefix string
2param location string = deployment().location
3param instanceCount int
4param tagsArray array = [] // Array of objects like { key: 'Name', value: 'Value' }
5
6// Validate that instanceCount is positive
7@minValue(1)
8param instanceCountValidated int = instanceCount
9
10// Validate that tagsArray is not empty
11@minLength(1)
12param tagsArrayValidated array = tagsArray
13
14// Helper to generate a unique name for each resource instance
15func generateResourceName(baseName string, index int) string {
16return '${baseName}-${index}'
17}
18
19// Helper to convert the array of tag objects into a Bicep map
20// Handles potential null or undefined values gracefully.
21func convertTagsToMap(tags array) object {
22var tagMap = {}
23// Iterate through the provided tags array
24for tag in tags {
25// Ensure tag object has 'key' and 'value' properties and they are not null/undefined
26if tag.key != null && tag.value != null {
27// Assign the tag to the map, ensuring the key is a string
28set tagMap[string(tag.key)] = tag.value
29} else {
30// Log a warning or throw an error for invalid tag format
31// For simplicity, we'll skip invalid tags here.
32// In a production scenario, consider throwing an error.
33trace('Warning: Skipping invalid tag format: ${tag}')
34}
35}
36return tagMap
37}
38
39// Generate the tag map once to avoid repeated computation within the loop
40var resourceTags = convertTagsToMap(tagsArrayValidated)
41
42// Deploy multiple storage accounts using a for loop
43resource storageAccounts 'Microsoft.Storage/storageAccounts@2021-09-01' = [for i in range(0, instanceCountValidated) {
44name: generateResourceName(resourceNamePrefix, i)
45location: location
46sku: {
47name: 'Standard_LRS'
48}
49kind: 'StorageV2'
50properties: {
51// Basic properties for a storage account
52}
53tags: resourceTags // Apply the generated tag map to each instance
54}]
55
56// Output the names of the deployed storage accounts
57output deployedStorageAccountNames array = [for i in range(0, instanceCountValidated) {
58name: storageAccounts[i].name
59}]
60
61// Output the generated tag map for verification
62output generatedTagMap object = resourceTags
63
64// --- Additional Helper Functions for Robustness ---
65
66// Function to validate the structure of individual tag objects
67// Ensures 'key' and 'value' exist and are of expected types (string).
68func validateTagObject(tag object) bool {
69if tag == null {
70return false
71}
72if !isString(tag.key) || !isString(tag.value) {
73return false
74}
75return true
76}
77
78// Function to process and validate the entire tags array
79// Returns a validated array or throws an error if invalid tags are found.
80func processAndValidateTags(tags array) array {
81var validatedTags = []
82for tag in tags {
83if validateTagObject(tag) {
84add validatedTags to tag
85} else {
86// Throw an error for malformed tags
87error('Invalid tag format detected. Each tag must be an object with string "key" and "value" properties.')
88}
89}
90// Ensure at least one valid tag exists after processing
91if length(validatedTags) == 0 {
92error('No valid tags provided. The tags array must contain at least one valid tag object.')
93}
94return validatedTags
95}
96
97// Re-process tags using the robust validation function
98var validatedResourceTags = processAndValidateTags(tagsArrayValidated)
99
100// Re-apply the validated tag map to storage accounts
101resource storageAccountsValidated 'Microsoft.Storage/storageAccounts@2021-09-01' = [for i in range(0, instanceCountValidated) {
102name: generateResourceName(resourceNamePrefix, i)
103location: location
104sku: {
105name: 'Standard_LRS'
106}
107kind: 'StorageV2'
108properties: {
109// Basic properties for a storage account
110}
111tags: validatedResourceTags // Apply the validated tag map
112}]
113
114// Output the names of the deployed storage accounts (validated)
115output deployedStorageAccountNamesValidated array = [for i in range(0, instanceCountValidated) {
116name: storageAccountsValidated[i].name
117}]
118
119// Output the validated tag map for verification
120output validatedTagMap object = validatedResourceTags
Algorithm description viewbox

Bicep Resource Loops with Dynamic Tagging

Algorithm description:

This Bicep module demonstrates deploying multiple identical resources using a `for` loop and applying dynamic, validated tags to each instance. It includes helper functions for generating resource names and converting an array of tag objects into the required Bicep map format. The module also features robust validation for the input tag array and individual tag objects, ensuring data integrity. A practical use case is provisioning a fleet of identical resources, such as web servers or databases, where each needs consistent, but potentially unique, metadata for management and cost allocation.

Algorithm explanation:

The module utilizes Bicep's `for` loop construct to iterate over a range, creating multiple instances of `Microsoft.Storage/storageAccounts`. The `generateResourceName` helper function ensures each instance has a unique name. The core logic lies in `convertTagsToMap` and `processAndValidateTags`, which transform an input array of tag objects into a Bicep object suitable for the `tags` property, while also performing validation. The `processAndValidateTags` function iterates through the input, checks each tag object for valid `key` and `value` properties (ensuring they are strings), and throws an error if any are malformed or if the array is empty after validation. This ensures that only correctly formatted tags are applied. The time complexity is dominated by the loop, which runs `instanceCount` times, and the tag processing, which is linear with respect to the number of tags. Space complexity is proportional to the number of resources deployed and the size of the tag map. Edge cases handled include an empty `tagsArray`, malformed tag objects (missing `key` or `value`, or incorrect types), and a non-positive `instanceCount` (via `@minValue`).

Pseudocode:

Define input parameters: resource name prefix, location, instance count, and an array of tag objects.
Validate that the instance count is at least 1.
Validate that the tags array is not empty.
Create a helper function to generate a unique resource name based on a prefix and an index.
Create a helper function to convert an array of tag objects into a Bicep map, validating each tag object's structure (key and value are strings).
Create a robust helper function to process and validate the entire tags array, throwing errors for invalid formats or if no valid tags remain.
Generate a validated tag map using the robust helper function.
Use a `for` loop to deploy multiple storage accounts, applying the generated resource name and the validated tag map to each instance.
Output the names of the deployed storage accounts.
Output the validated tag map for verification.