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