{"id":19569,"date":"2016-01-18T03:01:28","date_gmt":"2016-01-17T17:01:28","guid":{"rendered":"http:\/\/www.rjmprogramming.com.au\/ITblog\/?p=19569"},"modified":"2018-06-01T21:47:12","modified_gmt":"2018-06-01T11:47:12","slug":"ansible-inventory-primer-tutorial","status":"publish","type":"post","link":"https:\/\/www.rjmprogramming.com.au\/ITblog\/ansible-inventory-primer-tutorial\/","title":{"rendered":"Ansible Inventory Primer Tutorial"},"content":{"rendered":"<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/Inventory\/\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Ansible Inventory Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_inventory-131of.jpg\" title=\"Ansible Inventory Primer Tutorial\"  style=\"float:left;\" id='iapboft' onmouseover=\" this.src=this.src.replace('-11of.jpg','-21of.xjpg').replace('-21of.jpg','-31of.xjpg').replace('-31of.jpg','-51of.xjpg').replace('-51of.jpg','-99of.xjpg').replace('-99of.jpg','-11of.xjpg').replace('.xjpg','.jpg');  \"  \/><\/a><p class=\"wp-caption-text\">Ansible Inventory Primer Tutorial<\/p><\/div>\n<p>The last time we talked about Ansible (with <a title='Ansible Playbook TLS Tutorial' href='#aptt'>Ansible Playbook TLS Tutorial<\/a> is shown below) we advised to read about the subject &#8220;Inventory&#8221;.  Well, today, we dip our toes into this big subject matter, and thank very much &#8220;Ansible Up and Running&#8221; by Lorin Hochstein, specifically, the start of chapter 3.<\/p>\n<p>And in that chapter 3 the book starts to consider deployment scenarios involving lots of servers and server types you might want to classify as &#8230;<\/p>\n<ul>\n<li>production &#8230; live, real system<\/li>\n<li>staging &#8230; to test on host (ie. server) that software team get shared access to)<\/li>\n<li>vagrant &#8230; local server testing<\/li>\n<\/ul>\n<p> &#8230; and groups can be established for functionality types like &#8230;<\/p>\n<ul>\n<li>web server<\/li>\n<li>task queue &#8230; for execution of long-running jobs<\/li>\n<li>(sorry to go) etcetera etcetera etcetera (but there are a lot of things that can go here, as you can imagine)<\/li>\n<\/ul>\n<p>So we programmers will probably spend our time in the reverse order to server types way above, but the modern way of things may be getting them thinking about &#8230;<\/p>\n<ul>\n<li>how their work fits into the big picture, and what the interdependencies are<\/li>\n<li>what supports (or feeds into) the parts they&#8217;re working on, and whether to test software fully, they&#8217;ll need these surrounding functionalities that may require that <i>staging<\/i> server testing environment<\/li>\n<\/ul>\n<p> &#8230; either way, Ansible can aid with understanding and project management and testing regimes and project architecture (understanding), even for those programmers not in the &#8220;big picture&#8221; meeting loop.<\/p>\n<p>Inventory files (in <i>ini<\/i> text format) are the means by which Ansible define your hosts.  Square bracket entries define <i>groups<\/i> (eg. <i>[production]<\/i>).<\/p>\n<p>The first entries in your Ansible project <i>hosts<\/i> Inventory File (we&#8217;ve called our file <hosts<\/i> today, but the book, wisely, advises on using the better name <i>inventory<\/i> and this is controlled in your ansible.cfg file) are a list of hosts involved in the project.  So, today, we&#8217;re setting up a new <i>vagrant up<\/i> scenario to start a new Ansible project on our local 127.0.0.1 local web server and weave these thoughts into a bigger picture scenario &#8220;Ansible Up and Running&#8221; by Lorin Hochstein is very good at helping us imagine.  Pretty obviously, it&#8217;s worth reading, and we don&#8217;t devate much from its example in chapter 3.<\/p>\n<p>So here&#8217;s what we did between <i>nothing<\/i> and getting something sensible from (for example) &#8230;<\/p>\n<p><code>$ ansible vagrant2 -a \"ip addr show dev eth0\"<\/code><\/p>\n<ul>\n<li><code><br \/>\n$ cd $HOME<br \/>\n$ mkdir myboxes<br \/>\n$ mkdir myboxes\/playbooks<br \/>\n$ # ... and so we go to the new place for future \"vagrant up\" scenarios<br \/>\n$ cd myboxes\/playbooks<br \/>\n<\/code><\/li>\n<li><code>$ # Create a 64 bit ubuntu (Oracle) VirtualBox server<br \/>\n$ vagrant init -f ubuntu\/trusty64<\/code><br \/><img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_inventory-114of.jpg\"><\/img><\/li>\n<li><code>$ vi Vagrantfile  # note use of \"config.ssh.inert_key = false\"  allowing for the one SSH key file (to worry about, in ansible.cfg) ... and so ...<\/code><br \/><img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_inventory-114of.jpg\"><\/img><\/li>\n<li><code>$ vi ansible.cfg  # note the reference to the single SSH key file called ~\/.vagrant.d\/insecure_private_key ... and see that we've kept <i>hosts<\/i> as our Inventory File name rather than <i>inventory<\/i> (as per the book's good advice)<\/code><br \/><img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_inventory-124of.jpg\"><\/img><\/li>\n<li><code>$ vagrant up<\/code><br \/><img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_inventory-120of.jpg\"><\/img><img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_inventory-121of.jpg\"><\/img><\/li>\n<\/ul>\n<p> &#8230; like to take a pause at a good &#8220;vagrant up&#8221; scenario &#8230;<\/p>\n<ul>\n<li><code>$ vagrant ssh-config  # informs you what ports to use (and we've got 2201, 2202, 2203 going, whereas the book uses 2222, 2200, 2201)<\/code><br \/><img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_inventory-125of.jpg\"><\/img><\/li>\n<\/ul>\n<p> &#8230; voila &#8230; multiple servers &#8230;<\/p>\n<ul>\n<li><code>$ vi hosts  # first pass<br \/>\n$ cat hosts  # first pass<br \/>\nvagrant1 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2201<br \/>\nvagrant2 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2202<br \/>\nvagrant3 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2203<br \/>\n$ ansible vagrant2 -a \"ip addr show dev eth0\"<br \/>\n<\/code><br \/><img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_inventory-127of.jpg\"><\/img><\/li>\n<\/ul>\n<p>The rest of today&#8217;s tutorial builds on that first pass of &#8220;$ vi hosts&#8221; (and please note at this stage you could start using the more apt filename &#8220;inventory&#8221; if you like) to address this scenario (as comments (that start with #) up the top of the Inventory File) &#8230; huge thanks to &#8220;Ansible Up and Running&#8221; by Lorin Hochstein &#8230;<\/p>\n<blockquote><p>\n# We&#8217;re deploying a Django App (written in Python) &#8230;<br \/>\n# Services are &#8211; Django web app run by Gunicorn HTTP server, nginx web server, Celery task queue for long-running jobs<br \/>\n#              &#8211; RabbitMQ message queue is backend for Celery, Postgres database<br \/>\n# We have three server environment groups &#8230; production (real), staging (testing), vagrant (local testing) and we have two functional groupings &#8230; web server, task queue (for long running jobs)<br \/>\n# Production deployment &#8211; run web app on several hosts for good performance, run task queues on several hosts for good performance<br \/>\n#                       &#8211; put Gunicorn, Celery, RabbitMQ, Postgres on separate servers, two Postgres hosts are primary one and replica\n<\/p><\/blockquote>\n<ul>\n<li><code>$ vi hosts  # second pass makes it an Inventory File<br \/>\n$ cat hosts  # second pass makes it an Inventory File<br \/>\n[production]<br \/>\ndelaware.example.com<br \/>\ngeorgia.example.com<br \/>\nmaryland.example.com<br \/>\nnewhampshire.example.com<br \/>\nnewjersey.example.com<br \/>\nnewyork.example.com<br \/>\nnorthcarolina.example.com<br \/>\npennsylvania.example.com<br \/>\nrhodeisland.example.com<br \/>\nvirginia.example.com<\/p>\n<p>[staging]<br \/>\nontario.example.com<br \/>\nquebec.example.com<\/p>\n<p>[vagrant]<br \/>\nvagrant1 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2201<br \/>\nvagrant2 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2202<br \/>\nvagrant3 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2203 <\/p>\n<p>[lb]<br \/>\ndelaware.example.com<\/p>\n<p>[web]<br \/>\ngeorgia.example.com<br \/>\nnewhampshire.example.com<br \/>\nnewjersey.example.com<br \/>\nontario.example.com<br \/>\nvagrant1<\/p>\n<p>[task]<br \/>\nnewyork.example.com<br \/>\nnorthcarolina.example.com<br \/>\nmaryland.example.com<br \/>\nontario.example.com<br \/>\nvagrant2<\/p>\n<p>[rabbitmq]<br \/>\npennsylvania.example.com<br \/>\nquebec.example.com<br \/>\nvagrant3<\/p>\n<p>[db]<br \/>\nrhodeisland.example.com<br \/>\nvirginia.example.com<br \/>\nquebec.example.com<br \/>\nvagrant3<br \/>\n<\/code><img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_inventory-131of.jpg\"><\/img><\/li>\n<\/ul>\n<p> &#8230; and add in some &#8220;variables&#8221; concepts &#8230;<\/p>\n<ul>\n<li><code>$ vi hosts  # third pass adding variables to Inventory File<br \/>\n$ cat hosts  # third pass adding variables to Inventory File<br \/>\n<\/code><br \/><img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_inventory-132of.jpg\"><\/img><\/li>\n<\/ul>\n<p> &#8230; and reference the [production] variables (via [production:vars] group) off a separate <i>group_vars<\/i>\/<i>production<\/i> configuration file using YAML dictionaries &#8230;<\/p>\n<p><code><br \/>\ndb:<br \/>\n  name: widget_production<br \/>\n  user: widgetuser<br \/>\n  password: nbxgfngfdbnbvcngc<br \/>\n  primary:<br \/>\n    host: rhodeisland.example.com<br \/>\n    port: 5432<br \/>\n  replica:<br \/>\n    host: virginia.example.com<br \/>\n    port: 5432<br \/>\nrabbitmq:<br \/>\n  host: pennsylvania.example.com<br \/>\n  port: 5672<br \/>\n<\/code><br \/><img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_inventory-138of.jpg\"><\/img><\/p>\n<p> &#8230; as shown by the <b>bold<\/b> references in the <i>hosts<\/i> Inventory File (we &#8220;get to&#8221; today) to end up with our <i>hosts<\/i> Inventory File at which point we&#8217;ll break off with our explorations of Ansible with you going off to research &#8220;Dynamic Inventory&#8221; (from the second half of chapter 3 of &#8220;Ansible Up and Running by Lorin Hochstein &#8230; no doubt?!).  Before we go, just wanted to say, that although we don&#8217;t &#8220;make things happen&#8221; today with our &#8220;early days&#8221; scenario, we did check Inventory File syntax by shaping to run a playbook &#8230; we shaped to run one via &#8230; &#8220;$ ansible-playbook web_notls.yml&#8221; # from that playbook of the previous tutorials below.<\/p>\n<p><code><br \/>\n# We're deploying a Django App (written in Python) ...<br \/>\n# Services are - Django web app run by Gunicorn HTTP server, nginx web server, Celery task queue for long-running jobs<br \/>\n#              - RabbitMQ message queue is backend for Celery, Postgres database<br \/>\n# We have three server environment groups ... production (real), staging (testing), vagrant (local testing) and we have two functional groupings ... web server, task queue (for long running jobs)<br \/>\n# Production deployment - run web app on several hosts for good performance, run task queues on several hosts for good performance<br \/>\n#                       - put Gunicorn, Celery, RabbitMQ, Postgres on separate servers, two Postgres hosts are primary one and replica<br \/>\n<b><\/b><br \/>\n[production]<br \/>\ndelaware.example.com<br \/>\ngeorgia.example.com<br \/>\nmaryland.example.com<br \/>\nnewhampshire.example.com<br \/>\nnewjersey.example.com<br \/>\nnewyork.example.com<br \/>\nnorthcarolina.example.com<br \/>\npennsylvania.example.com<br \/>\nrhodeisland.example.com<br \/>\nvirginia.example.com<br \/>\n<b><\/b><br \/>\n[staging]<br \/>\nontario.example.com<br \/>\nquebec.example.com<br \/>\n<b><\/b><br \/>\n[vagrant]<br \/>\nvagrant1 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2201<br \/>\nvagrant2 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2202<br \/>\nvagrant3 ansible_ssh_host=127.0.0.1 ansible_ssh_port=2203<br \/>\n<b><\/b><br \/>\n[lb]<br \/>\ndelaware.example.com<br \/>\n<b><\/b><br \/>\n[web]<br \/>\ngeorgia.example.com<br \/>\nnewhampshire.example.com<br \/>\nnewjersey.example.com<br \/>\nontario.example.com<br \/>\nvagrant1<br \/>\n<b><\/b><br \/>\n[task]<br \/>\nnewyork.example.com<br \/>\nnorthcarolina.example.com<br \/>\nmaryland.example.com<br \/>\nontario.example.com<br \/>\nvagrant2<br \/>\n<b><\/b><br \/>\n[rabbitmq]<br \/>\npennsylvania.example.com<br \/>\nquebec.example.com<br \/>\nvagrant3<br \/>\n<b><\/b><br \/>\n[db]<br \/>\nrhodeisland.example.com<br \/>\nvirginia.example.com<br \/>\nquebec.example.com<br \/>\nvagrant3<br \/>\n<b><\/b><br \/>\n# Variables<br \/>\n<b><\/b><br \/>\n[all:vars]<br \/>\nntp_server=ntp.ubuntu.com<br \/>\n<b><\/b><br \/>\n<b><br \/>\n[production:vars]<br \/>\ndb_primary_host={{ db.primary.host }}<br \/>\ndb_primary_port={{ db.primary.port }}<br \/>\ndb_replica_host={{ db.replica.host }}<br \/>\ndb_name={{ db.name }}<br \/>\ndb_user={{ db.user }}<br \/>\ndb_password={{ db.password }}<br \/>\nrabbitmq_host={{ rabbitmq.host }}<br \/>\nrabbitmq_port={{ rabbitmq.port }}<br \/>\n<\/b><br \/>\n<b><\/b><br \/>\n[staging:vars]<br \/>\ndb_primary_host=quebec.example.com<br \/>\ndb_name=widget_staging<br \/>\ndb_user=widgetuser<br \/>\ndb_password=hbfgdgfgfdhgfdj<br \/>\nrabbitmq_host=quebec.example.com<br \/>\nrabbitmq_port=5672<br \/>\n<b><\/b><br \/>\n[vagrant:vars]<br \/>\ndb_primary_host=vagrant3<br \/>\ndb_primary_port=5432<br \/>\ndb_replica_host=virginia.example.com<br \/>\ndb_name=widget_vagrant<br \/>\ndb_user=widgetuser<br \/>\ndb_password=password<br \/>\nrabbitmq_host=vagrant3<br \/>\nrabbitmq_port=5672<br \/>\n<b><\/b><br \/>\n<\/code><br \/>\n<img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_inventory-139of.jpg\"><\/img><\/p>\n<hr>\n<p id='aptt'>Previous relevant <a target=_blank title='Ansible Playbook TLS Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/ansible-playbook-tls-tutorial\/'>Ansible Playbook TLS Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_playbook_tls-99of.jpg\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Ansible Playbook TLS Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_playbook_tls-99of.jpg\" title=\"Ansible Playbook TLS Tutorial\"  style=\"float:left;\" id='itlsapboft' onmouseover=\" this.src=this.src.replace('-11of.jpg','-21of.xjpg').replace('-21of.jpg','-31of.xjpg').replace('-31of.jpg','-51of.xjpg').replace('-51of.jpg','-99of.xjpg').replace('-99of.jpg','-11of.xjpg').replace('.xjpg','.jpg');  \"  \/><\/a><p class=\"wp-caption-text\">Ansible Playbook TLS Tutorial<\/p><\/div>\n<p>Yesterday saw this blog&#8217;s first Ansible Playbook to create an nginx web server on a VirtualBox virtual machine referenced by http:\/\/localhost:8080 but, did you notice, that https:\/\/localhost:8443 came up with, in Firefox, at least &#8230;<\/p>\n<blockquote><p>\nSecure Connection Failed<br \/>\n<b><\/b><br \/>\nThe connection to localhost:8443 was interrupted while the page was loading.<br \/>\n<b><\/b><br \/>\n    The page you are trying to view cannot be shown because the authenticity of the received data could not be verified.<br \/>\n    Please contact the website owners to inform them of this problem.\n<\/p><\/blockquote>\n<p>? &#8230; And that&#8217;s because we didn&#8217;t cater for Transport Layer Security, or <a target=_blank title='Transport Layer Security information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Transport_Layer_Security'>TLS<\/a>.  So we&#8217;ve got lots to cover as we continue on with Ansible Playbooks &#8230;<\/p>\n<ol>\n<li>more about YAML vs JSON format<\/li>\n<li>what is a Playbook file made up of?<\/li>\n<li>incorporation TLS functionality so that yesterday&#8217;s <a title='Ansible Playbook Primer Tutorial' href='#appt'>Ansible Playbook Primer Tutorial<\/a> is built upon to arrive at a Playbook allowing https:\/\/localhost:8443 to not come up with the error above<\/li>\n<\/ol>\n<p> &#8230; and this constitutes a ramble along through the actions advised in the latter half of Chapter 2 (&#8220;Playbooks: A Beginning&#8221;) of &#8220;Ansible Up and Running&#8221; by Lorin Hochstein, our highly recommended guide for today&#8217;s &#8220;excursion&#8221; and the book from which any quotes below were from. So please fasten your seatbelts and we&#8217;ll be off.<\/p>\n<ol>\n<li><b>more about YAML vs JSON format<\/b>\n<ul>\n<li>First off, did you know<br \/>\n<blockquote><p>a valid JSON file is also a valid YAML file.<\/p><\/blockquote>\n<p>?<\/li>\n<li>YAML files ideally start with three dashes &#8230; as so &#8212;<\/li>\n<li>YAML comments start with # <strike>man<\/strike> person<\/li>\n<li>YAML string syntax often requires no quote not double quote delimitation<\/li>\n<li>\n<blockquote><p>YAML lists are like arrays in JSON and Ruby or lists in Python.<\/p><\/blockquote>\n<p> &#8230; and they are delimited with hyphens ( &#8211; )<\/li>\n<li>\n<blockquote><p>YAML dictionaries are like objects in JSON, dictionaries in Python, or hashes in Ruby.<\/p><\/blockquote>\n<p> &#8230; for example <i><br \/>&nbsp;&nbsp;&nbsp;&nbsp;address: 747 Smith Street<br \/>&nbsp;&nbsp;&nbsp;&nbsp;city: Smithville<br \/>&nbsp;&nbsp;&nbsp;&nbsp;state: North Smithsonian<br \/><\/i><\/li>\n<li>YAML line continuations can happen via the greater than ( &gt; ) symbol usage<\/li>\n<\/ul>\n<\/li>\n<li><b>what is a Playbook file made up of?<\/b>\n<ul>\n<li>A Playbook is made up of a set of Plays.<\/li>\n<li>A play must have a set of <i>hosts<\/i> that are configured<\/li>\n<li>A play must have a list of <i>tasks<\/i> to be executed on the aforesaid mentioned hosts<\/li>\n<li>\n<blockquote><p>Think of a play as the thing that connects hosts to tasks.<\/p><\/blockquote>\n<\/li>\n<li>Tasks optionally have a name (that you saw in square brackets during the <i>ansible-playbook web-notls.yml<\/i> during <a title='Ansible Playbook Primer Tutorial' href='#appt'>Ansible Playbook Primer Tutorial<\/a><\/li>\n<li>Tasks have to have a <i>key<\/i> to a module name followed by <i>arguments<\/i> &#8230; as in <i>&nbsp;&nbsp;&nbsp;&nbsp;apt<\/i>: name=nginx <i>update_cache=yes<\/i> &#8230; and these arguments can be a YAML dictionary &#8230; and an older accepted syntax incorporating the keyword <i>action<\/i> can be <i>&nbsp;&nbsp;&nbsp;&nbsp;action<\/i>: <i>apt<\/i> name=nginx <i>update_cache=yes<\/i><\/li>\n<li>\n<blockquote><p>Modules are scripts that come packaged with Ansible and perform some kind of action on a host.<\/p><\/blockquote>\n<p> &#8230; and what follows are explanations for the five used yesterday &#8230;<\/p>\n<ol>\n<li><i>apt<\/i> installs\/removes packages<\/li>\n<li><i>copy<\/i> copies files from local to host<\/li>\n<li><i>file<\/i> sets file attributes<\/li>\n<li><i>service<\/i> starts\/stops\/restarts service<\/li>\n<li><i>template<\/i> generates file from template and copies to host<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<\/li>\n<li><b>incorporate TLS functionality so that yesterday&#8217;s <a target=_blank title='Ansible Playbook Primer Tutorial' href='#appt'>Ansible Playbook Primer Tutorial<\/a> is built upon to arrive at a Playbook allowing https:\/\/localhost:8443 to not come up with the error above<\/b>\n<ul>\n<li>here&#8217;s the new Playbook we create for TLS functionality you could call <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/web-tls.yml-GETME\" title=\"web-tls.yml\">web-tls.yml<\/a> (built upon yesterday&#8217;s work in <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/web-tls.yml-GETME\" title=\"web-tls.yml\">this way<\/a>) &#8230; that involves two new concepts &#8230;\n<ol>\n<li>variables<\/li>\n<li>handlers<\/li>\n<\/ol>\n<p><code><br \/>\n#!\/usr\/bin\/env ansible-playbook<br \/>\n- name: Configure webserver with nginx and tls<br \/>\n  hosts: webservers<br \/>\n  sudo: True<br \/>\n  vars:<br \/>\n    key_file: \/etc\/nginx\/ssl\/nginx.key<br \/>\n    cert_file: \/etc\/nginx\/ssl\/nginx.crt<br \/>\n    conf_file: \/etc\/nginx\/sites-available\/default<br \/>\n    server_name: localhost<br \/>\n  tasks:<br \/>\n    - name: install nginx<br \/>\n      apt: name=nginx update_cache=yes cache_valid_time=3600<br \/>\n<b><\/b><br \/>\n    - name: create directories for ssl certificates<br \/>\n      file: path=\/etc\/nginx\/ssl state=directory<br \/>\n<b><\/b><br \/>\n    - name: copy TLS key<br \/>\n      copy: src=files\/nginx.key dest={{ key_file }} owner=root mode=0600<br \/>\n      notify: restart nginx<br \/>\n<b><\/b><br \/>\n    - name: copy TLS certificate<br \/>\n      copy: src=files\/nginx.crt dest={{ cert_file }}<br \/>\n      notify: restart nginx<br \/>\n<b><\/b><br \/>\n    - name: copy nginx config file<br \/>\n      template: src=templates\/nginx.conf.j2 dest={{ conf_file }}<br \/>\n      notify: restart nginx<br \/>\n<b><\/b><br \/>\n    - name: enable configuration<br \/>\n      file: dest=\/etc\/nginx\/sites-enabled\/default src={{ conf_file }} state=link<br \/>\n      notify: restart nginx<br \/>\n<b><\/b><br \/>\n    - name: copy index.html<br \/>\n      template: src=templates\/index.html.j2 dest=\/usr\/share\/nginx\/html\/index.html<br \/>\n       mode=0644<br \/>\n<b><\/b><br \/>\n  handlers:<br \/>\n    - name: restart nginx<br \/>\n      service: name=nginx state=restarted<br \/>\n<b><\/b><br \/>\n<\/code>\n<\/li>\n<li>we manually generate TLS certificate (being in $HOME\/mybox\/playbooks like for yesterday&#8217;s work)<br \/>\n<code><br \/>\n$ mkdir files  # unnecessary (because of yesterday's work) but does no damage<br \/>\n$ <a target=_blank title='OpenSSL information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/OpenSSL'>openssl<\/a> req -x509 -nodes -days 3650 -newkey rsa:2048     -subj \/CN=localhost     -keyout files\/nginx.key -out files\/nginx.crt<br \/>\n<\/code><br \/>\n<img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_playbook_tls-11of.jpg\"><\/img><br \/>\n<code><br \/>\n$ vi files\/nginx.conf   # at end (of vi) we !wq templates\/<a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/nginx.conf.j2-GETME\" title=\"nginx.conf.j2\">nginx.conf.j2<\/a> (built upon yesterday's work in <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/PHP\/Geographicals\/diff.php?one=http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/nginx.conf.j2-GETME\" title=\"nginx.conf.j2\">this way<\/a>) as a <a target=_blank title='Jinja information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Jinja_(template_engine)'>Jinja<\/a>2 template<br \/>\n<\/code><br \/>\n<img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_playbook_tls-21of.jpg\"><\/img><br \/>\n<code><br \/>\n$ vagrant reload<br \/>\n<\/code><br \/>\n<img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_playbook_tls-31of.jpg\"><\/img><br \/>\n<code><br \/>\n$ ansible-playbook web-tls.yml<br \/>\n<\/code><br \/>\n<img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_playbook_tls-51of.jpg\"><\/img>\n<\/li>\n<li>\n<blockquote><p>Handlers only run after all the tasks are run, and they only run once, even if they are notified multiple times.<\/p><\/blockquote>\n<\/li>\n<p><img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_playbook_tls-99of.jpg\"><\/img>\n<\/ul>\n<\/li>\n<\/ol>\n<p>To avoid the &#8220;Untrusted Connection&#8221; webpage you&#8217;d need to get the certificate issued by a proper authority rather than being self-signed, as for our example today.  To read on we&#8217;d recommend reading about <a target=_blank title='Ansible Inventory' href='https:\/\/www.google.com.au\/search?q=Ansible+Inventory&#038;ie=utf-8&#038;oe=utf-8&#038;gws_rd=cr&#038;ei=4_CJVsHUGsTFmQWsjbr4AQ'>Ansible Inventory<\/a>.<\/p>\n<hr>\n<p id='appt'>Previous relevant <a target=_blank title='Ansible Playbook Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/ansible-playbook-primer-tutorial\/'>Ansible Playbook Primer Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_playbook-99of.jpg\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Ansible Playbook Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_playbook-99of.jpg\" title=\"Ansible Playbook Primer Tutorial\"  style=\"float:left;\" id='iapboft' onmouseover=\" this.src=this.src.replace('-11of.jpg','-21of.xjpg').replace('-21of.jpg','-31of.xjpg').replace('-31of.jpg','-51of.xjpg').replace('-51of.jpg','-99of.xjpg').replace('-99of.jpg','-11of.xjpg').replace('.xjpg','.jpg');  \"  \/><\/a><p class=\"wp-caption-text\">Ansible Playbook Primer Tutorial<\/p><\/div>\n<p>As a programmer, as time goes on, I get the creeping feeling that more is being asked of our job description.  Pretty sure am not alone, and hope world employment is not going to be too hard hit by similar such &#8220;pushes&#8221;.  Thinking on it, though, what would we expect to happen if robotics seriously became more &#8220;real&#8221;?  Don&#8217;t think it takes a Nostrodamus futurist to have predicted: <i>&#8216;Programmers would be drawn more into the &#8220;modelling&#8221; of systems and &#8220;deployment&#8221;.&#8217;<\/i><\/p>\n<p>So what is great for a project&#8217;s &#8220;bottom line&#8221; would be &#8230;<\/p>\n<ul>\n<li>a programmer doesn&#8217;t lose their expertise in programming and unit testing, as their primary &#8220;length of time&#8221; focus &#8230; yet &#8230;<\/li>\n<li>being as the programmer is there &#8220;in amongst it&#8221; can they help model the (customer) system, help model it, and program in that modelled environment prior to redeployment, even if they are not directly responsible for any of the &#8220;out of office&#8221; parts of setting this modelling up (ie. things are like &#8220;in the old days&#8221; for the programmer geographically speaking (or more convenient, actually), but the modelling means it is like they are in two places at the same time, but not interfering in the operations of that second (customer) environment)? &#8230; oh and yes, that &#8220;modelling&#8221; is simple enough not to spend days upon days attending to it &#8230; and yes, one last thing, that on the next similar such project, the knowledge from the previous one&#8217;s workings is incorporated almost seamlessly into the next?<\/li>\n<\/ul>\n<p> &#8230; and, trying not to overstate all this too much, but deployment with software tools such as <a target=_blank title='Ansible OpenSource project' href='https:\/\/github.com\/ansible\/ansible'>Ansible<\/a> makes all the above possible for (programmer) people whose strength is not exactly &#8220;deployment&#8221; or &#8220;configuration management&#8221;.<\/p>\n<p>The reason to try to not overstate all this is that <a target=_blank title='Ansible OpenSource project' href='https:\/\/github.com\/ansible\/ansible'>Ansible<\/a> is based on very simple principles &#8230; <a target=_blank title=\"Salt vs Ansible\" href=\"http:\/\/jensrantil.github.io\/salt-vs-ansible.html\">&#8220;Ansible is masterless and it uses SSH as its primary communication layer.&#8221;<\/a>.<\/p>\n<p>Today, as with WordPress 4.1.1&#8217;s  <a target=_blank title='Ansible Playbook Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/ansible-playbook-primer-tutorial\/'>Ansible Playbook Primer Tutorial<\/a>, we&#8217;re picking up from where we left off with the last advice from <a title='Ansible Hello World Primer Tutorial' href='#ahwpt'>Ansible Hello World Primer Tutorial<\/a> from two days ago (we studied <a title='Vagrant Primer Tutorial' href='#vpt'>Vagrant Primer Tutorial<\/a> yesterday) &#8230; <\/p>\n<blockquote><p>\nIn the meantime, research into Ansible <a target=_blank href='https:\/\/www.google.com.au\/search?q=ansible+playbook&#038;ie=utf-8&#038;oe=utf-8&#038;gws_rd=cr&#038;ei=uFeIVuinAsO8mgX7uoqYBQ'>Playbooks<\/a> would be a great idea.\n<\/p><\/blockquote>\n<p>Specifically we&#8217;re going to meander along through the actions advised in Chapter 2 (&#8220;Playbooks: A Beginning&#8221;) of &#8220;Ansible Up and Running&#8221; by Lorin Hochstein &#8230; just in case you haven&#8217;t done this yourself.<\/p>\n<p><a title='Ansible Hello World Primer Tutorial' href='#ahwpt'>Ansible Hello World Primer Tutorial<\/a> left us with a <i>Vagrantfile<\/i> &#8230; <img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_playbook-11of.jpg\"><\/img> &#8230; that becomes <img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_playbook-21of.jpg\"><\/img> &#8230; to expose ports 80 and 443 in order to access them, and that requests to ports 8080 and 8443, respectively, are forwarded to 80 and 443 on the Vagrant (Oracle VM VirtualBox) machine &#8230; so that &#8230;<\/p>\n<p><code>vagrant reload<\/code><\/p>\n<p> &#8230; you could call <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/Vagrantfile._GETME\" title=\"Vagrantfile\">Vagrantfile<\/a>  &#8230; looks like &#8230; <img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_playbook-31of.jpg\"><\/img> &#8230; so now we are going to create a playbook that runs an <a target=_blank title='nginx server landing page' href='http:\/\/nginx.org\/en\/'>nginx<\/a> web server via Ansible playbook (YAML) code (we are going to call <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/web-notls.yml_GETME\" title=\"web-notls.yml\">web-notls.yml<\/a>) as below &#8230; <\/p>\n<p><code><br \/>\n#!\/usr\/bin\/env ansible-playbook<br \/>\nname: Configure webserver with nginx<br \/>\nhosts: webservers<br \/>\nsudo: True<br \/>\ntasks:<br \/>\n  - name: install nginx<br \/>\n    apt: name=nginx update_cache=yes<br \/>\n<b><\/b><br \/>\n  - name: copy nginx config file<br \/>\n    copy: src=files\/nginx.conf dest=\/etc\/nginx\/sites-available\/default<br \/>\n<b><\/b><br \/>\n  - name: enable configuration<br \/>\n    file: ><br \/>\n      dest=\/etc\/nginx\/sites-enabled\/default<br \/>\n      src=\/etc\/nginx\/sites-available\/default<br \/>\n      state=link<br \/>\n<b><\/b><br \/>\n  - name: copy index.html<br \/>\n    template: src=templates\/index.html.j2 dest=\/usr\/share\/nginx\/html\/index.html<br \/>\n     mode=0644<br \/>\n<b><\/b><br \/>\n  - name: restart nginx<br \/>\n    service: name=nginx state=restarted<br \/>\n<b><\/b><br \/>\n<\/code><\/p>\n<p> &#8230; and an nginx configuration file (you could call <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/nginx.conf_GETME\" title=\"nginx.conf\">nginx.conf<\/a>) &#8230;<\/p>\n<p> &#8230; and an Ansible template file (you could call <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/index.html.j2_GETME\" title=\"index.html.j2\">index.html.j2<\/a>) &#8230; to result in &#8230;<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible_playbook-51of.jpg\"><\/img><\/p>\n<p>So that&#8217;s a simple Ansible playbook example for you, and we hope to develop this further over time.  Even so, have to tell you that at the browser going &#8220;http:\/\/localhost:8080&#8221; for a while I was getting <i>&#8216;Safari can\u2019t open the page \u201c\u200elocalhost:8080\/index.html\u201d because the server unexpectedly dropped the connection. This sometimes occurs when the server is busy. Wait for a few minutes, and then try again.&#8217;<\/i>  As <i>ansible-playbook web-notls.yml<\/i> had shown no errors, tried <i>ansible-playbook -vvvv web-notls.yml<\/i> with no difference.  After lot of looking around found it to be an &#8220;up to&#8221; threefold issue &#8230;<\/p>\n<ol>\n<li>misspelling in <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/nginx.conf_GETME\" title=\"nginx.conf\">nginx.conf<\/a> leaving out the first 6 (in &#8220;ipv6only&#8221;)<\/li>\n<li>do System Preferences&#8230; -&gt; Sharing show Remote Login is ticked on as per advice of <a target=_blank title='Useful link' href='http:\/\/www.sawantshah.com\/tech-talk\/resolution-of-ansible-issues-on-os-x-mavericks\/'>this link<\/a>?<\/li>\n<li>you may have been an eagle eyed one to notice that 2 days ago we had a (SSH friendly) port of 2200 being used for the &#8220;testserver&#8221; Ansible server of use (this happened due to some previous Ansible work) but this means that 2 days ago a record was written to <i>~\/.ssh\/known_hosts<\/i> for 127.0.0.1:2200 during that <i>vagrant up<\/i> run.  Now, as today&#8217;s work has not caused any initialization vagrant commands, nor even <i>vagrant halt<\/i> nor <i>vagrant up<\/i> to occur, when we ran <i>vagrant reload<\/i> after changing <a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/Vagrantfile._GETME\" title=\"Vagrantfile\">Vagrantfile<\/a> for those forwarding port changes made the default (SSH friendly) port 2222 come back into play and write a new record for 127.0.0.1:2222 at the end of <i>~\/.ssh\/known_hosts<\/i> (and how was this lead gotten to? &#8230; the &#8220;ssh -i .vagrant\/machines\/default\/virtualbox\/private_key vagrant@127.0.0.1 -p 2200&#8221; of 2 days ago was rerun today as &#8220;ssh -i .vagrant\/machines\/default\/virtualbox\/private_key vagrant@127.0.0.1 -p 2222&#8221; and caused an SSH error &#8230;<\/p>\n<p><code><br \/>\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<br \/>\n@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @<br \/>\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<br \/>\nIT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!<br \/>\nSomeone could be eavesdropping on you right now (man-in-the-middle attack)!<br \/>\nIt is also possible that a host key has just been changed.<br \/>\nThe fingerprint for the RSA key sent by the remote host is<br \/>\n87:blah:blah:blah:57.<br \/>\nPlease contact your system administrator.<br \/>\nAdd correct host key in \/Library\/pgAgent\/.ssh\/known_hosts to get rid of this message.<br \/>\nOffending RSA key in \/Library\/pgAgent\/.ssh\/known_hosts:8<br \/>\nRSA host key for [127.0.0.1]:2222 has changed and you have requested strict checking.<br \/>\nHost key verification failed.<br \/>\n<\/code><\/p>\n<p>).  Now those two records at the end of <i>~\/.ssh\/known_hosts<\/i> were different.  Making them the same except for the port number (doh!) made things work for the nginx server at http:\/\/localhost:8080\/ &#8230; so might an initialization vagrant scenario (plus all the rest), but didn&#8217;t try that.<\/li>\n<\/ol>\n<hr>\n<p id='vpt'>Previous relevant <a target=_blank title='Vagrant Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/vagrant-primer-tutorial'>Vagrant Primer Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/vagrant_primer.jpg\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Vagrant Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/vagrant_primer.jpg\" title=\"Vagrant Primer Tutorial\"  style=\"float:left;\"   \/><\/a><p class=\"wp-caption-text\">Vagrant Primer Tutorial<\/p><\/div>\n<p>In understanding what is out there on the net, tend to want to form relationships in my mind, between applications.<\/p>\n<p>So here&#8217;s a good one &#8230; <a target=_blank title='VirtualBox by Oracle' href='https:\/\/www.virtualbox.org\/'>VirtualBox<\/a> with Vagrant &#8230; or perhaps &#8230; <a target=_blank title='VirtualMachine by VMWare' href='https:\/\/www.vmware.com\/au'>VirtualMachine<\/a> with Vagrant.<\/p>\n<p>So here&#8217;s another one that&#8217;ll knock your socks off (and you&#8217;ll want to read after\/before\/same time\/while having corn flakes as today (to get it all in context, if this is new knowledge)) &#8230; <a target=_blank title='Ansible OpenSource project' href='https:\/\/github.com\/ansible\/ansible'>Ansible<\/a> with Vagrant, that we talked about yesterday with <a title='Ansible Hello World Primer Tutorial' href='#ahwpt'>Ansible Hello World Primer Tutorial<\/a> as shown below.  As you read it, take note of the title of the book we recommend &#8230; &#8220;Ansible Up and Running&#8221; by Lorin Hochstein &#8230; the word &#8220;up&#8221; is bound to be in the list of a  deployer&#8217;s favourite words, and is critical to all &#8220;Vagrant&#8221; talk as its favourite command (and its &#8220;nirvana&#8221; (if successful), and is slow the first time (when &#8220;vagrant up&#8221; is often preceded by an initialization vagrant command such as &#8220;vagrant init ubuntu\/trusty32&#8221;) with a project on an individual programmer&#8217;s system, but fast from then on for that programmer &#8220;revisiting&#8221;, so that on multiple projects they&#8217;re zooming (ie. cd&#8217;ing) around to places and going &#8220;vagrant up&#8221; <font size=3>vagrant up<\/font> <font size=2>vagrant up<\/font> <font size=1>vagrant up<\/font>) is &#8230;<br \/>\n<code>vagrant up<\/code><br \/>\n &#8230; and for today&#8217;s book recommendation &#8230; &#8220;Vagrant Up and Running&#8221; by Mitchell Hashimoto &#8230; fancy that?!\n<\/p>\n<p>So what&#8217;s <a target=_blank title='Vagrant' href='http:\/\/www.vagrantup.com\/'>Vagrant<\/a>?  And why is it so friendly?<\/p>\n<p>Can try to answer the first now, but the second one relates to early times spent with Caspar the Ghost &#8230; but we digress.<\/p>\n<p>To quote the Vagrant landing page &#8230;<\/p>\n<blockquote><p>\nCreate and configure lightweight, reproducible, and portable development environments.\n<\/p><\/blockquote>\n<p>What we understand in layperson&#8217;s terms is that if a client plonks a &#8220;system&#8221; on your doorstep and says any of &#8230;<\/p>\n<ol>\n<li>&#8220;Fix this.&#8221;<\/li>\n<li>&#8220;Maintain this.&#8221;<\/li>\n<li>&#8220;Make it do this, now (awwwwwwwright &#8230; after lunch, then).&#8221;<\/li>\n<\/ol>\n<p> &#8230; Vagrant may interface to an IDE like <a target=_blank title='PHPStorm IDE' href='https:\/\/www.jetbrains.com\/phpstorm\/'>PHPStorm<\/a> (which we&#8217;ll talk about soon) or use Git (or GitHub) and\/or Composer in a Work Flow helping a group of team leaders and dbas and analysts and programmers achieve this by &#8230;<\/p>\n<ul>\n<li>simulating the whole system<\/li>\n<li>modelling the whole system<\/li>\n<li>changing and modifying the resultant model, to check things improve, and still work, hopefully<\/li>\n<li>deploy this model back onto the reality, for the client to model a broad grin, hopefully<\/li>\n<\/ul>\n<p>Without this Vagrant and VirtualDisk (or VMWare) relationship, the job can be done, but you often find the (different) environment (between the programmer environments and the client environment) causes problems during the deployment phase, whereas using these products helps mitigate against these issues.  Comprehendo?<\/p>\n<hr>\n<p id='ahwpt'>Previous relevant <a target=_blank title='Ansible Hello World Primer Tutorial' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/ansible-hello-world-primer-tutorial'>Ansible Hello World Primer Tutorial<\/a> is shown below.<\/p>\n<div style=\"width: 230px\" class=\"wp-caption alignnone\"><a target=_blank href=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible-99of.jpg\"><img decoding=\"async\" style=\"border: 15px solid pink;\" alt=\"Ansible Hello World Primer Tutorial\" src=\"http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible-99of.jpg\" title=\"Ansible Hello World Primer Tutorial\"  style=\"float:left;\" id='iaoft' onmouseover=\" this.src=this.src.replace('-51of.jpg','-61of.xjpg').replace('-61of.jpg','-71of.xjpg').replace('-71of.jpg','-92of.xjpg').replace('-92of.jpg','-93of.xjpg').replace('-93of.jpg','-94of.xjpg').replace('-94of.jpg','-97of.xjpg').replace('-97of.jpg','-99of.xjpg').replace('-99of.jpg','-51of.xjpg').replace('.xjpg','.jpg');  \"  \/><\/a><p class=\"wp-caption-text\">Ansible Hello World Primer Tutorial<\/p><\/div>\n<p>The role of a programmer is expanding into deployment with software tools such as <a target=_blank title='Ansible OpenSource project' href='https:\/\/github.com\/ansible\/ansible'>Ansible<\/a>, because it has the capability of making the piloting of automation systems &#8220;approachable&#8221; as an &#8220;art&#8221;.<\/p>\n<p>Why would you want to &#8220;pilot an automation system&#8221;?  Well, to see the whole picture, when you (are part of a team that) are given a software project of improving a &#8220;system&#8221;, wouldn&#8217;t it be great to &#8230;<\/p>\n<ul>\n<li>model that customer system at a snapshot of time<\/li>\n<li>be able to work and test on that model away from the customer environment until satisfaction<\/li>\n<li>after changes are tested to satisfaction, redeploy to the customer&#8217;s live system via software changes made to the model, and perhaps to data and configuration settings as well<\/li>\n<\/ul>\n<p>?  We think it sounds very good, especially with Ansible helping out with that modelling, because a lot of the doubt in a programmer&#8217;s head when working away from a customer site&#8217;s environment (back at their office, perhaps) on a project that is going to be deployed back at the customer is that what they are seeing working, may not work when taken back and deployed onto the customer site&#8217;s environment again.  The work methods above help to mitigate that, and Ansible really helps with the deployment aspects to the whole job, leaving programmers more time to get back to what they enjoy the most, methinks &#8230; programming and unit testing.<\/p>\n<p>Without Ansible, achieving a project with new (never before used) software tools required, involves programmers working out the <i>configuration management<\/i> aspects to the job via Search Engine Searches (with a lot of &#8220;Adding to Favourites&#8221;) and\/or the recalling of online documents (often from the OpenSource world), and trialling configurations, hopefully combined with personalized accompanying documentation.   Employing Ansible into the planning may still involve this initial effort, but should never happen again, because what you are left with will be an Ansible approach capturing knowledge that has a far better chance of staying up to date.<\/p>\n<p>Ansible is pretty obviously most advantageous in complex deployment scenarios, but it can be applied to the one server (and we are talking Linux or Unix with this today, but <a target=_blank href='http:\/\/www.ansible.com\/windows' title='Ansible for Windows support'>Windows<\/a> is also supported) scenario as well, and we&#8217;ll be showing a bit of this today, to show you a bit about how Ansible works.<\/p>\n<p>Let&#8217;s, before that, do a glossary list of terms (mainly from Wikipedia .. thanks) we might use in relation to Ansible &#8230;<\/p>\n<ul>\n<li><a target=_blank title='Configuration management information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Configuration_management'>configuration management<\/a> &#8230; that&#8217;s Ansible<\/li>\n<li><a target=_blank title='Provisioning information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Provisioning#Server_provisioning'>provisioning<\/a> <a target=_blank title='Privisioning tool discussion' href='http:\/\/www.computerworld.com\/article\/2570007\/security0\/how-to-choose-a-provisioning-tool.html'>tool<\/a> &#8230; that&#8217;s Ansible<\/li>\n<li><a target=_blank title='Ansible OpenSource project' href='https:\/\/github.com\/ansible\/ansible'>Ansible<\/a> on GitHub by Michael DeHaan<\/li>\n<li><a target=_blank title='Secure shell information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Secure_Shell'>SSH<\/a><\/li>\n<li><a target=_blank title='YAML information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/YAML'>YAML<\/a> (and <a target=_blank href='https:\/\/www.google.com.au\/search?q=ansible+playbook&#038;ie=utf-8&#038;oe=utf-8&#038;gws_rd=cr&#038;ei=uFeIVuinAsO8mgX7uoqYBQ'>Playbooks<\/a>)<\/li>\n<li><a target=_blank title='JSON information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/JSON'>JSON<\/a><\/li>\n<li><a target=_blank title='Package manager information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Package_manager'>package manager<\/a> &#8230; eg. Homebrew, apt, YUM, MacPorts, pip, RPM, OpenPKG, nix, Conary, dpkg, Cygwin<\/li>\n<li><a target=_blank title='Jinja information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Jinja_(template_engine)'>Jinja<\/a> template manager<\/li>\n<li><a target=_blank title='Solution stack information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Solution_stack'>development stack<\/a><\/li>\n<li><a target=_blank title='Deployment information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Software_deployment'>deployment<\/a><\/li>\n<li><a target=_blank title='Virtual machine information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Virtual_machine'>virtual machine<\/a><\/li>\n<li><a target=_blank title='Automation information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Test_automation'>automation<\/a><\/li>\n<li><a target=_blank title='Source control information from Wikipedia ... thanks' href='https:\/\/en.wikipedia.org\/wiki\/Source_Code_Control_System'>source control<\/a><\/li>\n<li><a target=_blank title='Oracle VM VirtualNox' href='https:\/\/www.virtualbox.org\/'>VirtualBox<\/a><\/li>\n<li><a target=_blank title='Vagrant VMWare integration' href='https:\/\/www.vagrantup.com\/'>Vagrant<\/a> &#8230; more tomorrow <a target=_blank title='Vagrant Primer Tutorial will be available on 3rd January 2016' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/vagrant-primer-tutorial'>here<\/a><\/li>\n<li><a target=_blank title='GitHib repository' href='https:\/\/github.com\/'>GitHub<\/a><\/li>\n<li><a target=_blank title='PHPStorm IDE' href='https:\/\/www.jetbrains.com\/phpstorm\/'>PHPStorm<\/a> IDE we&#8217;ve mentioned before <a target=_blank title='PHPStorm postings here' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/phpstorm'>here<\/a> (integrates some of concepts above)<\/li>\n<\/ul>\n<p> &#8230; and direct you towards a good book, namely &#8220;Ansible Up and Running&#8221; by Lorin Hochstein, from which a lot of today&#8217;s blog posting&#8217;s information is derived &#8230; so, thanks.<\/p>\n<p>Okay, so what will we do with Ansible?<\/p>\n<p><b>Install<\/b> Ansible &#8230; on Mac OS X (via Terminal application) &#8230; and you&#8217;ll need <a target=_blank title='ssh via OpenSSH' href='http:\/\/www.openssh.com\/'>ssh<\/a> (if &#8220;ssh&#8221; on command line means nothing) &#8230; if you have <a target=_blank title='Homebrew Package Manager' href='http:\/\/brew.sh\/'>Homebrew<\/a> package manager installed you can go &#8230;<\/p>\n<p><code><a target=_blank title='Install Ansible on Mac OSX' href='https:\/\/valdhaus.co\/writings\/ansible-mac-osx\/'>$ brew install ansible<\/a><\/code><\/p>\n<p> &#8230; or you can install as root via Python&#8217;s pip package manager &#8230;<\/p>\n<p><code>$ sudo pip install ansible<\/code><\/p>\n<p> &#8230; or another way to install as root via the apt package manager &#8230;<\/p>\n<p><code>$ sudo apt-add-repository -y ppa:ansible\/ansible<br \/>\n$ sudo apt-get update<br \/>\n$ sudo apt-get install -y ansible<\/code><\/p>\n<p> &#8230; or you can install into a <a target=_blank title='Python landing page' href='https:\/\/www.python.org\/'>Python<\/a> (2.6 or above) <i>virtualenv<\/i> with <a target=_blank title='wget GNU' href='https:\/\/www.gnu.org\/software\/wget\/'>wget<\/a> via &#8230;<\/p>\n<p><code>$ wget https:\/\/raw.githubusercontent.com\/mitsuhiko\/pipsi\/master\/get-pipsi.py<br \/>\n$ python get-pipsi.py<br \/>\n$ pipsi install ansible<\/code><\/p>\n<p> ( with an updating of PATH to include <i>~\/.local\/bin<\/i> ) &#8230; or you can use GitHub via &#8230;<\/p>\n<p><code>$ git clone https:\/\/github.com\/ansible\/ansible.git --recursive<\/code><\/p>\n<p> &#8230; so that you can have &#8230;<\/p>\n<p><code>$ ansible<\/code><\/p>\n<p> &#8230; mean something at a command prompt (if not, a &#8220;find \/ -name &#8216;ansible&#8217; 2&gt; \/dev\/null&#8221; and adjustment of PATH in ~\/.profile may be necessary) &#8230; a suffix of &#8221; -vvvv&#8221; is useful for debugging purposes.<\/p>\n<p><b>Show you a 127.0.0.1 local web server with VirtualBox &#8220;Hello World&#8221; feeling example<\/b> using Ansible involved the need for installation, as required of Oracle&#8217;s <a target=_blank title='Virtaul VM VirtualBox by Oracle' href='https:\/\/www.virtualbox.org\/'>VirtualBox<\/a> and, for tomorrow specifically, we talk about <a target=_blank title='Vagrant VMWare integration' href='https:\/\/www.vagrantup.com\/'>Vagrant<\/a> via &#8230;<\/p>\n<p><!--img title='VirtualBox new Linux Ubuntu (64 bit)' src='http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible-51of.jpg'><\/img>\n<img title='VirtualBox new Linux Ubuntu (64 bit)' src='http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible-61of.jpg'><\/img--><\/p>\n<p><a target=_blank title='Vagrant Primer Tutorial will be available on 3rd January 2016' href='https:\/\/www.rjmprogramming.com.au\/ITblog\/vagrant-primer-tutorial'><img title='Vagrant Primer Tutorial will be available on 3rd January 2016' src='http:\/\/www.rjmprogramming.com.au\/Mac\/vagrant_primer.jpg'><\/img><\/a><\/p>\n<p> &#8230; then, working off the install we made of Ansible we found an example <i>hosts<\/i> file off the install, and copied it to \/etc\/ansible\/hosts.orig as shown by &#8230;<\/p>\n<p><img title='Arrange hosts.orig Ansible file in \/etc\/ansible' src='http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible-71of.jpg'><\/img><\/p>\n<p><code><br \/>\n$ cd $HOME<br \/>\n$ mkdir mybox<br \/>\n$ cd mybox<br \/>\n$ mkdir playbooks<br \/>\n$ cd playbooks<br \/>\n$ vagrant init ubuntu\/trusty32<br \/>\n$ vagrant up<br \/>\n<\/code><\/p>\n<p><img title='Arrange hosts.orig Ansible file in \/etc\/ansible' src='http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible-92of.jpg'><\/img><br \/>\n<img title='Arrange hosts.orig Ansible file in \/etc\/ansible' src='http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible-93of.jpg'><\/img><br \/>\n<img title='Arrange hosts.orig Ansible file in \/etc\/ansible' src='http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible-94of.jpg'><\/img><\/p>\n<p><code><br \/>\n$ ssh -i .vagrant\/machines\/default\/virtualbox\/private_key vagrant@127.0.0.1 -p 2200<br \/>\n       vagrant@vagrant-ubuntu-trusty-32:~$ echo \"Hello World ... via Ansible\"<br \/>\n       Hello World ... via Ansible<br \/>\n       vagrant@vagrant-ubuntu-trusty-32:~$ exit<br \/>\n$ cat hosts<br \/>\n$ head -15 ansible.cfg<br \/>\n$ ansible testserver -m ping<br \/>\n$ ansible testserver -a uptime<br \/>\n<\/code><\/p>\n<p><img title='VirtualBox new Linux Ubuntu (32 bit)' src='http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible-97of.jpg'><\/img><br \/>\n<img title='VirtualBox new Linux Ubuntu (32 bit)' src='http:\/\/www.rjmprogramming.com.au\/Mac\/Ansible\/ansible-99of.jpg'><\/img><\/p>\n<p>Ansible is not alone with what it sets out to achieve &#8230; think Chef, Puppet or Salt &#8230; read more thanks to this <a target=_blank title='Useful link' href='https:\/\/serversforhackers.com\/an-ansible-tutorial'>useful link<\/a> for that information.<\/p>\n<p>We hope to be back with more about this powerful product as time goes by.  In the meantime, research into Ansible <a target=_blank href='https:\/\/www.google.com.au\/search?q=ansible+playbook&#038;ie=utf-8&#038;oe=utf-8&#038;gws_rd=cr&#038;ei=uFeIVuinAsO8mgX7uoqYBQ'>Playbooks<\/a> would be a great idea.<\/p>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d19261' onclick='var dv=document.getElementById(\"d19261\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/server\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d19261' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d18803' onclick='var dv=document.getElementById(\"d18803\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/virtualdisk\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d18803' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d19294' onclick='var dv=document.getElementById(\"d19294\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/ssh\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d19294' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d19356' onclick='var dv=document.getElementById(\"d19356\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/tls\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d19356' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n<hr>\n<p>If this was interesting you may be interested in <a title='Click here to see topics in which you might be interested' href='#d19569' onclick='var dv=document.getElementById(\"d19569\"); dv.innerHTML = \"&lt;iframe width=670 height=600 src=\" + \"https:\/\/www.rjmprogramming.com.au\/ITblog\/tag\/playbook\" + \"&gt;&lt;\/iframe&gt;\"; dv.style.display = \"block\";'>this<\/a> too.<\/p>\n<div id='d19569' style='display: none; border-left: 2px solid green; border-top: 2px solid green;'><\/div>\n","protected":false},"excerpt":{"rendered":"<p>The last time we talked about Ansible (with Ansible Playbook TLS Tutorial is shown below) we advised to read about the subject &#8220;Inventory&#8221;. Well, today, we dip our toes into this big subject matter, and thank very much &#8220;Ansible Up &hellip; <a href=\"https:\/\/www.rjmprogramming.com.au\/ITblog\/ansible-inventory-primer-tutorial\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,18,19,25,29,31,33,37],"tags":[1880,249,1768,611,1783,1775,707,1774,1952,886,1770,1769,1114,1122,1166,1176,1773,1319,1339,1754],"class_list":["post-19569","post","type-post","status-publish","format-standard","hentry","category-elearning","category-hardware","category-installers","category-networking","category-operating-system","category-projects","category-software","category-tutorials","tag-ansible","tag-configuration","tag-deployment","tag-install","tag-inventory","tag-jinja","tag-linux","tag-nginx","tag-openssl","tag-operations","tag-playbook","tag-provisioning","tag-security","tag-server","tag-software-2","tag-source-control","tag-tls","tag-tutorial","tag-unix","tag-vagrant"],"_links":{"self":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/19569"}],"collection":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/comments?post=19569"}],"version-history":[{"count":11,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/19569\/revisions"}],"predecessor-version":[{"id":38565,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/posts\/19569\/revisions\/38565"}],"wp:attachment":[{"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/media?parent=19569"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/categories?post=19569"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rjmprogramming.com.au\/ITblog\/wp-json\/wp\/v2\/tags?post=19569"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}