Skip to content

Lifecycle

Agoraform v0.6.0 mutations are create, update, and explicit destroy/remove. apply does not delete remote resources. Removing a resource from the manifest does not prune it.

New resources:
validate -> plan -> apply -> plan
Existing resources:
import -> add/review generated config -> plan
Managed resources:
destroy

agoraform validate loads the manifest and checks:

  • YAML and apiVersion
  • provider names and provider-specific configuration
  • resource address syntax and duplicates
  • $ref and { $ref, output } validity and dependency cycles
  • registered provider and resource support
  • provider connectivity
  • provider-specific resource fields
  • managed-container versus MATOMO_CONTAINER_ID exclusivity

It may contact providers. It does not mutate them.

agoraform plan compares desired manifest state with provider-reported remote state and prints deterministic actions. It is non-mutating.

When a manifest resource has no local state binding, some provider/resource types may match an existing remote object through provider-specific discovery. If the match already satisfies the manifest, plan may report no changes even without a state entry; that does not make the resource managed. Otherwise an unbound resource with no remote match becomes a create. A bound identity missing remotely is a stale-state error rather than an implicit replacement. Remote objects not represented in the manifest are ignored. See agoraform plan for details.

Some desired states require provider-level convergence after resource CRUD. These actions are still part of the reviewed plan. Matomo Tag Manager publication can appear as:

> matomo.container.main: publish -> live [conditional]

When MATOMO_CONTAINER_ID selects an existing container, the same action is addressed as matomo.container.external.

Conditional provider actions still count as planned work. A plan containing only a provider action still exits with code 2.

ActionMeaning
createDesired resource is absent remotely
updateConfigurable attributes differ
unchangedDesired and comparable remote state match
adoptGoogle Ads customer conversion goals are created by Google Ads; Agoraform binds and reconciles them
destroy / removePlanned only by agoraform destroy, not by plan/apply

plan and apply never delete remote resources.

agoraform apply builds the same reviewed plan and executes it:

  1. Validate and configure providers
  2. Build the resource and provider-action plan
  3. Apply resource creates and updates in prerequisite-first order
  4. Persist identities in agoraform.state.json
  5. Run provider finalization (for example Matomo publication) only after every resource mutation succeeds

Address-only $ref values resolve to the prerequisite’s runtime binding. { $ref, output } selectors resolve to one declared non-sensitive named output after that prerequisite converges. Missing, sensitive, unknown, and wrong-kind outputs fail before the dependent mutation.

Failed mutations do not create new bindings. Provider finalization is not attempted after a resource or required state-persistence failure. Successful remote changes are not rolled back.

If a create succeeds but the state file cannot be written, re-bind with agoraform import after fixing the file. A later unchanged plan does not repair a missing binding.

agoraform import ADDRESS REMOTE-ID reads one existing remote object, prints configurable YAML, and persists the identity. It never creates, updates, or deletes the remote resource and does not rewrite your manifest.

Import related Tag Manager triggers and variables before a tag so $refs can be reconstructed. Import a managed matomo.container before children when you want those children to reconstruct container: { $ref }. Import a Google Ads conversion action before a Matomo Google Ads conversion tag so { $ref, output } can be reconstructed on a unique match.

agoraform destroy plans supported destructions in reverse dependency order, requires interactive confirmation or --auto-approve, and removes local state only after a confirmed remote terminal or already-absent result.

Unsupported and provider-owned resources remain in state and do not block supported teardown. Destroy then exits non-zero while those remnants remain. See destroy.

agoraform.state.json maps logical addresses to provider-native IDs:

{
"version": 1,
"resources": {
"matomo.goal.trial_started": {
"provider": "matomo",
"remoteId": "12"
}
}
}

The v0.6.0 state schema is unchanged from v0.5.0. Plan reads bound objects by identity, not by mutable name. See project structure.