summaryrefslogtreecommitdiff
path: root/src/talks/ansible-openstack.hbs
diff options
context:
space:
mode:
Diffstat (limited to 'src/talks/ansible-openstack.hbs')
-rw-r--r--src/talks/ansible-openstack.hbs502
1 files changed, 502 insertions, 0 deletions
diff --git a/src/talks/ansible-openstack.hbs b/src/talks/ansible-openstack.hbs
new file mode 100644
index 0000000..4b2af33
--- /dev/null
+++ b/src/talks/ansible-openstack.hbs
@@ -0,0 +1,502 @@
1<!doctype html>
2<html lang="en">
3
4 <head>
5 <meta charset="utf-8">
6
7 <title>Using Ansible with OpenStack</title>
8
9 </head>
10 <body>
11
12 <section id="who-am-i-redhat" class="slide level2">
13 <h1>Who am I?</h1>
14 <img style="float:right; margin:24pt" src="/images/Logo_RH_CMYK_Default.jpg" />
15 <p> Office of Technology </p>
16 <p> Zuul </p>
17 <p> Ansible </p>
18 </section>
19
20 <section id="who-am-i-openstack" class="slide level2">
21 <h1>Who am I?</h1>
22 <img style="float:right; margin-right:24pt; width:300px; height: auto" src="/images/openstack-cloud-software-vertical-large.png" />
23 <p>Technical Committee</p>
24 <p>Developer Infrastructure Core Team</p>
25 <p>Former Foundation Board of Directors</p>
26 <p>PTL of shade project</p>
27 </section>
28
29 <section id="ansible" class="slide level1">
30 <h1>Ansible</h1>
31 <p>Ansible is a radically simple IT automation engine that automates cloud provisioning, configuration management, application deployment, intra-service orchestration, and many other IT needs.</p>
32 </section>
33
34 <section id="why-ansible-is-great" class="slide level1">
35 <h1>Why Ansible is Great</h1>
36 <ul>
37 <li>simple declarative YAML syntax</li>
38 <li>list of tasks to perform - easy to debug</li>
39 <li>agentless - don't infect machines under management</li>
40 <li>Open Source - thousands of contributors worldwide</li>
41 </ul>
42 </section>
43
44 <section id="ansible-overview" class="slide level1">
45 <h1>Ansible Overview</h1>
46 <ul>
47 <li>task - an action to perform</li>
48 <li>module - code that exposes a type of action</li>
49 <li>role - reusable collection of tasks to acomplish a goal</li>
50 <li>play - tasks and roles run on a specific host or hosts</li>
51 <li>inventory - list of locations available to run plays on</li>
52 <li>playbook - file containing one or more plays</li>
53 </ul>
54 </section>
55
56 <section id="ansible-simple-example" class="slide level1">
57 <h1>Ansible Simple Example</h1>
58 <p><em>simple.yaml</em></p>
59 <pre><code>
60- hosts: all
61 tasks:
62 - name: Print hostname of server
63 command: hostname
64 </code></pre>
65 <p>A <em>playbook</em> containing a <em>play</em> that will run
66 against all hosts in the <em>inventory</em>. It has one <em>task</em>
67 that uses the <em>command</em> module to run the "hostname" command.
68 </p>
69 </section>
70
71 <section id="ansible-longer-example" class="slide level1">
72 <h1>Ansible Longer Example</h1>
73 <p><em>longer.yaml</em></p>
74 <pre><code>
75- hosts: git
76 roles:
77 - create-mirror-locations
78- hosts: code-review.example.com
79 roles:
80 - create-repositories
81 </code></pre>
82 <p>A <em>playboook</em> containing two <em>plays</em>. The first runs
83 a <em>role</em> called "create-mirror-locations" against a group of hosts
84 from the <em>inventory</em> called "git". Then it runs a <em>role</em>
85 called "create-repositories" against a host from the <em>inventory</em>
86 called "code-review.example.com".
87 </p>
88 </section>
89
90 <section id="ansible-modules" class="slide level1">
91 <h1>Ansible Modules</h1>
92 <ul>
93 <li>Usually written in Python</li>
94 <li>Can do anything, not limited to executing commands on a server</li>
95 <li>Manipulate Network Switch Config (ansible-network)</li>
96 <li>Build Containers (ansible-container)</li>
97 <li>Interact with REST APIs</li>
98 </ul>
99 </section>
100
101 <section id="ansible-openstack-modules" class="slide level1">
102 <h1>Ansible OpenStack Modules</h1>
103 <ul>
104 <li><a href="http://docs.ansible.com/ansible/list_of_cloud_modules.html#openstack" class="uri">http://docs.ansible.com/ansible/list_of_cloud_modules.html#openstack</a></li>
105 <li>Focused on consuming OpenStack APIs</li>
106 <li>Some are end-user focused</li>
107 <li>Some are deployer focused</li>
108 </ul>
109 </section>
110
111 <section id="interop---work-on-all-openstack-clouds" class="slide level1">
112 <h1>Interop - Work on All OpenStack Clouds</h1>
113 <ul>
114 <li>Ansible's OpenStack modules work the same on every OpenStack cloud</li>
115 </ul>
116 <p class='fragment'>
117 Don't let the existence of Rackspace modules confuse you.
118 The OpenStack modules work just great on Rackspace</p>
119 </section>
120
121 <section id="work-around-deployer-differences-...-to-a-point" class="slide level1">
122 <h1>Work Around Deployer Differences ... To a Point</h1>
123 <ul>
124 <li>Herculean effort is made to hide a giant amount of differences</li>
125 <li>Even so - some bugs are EWONTFIX</li>
126 </ul>
127 <p class='fragment'>
128 A provider decided to redefine the OpenStack Availability Zone concept
129 complete with incompatible API changes. That is unsupportable.</p>
130 <p class='fragment'>PS. Don't do that</p>
131 </section>
132
133 <section id="based-on-shade-library" class="slide level1">
134 <h1>Based on shade library</h1>
135 <ul>
136 <li>OpenStack python library to abstract deployment differences</li>
137 <li>designed for multi-cloud</li>
138 <li>simple to use</li>
139 <li>massive scale
140 <ul>
141 <li>optional advanced features to handle &gt;20k servers a day</li>
142 </ul></li>
143 <li>Initial logic/design extracted from OpenStack Infra's nodepool</li>
144 <li>Turned in to library for re-use in Ansible</li>
145 </ul>
146 </section>
147
148 <section id="integration-testing" class="slide level1">
149 <h1>Integration Testing</h1>
150 <ul>
151 <li>Every shade patch is integration tested in OpenStack Infra</li>
152 <li>Every shade patch tests the ansible modules in OpenStack Infra</li>
153 <li>Support coming very soon to test PRs to ansible modules in OpenStack Infra</li>
154 </ul>
155 </section>
156
157 <section id="lets-take-a-few-steps-back" class="slide level1">
158 <h1>Let's Take a Few Steps Back</h1>
159 <p>OpenStack in Ansible and Multi-cloud Operations are easy...</p>
160 <p>but you need to know a few things.</p>
161 <ul>
162 <li>Module structure</li>
163 <li>Terminology</li>
164 <li>Config</li>
165 </ul>
166 </section>
167
168 <section id="module-structure" class="slide level1">
169 <h1>Module Structure</h1>
170 <ul>
171 <li>All modules start with <code>os_</code></li>
172 <li>End-user oriented modules are named for the resource
173 <ul>
174 <li>os_image</li>
175 <li>os_sever</li>
176 </ul>
177 </li>
178 <li>Operator oriented modules are named for the service
179 <ul>
180 <li>os_nova_flavor</li>
181 <li>os_keystone_domain</li>
182 </ul>
183 </li>
184 <li>If it could go both ways, we prefer user orientation
185 <ul>
186 <li>os_user</li>
187 <li>os_group</li>
188 </ul>
189 </li>
190 <li>If more than one service provides a resource, they DTRT
191 <ul>
192 <li>os_security_group</li>
193 <li>os_floating_ip</li>
194 </ul>
195 </li>
196 </ul>
197 </section>
198
199 <section id="openstack-dynamic-inventory-script" class="slide level1">
200 <h1>OpenStack Dynamic Inventory Script</h1>
201 <ul>
202 <li>github.com/ansible/ansible/contrib/inventory/openstack.py</li>
203 <li>Uses all hosts in all clouds as one inventory</li>
204 <li>Excludes hosts without IPs</li>
205 <li>Makes a bunch of auto-groups (flavor, image, az, region, cloud)</li>
206 <li>Makes groups for metadata['groups']</li>
207 </ul>
208 <p>New inventory plugin coming in Ansible 2.4</p>
209 </section>
210
211 <section id="modules-for-all-openstack-resources-are-welcome-upstream" class="slide level1">
212 <h1>Modules for All OpenStack Resources are Welcome Upstream</h1>
213 <ul>
214 <li>If there is a thing you want to manage that doesn't have a module,
215 add one</li>
216 <li>We're very welcoming/accepting</li>
217 <li>Same goes for features to existing modules</li>
218 </ul>
219 </section>
220
221 <section id="to-serve-all-users-we-have-to-be-strict" class="slide level1">
222 <h1>To Serve All Users, We Have to be Strict</h1>
223 <ul>
224 <li>Modules that touch OpenStack APIs must do so via shade library</li>
225 <li>In user modules, vendor differences should be hidden</li>
226 <li>In operator modules, exposing them is ok</li>
227 </ul>
228 </section>
229
230 <section id="clouds.yaml" class="slide level1">
231 <h1>clouds.yaml</h1>
232 <ul>
233 <li>Information about the clouds you want to connect to is stored in a
234 file called clouds.yaml.</li>
235 <li>In OpenStack Pike release, Horizon provides downloadable clouds.yaml</li>
236 <li>Both yaml and yml are acceptable.</li>
237 <li>clouds.yaml can be in your homedir: ~/.config/openstack/clouds.yaml or system-wide: /etc/openstack/clouds.yaml.</li>
238 <li>Information in your homedir, if it exists, takes precedence.</li>
239 <li>Full docs on clouds.yaml are at <a href="https://docs.openstack.org/developer/os-client-config/" class="uri">https://docs.openstack.org/developer/os-client-config/</a></li>
240 </ul>
241 </section>
242
243 <section id="what-about-mac-and-windows" class="slide level1">
244 <h1>What about Mac and Windows?</h1>
245 <p>USER_CONFIG_DIR is different on Linux, OSX and Windows.</p>
246 <ul>
247 <li>Linux: ~/.config/openstack</li>
248 <li>OSX: ~/Library/Application Support/openstack</li>
249 <li>Windows: C:\\Users\\USERNAME\\AppData\\Local\\OpenStack\\openstack</li>
250 </ul>
251 <p>SITE_CONFIG_DIR is different on Linux, OSX and Windows.</p>
252 <ul>
253 <li>Linux: /etc/openstack</li>
254 <li>OSX: /Library/Application Support/openstack</li>
255 <li>Windows: C:\\ProgramData\\OpenStack\\openstack</li>
256 </ul>
257 </section>
258
259 <section id="config-terminology" class="slide level1">
260 <h1>Config Terminology</h1>
261 <p>For multi-cloud, think of two types:</p>
262 <ul>
263 <li>profile - Facts about the cloud that are true for everyone</li>
264 <li>cloud - Information specific to a given user</li>
265 </ul>
266 </section>
267
268 <section id="remember-your-execution-context" class="slide level1">
269 <h1>Remember your Execution Context!</h1>
270 <ul>
271 <li>ansible executes code on remote systems</li>
272 <li>clouds.yaml needs to be on the host where the modules run</li>
273 <li>auth information can be passed to modules directly</li>
274 <li>other config (currently) MUST go in clouds.yaml</li>
275 <li class='fragment'>Ability to pass entire cloud config to module coming soon</li>
276 </ul>
277 </section>
278
279 <section id="basic-clouds.yaml-for-the-example-code" class="slide level1">
280 <h1>basic clouds.yaml for the example code</h1>
281 <p>Simple example of a clouds.yaml</p>
282 <ul>
283 <li>Config for a named cloud &quot;my-citycloud&quot;</li>
284 <li>Reference a well-known &quot;named&quot; profile: citycloud</li>
285 <li>os-client-config has a built-in list of profiles at <a href="https://docs.openstack.org/developer/os-client-config/vendor-support.html" class="uri">https://docs.openstack.org/developer/os-client-config/vendor-support.html</a></li>
286 <li>Vendor profiles contain various advanced config</li>
287 <li>cloud name can match profile name (using different names for clarity)</li>
288 </ul>
289 <div class="sourceCode"><pre class="sourceCode yaml"><code class="sourceCode yaml">
290clouds:
291 my-citycloud:
292 profile: citycloud
293 auth:
294 username: mordred
295 project_id: 65222a4d09ea4c68934fa1028c77f394
296 user_domain_id: d0919bd5e8d74e49adf0e145807ffc38
297 project_domain_id: d0919bd5e8d74e49adf0e145807ffc38
298 </code></pre></div>
299 <p>Where's the password?</p>
300 </section>
301
302 <section id="secure.yaml" class="slide level1">
303 <h1>secure.yaml</h1>
304 <ul>
305 <li>Optional additional file just like clouds.yaml</li>
306 <li>Values overlaid on clouds.yaml</li>
307 <li>Useful if you want to protect secrets more stringently</li>
308 </ul>
309 </section>
310
311 <section id="example-secure.yaml" class="slide level1">
312 <h1>Example secure.yaml</h1>
313 <ul>
314 <li>No, my password isn't XXXXXXXX</li>
315 <li>cloud name should match clouds.yaml</li>
316 <li>Optional - I actually keep mine in my clouds.yaml</li>
317 </ul>
318 <div class="sourceCode"><pre class="sourceCode yaml"><code class="sourceCode yaml">
319clouds:
320 my-citycloud:
321 auth:
322 password: XXXXXXXX
323 </code></pre></div>
324 </section>
325
326 <section id="more-clouds.yaml" class="slide level1">
327 <h1>more clouds.yaml</h1>
328 <p>More information can be provided.</p>
329 <ul>
330 <li>Use v3 of the identity API - even if others are present</li>
331 <li>Use https://image-ca-ymq-1.vexxhost.net/v2 for image API instead of what's in the catalog</li>
332 </ul>
333 <div class="sourceCode"><pre class="sourceCode yaml"><code class="sourceCode yaml">
334my-vexxhost:
335 identity_api_version: 3
336 image_endpoint_override: https://image-ca-ymq-1.vexxhost.net/v2
337 profile: vexxhost
338 auth:
339 user_domain_id: default
340 project_domain_id: default
341 project_name: d8af8a8f-a573-48e6-898a-af333b970a2d
342 username: 0b8c435b-cc4d-4e05-8a47-a2ada0539af1
343 </code></pre></div>
344 </section>
345
346 <section id="much-more-complex-clouds.yaml-example" class="slide level1">
347 <h1>Much more complex clouds.yaml example</h1>
348 <ul>
349 <li>Not using a profile - all settings included</li>
350 <li>In the ams01 region there are two networks with undiscoverable qualities</li>
351 <li>Each one are labeled here so choices can be made</li>
352 <li>Any of the settings can be specific to a region if needed</li>
353 <li>region settings override cloud settings</li>
354 <li>cloud does not support floating-ips</li>
355 </ul>
356 </section>
357
358 <section id="much-more-complex-clouds.yaml-example-core" class="slide level1">
359 <div class="sourceCode"><pre class="sourceCode yaml"><code class="sourceCode yaml">
360my-internap:
361 auth:
362 auth_url: https://identity.api.cloud.iweb.com
363 username: api-55f9a00fb2619
364 project_name: inap-17037
365 identity_api_version: 3
366 floating_ip_source: None
367 regions:
368 - name: ams01
369 values:
370 networks:
371 - name: inap-17037-WAN1654
372 routes_externally: true
373 default_interface: true
374 - name: inap-17037-LAN3631
375 routes_externally: false</code></pre></div>
376 </section>
377
378 <section id="extra-variables-to-control-inventory-behavior" class="slide level1">
379 <h1>Extra Variables to Control Inventory Behavior</h1>
380 <ul>
381 <li>
382 <dl>
383 <dt>expand_hostvars</dt>
384 <dd>whether to make extra API calls to fill out additional
385 information about each server
386 </dd>
387 </dl>
388 </li>
389 <li>
390 <dl>
391 <dt>use_hostnames</dt>
392 <dd>changes the behavior from registering every host with its
393 UUID and making a group of its hostname to only doing this if the
394 hostname in question has more than one server
395 </dd>
396 </dl>
397 </li>
398 <li>
399 <dl>
400 <dt>fail_on_errors</dt>
401 <dd>causes the inventory to fail and return no hosts if one
402 cloud has failed</dd>
403 </dl>
404 </li>
405 </ul>
406
407 <div class="sourceCode"><pre class="sourceCode yaml"><code class="sourceCode yaml">ansible:
408 use_hostnames: False
409 expand_hostvars: True
410 fail_on_errors: True</code></pre></div>
411 </section>
412 <section id="test-your-config" class="slide level1">
413 <h1>Test Your Config</h1>
414 <div class="sourceCode"><pre class="sourceCode yaml"><code class="sourceCode yaml">---
415- hosts: localhost
416 tasks:
417 - os_auth:
418 cloud: "{{ item.cloud }}"
419 region_name: "{{ item.region }}"
420 with_items:
421 - cloud: my-vexxhost
422 region: ca-ymq-1
423 - cloud: my-citycloud
424 region: Buf1
425 - cloud: my-internap
426 region: ams01
427 </code></pre></div>
428 </section>
429
430 <section id="more-interesting" class="slide level1">
431 <h1>More Interesting</h1>
432 <div class="sourceCode"><pre class="sourceCode yaml"><code class="sourceCode yaml">
433- hosts: localhost
434 tasks:
435 - os_server:
436 name: "my-server"
437 cloud: "{{ item.cloud }}"
438 region_name: "{{ item.region }}"
439 image: "{{ item.image }}"
440 flavor: "{{ item.flavor }}"
441 auto_ip: true
442 with_items:
443 - cloud: my-vexxhost
444 region: ca-ymq-1
445 image: Ubuntu 16.04.1 LTS [2017-03-03]
446 flavor: v1-standard-4
447 - cloud: my-citycloud
448 region: Buf1
449 image: Ubuntu 16.04 Xenial Xerus
450 flavor: 4C-4GB-100GB
451 - cloud: my-internap
452 region: ams01
453 image: Ubuntu 16.04 LTS (Xenial Xerus)
454 flavor: A1.4</code></pre></div>
455 </section>
456
457 <section id="check-that-there-is-an-inventory" class="slide level1">
458 <h1>Check That There is an Inventory</h1>
459 <blockquote>
460 python ~/src/github.com/ansible/ansible/contrib/inventory/openstack.py --list
461 </blockquote>
462 </section>
463
464 <section id="cleanup-after-ourselves" class="slide level1">
465 <h1>Cleanup After Ourselves</h1>
466 <div class="sourceCode"><pre class="sourceCode yaml"><code class="sourceCode yaml">
467- hosts: localhost
468 tasks:
469 - os_server:
470 cloud: "{{ item.cloud }}"
471 region_name: "{{ item.region }}"
472 name: my-server
473 state: absent
474 with_items:
475 - cloud: my-vexxhost
476 region: ca-ymq-1
477 - cloud: my-citycloud
478 region: Buf1
479 - cloud: my-internap
480 region: ams01
481 </code></pre></div>
482 </section>
483
484 <section id="check-out-ansible-cloud-launcher" class="slide level1">
485 <h1>Check out Ansible Cloud Launcher</h1>
486 <p><a href="https://git.openstack.org/cgit/openstack/ansible-role-cloud-launcher" class="uri">https://git.openstack.org/cgit/openstack/ansible-role-cloud-launcher</a></p>
487 <ul>
488 <li>Role for launching resources on an OpenStack Cloud</li>
489 </ul>
490 </section>
491
492 <section id="check-out-linch-pin" class="slide level1">
493 <h1>Check out Linch-pin</h1>
494 <p><a href="http://linch-pin.readthedocs.io/en/develop/" class="uri">http://linch-pin.readthedocs.io/en/develop/</a></p>
495 <ul>
496 <li>From our friends in CentOS</li>
497 </ul>
498 <p>Linch-pin provides a collection of Ansible playbooks for provisioning, decommissioning, and managing resources across multiple infrastructures. The main goal of linch-pin is to facilitate provisioning and orchestration of resources in a multi-cloud environment through a topology file.</p>
499 </section>
500
501 </body>
502</html>