Best practices """""""""""""" * keep it simple * if something feels complicated, then we are probably doing it the wrong way * think about, what you would like to achieve and don't think about, what you've done so far... * version pinning * yum -> ``name: 'docker-{{ docker_version }}'`` * apt -> ``name: 'ntp={{ ntp_version }}'`` * application deployment with SCM e.g git -> use tags as ``version:`` * use ``version`` in requirements.yml for Ansible galaxy * keep your inventory file and variables in a git repo (or other version control). this is an excellent way to track changes to your inventory and variables. * If you write the same tasks in multiple playbooks, create a role. * use the prefix ``_`` in role variables * roles have defaults variables, that can be overwritten by ``group_vars`` * ``all`` is for global variables. * create a ``README.md`` for every role and describe the **usage** and **variables** -> maybe use the ``ansible-galaxy init test`` command and take that readme * share your roles for other projects (internal via ``SCM``/``HTTP`` or external via Ansible Galaxy) * try to avoid tasks with the command or shell module -> Ansible modules are designed to be safely repeatable -> Idempotency! * Use the file module rather than command with rm, mkdir, rmdir etc * Other modules that replace shell commands include synchronize, unarchive, git, hg, svn * if you use command/shell module, have a look at the ``creates`` parameter (only run, if the file is not in place) * command vs shell -> https://blog.confirm.ch/ansible-modules-shell-vs-command/ * `Idempotency / Error Handling `_ * use ``verbosity`` with the `Debug module `_ for messages .. code-block:: shell - debug: msg: "This only displays with ansible-playbook -vv+" verbosity: 2 * `Testing Strategies `_ / `ansible-ci `_ / `ansible-lint `_ * create tests with tags and modules like ``wait_for`` * don't use the short forms of tasks / lists / dictionaries in YAML -> ``git diff``, human readable * with git -> use tags instead of branches as version for SCM checkouts * useful tags of tasks * configuration * packages * installation * service * scm * deployment * critical * notification * debug * if your group_vars / host_vars file is to big -> use folders with sub-files * only parameterize variables you also need in a template or role * use fixed versions for role dependencies * there are ways to automate the role installation via ``SCM`` or ``ansible-galaxy`` * a task with ``local_action`` in a playbook * git submodule * create a "layer of indirection" for ansible vault variables. See `Ansible Docs `_ * `Ansible Porting Guide `_ * `Ansible Release and Maintenance Page `_ * You can learn something, if you check out other roles / examples from the `Ansible example repo `_, `Ansible Galaxy `_ or the `Debops Project `_ * you can use ``force: no`` to transfer a file only, if the destination does not exist (initial configuration). it's available in some modules like ``copy / template`` * have a look at the `callback plugins `_ .. code-block:: shell # actionable callback plugin, to only see changed/failed tasks ANSIBLE_STDOUT_CALLBACK=actionable ansible-playbook playbooks/config_backup.yml -l backup1.pvt.confirm.ch --tags iscsi # profile_tasks, adds time information to tasks ANSIBLE_STDOUT_CALLBACK=profile_tasks ansible-playbook playbooks/config_backup.yml -l backup1.pvt.confirm.ch --tags iscsi # profile_roles, adds timing information to roles ANSIBLE_STDOUT_CALLBACK=profile_roles ansible-playbook playbooks/config_backup.yml -l backup1.pvt.confirm.ch --tags iscsi # yaml - yaml-ized Ansible screen output (since Ansible v2.5) ANSIBLE_STDOUT_CALLBACK=yaml ansible-playbook playbooks/config_backup.yml -l backup1.pvt.confirm.ch --tags iscsi * decide, if you permanently set the ``become`` value in the configuration, or per playbook or per task. But be aware of the file owner/group-ship. * have a look at ssh key signing * have a look at `ansible-console `_ * make sure, the control machine(s) uses the same Ansible version. Maybe you can achieve this with `Python Virtualenvs `_. * have a look at `meta "module" `_ (flush_handlers, refresh_inventory, reset_connection, ...) .. code-block:: shell ansible-console # run a command ls -lh whoami # run a module package name=tree state=latest * use validation for configuration changes (if possible) .. code-block:: shell validate: '/usr/sbin/apache2ctl -f %s -t' validate: '/usr/sbin/sshd -t -f %s' validate: 'visudo -cf %s' validate: 'grep ntp %s' Tuning ------ * `Ansible Perfomance Tuning `_ * Check out the callback plugins `Profile_tasks `_ and `Profile_roles `_ * `Ansible Strategies `_ Styling ------- * use spaces around jinja2 variable names -> ``{{ var }}`` and not ``{{var}}`` * All yaml files should use 2 space indents and end with ``.yml`` * choose your quoting style (single ``path: '/etc/some.conf'`` / double ``path: "/etc/some.conf"``) * decide to quote not needed stuff like ``path: /etc/some.conf`` Useful commands --------------- .. code-block:: shell # save facts from all hosts ansible -m setup --tree /tmp/setup all ls -l /tmp/setup # show all variables ansible -m debug -a "msg='{{ vars }}'" localhost, Useful snippets --------------- .. code-block:: yaml # fileglob - name: Copy each file over that matches the given pattern copy: src: "{{ item }}" dest: "/etc/ssl/ca" owner: "root" mode: 0600 with_fileglob: - "/playbooks/files/fooapp/*.pem" {% if inventory_hostname in groups['dbservers'] %} -A INPUT -p tcp --dport 3306 -j ACCEPT {% endif %} Useful modules -------------- Have a look at this modules. * http://docs.ansible.com/ansible/latest/add_host_module.html * http://docs.ansible.com/ansible/latest/fetch_module.html * http://docs.ansible.com/ansible/latest/file_module.html * http://docs.ansible.com/ansible/latest/stat_module.html * http://docs.ansible.com/ansible/latest/unarchive_module.html * http://docs.ansible.com/ansible/latest/copy_module.html * http://docs.ansible.com/ansible/latest/template_module.html * http://docs.ansible.com/ansible/latest/filesystem_module.html * http://docs.ansible.com/ansible/latest/lvg_module.html * http://docs.ansible.com/ansible/latest/lvol_module.html * http://docs.ansible.com/ansible/latest/mount_module.html * http://docs.ansible.com/ansible/latest/get_url_module.html * http://docs.ansible.com/ansible/latest/git_module.html * http://docs.ansible.com/ansible/latest/group_by_module.html * http://docs.ansible.com/ansible/latest/java_cert_module.html * http://docs.ansible.com/ansible/latest/mail_module.html * http://docs.ansible.com/ansible/latest/jira_module.html * http://docs.ansible.com/ansible/latest/lineinfile_module.html * http://docs.ansible.com/ansible/latest/replace_module.html * http://docs.ansible.com/ansible/latest/cron_module.html * http://docs.ansible.com/ansible/latest/include_vars_module.html * http://docs.ansible.com/ansible/latest/set_fact_module.html * http://docs.ansible.com/ansible/latest/sysctl_module.html * http://docs.ansible.com/ansible/latest/pause_module.html * http://docs.ansible.com/ansible/latest/wait_for_connection_module.html * http://docs.ansible.com/ansible/latest/wait_for_module.html * http://docs.ansible.com/ansible/latest/assemble_module.html * http://docs.ansible.com/ansible/latest/raw_module.html * http://docs.ansible.com/ansible/latest/script_module.html * http://docs.ansible.com/ansible/latest/shell_module.html * http://docs.ansible.com/ansible/latest/command_module.html * http://docs.ansible.com/ansible/latest/user_module.html * http://docs.ansible.com/ansible/latest/group_module.html * http://docs.ansible.com/ansible/latest/apt_module.html * http://docs.ansible.com/ansible/latest/service_module.html * http://docs.ansible.com/ansible/latest/package_module.html * http://docs.ansible.com/ansible/latest/yum_module.html * http://docs.ansible.com/ansible/latest/yum_repository_module.html * http://docs.ansible.com/ansible/latest/pip_module.html Links ----- * http://docs.ansible.com/ansible/playbooks_best_practices.html * https://www.ansible.com/blog/ansible-best-practices-essentials * https://docs.ansible.com/ansible/devel/plugins/callback/actionable.html * https://www.slideshare.net/bcoca/more-tips-n-tricks