Providers & Resources
The machine-API bridge and its behaviors
Providers are SDKs from cloud APIs into Terraform's graph; resources map API objects. Understanding provider schema, resource behaviors (in-place vs force-new), and data sources is the difference between readable plans and 'why did it recreate?' mysteries.
What you will learn
- Explain provider + resource + data source roles
- Predict force-new vs in-place changes from a plan
- Import existing infra as data sources/resources
Providers translate HCL → provider API calls. Each resource type declares attributes and behaviors: mutable properties update in-place; structurally-identity attributes (name, availability zone at creation) force recreation. Data sources read existing infra without creating.
What is this?
Provider config: creds, region, aliases (multiple providers of same type for regions), required_providers + version. Resource lifecycles: create → read/update (in-place) → delete; ForceNew changes trigger delete+create (plan warns). Attributes: computed (provider fills), optional, required; sensitive. Data sources: data "aws_iam_policy" … existing without ownership. Import: adopt manual infra; then plan usually needs resource config tuned. Implicit vs explicit dependencies (references vs depends_on). Providers with custom hooks: kubernetes, helm, null, template. Multi-region aliases and provider-level defaults.
Why do you need it?
- Predictable plan behavior prevents ship-jumps: force-new waits visible in plan.
- Data sources read authoritative state (VPCs, AMIs) without re-defining reality.
- Provider aliases build multi-region layouts in one tree.
- Import brings pre-IaC pillage under code without recreating the world.
Mental model
Lego instruction API: each piece type knows how to snap and un-snap
Provider resource behaviors
Some bricks can be swapped without rebuilding (in-place update); others are glued into the structure — changing them means rebuilding that section (force-new). The instruction book (plan) tells you which.
How it works
- Provider config authenticates; init downloads the schema.
- Resource declaration → provider create/read/update/delete calls.
- Attributes carry flags (ForceNew) in the schema that drive plan decisions.
- Data sources execute read-only API calls at plan/apply time.
- Import maps a live resource id into state for a matching resource block.
Provider machinery.
Examples
Resource + data source + alias
provider "aws" { region = "us-east-1" }provider "aws" { alias = "west"; region = "us-west-2" } data "aws_ami" "ubuntu" { most_recent = true filter { name = "name"; values = ["ubuntu/images/hvm-ssd/*22.04*"] }} resource "aws_instance" "app" { provider = aws.west ami = data.aws_ami.ubuntu.id # read, not owned instance_type = "t4g.small" tags = { Name = "app" }}An AMI is read, an instance is owned, the provider is aliased per region — the three core provider patterns in one view.
In production
- Multi-region: shared module instantiated per region with aliased providers.
- Import legacy VPC/SG/roles then convert to code with reviewed plans.
- Data sources for AMIs, AZ numbers, or consumption of org-wide policies created elsewhere.
Best practices
- Pin provider versions; run terraform command hash-check on CI.
- Prefer computed defaults over guesswork; read provider docs for ForceNew flags.
- Import one resource at a time, always start with a plan that shows only that resource's clean state.
- Keep provider config in a central file (versions, common regions).
- Use multi-provider aliases sparingly; prefer modules that take providers as inputs.
Common mistakes
- Ignore the ForceNew column → every tag edit recreates the instance/disk.
- Recreating infra instead of importing: hurray, you've delivered an outage window to no one.
- Data sources resolving with wrong filters → wrong AMI/tier silently applied.
- Provider alias soup where a single region layout would do.
Debugging tips
- A plan recreating something → find the ForceNew attribute the change hits.
- Data source timing out → verify creds/source region/filters produce results.
- Import followed by plan garbage → your config doesn't match the live resource capital, tune block.
- Provider errors tunneling → upgrade provider and re-run; many are API payload changes.
Interview checkpoint
Hands-on lab
- Create a resource whose tag edits are in-place
- Change a force-new attribute and see recreation in plan
- Import one hand-created resource under code
Watch Force-New vs In-Place on a Resource
35 min · intermediate
Quick quiz
A ForceNew attribute change appears in plan as:
Adopting a pre-existing resource into Terraform uses: