summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty Taylor <mordred@inaugust.com>2015-08-01 02:53:18 +1000
committerMonty Taylor <mordred@inaugust.com>2015-08-01 03:21:11 +1000
commit22ab0f1a87a61a84dc78721ecbdde43ec2b1c556 (patch)
treeec912b14a07cf7e1e046e4b9e957feb727e18800
parent71db6e4ca1962d708f2da6cf6e532ace38eabfba (diff)
Add talks
-rw-r--r--src/talks/a-vision-for-the-future/index.html2
-rw-r--r--src/talks/ansible-cloud/index.html792
-rw-r--r--src/talks/glean/index.html209
-rw-r--r--src/talks/index/index.html74
-rw-r--r--src/talks/lemmings/index.html331
-rw-r--r--src/talks/now-what/index.html436
-rw-r--r--src/talks/os-client-config/index.html242
-rw-r--r--src/talks/product-management/index.html454
-rw-r--r--src/talks/tripleo-ansible/index.html794
9 files changed, 3333 insertions, 1 deletions
diff --git a/src/talks/a-vision-for-the-future/index.html b/src/talks/a-vision-for-the-future/index.html
index 88fdbe5..abd3851 100644
--- a/src/talks/a-vision-for-the-future/index.html
+++ b/src/talks/a-vision-for-the-future/index.html
@@ -483,7 +483,7 @@
483 Creative Commons Attribution 4.0 International License 483 Creative Commons Attribution 4.0 International License
484 </a>. 484 </a>.
485 <br /> 485 <br />
486 Source code available at <a href='http://git.inaugust.com/cgit/mordred-talks'>http://git.inaugust.com/cgit/mordred-talks</a> 486 Source code available at <a href='http://git.inaugust.com/cgit/inaugust.com'>http://git.inaugust.com/cgit/inaugust.com</a>
487 </div> 487 </div>
488 488
489 </div> 489 </div>
diff --git a/src/talks/ansible-cloud/index.html b/src/talks/ansible-cloud/index.html
new file mode 100644
index 0000000..37e66c6
--- /dev/null
+++ b/src/talks/ansible-cloud/index.html
@@ -0,0 +1,792 @@
1<!doctype html>
2<html lang="en">
3
4 <head>
5 <meta charset="utf-8">
6
7 <title>NoOps with Ansible and Puppet</title>
8
9 <meta name="author" content="Monty Taylor" />
10
11 <meta name="apple-mobile-web-app-capable" content="yes" />
12 <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
13
14 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
15
16 <link rel="stylesheet" href="/css/reveal.css">
17 <link rel="stylesheet" href="/css/theme/openstack.css" id="theme">
18
19 <!-- For syntax highlighting -->
20 <link rel="stylesheet" href="/lib/css/zenburn.css">
21
22 <!-- If the query includes 'print-pdf', include the PDF print sheet -->
23 <script>
24 var link = document.createElement('link');
25 link.rel = 'stylesheet';
26 link.type = 'text/css';
27 link.href =
28 window.location.search.match(/print-pdf/gi) ? '/css/print/pdf.css' :
29 '/css/print/paper.css';
30 document.getElementsByTagName('head')[0].appendChild(link);
31 </script>
32 </head>
33 <body>
34 <body>
35
36 <div class="background">
37 <img alt="" id="head-icon" width="218" height="67"
38 src="/images/openstack-cloud-software-horizontal-small.png" /></div>
39
40
41 <div class="reveal">
42 <div class="slides">
43
44 <section data-state="cover">
45 <img src="/images/openstack-cloud-software-vertical-large.png"
46 alt="OpenStack" id="cover"/>
47
48 <h1><span xmlns:dct="http://purl.org/dc/terms/"
49 href="http://purl.org/dc/dcmitype/InteractiveResource"
50 property="dct:title"
51 rel="dct:type">
52 NoOps with Ansible and Puppet
53 </span></h1>
54 <h3 xmlns:cc="http://creativecommons.org/ns#"
55 property="cc:attributionName">Monty Taylor</h3>
56 <h4><a xmlns:cc="http://creativecommons.org/ns#"
57 rel="cc:attributionURL"
58 href='http://inaugust.com/talks/ansible-cloud.html'>http://inaugust.com/talks/ansible-cloud.html</a> </h4>
59 <h3> twitter: @e_monty </h3>
60 </section>
61
62 <section id="who-am-i" class="slide level2">
63 <h1>Who am I?</h1>
64 <ul>
65 <li>Distinguished Technologist at HP</li>
66 <li>OpenStack Technical Committee</li>
67 <li>OpenStack Foundation Board of Directors</li>
68 <li>OpenStack Developer Infrastructure Core Team</li>
69 <li>Former Consultant for MySQL, Inc</li>
70 <li>Former Drizzle Core Developer</li>
71 </ul>
72 </section>
73
74 <section id="what-are-we-going-to-talk-about" class="slide level2">
75 <h1>What are we going to talk about?</h1>
76 <ul>
77 <li>NoOps</li>
78 <li>Cloud Applications</li>
79 <li>Puppet</li>
80 <li>Ansible</li>
81 </ul>
82 </section>
83
84 <section id="no-ops" class="slide level2">
85 <h1>NoOps</h1>
86 <p class="fragment">NoOps means developers can code and let a service deploy, manage and scale their code</p>
87 <p class="fragment">I don't want to "do ops"</p>
88 <p class="fragment">I want to change the system by landing commits</p>
89 <p class="fragment">If I have to use my root access, it's a bug</p>
90 </section>
91
92 <section id="cloud-native" class="slide level2">
93 <h1>Cloud Native</h1>
94 <ul>
95 <li>Ephemeral Compute</li>
96 <li>Data services</li>
97 <li>Design your applications to be resilient via scale out</li>
98 </ul>
99 </section>
100
101 <section id="cloud-scale-out" class="slide level2">
102 <h1>Cloud Scale Out</h1>
103 <ul>
104 <li>Forget HA of one system</li>
105 <li>Forget long-lived systems</li>
106 <li>Shared-nothing for EVERYTHING</li>
107 </ul>
108 </section>
109
110 <section id="cloud-scale-out-is-great-for-new-applications" class="slide level2">
111 <h1>Cloud Scale Out is great for new applications</h1>
112 </section>
113
114 <section id="what-about-existing-applications" class="slide level2">
115 <h1>What about existing applications?</h1>
116 </section>
117
118 <section>
119 <section id="openstack-infra" data-transition='zoom'>
120 <h1>OpenStack Infra</h1>
121 </section>
122
123 <section id="tooling-automation-and-ci-for-openstack-project" class="slide level2" data-transition='zoom'>
124 <h1>Tooling, Automation and CI for OpenStack Project</h1>
125 </section>
126
127 <section id="developers" class="slide level2" data-transition='zoom'>
128 <h1>2000 Developers</h1>
129 </section>
130
131 <section id="gated-commits" class="slide level2" data-transition='zoom'>
132 <h1>Gated Commits</h1>
133 <p>Every commit is fully integration tested (twice) before landing</p>
134 </section>
135
136 <section id="each-test-runs-on-a-single-use-cloud-slave" class="slide level2" data-transition='zoom'>
137 <h1>Each Test Runs on a Single Use Cloud Slave</h1>
138 <p>This is that "cloud scale out" part</p>
139 </section>
140
141 <section id="million-test-jobs-in-the-last-6-months" class="slide level2" data-transition='zoom'>
142 <h1>1.7 Million Test Jobs in the last 6 Months</h1>
143 </section>
144
145 <section id="15-million-tests-in-december" class="slide level2" data-transition='zoom'>
146 <h1>15 Million Tests in December</h1>
147 </section>
148
149 <section id="terabytes-of-log-data-in-six-months" class="slide level2" data-transition='zoom'>
150 <h1>18 Terabytes of Log Data in six months</h1>
151 </section>
152
153 <section id="we-have-no-servers" class="slide level2" data-transition='zoom'>
154 <h1>We have no servers</h1>
155 <p>It all runs across HP and Rackspace Public Clouds.</p>
156 </section>
157
158 </section>
159
160 <section id="architecture" class="slide level2">
161 <h1>Architecture</h1>
162 <p><img src="/images/infra_architecture.jpg" alt="image" /></p>
163 </section>
164
165 <section id="it-didnt-start-this-way" class="slide level2">
166 <h1>It didn't start this way</h1>
167 <p><img src="/images/original.jpg" alt="image" /></p>
168 </section>
169
170 <section id="step-one-puppet" class="titleslide slide level1">
171 <h1>Step One: Puppet</h1>
172 </section>
173
174 <section id="overview" class="slide level2">
175 <h1>Overview</h1>
176 <ul>
177 <li>Open Source Config Management System</li>
178 <li>Written in Ruby</li>
179 <li>Models intended state</li>
180 <li>Wants to own entire system</li>
181 </ul>
182 </section>
183
184 <section id="config-management-is-great" class="slide level2">
185 <h1>Config Management is Great</h1>
186 <ul>
187 <li>Repeatable and consistent machines</li>
188 <li>Code Review</li>
189 <li>Collaboration from non-root users</li>
190 <li>Less repetition for me</li>
191 <li>Open Source Infrastructure</li>
192 <li><a href="http://git.openstack.org/cgit/openstack-infra/system-config/">http://git.openstack.org/cgit/openstack-infra/system-config/</a></li>
193 <li><a href="http://puppetdb.openstack.org/">http://puppetdb.openstack.org/</a></li>
194 </ul>
195 </section>
196
197 <section id="ruby-dsl" class="slide level2">
198 <h1>Ruby DSL</h1>
199 <pre><code>
200package { 'git':
201 ensure =&gt; 'present',
202}
203 </code></pre>
204 </section>
205
206 <section id="leaky-abstraction" class="slide level2">
207 <h1>Leaky Abstraction</h1>
208 <pre><code>
209if !defined(Package['git']) {
210 package { 'git':
211 ensure =&gt; 'present',
212 }
213}
214 </code></pre>
215 </section>
216
217 <section id="three-ways-to-run" class="slide level2">
218 <h1>Three ways to run</h1>
219 <ul>
220 <li>puppet apply</li>
221 <li>puppetmaster + puppet agent daemons</li>
222 <li>puppetmaster + puppet agent non-daemon</li>
223 </ul>
224 </section>
225
226 <section id="managing-users-and-ssh-keys" class="slide level2">
227 <h1>Managing users and ssh keys</h1>
228 <pre><code>
229define user::virtual::localuser(
230 $realname,
231 $groups = [ 'sudo', 'admin', ],
232 $sshkeys = '',
233 $key_id = '',
234 $old_keys = [],
235 $shell = '/bin/bash',
236 $home = "/home/${title}",
237 $managehome = true
238) {
239
240 group { $title:
241 ensure =&gt; present,
242 }
243 </code></pre>
244 </section>
245
246 <section id="managing-users-and-ssh-keys-2" class="slide level2">
247 <h1>Managing users and ssh keys (cont.)</h1>
248 <pre><code>
249 user { $title:
250 ensure =&gt; present,
251 comment =&gt; $realname,
252 gid =&gt; $title,
253 groups =&gt; $groups,
254 home =&gt; $home,
255 managehome =&gt; $managehome,
256 membership =&gt; 'minimum',
257 shell =&gt; $shell,
258 require =&gt; Group[$title],
259 }
260 </code></pre>
261 </section>
262
263 <section id="managing-users-and-ssh-keys-3" class="slide level2">
264 <h1>Managing users and ssh keys (cont.)</h1>
265 <pre><code>
266 ssh_authorized_key { $key_id:
267 ensure =&gt; present,
268 key =&gt; $sshkeys,
269 user =&gt; $title,
270 type =&gt; 'ssh-rsa',
271 }
272
273 if ( $old_keys != [] ) {
274 ssh_authorized_key { $old_keys:
275 ensure =&gt; absent,
276 user =&gt; $title,
277 }
278 }
279}
280 </code></pre>
281 </section>
282
283 <section id="our-code-is-open-source-right-what-about-passwords-and-keys-..." class="slide level2">
284 <h1>Our code is Open Source, right? What about passwords and keys ...</h1>
285 </section>
286
287 <section id="hiera" class="slide level2">
288 <h1>hiera</h1>
289 <ul>
290 <li>Simple YAML database, sits on puppetmaster</li>
291 <li>Use it for secret data</li>
292 <li>puppet code is still complete</li>
293 </ul>
294 <pre><code>
295node default {
296 class { 'openstack_project::server':
297 sysadmins =&gt; hiera('sysadmins', []),
298 }
299}
300 </code></pre>
301 <p>Breaks ability to use simple puppet apply</p>
302 </section>
303
304 <section id="step-two-ansible-for-orchestration" class="titleslide slide level1">
305 <h1>Step Two: Ansible for Orchestration</h1>
306 </section>
307
308 <section id="about-ansible" class="slide level2">
309 <h1>About Ansible</h1>
310 <ul>
311 <li>Open Source System Management tool</li>
312 <li>Written in Python</li>
313 <li>Sequence of steps to perform</li>
314 <li>Works over SSH</li>
315 <li>Incremental Adoption</li>
316 </ul>
317 </section>
318
319 <section>
320 <h1>ad-hoc operation</h1>
321 <pre>
322ansible '*' -m shell -p uptime
323 </pre>
324 </section>
325
326 <section id="yaml-syntax" class="slide level2">
327 <h1>YAML Syntax</h1>
328 <pre><code>
329- hosts: '*.slave.openstack.org'
330 tasks:
331 - shell: 'rm -rf ~jenkins/workspace/*{{ project }}*'
332 </code></pre>
333 <p>That's executed:</p>
334 <pre>
335ansible-playbook -f 10 /etc/ansible/clean_workspaces.yaml --extra-vars "project=$PROJECTNAME"
336 </pre>
337 </section>
338
339 <section id="ansible-organization" class="slide level2">
340 <h1>Ansible Organization</h1>
341 <ul>
342 <li>modules</li>
343 <li>plays</li>
344 <li>playbooks</li>
345 <li>roles</li>
346 </ul>
347 </section>
348
349 <section id="use-ansible-to-run-puppet" class="slide level2">
350 <h1>Use Ansible to Run Puppet!</h1>
351 </section>
352
353 <section id="puppet-module" class="slide level2">
354 <h1>puppet module</h1>
355 <pre><code>def main():
356 module = AnsibleModule(argument_spec=dict(
357 timeout=dict(default="30m"),
358 puppetmaster=dict(required=True),
359 show_diff=dict(default=False, aliases=['show-diff'], type='bool'),
360 ))
361 p = module.params
362
363 puppet_cmd = module.get_bin_path("puppet", False)
364 if not puppet_cmd:
365 module.fail_json(msg="Could not find puppet. Please ensure it is installed.")
366 </code></pre>
367 </section>
368
369 <section id="puppet-module-2" class="slide level2">
370 <h1>puppet module (cont)</h1>
371 <pre><code class="python">
372 cmd = ("timeout -s 9 %(timeout)s %(puppet_cmd)s agent --onetime"
373 " --server %(puppetmaster)s"
374 " --ignorecache --no-daemonize --no-usecacheonfailure --no-splay"
375 " --detailed-exitcodes --verbose") % dict(
376 timeout=pipes.quote(p['timeout']), puppet_cmd=PUPPET_CMD,
377 puppetmaster=pipes.quote(p['puppetmaster']))
378 if p['show_diff']:
379 cmd += " --show-diff"
380 rc, stdout, stderr = module.run_command(cmd)
381 </code></pre>
382 </section>
383
384 <section id="puppet-module-3" class="slide level2">
385 Please. Everyone. Marvel at the following logic
386 <pre><code>
387 if rc == 0: # success
388 module.exit_json(rc=rc, changed=False, stdout=stdout)
389 elif rc == 1:
390 # rc==1 could be because it's disabled OR there was a compilation failure
391 disabled = "administratively disabled" in stdout
392 if disabled:
393 msg = "puppet is disabled"
394 else:
395 msg = "puppet compilation failed"
396 module.fail_json(rc=rc, disabled=disabled, msg=msg, stdout=stdout, stderr=stderr)
397 elif rc == 2: # success with changes
398 module.exit_json(changed=True)
399 elif rc == 124: # timeout
400 module.exit_json(rc=rc, msg="%s timed out" % cmd, stdout=stdout, stderr=stderr)
401 else: # failure
402 module.fail_json(rc=rc, msg="%s failed" % (cmd), stdout=stdout, stderr=stderr)
403 </code></pre>
404 </section>
405
406 <section id="puppet-play" class="slide level2">
407 <h1>puppet play</h1>
408 <pre><code>
409- name: run puppet
410 puppet:
411 puppetmaster: "{{puppetmaster}}"
412 </code></pre>
413 </section>
414
415 <section id="puppet-role" class="slide level2">
416 <h1>puppet role</h1>
417 <p>roles/puppet/tasks/main.yml</p>
418 </section>
419
420 <section id="remote-puppet-playbook" class="slide level2">
421 <h1>remote puppet playbook</h1>
422 <pre><code>
423- hosts: git0*
424 gather_facts: false
425 max_fail_percentage: 1
426 roles:
427 - { role: puppet, puppetmaster: puppetmaster.openstack.org }
428- hosts: review.openstack.org
429 gather_facts: false
430 roles:
431 - { role: puppet, puppetmaster: puppetmaster.openstack.org }
432- hosts: "!review.openstack.org:!git0*:!afs*"
433 gather_facts: false
434 roles:
435 - { role: puppet, puppetmaster: puppetmaster.openstack.org }
436 </pre></code>
437 </section>
438
439 <section id="ansible-inventory" class="slide level2">
440 <h1>ansible inventory</h1>
441 <ul>
442 <li>List of servers to operate on</li>
443 <li>Optionally variables associated with each server</li>
444 <li>Optional groups of servers</li>
445 <li>Simple yaml file in /etc/ansible/hosts</li>
446 <li>Dynamic executable that returns JSON</li>
447 </ul>
448 </section>
449
450 <section id="ansible-inventory-from-file" class="slide level2">
451 <h1>Simple inventory</h1>
452 <pre>
453review.openstack.org
454git01.openstack.org
455git02.openstack.org
456pypi.dfw.openstack.org
457pypi.iad.openstack.org
458
459[pypi]
460pypi.dfw.openstack.org
461pypi.iad.openstack.org
462
463[git]
464git01.openstack.org
465git02.openstack.org
466 </pre>
467 </section>
468
469 <section id="ansible-inventory-from-puppet" class="slide level2">
470 <h1>ansible inventory from puppet certs</h1>
471 <pre><code>
472import json
473import subprocess
474
475output = [
476 x.split()[1][1:-1] for x in subprocess.check_output(
477 ["puppet","cert","list","-a"]).split('\n')
478 if x.startswith('+')
479]
480
481data = {
482 '_meta': {'hostvars': dict()},
483 'ungrouped': output,
484}
485print json.dumps(data, sort_keys=True, indent=2)
486 </code></pre>
487 </section>
488
489 <section>
490 <h1>Step Three: Ansible for Cloud Management</h1>
491 </section>
492
493 <section>
494 <h1>ansible and OpenStack</h1>
495 <ul>
496 <li>Ansible modules are just python</li>
497 <li>playbooks are lists of steps to take</li>
498 <li>Have plays/roles that provision servers</li>
499 <li>Infrastructure as code - for real!</li>
500 </ul>
501 </section>
502
503 <section>
504 <h1>Consider this data</h1>
505 <pre><code>
506pypi.dfw.openstack.org:
507 image_name: Ubuntu 12.04.4
508 flavor_ram: 2048
509 region: DFW
510 cloud: rackspace
511 volumes:
512 - size: 200
513 mount: /srv
514pypi.region-b.geo-1.openstack.org:
515 image_name: Ubuntu 12.04.4
516 flavor_ram: 2048
517 region: region-b.geo-1
518 cloud: hp
519 volumes:
520 - size: 200
521 mount: /srv
522 </code></pre>
523 </section>
524
525 <section>
526 <h1>Further consider this data</h1>
527 <pre><code>
528pypi:
529 image_name: Ubuntu 12.04.4
530 flavor_ram: 2048
531 volumes:
532 - size: 200
533 mount: /srv
534 hosts:
535 pypi.dfw:
536 region: DFW
537 pypi.iad:
538 region: IAD
539 pypi.ord:
540 region: ORD
541 pypi.region-b.geo-1:
542 cloud: hp
543 </code></pre>
544 </section>
545
546 <section>
547 <h1>Steps to launch a node</h1>
548 <ol>
549 <li>Create a compute instance</li>
550 <li>Wait for instance to exist</li>
551 <li>Create a floating IP</li>
552 <li>Attach floating IP to instance</li>
553 <li>Create one or more volumes</li>
554 <li>Attach volumes to instance</li>
555 <li>Wait for SSH to work</li>
556 <li>On host, format each volume</li>
557 <li>On host, mount each volume</li>
558 <li>On host, install config management software</li>
559 <li>On host, run config management software</li>
560 </ol>
561 </section>
562
563 <section>
564 <h1>Launch a node</h1>
565 <pre><code>
566---
567- name: Launch Node
568 os_compute:
569 cloud: "{{ cloud }}"
570 region_name: "{{ region_name }}"
571 name: "{{ name }}"
572 image_name: "{{ image_name }}"
573 flavor_ram: "{{ flavor_ram }}"
574 flavor_include: "{{ flavor_include }}"
575 meta:
576 group: "{{ group }}"
577 key_name: "{{ launch_keypair }}"
578 register: node
579- name: Create volumes
580 os_volume:
581 cloud: "{{ cloud }}"
582 size: "{{ item.size }}"
583 display_name: "{{ item.display_name }}"
584 with_items: volumes
585- name: Attach volumes
586 os_compute_volume:
587 cloud: "{{ cloud }}"
588 server_id: "{{ node.id }}"
589 volume_name: "{{ item.display_name }}"
590 with_items: volumes
591 register: attached_volumes
592- debug: var=attached_volumes
593- name: Re-request server to get up to date metadata after the volume loop
594 os_compute_facts:
595 cloud: "{{ cloud }}"
596 name: "{{ name }}"
597 when: attached_volumes.changed
598- name: Wait for SSH to work
599 wait_for: host={{ node.openstack.interface_ip }} port=22
600 when: node.changed == True
601- name: Add SSH host key to known hosts
602 shell: ssh-keyscan "{{ node.openstack.interface_ip|quote }}" &gt;&gt; ~/.ssh/known_hosts
603 when: node.changed == True
604- name: Add all instance public IPs to host group
605 add_host:
606 name: "{{ node.openstack.interface_ip }}"
607 groups: "{{ provision_group }}"
608 openstack: "{{ node.openstack }}"
609 when: attached_volumes|length == 0
610- name: Add all instance public IPs to host and volumes group
611 add_host:
612 name: "{{ node.openstack.interface_ip }}"
613 groups: "{{ provision_group }},hasvolumes"
614 openstack: "{{ node.openstack }}"
615 when: attached_volumes|length != 0
616 </code></pre>
617 </section>
618
619 <section>
620 <h1> Cloud based inventory </h1>
621 <ul>
622 <li> Just ask the cloud for the inventory </li>
623 <li> All of the meta-data the cloud knows is available </li>
624 <li> No need for puppetmaster now </li>
625 </ul>
626 </section>
627
628 <section>
629 <pre><code>
630 "pypi.dfw.openstack.org": {
631 "ansible_ssh_host": "23.253.237.8",
632 "openstack": {
633 "HUMAN_ID": true,
634 "NAME_ATTR": "name",
635 "OS-DCF:diskConfig": "MANUAL",
636 "OS-EXT-STS:power_state": 1,
637 "OS-EXT-STS:task_state": null,
638 "OS-EXT-STS:vm_state": "active",
639 "accessIPv4": "23.253.237.8",
640 "accessIPv6": "2001:4800:7817:104:d256:7a33:5187:7e1b",
641 "addresses": {
642 "private": [
643 {
644 "addr": "10.208.195.50",
645 "version": 4
646 }
647 ],
648 "public": [
649 {
650 "addr": "23.253.237.8",
651 "version": 4
652 },
653 {
654 "addr": "2001:4800:7817:104:d256:7a33:5187:7e1b",
655 "version": 6
656 }
657 ]
658 },
659 "cloud": "rax",
660 "config_drive": "",
661 "created": "2014-09-05T15:32:14Z",
662 "flavor": {
663 "id": "performance1-4",
664 "links": [
665 {
666 "href": "https://dfw.servers.api.rackspacecloud.com/610275/flavors/performance1-4",
667 "rel": "bookmark"
668 }
669 ],
670 "name": "4 GB Performance"
671 },
672 "hostId": "adb603d4566efe0392756c76dab38ffcba22099368837c7973321e77",
673 "human_id": "pypidfwopenstackorg",
674 "id": "de672205-9245-46b6-b3df-489ccf9e0c17",
675 "image": {
676 "id": "928e709d-35f0-47eb-b296-d18e1b0a76b7",
677 "links": [
678 {
679 "href": "https://dfw.servers.api.rackspacecloud.com/610275/images/928e709d-35f0-47eb-b296-d18e1b0a76b7",
680 "rel": "bookmark"
681 }
682 ]
683 },
684 "interface_ip": "23.253.237.8",
685 "key_name": "launch-node-root",
686 "links": [
687 {
688 "href": "https://dfw.servers.api.rackspacecloud.com/v2/610275/servers/de672205-9245-46b6-b3df-489ccf9e0c17",
689 "rel": "self"
690 },
691 {
692 "href": "https://dfw.servers.api.rackspacecloud.com/610275/servers/de672205-9245-46b6-b3df-489ccf9e0c17",
693 "rel": "bookmark"
694 }
695 ],
696 "metadata": {},
697 "name": "pypi.dfw.openstack.org",
698 "networks": {
699 "private": [
700 "10.208.195.50"
701 ],
702 "public": [
703 "23.253.237.8",
704 "2001:4800:7817:104:d256:7a33:5187:7e1b"
705 ]
706 },
707 "progress": 100,
708 "region": "DFW",
709 "status": "ACTIVE",
710 "tenant_id": "610275",
711 "updated": "2014-09-05T15:32:49Z",
712 "user_id": "156284",
713 "volumes": [
714 {
715 "HUMAN_ID": false,
716 "NAME_ATTR": "name",
717 "attachments": [
718 {
719 "device": "/dev/xvdb",
720 "host_name": null,
721 "id": "c6f5229c-1cc0-47c4-aab7-60db1f6cf8e8",
722 "server_id": "de672205-9245-46b6-b3df-489ccf9e0c17",
723 "volume_id": "c6f5229c-1cc0-47c4-aab7-60db1f6cf8e8"
724 }
725 ],
726 "availability_zone": "nova",
727 "bootable": "false",
728 "created_at": "2014-09-05T14:37:42.000000",
729 "device": "/dev/xvdb",
730 "display_description": null,
731 "display_name": "pypi.dfw.openstack.org/main01",
732 "human_id": null,
733 "id": "c6f5229c-1cc0-47c4-aab7-60db1f6cf8e8",
734 "metadata": {
735 "readonly": "False",
736 "storage-node": "1845027a-5e07-47a1-9572-3eea4716f726"
737 },
738 "os-vol-tenant-attr:tenant_id": "610275",
739 "size": 200,
740 "snapshot_id": null,
741 "source_volid": null,
742 "status": "in-use",
743 "volume_type": "SATA"
744 }
745 ]
746 }
747 },
748 </code></pre>
749 </section>
750
751 <section>
752 <h1> Wait - what about secrets? </h1>
753 <p class="fragment">ansible can just pass secrets to puppet apply as parameters </p>
754 </section>
755
756 <section>
757 <h1> Step Four: Just get rid of puppet ... </h1>
758 <p class="fragment">but that's another talk</p>
759 </section>
760
761 <section>
762 <h1> Thank you! </h1>
763 <p> http://inaugust.com/talks/ansible-cloud.html </p>
764 <h3>Monty Taylor</h3>
765 <h3> twitter: @e_monty </h3>
766 <h4> <a href='http://inaugust.com/talks/ansible-cloud.html'>http://inaugust.com/talks/ansible-cloud.html</a> </h4>
767 </section>
768
769 </div>
770 <div class="footer">
771 <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">
772 <img alt="Creative Commons License"
773 style="border-width:0"
774 src="https://i.creativecommons.org/l/by/4.0/88x31.png" />
775 </a><br />
776 Licensed under a
777 <a rel="license"
778 href="http://creativecommons.org/licenses/by/4.0/">
779 Creative Commons Attribution 4.0 International License
780 </a>.
781 <br />
782 Source code available at <a href='http://git.inaugust.com/cgit/inaugust.com'>http://git.inaugust.com/cgit/inaugust.com</a>
783 </div>
784 </div>
785
786 <script src="/lib/js/head.min.js"></script>
787 <script src="/js/reveal.js"></script>
788
789 <script src="/js/this.js"></script>
790
791</body>
792</html>
diff --git a/src/talks/glean/index.html b/src/talks/glean/index.html
new file mode 100644
index 0000000..bbf943a
--- /dev/null
+++ b/src/talks/glean/index.html
@@ -0,0 +1,209 @@
1<!doctype html>
2<html lang="en">
3
4 <head>
5 <meta charset="utf-8">
6
7 <title>glean: a minimal non-cloud-init cloud-init</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"></div>
35
36 <div class="reveal">
37 <div class="slides">
38
39 <section data-state="cover">
40 <h1><span xmlns:dct="http://purl.org/dc/terms/"
41 href="http://purl.org/dc/dcmitype/InteractiveResource"
42 property="dct:title"
43 rel="dct:type">
44 glean: a minimal non-cloud-init cloud-init
45 </span></h1>
46 <h3 xmlns:cc="http://creativecommons.org/ns#"
47 property="cc:attributionName">Monty Taylor</h3>
48 <h4><a xmlns:cc="http://creativecommons.org/ns#"
49 rel="cc:attributionURL"
50 href='http://inaugust.com/talks/os-client-config.html'>http://inaugust.com/talks/glean.html</a> </h4>
51 <h3> twitter: @e_monty </h3>
52 </section>
53
54 <section>
55 <h1>When you boot a VM, it needs boot time data or bootstrapping</h1>
56 </section>
57
58 <section>
59 <h1>I use ansible for orchestration</h1>
60 </section>
61
62 <section>
63 <h1>I don't need boot time fancy,
64 I <em>JUST</em> need ssh bootstrap</h1>
65 <p class='fragment'>Ok. And maybe network</p>
66 </section>
67
68 <section>
69 <h1>Things I must consume at boot</h1>
70 <ul>
71 <li class='fragment'>
72 Network Configuration
73 </li>
74 <li class='fragment'>
75 <em>maybe</em> SSH Keys
76 </li>
77 </ul>
78 </section>
79
80 <section class="slide level2">
81 <h1>Network information should be easy</h1>
82 <p>There is this thing called DHCP</p>
83 <p>Dynamic Host Configuration Protocol</p>
84 </section>
85
86 <section class="slide level2">
87 <img src="/images/worstcat-lettuce.jpg" />
88 </section>
89
90 <section class="slide level2">
91 <h1>Some providers don't support DHCP - because bong</h1>
92 </section>
93
94 <section class="slide level2">
95 <h1>cloud-init</h1>
96 <p>Handles many cases, but not all</p>
97 <p>Has lots of dependencies that conflict with gate depends</p>
98 <p>'frozen' pending 2.0 rewrite</p>
99 </section>
100
101 <section class="slide level2">
102 <h1>glean</h1>
103 <h3>http://git.openstack.org/cgit/openstack-infra/glean</h3>
104 <ul>
105 <p>No dependencies</p>
106 <p>Handles future static network config in config drive</p>
107 <p>Optionally also reads ssh keys from config drive</p>
108 <p>Nothing else</p>
109 </ul>
110 </section>
111
112 <section>
113 <h1>network_info.json</h1>
114 <p>Hopefully added in liberty</p>
115 <pre>
116services:
117- type: dns
118 address: 72.3.128.241
119- type: dns
120 address: 72.3.128.240
121networks:
122- network_id: 00000000-0000-0000-0000-000000000000
123 type: ipv4
124 netmask: 255.255.255.0
125 link: tapfafb5c05-a6
126 routes:
127 - netmask: 0.0.0.0
128 network: 0.0.0.0
129 gateway: 23.253.229.1
130 ip_address: 23.253.229.154
131 id: network0
132- network_id: 11111111-1111-1111-1111-111111111111
133 type: ipv4
134 netmask: 255.255.224.0
135 link: tape501e1cd-10
136 routes:
137 - netmask: 255.240.0.0
138 network: 10.176.0.0
139 gateway: 10.208.160.1
140 - netmask: 255.240.0.0
141 network: 10.208.0.0
142 gateway: 10.208.160.1
143 ip_address: 10.208.169.118
144 id: network1
145links:
146- ethernet_mac_address: BC:76:4E:01:62:86
147 mtu: 1500
148 type: null
149 id: tapfafb5c05-a6
150 vif_id: fafb5c05-a661-48ae-9810-46601c7e22d1
151- ethernet_mac_address: BC:76:4E:05:7B:06
152 mtu: 1500
153 type: null
154 id: tape501e1cd-10
155 vif_id: e501e1cd-10d0-4e63-b0c2-6542989ccbb2
156 </pre>
157 </section>
158
159 <section class="slide level2">
160 <h1>Integrated with diskimage-builder</h1>
161 <pre>
162disk-image-create -o debian.qcow2 debian-minimal vm simple-init
163 </pre>
164 </section>
165
166 <section class="slide level2">
167 <h1>You know what has less depends than minimal python?</h1>
168 </section>
169
170 <section class="slide level2">
171 <h1>Rust</h1>
172 </section>
173
174 <section class="slide level2">
175 <h1>glean.rs</h1>
176 <h3>https://gitlab.com/mordred/glean.rs</h3>
177 </section>
178
179 <section>
180 <h1> Thank you! </h1>
181 <h4> <a href='http://inaugust.com/talks/glean.html'>http://inaugust.com/talks/glean.html</a> </h4>
182 <h3> twitter: @e_monty </h3>
183 </section>
184
185 </div>
186
187 <div class="footer">
188 <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">
189 <img alt="Creative Commons License"
190 style="border-width:0"
191 src="https://i.creativecommons.org/l/by/4.0/88x31.png" />
192 </a><br />
193 Licensed under a
194 <a rel="license"
195 href="http://creativecommons.org/licenses/by/4.0/">
196 Creative Commons Attribution 4.0 International License
197 </a>.
198 <br />
199 Source code available at <a href='http://git.inaugust.com/cgit/inaugust.com'>http://git.inaugust.com/cgit/inaugust.com</a>
200 </div>
201 </div>
202
203 <script src="/lib/js/head.min.js"></script>
204 <script src="/js/reveal.js"></script>
205
206 <script src="/js/this.js"></script>
207
208</body>
209</html>
diff --git a/src/talks/index/index.html b/src/talks/index/index.html
new file mode 100644
index 0000000..47b9774
--- /dev/null
+++ b/src/talks/index/index.html
@@ -0,0 +1,74 @@
1<!doctype html>
2<html lang="en">
3
4<head>
5<meta charset="utf-8">
6
7<title>Monty Taylor Conference Talks</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>
22if( 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
32<script src="js/jquery-1.7.2.min.js" charset="utf-8" type="text/javascript"></script>
33<script src="js/raphael-min.js" type="text/javascript" charset="utf-8"></script>
34
35</head>
36<body>
37
38<div class="reveal">
39 <div class="slides">
40 <section data-state="cover">
41 <h1> Monty Taylor Conference Talks </h1>
42
43 <p><a href='http://inaugust.com/talks/os-client-config.html'>os-client-config lightning talk</a></p>
44 <p><a href='http://inaugust.com/talks/ansible-cloud.html'>Using Ansible to Manage Cloud Applications</a></p>
45 <p><a href='http://inaugust.com/talks/tripleo-ansible.html'>Deploying OpenStack using TripleO and Ansible</a></p>
46 <p><a href='http://inaugust.com/talks/lemmings.html'>Lemmings, Think Different and Why Free Software is Important</a></p>
47 <p><a href='http://inaugust.com/talks/product-management.html'>Liberty, Product Management and OpenStack Technology</a></p>
48 <p><a href='http://inaugust.com/talks/now-what.html'>OpenStack works ... so now what?</a></p>
49 <p><a href='http://inaugust.com/talks/glean.html'>glean: a minimal non-cloud-init cloud-init</a></p>
50 <p><a href='http://inaugust.com/talks/a-vision-for-the-future.html'>OpenStack: a vision for the future</a>
51
52 </section>
53 </div>
54 <div class="footer">
55 <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">
56 <img alt="Creative Commons License"
57 style="border-width:0"
58 src="https://i.creativecommons.org/l/by/4.0/88x31.png" />
59 </a><br />
60 Licensed under a
61 <a rel="license"
62 href="http://creativecommons.org/licenses/by/4.0/">
63 Creative Commons Attribution 4.0 International License
64 </a>.
65 <br />
66 Source code available at <a href='http://git.inaugust.com/cgit/inaugust.com'>http://git.inaugust.com/cgit/inaugust.com</a>
67 </div>
68</div>
69<script src="lib/js/head.min.js"></script>
70<script src="js/reveal.js"></script>
71
72<script src="js/this.js"></script>
73
74</html>
diff --git a/src/talks/lemmings/index.html b/src/talks/lemmings/index.html
new file mode 100644
index 0000000..bbaa982
--- /dev/null
+++ b/src/talks/lemmings/index.html
@@ -0,0 +1,331 @@
1<!doctype html>
2<html lang="en">
3
4 <head>
5 <meta charset="utf-8">
6
7 <title>Lemmings, Think Different and Why Free Software is Important</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="reveal"><div class="slides">
35
36 <section data-state="cover">
37
38 <h1><span xmlns:dct="http://purl.org/dc/terms/"
39 href="http://purl.org/dc/dcmitype/InteractiveResource"
40 property="dct:title"
41 rel="dct:type">
42 Lemmings, Think Different and Why Free Software is Important
43 </span></h1>
44 <h3 xmlns:cc="http://creativecommons.org/ns#"
45 property="cc:attributionName">Monty Taylor</h3>
46 <h4><a xmlns:cc="http://creativecommons.org/ns#"
47 rel="cc:attributionURL"
48 href='http://inaugust.com/talks/lemmings.html'>http://inaugust.com/talks/lemmings.html</a> </h4>
49 <h3> twitter: @e_monty </h3>
50 </section>
51
52 <section class="slide level2">
53 <img src="/images/openstack-cloud-software-vertical-large.png"
54 alt="OpenStack" />
55 </section>
56
57 <section class="slide level2">
58 <img src="/images/openstack-software-diagram.png" alt="OpenStack" />
59 </section>
60
61 <section class="slide level2">
62 <h1>Mission</h1>
63 <p>
64 to produce the ubiquitous Open Source Cloud Computing platform that will meet the needs of public and private clouds regardless of size, by being simple to implement and massively scalable.
65 </p>
66 </section>
67
68 <section class="slide level2">
69 <img src="/images/openstack-size.jpg" />
70 </section>
71
72 <section class="slide level2">
73 <h1>Borrowed from Ubuntu</h1>
74 <p>Time Based Releases</p>
75 <p>Six Month Cadance</p>
76 <p>Design summits each cycle</p>
77 <p>Release codenames in alphabetical order</p>
78 </section>
79
80 <section class="slide level2">
81 <h1>Different from Ubuntu</h1>
82 <p>No BDFL</p>
83 <p>All decisions are democratic</p>
84 </section>
85
86 <section class="slide level2">
87 <h1>Naming Process</h1>
88 Pick a name from names of cities or geographical features near the
89 summit location
90 </section>
91
92 <section class="slide level2">
93 <h1>Grizzly</h1>
94 <p class="fragment">San Diego</p>
95 <p class="fragment">Grizzly bear on the flag</p>
96 </section>
97
98 <section class="slide level2">
99 <h1>Havana</h1>
100 <p class="fragment">Portland, OR</p>
101 <p class="fragment">not Cuba</p>
102 </section>
103
104 <section class="slide level2">
105 <h1>Icehouse</h1>
106 <p class="fragment">Hong Kong</p>
107 <p class="fragment">Street in HK</p>
108 </section>
109
110 <section class="slide level2">
111 <h1>Juno</h1>
112 <p class="fragment">Atlanta, GA</p>
113 <p class="fragment">Town in Georgia</p>
114 </section>
115
116 <section class="slide level2">
117 <h1>Kilo</h1>
118 <p class="fragment">Paris</p>
119 <p class="fragment">location of the actual kilogramme</p>
120 </section>
121
122 <section class="slide level2">
123 <h1>The L Word</h1>
124 <p class="fragment">Vancouver</p>
125 <p class="fragment">Lemming?</p>
126 <p class="fragment">Lemming Peak</p>
127 </section>
128
129 <section class="slide level2">
130 <h1>The Marketing Community was not thrilled</h1>
131 </section>
132
133 <section class="slide level2">
134 <h1>Lemmings commit mass suicide by following each other off cliffs</h1>
135 </section>
136
137 <section class="slide level2">
138 <h1>Except they don't</h1>
139 </section>
140
141 <section class="slide level2">
142 <h1>White Wilderness</h1>
143 <p>1958 Disney Documentary</p>
144 <p>Staged footage</p>
145 <p class="fragment">Camera crew forced them off the cliff</p>
146 <p class="fragment">Won an Oscar, of course</p>
147 </section>
148
149 <section class="slide level2">
150 <h1>Definition of Irony</h1>
151 <p>The actual meaning is the opposite of the literal meaning</p>
152 </section>
153
154 <section class="slide level2">
155 <h1>Recursive Definition of Irony</h1>
156 <p>The lemmings metaphor only works because people are lemmings in their adherence to the myth that lemmings are like lemmings.</p>
157 </section>
158
159 <section class="slide level2">
160 <h1>This could never happen to us, right?</h1>
161 <p class="fragment">MySQL doesn't have transactions</p>
162 <p class="fragment">MongoDB is Web Scale</p>
163 <p class="fragment">PHP is insecure</p>
164 <p class="fragment">Frequent password rotation is secure</p>
165 <p class="fragment">sysvinit needs to be replaced</p>
166 </section>
167
168 <section class="slide level2">
169 <h1>Results</h1>
170 <p>We didn't pick Lemming - we picked Liberty</p>
171 <p class="fragment">Liberty is a town in Saskatchewan</p>
172 </section>
173
174 <section class="slide level2">
175 <h1>Four Freedoms</h1>
176 <p>0 - to run the program as you wish, for any purpose</p>
177 <p>1 - to study how the program works, and change it so it does your computing as you wish</p>
178 <p>2 - to redistribute copies so you can help your neighbor</p>
179 <p>3 - to distribute copies of your modified version to others</p>
180 </section>
181
182 <section class="slide level2">
183 <h1> GPL is anti-business </h1>
184 </section>
185
186 <section class="slide level2">
187 <h1>Except it isn't</h1>
188 </section>
189
190 <section class="slide level2">
191 <h1>Definition of Eating Crow</h1>
192 <p>humiliation by admitting wrongness or having been proven wrong after taking a strong position</p>
193 </section>
194
195 <section class="slide level2">
196 <h1>Enjoyable Definition of Eating Crow</h1>
197 <p>Microsoft purchases Revolution Analytics</p>
198 <p>R language is GPL</p>
199 </section>
200
201 <section class="slide level2">
202 <h1>Sun/MySQL</h1>
203 <p>Sun bought MySQL for $1 Billion</p>
204 <p>Oracle bought Sun</p>
205 <p>Oracle now develops and ships MySQL under the GPL</p>
206 </section>
207
208 <section class="slide level2">
209 <h1>Linux</h1>
210 <p class="fragment">anybody here heard of it?</p>
211 </section>
212
213 <section class="slide level2">
214 <h1>Android is the market leading Mobile OS</p>
215 </section>
216
217 <section class="slide level2">
218 <h1>Linux runs:</h1>
219 <p>Google</p>
220 <p>Facebook</p>
221 <p>Twitter</p>
222 <p class="fragment">They run MySQL too</p>
223 </section>
224
225 <section class="slide level2">
226 <h1>Linux is not just for big companies - it's startup friendly too!</h1>
227 </section>
228
229 <section class="slide level2">
230 <img src="/images/hp-logo.png" />
231 </section>
232
233 <section class="slide level2">
234 <h1>HP ships a Linux server every minute</h1>
235 <p class="fragment">business unit that does is a $28B business</p>
236 </section>
237
238 <section class="slide level2">
239 <h1>Why is Free Software Important?</h1>
240 </section>
241
242 <section class="slide level2">
243 <p>1984 - Apple's 1984 Super Bowl Commercial</p>
244 <p class="fragment">1985 - Apple's Lemmings Super Bowl Commercial</p>
245 <p class="fragment">1997 - Apple's Think Different Campaign</p>
246 </section>
247
248 <section class="slide level2">
249 <p>Don't be a lemming</p>
250 </section>
251
252 <section class="slide level2">
253 <h1>Everybody in this room is wearing a uniform and don't kid yourself</h1>
254 <p>Frank Zappa</p>
255 </section>
256
257 <section class="slide level2">
258 <h1>"Think Different" isn't about allowing for individualism, it's about defining an alternate tribe</h1>
259 <p class="fragment">And don't kid yourself, it's about selling product</p>
260 </section>
261
262 <section class="slide level2">
263 <h1>What if you're this poor fellow?</h1>
264 <img src="/images/worstcat-lettuce.jpg" />
265 <p class="fragment">http://worstcats.tumblr.com</p>
266 </section>
267
268 <section class="slide level2">
269 <p>How much of your life is computerized?</p>
270 <p>How many of the four freedoms do you have with each of those things?</p>
271 </section>
272
273 <section class="slide level2">
274 <h1>superfish</p>
275 <p class="fragment">My laptop did not come with any software pre-installed that is designed to "improve my shopping experience"</p>
276 <p class="fragment">If it had, I am empowered to remove it</p>
277 </section>
278
279 <section class="slide level2">
280 <p>Why are we here? I think many people assume, wrongly, that a company exists solely to make money. Money is an important part of a company's existence, if the company is any good. But a result is not a cause. We have to go deeper and find the real reason for our being.</p>
281 <p>David Packard</p>
282 </section>
283
284 <section class="slide level2">
285 <h1>Free Software is a way that I can make the world a better place</h1>
286 </section>
287
288 <section class="slide level2">
289 <h1>Free Software is a way to reconnect with our humanity in a sea of white privilege</h1>
290 </section>
291
292 <section class="slide level2">
293 <h1>Free Software drives an unprecedented amount of innovation</h1>
294 </section>
295
296 <section class="slide level2">
297 <h1>Believe you can change the world</h1>
298 <p>David Packard</p>
299 </section>
300
301 <section>
302 <h1> Thank you! </h1>
303 <h4> <a href='http://inaugust.com/talks/lemmings.html'>http://inaugust.com/talks/lemmings.html</a> </h4>
304 <h3> twitter: @e_monty </h3>
305 </section>
306
307 </div>
308 <div class="footer">
309 <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">
310 <img alt="Creative Commons License"
311 style="border-width:0"
312 src="https://i.creativecommons.org/l/by/4.0/88x31.png" />
313 </a><br />
314 Licensed under a
315 <a rel="license"
316 href="http://creativecommons.org/licenses/by/4.0/">
317 Creative Commons Attribution 4.0 International License
318 </a>.
319 <br />
320 Source code available at <a href='http://git.inaugust.com/cgit/inaugust.com'>http://git.inaugust.com/cgit/inaugust.com</a>
321 </div>
322
323 </div>
324
325 <script src="/lib/js/head.min.js"></script>
326 <script src="/js/reveal.js"></script>
327
328 <script src="/js/this.js"></script>
329
330</body>
331</html>
diff --git a/src/talks/now-what/index.html b/src/talks/now-what/index.html
new file mode 100644
index 0000000..ca21fa8
--- /dev/null
+++ b/src/talks/now-what/index.html
@@ -0,0 +1,436 @@
1<!doctype html>
2<html lang="en">
3
4 <head>
5 <meta charset="utf-8">
6
7 <title>OpenStack works ... so now what?</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="reveal"><div class="slides">
35
36 <section data-state="cover">
37
38 <h1><span xmlns:dct="http://purl.org/dc/terms/"
39 href="http://purl.org/dc/dcmitype/InteractiveResource"
40 property="dct:title"
41 rel="dct:type">
42 OpenStack works ... so now what?
43 </span></h1>
44 <h3 xmlns:cc="http://creativecommons.org/ns#"
45 property="cc:attributionName">Monty Taylor</h3>
46 <h4><a xmlns:cc="http://creativecommons.org/ns#"
47 rel="cc:attributionURL"
48 href='http://inaugust.com/talks/now-what.html'>http://inaugust.com/talks/now-what.html</a> </h4>
49 <h3> twitter: @e_monty </h3>
50 </section>
51
52 <section id="who-am-i-hp" class="slide level2">
53 <h1>Who am I?</h1>
54 <img style="float:right; margin-right:24pt" src="/images/hp-logo.png"/>
55 <p> Distinguished Technologist </p>
56 <p> HP Cloud </p>
57 </section>
58
59 <section id="who-am-i-openstack" class="slide level2">
60 <h1>Who am I?</h1>
61 <img style="float:right; margin-right:24pt" src="/images/openstack-cloud-software-vertical-large.png" />
62 <p>Technical Committee</p>
63 <p>Foundation Board of Directors</p>
64 <p>Developer Infrastructure Core Team</p>
65 </section>
66
67 <section id="what-are-we-going-to-talk-about" class="slide level2">
68 <h1>What are we going to talk about?</h1>
69 <ul>
70 <li>OpenStack</li>
71 <li>My application</li>
72 <li>Your applications</li>
73 </ul>
74 </section>
75
76 <section class="slide level2">
77 <img src="/images/openstack-software-diagram.png"
78 alt="OpenStack" />
79 </section>
80
81 <section class="slide level2">
82 <p>As an application developer,<br />
83 I want to deploy and run an application on the internet<br />
84 so that my customers all over the world can consume it.</p>
85 </section>
86
87 <section class="slide level2">
88 <p>As an application developer,<br />
89 I want to deploy the application across multiple clouds<br />
90 so that my service survives issues in any one of them.</p>
91 </section>
92 <section class="slide level2">
93 <h1>THIS WORKS</h1>
94 <h3>I'm doing it myself as we speak</h3>
95 <img style="float:right; margin-right:24pt" src="/images/graphite.openstack.org.png"/>
96
97
98 <p class='fragment'>10-20k VMs per-day</p>
99 <p class='fragment'>3 (soon to be 6) clouds</p>
100 <p class='fragment'>Only using OpenStack APIs</p>
101
102 </section>
103
104 <section id="openstack-infra" data-transition='zoom'>
105 <h1>OpenStack Infra</h1>
106 </section>
107
108 <section id="tooling-automation-and-ci-for-openstack-project" class="slide level2" data-transition='zoom'>
109 <h1>Tooling, Automation and CI for OpenStack Project</h1>
110 </section>
111
112 <section id="developers" class="slide level2" data-transition='zoom'>
113 <h1>2000 Developers</h1>
114 </section>
115
116 <section id="gated-commits" class="slide level2" data-transition='zoom'>
117 <h1>Gated Commits</h1>
118 <p>Every commit is fully integration tested (twice) before landing</p>
119 </section>
120
121 <section id="each-test-runs-on-a-single-use-cloud-slave" class="slide level2" data-transition='zoom'>
122 <h1>Each Test Runs on a Single Use Cloud Slave</h1>
123 <p>This is that "cloud scale out" part</p>
124 </section>
125
126 <section id="million-test-jobs-in-the-last-6-months" class="slide level2" data-transition='zoom'>
127 <h1>1.7 Million Test Jobs in the last 6 Months</h1>
128 </section>
129
130 <section id="million-tests-in-a-month" class="slide level2" data-transition='zoom'>
131 <h1>15 Million Tests in a month</h1>
132 </section>
133
134 <section id="terabytes-of-log-data-in-six-months" class="slide level2" data-transition='zoom'>
135 <h1>18 Terabytes of Log Data in six months</h1>
136 </section>
137
138 <section id="we-have-no-servers" class="slide level2" data-transition='zoom'>
139 <h1>We have no servers</h1>
140 <p>It all runs across HP and Rackspace Public Clouds.</p>
141 </section>
142
143 <section id="architecture" class="slide level2">
144 <h1>Architecture</h1>
145 <p><img src="/images/infra_architecture.jpg" alt="image" /></p>
146 </section>
147
148 <section class="slide level2">
149 <h1>Gerrit</h1>
150 <ul>
151 <li class="fragment">
152 Traditional 'Enterprise' Java Application</li>
153 <li class="fragment">Single Nova VM, Cinder Volume</li>
154 <li class="fragment">Scale out farm of git replicas</li>
155 </ul>
156 </section>
157
158 <section class="slide level2">
159 <img src="/images/gerrit-graph.png" />
160 </section>
161
162 <section class="slide level2">
163 <h1>Fun Numbers</h1>
164 <ul>
165 <li>2500 changes every week</li>
166 <li>15000 change <em>revisions</em> every week</li>
167 <li>10,000 new changes every 42 days</li>
168 </ul>
169 </section>
170
171 <section class="slide level2">
172 <img src="/images/what-happens.png" />
173 </section>
174
175 <section class="slide level2">
176 <h1>nodepool</h1>
177 <ul>
178 <li class="fragment">Cloud Native</li>
179 <li class="fragment">
180 Purpose built in Python</li>
181 <li class="fragment">Keeps a pool of ready to go nodes</li>
182 <li class="fragment">Multi-cloud</li>
183 <li class="fragment">Fully elastic - responds to demand</li>
184 </ul>
185 </section>
186
187 <section class="slide level2">
188 <img style="float:left; margin-left:24pt; width:35%;" src="/images/gerrit-graph.png" />
189 <img style="float:right; margin-right:24pt; width: 50%;" src="/images/nodepool-graph.png" />
190 </section>
191
192 <section class="slide level2">
193 <h1>OpenStack Works!</h1>
194 <p class='fragment'>What next?</p>
195 <p class='fragment'>Make it easier</p>
196 </section>
197
198 <section class="slide level2">
199 <h1>Basic things you want to do</h1>
200
201 <p class='fragment'>Get (make/fetch/find) a base image</p>
202 <p class='fragment'>Upload it to each cloud</p>
203 <p class='fragment'>Boot a VM on one or more of the clouds</p>
204 <p class='fragment'>Ensure it's on the Internet</p>
205 </section>
206
207 <section class="slide level2">
208 <h1>We've made this harder than it should be</h1>
209 </section>
210
211 <section class="slide level2">
212 <h1>Get a base image</h1>
213 <p class='fragment'>OpenStack diskimage-builder</p>
214 <p class='fragment'>packer</p>
215 <p class='fragment'>Download pre-built image from Ubuntu/RedHat/SuSE</p>
216 </section>
217
218 <section class="slide level2">
219 <h1>Problem: hypervisor image file format</h1>
220 <ul>
221 <li class='fragment'>
222 Rackspace uses VHD
223 </li>
224 <li class='fragment'>
225 HP uses qcow2
226 </li>
227 <li class='fragment'>
228 DreamHost uses RAW
229 </li>
230 </ul>
231 </section>
232
233 <section class="slide level2">
234 <h1>Problem: image API version</h1>
235 <ul>
236 <li class='fragment'>
237 HP uses v1
238 </li>
239 <li class='fragment'>
240 vexxhost uses v2
241 </li>
242 </ul>
243 <p class="fragment">Good news! We made a plan for this at
244 the summit</p>
245 </section>
246
247 <section class="slide level2">
248 <h1>Problem: image task vs. PUT</h1>
249 <pre>
250swift upload --object-name local-image-filename images image-name
251glance task-create
252 --type=import
253 --input='{"import_from": "images/image-name",
254 "image_properties" : {"name": "My Image Name"}}'
255 </pre>
256 <pre>
257glance image-create --name=image-name --file=local-image-filename
258 </pre>
259 </section>
260
261 <section class="slide level2">
262 <h1>Problem: Ensure it's on the Internet</h1>
263 <ul>
264 <li class='fragment'>Cloud has externally routable IP from neutron (RunAbove, OVH)</li>
265 <li class='fragment'>Cloud has externally routable IP neutron AND supports optional private tenant networks (vexxhost)</li>
266 <li class='fragment'>Cloud has private tenant network provided by neutron and requires floating IP (HP, Dreamhost)</li>
267 <li class='fragment'>Cloud only has private tenant network provided by nova-network and requires floating-ip for external routing (auro)</li>
268 <li class='fragment'>Cloud has externally routable IP from neutron but no neutron APIs (Rackspace)</li>
269 </ul>
270 </section>
271
272 <section class="slide level2">
273 <h1>Maybe in code ...</h1>
274 <pre>
275def get_server_external_ipv4(cloud, server):
276 if cloud.has_service('network'):
277 try:
278 server_ports = cloud.search_ports(
279 filters={'device_id': server.id})
280 ext_nets = cloud.search_networks(filters={'router:external': True})
281 except NeutronClientException as e:
282 pass # fall through
283 else:
284 for net in ext_nets:
285 for port in server_ports:
286 if net['id'] == port['network_id']:
287 for ip in port['fixed_ips']:
288 if _utils.is_ipv4(ip['ip_address']):
289 return ip['ip_address']
290 ext_ip = get_server_ip(server, key_name='public')
291 if ext_ip is not None:
292 return ext_ip
293 for interfaces in server.addresses.values():
294 for interface in interfaces:
295 if _utils.is_ipv4(interface['addr']) and \
296 _utils.is_globally_routable_ipv4(interface['addr']):
297 return interface['addr']
298 return None
299 </pre>
300 </section>
301
302 <section class="slide level2">
303 <h1>I think we can do better than that</h1>
304 </section>
305
306 <section class="slide level2">
307 <h1>What am I doing about it?</h1>
308 </section>
309
310 <section class="slide level2">
311 <h1>os-client-config</h1>
312 <h3>http://git.openstack.org/cgit/openstack/os-client-config</h3>
313 <p>A library to handle config information for openstack clients</p>
314 <p>Tracks differences in vendors that can't be discovered</p>
315 <p>In use in python-openstackclient and ansible</p>
316 </section>
317
318 <section class="slide level2">
319 <h1>os-client-config</h1>
320 <p>~/.config/openstack/clouds.yaml</p>
321 <pre>
322clouds:
323 hp-mordred:
324 profile: hp
325 auth:
326 username: mordred@inaugust.com
327 password: XXXXXXXXXXXXX
328 project_name: mordred@inaugust.com
329 region_name: region-b.geo-1
330 dreamhost:
331 profile: dreamhost
332 auth:
333 username: montay6
334 project_name: dhc2111978
335 password: XXXXXXXXXXXXX
336 region_name: RegionOne
337 </pre>
338 </section>
339
340 <section class="slide level2">
341 <h1>shade</h1>
342 <h3>http://git.openstack.org/cgit/openstack-infra/shade</h3>
343 <p>A library to wrap business logic around client libraries</p>
344 <pre>
345cloud.create_image('image-name', filename='image-filename.qcow2')
346cloud.create_server('my-server', image='immage-name', auto_ip=True)
347 </pre>
348 <p>In use in Infra Nodepool and ansible</p>
349 </section>
350
351 <section class="slide level2">
352 <h1>ansible</h1>
353 <p>Brand new modules, based on shade</p>
354 <p>Coming in 2.0 release</p>
355 <pre>
356- os_keypair:
357 cloud: hp-mordred
358 name: mordred
359 public_key_file: ~/.ssh/id_rsa.pub
360- os_image:
361 cloud: hp-mordred
362 name: Monty Ubuntu
363 file: ubuntu.vhd
364- os_server:
365 cloud: hp-mordred
366 name: my-server
367 flavor_ram: 1024
368 image: Monty Ubuntu
369 </pre>
370 </section>
371
372 <section class="slide level2">
373 <h1>ansible</h1>
374 <p>multi-cloud support</p>
375 <pre>
376- os_keypair:
377 cloud: "{{ item }"
378 name: mordred
379 public_key_file: ~/.ssh/id_rsa.pub
380 with-items:
381 - vexxhost
382 - rackspace
383 - mordred-hp
384 - ovh
385 </pre>
386 </section>
387
388 <section class="slide level2">
389 <h1>What should we do about it?</h1>
390 <ul>
391 <li>
392 Get back to basics
393 </li><li>
394 shade existence is a bug
395 </li><li>
396 Make some decisions about divergences in the basic levels
397 </li><li>
398 Take a stand even if one of our product managers disagrees
399 </li><li>
400 Ensure that simple things are simple
401 </li>
402 </ul>
403 </section>
404
405
406 <section>
407 <h1> Thank you! </h1>
408 <h4> <a href='http://inaugust.com/talks/now-what.html'>http://inaugust.com/talks/now-what.html</a> </h4>
409 <h3> twitter: @e_monty </h3>
410 </section>
411
412 </div>
413 <div class="footer">
414 <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">
415 <img alt="Creative Commons License"
416 style="border-width:0"
417 src="https://i.creativecommons.org/l/by/4.0/88x31.png" />
418 </a><br />
419 Licensed under a
420 <a rel="license"
421 href="http://creativecommons.org/licenses/by/4.0/">
422 Creative Commons Attribution 4.0 International License
423 </a>.
424 <br />
425 Source code available at <a href='http://git.inaugust.com/cgit/inaugust.com'>http://git.inaugust.com/cgit/inaugust.com</a>
426 </div>
427
428 </div>
429
430 <script src="/lib/js/head.min.js"></script>
431 <script src="/js/reveal.js"></script>
432
433 <script src="/js/this.js"></script>
434
435 </body>
436</html>
diff --git a/src/talks/os-client-config/index.html b/src/talks/os-client-config/index.html
new file mode 100644
index 0000000..04ef2fd
--- /dev/null
+++ b/src/talks/os-client-config/index.html
@@ -0,0 +1,242 @@
1<!doctype html>
2<html lang="en">
3
4 <head>
5 <meta charset="utf-8">
6
7 <title>os-client-config: Making OpenStack usability easier, starting with client configuration</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"></div>
35
36 <div class="reveal">
37 <div class="slides">
38
39 <section data-state="cover">
40 <h1><span xmlns:dct="http://purl.org/dc/terms/"
41 href="http://purl.org/dc/dcmitype/InteractiveResource"
42 property="dct:title"
43 rel="dct:type">
44 os-client-config
45 </span></h1>
46 <h3 xmlns:cc="http://creativecommons.org/ns#"
47 property="cc:attributionName">Monty Taylor</h3>
48 <h4><a xmlns:cc="http://creativecommons.org/ns#"
49 rel="cc:attributionURL"
50 href='http://inaugust.com/talks/os-client-config.html'>http://inaugust.com/talks/os-client-config.html</a> </h4>
51 <h3> twitter: @e_monty </h3>
52 </section>
53
54 <section>
55 <h1>I'm awash in cloud accounts</h1>
56 <ul>
57 <li>Infra has 5<ul>
58 <li>control plane and nodepool in 3 Rackspace regions</li>
59 <li>control plane and nodepool in HP</li>
60 </ul></li>
61 <li>two personal on HP and one on Rackspace</li>
62 <li>two internal HP accounts</li>
63 <li>That's 12 OpenStack cloud-regions</li>
64 </ul>
65 </section>
66
67 <section>
68 How do I connect to them?
69 </section>
70
71 <section>
72 List Servers
73 <pre>
74openstack \
75 --auth-url=https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0 \
76 --username=mordred@inaugust.com \
77 --password=XXXXXX \
78 --project-name=mordred@inaugust.com \
79 --region-name=region-b.geo-1 \
80 server list
81 </pre>
82 </section>
83
84 <section>
85 Well that's silly
86 </section>
87
88 <section>
89 Consistent Environment Variables
90 <pre>
91export OS_AUTH_URL=https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0
92export OS_USERNAME=mordred@inaugust.com
93export OS_PASSWORD=XXXXXXXXXXXXX
94export OS_TENANT_NAME=mordred@inaugust.com
95export OS_REGION_NAME=region-b.geo-1
96 </pre>
97 </section>
98
99 <section>
100 12 shell script snippet files
101 </section>
102
103 <section>
104 ENV processing is in command line tools, not client libraries
105 </section>
106
107 <section>
108 ENV processing is just copied everywhere
109 <pre>
110$ egrep -r 'add_(option|argument).*os-username' openstack/python*client | wc -l
11113
112 </pre>
113 </section>
114
115 <section>
116 <h1> Pre-existing knowledge </h1>
117 <ul>
118 <li>auth-url</li>
119 <li>glance API version</li>
120 <li>override settings<ul>
121 <li>URLs (swift URL in rackspace keystone catalog is wrong)</li>
122 <li>service types (DNS in HP is hpext:dns)</li>
123 </ul></li>
124 </ul>
125 </section>
126
127 <section>
128 <p>I wrote a library (yay!)</p>
129 <h1>os-client-config</h1>
130 </section>
131
132 <section>
133 <h1>Processes, in this order</h1>
134 <ul>
135 <li>config file: clouds.yaml</li>
136 <li>env vars</li>
137 <li>command line args</li>
138 </ul>
139 </section>
140
141 <section>
142 <h1>Provides vendor defaults</h1>
143 <pre>
144CLOUD_DEFAULTS = dict(
145 hp=dict(
146 auth_url='https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0',
147 dns_service_type='hpext:dns',
148 ),
149 rackspace=dict(
150 auth_url='https://identity.api.rackspacecloud.com/v2.0/',
151 database_service_type='rax:database',
152 image_api_version='2',
153 )
154)
155 </pre>
156 <p> Patches welcome for any cloud </p>
157 </section>
158
159 <section>
160 <h1>clouds.yaml</h1>
161 <pre>
162clouds:
163 mordred:
164 cloud: hp
165 username: mordred@inaugust.com
166 password: XXXXXXXXXX
167 project_name: mordred@inaugust.com
168 region_name: region-b.geo-1
169 monty:
170 cloud: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0
171 username: monty.taylor@hp.com
172 password: XXXXXXXXX
173 project_name: monty.taylor@hp.com-default-tenant
174 region_name: region-b.geo-1
175 dns_service_type: hpext:dns
176 rax:
177 cloud: rackspace
178 username: openstackci
179 password: XXXXXXX
180 project_id: 610275
181 region_name: DFW,ORD,IAD
182 </pre>
183 </section>
184
185 <section>
186 <h1> Allows for named clouds </h1>
187 <pre>
188openstack --cloud=mordred server list
189 </pre>
190 <pre>
191export OS_CLOUD=mordred
192openstack server list
193 </pre>
194 </section>
195
196
197 <section>
198 <h1> Where is it in use? </h1>
199 <ul>
200 <li>Shade library</li>
201 <li>python-openstackclient <small>(patch in flight)</small></li>
202 <li>ansible <small>(patch in flight)</small></li>
203 </ul>
204 </section>
205
206 <section>
207 <h1>Where is it?</h1>
208 <p>http://git.openstack.org/stackforge/os-client-config</p>
209 <p>http://pypi.python.org/pypi/os-client-config</p>
210 </section>
211
212 <section>
213 <h1>Where is it?</h1>
214 <p>http://git.openstack.org/stackforge/os-client-config</p>
215 <p>http://pypi.python.org/pypi/os-client-config</p>
216 </section>
217
218 </div>
219
220 <div class="footer">
221 <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">
222 <img alt="Creative Commons License"
223 style="border-width:0"
224 src="https://i.creativecommons.org/l/by/4.0/88x31.png" />
225 </a><br />
226 Licensed under a
227 <a rel="license"
228 href="http://creativecommons.org/licenses/by/4.0/">
229 Creative Commons Attribution 4.0 International License
230 </a>.
231 <br />
232 Source code available at <a href='http://git.inaugust.com/cgit/inaugust.com'>http://git.inaugust.com/cgit/inaugust.com</a>
233 </div>
234 </div>
235
236 <script src="/lib/js/head.min.js"></script>
237 <script src="/js/reveal.js"></script>
238
239 <script src="/js/this.js"></script>
240
241</body>
242</html>
diff --git a/src/talks/product-management/index.html b/src/talks/product-management/index.html
new file mode 100644
index 0000000..58f8bd4
--- /dev/null
+++ b/src/talks/product-management/index.html
@@ -0,0 +1,454 @@
1<!doctype html>
2<html lang="en">
3
4 <head>
5 <meta charset="utf-8">
6
7 <title>Liberty, Product Management and OpenStack Technology</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="reveal"><div class="slides">
35
36 <section data-state="cover">
37
38 <h1><span xmlns:dct="http://purl.org/dc/terms/"
39 href="http://purl.org/dc/dcmitype/InteractiveResource"
40 property="dct:title"
41 rel="dct:type">
42 Liberty, Product Management and OpenStack Technology
43 </span></h1>
44 <h3 xmlns:cc="http://creativecommons.org/ns#"
45 property="cc:attributionName">Monty Taylor</h3>
46 <h4><a xmlns:cc="http://creativecommons.org/ns#"
47 rel="cc:attributionURL"
48 href='http://inaugust.com/talks/product-management.html'>http://inaugust.com/talks/product-management.html</a> </h4>
49 <h3> twitter: @e_monty </h3>
50 </section>
51
52 <section class="slide level2">
53 <img src="/images/openstack-cloud-software-vertical-large.png"
54 alt="OpenStack" />
55 </section>
56
57 <section class="slide level2">
58 <h1>Mission</h1>
59 <p>
60 to produce the ubiquitous Open Source Cloud Computing platform that will meet the needs of public and private clouds regardless of size, by being simple to implement and massively scalable.
61 </p>
62 </section>
63
64 <section class="slide level2">
65 <h1>Borrowed from Ubuntu</h1>
66 <p>Time Based Releases</p>
67 <p>Design summits each cycle</p>
68 <p>Release codenames in alphabetical order</p>
69 </section>
70
71 <section class="slide level2">
72 <h1>Different from Ubuntu</h1>
73 <p>No BDFL</p>
74 <p>All decisions are democratic</p>
75 </section>
76
77 <section class="slide level2">
78 <img src="/images/openstack-size.jpg" />
79 </section>
80
81 <section class="slide level2">
82 <h1>"OpenStack needs product management"</h1>
83 </section>
84
85 <section class="slide level2">
86 <p>Developers work on whatever they feel like, so there is no cohesion</p>
87 <p class='fragment'><small>not quite</small></p>
88 </section>
89
90 <section class="slide level2">
91 <img src="/images/openstack-size.jpg" />
92 </section>
93
94 <section class="slide level2">
95 <h1>OpenStack needs product management <em>coordination</em></h1>
96 </section>
97
98 <section class="slide level2">
99 <h1> Product Management Working Group </h1>
100 <p>Today 2:00pm - 3:30pm Room 212</p>
101 </section>
102
103 <section class="slide level2">
104 <h1>What can the working group do?</h1>
105 <ul>
106 <li class='fragment'>
107 Define problems
108 </li>
109 <li class='fragment'>
110 Coordinate prorities
111 </li>
112 <li class='fragment'>
113 Communicate problems clearly to tech community
114 </li>
115 </section>
116
117 <section class="slide level2">
118 <h1>I've got 99 Problems ...</h1>
119 <img src="/images/worstcat-lettuce.jpg" />
120 </section>
121
122 <section class="slide level2">
123 <p>As an application developer,<br />
124 I want to deploy and run an application on the internet<br />
125 so that my customers all over the world can consume it.</p>
126 </section>
127
128 <section class="slide level2">
129 <p>As an application developer,<br />
130 I want to deploy the application across multiple clouds<br />
131 so that my service survives issues in any one of them.</p>
132 </section>
133
134 <section class="slide level2">
135 <h1>THIS WORKS</h1>
136 <h3>I'm doing it myself as we speak</h3>
137 <img style="float:right; margin-right:24pt" src="/images/graphite.openstack.org.png"/>
138
139
140 <p class='fragment'>10-20k VMs per-day</p>
141 <p class='fragment'>3 (soon to be 6) clouds</p>
142 <p class='fragment'>Only using OpenStack APIs</p>
143
144 </section>
145
146 <section class="slide level2">
147 <h1>To do this, there are some basic steps</h1>
148
149 <p class='fragment'>Get (make/fetch/find) a base image</p>
150 <p class='fragment'>Upload it to each cloud</p>
151 <p class='fragment'>Boot a VM on one or more of the clouds</p>
152 <p class='fragment'>Ensure it's on the Internet</p>
153
154 </section>
155
156 <section class="slide level2">
157 <h1>Get a base image</h1>
158 <p class='fragment'>OpenStack diskimage-builder</p>
159 <p class='fragment'>packer</p>
160 <p class='fragment'>Download pre-built image from Ubuntu/Fedora</p>
161 </section>
162
163 <section class="slide level2">
164 <h1>NO</h1>
165 <img src="/images/worstcat-lettuce.jpg" />
166 </section>
167
168 <section class="slide level2">
169 <h1>Problem: hypervisor image file format</h1>
170 <ul>
171 <li class='fragment'>
172 Rackspace uses VHD
173 </li>
174 <li class='fragment'>
175 HP uses qcow2
176 </li>
177 <li class='fragment'>
178 DreamHost uses RAW
179 </li>
180 </ul>
181 </section>
182
183 <section class="slide level2">
184 <h1>Upload it to each cloud</h1>
185 <pre>glance image-create</pre>
186 </section>
187
188 <section class="slide level2">
189 <h1>NO</h1>
190 <img src="/images/worstcat-lettuce.jpg" />
191 </section>
192
193 <section class="slide level2">
194 <h1>Problem: image API version</h1>
195 <ul>
196 <li class='fragment'>
197 HP uses v1
198 </li>
199 <li class='fragment'>
200 vexxhost uses v2
201 </li>
202 </ul>
203 </section>
204
205 <section class="slide level2">
206 <h1>Problem: List API versions</h1>
207 <p>Root of the Image API lists versions</p>
208 <p>keystone catalog only lists a versioned endpoint</p>
209 </section>
210
211 <section class="slide level2">
212 <h1>Problem: API version discovery</h1>
213 <p>Try one - if it doesn't work, try the other</p>
214 <p><em>maybe</em> look at the end of the API endpoint for v1 or v2</p>
215 </section>
216
217 <section class="slide level2">
218 <h1>Upload it to each cloud</h1>
219 <pre>glance image-create filename</pre>
220 </section>
221
222 <section class="slide level2">
223 <h1>NO</h1>
224 <img src="/images/worstcat-lettuce.jpg" />
225 </section>
226
227 <section class="slide level2">
228 <h1>Problem: image task vs. PUT</h1>
229 <pre>
230swift upload --object-name local-image-filename images image-name
231glance task-create
232 --type=import
233 --input='{"import_from": "images/image-name",
234 "image_properties" : {"name": "My Image Name"}}'
235 </pre>
236 <pre>
237glance image-create --name=image-name --file=local-image-filename
238 </pre>
239 </section>
240
241 <section class="slide level2">
242 <h1>Boot a VM on one or more of the clouds</h1>
243 <pre>nova boot --image=image-name --flavor=something
244 </pre>
245 </section>
246
247 <section class="slide level2">
248 <h1>NO</h1>
249 <img src="/images/worstcat-lettuce.jpg" />
250 </section>
251
252 <section class="slide level2">
253 <h1>Problem: the image needs to get on the network</h1>
254 <ul>
255 <li class='fragment'>DHCP</li>
256 <li class='fragment'>Static Network Config in Config Drive</li>
257 <li class='fragment'>Vendor-specific agent doing file injection</li>
258 </ul>
259 </section>
260
261 <section class="slide level2">
262 <h1>
263 <pre>nova boot --image=image-name --flavor=something
264 </pre>
265 </section>
266
267 <section class="slide level2">
268 <h1>NO</h1>
269 <img src="/images/worstcat-lettuce.jpg" />
270 </section>
271
272 <section class="slide level2">
273 <h1>Problem: Ensure it's on the Internet</h1>
274 <ul>
275 <li class='fragment'>My VM may have a public IP</li>
276 <li class='fragment'>My VM may need a floating IP from nova</li>
277 <li class='fragment'>My VM may need a floating IP from neutron</li>
278 </ul>
279 </section>
280
281 <section class="slide level2">
282 <h1>VM Network with nova-network</h1>
283 <pre>
284 addresses:
285 private:
286 - addr: 10.181.5.77
287 version: 4
288 public:
289 - addr: 2001:4800:7810:512:be76:4eff:fe05:8325
290 version: 6
291 - addr: 98.129.169.30
292 version: 4
293 </pre>
294 </section>
295
296 <section class="slide level2">
297 <h1>VM Network with nova-network</h1>
298 <pre>
299 addresses:
300 mordred@inaugust.com-network:
301 - OS-EXT-IPS-MAC:mac_addr: fa:16:3e:a6:de:26
302 OS-EXT-IPS:type: fixed
303 addr: 10.0.0.6
304 version: 4
305 - OS-EXT-IPS-MAC:mac_addr: fa:16:3e:a6:de:26
306 OS-EXT-IPS:type: floating
307 addr: 15.126.239.219
308 version: 4
309 </pre>
310 </section>
311
312 <section class="slide level2">
313 <h1>Boot a VM on one or more of the clouds</h1>
314 <pre>
315nova boot --image=image-name --flavor=something --name=my-server
316nova floating-ip-create
317nova floating-ip-associate my-server {{ value_from_create }}
318 </pre>
319 </section>
320
321 <section class="slide level2">
322 <h1>NO</h1>
323 <img src="/images/worstcat-lettuce.jpg" />
324 </section>
325
326 <section class="slide level2">
327 <h1>Problem: My Internet server is behind a NAT</h1>
328 </section>
329
330 <section class="slide level2">
331 <h1>Problem: Security Groups<h1>
332 <p>I was trying to spin up a web server, but all my ports were blocked</p>
333 <p><small>I'll be using ansible and puppet on this machine, I can configure iptables thanks</small></p>
334 </section>
335
336 <section class="slide level2">
337 <h1>Boot a VM on one or more of the clouds</h1>
338 <pre>
339nova secgroup-add-rule default tcp 80 80 0.0.0.0/0
340nova boot --image=image-name --flavor=something --name=my-server
341nova floating-ip-create
342nova floating-ip-associate my-server {{ value_from_create }}
343 </pre>
344 </section>
345
346 <section class="slide level2">
347 <h1>Wow. So that's</h1>
348 <ul>
349 <li>
350 Image Format
351 </li><li>
352 Image API version
353 </li><li>
354 Image upload mechanism
355 </li><li>
356 Networking config / public private
357 </li><li>
358 Networking config nova/neutron
359 </li><li>
360 Floating IP?
361 </li><li>
362 Floating IP nova/neutron
363 </li><li>
364 DHCP or Static networking config
365 </li><li>
366 Security Group config
367 </li>
368 </ul>
369 </section>
370
371 <section class="slide level2">
372 <h1>I think we can do better than that</h1>
373 </section>
374
375 <section class="slide level2">
376 <h1>What am I doing about it?</h1>
377 </section>
378
379 <section class="slide level2">
380 <h1>os-client-config</h1>
381 <h3>http://git.openstack.org/cgit/openstack/os-client-config</h3>
382 <p>A library to handle config information for openstack clients</p>
383 <p>Tracks differences in vendors that can't be discovered</p>
384 <p>In use in python-openstackclient and ansible today</p>
385 </section>
386
387 <section class="slide level2">
388 <h1>shade</h1>
389 <h3>http://git.openstack.org/cgit/openstack-infra/shade</h3>
390 <p>A library to wrap business logic around client libraries</p>
391 <pre>
392cloud.create_server('my-server', auto_ip=True)
393 </pre>
394 <p>In use in Infra Nodepool and ansible today</p>
395 </section>
396
397 <section class="slide level2">
398 <h1>Raising Issues</h1>
399 <ul>
400 <li> Product Management Working Group (today, 2pm, room 212) </li>
401 <li> DefCore (Wednesday 10:30 - 12:30, East Building Room 2/3)</li>
402 <li> Direct interaction with the teams and PTLs </li>
403 </ul>
404 </section>
405
406 <section class="slide level2">
407 <h1>What should we do about it?</h1>
408 <ul>
409 <li>
410 Get back to basics
411 </li><li>
412 shade existence is a bug
413 </li><li>
414 Make some decisions about divergences in the basic levels
415 </li><li>
416 Take a stand even if one of our product managers disagrees
417 </li><li>
418 Ensure that simple things are simple
419 </li>
420 </ul>
421 </section>
422
423
424 <section>
425 <h1> Thank you! </h1>
426 <h4> <a href='http://inaugust.com/talks/product-management.html'>http://inaugust.com/talks/product-management.html</a> </h4>
427 <h3> twitter: @e_monty </h3>
428 </section>
429
430 </div>
431 <div class="footer">
432 <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">
433 <img alt="Creative Commons License"
434 style="border-width:0"
435 src="https://i.creativecommons.org/l/by/4.0/88x31.png" />
436 </a><br />
437 Licensed under a
438 <a rel="license"
439 href="http://creativecommons.org/licenses/by/4.0/">
440 Creative Commons Attribution 4.0 International License
441 </a>.
442 <br />
443 Source code available at <a href='http://git.inaugust.com/cgit/inaugust.com'>http://git.inaugust.com/cgit/inaugust.com</a>
444 </div>
445
446 </div>
447
448 <script src="/lib/js/head.min.js"></script>
449 <script src="/js/reveal.js"></script>
450
451 <script src="/js/this.js"></script>
452
453 </body>
454</html>
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>