Infrastructure as Code (Pulumi)
Infrastructure built by hand in a portal is undocumented, hard to reproduce, and impossible to review. Nobody fully understands it until it breaks. Defining infrastructure as code makes the environment a versioned, reviewed, repeatable artifact. The same inputs always produce the same infrastructure, and every change has an author and a diff.
We provision with Pulumi, which lets us define cloud resources in real code under source control. To make IaC valuable, treat that code exactly like application code: reviewed, tested, deployed through the pipeline, and never bypassed by manual portal changes. The payoff is reproducibility (rebuild an environment from scratch), auditability (every change is a reviewed commit), and consistency (dev, test, and prod differ only by parameters).
IaC is also a security surface. The code can set secure defaults: private networking, managed identity, the correct region, and least-privilege roles. This makes the whole estate secure by construction. But IaC state and definitions can also leak secrets or grant too much privilege if written carelessly. So the same rules about secrets and least privilege apply here as everywhere.
Define everything as reviewed code
- AlwaysProvision and manage all infrastructure through Pulumi in source control. Every resource, role, and network rule is versioned code, deployed via CI/CD. The only exception is purely experimental, throwaway resources that never touch real data or production.
- DoApply changes only through the pipeline. Review the plan or preview before you apply, so you see the diff before anything changes.
- DoParameterise per environment (region, sizing, names) from one definition, so environments stay consistent and differ only where intended.
- DoSet secure defaults in the IaC: private endpoints, managed identity, the correct region, and least-privilege roles. This way new resources start hardened.
- ConsiderPolicy-as-code (Azure Policy or Pulumi CrossGuard) to automatically reject non-compliant infrastructure (wrong region, public exposure) at deploy time.
- NeverMake production infrastructure changes by hand in the portal, outside IaC and change control.
- NeverHold or use standing direct edit or write access to deployed infrastructure (portal, CLI, or console). Changes go through Pulumi and CI/CD. Direct access causes drift and bypasses review. Break-glass access is the rare, time-bound, audited exception.
Manage state and secrets safely
- DoTreat Pulumi state as sensitive. Store it in a secure managed backend with restricted access, since it can contain resource details and secrets.
- DoGet any secrets the IaC needs from Key Vault or Pulumi's encrypted secrets. Never put them as plaintext in the code or in committed config.
- DoKeep infrastructure changes small and easy to review. On stateful resources, prefer additive, expand-contract changes over destructive ones.
- ConsiderDrift detection, so manual or out-of-band changes are caught and brought back into code.
- Do notHand-edit deployed resources and let them drift from the code. The code must remain the source of truth.
- NeverCommit secrets, connection strings, or keys into IaC source or unencrypted state.
new azure.sql.Database("db", { /* defaults: public access on */ });
const conn = "Server=...;Password=P@ss!"; // in the IaC source
A database left reachable from the public internet by default, and a secret committed to the repo. The infrastructure itself is now the vulnerability, and it is reproduced on every deploy.
new azure.sql.Server("sql", { location: "westeurope",
azureadAdministrator: { /* managed identity */ }, publicNetworkAccess: "Disabled" });
// secret read from Key Vault at runtime, not embedded
The region meets residency rules, public access is off, access is identity-based, and no secret lives in the code. It is secure by construction and reproducible.
Self-review checklist
- AskIs this infrastructure change in code and going through the pipeline, or done by hand?
- AskDid I review the preview/plan diff before applying?
- AskAre secure defaults (private, identity, region, least-privilege) encoded here?
- AskIs any secret sitting in the IaC source or unencrypted state?