blob: 172ffbe292d7c88340f9d85e340a4d6b5180b9fc [file] [log] [blame]
martin f. krafft5ee69b32013-06-24 13:41:06 +02001=============================================================
2 reclass recursive external node classification
3=============================================================
4reclass is © 20072013 martin f. krafft <madduck@madduck.net>
5and available under the terms of the Artistic Licence 2.0
6'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
7
8Please make sure to read the generic information in the README file first, or
9alongside this document.
10
11Quick start with Ansible
12~~~~~~~~~~~~~~~~~~~~~~~~
13The following steps should get you up and running quickly. Generally, we will
14be working in /etc/ansible. However, if you are using a source-code checkout
15of Ansible, you might also want to work inside the ./hacking directory
16instead.
17
18Or you can also just look into ./examples/ansible of your reclass checkout,
19where the following steps have already been prepared.
20
21/…/reclass refers to the location of your reclass checkout.
22
martin f. kraffta7451012013-06-26 18:09:20 +020023 0. Run 'make' in the root of the reclass checkout (see the section
24 'Installation' in the README file for the reason).
25
martin f. krafft5ee69b32013-06-24 13:41:06 +020026 1. Symlink /…/reclass/adapters/ansible to /etc/ansible/hosts (or
27 ./hacking/hosts)
28
29 2. Copy the two directories 'nodes' and 'classes' from the example
30 subdirectory in the reclass checkout to /etc/ansible
31
32 If you prefer to put those directories elsewhere, you can create
33 /etc/ansible/reclass-config.yml with contents such as
34
35 storage_type: yaml_fs
36 nodes_uri: /srv/reclass/nodes
37 classes_uri: /srv/reclass/classes
38
39 Note that yaml_fs is currently the only supported storage_type, and it's
40 the default if you don't set it.
41
42 3. Check out your inventory by invoking
43
44 ./hosts --list
45
46 which should return 5 groups in JSON-format, and each group has exactly
47 one member 'localhost'.
48
49 4. See the node information for 'localhost':
50
51 ./hosts --host localhost
52
53 This should print a set of keys and values, including a greeting,
martin f. krafft4cf004b2013-06-26 18:38:23 +020054 a colour, and a sub-class called '__reclas__'.
martin f. krafft5ee69b32013-06-24 13:41:06 +020055
56 5. Execute some ansible commands, e.g.
57
58 ansible -i hosts \* --list-hosts
59 ansible -i hosts \* -m ping
60 ansible -i hosts \* -m debug -a 'msg="${greeting}"'
61 ansible -i hosts \* -m setup
62 ansible-playbook -i hosts test.yml
63
64 6. You can also invoke reclass directly, which gives a slightly different
65 view onto the same data, i.e. before it has been adapted for Ansible:
66
67 /…/reclass.py --pretty-print --inventory
68 /…/reclass.py --pretty-print --nodeinfo localhost
69
70Integration with Ansible
71~~~~~~~~~~~~~~~~~~~~~~~~
72The integration between reclass and Ansible is performed through an adapter,
73and needs not be of our concern too much.
74
75However, Ansible has no concept of "nodes", "applications", "parameters", and
76"classes". Therefore it is necessary to explain how those correspond to
77Ansible. Crudely, the following mapping exists:
78
79 nodes hosts
80 classes groups
81 applications playbooks
82 parameters host_vars
83
84reclass does not provide any group_vars because of its node-centric
85perspective. While class definitions include parameters, those are inherited
86by the node definitions and hence become node_vars.
87
88reclass also does not provide playbooks, nor does it deal with any of the
89related Ansible concepts, i.e. vars_files, vars, tasks, handlers, roles, etc..
90
91 Let it be said at this point that you'll probably want to stop using
92 host_vars, group_vars and vars_files altogether, and if only because you
93 should no longer need them, but also because the variable precedence rules
94 of Ansible are full of surprises, at least to me.
95
96reclass' Ansible adapter massage the reclass output into Ansible-usable data,
97namely:
98
99 - Every class in the ancestry of a node becomes a group to Ansible. This is
100 mainly useful to be able to target nodes during interactive use of
101 Ansible, e.g.
102
103 ansible debiannode@wheezy -m command -a 'apt-get upgrade'
104 → upgrade all Debian nodes running wheezy
105
106 ansible ssh.server -m command -a 'invoke-rc.d ssh restart'
107 → restart all SSH server processes
108
109 ansible mailserver -m command -a 'tail -n1000 /var/log/mail.err'
110 → obtain the last 1,000 lines of all mailserver error log files
111
112 The attentive reader might stumble over the use of singular words, whereas
113 it might make more sense to address all 'mailserver*s*' with this tool.
114 This is convention and up to you. I prefer to think of my node as
115 a (singular) mailserver when I add 'mailserver' to its parent classes.
116
117 - Every entry in the list of a host's applications might well correspond to
118 an Ansible playbook. Therefore, reclass creates a (Ansible-)group for
119 every application, and adds '_hosts' to the name. This postfix can be
120 configured with a CLI option (--applications-postfix) or in the
121 configuration file (applications_postfix).
122
123 For instance, the ssh.server class adds the ssh.server application to
124 a node's application list. Now the admin might create an Ansible playbook
125 like so:
126
127 - name: SSH server management
128 hosts: ssh.server_hosts ← SEE HERE
129 tasks:
130 - name: install SSH package
131 action: …
132
133
134 There's a bit of redundancy in this, but unfortunately Ansible playbooks
135 hardcode the nodes to which a playbook applies.
136
137 It's now trivial to apply this playbook across your infrastructure:
138
139 ansible-playbook ssh.server.yml
140
141 My suggested way to use Ansible site-wide is then to create a 'site'
142 playbook that includes all the other playbooks (which shall hopefully be
143 based on Ansible roles), and then to invoke Ansible like this:
144
145 ansible-playbook site.yml
146
147 or, if you prefer only to reconfigure a subset of nodes, e.g. all
148 webservers:
149
150 ansible-playbook site.yml --limit webserver
151
152 Again, if the singular word 'webserver' puts you off, change the
153 convention as you wish.
154
155 And if anyone comes up with a way to directly connect groups in the
156 inventory with roles, thereby making it unnecessary to write playbook
157 files (containing redundant information), please tell me!
158
159 - Parameters corresponding to a node become host_vars for that host.
160
161It is possible to include Jinja2-style variables like you would in Ansible,
162in parameter values. This is especially powerful in combination with the
163recursive merging, e.g.
164
165 parameters:
166 motd:
167 greeting: Welcome to {{ ansible_fqdn }}!
168 closing: This system is part of {{ realm }}
169
170Now you just need to specify realm somewhere. The reference can reside in
171a parent class, while the variable is defined e.g. in the node.