Skip to content

plan

Terminal window
agoraform plan
agoraform plan -f path/to/manifest.yaml
agoraform plan path/to/manifest.yaml

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

The default manifest is agoraform.yaml.

Plan loads and validates the manifest, configures registered providers with non-secret provider desired state, validates connectivity, reads local identity state, and then reads desired resources in dependency order.

ArgumentDescription
[file]Optional positional path to the manifest. At most one argument.

Specify a manifest as an argument or with --file, not both.

FlagDescription
-f, --filePath to the Agoraform manifest (default agoraform.yaml)

When a manifest resource has no local state binding, planning behavior depends on the provider and resource type:

  • If the type does not support provider-side discovery, a missing remote match becomes a create.
  • Some types support unmanaged discovery: an unbound manifest resource may be matched to an existing remote object using provider-specific discovery or natural identity fields.
  • If discovery finds a remote object that already matches the manifest, agoraform plan may report No changes. even when the resource is not present in agoraform.state.json.
  • A successful no-op discovery does not make the resource managed. Lifecycle operations that require state — including agoraform destroy — still need an explicit state binding.
  • To manage an existing remote resource, including destroying it later, use agoraform import to establish the binding.

A bound identity missing remotely is a stale-state error rather than an implicit replacement. Provider normalizers may remove computed/default noise before diffing.

Remote objects that are not represented in the manifest are ignored. Destructive deletion is not part of plan or apply. Use agoraform destroy for teardown.

Example when discovery matches but there is no state binding:

manifest resource exists
matching remote resource exists
no local state binding
agoraform plan
→ No changes
agoraform destroy
→ resource is not managed and is not destroyed

Example resource changes:

Agoraform will perform the following actions:
+ matomo.goal.trial_started
name: "Trial Started"
matchAttribute: "event_action"
pattern: "trialStarted"
Plan: 1 to create, 0 to update, 0 to destroy.

Example with Matomo publication:

Agoraform will perform the following actions:
~ matomo.tag.trial_started
eventAction:
"trialStart" -> "trialStarted"
> matomo.container.main: publish -> live [conditional]
Plan: 0 to create, 1 to update, 0 to destroy, 1 provider action.

Zero change:

No changes. Desired configuration matches live resources.
Plan: 0 to create, 0 to update, 0 to destroy.

The 0 to destroy counter is present in plan output. plan and apply do not schedule destroy actions; only agoraform destroy does.

Matomo Tag Manager publication is part of the reviewed plan, not a separate command. If managed Tag Manager draft resources already have planned changes and providers.matomo.publish is enabled, publication is shown as conditional. The address is the managed matomo.container resource, or matomo.container.external when MATOMO_CONTAINER_ID selects an existing container. Apply rechecks the converged draft before creating a version.

A plan containing only a provider action still exits with code 2 because apply has work to do.

Permission and environment checks for Matomo publication happen during planning without creating a version.

CodeMeaning
0Plan succeeded and no actions are required
1Planning failed
2Plan succeeded and resource or provider actions are present
3Invalid invocation

Exit 2 is intended for CI/GitOps workflows that treat a non-empty plan as an actionable result rather than a failure.

  • Plan never calls provider mutation methods.
  • Plan ignores remote objects that are not represented in the manifest. Discovery without a state binding does not adopt remote objects.
  • Secrets are not written to plan output.