diff options
| author | Monty Taylor <mordred@inaugust.com> | 2017-11-05 13:24:37 +1100 |
|---|---|---|
| committer | Monty Taylor <mordred@inaugust.com> | 2017-11-05 17:07:06 +1100 |
| commit | 4ac60cf090af9618bd52b4b30cac4ee31b5d5967 (patch) | |
| tree | 7dda33747456c3b806d25c4318bef9b717f8aa3e /src | |
| parent | 2f5dfc495113c6dadf66fc7d5d395f90118514ca (diff) | |
Add ansible playbooks for 3 minute multi-cloud demo
Diffstat (limited to 'src')
| -rw-r--r-- | src/three-minute-demo/Dockerfile | 11 | ||||
| -rw-r--r-- | src/three-minute-demo/README.rst | 80 | ||||
| -rwxr-xr-x | src/three-minute-demo/ansible-playbook.sh | 11 | ||||
| -rwxr-xr-x | src/three-minute-demo/build-docker-image.sh | 3 | ||||
| -rw-r--r-- | src/three-minute-demo/demo.yaml | 101 | ||||
| -rw-r--r-- | src/three-minute-demo/hosts | 1 | ||||
| -rw-r--r-- | src/three-minute-demo/prep.yaml | 6 | ||||
| -rw-r--r-- | src/three-minute-demo/roles/build-image/defaults/main.yaml | 3 | ||||
| -rw-r--r-- | src/three-minute-demo/roles/build-image/tasks/main.yaml | 19 | ||||
| -rw-r--r-- | src/three-minute-demo/roles/get-cloud-config/tasks/main.yaml | 6 | ||||
| -rw-r--r-- | src/three-minute-demo/roles/upload-image/defaults/main.yaml | 3 | ||||
| -rw-r--r-- | src/three-minute-demo/roles/upload-image/tasks/main.yaml | 25 | ||||
| -rw-r--r-- | src/three-minute-demo/templates/setup.json.j2 | 1 |
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 @@ | |||
| 1 | FROM python | ||
| 2 | |||
| 3 | RUN 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 | ||
| 7 | VOLUME /demo | ||
| 8 | WORKDIR /demo | ||
| 9 | |||
| 10 | ENTRYPOINT ["ansible-playbook"] | ||
| 11 | CMD ["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 @@ | |||
| 1 | 3 Minute Demo of OpenStack Public Clouds | ||
| 2 | ======================================== | ||
| 3 | |||
| 4 | This is all the Ansible needed for the 3 minute public cloud demo. | ||
| 5 | |||
| 6 | It uses docker containers to avoid the need to install things on the local | ||
| 7 | computer. The Dockerfile uses the base ``python`` docker image regardless | ||
| 8 | of 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 | |||
| 18 | Building Docker Image | ||
| 19 | --------------------- | ||
| 20 | |||
| 21 | Step one is building the docker image: | ||
| 22 | |||
| 23 | .. code-block:: bash | ||
| 24 | |||
| 25 | docker build -t three-minute-demo . | ||
| 26 | |||
| 27 | A convenience script, ``build-docker-image.sh`` is provided that runs that | ||
| 28 | command. | ||
| 29 | |||
| 30 | Wrapper Script | ||
| 31 | -------------- | ||
| 32 | |||
| 33 | Once the ``three-minute-demo`` image exists, the ``ansible-playbook.sh`` script | ||
| 34 | will 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 | ||
| 36 | script. | ||
| 37 | |||
| 38 | The ``ansible-playbook.sh`` script will also bind-mount the current directory | ||
| 39 | as the main work dir and ``~/.config/openstack`` into ``/etc/openstack`` in the | ||
| 40 | container 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 | |||
| 48 | Building and Uploading Images | ||
| 49 | ----------------------------- | ||
| 50 | |||
| 51 | The demo depends on base images existing. The ``prep.yaml`` playbook will | ||
| 52 | create the images and upload them to all of the cloud regions. | ||
| 53 | |||
| 54 | .. code-block:: bash | ||
| 55 | |||
| 56 | ./ansible-playbook.sh prep.yaml | ||
| 57 | |||
| 58 | By default it will create a minimal ubuntu image. That can be changed by | ||
| 59 | setting ``distro`` on the ansible-playbook command line to something else, such | ||
| 60 | as ``fedora`` or ``centos``. | ||
| 61 | |||
| 62 | .. code-block:: bash | ||
| 63 | |||
| 64 | ./ansible-playbook.sh -edistro=fedora prep.yaml | ||
| 65 | |||
| 66 | The Demo | ||
| 67 | -------- | ||
| 68 | |||
| 69 | ``ansible-playbook.sh`` defaults to running ``demo.yaml``, which will create a | ||
| 70 | server in each cloud region, install Apache on that server, write out a json | ||
| 71 | file for apache to serve, fetch the contents into a variable and print out the | ||
| 72 | FQDN. | ||
| 73 | |||
| 74 | If you're thinking "wow, that's not useful" - you're right! This isn't intended | ||
| 75 | to be a demo of doing useful things with Ansible. It's intended to be a demo of | ||
| 76 | getting servers on a set of cloud regions across multiple public clouds and | ||
| 77 | then doing something with them. | ||
| 78 | |||
| 79 | Once you can perform a single task on the remote server with Ansible, you can | ||
| 80 | do 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 | |||
| 3 | if [ -d ${HOME}/.config/openstack ] ; then | ||
| 4 | CONFIG_DIR=${HOME}/.config/openstack | ||
| 5 | else | ||
| 6 | CONFIG_DIR=/etc/openstack | ||
| 7 | fi | ||
| 8 | |||
| 9 | exec 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 | |||
| 3 | docker 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 @@ | |||
| 1 | distro: debian | ||
| 2 | image_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 @@ | |||
| 1 | distro: debian | ||
| 2 | image_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 }} | |||
