Lifecycle Overview
A resource instance moves through several provider method calls:State Values Through Lifecycle
Different state representations flow through the lifecycle:- Configuration
- Prior State
- Proposed New State
- Planned State
- New State
User-written values from
.tf files.- Null for unspecified optional attributes
- May contain unknown values (from other resources)
- Type-converted to match schema
docs/resource-instance-change-lifecycle.md
Phase 1: Previous Run State
When Terraform starts, it has the Previous Run State from the last operation.UpgradeResourceState
Handles provider version upgrades: Provider responsibilities:- Accept raw state data (any format)
- Identify schema version
- Transform to current schema
- Do not detect external changes
- Do not call external APIs
docs/resource-instance-change-lifecycle.md:224
ReadResource
Detects external changes (drift): Provider must distinguish:- Normalization
- Drift
Same meaning, different representationAction: Return state value unchanged (preserve user’s format)Rationale: Avoid spurious diffs from whitespace/formatting
- Write-only attributes: Cannot detect drift (e.g., passwords)
- Resource deleted: Return null state
- Partial read failure: Return best-effort state + diagnostics
docs/resource-instance-change-lifecycle.md:252
Phase 2: Planning
Planning happens in two calls toPlanResourceChange.
First PlanResourceChange (Planning Phase)
Called duringterraform plan:
Inputs:
prior_state: Current infrastructure stateproposed_new_state: Terraform Core’s merge suggestionconfig: User configuration (may have unknown values)
- Preserve non-null config values exactly
- Use proposed_new_state as starting point
- Mark unpredictable attributes as unknown
- Return known values where possible
- Indicate required replacements via
requires_replace
- Non-null config values must appear unchanged in plan
- Null optional+computed attributes may be set to any value
- Planned known values cannot change in
ApplyResourceChange
docs/resource-instance-change-lifecycle.md:134
Second PlanResourceChange (Apply Phase)
Called duringterraform apply before applying:
Differences from first call:
- All config values are known (dependencies applied)
- Can refine previous unknowns to known values
- Can replace unknowns with better unknowns (refinements)
- Cannot change previously known values
- Known values from initial plan must be identical
- Unknown values can become known or stay unknown
- Unknown values can gain refinements
docs/resource-instance-change-lifecycle.md:160
Phase 3: Applying
ApplyResourceChange
Executes the planned change: Provider must:- Make actual infrastructure changes
- Preserve all known values from
planned_state - Replace unknown values with actual results
- Return all-known state (no unknowns allowed)
- Return error if actual result doesn’t match plan
- Return partial new state showing what was created
- Include diagnostics explaining failure
- Terraform saves partial state for recovery
docs/resource-instance-change-lifecycle.md:188
Special Cases
Import Workflow
Adopting existing infrastructure: ImportResourceState responsibilities:- Accept provider-defined ID string
- Query external system
- Return minimal state for
ReadResourceto complete - May return partial state for write-only attributes
password to configuration to match imported resource.
See: docs/resource-instance-change-lifecycle.md:318
Replace Triggered By
Forced replacement due to triggers:aws_ami.latest changes:
- Terraform marks
aws_instance.examplefor replacement PlanResourceChangereceives indication of forced replacement- Provider plans destroy + create even if config unchanged
Create Before Destroy
Minimize downtime during replacement:- Create new instance
- Update dependencies to point to new instance
- Destroy old instance
Validation Rules
Terraform enforces contracts at each phase:ValidateResourceConfig
- Should tolerate unknown values
- Report errors for definitely-invalid configs
- May return warnings for potentially-invalid configs
PlanResourceChange
- Config Values
- Computed Values
- Plan Consistency
docs/resource-instance-change-lifecycle.md:143
ApplyResourceChange
docs/resource-instance-change-lifecycle.md:202
Nested Blocks
Blocks have special rules:- Number of blocks fixed during planning
- Cannot add/remove blocks during apply
- Each block must have corresponding planned block
docs/resource-instance-change-lifecycle.md:296
Further Reading
Plugin Protocol
RPC method specifications
Graph Evaluation
How resources are scheduled