summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty Taylor <mordred@inaugust.com>2017-11-05 13:24:37 +1100
committerMonty Taylor <mordred@inaugust.com>2017-11-05 17:07:06 +1100
commit4ac60cf090af9618bd52b4b30cac4ee31b5d5967 (patch)
tree7dda33747456c3b806d25c4318bef9b717f8aa3e
parent2f5dfc495113c6dadf66fc7d5d395f90118514ca (diff)
Add ansible playbooks for 3 minute multi-cloud demo
-rw-r--r--src/three-minute-demo/Dockerfile11
-rw-r--r--src/three-minute-demo/README.rst80
-rwxr-xr-xsrc/three-minute-demo/ansible-playbook.sh11
-rwxr-xr-xsrc/three-minute-demo/build-docker-image.sh3
-rw-r--r--src/three-minute-demo/demo.yaml101
-rw-r--r--src/three-minute-demo/hosts1
-rw-r--r--src/three-minute-demo/prep.yaml6
-rw-r--r--src/three-minute-demo/roles/build-image/defaults/main.yaml3
-rw-r--r--src/three-minute-demo/roles/build-image/tasks/main.yaml19
-rw-r--r--src/three-minute-demo/roles/get-cloud-config/tasks/main.yaml6
-rw-r--r--src/three-minute-demo/roles/upload-image/defaults/main.yaml3
-rw-r--r--src/three-minute-demo/roles/upload-image/tasks/main.yaml25
-rw-r--r--src/three-minute-demo/templates/setup.json.j21
13 files changed, 270 insertions, 0 deletions
diff --git a/src/three-minute-demo/Dockerfile b/src/three-minute-demo/Dockerfile
new file mode 100644
index 0000000..823c94e
--- /dev/null
+++ b/src/three-minute-demo/Dockerfile
@@ -0,0 +1,11 @@
1FROM python
2
3RUN apt-get update && \
4 apt-get install -y qemu-utils libffi-dev libssl-dev sudo \
5 rpm yum-utils debootstrap && \
6 pip install ansible shade diskimage-builder
7VOLUME /demo
8WORKDIR /demo
9
10ENTRYPOINT ["ansible-playbook"]
11CMD ["demo.yaml"]
diff --git a/src/three-minute-demo/README.rst b/src/three-minute-demo/README.rst
new file mode 100644
index 0000000..1247ea1
--- /dev/null
+++ b/src/three-minute-demo/README.rst
@@ -0,0 +1,80 @@
13 Minute Demo of OpenStack Public Clouds
2========================================
3
4This is all the Ansible needed for the 3 minute public cloud demo.
5
6It uses docker containers to avoid the need to install things on the local
7computer. The Dockerfile uses the base ``python`` docker image regardless
8of other distro since it's just a container for installing ansible.
9
10.. note::
11
12 There is nothing docker-specific about the demo, it's just being used as
13 a convenient way to bundle actions without polluting the user's computer.
14 The playbooks themselves can be used directly for people who have the
15 pre-reqs of ansible, shade and diskimage-builder installed or who do not
16 mind installing them globally.
17
18Building Docker Image
19---------------------
20
21Step one is building the docker image:
22
23.. code-block:: bash
24
25 docker build -t three-minute-demo .
26
27A convenience script, ``build-docker-image.sh`` is provided that runs that
28command.
29
30Wrapper Script
31--------------
32
33Once the ``three-minute-demo`` image exists, the ``ansible-playbook.sh`` script
34will user it to run ``ansible-playbook``. By default it will run the
35``run.yaml`` playbook, but that can be overridden by passing parameters to the
36script.
37
38The ``ansible-playbook.sh`` script will also bind-mount the current directory
39as the main work dir and ``~/.config/openstack`` into ``/etc/openstack`` in the
40container so that ``clouds.yaml`` is available.
41
42.. note::
43
44 If ~/.config/openstack doesn't exist but /etc/openstack does,
45 ansible-playbook.sh will mount /etc/openstack instead. If a different setup
46 is desired, you can always run docker commands.
47
48Building and Uploading Images
49-----------------------------
50
51The demo depends on base images existing. The ``prep.yaml`` playbook will
52create the images and upload them to all of the cloud regions.
53
54.. code-block:: bash
55
56 ./ansible-playbook.sh prep.yaml
57
58By default it will create a minimal ubuntu image. That can be changed by
59setting ``distro`` on the ansible-playbook command line to something else, such
60as ``fedora`` or ``centos``.
61
62.. code-block:: bash
63
64 ./ansible-playbook.sh -edistro=fedora prep.yaml
65
66The Demo
67--------
68
69``ansible-playbook.sh`` defaults to running ``demo.yaml``, which will create a
70server in each cloud region, install Apache on that server, write out a json
71file for apache to serve, fetch the contents into a variable and print out the
72FQDN.
73
74If you're thinking "wow, that's not useful" - you're right! This isn't intended
75to be a demo of doing useful things with Ansible. It's intended to be a demo of
76getting servers on a set of cloud regions across multiple public clouds and
77then doing something with them.
78
79Once you can perform a single task on the remote server with Ansible, you can
80do anything with Ansible you want to do.
diff --git a/src/three-minute-demo/ansible-playbook.sh b/src/three-minute-demo/ansible-playbook.sh
new file mode 100755
index 0000000..87c3c18
--- /dev/null
+++ b/src/three-minute-demo/ansible-playbook.sh
@@ -0,0 +1,11 @@
1#!/bin/bash
2
3if [ -d ${HOME}/.config/openstack ] ; then
4 CONFIG_DIR=${HOME}/.config/openstack
5else
6 CONFIG_DIR=/etc/openstack
7fi
8
9exec docker run -it --rm --privileged \
10 -v${PWD}:/demo -v${CONFIG_DIR}:/etc/openstack \
11 three-minute-demo $*
diff --git a/src/three-minute-demo/build-docker-image.sh b/src/three-minute-demo/build-docker-image.sh
new file mode 100755
index 0000000..d229241
--- /dev/null
+++ b/src/three-minute-demo/build-docker-image.sh
@@ -0,0 +1,3 @@
1#!/bin/sh
2
3docker build -t three-minute-demo .
diff --git a/src/three-minute-demo/demo.yaml b/src/three-minute-demo/demo.yaml
new file mode 100644
index 0000000..985f265
--- /dev/null
+++ b/src/three-minute-demo/demo.yaml
@@ -0,0 +1,101 @@
1- hosts: localhost
2 gather_facts: false
3 tasks:
4
5 - name: Read in cloud config
6 os_client_config:
7
8 - name: Add fake host for each cloud region so we can parallelize
9 add_host:
10 name: "{{ item.name }}-{{ item.region_name }}"
11 ansible_host: localhost
12 ansible_connection: local
13 groups: clouds
14 cloud: "{{ item.name }}"
15 region_name: "{{ item.region_name }}"
16 with_items: "{{ openstack.clouds }}"
17
18- hosts: clouds
19 gather_facts: false
20 tasks:
21
22 - name: Upload ssh public key
23 os_keypair:
24 public_key_file: "{{ ansible_user_dir }}/.ssh/id_rsa.pub"
25 name: "three_minute_demo"
26 cloud: "{{ cloud }}"
27 region_name: "{{ region_name }}"
28
29 - name: Add wide-open security group
30 os_security_group:
31 name: three-minute-demo-group
32 description: Open security group
33
34 - name: Add rules to group
35 os_security_group_rules:
36 ethertype: "{{ item.ethertype }}"
37 remote_group: "{{ item.remote_group|default(omit) }}"
38 remote_ip_prefix: "{{ item.remote_ip_prefix|default(omit) }}"
39 security_group: three-minute-demo-group
40 with_items:
41 - ethertype: IPv4
42 remote_group: default
43 state: absent
44 - ethertype: IPv6
45 remote_group: default
46 state: absent
47 - ethertype: IPv4
48 remote_ip_prefix: 0.0.0.0/0
49 - ethertype: IPv6
50 remote_ip_prefix: ::/0
51
52 - name: Create a small VM
53 os_server:
54 auto_ip: true
55 key_name: three_minute_demo
56 name: three_minute_demo_server
57 cloud: "{{ cloud }}"
58 region_name: "{{ region_name }}"
59 wait: true
60 register: created_server
61
62 - name: Add VM to inventory
63 add_host:
64 name: "{{ cloud }}.{{ region_name }}.demo"
65 ansible_host: "{{ created_server.interface_ip }}"
66 group: demo_servers
67
68 - name: Print Interface IP for created server
69 debug:
70 var: created_server.interface_ip
71
72- hosts: demo_servers
73 tasks:
74
75 - name: Install webserver
76 package:
77 name: apache2
78 state: installed
79 become: yes
80
81 - name: Write content
82 template:
83 src: templates/setup.json.j2
84 dest: /var/www/html/setup.json
85 become: yes
86
87 - name: Ensure webserver is running
88 service:
89 name: apache2
90 state: started
91 become: yes
92
93 - name: Get Info from Server
94 uri:
95 url: "http://{{ ansible_host }}/setup.json"
96 register: server_info
97 delegate_to: localhost
98
99 - name: Print FQDN information about host
100 debug:
101 var: server_info.json.ansible_fqdn
diff --git a/src/three-minute-demo/hosts b/src/three-minute-demo/hosts
new file mode 100644
index 0000000..2fbb50c
--- /dev/null
+++ b/src/three-minute-demo/hosts
@@ -0,0 +1 @@
localhost
diff --git a/src/three-minute-demo/prep.yaml b/src/three-minute-demo/prep.yaml
new file mode 100644
index 0000000..412bfd4
--- /dev/null
+++ b/src/three-minute-demo/prep.yaml
@@ -0,0 +1,6 @@
1- hosts: localhost
2 gather_facts: false
3 roles:
4 - get-cloud-config
5 - build-image
6 - upload-image
diff --git a/src/three-minute-demo/roles/build-image/defaults/main.yaml b/src/three-minute-demo/roles/build-image/defaults/main.yaml
new file mode 100644
index 0000000..b6283b8
--- /dev/null
+++ b/src/three-minute-demo/roles/build-image/defaults/main.yaml
@@ -0,0 +1,3 @@
1distro: debian
2image_formats:
3- qcow2
diff --git a/src/three-minute-demo/roles/build-image/tasks/main.yaml b/src/three-minute-demo/roles/build-image/tasks/main.yaml
new file mode 100644
index 0000000..57be287
--- /dev/null
+++ b/src/three-minute-demo/roles/build-image/tasks/main.yaml
@@ -0,0 +1,19 @@
1- block:
2
3 - name: Check for existing image
4 stat:
5 path: "{{ distro }}.{{ image_formats[0] }}"
6 register: image_file
7
8 - name: Build image
9 command: |
10 disk-image-create -o {{ distro }} -t {{ image_formats | join(',') }} {{ distro }}-minimal simple-init growroot
11 when: not image_file.stat.exists
12
13- rescue:
14
15 - name: Clean up after a build failure
16 file:
17 path: "{{ distro }}.{{ item }}"
18 state: absent
19 with_items: "{{ image_formats }}"
diff --git a/src/three-minute-demo/roles/get-cloud-config/tasks/main.yaml b/src/three-minute-demo/roles/get-cloud-config/tasks/main.yaml
new file mode 100644
index 0000000..e6f5ecd
--- /dev/null
+++ b/src/three-minute-demo/roles/get-cloud-config/tasks/main.yaml
@@ -0,0 +1,6 @@
1- name: Grab OpenStack cloud config from clouds.yaml
2 os_client_config:
3
4- name: Get list of needed image formats
5 set_fact:
6 image_formats: "{{ openstack.clouds|json_query('[*].image_format') | unique }}"
diff --git a/src/three-minute-demo/roles/upload-image/defaults/main.yaml b/src/three-minute-demo/roles/upload-image/defaults/main.yaml
new file mode 100644
index 0000000..b6283b8
--- /dev/null
+++ b/src/three-minute-demo/roles/upload-image/defaults/main.yaml
@@ -0,0 +1,3 @@
1distro: debian
2image_formats:
3- qcow2
diff --git a/src/three-minute-demo/roles/upload-image/tasks/main.yaml b/src/three-minute-demo/roles/upload-image/tasks/main.yaml
new file mode 100644
index 0000000..c14c7eb
--- /dev/null
+++ b/src/three-minute-demo/roles/upload-image/tasks/main.yaml
@@ -0,0 +1,25 @@
1# All three are marked no_log because auth info from clouds.yaml is being
2# extracted and passed around
3
4- name: Check for existing images
5 os_image_facts:
6 cloud: "{{ item.name }}"
7 region_name: "{{ item.region_name }}"
8 image: "three-minute-demo-image"
9 with_items: "{{ openstack.clouds }}"
10 no_log: true
11 register: image_records
12
13- name: Get list of clouds without image
14 set_fact:
15 clouds_without_image: "{{ image_records.results|json_query('[?ansible_facts.openstack_image==null].item') }}"
16 no_log: true
17
18- name: Upload image if it's not there
19 os_image:
20 cloud: "{{ item.name }}"
21 region_name: "{{ item.region_name }}"
22 name: "three-minute-demo-image"
23 filename: "{{ distro }}.{{ item.image_format }}"
24 no_log: true
25 with_items: "{{ clouds_without_image }}"
diff --git a/src/three-minute-demo/templates/setup.json.j2 b/src/three-minute-demo/templates/setup.json.j2
new file mode 100644
index 0000000..1f6e6ab
--- /dev/null
+++ b/src/three-minute-demo/templates/setup.json.j2
@@ -0,0 +1 @@
{{ hostvars[inventory_hostname]|to_json }}