{"id":245,"date":"2020-09-18T11:25:54","date_gmt":"2020-09-18T11:25:54","guid":{"rendered":"https:\/\/www.adriatic-staging.mattbedford.work\/?p=245"},"modified":"2020-09-18T14:08:46","modified_gmt":"2020-09-18T14:08:46","slug":"ansible-global-variables","status":"publish","type":"post","link":"https:\/\/www.adriaticnetworks.com\/de\/ansible-global-variables\/","title":{"rendered":"Ansible globale Variablen"},"content":{"rendered":"<p>Ansible has the ability to use group _vars and host _vars and is very flexible in the way they can be defined. However, there is often a need to store data globally. This is particularly true in a multi-play Ansible playbook. A global variable is one that can be stored in one play and used in another play. This article will show how the concept of global variables can be achieved in Ansible.<\/p>\n\n\n\n<p>The following playbook demonstrates how variables can be used between two playbooks, essentially emulating the global variable concept:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">---\n- name: &quot;PLAY 01 --- collect inputs and create global vars&quot;\n  hosts: localhost\n  gather_facts: no\n\n  vars_prompt:\n    - name: &#039;router_username&#039;\n      prompt: &quot;Please enter router username&quot;\n      private: no\n    - name: &#039;router_password&#039;\n      prompt: &quot;please enter router password&quot;\n      private: yes\n\n  tasks:\n    - name: Save credentials as global vars\n      set_fact:\n        router_username: &quot;{{ router_username }}&quot;\n        router_password: &quot;{{ router_password }}&quot;\n      no_log: true\n\n- name: &quot;PLAY 02 --- consume global vars&quot;\n  hosts: cisco_routers\n  connection: network_cli\n  gather_facts: no\n\n  tasks:\n    - name: fetch global vars from PLAY 01\n      set_fact:\n        ansible_user: &quot;{{ hostvars[&#039;localhost&#039;][&#039;router_username&#039;] }}&quot;\n        ansible_ssh_pass: &quot;{{ hostvars[&#039;localhost&#039;][&#039;router_password&#039;] }}&quot;\n      no_log: true\n\n    - name: send show run to Cisco devices\n      cli_command:\n        command: show running-config\n      register: show_run\n\n    - name: print show_run\n      debug: \n        msg: &quot;{{ show_run.stdout_lines }}&quot;<\/code><\/pre>\n\n\n\n<p>Here is what happens within the playbook: (i) first it prompts for a username and password, (ii) the credentials are stored as<code> host _vars<\/code> of\u00a0 localhost, (iii) the same credentials are used in the second play (which runs against different group of hosts) to connect to the Cisco Devices. With this code we effectively use <code>localhost host vars<\/code> as a container for our global vars.\u00a0 Please notice the set_fact task in PLAY 01. At first, it may seem redundant but the vars whose content is received through the <code>vars_prompt<\/code> are not stored in\u00a0<code>hostvars[\u2018locahost\u2019][var_name]<\/code>. We do that manually with set_fact.<\/p>\n\n\n\n<p>In PLAY02, cisco_routers is used and not localhost. Let\u2019s have a brief look at our inventory file:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">[cisco_routers]\nR1 ansible_host=&quot;192.168.0.101&quot; device_role=&quot;PE&quot;\nR2 ansible_host=&quot;192.168.0.102&quot; device_role=&quot;PE&quot;\n\n[cisco_routers:vars]\nansible_network_os=&quot;ios&quot;<\/code><\/pre>\n\n\n\n<p>For each host in that group, we first create host <code>vars ansible_user<\/code> und <code>ansible_ssh_pass<\/code> from global vars.\u00a0 Then we are ready to proceed to the rest of the business logic in the playbook.<\/p>\n\n\n\n<p>In both plays no_log is set to true. This is to disable Ansible from printing sensitive data in <code>stdout <\/code>if the task fails. We certainly do not want this data to be ever printed in the Ansible output. One important thing to note here is that the data is saved in <code>hostvars <\/code>as clear text. So, if you ever do something like <code>debug: var=hostvars<\/code> the sensitive data will be printed there.<\/p>\n\n\n\n<p>Sometimes you may want to not only set global vars, but also change them over the course of a multi-play playbook.<br>Let\u2019s extend our playbook to demonstrate this:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-python\">---\n- name: &quot;PLAY 01 --- collect inputs and create global vars&quot;\n  hosts: localhost\n  gather_facts: no\n\n  vars_prompt:\n    - name: &#039;router_username&#039;\n      prompt: &quot;Please enter router username&quot;\n      private: no\n    - name: &#039;router_password&#039;\n      prompt: &quot;please enter router password&quot;\n      private: yes\n\n  tasks:\n    - name: Save credentials as global vars\n      set_fact:\n        router_username: &quot;{{ router_username }}&quot;\n        router_password: &quot;{{ router_password }}&quot;\n        show_config_sent: not yet\n      no_log: true\n\n    - name: print show_config_sent\n      debug:\n        msg: &quot;{{ show_config_sent }}&quot;\n\n- name: &quot;PLAY 02 --- consume global vars&quot;\n  hosts: cisco_routers\n  connection: network_cli\n  gather_facts: no\n\n  tasks:\n    - name: fetch global vars from PLAY 01\n      set_fact:\n        ansible_user: &quot;{{ hostvars[&#039;localhost&#039;][&#039;router_username&#039;] }}&quot;\n        ansible_ssh_pass: &quot;{{ hostvars[&#039;localhost&#039;][&#039;router_password&#039;] }}&quot;\n      no_log: true\n\n    - name: send show run to Cisco devices\n      cli_command:\n        command: show running-config\n      register: show_run\n\n    - name: print show_run\n      debug: \n        msg: &quot;{{ show_run.stdout_lines }}&quot;\n\n    - name: update global variable\n      set_fact:\n        show_config_sent: yes of course\n      delegate_to: localhost\n      delegate_facts: true\n      run_once: true\n\n- name: &quot;PLAY 03 --- read updated global vars from localhost&quot;\n  hosts: localhost\n  gather_facts: no\n\n  tasks:\n    - name: print show_config_sent\n      debug:\n        msg: &quot;{{ show_config_sent }}&quot;<\/code><\/pre>\n\n\n\n<p>In PLAY02, in the update global variable task, we instruct Ansible to set the value of the localhost <code>hostvar show_config_sent<\/code>. Setting <code>delegate_to: localhost<\/code> und <code>delegate_facts: true<\/code> are required to achieve that.<br>Please notice that in PLAY03 we get the variable<code> show_config_sent<\/code> as a host variable bound to the localhost.<\/p>","protected":false},"excerpt":{"rendered":"<p>Eine globale Variable kann in einem Spiel gespeichert und in einem anderen Spiel verwendet werden. Dieser Artikel zeigt, wie das Konzept globaler Variablen in Ansible erreicht werden kann.<\/p>","protected":false},"author":1,"featured_media":247,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[17,18,19,20,21],"_links":{"self":[{"href":"https:\/\/www.adriaticnetworks.com\/de\/wp-json\/wp\/v2\/posts\/245"}],"collection":[{"href":"https:\/\/www.adriaticnetworks.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.adriaticnetworks.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.adriaticnetworks.com\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.adriaticnetworks.com\/de\/wp-json\/wp\/v2\/comments?post=245"}],"version-history":[{"count":9,"href":"https:\/\/www.adriaticnetworks.com\/de\/wp-json\/wp\/v2\/posts\/245\/revisions"}],"predecessor-version":[{"id":463,"href":"https:\/\/www.adriaticnetworks.com\/de\/wp-json\/wp\/v2\/posts\/245\/revisions\/463"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.adriaticnetworks.com\/de\/wp-json\/wp\/v2\/media\/247"}],"wp:attachment":[{"href":"https:\/\/www.adriaticnetworks.com\/de\/wp-json\/wp\/v2\/media?parent=245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.adriaticnetworks.com\/de\/wp-json\/wp\/v2\/categories?post=245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.adriaticnetworks.com\/de\/wp-json\/wp\/v2\/tags?post=245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}