blob: b02932594bcf7f0203f19c3861e15be59573a1c2 [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
12I have no interest in developing this adapter anymore. If you use it and want
13to turn it into a setuptools entrypoints compatible adapter, I will take your
14patch.
15
martin f. krafft5ee69b32013-06-24 13:41:06 +020016Quick start with Ansible
17~~~~~~~~~~~~~~~~~~~~~~~~
18The following steps should get you up and running quickly. Generally, we will
19be working in /etc/ansible. However, if you are using a source-code checkout
20of Ansible, you might also want to work inside the ./hacking directory
21instead.
22
23Or you can also just look into ./examples/ansible of your reclass checkout,
24where the following steps have already been prepared.
25
26/…/reclass refers to the location of your reclass checkout.
27
martin f. kraffta7451012013-06-26 18:09:20 +020028 0. Run 'make' in the root of the reclass checkout (see the section
29 'Installation' in the README file for the reason).
30
martin f. krafft5ee69b32013-06-24 13:41:06 +020031 1. Symlink /…/reclass/adapters/ansible to /etc/ansible/hosts (or
32 ./hacking/hosts)
33
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
49 ./hosts --list
50
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
56 ./hosts --host localhost
57
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
63 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
68
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
72 /…/reclass.py --pretty-print --inventory
73 /…/reclass.py --pretty-print --nodeinfo localhost
74
75Integration with Ansible
76~~~~~~~~~~~~~~~~~~~~~~~~
77The integration between reclass and Ansible is performed through an adapter,
78and needs not be of our concern too much.
79
80However, Ansible has no concept of "nodes", "applications", "parameters", and
81"classes". Therefore it is necessary to explain how those correspond to
82Ansible. Crudely, the following mapping exists:
83
84 nodes hosts
85 classes groups
86 applications playbooks
87 parameters host_vars
88
89reclass does not provide any group_vars because of its node-centric
90perspective. While class definitions include parameters, those are inherited
91by the node definitions and hence become node_vars.
92
93reclass also does not provide playbooks, nor does it deal with any of the
94related Ansible concepts, i.e. vars_files, vars, tasks, handlers, roles, etc..
95
96 Let it be said at this point that you'll probably want to stop using
97 host_vars, group_vars and vars_files altogether, and if only because you
98 should no longer need them, but also because the variable precedence rules
99 of Ansible are full of surprises, at least to me.
100
101reclass' Ansible adapter massage the reclass output into Ansible-usable data,
102namely:
103
104 - Every class in the ancestry of a node becomes a group to Ansible. This is
105 mainly useful to be able to target nodes during interactive use of
106 Ansible, e.g.
107
108 ansible debiannode@wheezy -m command -a 'apt-get upgrade'
109 → upgrade all Debian nodes running wheezy
110
111 ansible ssh.server -m command -a 'invoke-rc.d ssh restart'
112 → restart all SSH server processes
113
114 ansible mailserver -m command -a 'tail -n1000 /var/log/mail.err'
115 → obtain the last 1,000 lines of all mailserver error log files
116
117 The attentive reader might stumble over the use of singular words, whereas
118 it might make more sense to address all 'mailserver*s*' with this tool.
119 This is convention and up to you. I prefer to think of my node as
120 a (singular) mailserver when I add 'mailserver' to its parent classes.
121
122 - Every entry in the list of a host's applications might well correspond to
123 an Ansible playbook. Therefore, reclass creates a (Ansible-)group for
124 every application, and adds '_hosts' to the name. This postfix can be
125 configured with a CLI option (--applications-postfix) or in the
126 configuration file (applications_postfix).
127
128 For instance, the ssh.server class adds the ssh.server application to
129 a node's application list. Now the admin might create an Ansible playbook
130 like so:
131
132 - name: SSH server management
133 hosts: ssh.server_hosts ← SEE HERE
134 tasks:
135 - name: install SSH package
136 action: …
137
138
139 There's a bit of redundancy in this, but unfortunately Ansible playbooks
140 hardcode the nodes to which a playbook applies.
141
142 It's now trivial to apply this playbook across your infrastructure:
143
144 ansible-playbook ssh.server.yml
145
146 My suggested way to use Ansible site-wide is then to create a 'site'
147 playbook that includes all the other playbooks (which shall hopefully be
148 based on Ansible roles), and then to invoke Ansible like this:
149
150 ansible-playbook site.yml
151
152 or, if you prefer only to reconfigure a subset of nodes, e.g. all
153 webservers:
154
155 ansible-playbook site.yml --limit webserver
156
157 Again, if the singular word 'webserver' puts you off, change the
158 convention as you wish.
159
160 And if anyone comes up with a way to directly connect groups in the
161 inventory with roles, thereby making it unnecessary to write playbook
162 files (containing redundant information), please tell me!
163
164 - Parameters corresponding to a node become host_vars for that host.
165
166It is possible to include Jinja2-style variables like you would in Ansible,
167in parameter values. This is especially powerful in combination with the
168recursive merging, e.g.
169
170 parameters:
171 motd:
172 greeting: Welcome to {{ ansible_fqdn }}!
173 closing: This system is part of {{ realm }}
174
175Now you just need to specify realm somewhere. The reference can reside in
176a parent class, while the variable is defined e.g. in the node.