Yesterday saw this blogโs first Ansible Playbook to create an nginx web server on a VirtualBox virtual machine referenced by //localhost:8080 but, did you notice, that https://localhost:8443 came up with, in Firefox, at least โฆ
Secure Connection Failed
The connection to localhost:8443 was interrupted while the page was loading.
The page you are trying to view cannot be shown because the authenticity of the received data could not be verified.
Please contact the website owners to inform them of this problem.
? โฆ And thatโs because we didnโt cater for Transport Layer Security, or TLS. So weโve got lots to cover as we continue on with Ansible Playbooks โฆ
- more about YAML vs JSON format
- what is a Playbook file made up of?
- incorporation TLS functionality so that yesterdayโs Ansible Playbook Primer Tutorial is built upon to arrive at a Playbook allowing https://localhost:8443 to not come up with the error above
โฆ and this constitutes a ramble along through the actions advised in the latter half of Chapter 2 (โPlaybooks: A Beginningโ) of โAnsible Up and Runningโ by Lorin Hochstein, our highly recommended guide for todayโs โexcursionโ and the book from which any quotes below were from. So please fasten your seatbelts and weโll be off.
- more about YAML vs JSON format
- First off, did you know
a valid JSON file is also a valid YAML file.
?
- YAML files ideally start with three dashes โฆ as so โ
- YAML comments start with #
manperson - YAML string syntax often requires no quote not double quote delimitation
-
YAML lists are like arrays in JSON and Ruby or lists in Python.
โฆ and they are delimited with hyphens ( โ )
-
YAML dictionaries are like objects in JSON, dictionaries in Python, or hashes in Ruby.
โฆ for example
address: 747 Smith Street
city: Smithville
state: North Smithsonian - YAML line continuations can happen via the greater than ( > ) symbol usage
- First off, did you know
- what is a Playbook file made up of?
- A Playbook is made up of a set of Plays.
- A play must have a set of hosts that are configured
- A play must have a list of tasks to be executed on the aforesaid mentioned hosts
-
Think of a play as the thing that connects hosts to tasks.
- Tasks optionally have a name (that you saw in square brackets during the ansible-playbook web-notls.yml during Ansible Playbook Primer Tutorial
- Tasks have to have a key to a module name followed by arguments โฆ as in apt: name=nginx update_cache=yes โฆ and these arguments can be a YAML dictionary โฆ and an older accepted syntax incorporating the keyword action can be action: apt name=nginx update_cache=yes
-
Modules are scripts that come packaged with Ansible and perform some kind of action on a host.
โฆ and what follows are explanations for the five used yesterday โฆ
- apt installs/removes packages
- copy copies files from local to host
- file sets file attributes
- service starts/stops/restarts service
- template generates file from template and copies to host
- incorporate TLS functionality so that yesterdayโs Ansible Playbook Primer Tutorial is built upon to arrive at a Playbook allowing https://localhost:8443 to not come up with the error above
- hereโs the new Playbook we create for TLS functionality you could call web-tls
yml (built upon yesterdayโs work in thisway) โฆ that involves two new concepts โฆ
- variables
- handlers
#!/usr/bin/env ansible-playbook
- name: Configure webserver with nginx and tls
hosts: webservers
sudo: True
vars:
key_file: /etc/nginx/ssl/nginx.key
cert_file: /etc/nginx/ssl/nginx.crt
conf_file: /etc/nginx/sites-available/default
server_name: localhost
tasks:
- name: install nginx
apt: name=nginx update_cache=yes cache_valid_time=3600
- name: create directories for ssl certificates
file: path=/etc/nginx/ssl state=directory
- name: copy TLS key
copy: src=files/nginx.key dest={{ key_file }} owner=root mode=0600
notify: restart nginx
- name: copy TLS certificate
copy: src=files/nginx.crt dest={{ cert_file }}
notify: restart nginx
- name: copy nginx config file
template: src=templates/nginx.conf.j2 dest={{ conf_file }}
notify: restart nginx
- name: enable configuration
file: dest=/etc/nginx/sites-enabled/default src={{ conf_file }} state=link
notify: restart nginx
- name: copy index.html
template: src=templates/index.html.j2 dest=/usr/share/nginx/html/index.html
mode=0644
handlers:
- name: restart nginx
service: name=nginx state=restarted - we manually generate TLS certificate (being in $HOME/mybox/playbooks like for yesterdayโs work)
$ mkdir files # unnecessary (because of yesterday's work) but does no damage
$ openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -subj /CN=localhost -keyout files/nginx.key -out files/nginx.crt
$ vi files/nginx.conf # at end (of vi) we !wq templates/nginxconf.j2 (built upon yesterday's work in thisway) as a Jinja2 template
$ vagrant reload
$ ansible-playbook web-tls.yml
-
Handlers only run after all the tasks are run, and they only run once, even if they are notified multiple times.
- hereโs the new Playbook we create for TLS functionality you could call web-tls
To avoid the โUntrusted Connectionโ webpage youโ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โd recommend reading about Ansible Inventory.
Previous relevant Ansible Playbook Primer Tutorial is shown below.
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 โpushesโ. Thinking on it, though, what would we expect to happen if robotics seriously became more โrealโ? Donโt think it takes a Nostrodamus futurist to have predicted: โProgrammers would be drawn more into the โmodellingโ of systems and โdeploymentโ.โ
So what is great for a projectโs โbottom lineโ would be โฆ
- a programmer doesnโt lose their expertise in programming and unit testing, as their primary โlength of timeโ focus โฆ yet โฆ
- being as the programmer is there โin amongst itโ 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 โout of officeโ parts of setting this modelling up (ie. things are like โin the old daysโ 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)? โฆ oh and yes, that โmodellingโ is simple enough not to spend days upon days attending to it โฆ and yes, one last thing, that on the next similar such project, the knowledge from the previous oneโs workings is incorporated almost seamlessly into the next?
โฆ and, trying not to overstate all this too much, but deployment with software tools such as Ansible makes all the above possible for (programmer) people whose strength is not exactly โdeploymentโ or โconfiguration managementโ.
The reason to try to not overstate all this is that Ansible is based on very simple principles โฆ โAnsible is masterless and it uses SSH as its primary communication layer.โ.
Today, as with WordPress 4.1.1โs Ansible Playbook Primer Tutorial, weโre picking up from where we left off with the last advice from Ansible Hello World Primer Tutorial from two days ago (we studied Vagrant Primer Tutorial yesterday) โฆ
In the meantime, research into Ansible Playbooks would be a great idea.
Specifically weโre going to meander along through the actions advised in Chapter 2 (โPlaybooks: A Beginningโ) of โAnsible Up and Runningโ by Lorin Hochstein โฆ just in case you havenโt done this yourself.
Ansible Hello World Primer Tutorial left us with a Vagrantfile โฆ โฆ that becomes
โฆ 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 โฆ so that โฆ
vagrant reload
โฆ you could call Vagrantfile โฆ looks like โฆ โฆ so now we are going to create a playbook that runs an nginx web server via Ansible playbook (YAML) code (we are going to call web-notls
yml) as below โฆ
#!/usr/bin/env ansible-playbook
name: Configure webserver with nginx
hosts: webservers
sudo: True
tasks:
- name: install nginx
apt: name=nginx update_cache=yes
- name: copy nginx config file
copy: src=files/nginx.conf dest=/etc/nginx/sites-available/default
- name: enable configuration
file: >
dest=/etc/nginx/sites-enabled/default
src=/etc/nginx/sites-available/default
state=link
- name: copy index.html
template: src=templates/index.html.j2 dest=/usr/share/nginx/html/index.html
mode=0644
- name: restart nginx
service: name=nginx state=restarted
โฆ and an nginx configuration file (you could call nginxconf) โฆ
โฆ and an Ansible template file (you could call indexhtml.j2) โฆ to result in โฆ
So thatโ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 โ//localhost:8080โ for a while I was getting โSafari canโt open the page โโlocalhost:8080/index.htmlโ because the server unexpectedly dropped the connection. This sometimes occurs when the server is busy. Wait for a few minutes, and then try again.โ As ansible-playbook web-notls.yml had shown no errors, tried ansible-playbook -vvvv web-notls.yml with no difference. After lot of looking around found it to be an โup toโ threefold issue โฆ
- misspelling in nginx
conf leaving out the first 6 (in โipv6onlyโ)
- do System Preferencesโฆ -> Sharing show Remote Login is ticked on as per advice of this link?
- 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 โtestserverโ Ansible server of use (this happened due to some previous Ansible work) but this means that 2 days ago a record was written to ~/.ssh/known_hosts for 127.0.0.1:2200 during that vagrant up run. Now, as todayโs work has not caused any initialization vagrant commands, nor even vagrant halt nor vagrant up to occur, when we ran vagrant reload after changing Vagrantfile 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 ~/.ssh/known_hosts (and how was this lead gotten to? โฆ the โssh -i .vagrant/machines/default/virtualbox/private_key vagrant@127.0.0.1 -p 2200โ of 2 days ago was rerun today as โssh -i .vagrant/machines/default/virtualbox/private_key vagrant@127.0.0.1 -p 2222โ and caused an SSH error โฆ
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
87:blah:blah:blah:57.
Please contact your system administrator.
Add correct host key in /Library/pgAgent/.ssh/known_hosts to get rid of this message.
Offending RSA key in /Library/pgAgent/.ssh/known_hosts:8
RSA host key for [127.0.0.1]:2222 has changed and you have requested strict checking.
Host key verification failed.). Now those two records at the end of ~/.ssh/known_hosts were different. Making them the same except for the port number (doh!) made things work for the nginx server at //localhost:8080/ โฆ so might an initialization vagrant scenario (plus all the rest), but didnโt try that.
Previous relevant Vagrant Primer Tutorial is shown below.
In understanding what is out there on the net, tend to want to form relationships in my mind, between applications.
So hereโs a good one โฆ VirtualBox with Vagrant โฆ or perhaps โฆ VirtualMachine with Vagrant.
So hereโs another one thatโll knock your socks off (and youโ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)) โฆ Ansible with Vagrant, that we talked about yesterday with Ansible Hello World Primer Tutorial as shown below. As you read it, take note of the title of the book we recommend โฆ โAnsible Up and Runningโ by Lorin Hochstein โฆ the word โupโ is bound to be in the list of a deployerโs favourite words, and is critical to all โVagrantโ talk as its favourite command (and its โnirvanaโ (if successful), and is slow the first time (when โvagrant upโ is often preceded by an initialization vagrant command such as โvagrant init ubuntu/trusty32โ) with a project on an individual programmerโs system, but fast from then on for that programmer โrevisitingโ, so that on multiple projects theyโre zooming (ie. cdโing) around to places and going โvagrant upโ vagrant up vagrant up vagrant up) is โฆ
vagrant up
โฆ and for todayโs book recommendation โฆ โVagrant Up and Runningโ by Mitchell Hashimoto โฆ fancy that?!
So whatโs Vagrant? And why is it so friendly?
Can try to answer the first now, but the second one relates to early times spent with Caspar the Ghost โฆ but we digress.
To quote the Vagrant landing page โฆ
Create and configure lightweight, reproducible, and portable development environments.
What we understand in laypersonโs terms is that if a client plonks a โsystemโ on your doorstep and says any of โฆ
- โFix this.โ
- โMaintain this.โ
- โMake it do this, now (awwwwwwwright โฆ after lunch, then).โ
โฆ Vagrant may interface to an IDE like PHPStorm (which weโ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 โฆ
- simulating the whole system
- modelling the whole system
- changing and modifying the resultant model, to check things improve, and still work, hopefully
- deploy this model back onto the reality, for the client to model a broad grin, hopefully
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?
Previous relevant Ansible Hello World Primer Tutorial is shown below.
The role of a programmer is expanding into deployment with software tools such as Ansible, because it has the capability of making the piloting of automation systems โapproachableโ as an โartโ.
Why would you want to โpilot an automation systemโ? Well, to see the whole picture, when you (are part of a team that) are given a software project of improving a โsystemโ, wouldnโt it be great to โฆ
- model that customer system at a snapshot of time
- be able to work and test on that model away from the customer environment until satisfaction
- after changes are tested to satisfaction, redeploy to the customerโs live system via software changes made to the model, and perhaps to data and configuration settings as well
? We think it sounds very good, especially with Ansible helping out with that modelling, because a lot of the doubt in a programmerโs head when working away from a customer siteโ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โ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 โฆ programming and unit testing.
Without Ansible, achieving a project with new (never before used) software tools required, involves programmers working out the configuration management aspects to the job via Search Engine Searches (with a lot of โAdding to Favouritesโ) 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.
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 Windows is also supported) scenario as well, and weโll be showing a bit of this today, to show you a bit about how Ansible works.
Letโs, before that, do a glossary list of terms (mainly from Wikipedia .. thanks) we might use in relation to Ansible โฆ
- configuration management โฆ thatโs Ansible
- provisioning tool โฆ thatโs Ansible
- Ansible on GitHub by Michael DeHaan
- SSH
- YAML (and Playbooks)
- JSON
- package manager โฆ eg. Homebrew, apt, YUM, MacPorts, pip, RPM, OpenPKG, nix, Conary, dpkg, Cygwin
- Jinja template manager
- development stack
- deployment
- virtual machine
- automation
- source control
- VirtualBox
- Vagrant โฆ more tomorrow here
- GitHub
- PHPStorm IDE weโve mentioned before here (integrates some of concepts above)
โฆ and direct you towards a good book, namely โAnsible Up and Runningโ by Lorin Hochstein, from which a lot of todayโs blog postingโs information is derived โฆ so, thanks.
Okay, so what will we do with Ansible?
Install Ansible โฆ on Mac OS X (via Terminal application) โฆ and youโll need ssh (if โsshโ on command line means nothing) โฆ if you have Homebrew package manager installed you can go โฆ
โฆ or you can install as root via Pythonโs pip package manager โฆ
$ sudo pip install ansible
โฆ or another way to install as root via the apt package manager โฆ
$ sudo apt-add-repository -y ppa:ansible/ansible
$ sudo apt-get update
$ sudo apt-get install -y ansible
โฆ or you can install into a Python (2.6 or above) virtualenv with wget via โฆ
$ wget https://raw.githubusercontent.com/mitsuhiko/pipsi/master/get-pipsi.py
$ python get-pipsi.py
$ pipsi install ansible
( with an updating of PATH to include ~/.local/bin ) โฆ or you can use GitHub via โฆ
$ git clone https://github.com/ansible/ansible.git --recursive
โฆ so that you can have โฆ
$ ansible
โฆ mean something at a command prompt (if not, a โfind / -name โansibleโ 2> /dev/nullโ and adjustment of PATH in ~/.profile may be necessary) โฆ a suffix of โ -vvvvโ is useful for debugging purposes.
Show you a 127.0.0.1 local web server with VirtualBox โHello Worldโ feeling example using Ansible involved the need for installation, as required of Oracleโs VirtualBox and, for tomorrow specifically, we talk about Vagrant via โฆ
โฆ then, working off the install we made of Ansible we found an example hosts file off the install, and copied it to /etc/ansible/hosts.orig as shown by โฆ
$ cd $HOME
$ mkdir mybox
$ cd mybox
$ mkdir playbooks
$ cd playbooks
$ vagrant init ubuntu/trusty32
$ vagrant up
$ ssh -i .vagrant/machines/default/virtualbox/private_key vagrant@127.0.0.1 -p 2200
vagrant@vagrant-ubuntu-trusty-32:~$ echo "Hello World ... via Ansible"
Hello World ... via Ansible
vagrant@vagrant-ubuntu-trusty-32:~$ exit
$ cat hosts
$ head -15 ansible.cfg
$ ansible testserver -m ping
$ ansible testserver -a uptime
Ansible is not alone with what it sets out to achieve โฆ think Chef, Puppet or Salt โฆ read more thanks to this useful link for that information.
We hope to be back with more about this powerful product as time goes by. In the meantime, research into Ansible Playbooks would be a great idea.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
If this was interesting you may be interested in this too.
11 Responses to Ansible Playbook TLS Tutorial