summaryrefslogtreecommitdiff
path: root/src/talks/tripleo-ansible
diff options
context:
space:
mode:
Diffstat (limited to 'src/talks/tripleo-ansible')
-rw-r--r--src/talks/tripleo-ansible/index.html794
1 files changed, 794 insertions, 0 deletions
diff --git a/src/talks/tripleo-ansible/index.html b/src/talks/tripleo-ansible/index.html
new file mode 100644
index 0000000..58814df
--- /dev/null
+++ b/src/talks/tripleo-ansible/index.html
@@ -0,0 +1,794 @@
1<!doctype html>
2<html lang="en">
3
4 <head>
5 <meta charset="utf-8">
6
7 <title>TripleO and Ansible</title>
8
9 <meta name="apple-mobile-web-app-capable" content="yes" />
10 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
11
12 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
13
14 <link rel="stylesheet" href="/css/reveal.css">
15 <link rel="stylesheet" href="/css/theme/openstack.css" id="theme">
16
17 <!-- For syntax highlighting -->
18 <link rel="stylesheet" href="/lib/css/zenburn.css">
19
20 <!-- If the query includes 'print-pdf', include the PDF print sheet -->
21 <script>
22 if( window.location.search.match( /print-pdf/gi ) ) {
23 var link = document.createElement( 'link' );
24 link.rel = 'stylesheet';
25 link.type = 'text/css';
26 link.href = '/css/print/pdf.css';
27 document.getElementsByTagName( 'head' )[0].appendChild( link );
28 }
29 </script>
30
31 </head>
32 <body>
33
34 <div class="background">
35 <img alt="" id="head-icon" width="218" height="67"
36 src="/images/openstack-cloud-software-horizontal-small.png" /></div>
37
38
39 <div class="reveal">
40 <div class="slides">
41
42 <section data-state="cover">
43 <img src="/images/openstack-cloud-software-vertical-large.png"
44 alt="OpenStack" id="cover"/>
45
46 <h1><span xmlns:dct="http://purl.org/dc/terms/"
47 href="http://purl.org/dc/dcmitype/InteractiveResource"
48 property="dct:title"
49 rel="dct:type">
50 TripleO and Ansible
51 </span></h1>
52 <h3 xmlns:cc="http://creativecommons.org/ns#"
53 property="cc:attributionName">Monty Taylor</h3>
54 <h4><a xmlns:cc="http://creativecommons.org/ns#"
55 rel="cc:attributionURL"
56 href='http://inaugust.com/talks/tripleo-ansible.html'>http://inaugust.com/talks/tripleo-ansible.html</a> </h4>
57 <h3> twitter: @e_monty </h3>
58 </section>
59
60 <section id="who-am-i" class="slide level2">
61 <h1>Who am I?</h1>
62 <ul>
63 <li>Distinguished Technologist at HP</li>
64 <li>OpenStack Technical Committee</li>
65 <li>OpenStack Foundation Board of Directors</li>
66 <li>OpenStack Infra Core Team</li>
67 </ul>
68 </section>
69
70 <section id="what-are-we-going-to-talk-about" class="slide level2">
71 <h1>What are we going to talk about?</h1>
72 <ul>
73 <li>TripleO</li>
74 <li>Ironic</li>
75 <li>Ansible</li>
76 </ul>
77 </section>
78
79 <section>
80 <h1>What is TripleO?</h1>
81 <ul>
82 <li class="fragment"> an idea </li>
83 <li class="fragment"> OpenStack On OpenStack </li>
84 <li class="fragment"> use Ironic-based OpenStack to Operate Openstack </li>
85 </ul>
86 </section>
87
88
89 <section>
90 <h1>Velocity</h1>
91 <ul>
92 <li>Cloud Empowers <em>developers</em></li>
93 <li>Cloud Enables Increased Velocity</li>
94 <li>Cloud Drives Agility</li>
95 </ul>
96 </section>
97
98 <section>
99 <a href="#/2" class="image"><img src="/images/openstack-software-diagram.png" width="90%"></a>
100 <aside class="notes">
101 Perhaps you've seen this before. <br>
102 Even with addition of lots of PaaS projects, the abstraction here still holds.
103 </aside>
104 </section>
105
106 <section>
107 <h1>OpenStack is not a virtualization layer,
108 it's an abstraction layer.</h1>
109 <aside class="notes">
110 When Danny Sabah @ IBM said this, it hit home for me. I had already been working on Ironic for a year.<br>
111 KVM, NFV ... <br>
112 Virtualization is a powerful tool. Abstraction empowers people.<br>
113 OpenStack community is thriving because of the power of open abstractions layers.
114 </aside>
115 </section>
116
117 <section>
118 <section>
119 <h1>What if your <em>developers</em> aren't writing Angry Birds?</h1>
120 </section>
121
122 <section>
123 <h1>What if your <em>developers</em> aren't developers?</h1>
124 </section>
125
126 <section>
127 <h3>If infrastructure is code ...</h3>
128 <h1>What if your <em>developers</em> are <em>operators</em>?</h1>
129 </section>
130
131 <section>
132 <img src="/images/ugly-openstack.jpg" />
133 </section>
134
135 <section>
136 <h1>Why wouldn't you give your operators the same power as your
137 developers?</h1>
138 <p>Don't you like them?</p>
139 </section>
140
141 </section>
142
143 <section>
144 <h1><i>Ironic</i> is a service capable of<br>
145 managing and provisioning<br>
146 <i>physical machines</i>.</h1>
147 <aside class="notes">
148 Do one thing and do it well. Ready-state-GO!<br>
149 Vendor neutral API. Distributed control plane.<br>
150 Deploy images to reduce entropy. Servers are cattle, not pets.<br>
151 Can use stand-alone, but not simple today.
152 </aside>
153 </section>
154
155 <section>
156 <h1>Nova + Ironic</h1>
157 Same but different
158 <aside class="notes">
159 User gets same Nova API. Abstraction is maintained.<br>
160 What are the benefits using Nova? (sched, flavors, etc)<br>
161 Talk briefly about evolution from nova-baremetal.
162 </aside>
163 </section>
164
165 <section>
166 <a href="#/2" class="image"><img src="/images/ironic-nova-layer.jpg"></a>
167 <aside class="notes">
168 Talk through the slide<br>
169 Going to show some examples next
170 </aside>
171 </section>
172 <section>
173 <pre><code>
174$ ironic node-create -d pxe_ipmitool \
175 -i ipmi_username=admin -i ipmi_password=fake -i ipmi_address=10.1.2.3 \
176 -p cpus=4 -p memory_mb=8192 -p local_gb=500 \
177 -e note='spare server'
178+--------------+------------------------------------------------------------+
179| Property | Value |
180+--------------+------------------------------------------------------------+
181| chassis_uuid | None |
182| driver | pxe_ipmitool |
183| driver_info | {u'ipmi_address': u'10.1.2.3', u'ipmi_username': u'admin', |
184| | u'ipmi_password': u'fake'} |
185| extra | {u'note': u'spare server'} |
186| properties | {u'memory_mb': u'8192', u'local_gb': u'500', u'cpus': u'4'}|
187| uuid | 7a1ce8d0-9679-4d87-8f54-b11f6e8adb8f |
188+--------------+------------------------------------------------------------+
189 </code></pre>
190 </section>
191 <section>
192 <pre><code>
193$ tail -f /var/log/nova/n-cpu.log
194...
1952014-05-01 03:47:05.878 AUDIT nova.compute.resource_tracker [-]
196 Free ram (MB): 8192
1972014-05-01 03:47:05.878 AUDIT nova.compute.resource_tracker [-]
198 Free disk (GB): 500
1992014-05-01 03:47:05.878 AUDIT nova.compute.resource_tracker [-]
200 Free VCPUS: 4
201 </code></pre>
202 </section>
203
204 <section>
205 <h1>Diversity is good</h1>
206 <ul>
207 <li>Cloud providers: HP, Rackspace, Dreamhost, Cloudwatt</li>
208 <li>Deployments: Public, Managed, Private</li>
209 <li>Compute drivers: virtual, bare metal, container</li>
210 <li>Ironic drivers: pxe/impi, ilo, HP OneView</li>
211 </ul>
212 </section>
213
214 <section>
215 <h1>What can you do?</h1>
216 <h3 class="fragment">anything - it's a cloud</h3>
217 </section>
218
219 <section>
220 <h1>What the heck has the TripleO team been doing then?</h1>
221 <img src="/images/worstcat-lettuce.jpg" />
222 </section>
223
224 <section>
225 <h1>TripleO</h1>
226 <ul>
227 <li>Community developed</li>
228 <li>Opinionated</li>
229 <li>Avoid distro and config management religion</li>
230 <li>Be a usable <em>real</em> deployment we can gate on</li>
231 </ul>
232 </section>
233
234 <section>
235 <h1> Community Developed </h1>
236 <ul>
237 <li>Exist as part of the OpenStack project</li>
238 <li>Prove the story end to end</li>
239 <li>Subject to TC governance</li>
240 <li>Tighter feedback loop</li>
241 </ul>
242 </section>
243
244 <section>
245 <h1> Avoid distro and config management religion </h1>
246 <ul>
247 <li>rpm vs. deb - in the gate == rpm + deb</li>
248 <li>puppet vs. chef vs. salt vs. ansible == all of them</li>
249 <li>Choosing one excludes other folks from participating</li>
250 </ul>
251 </section>
252
253 <section>
254 <h1> Opinionated </h1>
255 <ul>
256 <li>Golden Images</li>
257 <li>Upgrade tied to HA</li>
258 <li>Target Continual Delivery</li>
259 <li>Drive fixes into OpenStack directly</li>
260 </ul>
261 </section>
262
263 <section>
264 <h1>Major Components</h1>
265 <ul>
266 <li>nova+ironic</li>
267 <li>heat</li>
268 <li>diskimage-builder</li>
269 <li>os-collect-config</li>
270 <li>os-apply-config</li>
271 <li>os-refresh-config</li>
272 </ul>
273 </section>
274
275 <section>
276 <h1>Lesson from os-*-config</h1>
277 <img class="fragment" src="/images/worstcat-dog.jpg" />
278 </section>
279
280 <section>
281 <h1>Lesson from os-*-config</h1>
282 <img class="fragment" src="/images/standards.png" />
283 </section>
284
285 <section>
286 <h1>Lesson from os-*-config</h1>
287 <p>If you ever think "oh, that's silly, it would be so much easier
288 if I just ..."<br /> it will almost never actually be easier if you
289 just ...</p>
290 </section>
291
292 <section>
293 <h1>The Deployment Story</h1>
294 <ol>
295 <li>disk-image-builder builds images and uploads to glance</li>
296 <li>Heat drives Nova/Ironic</li>
297 <li>Heat delivers metadata to os-collect-config</li>
298 <li>os-collect-config applies any in-instance changes needed</li>
299 </ol>
300 </section>
301
302 <section>
303 <h1>The Update Story</h1>
304 <p>Heat magically just updates things</li>
305 </section>
306
307 <section>
308 <h1>BUT I ALREADY USE ?????</h1>
309 <h3>(screw you guys, I'm going home)</h3>
310 </section>
311
312 <section>
313 <h1>Yeah, I do to</h1>
314 <h3>(I use puppet and ansible myself)</h3>
315 </section>
316
317 <section>
318 <h1>That's fine - use them - it's a cloud!</h1>
319 <h3 class="fragment">This is supposed to be empowering, not enforcing</h3>
320 </section>
321
322 <section>
323 <h1>Whatever you want!</h1>
324 <ul>
325 <li>Heat to deploy and update images, os-*-*config for config</li>
326 <li>Heat to deploy images, ansible to update images, puppet for config</li>
327 <li>Ansible to deploy base image + packages, salt to update packages, chef for config</li>
328 <li>juju to deploy ... nah, I'm just kidding</li>
329 </ul>
330 </section>
331
332 <section>
333 <h1>The New Update Story</h1>
334 <p>Ansible takes over for upgrades</p>
335 </section>
336
337 <section id="step-two-ansible-for-orchestration" class="titleslide slide level1">
338 <h1>Ansible for Orchestration</h1>
339 </section>
340
341 <section id="about-ansible" class="slide level2">
342 <h1>About Ansible</h1>
343 <ul>
344 <li>Open Source System Management tool</li>
345 <li>Written in Python</li>
346 <li>Sequence of steps to perform</li>
347 <li>Works over SSH</li>
348 <li>Incremental Adoption</li>
349 </ul>
350 </section>
351
352 <section>
353 <h1>ad-hoc operation</h1>
354 <pre>
355ansible '*' -m shell -p uptime
356 </pre>
357 </section>
358
359 <section id="yaml-syntax" class="slide level2">
360 <h1>YAML Syntax</h1>
361 <pre><code>
362- hosts: '*.slave.openstack.org'
363 tasks:
364 - shell: 'rm -rf ~jenkins/workspace/*{{ project }}*'
365 </code></pre>
366 <p>That's executed:</p>
367 <pre>
368ansible-playbook -f 10 /etc/ansible/clean_workspaces.yaml --extra-vars "project=$PROJECTNAME"
369 </pre>
370 </section>
371
372 <section id="ansible-organization" class="slide level2">
373 <h1>Ansible Organization</h1>
374 <ul>
375 <li>modules</li>
376 <li>plays</li>
377 <li>playbooks</li>
378 <li>roles</li>
379 </ul>
380 </section>
381
382 <section id="use-ansible-to-run-puppet" class="slide level2">
383 <h1>Use Ansible to Run Puppet!</h1>
384 </section>
385
386 <section id="puppet-module" class="slide level2">
387 <h1>puppet module</h1>
388 <pre><code>def main():
389 module = AnsibleModule(argument_spec=dict(
390 timeout=dict(default="30m"),
391 puppetmaster=dict(required=True),
392 show_diff=dict(default=False, aliases=['show-diff'], type='bool'),
393 ))
394 p = module.params
395
396 puppet_cmd = module.get_bin_path("puppet", False)
397 if not puppet_cmd:
398 module.fail_json(msg="Could not find puppet. Please ensure it is installed.")
399 </code></pre>
400 </section>
401
402 <section id="puppet-module-2" class="slide level2">
403 <h1>puppet module (cont)</h1>
404 <pre><code class="python">
405 cmd = ("timeout -s 9 %(timeout)s %(puppet_cmd)s agent --onetime"
406 " --server %(puppetmaster)s"
407 " --ignorecache --no-daemonize --no-usecacheonfailure --no-splay"
408 " --detailed-exitcodes --verbose") % dict(
409 timeout=pipes.quote(p['timeout']), puppet_cmd=PUPPET_CMD,
410 puppetmaster=pipes.quote(p['puppetmaster']))
411 if p['show_diff']:
412 cmd += " --show-diff"
413 rc, stdout, stderr = module.run_command(cmd)
414 </code></pre>
415 </section>
416
417 <section id="puppet-module-3" class="slide level2">
418 Please. Everyone. Marvel at the following logic
419 <pre><code>
420 if rc == 0: # success
421 module.exit_json(rc=rc, changed=False, stdout=stdout)
422 elif rc == 1:
423 # rc==1 could be because it's disabled OR there was a compilation failure
424 disabled = "administratively disabled" in stdout
425 if disabled:
426 msg = "puppet is disabled"
427 else:
428 msg = "puppet compilation failed"
429 module.fail_json(rc=rc, disabled=disabled, msg=msg, stdout=stdout, stderr=stderr)
430 elif rc == 2: # success with changes
431 module.exit_json(changed=True)
432 elif rc == 124: # timeout
433 module.exit_json(rc=rc, msg="%s timed out" % cmd, stdout=stdout, stderr=stderr)
434 else: # failure
435 module.fail_json(rc=rc, msg="%s failed" % (cmd), stdout=stdout, stderr=stderr)
436 </code></pre>
437 </section>
438
439 <section id="puppet-play" class="slide level2">
440 <h1>puppet play</h1>
441 <pre><code>
442- name: run puppet
443 puppet:
444 puppetmaster: "{{puppetmaster}}"
445 </code></pre>
446 </section>
447
448 <section id="puppet-role" class="slide level2">
449 <h1>puppet role</h1>
450 <p>roles/remote_puppet/tasks/main.yml</p>
451 </section>
452
453 <section id="remote-puppet-playbook" class="slide level2">
454 <h1>remote puppet playbook</h1>
455 <pre><code>
456- hosts: git0*
457 gather_facts: false
458 max_fail_percentage: 1
459 roles:
460 - { role: remote_puppet, puppetmaster: puppetmaster.openstack.org }
461- hosts: review.openstack.org
462 gather_facts: false
463 roles:
464 - { role: remote_puppet, puppetmaster: puppetmaster.openstack.org }
465- hosts: "!review.openstack.org:!git0*:!afs*"
466 gather_facts: false
467 roles:
468 - { role: remote_puppet, puppetmaster: puppetmaster.openstack.org }
469 </pre></code>
470 </section>
471
472 <section id="ansible-inventory" class="slide level2">
473 <h1>ansible inventory</h1>
474 <ul>
475 <li>List of servers to operate on</li>
476 <li>Optionally variables associated with each server</li>
477 <li>Optional groups of servers</li>
478 <li>Simple file in /etc/ansible/hosts</li>
479 <li>Dynamic executable that returns JSON</li>
480 </ul>
481 </section>
482
483 <section id="ansible-inventory-from-file" class="slide level2">
484 <h1>Simple inventory</h1>
485 <pre>
486review.openstack.org
487git01.openstack.org
488git02.openstack.org
489pypi.dfw.openstack.org
490pypi.iad.openstack.org
491
492[pypi]
493pypi.dfw.openstack.org
494pypi.iad.openstack.org
495
496[git]
497git01.openstack.org
498git02.openstack.org
499 </pre>
500 </section>
501
502 <section id="ansible-inventory-from-puppet" class="slide level2">
503 <h1>ansible inventory from puppet certs</h1>
504 <pre><code>
505import json
506import subprocess
507
508output = [
509 x.split()[1][1:-1] for x in subprocess.check_output(
510 ["puppet","cert","list","-a"]).split('\n')
511 if x.startswith('+')
512]
513
514data = {
515 '_meta': {'hostvars': dict()},
516 'ungrouped': output,
517}
518print json.dumps(data, sort_keys=True, indent=2)
519 </code></pre>
520 </section>
521
522 <section>
523 <h1>Ansible for Cloud Management</h1>
524 </section>
525
526 <section>
527 <h1>ansible and OpenStack</h1>
528 <ul>
529 <li>Ansible modules are just python</li>
530 <li>playbooks are lists of steps to take</li>
531 <li>Have plays/roles that provision servers</li>
532 <li>Infrastructure as code - for real!</li>
533 </ul>
534 </section>
535
536 <section>
537 <h1>Consider this data</h1>
538 <pre><code>
539pypi:
540 image_name: Ubuntu 12.04.4
541 flavor_ram: 2048
542 provision_group: ubuntu_hosts
543 volumes:
544 - size: 200
545 mount: /srv
546 hosts:
547 pypi.dfw:
548 region: DFW
549 pypi.iad:
550 region: IAD
551 pypi.ord:
552 region: ORD
553 pypi.region-b.geo-1:
554 cloud: hp
555 </code></pre>
556 </section>
557
558 <section>
559 <h1>Steps to launch a node</h1>
560 <ol>
561 <li>Create a compute instance</li>
562 <li>Wait for instance to exist</li>
563 <li>Create a floating IP</li>
564 <li>Attach floating IP to instance</li>
565 <li>Create one or more volumes</li>
566 <li>Attach volumes to instance</li>
567 <li>Wait for SSH to work</li>
568 <li>On host, format each volume</li>
569 <li>On host, mount each volume</li>
570 <li>On host, install config management software</li>
571 <li>On host, run config management software</li>
572 </ol>
573 </section>
574
575 <section>
576 <h1>Launch a node</h1>
577 <pre><code>
578---
579- name: Launch Node
580 os_compute:
581 cloud: "{{ cloud }}"
582 region_name: "{{ region_name }}"
583 name: "{{ name }}"
584 image_name: "{{ image_name }}"
585 flavor_ram: "{{ flavor_ram }}"
586 flavor_include: "{{ flavor_include }}"
587 meta:
588 group: "{{ group }}"
589 key_name: "{{ launch_keypair }}"
590 register: node
591- name: Create volumes
592 os_volume:
593 cloud: "{{ cloud }}"
594 size: "{{ item.size }}"
595 display_name: "{{ item.display_name }}"
596 with_items: volumes
597- name: Attach volumes
598 os_compute_volume:
599 cloud: "{{ cloud }}"
600 server_id: "{{ node.id }}"
601 volume_name: "{{ item.display_name }}"
602 with_items: volumes
603 register: attached_volumes
604- debug: var=attached_volumes
605- name: Re-request server to get up to date metadata after the volume loop
606 os_compute_facts:
607 cloud: "{{ cloud }}"
608 name: "{{ name }}"
609 when: attached_volumes.changed
610- name: Wait for SSH to work
611 wait_for: host={{ node.openstack.interface_ip }} port=22
612 when: node.changed == True
613- name: Add SSH host key to known hosts
614 shell: ssh-keyscan "{{ node.openstack.interface_ip|quote }}" &gt;&gt; ~/.ssh/known_hosts
615 when: node.changed == True
616- name: Add all instance public IPs to host group
617 add_host:
618 name: "{{ node.openstack.interface_ip }}"
619 groups: "{{ provision_group }}"
620 openstack: "{{ node.openstack }}"
621 when: attached_volumes|length == 0
622- name: Add all instance public IPs to host and volumes group
623 add_host:
624 name: "{{ node.openstack.interface_ip }}"
625 groups: "{{ provision_group }},hasvolumes"
626 openstack: "{{ node.openstack }}"
627 when: attached_volumes|length != 0
628 </code></pre>
629 </section>
630
631 <section>
632 <h1> Cloud based inventory </h1>
633 <ul>
634 <li> Just ask the cloud for the inventory </li>
635 <li> All of the meta-data the cloud knows is available </li>
636 </ul>
637 </section>
638
639 <section>
640 <pre><code>
641 "pypi.dfw.openstack.org": {
642 "ansible_ssh_host": "23.253.237.8",
643 "openstack": {
644 "HUMAN_ID": true,
645 "NAME_ATTR": "name",
646 "OS-DCF:diskConfig": "MANUAL",
647 "OS-EXT-STS:power_state": 1,
648 "OS-EXT-STS:task_state": null,
649 "OS-EXT-STS:vm_state": "active",
650 "accessIPv4": "23.253.237.8",
651 "accessIPv6": "2001:4800:7817:104:d256:7a33:5187:7e1b",
652 "addresses": {
653 "private": [
654 {
655 "addr": "10.208.195.50",
656 "version": 4
657 }
658 ],
659 "public": [
660 {
661 "addr": "23.253.237.8",
662 "version": 4
663 },
664 {
665 "addr": "2001:4800:7817:104:d256:7a33:5187:7e1b",
666 "version": 6
667 }
668 ]
669 },
670 "cloud": "rax",
671 "config_drive": "",
672 "created": "2014-09-05T15:32:14Z",
673 "flavor": {
674 "id": "performance1-4",
675 "links": [
676 {
677 "href": "https://dfw.servers.api.rackspacecloud.com/610275/flavors/performance1-4",
678 "rel": "bookmark"
679 }
680 ],
681 "name": "4 GB Performance"
682 },
683 "hostId": "adb603d4566efe0392756c76dab38ffcba22099368837c7973321e77",
684 "human_id": "pypidfwopenstackorg",
685 "id": "de672205-9245-46b6-b3df-489ccf9e0c17",
686 "image": {
687 "id": "928e709d-35f0-47eb-b296-d18e1b0a76b7",
688 "links": [
689 {
690 "href": "https://dfw.servers.api.rackspacecloud.com/610275/images/928e709d-35f0-47eb-b296-d18e1b0a76b7",
691 "rel": "bookmark"
692 }
693 ]
694 },
695 "interface_ip": "23.253.237.8",
696 "key_name": "launch-node-root",
697 "links": [
698 {
699 "href": "https://dfw.servers.api.rackspacecloud.com/v2/610275/servers/de672205-9245-46b6-b3df-489ccf9e0c17",
700 "rel": "self"
701 },
702 {
703 "href": "https://dfw.servers.api.rackspacecloud.com/610275/servers/de672205-9245-46b6-b3df-489ccf9e0c17",
704 "rel": "bookmark"
705 }
706 ],
707 "metadata": {},
708 "name": "pypi.dfw.openstack.org",
709 "networks": {
710 "private": [
711 "10.208.195.50"
712 ],
713 "public": [
714 "23.253.237.8",
715 "2001:4800:7817:104:d256:7a33:5187:7e1b"
716 ]
717 },
718 "progress": 100,
719 "region": "DFW",
720 "status": "ACTIVE",
721 "tenant_id": "610275",
722 "updated": "2014-09-05T15:32:49Z",
723 "user_id": "156284",
724 "volumes": [
725 {
726 "HUMAN_ID": false,
727 "NAME_ATTR": "name",
728 "attachments": [
729 {
730 "device": "/dev/xvdb",
731 "host_name": null,
732 "id": "c6f5229c-1cc0-47c4-aab7-60db1f6cf8e8",
733 "server_id": "de672205-9245-46b6-b3df-489ccf9e0c17",
734 "volume_id": "c6f5229c-1cc0-47c4-aab7-60db1f6cf8e8"
735 }
736 ],
737 "availability_zone": "nova",
738 "bootable": "false",
739 "created_at": "2014-09-05T14:37:42.000000",
740 "device": "/dev/xvdb",
741 "display_description": null,
742 "display_name": "pypi.dfw.openstack.org/main01",
743 "human_id": null,
744 "id": "c6f5229c-1cc0-47c4-aab7-60db1f6cf8e8",
745 "metadata": {
746 "readonly": "False",
747 "storage-node": "1845027a-5e07-47a1-9572-3eea4716f726"
748 },
749 "os-vol-tenant-attr:tenant_id": "610275",
750 "size": 200,
751 "snapshot_id": null,
752 "source_volid": null,
753 "status": "in-use",
754 "volume_type": "SATA"
755 }
756 ]
757 }
758 },
759 </code></pre>
760 </section>
761
762
763 <section>
764 <h1> Thank you! </h1>
765 <h3>Monty Taylor</h3>
766 <h3> twitter: @e_monty </h3>
767 <h4> <a href='http://inaugust.com/talks/tripleo-ansible.html'>http://inaugust.com/talks/tripleo-ansible.html</a> </h4>
768 </section>
769
770 </div>
771
772 <div class="footer">
773 <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">
774 <img alt="Creative Commons License"
775 style="border-width:0"
776 src="https://i.creativecommons.org/l/by/4.0/88x31.png" />
777 </a><br />
778 Licensed under a
779 <a rel="license"
780 href="http://creativecommons.org/licenses/by/4.0/">
781 Creative Commons Attribution 4.0 International License
782 </a>.
783 <br />
784 Source code available at <a href='http://git.inaugust.com/cgit/inaugust.com'>http://git.inaugust.com/cgit/inaugust.com</a>
785 </div>
786 </div>
787
788 <script src="/lib/js/head.min.js"></script>
789 <script src="/js/reveal.js"></script>
790
791 <script src="/js/this.js"></script>
792
793</body>
794</html>