Variables """"""""" Variable Definition =================== * Variable names should be letters, numbers or underscores and should always start with a letter * variable files are in YAML format * valid file extensions include ``.yml``, ``.yaml``, ``.json`` or no file extension. * there are many places to define a variable * Inventory * Playbook * Roles * included Files * group_vars * host_vars * If multiple variables of the same name are defined in different places, they get overwritten in a certain order. * variables can override another, so the order is important (`variable precedence`_) * If multiple groups have the same variable, the last one loaded wins. * Child groups variables override parent groups * Site wide values should be defined in ``group_vars/all.yml`` .. hint:: It's recommended to prefix your role variables with ``_``. .. important:: Variables are overwritten in a certain order! .. _variable precedence: http://docs.ansible.com/ansible/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable How to use variables -------------------- * Ansible is using the Jinja2 templating system * use ``{{ }}`` brackets * a variable in a task needs quotes ``''`` -> ``'{{ myvariable }}'`` * use a variable in a template without quotes ``{{ myvariable }}`` group_vars ---------- * directory is called ``group_vars`` * Ansible will pick up the ``group_vars`` directories in the same location as the inventory file * files can optionally end in ``.yml``, ``.yaml`` or ``.json`` * you can create directories named after your groups and Ansible will read all the files in these directories * ``group_vars/all.yml`` can be used to define variables for all host groups. .. code-block:: bash group_vars//ntp.yml group_vars/.yml .. hint:: If your group_vars file is big, create a folder for your group_vars. Then split the variables in specified files like ``ntp.yml`` .. important:: Child groups override parent groups host_vars --------- * folder is called ``host_vars`` * Ansible will pick up the ``host_vars`` folder in the same location as the inventory file * all files in directories named after your hosts will be read by Ansible * you can create directories named after your hosts and Ansible will read all the files in these directories * single file with file exentsion possible (depends on the ansible version) * sub-files in directories with file extension .. code-block:: bash host_vars//connection.yml host_vars/ / host_vars/.yml .. important:: The host_vars file or directory have to match with the inventory hostname. Links ----- * http://docs.ansible.com/ansible/playbooks_variables.html * http://docs.ansible.com/ansible/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable * http://docs.ansible.com/ansible/intro_inventory.html#host-variables * http://docs.ansible.com/ansible/playbooks_variables.html#using-variables-about-jinja2 * http://docs.ansible.com/ansible/playbooks_variables.html#variable-examples Role Variables ============== * Go back to the `roles chapter <09_roles.html#role-variables>`_. Loops ===== * loops are useful to do many things in one task * install a lot of packages * create a lot of users * there are a lot of loops availabe, checkout the links below * standard loop over a list works with ``with_items:`` btw. ``loop:`` .. code-block:: yaml # list values defined in the task - name: install some packages apt: name: '{{ item }}' state: present with_items: - apache2 - python-pip # list values defined in the task - name: install some packages apt: name: '{{ item }}' state: present loop: - apache2 - python-pip * you can define a list in the group_vars and use it .. code-block:: yaml # group_vars/all.yml mypackages: - apache2 - python-pip # use the variable mypackages - name: install some packages apt: name: '{{ item }}' state: present with_items: '{{ mypackages }}' # use the variable mypackages - name: install some packages apt: name: '{{ item }}' state: present loop: '{{ mypackages }}' Links ----- * http://docs.ansible.com/ansible/playbooks_loops.html Facts ===== * everytime ansible is running on the managed node, it will gather facts from that system * the facts are available as variables * can be used in templates or playbooks * useful for conditions (e.g includes, tasks, variables) * facts can be turned off with ``gather_facts`` * only a subset of facts can be gathered via ``gather_subset`` * facts can be cached (default is ``memory`` -> no caching) .. hint:: Facts are a good way for OS specific tasks / variables. .. code-block:: yaml # file: playbook.yml # turning off facts in a playbook gather_facts: false .. code-block:: bash # show all facts ansible -m setup * load os variables based on facts in a playbook with ``vars_files:`` Links ----- * http://docs.ansible.com/ansible/playbooks_variables.html#information-discovered-from-systems-facts * http://docs.ansible.com/ansible/playbooks_variables.html#turning-off-facts Conditionals ============ * skip or run a task if a condition is given (e.g os compatibilty, requirement) * multiple conditions are also allowed (and / or) * it's also possible to negate a condition with ``!=`` .. hint:: Conditionals in combination with loops -> when evaluates for EACH item .. code-block:: yaml # file: conditional.yml --- - hosts: web*.pascal.lab tasks: - name: install epel-release on redhat yum: name: epel-release state: latest when: ansible_os_family == "RedHat" # file: conditional_or.yml --- - hosts: web*.pascal.lab tasks: - name: "run on CentOS 7 and Debian 9 systems" command: whoami when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "7") or (ansible_distribution == "Debian" and ansible_distribution_major_version == "9") # file: conditional_and.yml --- - hosts: web*.pascal.lab tasks: - name: "run on CentOS 7 systems"" command: whoami when: - ansible_distribution == "CentOS" - ansible_distribution_major_version == "7" # file: conditional_not.yml --- - hosts: web*.pascal.lab tasks: - name: "run on all other os systems"" command: whoami when: - ansible_distribution != "CentOS" * you can import os specified variables with the ``include_vars`` module .. code-block:: yaml # load os specific variables - name: include Debian variables include_vars: debian.yml when: ansible_os_family == "Debian" * you can import os specified tasks with the ``include_tasks`` statement .. code-block:: yaml # load os specific task - name: include Debian task include_tasks: debian.yml when: ansible_os_family == "Debian" Links ----- * http://docs.ansible.com/ansible/playbooks_conditionals.html * http://docs.ansible.com/ansible/playbooks_conditionals.html#conditional-imports * http://docs.ansible.com/ansible/playbooks_variables.html#variable-scopes Prompting for variables ======================= * When running a playbook, you may wish to prompt the user for certain input * this can be done with a ``vars_prompt:`` section. * ``name:`` defines the variablename .. hint:: A common use-case could be asking for sensitive data that you do not want to record. .. code-block:: yaml --- - name: give temporary root access hosts: "{{ hostname }}" vars_prompt: - name: list prompt: 'Enter host/host group' private: no - name: user prompt: 'Enter username' private: no tasks: - name: create sudo file template: src: sudo.j2 dest: /etc/sudoers.d/temproot owner: root group: root mode: 0640 become: yes .. code-block:: bash ansible-playbook prompt.yml # prompt Enter host/host group: web1.pascal.lab Enter username: pascal Links ----- * http://docs.ansible.com/ansible/playbooks_prompts.html Register Variables ================== * The value of a task being executed can be saved in a variable * use ``register: `` .. code-block:: yaml --- - hosts: web1.pascal.lab tasks: - name: run a command command: hostname register: myvar - name: print registered variable debug: msg: '{{ myvar }}' # output ok: [web1.pascal.lab] => { "msg": { "changed": true, "cmd": [ "hostname" ], "delta": "0:00:00.004890", "end": "2016-04-21 06:06:20.604805", "rc": 0, "start": "2016-04-21 06:06:20.599915", "stderr": "", "stdout": "web1.pascal.lab", "stdout_lines": [ "web1.pascal.lab" ], "warnings": [] } } Links ----- * http://docs.ansible.com/ansible/playbooks_variables.html#registered-variables Playbook Blocks =============== * Go back to the `playbooks chapter <08_playbooks.html#blocks>`_.