Week 14 - Infrastructure as Code
Why use Infrastructure as Code
This page is optional. Nothing here is required for Week 14's learning goals or the assignment. Back to the Going Further overview.
Week 14 gives you one safety net before a deploy: what-if. Real templates get three more, and two of them run without touching Azure at all. In rough order of how early they catch a mistake:
| Check | Needs Azure? | Catches |
|---|---|---|
az bicep build |
No | Syntax errors, unknown properties, bad API versions |
| Bicep linter | No | Best-practice violations, unused parameters, hardcoded secrets |
az deployment group validate |
Yes | Template plus parameters against the real subscription |
az deployment group what-if |
Yes | What would actually change on the resources you have |
The linter is already running. It is built into the Bicep CLI and the VS Code extension, so az bicep build prints its findings whether you ask or not. You met it on the assignment: the deliberately unused @secure() parameter produces
Warning no-unused-params: Parameter "dbAdminPassword" is declared but never used.
The default rule set is small and mostly set to warning level. A few that matter for this week's habits:
| Rule | What it is telling you |
|---|---|
no-unused-params |
A parameter nobody reads. Usually a leftover from an edit. |
secure-parameter-default |
A @secure() parameter with a literal default. That default lands in git. |
outputs-should-not-contain-secrets |
An output that would publish a secret into deployment history. |
adminusername-should-not-be-literal |
A username hardcoded instead of parameterised. |
use-parent-property |
Build nesting with parent: rather than string-concatenated names. |
prefer-interpolation |
Use '${a}-${b}' instead of concat(). |
Three of those six are secret-hygiene rules, which is a fair signal about the mistake Azure sees most often.
When a warning is genuinely wrong for your file, suppress that line and leave the rule on everywhere else:
@secure()
#disable-next-line no-unused-params
param dbAdminPassword string
The directive must sit directly above the param line, not above @secure(). Bicep reports the diagnostic on the param line, so a directive above the decorator silences the wrong line and the warning still prints.
To change a rule everywhere, add a bicepconfig.json next to your templates:
{
"analyzers": {
"core": {
"rules": {
"no-unused-params": {
"level": "off"
}
}
}
}
}
Levels are off, warning, or error. Setting a rule to error is how a team makes az bicep build fail a pull request on it, which is the point of running the build step in CI at all.
validate versus what-ifThese two look similar and answer different questions.
az deployment group validate sends the template and your parameters to Azure and asks "would this deployment be accepted?". It catches a missing required parameter, a name that breaks a service's rules, a resource type your subscription cannot use. It does not tell you what would change.
az deployment group validate \
--resource-group "$CLASS_RG" \
--template-file main.bicep \
--parameters storageName=sthyf<yourname> environment=dev dbAdminPassword=not-a-real-secret
az deployment group what-if assumes the template is valid and shows you the diff against what is deployed. That is the one the week teaches, because on shared infrastructure the dangerous question is not "is my syntax right" but "what am I about to change".
A CI pipeline usually runs build, then validate, then what-if on the pull request, so a broken template fails in seconds without waiting for an Azure round trip.
<aside>
💡 Using AI to help: an LLM will happily invent Bicep properties and API versions that do not exist. az bicep build is the cheapest way to catch that, because unknown properties fail at compile time before you spend a deploy on them. (⚠️ no real data, no PII)
</aside>
bicepconfig.json syntax.The HackYourFuture curriculum is licensed under CC BY-NC-SA 4.0 https://hackyourfuture.net/

Built with ❤️ by the HackYourFuture community · Thank you, contributors
Found a mistake or have a suggestion? Let us know in the feedback form.