# pravo > An open study of the declarative layer of OpenTofu and Terraform, reimagined: per-resource state, scoped plans, policy and CUE, on the providers that already exist. ## Learn New to CUE or pravo? Lessons in order, with exercises. - [Learn](https://pravo.systems/learn/index.md): Two tracks in order. Track A teaches CUE from zero. Track B teaches pravo. Each lesson takes between 6 and 20 minutes. - [Your data is already CUE](https://pravo.systems/learn/a01-your-data-is-already-cue.md): A CUE file may contain plain JSON. You shorten it one piece of punctuation at a time, and the data never changes. - [A value can be a type](https://pravo.systems/learn/a02-a-value-can-be-a-type.md): In CUE, int and 30 are both values. One allows every integer and the other allows one. - [Writing a field twice](https://pravo.systems/learn/a03-writing-a-field-twice.md): Writing a field twice adds detail. The copies must agree, and a disagreement is an error, not an override. - [Order does not matter](https://pravo.systems/learn/a04-order-does-not-matter.md): Lines and files can come in any order. The result is the same, so there is no precedence list to learn. - [Constraints narrow a value](https://pravo.systems/learn/a05-constraints-narrow-a-value.md): A rule in CUE is a value written on the field. Bounds and regular expressions narrow what the field may hold. - [Choices and defaults](https://pravo.systems/learn/a06-choices-and-defaults.md): Offer a short list of values, mark one as the default, and select it from the command line. - [Required, optional, regular](https://pravo.systems/learn/a07-required-optional-regular.md): Decide for each field whether it must be supplied, may be supplied, or is a plain field. - [Definitions reject typos](https://pravo.systems/learn/a08-definitions-reject-typos.md): Write a shape once, build values from it, and let the shape refuse every field it does not declare. - [One rule for every entry](https://pravo.systems/learn/a09-patterns.md): Write a rule once for every entry of a collection with a pattern. Each entry states only what differs. - [Generating fields from data](https://pravo.systems/learn/a10-comprehensions.md): Build fields from a list or a struct with for. Choose keys that stay the same when the data is reordered. - [Naming a value once](https://pravo.systems/learn/a11-references-let-hidden.md): Use the value of one field in another. Keep helper values out of the output with let. Share them across files with hidden fields. - [Conditions and strings](https://pravo.systems/learn/a12-conditions-and-strings.md): Include a field only when a condition holds. Build strings from values. See why a condition needs a concrete value. - [Packages and the standard library](https://pravo.systems/learn/a13-packages-and-the-standard-library.md): Import validators and functions from the standard library, and share a definition between directories with your own package. - [Project, three environments from one definition](https://pravo.systems/learn/a14-project-three-environments.md): Write one specification from a brief. It runs in dev, staging and prod, is stricter in prod, and refuses every other environment. - [Reading a CUE error](https://pravo.systems/learn/c1-reading-a-cue-error.md): The four parts of a pravo error, the three stages that produce one, and the messages you meet first. - [Why is my value incomplete?](https://pravo.systems/learn/c2-why-is-my-value-incomplete.md): The three causes of an incomplete value, each with the error pravo prints, how to read it and the fix. - [Closed or open?](https://pravo.systems/learn/c3-closed-or-open.md): Which structs refuse a field they do not declare, how definitions combine, and the real errors when they do not. - [eval and validate](https://pravo.systems/learn/c4-eval-and-validate.md): What pravo eval and pravo validate check, what they print, and what the flags -c, -e and -O change. - [CUE cheat sheet](https://pravo.systems/learn/cue-cheat-sheet.md): Every construct of Track A on one page. Each has a short example and the output that pravo prints. - [Providers and resources](https://pravo.systems/learn/b01-providers-and-resources.md): A provider is a struct built from a generated definition. A resource is a struct built through it. Its address is its path. - [Reading a plan](https://pravo.systems/learn/b02-reading-a-plan.md): A plan is a diff with a legend. Learn the glyphs, unknown values, the replacement marker and the Graph line, then predict three plans. - [Apply, outputs, state](https://pravo.systems/learn/b03-apply-outputs-state.md): Apply a plan, read the outputs and open the state. A plan with no changes shows that a refactor changed nothing. - [Inputs, tags, environments](https://pravo.systems/learn/b04-inputs-tags-environments.md): Run one specification as dev, staging and prod. Use a constrained field, a tag and a state path derived from it. - [Many resources from one rule](https://pravo.systems/learn/b05-many-resources-from-one-rule.md): A comprehension produces resources. Each key becomes the last element of an address, so reordering the source replaces nothing. - [Modules, providers, credentials](https://pravo.systems/learn/b06-modules-providers-credentials.md): Share one definition between instances, pass a provider in as an input, and keep a credential out of the state. - [Changing live infrastructure](https://pravo.systems/learn/b07-changing-live-infrastructure.md): Save a plan, apply exactly that plan or nothing, and apply it in stages. Read the refusal when the plan is stale. - [Renames, moves, imports](https://pravo.systems/learn/b08-renames-moves-imports.md): Keep the object of a resource when its address changes, and adopt an object that already exists. - [Drift: find and reconcile changes](https://pravo.systems/learn/b09-drift.md): Change a resource outside pravo, find the change with pravo drift, and reconcile it in both directions. - [Policy on providers and on plans](https://pravo.systems/learn/b10-policy.md): A constraint on a provider binds every resource built through it, and a policy file judges what a plan does. - [Lab 1: break it](https://pravo.systems/learn/lab1-break-it-on-purpose.md): Cause ten failures one at a time and read each message. Match each failure to the exit code that a pipeline sees. - [Lab 2: two applies at once](https://pravo.systems/learn/lab2-two-applies-at-once.md): Run three applies against one state while one of them holds a lock. Read the locks and the log afterwards. - [Project: an estate in three environments](https://pravo.systems/learn/b11-project.md): Build three environments from one definition, with a policy, a secret, a drift check and a destroy. A script checks the outcomes. ## Migrate From OpenTofu or Terraform: a gated runbook, a concept map and a worked example. - [Migrate from OpenTofu or Terraform](https://pravo.systems/migrate/index.md): A gated path from an OpenTofu or Terraform project to pravo, with the promise it keeps, what it applies to, and three ways to go. - [Before you start](https://pravo.systems/migrate/m1-before-you-start.md): Make the OpenTofu plan empty, back up the state and the code, scan for constructs that need a decision, preview the conversion and write the recovery plan. - [Concept map](https://pravo.systems/migrate/m2-concept-map.md): Each OpenTofu construct, command and function beside its pravo equivalent, with one example for each group and the rows that have none. - [A worked example](https://pravo.systems/migrate/m3-worked-example.md): One stack with a module, a for_each, a remote output, a sensitive value and a moved history, translated by hand, converted and planned to empty. - [Translate the specification](https://pravo.systems/migrate/m4-translate-the-specification.md): Rewrite each OpenTofu construct as CUE in a fixed order, and check every step with pravo validate. - [Convert the state](https://pravo.systems/migrate/m5-convert-the-state.md): Convert the OpenTofu state into pravo records, point each record at its address, and plan until nothing changes. - [Rewrite the checks on plans](https://pravo.systems/migrate/m6-rewrite-plan-checks.md): Turn the CI checks that read the OpenTofu plan JSON into plan policies, and run both until they agree. - [Cut over](https://pravo.systems/migrate/m7-cut-over.md): Remove OpenTofu's claim on the objects, move the pipeline to pravo, order roots that share outputs, and archive the old state. - [Roll back](https://pravo.systems/migrate/m8-rollback.md): Where the migration can be undone by deleting the pravo files, and what to do after the first apply that changes an object. - [Pitfalls](https://pravo.systems/migrate/m9-pitfalls.md): Symptoms you may meet while you translate, convert and cut over, with the cause, the fix and the message as pravo prints it. - [Not in pravo: what to use instead](https://pravo.systems/migrate/m10-not-in-pravo.md): The OpenTofu features that pravo does not have, what to use in each case, and the parts of a state that the conversion does not carry over. - [After the migration](https://pravo.systems/migrate/m11-after-the-migration.md): Rewrite the faithful translation in the idiom of CUE, one idea per commit, and let a policy confirm that no commit changes an object. - [Function map](https://pravo.systems/migrate/function-map.md): Every OpenTofu built-in function, with the CUE expression that replaces it, or the statement that none does. - [Command map](https://pravo.systems/migrate/command-map.md): Each OpenTofu command, flag, environment variable and file beside the pravo command, flag, variable or file that replaces it. - [Construct matrix](https://pravo.systems/migrate/construct-matrix.md): Which OpenTofu constructs pravo supports, supports in part, or does not support, with the replacement for each. ## How-to You know the basics and need to do one thing. - [How-to](https://pravo.systems/how-to/index.md): Task-shaped pages for a reader who knows the basics. Each page shows how to do one thing and stops there. - [Quick start](https://pravo.systems/how-to/quick-start.md): Twelve minutes from install to a first plan, an apply, a conflict and a destroy. No account and no cloud. - [Run one specification in several environments](https://pravo.systems/how-to/environments.md): Select dev, staging or prod with a tag, keep the differences in one table and give each environment its own state. - [Share code between roots in one repository](https://pravo.systems/how-to/modules-in-a-repository.md): Keep shared modules in one repository, run one root per environment and see how a change to shared code reaches every root. - [Publish a module](https://pravo.systems/how-to/publishing-a-module.md): Create a module in a git repository, try it from an example, and publish a version to a registry that others can use. - [Use a published module](https://pravo.systems/how-to/using-a-module.md): Add a published module to a root, lock it, read an upgrade before you take it and know what happens in CI and offline. - [Keep the state in a shared bucket](https://pravo.systems/how-to/remote-state.md): Store the state in an S3 bucket so that a team shares it, move an existing local state into the bucket and read another root's outputs. - [Install providers from your own registry](https://pravo.systems/how-to/providers-from-a-registry.md): Copy a provider into a container registry, install it from there and move a root that has resources to the copy without touching them. - [Rename, move and adopt resources](https://pravo.systems/how-to/importing-and-moving.md): Rename a resource without recreating it, move a group of resources, adopt an object that already exists and forget one without destroying it. - [Run pravo in a pipeline](https://pravo.systems/how-to/ci.md): Validate without credentials, plan under a policy, apply a saved plan, find drift and test offline, with the exit code of every step. - [Write and roll out plan policies](https://pravo.systems/how-to/policies.md): Write a plan policy, test it on fixtures with the matching cue version, roll a new rule out as advice, exempt by type and name the policy in the apply job. - [Let an agent plan and apply](https://pravo.systems/how-to/agents-and-mcp.md): Give a program or an AI agent the schema, a plan file, a reservation and a tool server bound to a policy, and see what that does and does not protect. - [Keep secrets out of the state](https://pravo.systems/how-to/secrets.md): Read a secret from the environment with pravo.#SecretEnv, hand it to a provider and see where pravo allows the value and where it refuses. - [Find out why a run fails](https://pravo.systems/how-to/debugging.md): Read an evaluation error, ask pravo what it decided with -v, ask why a resource changes, check for drift and follow a run in a trace. - [Upgrade pravo and providers](https://pravo.systems/how-to/upgrading.md): Replace the pravo binary, move a provider to a newer version through the lock file, pin the archives of every platform and review the plan that follows. ## Concepts How pravo behaves, with diagrams. - [Concepts](https://pravo.systems/concepts/index.md): How pravo behaves, with diagrams. Each page explains one part of the system. - [How pravo works](https://pravo.systems/concepts/how-pravo-works.md): One run of pravo in seven stages, from the CUE files of a directory to the providers, the state and the output. - [Evaluation](https://pravo.systems/concepts/evaluation.md): How pravo turns the CUE files of a directory into one value, finds resources by identity and builds the dependency graph before any provider is asked anything. - [Resources and addresses](https://pravo.systems/concepts/resources-and-addresses.md): What makes a struct a resource, how its address is its path, and what renaming, moving or reordering does to the record of an object. - [Plans](https://pravo.systems/concepts/plans.md): What a plan contains, how pravo decides which resources a plan reaches, what an unknown value is, how refresh age works and how a saved plan is checked. - [State](https://pravo.systems/concepts/state.md): What pravo records for each resource, how revisions, locks and transactions work, why the cost of a run follows the change, and where the state lives. - [What a plan reaches](https://pravo.systems/concepts/what-a-plan-reaches.md): Change one setting, replace a root key, add a zone or run two applies on one estate, and see which resources each plan reaches and which locks each apply holds. - [Providers](https://pravo.systems/concepts/providers.md): How pravo finds, installs, locks, starts and talks to a provider, how a provider becomes a CUE struct, and how an instance is named. - [Policies: two moments, one idea](https://pravo.systems/concepts/policies.md): One idea at two moments: a constraint on a provider is checked at evaluation, a policy file against a plan. What each binds and what neither guarantees. - [Secrets and ephemeral values](https://pravo.systems/concepts/secrets-and-ephemeral-values.md): Which values pravo records in state, saved plans and outputs, what an ephemeral value is, where it may go, and what hiding a value does and does not do. ## Reference Lookup: one page per command and per specification topic. - [Reference](https://pravo.systems/reference/index.md): Lookup pages for every command, every field of a specification, plan policies, file formats and error messages. Each page opens with a table. - [pravo init](https://pravo.systems/reference/init.md): Install the providers a root needs, write the lock file and generate the CUE packages that a specification imports. - [pravo plan](https://pravo.systems/reference/plan.md): Show the actions that apply takes. A plan changes no infrastructure, and it can be saved, judged by a policy and applied later. - [pravo apply](https://pravo.systems/reference/apply.md): Plan, ask for confirmation and apply, or apply a saved plan exactly as it was reviewed, in whole or in closed parts. - [pravo destroy](https://pravo.systems/reference/destroy.md): Destroy every resource recorded in the state, dependents first, after a plan and a confirmation. - [pravo show](https://pravo.systems/reference/show.md): Print a saved plan, with the time, the command and the actor that made it, and a warning when it cannot be applied. - [pravo output](https://pravo.systems/reference/output.md): Print the output values that the last apply recorded in the state, as CUE or as JSON. - [pravo state](https://pravo.systems/reference/state.md): Inspect and edit the state graph: list, show, move or forget a node, read the log and the locks, copy the state, query it, convert an OpenTofu state file. - [pravo import](https://pravo.systems/reference/import.md): Bring an existing object under management from the command line, by the address of a declared resource and the provider's import id. - [pravo providers](https://pravo.systems/reference/providers.md): List the providers a root resolves, print a provider's schema, pin archive hashes for more platforms and copy a provider to a container registry. - [pravo validate, eval, fmt and gen](https://pravo.systems/reference/validate-eval-fmt-gen.md): Check a specification without planning it, print its evaluated value, format the CUE files and regenerate the provider packages. - [pravo schema](https://pravo.systems/reference/schema.md): Print the CUE definition of a resource, data source, ephemeral resource or function type, with the provider's documentation. - [pravo why and pravo drift](https://pravo.systems/reference/why-and-drift.md): Explain why a plan creates, changes, replaces or skips a resource, and read the records that a plan does not read to report what changed outside pravo. - [pravo mcp](https://pravo.systems/reference/mcp.md): Serve pravo to an agent over the Model Context Protocol on stdio. Thirteen tools, applies only from saved plans, and plan policies the agent cannot remove. - [pravo mod](https://pravo.systems/reference/mod.md): Create, fetch and publish CUE modules for sharing, list the modules a root loads and verify them against the lock file. - [pravo version](https://pravo.systems/reference/version.md): Print the version of pravo and the version of CUE that is built into it. - [Global flags, environment and exit codes](https://pravo.systems/reference/global-flags.md): The flags every pravo command accepts, the flags several commands share, the debug log, JSON output, the environment variables and where the exit codes are listed. - [The specification](https://pravo.systems/reference/spec-overview.md): What a root is, which constructs pravo reads from it, and the page that describes each one. - [Settings](https://pravo.systems/reference/spec-settings.md): The $settings block. It sets where the state lives and the default refresh age, and nothing else. - [Resources, data sources and calls](https://pravo.systems/reference/spec-resources.md): How to declare managed resources, data sources, ephemeral resources and function calls, how pravo finds them, and how they are addressed. - [Provider declarations](https://pravo.systems/reference/spec-providers.md): How to declare a provider, the $-fields that tell pravo how to obtain it, instance keys, and rules that bind every resource built through a provider. - [Moves and imports](https://pravo.systems/reference/spec-moves-and-imports.md): $from renames or moves a record to a new address. $import adopts an existing object. Both are fields of the resource they describe. - [Outputs](https://pravo.systems/reference/spec-outputs.md): pravo.#Output publishes a value. It is recorded in state when a plan is applied and printed by pravo output. - [Environment and remote outputs](https://pravo.systems/reference/spec-env.md): pravo.#Env and pravo.#SecretEnv read environment variables. pravo.#RemoteOutputs reads the outputs another root has recorded. - [Meta fields](https://pravo.systems/reference/spec-meta-fields.md): The $-prefixed fields that resources, data sources and ephemeral resources accept in addition to the provider schema. - [Tags and variables](https://pravo.systems/reference/spec-tags-and-variables.md): Inputs are fields with a @tag attribute. -t and -T inject their values. Defaults and constraints are plain CUE. - [Modules](https://pravo.systems/reference/spec-modules.md): A module is a CUE definition or package that contains resources. Instantiating it is enough. pravo finds the resources inside the instance. - [Generated packages](https://pravo.systems/reference/spec-generated-packages.md): The CUE packages that pravo init writes under cue.mod/gen, one per provider and one for pravo itself. - [Policies overview](https://pravo.systems/reference/policies-overview.md): A plan policy is one CUE file that a plan must satisfy. It is named with --policy by whoever runs pravo and never by the specification. - [The plan document in a policy](https://pravo.systems/reference/policies-plan-document.md): What a policy is unified with. How absent, null and unknown values behave, and what differs when a saved plan is applied. - [Writing policies](https://pravo.systems/reference/policies-writing.md): The four rules for writing a plan policy, each with a captured run, plan-wide rules, and the typos that forbid nothing. - [Operating policies](https://pravo.systems/reference/policies-operations.md): Where each command judges a policy, what a plan does before the verdict, how to roll a policy out and test it, and what a policy does and does not guarantee. - [State format](https://pravo.systems/reference/state-format.md): The files of the state graph: nodes, outputs, transactions, locks and the metadata that identifies a store. - [The plan document](https://pravo.systems/reference/plan-document.md): The JSON document that pravo plan --json prints, the form of a saved plan file, and the events that apply and destroy stream. - [Exit codes](https://pravo.systems/reference/exit-codes.md): The exit status of every pravo command, what each code means, and how --json reports an error. - [Telemetry](https://pravo.systems/reference/telemetry.md): OpenTelemetry traces and metrics for every command, resource and provider call, configured with the standard OTEL variables. - [Compatibility](https://pravo.systems/reference/compatibility.md): The versions and formats that pravo reads and writes, the provider protocol it speaks, and what it does with a version it does not know. - [S3-compatible stores](https://pravo.systems/reference/s3-stores.md): The three conditional requests that the S3 backend needs, how pravo checks that a store honours them, and how to test a store before it holds a state. - [Error catalogue](https://pravo.systems/reference/errors.md): Every error a user is likely to meet, as pravo prints it: the symptom, the cause and the fix. - [Glossary](https://pravo.systems/reference/glossary.md): The terms of CUE and of pravo, each with a definition of one or two sentences and a link to the lesson that teaches it. - [FAQ](https://pravo.systems/reference/faq.md): Short, factual answers to the questions asked first. - [Not in pravo](https://pravo.systems/reference/not-in-pravo.md): The commands, flags, blocks and files of OpenTofu and Terraform that pravo does not have, and what to use in each place. ## Optional - [llms-full.txt](https://pravo.systems/llms-full.txt): all pages in one file - [Search index](https://pravo.systems/search-index.json): titles, headings and excerpts as JSON