diff --git a/docs/docsite/rst/reference_appendices/faq.rst b/docs/docsite/rst/reference_appendices/faq.rst index 6294b517fd4..b17e4b65325 100644 --- a/docs/docsite/rst/reference_appendices/faq.rst +++ b/docs/docsite/rst/reference_appendices/faq.rst @@ -754,6 +754,45 @@ In such environments we recommend securing around Ansible's execution but still This is something that Tower/AWX excels at by allowing administrators to set up RBAC access to inventory, along with managing credentials and job execution. +.. _complex_configuration_validation: + +The 'validate' option is not enough for my needs, what do I do? ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Many Ansible modules that create or update files have a ``validate`` option that allows you to abort the update if the validation command fails. +This uses the temporary file Ansible creates before doing the final update. In many cases this does not work since the validation tools +for the specific application require either specific names, multiple files or some other factor that is not present in this simple feature. + +For these cases you have to handle the validation and restoration yourself. The following is a simple example of how to do this with block/rescue +and backups, which most file based modules also support: + +.. code-block:: yaml + + - name: update config and backout if validation fails + block: + - name: do the actual update, works with copy, lineinfile and any action that allows for `backup`. + template: src=template.j2 dest=/x/y/z backup=yes moreoptions=stuff + register: updated + + - name: run validation, this will change a lot as needed. We assume it returns an error when not passing, use `failed_when` if otherwise. + shell: run_validation_commmand + become: yes + become_user: requiredbyapp + environment: + WEIRD_REQUIREMENT: 1 + rescue: + - name: restore backup file to original, in the hope the previous configuration was working. + copy: + remote_src: yes + dest: /x/y/z + src: "{{ updated['backup_file'] }}" + always: + - name: We choose to always delete backup, but could copy or move, or only delete in rescue. + file: + path: "{{ updated['backup_file'] }}" + state: absent + + .. _docs_contributions: How do I submit a change to the documentation? diff --git a/lib/ansible/plugins/doc_fragments/validate.py b/lib/ansible/plugins/doc_fragments/validate.py index 99bbe00049a..f77514d27fb 100644 --- a/lib/ansible/plugins/doc_fragments/validate.py +++ b/lib/ansible/plugins/doc_fragments/validate.py @@ -12,8 +12,10 @@ class ModuleDocFragment(object): options: validate: description: - - The validation command to run before copying into place. - - The path to the file to validate is passed in via '%s' which must be present as in the examples below. - - The command is passed securely so shell features like expansion and pipes will not work. + - The validation command to run before copying the updated file into the final destination. + - A temporary file path is used to validate, passed in through '%s' which must be present as in the examples below. + - Also, the command is passed securely so shell features such as expansion and pipes will not work. + - For an example on how to handle more complex validation than what this option provides, + see L(Complex configuration validation,https://docs.ansible.com/ansible/devel/reference_appendices/faq.html). type: str '''