$ run as a normal user# run as root (or with sudo)
Skills in this chapter
- Install, version and use providers (also several)
Install and pin providers
Declare providers in required_providers with a source and a version constraint. terraform init downloads them and writes the exact versions into .terraform.lock.hcl.
terraform {
required_version = ">= 1.12"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.20"
}
random = {
source = "hashicorp/random"
version = ">= 3.6, < 4.0"
}
}
}| Constraint | Allows |
|---|---|
= 4.20.0 | Only this version |
>= 4.20 | This and newer |
~> 4.20 | 4.20 and newer 4.x (not 5.0) |
~> 4.20.1 | 4.20.1 and newer 4.20.x |
>= 3.6, < 4.0 | A range |
Remember
Commit .terraform.lock.hcl to Git, so every person and the pipeline use the same provider versions. Do not commit the .terraform/ folder.
Know how Terraform uses providers
A provider turns resources in your code into API calls (create, read, update, delete). Each provider brings its own resource types and data sources.
- Names are
TYPE_NAME:azurerm_virtual_network,aws_s3_bucket,kubernetes_namespace. - The source address is
HOSTNAME/NAMESPACE/TYPE—registry.terraform.io/hashicorp/azurerm(the hostname is usually left out). - Tiers in the Terraform Registry: official (HashiCorp), partner, community.
Use several providers and aliases
One configuration can use many providers — and the same provider several times with different settings, using an alias.
provider "azurerm" {
features {}
subscription_id = var.sub_prod
}
provider "azurerm" {
alias = "dr"
features {}
subscription_id = var.sub_dr
}
resource "azurerm_resource_group" "dr" {
provider = azurerm.dr
name = "rg-web-dr"
location = "northeurope"
}Exam tip
Without provider = …, a resource uses the default (un-aliased) provider of its type.
Log in providers safely
Never write passwords or keys in .tf files. Use the platform's normal login or environment variables.
In pipelines, use OIDC (workload identity federation): no secret is stored at all — see Deploy to Azure with OIDC.
Understand state
Terraform saves what it created in a state file (terraform.tfstate): the mapping between your code and the real resource IDs, plus their attributes.
| State is used to | Example |
|---|---|
| Map code to real objects | azurerm_resource_group.web = /subscriptions/…/resourceGroups/rg-web-dev |
| Know what to change or delete | A resource removed from code → destroy it |
| Speed up plans | Cached attributes |
| Track dependencies | Destroy in the right order |
Watch out
State can contain secrets in plain text (passwords, keys). Store it in a protected remote backend, never in Git. More: Manage state.