Playbooks """"""""" About Playbooks =============== * a play links hosts / hostgroups with tasks or roles * a playbook contains one or more **play** * playbooks are the basis for a really simple configuration management * playbooks are expressed in **YAML** with a minimum syntax * a playbook can import other playbooks with ``import_playbook:`` * plays are executed in sequence .. code-block:: yaml --- - name: first play <- play name (optional) hosts: all <- host / hostgroup tasks: <- task list - name: the first task <- first task apt: name: apache2 state: latest # playbook with imported playbooks --- # file: site.yml - import_playbook: webservers.yml - import_playbook: dbservers.yml * it's possible to set variables and settings in a playbook (e.g ``become``, ``remote_user``, etc.) .. code-block:: yaml # advaned playbook with two plays and become & remote_user --- - name: play 1 hosts: all become: yes tasks: - name: install apache apt: name: apache2 state: latest - name: play 2 hosts: all remote_user: special-user become: yes tasks: - name: install pip apt: name: python-pip state: latest Links ----- * http://docs.ansible.com/ansible/playbooks.html * http://docs.ansible.com/ansible/playbooks_intro.html * http://docs.ansible.com/ansible/latest/playbooks_reuse.html * http://docs.ansible.com/ansible/latest/playbooks_keywords.html * http://docs.ansible.com/ansible/latest/user_guide/playbooks.html Create and run the first playbook ================================= * Create a new file * Start the YAML ``---`` * Define the ``hosts:`` * Create the ``tasks:`` list * Add your first task * Save the file as ``apache2.yml`` * Run the playbook ``ansible-playbook apache2.yml`` .. code-block:: yaml --- - hosts: web1.pascal.lab tasks: - name: install apache2 apt: name: apache2 state: latest Action Result ------------- * there are 4 possible results after a run .. code-block:: bash PLAY RECAP ********************************************************************* web1.pascal.lab : ok=2 changed=1 unreachable=0 failed=0 +-------------+----------------------------+ | Result | Description | +=============+============================+ | ok | nothing changed, all okay | +-------------+----------------------------+ | changed | the task changed the state | +-------------+----------------------------+ | failed | the task failed | +-------------+----------------------------+ | unreachable | the server was unreachable | +-------------+----------------------------+ Privilege Escalation -------------------- * Ansible allows you ‘become’ another user, different from the user that logged into the machine (remote user). * these settings can be set from play to task level Links ----- * http://docs.ansible.com/ansible/become.html Check Mode (Dry Run) ==================== * simulate a run with the ``--check`` option -> no changes are made (read-only) * skip tasks in check mode with ``when: not ansible_check_mode`` * ignore errors in check mode with ``ignore_errors: "{{ ansible_check_mode }}"`` * show the differences in a run with the ``--diff`` option (useful in combination with the check mode) .. code-block:: shell # check mode ansible-playbook test.yml --check # diff mode ansible-playbook test.yml --check --diff .. important:: Not all modules support the check / diff mode! But most of the primary core modules do. Other modules that do not support check mode will also take no action, but just will not report what changes they might have made. Links ----- * http://docs.ansible.com/ansible/latest/playbooks_checkmode.html# Error Handling ============== * ``ignore_errors: yes`` -> ignore all errors for a task * ``changed_when`` -> override the changed result of a task * ``failed_when`` -> control, if the task is failed * ``any_errors_fatal`` -> mark all hosts as failed if any tasks fails (in the playbook) .. code-block:: shell # ignore_errors - name: this will not be counted as a failure command: /bin/false ignore_errors: yes # failed_when - name: Fail task when both files are identical raw: diff foo/file1 bar/file2 register: diff_cmd failed_when: diff_cmd.rc == 0 or diff_cmd.rc >= 2 # changed_when - shell: /usr/bin/billybass --mode="take me to the river" register: bass_result changed_when: "bass_result.rc != 2" # this will never report 'changed' status - shell: wall 'beep' changed_when: False # mark all hosts as failed if any fails - hosts: somehosts any_errors_fatal: true roles: - myrole .. hint:: Be sure what you do, if you set ``ignore_errors: true`` Links ----- * http://docs.ansible.com/ansible/latest/playbooks_error_handling.html * http://docs.ansible.com/ansible/latest/user_guide/playbooks_error_handling.html#aborting-the-play Tags ==== * playbooks and tasks are supporting ``tags`` * useful to run only a specificed part * multiple tags are allowed * it's also possible to skip tags * special tags: * ``never``, prevent a task from running unless a tag is specifically requested (like debug & never) * ``always``, always run a task, unless specifically skipped (``--skip-tags always``) * ``tagged``, which run only tagged * ``untagged``, which run only untagged * ``all``, run all tasks .. code-block:: yaml - name: install httpd package yum: name: httpd state: present tags: - httpd - installation .. code-block:: bash # run httpd and installation tags ansible-playbook play.yml --tags "configuration,installation" # skip notification tags ansible-playbook example.yml --skip-tags "notification" Links ----- * http://docs.ansible.com/ansible/playbooks_tags.html * http://docs.ansible.com/ansible/latest/playbooks_tags.html#special-tags * http://docs.ansible.com/ansible/latest/intro_configuration.html#merge-multiple-cli-tags Playbook Options ================ * ``--tags / --skip-tags`` -> only run / skip a specified tag * ``--limit`` -> only run on a specified host/hostgroup -> nützlich! * ``--step`` -> run step-by-step and confirm every task (yes/no/continue) * ``--check`` -> don't execute, only check * ``--diff`` -> print out the differences, if implemented in the modules * ``--syntax-check`` -> YAML syntax check * ``--list-tasks`` -> list the tasks, that would be run in the playbooks * ``--list-hosts`` -> list the hosts, on which the plays would run * ``--force-handlers`` -> run handlers even if a task fails Strategies ========== * Linear -> Run each task before the next starts, 5 forks parallel (default) * Serial -> Run everything on a subset of hosts * free -> Run everything on each host until the end of the play Links ----- * https://docs.ansible.com/ansible/latest/user_guide/playbooks_strategies.html +Blocks ======= Requirement: Variables chapter * logical grouping of tasks (when, become, etc. can be set on block level) * also useful for error handling -> try / except / finally * rescue -> tasks to run after a fail e.g flush_handlers * always -> always executed tasks e.g good for clean-up / restore .. code-block:: yaml --- - hosts: - web1.pascal.lab tasks: - name: my first block (added in ansible 2.3) block: - name: "task1 in block1" debug: msg: "execute normally" - name: "task2 in block1" command: /bin/false rescue: - name: "rescue block1" debug: msg: "caught an error" always: - name: "always block1" debug: msg: "this always executes" when: ansible_distribution == 'Debian' tags: - test1 - blockxy become: yes Links ----- * http://docs.ansible.com/ansible/playbooks_blocks.html