Skip to content

Discovery, snapshot, and restore

Two different things share the word "discover". Knowing which one you want saves confusion.

  • Capability discovery asks the instance what it is — version, edition, limits — and records a fact for the play. It can also capture a snapshot of current application settings.
  • Resource discovery lists actual GitLab resources — groups, projects, branches, members — as normalized records you can loop over.

Capability discovery

The role's discover entry point probes the target and records gitlab_settings_capabilities as a per-host fact for the current play:

- name: Discover capabilities and capture current settings
  ansible.builtin.include_role:
    name: primetheus.gitlab_settings
    tasks_from: discover
  vars:
    gitlab_settings_snapshot_file: /var/backups/gitlab-settings.yml

The fact contains version, a nullable revision, enterprise, and maximum_group_depth. It is deliberately not cacheable — an instance can be upgraded between runs, and a stale capability fact would produce confidently wrong routing decisions.

It is also separate from the snapshot file. Discovery without gitlab_settings_snapshot_file records capabilities and persists nothing.

Snapshots

gitlab_settings_snapshot_file is where captured application settings are written.

An existing snapshot is preserved, never overwritten

Pointing discover at a path that already holds a snapshot leaves it alone. This protects the record of a known-good state from being overwritten by a run made after something went wrong. Move or delete the old file deliberately when you want a fresh capture.

Restore

restore applies a captured snapshot:

- name: Restore previously captured settings
  ansible.builtin.include_role:
    name: primetheus.gitlab_settings
    tasks_from: restore
  vars:
    gitlab_settings_restore_file: /var/backups/gitlab-settings.yml
    gitlab_settings_resource: instance
    gitlab_settings_instance:
      application:
        defaults:
          help_page_text: managed   # the fields you manage; values come
                                    # from the snapshot, not from here

Restore is scoped by your declared application settings

Restore covers instance application settings and applies snapshot values only for the application fields you declare — the declared values are replaced by the snapshot's. It is not a blanket rollback of the instance, and group/project declarations never take snapshot values. That is what makes it safe to run against an instance whose other settings have legitimately moved on.

Restore fails closed in three named cases rather than guessing:

  • no managed application settings were declared alongside the restore file (there is nothing to scope the restore to);
  • the snapshot is missing a declared field;
  • the snapshot holds null for a declared field — the field had no value when the snapshot was captured, so the original cannot be proven. Converge a baseline before snapshotting (the same order an operator uses anyway: converge your declaration, then snapshot it).

Restore runs the same apply path as any other convergence, so --check, --diff, strict and compatible modes, and the coverage manifest all behave identically. Under a bounded credential (bound_to), discovery must also be parent-scoped to the boundary — an unscoped listing cannot prove it stays inside the declared authority, so the role refuses it locally; use the parent: form shown below. Preview a restore before committing to it:

ansible-playbook -i localhost, restore.yml --check --diff

Resource discovery

The collection's discover action lists live resources as normalized records:

- name: Discover all groups
  primetheus.gitlab_settings.gitlab_settings_discover:
    target: "{{ gitlab_settings_target }}"
    resource: group
    scope: all
  register: discovered_groups

Each record carries the exact identifier the reconciliation action accepts, so discovery and convergence compose without translation:

- name: Enable Duo for every discovered group
  primetheus.gitlab_settings.gitlab_settings:
    target: "{{ gitlab_settings_target }}"
    resource: group
    identifier: "{{ item['identifier'] }}"
    settings:
      duo:
        duo_features_enabled: true
  loop: "{{ discovered_groups['resources'] }}"
  loop_control:
    label: "{{ item['identifier'] }}"

scope is a resource-specific semantic declared by the registry. Omit it to use the resource's safe default — memberships, for instance, default to direct rather than including inherited ones.

Nested resources take a parent:

- name: Discover branches in one project
  primetheus.gitlab_settings.gitlab_settings_discover:
    target: "{{ gitlab_settings_target }}"
    resource: branch
    parent:
      resource: project
      identifier: platform/service

Verify the credential once, before the loop

A discovery-to-loop play can make many requests. Running gitlab_credential_check once at the top costs a single request and turns a mid-loop authorization failure into an up-front one.

Which one do I want?

Goal Use
Know the instance version before deciding what to apply tasks_from: discover
Capture current settings for later restore tasks_from: discover with gitlab_settings_snapshot_file
Roll a managed surface back to a captured state tasks_from: restore
Loop over groups, projects, branches, or members gitlab_settings_discover action