Module & provider supply chain
Trust the code you did not write.
IaC runs code you mostly did not write — providers, community modules, Helm charts, base images — against your production infrastructure with high privilege, which makes it a supply-chain target just like application dependencies. A malicious or compromised module could exfiltrate your secrets during a plan, or quietly add a backdoor resource; a typosquatted provider could do the same. The supply-chain discipline from the CI/CD course applies directly to your infrastructure code: trust deliberately, pin everything, and verify what you can.
Pin and vet everything external
The foundation is pinning and provenance. Pin provider versions and commit the lock file (.terraform.lock.hcl), which also records the providers’ checksums so a tampered provider is rejected. Pin module versions to specific tags or commits, never a floating branch. Pin Helm chart versions and base image digests. And prefer sources you trust — official/verified providers and modules, your own internal registry for shared modules — over arbitrary community code, reviewing anything important before you run it. An unpinned, unvetted external module is untrusted code with production access.
# the lock file pins providers AND their checksums — commit it$ terraform providers lock -platform=linux_amd64$ cat .terraform.lock.hcl # version + h1: hashes; a tampered provider fails verification# pin modules to an immutable ref, not a branch:module "vpc" { source = "terraform-aws-modules/vpc/aws", version = "5.1.2" } # not "latest"
A private registry and least-privilege runs
At scale, teams run a private module registry (Terraform Cloud, or an internal one) as the single vetted source for shared modules, so everyone reuses reviewed code rather than pulling arbitrary sources — the infrastructure equivalent of a trusted internal package registry. And because IaC runs with powerful credentials, apply it with least privilege: scoped, short-lived credentials (OIDC), a locked-down runner, and separation between the plan (which needs read) and apply (which needs write) where you can. A compromised module can only do as much as the credentials the run holds.
The whole picture
Put the advanced section together and you have production-grade IaC: policy-as-code and scanners guard the code, GitOps applies it from Git with reviewed plans and no local credentials, drift detection keeps reality honest, testing proves modules work, secrets stay out of code and state is protected, and the supply chain is pinned and vetted. That is the difference between IaC as a convenience and IaC as a trustworthy, secure foundation — the same journey from "it works" to "it is safe and verifiable" that every track in this curriculum walks.