Blame view

README.markdown 7.73 KB
4039e577   Lars Tiede   first commit
1
2
3
  Utviklerlunsj: Ansible
  ======================
  
b47804ca   Lars Tiede   a bit more conten...
4
  The presentation is available as a [keynote](presentation.key) or [pdf](presentation.pdf) file.
9d18e1b0   Lars Tiede   small improvements
5
6
  
  
4039e577   Lars Tiede   first commit
7
8
9
  How to install the demo environment
  -----------------------------------
  
9d18e1b0   Lars Tiede   small improvements
10
  First, install [Vagrant](https://www.vagrantup.com/) and [VirtualBox](https://www.virtualbox.org/) on your Linux, Mac, or Windows box. Both installs are easy and fairly quick.
4039e577   Lars Tiede   first commit
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  
  Then, clone this repository somewhere and, in a terminal, cd into the directory you cloned the repo into. There:
  
      $ vagrant plugin install vagrant-hosts
  
  You need to do that step only once. On my mac, it failed at first because it didn't find some Ruby gem, but when I just tried again a few minutes later, it worked. No idea whether that was just bad luck.
  
  Then, to build and start all the demo VMs:
  
      $ vagrant up
  
  That will take a bit of time, certainly the first time you run this. When everything is up and running, you have 3 VirtualBox VMs running on your machine: "control", "target1", and "target2". You can ssh to either of them like this:
  
      $ vagrant ssh NAME
  
  The directory you've been in on the host OS (the one with the Vagrantfile) is mapped into the guest VM at `/vagrant`.
  
  When you're done playing and want to ditch the VMs, do this:
  
      $ vagrant destroy
  
  For anything beyond this, consult the Vagrant [documentation](https://docs.vagrantup.com/v2/).
  
  
  Demo
  ----
  
  These are the things I demonstrate in the talk.
  
  
  ### 1. Install ansible on the control machine
  
      $ vagrant ssh control
      vagrant@demo-control:~$ sudo apt-get update
      vagrant@demo-control:~$ sudo apt-get install -y ansible
  
  Ubuntu 14.04's Ansible version is a bit outdated, but it's recent enough for us.
  
  
  ### 2. Run a few innocent ad-hoc commands ("SSH is all you need")
  
  First, cd to /vagrant, which is the directory containing the cloned repository, mapped into the VM. Then
  
      vagrant@demo-control:/vagrant$ ansible all -i inventory/demo -m ping
  
9d18e1b0   Lars Tiede   small improvements
56
  You need to say yes to adding target1's and target2's host keys now. This happens only the first time you connect to the hosts, as usual with SSH.
4039e577   Lars Tiede   first commit
57
58
59
60
61
62
63
64
65
66
67
68
  
  Run a few other commands to get a feel for what's happening.
  
      vagrant@demo-control:/vagrant$ ansible all -i inventory/demo -m shell -a "free -h"
      vagrant@demo-control:/vagrant$ ansible target1 -i inventory/demo -m shell -a "free -h"
  
  Ignore the -m and -i things for now, we'll get to them later.
  
  Here's one that spews out a lot of info about target1:
  
      vagrant@demo-control:/vagrant$ ansible target1 -i inventory/demo -m setup
  
9d18e1b0   Lars Tiede   small improvements
69
  Since Ansible uses SSH under the hood, and you very likely require root privileges on your target systems at some point, it is important to be able to get root privileges in one way or another. If you don't specify anything to that effect, Ansible will just try to log in as "the current user":
4039e577   Lars Tiede   first commit
70
71
72
  
      vagrant@demo-control:/vagrant$ ansible target1 -i inventory/demo -m shell -a "whoami"
  
a06b33c7   Lars Tiede   small stuff
73
  There are two ways to become root with Ansible: Either SSH as root to the target (`-u root` will do this), or log in as whichever user and use sudo on the target (`--sudo`). In both cases, you have to be able to do the respective thing without password. There are options you can specify that lets Ansible ask you for a password, but that is really not recommended.
4039e577   Lars Tiede   first commit
74
75
76
77
78
79
80
81
82
83
  
  On our Vagrant boxes, passwordless SSH for the root user is not set up, but the 'vagrant' user can sudo without a password. So let's use sudo:
  
      vagrant@demo-control:/vagrant$ ansible target1 -i inventory/demo -m shell -a "whoami" --sudo
  
  
  ### 3. Describe the state you want a target to be in, not how to get there
  
  Let's *do* something.
  
9d18e1b0   Lars Tiede   small improvements
84
  Say we want to have pip (a Python package manager) installed on one of the target machines. We tell Ansible that we want the apt package named "python-pip" present:
4039e577   Lars Tiede   first commit
85
86
87
  
      vagrant@demo-control:/vagrant$ ansible target1 --sudo -i inventory/demo -m apt -a "pkg=python-pip state=present"
  
9d18e1b0   Lars Tiede   small improvements
88
  Note that we didn't say "install python-pip", but rather "have python-pip installed". It is up to Ansible to figure out whether anything has to be done or not. Go on, just do the same thing again. All you get back now is "changed: false". So Ansible only does something if something needs to be done. That's why you specify what state you want in the end, not how to get there. That last bit is an implementation detail you usually don't concern yourself with!
4039e577   Lars Tiede   first commit
89
90
91
92
  
  If you want to break the rules, however, nothing stops you from running "apt-get install -y python-pip" with the "shell" module.
  
  
a06b33c7   Lars Tiede   small stuff
93
  ### 4. On second "abstractions" slide: make re-usable descriptions of small aspects of the system that you can combine in endless ways
4039e577   Lars Tiede   first commit
94
  
a06b33c7   Lars Tiede   small stuff
95
  We have a minimal web app in the [webapp](webapp/) directory. We want to deploy this to two app servers (target1 and target2), and put those behind a simple load balancer on target1.
4039e577   Lars Tiede   first commit
96
97
98
  
  The playbook in [deploy\_and\_run\_web\_app.yml](deploy_and_run_web_app.yml) does all of this.
  
a06b33c7   Lars Tiede   small stuff
99
  The playbook contains two 'plays', i.e., sequences of tasks and role invocations that are applied to a set of hosts. In the first play, the playbook sets up the web app instances on all hosts in the 'app\_servers' group (as defined in the [inventory file](inventory/demo)). To do this on each host, we have a role '[runs\_web\_app](roles/runs_web_app)'. In it, a sequence of tasks is (per convention) in [tasks/main.yml](roles/runs_web_app/tasks/main.yml). Files, templates and other role specific things can also be found in the role's directory. For this role, we just have one file in its 'files' subdirectory. Check out the Ansible documentation on [roles](http://docs.ansible.com/playbooks_roles.html#roles) for more details about what you can do with and inside roles. Roles are Ansible's main abstraction for making re-usable and shareable bits and pieces.
4039e577   Lars Tiede   first commit
100
  
a06b33c7   Lars Tiede   small stuff
101
  The second play of the playbook sets up the load balancer on all hosts in the 'load\_balancer' group. In our inventory, that group contains only one host. For running a simple load balancer, we have the role '[runs\_simple\_load\_balancer](roles/runs_simple_load_balancer)'. This role can be configured a bit through variables that are passed into it on invocation: you can specify which hosts and ports the app servers that should be load-balanced run on. There is one template in the role ([the nginx config file snippet](roles/runs_simple_load_balancer/templates/sites-enabled/webapp.j2)) that uses these variables. Variables can also be used nearly anywhere else outside of templates; think of most of the playbook text content as template-able content. Nearly everything you write is (or can be) passed through the jinja2 templating engine that comes bundled with Ansible. Check the Ansible documentation on [variables and templating everywhere](http://docs.ansible.com/playbooks_variables.html#using-variables-about-jinja2) for more.
b47804ca   Lars Tiede   a bit more conten...
102
103
104
105
106
107
108
109
110
111
112
113
114
  
  
  ### 5. Play!
  
  Run the playbook:
  
      vagrant@demo-control:/vagrant$ ansible-playbook -i inventory/demo deploy_and_run_web_app.yml
  
  Point your browser to the IP that is shown at the end of the playbook output. Refresh the page a couple of times to see the load balancer in action.
  
  Now play around with the sources and playbooks and files as you wish. For example, change the inventory file so that you have only one host in the app\_servers group. Run the playbook again. See the difference? It is that easy now to change your infrastructure and update your app's configuration.
  
  Use Vagrant to your advantage while playing around. If you want to "wipe" target2, for example, just run "vagrant destroy target2" and then "vagrant up target2" on your machine (in the directory with our Vagrantfile). When you do this, target2 will get a new SSH host key. You will have to deal with that on the control VM. How to do this is left as an exercise to the reader ;) (approaches include disabling strict host key checking or removing the host key from /home/vagrant/.ssh/known\_hosts).