{"id":3168,"date":"2020-01-06T20:59:57","date_gmt":"2020-01-06T19:59:57","guid":{"rendered":"http:\/\/miro.borodziuk.eu\/?p=3168"},"modified":"2021-05-25T16:21:31","modified_gmt":"2021-05-25T14:21:31","slug":"automation-with-ansible-1","status":"publish","type":"post","link":"http:\/\/miro.borodziuk.eu\/index.php\/2020\/01\/06\/automation-with-ansible-1\/","title":{"rendered":"Ansible &#8211; Inventory"},"content":{"rendered":"<p>Ansible is an open source configuration management and orchestration utility. It can automate and standardize the configuration of remote hosts and virtual machines. Its orchestration functionality allows Ansible to coordinate the launch and graceful shutdown of multitiered applications. Because of this, Ansible can perform rolling updates of multiple systems in a way that results in zero downtime.<br \/>\n<!--more-->Instead of writing custom, individualized scripts, system administrators create high-level plays in Ansible. A play performs a series of tasks on the host, or group of hosts, specified in the play. A file that contains one or more plays is called a playbook. Ansible&#8217;s architecture is agentless. Work is pushed to remote hosts when Ansible executes. Modules are the programs that perform the actual work of the tasks of a play. Ansible is immediately useful because it comes with hundreds of core modules that perform useful system administrative work.<\/p>\n<p><span style=\"color: #3366ff;\">Inventories<\/span><\/p>\n<ul>\n<li>An inventory is a list of hosts that Ansible manages<\/li>\n<li>Inventory location may be specified as follows:\n<ul>\n<li>Default: <code>\/etc\/ansible\/hosts<\/code><\/li>\n<li>Specified by CLI: <code>ansible -i &lt;filename&gt;<\/code><\/li>\n<li>Can be set in <code>ansible.cfg<\/code><\/li>\n<\/ul>\n<\/li>\n<li>The inventory file may contain hosts, patterns, groups, and variables<\/li>\n<li>You may specify the inventory as a directory containing a series of inventory files (both static and dynamic)<\/li>\n<li>The inventory may be specified in YAML or INI format<\/li>\n<li>Can be static or dynamic<\/li>\n<\/ul>\n<p>Default inventory file<\/p>\n<pre class=\"lang:sh decode:true\">[root@controlnode ~]# cat \/etc\/ansible\/hosts\r\n\r\n# This is the default ansible 'hosts' file.\r\n#\r\n# It should live in \/etc\/ansible\/hosts\r\n#\r\n# - Comments begin with the '#' character\r\n# - Blank lines are ignored\r\n# - Groups of hosts are delimited by [header] elements\r\n# - You can enter hostnames or ip addresses\r\n# - A hostname\/ip can be a member of multiple groups\r\n\r\n# Ex 1: Ungrouped hosts, specify before any group headers.\r\n\r\n## green.example.com\r\n## blue.example.com\r\n## 192.168.100.1\r\n## 192.168.100.10\r\n\r\n# Ex 2: A collection of hosts belonging to the 'webservers' group\r\n\r\n## [webservers]\r\n## alpha.example.org\r\n## beta.example.org\r\n## 192.168.1.100\r\n## 192.168.1.110\r\n\r\n# If you have multiple hosts following a pattern you can specify\r\n# them like this:\r\n\r\n## www[001:006].example.com\r\n\r\n# Ex 3: A collection of database servers in the 'dbservers' group\r\n\r\n## [dbservers]\r\n##\r\n## db01.intranet.mydomain.net\r\n## db02.intranet.mydomain.net\r\n## 10.25.1.56\r\n## 10.25.1.57\r\n\r\n# Here's another example of host ranges, this time there are no\r\n# leading 0s:\r\n\r\n## db-[99:101]-node.example.com<\/pre>\n<p>Default host inventory defines two host groups, webservers and<br \/>\ndb-servers.<\/p>\n<p>Consider such an example:<\/p>\n<pre class=\"lang:sh decode:true \">[webservers]\r\nlocalhost ansible_connection=local\r\nweb1.example.com\r\nweb2.example.com:1234 ansible_connection=ssh ansible_user=ftaylor\r\n192.168.3.7\r\n\r\n[db-servers]\r\nweb1.example.com\r\ndb1.example.com<\/pre>\n<p>Host entries can also define how Ansible communicates with the managed host, including transport and user account information. In the previous example, SSH on<code> web2.example.com<\/code> is configured to listen on a non-standard port, port <code>1234<\/code>. The account Ansible should use to log into that host is <code>ftaylor<\/code>.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\">Variables and Inventories<\/span><\/p>\n<ul>\n<li>Ansible recommends that variables not be defined in inventory files:\n<ul>\n<li>Should be stored in YAML files located relative to inventory file<\/li>\n<li>group_vars<\/li>\n<li>host_vars<\/li>\n<\/ul>\n<\/li>\n<li>Files named by host or group and may end in yml or yaml<\/li>\n<\/ul>\n<pre class=\"lang:sh decode:true\">[miro@controlnode ansible]$ cat inventory\r\nmaile.example.com\r\n\r\n[httpd]\r\nhttpd1.example.com\r\nhttpd2.example.com\r\n\r\n[miro@controlnode ansible]$ ls -lR\r\n.:\r\nrazem 4\r\ndrwxrwxr-x. 2 miro miro 19 01-06 23:45 group_vars\r\ndrwxrwxr-x. 2 miro miro 32 01-06 23:45 host_vars\r\n-rw-rw-r--. 1 miro miro 66 01-06 23:44 inventory\r\n\r\n.\/group_vars:\r\nrazem 4\r\n-rw-rw-r--. 1 miro miro 16 01-06 23:45 httpd\r\n\r\n.\/host_vars:\r\nrazem 4\r\n-rw-rw-r--. 1 miro miro 14 01-06 23:45 httpd1.example.com\r\n[miro@controlnode ansible]$ cat group_vars\/httpd\r\nhttp_port: 8080\r\n[miro@controlnode ansible]$ cat host_vars\/httpd1.example.com\r\nopt_dir: \/opt\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"lang:sh decode:true \">[root@controlnode ansible]# ll\r\nrazem 4\r\ndrwxrwxr-x. 2 miro miro 37 01-10 21:19 group_vars\r\ndrwxrwxr-x. 2 miro miro 64 01-10 22:30 host_vars\r\n-rw-rw-r--. 1 miro miro 116 01-10 22:24 inventory\r\n[root@controlnode ansible]# cat inventory\r\nmanagedhost1 ansible_host=managedhost1.example.com\r\n\r\n[labservers]\r\nmanagedhost1.example.com\r\n\r\n[root@controlnode ansible]# cat host_vars\/managedhost1.example.com\r\nopt_dir: \/opt\r\n[root@controlnode ansible]# ansible managedhost1.example.com -i inventory -a \"ls -l {{opt_dir}}\"\r\nmanagedhost1.example.com | SUCCESS | rc=0 &gt;&gt;\r\nrazem 0\r\n-rw-r--r--. 1 root root 0 01-10 22:42 file1\r\n-rw-r--r--. 1 root root 0 01-10 22:42 file2\r\n\r\n[root@controlnode ansible]# cat group_vars\/labservers\r\nlogs : \/var\/log\/messages\r\n[root@controlnode ansible]# ansible managedhost1.example.com -i inventory -b -a \"tail {{logs}}\"\r\nmanagedhost1.example.com | SUCCESS | rc=0 &gt;&gt;\r\nJan 10 22:44:03 managedhost1 systemd-logind: Removed session 106.\r\nJan 10 23:01:01 managedhost1 systemd: Started Session 108 of user root.\r\nJan 10 23:02:10 managedhost1 systemd: Started Session 109 of user root.\r\nJan 10 23:02:10 managedhost1 systemd-logind: New session 109 of user root.\r\nJan 10 23:02:10 managedhost1 ansible-command: Invoked with warn=True executable=None _uses_shell=False _raw_params=ls -l \/opt removes=None creates=None chdir=None stdin=None\r\nJan 10 23:03:10 managedhost1 systemd-logind: Removed session 109.\r\nJan 10 23:04:25 managedhost1 systemd: Started Session 110 of user root.\r\nJan 10 23:04:25 managedhost1 systemd-logind: New session 110 of user root.\r\nJan 10 23:04:26 managedhost1 ansible-command: Invoked with warn=True executable=None _uses_shell=False _raw_params=tail \/opt removes=None creates=None chdir=None stdin=None\r\nJan 10 23:04:37 managedhost1 ansible-command: Invoked with warn=True executable=None _uses_shell=False _raw_params=tail \/var\/log\/messages removes=None creates=None chdir=None stdin=None<\/pre>\n<p>&nbsp;<\/p>\n<p><code>YAML vs INI<\/code><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-3172 aligncenter\" src=\"http:\/\/miro.borodziuk.eu\/wp-content\/uploads\/Inventories.jpg\" alt=\"\" width=\"775\" height=\"372\" srcset=\"http:\/\/miro.borodziuk.eu\/wp-content\/uploads\/Inventories.jpg 775w, http:\/\/miro.borodziuk.eu\/wp-content\/uploads\/Inventories-300x144.jpg 300w, http:\/\/miro.borodziuk.eu\/wp-content\/uploads\/Inventories-768x369.jpg 768w\" sizes=\"(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><\/p>\n<p><code>YAML<\/code><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-3184 aligncenter\" src=\"http:\/\/miro.borodziuk.eu\/wp-content\/uploads\/Inventories-yaml.jpg\" alt=\"\" width=\"701\" height=\"397\" srcset=\"http:\/\/miro.borodziuk.eu\/wp-content\/uploads\/Inventories-yaml.jpg 701w, http:\/\/miro.borodziuk.eu\/wp-content\/uploads\/Inventories-yaml-300x170.jpg 300w\" sizes=\"(max-width: 701px) 100vw, 701px\" \/><\/p>\n<p><code>INI<\/code><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-3185 aligncenter\" src=\"http:\/\/miro.borodziuk.eu\/wp-content\/uploads\/Inventories-ini.jpg\" alt=\"\" width=\"720\" height=\"284\" srcset=\"http:\/\/miro.borodziuk.eu\/wp-content\/uploads\/Inventories-ini.jpg 720w, http:\/\/miro.borodziuk.eu\/wp-content\/uploads\/Inventories-ini-300x118.jpg 300w\" sizes=\"(max-width: 720px) 100vw, 720px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #3366ff;\">Static &amp; Dynamic Inventories<\/span><\/p>\n<p><span class=\"_5yl5\">Static: <\/span><\/p>\n<ul>\n<li><span class=\"_5yl5\">INI or YAML format <\/span><\/li>\n<li><span class=\"_5yl5\">Maintained by hand <\/span><\/li>\n<li><span class=\"_5yl5\">Easy to manage for static configuration<br \/>\n<\/span><\/li>\n<\/ul>\n<p>Dynamic:<\/p>\n<ul>\n<li>Executable (bash script, python script, etc.)<\/li>\n<li>Script returns JSON containing inventory information<\/li>\n<li>Good for use with cloud resources subject to sudden change<\/li>\n<\/ul>\n<p>On Dynamic Inventories<\/p>\n<ul>\n<li>Specifying an executable file as the inventory is considered a dynamic inventory<\/li>\n<li>JSON output is expected to be returned to\u00a0 STDOUT from the executable<\/li>\n<li>The implementation (python, java, C, bash, etc) does not matter as long as the program can run on the control host and behaves as Ansible expects<\/li>\n<li>The program\/script must respond to two possible parameters:\n<ul>\n<li>&#8211;list<\/li>\n<li>&#8211;host [hostname]<\/li>\n<\/ul>\n<\/li>\n<li>The program script must return JSON in the format Ansible is expecting<\/li>\n<li>Do not forget to make the file executable:\n<ul>\n<li><code>chmod +x dynamic.py<\/code><\/li>\n<\/ul>\n<\/li>\n<li>Using dynamic inventories, you can pull inventory information from the likes of:\n<ul>\n<li>A cloud provider<\/li>\n<li>LDAP<\/li>\n<li>Cobbler<\/li>\n<li>Other CMDB software<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Ansible is an open source configuration management and orchestration utility. It can automate and standardize the configuration of remote hosts and virtual machines. Its orchestration functionality allows Ansible to coordinate the launch and graceful shutdown of multitiered applications. Because of this, Ansible can perform rolling updates of multiple systems in a way that results in &hellip; <\/p>\n<p class=\"link-more\"><a href=\"http:\/\/miro.borodziuk.eu\/index.php\/2020\/01\/06\/automation-with-ansible-1\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Ansible &#8211; Inventory&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":3196,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[86],"tags":[],"_links":{"self":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/3168"}],"collection":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/comments?post=3168"}],"version-history":[{"count":23,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/3168\/revisions"}],"predecessor-version":[{"id":3195,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/posts\/3168\/revisions\/3195"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/media\/3196"}],"wp:attachment":[{"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/media?parent=3168"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/categories?post=3168"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/miro.borodziuk.eu\/index.php\/wp-json\/wp\/v2\/tags?post=3168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}