--- # verify.yaml — Read-only S1 baseline verification and local TAP collection. # # This playbook must not install, template, enable, restart, or otherwise # mutate a managed host. scripts/handoff_contract.py enforces the allowed # module and command surface before scripts/s1_handoff.py contacts a host. # Use verify-refresh.yaml only after reviewing and approving host changes. - name: Verify the installed S1 baseline without changing the host hosts: all become: true gather_facts: false vars_files: - ../inventory/group_vars/all.yaml vars: goss_bin: /usr/local/bin/goss goss_config: /etc/goss/baseline.yaml expected_goss_baseline: >- {{ lookup('ansible.builtin.template', playbook_dir ~ '/../../goss/baseline.yaml.j2', keep_trailing_newline=true) }} expected_goss_sha256: "{{ expected_goss_baseline | hash('sha256') }}" report_stamp: "{{ now(utc=true, fmt='%Y%m%dT%H%M%SZ') }}" tasks: - name: Inspect the installed Goss executable ansible.builtin.stat: path: "{{ goss_bin }}" register: installed_goss - name: Inspect the installed baseline digest ansible.builtin.stat: path: "{{ goss_config }}" checksum_algorithm: sha256 register: installed_baseline - name: Require the exact source-rendered verification surface ansible.builtin.assert: that: - installed_goss.stat.exists | default(false) - installed_goss.stat.executable | default(false) - installed_baseline.stat.exists | default(false) - installed_baseline.stat.checksum | default('') == expected_goss_sha256 fail_msg: >- {{ inventory_hostname }} has no usable Goss surface or its baseline is stale. Review changes, then run verify-refresh for this host before retrying the read-only handoff gate. - name: Run the installed baseline assertions ansible.builtin.command: argv: - "{{ goss_bin }}" - -g - "{{ goss_config }}" - validate - --format - tap register: goss_result changed_when: false failed_when: false - name: Ensure the controller reports directory exists ansible.builtin.file: path: "{{ playbook_dir }}/../../reports" state: directory mode: "0755" delegate_to: localhost become: false - name: Record TAP evidence on the controller ansible.builtin.copy: content: "{{ goss_result.stdout }}\n" dest: >- {{ playbook_dir }}/../../reports/goss-{{ inventory_hostname }}-{{ report_stamp }}.tap mode: "0644" delegate_to: localhost become: false changed_when: false - name: Fail closed on a baseline assertion failure ansible.builtin.assert: that: - goss_result.rc == 0 fail_msg: "Goss baseline failed on {{ inventory_hostname }}"