<p>The hub keeps this repository's Terraform and OpenTofu state, sealed at rest, with its last {{ crate::terraform::VERSIONS_KEPT }} versions, outside the repository's history. Point a configuration at it with this backend block, naming the state in place of <code>NAME</code> (a repository may keep several):</p>
<p>A job uses it with an identity token of this hub's, so it needs no cloud credential for the state. Give the job <code>identity "{{ shell.base_url }}/terraform" {% raw %}{{% endraw %} mount-path "/run/secrets/tf" {% raw %}}{% endraw %}</code>, run <code>export TF_HTTP_PASSWORD=$(cat /run/secrets/tf)</code> before <code>tofu init</code>, and let its sandbox reach this hub (<code>network "egress" {% raw %}{{% endraw %} allow "{{ shell.base_url|host }}" {% raw %}}{% endraw %}</code>, beside whatever else it reaches).</p>
<p>Set <code>TF_HTTP_PASSWORD</code> to one of your tokens with <code>repo:write</code>, as someone with the write role here. Reading a state needs that too: states hold secrets.</p>
<pclass="small mute">Each write keeps the state it replaced (the last {{ crate::terraform::VERSIONS_KEPT }}). Restoring one writes it again with the next serial, so OpenTofu and Terraform take it, and keeps the current state as a version: restoring never loses anything, and a later version can be restored in turn.</p>
{% for k in v.versions %}<tr><td>{{ k.serial }}</td><tdclass="small">{{ k.created_by }}</td><tdclass="small"><timetitle="{{ k.created_ms|when_i }}">{{ k.created_ms|ago_i }}</time></td><tdclass="small"><ahref="{{ repo.url }}/terraform/{{ v.s.name|urlencode }}/download?version={{ k.id }}">download</a>{% if repo.can_maintain() %} <formclass="tiny"method="post"action="{{ repo.url }}/terraform/{{ v.s.name|urlencode }}/restore"data-confirm="Restore {{ v.s.name }} to serial {{ k.serial }}? It becomes the current state; the current one is kept as a version."><inputtype="hidden"name="_csrf"value="{{ shell.csrf }}"><inputtype="hidden"name="version"value="{{ k.id }}"><button>restore</button></form>{% endif %}</td></tr>{% endfor %}