Add ansible playbooks for 3 minute multi-cloud demo
This commit is contained in:
parent
2f5dfc4951
commit
4ac60cf090
|
@ -0,0 +1,11 @@
|
|||
FROM python
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y qemu-utils libffi-dev libssl-dev sudo \
|
||||
rpm yum-utils debootstrap && \
|
||||
pip install ansible shade diskimage-builder
|
||||
VOLUME /demo
|
||||
WORKDIR /demo
|
||||
|
||||
ENTRYPOINT ["ansible-playbook"]
|
||||
CMD ["demo.yaml"]
|
|
@ -0,0 +1,80 @@
|
|||
3 Minute Demo of OpenStack Public Clouds
|
||||
========================================
|
||||
|
||||
This is all the Ansible needed for the 3 minute public cloud demo.
|
||||
|
||||
It uses docker containers to avoid the need to install things on the local
|
||||
computer. The Dockerfile uses the base ``python`` docker image regardless
|
||||
of other distro since it's just a container for installing ansible.
|
||||
|
||||
.. note::
|
||||
|
||||
There is nothing docker-specific about the demo, it's just being used as
|
||||
a convenient way to bundle actions without polluting the user's computer.
|
||||
The playbooks themselves can be used directly for people who have the
|
||||
pre-reqs of ansible, shade and diskimage-builder installed or who do not
|
||||
mind installing them globally.
|
||||
|
||||
Building Docker Image
|
||||
---------------------
|
||||
|
||||
Step one is building the docker image:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
docker build -t three-minute-demo .
|
||||
|
||||
A convenience script, ``build-docker-image.sh`` is provided that runs that
|
||||
command.
|
||||
|
||||
Wrapper Script
|
||||
--------------
|
||||
|
||||
Once the ``three-minute-demo`` image exists, the ``ansible-playbook.sh`` script
|
||||
will user it to run ``ansible-playbook``. By default it will run the
|
||||
``run.yaml`` playbook, but that can be overridden by passing parameters to the
|
||||
script.
|
||||
|
||||
The ``ansible-playbook.sh`` script will also bind-mount the current directory
|
||||
as the main work dir and ``~/.config/openstack`` into ``/etc/openstack`` in the
|
||||
container so that ``clouds.yaml`` is available.
|
||||
|
||||
.. note::
|
||||
|
||||
If ~/.config/openstack doesn't exist but /etc/openstack does,
|
||||
ansible-playbook.sh will mount /etc/openstack instead. If a different setup
|
||||
is desired, you can always run docker commands.
|
||||
|
||||
Building and Uploading Images
|
||||
-----------------------------
|
||||
|
||||
The demo depends on base images existing. The ``prep.yaml`` playbook will
|
||||
create the images and upload them to all of the cloud regions.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./ansible-playbook.sh prep.yaml
|
||||
|
||||
By default it will create a minimal ubuntu image. That can be changed by
|
||||
setting ``distro`` on the ansible-playbook command line to something else, such
|
||||
as ``fedora`` or ``centos``.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
./ansible-playbook.sh -edistro=fedora prep.yaml
|
||||
|
||||
The Demo
|
||||
--------
|
||||
|
||||
``ansible-playbook.sh`` defaults to running ``demo.yaml``, which will create a
|
||||
server in each cloud region, install Apache on that server, write out a json
|
||||
file for apache to serve, fetch the contents into a variable and print out the
|
||||
FQDN.
|
||||
|
||||
If you're thinking "wow, that's not useful" - you're right! This isn't intended
|
||||
to be a demo of doing useful things with Ansible. It's intended to be a demo of
|
||||
getting servers on a set of cloud regions across multiple public clouds and
|
||||
then doing something with them.
|
||||
|
||||
Once you can perform a single task on the remote server with Ansible, you can
|
||||
do anything with Ansible you want to do.
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -d ${HOME}/.config/openstack ] ; then
|
||||
CONFIG_DIR=${HOME}/.config/openstack
|
||||
else
|
||||
CONFIG_DIR=/etc/openstack
|
||||
fi
|
||||
|
||||
exec docker run -it --rm --privileged \
|
||||
-v${PWD}:/demo -v${CONFIG_DIR}:/etc/openstack \
|
||||
three-minute-demo $*
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
docker build -t three-minute-demo .
|
|
@ -0,0 +1,101 @@
|
|||
- hosts: localhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
|
||||
- name: Read in cloud config
|
||||
os_client_config:
|
||||
|
||||
- name: Add fake host for each cloud region so we can parallelize
|
||||
add_host:
|
||||
name: "{{ item.name }}-{{ item.region_name }}"
|
||||
ansible_host: localhost
|
||||
ansible_connection: local
|
||||
groups: clouds
|
||||
cloud: "{{ item.name }}"
|
||||
region_name: "{{ item.region_name }}"
|
||||
with_items: "{{ openstack.clouds }}"
|
||||
|
||||
- hosts: clouds
|
||||
gather_facts: false
|
||||
tasks:
|
||||
|
||||
- name: Upload ssh public key
|
||||
os_keypair:
|
||||
public_key_file: "{{ ansible_user_dir }}/.ssh/id_rsa.pub"
|
||||
name: "three_minute_demo"
|
||||
cloud: "{{ cloud }}"
|
||||
region_name: "{{ region_name }}"
|
||||
|
||||
- name: Add wide-open security group
|
||||
os_security_group:
|
||||
name: three-minute-demo-group
|
||||
description: Open security group
|
||||
|
||||
- name: Add rules to group
|
||||
os_security_group_rules:
|
||||
ethertype: "{{ item.ethertype }}"
|
||||
remote_group: "{{ item.remote_group|default(omit) }}"
|
||||
remote_ip_prefix: "{{ item.remote_ip_prefix|default(omit) }}"
|
||||
security_group: three-minute-demo-group
|
||||
with_items:
|
||||
- ethertype: IPv4
|
||||
remote_group: default
|
||||
state: absent
|
||||
- ethertype: IPv6
|
||||
remote_group: default
|
||||
state: absent
|
||||
- ethertype: IPv4
|
||||
remote_ip_prefix: 0.0.0.0/0
|
||||
- ethertype: IPv6
|
||||
remote_ip_prefix: ::/0
|
||||
|
||||
- name: Create a small VM
|
||||
os_server:
|
||||
auto_ip: true
|
||||
key_name: three_minute_demo
|
||||
name: three_minute_demo_server
|
||||
cloud: "{{ cloud }}"
|
||||
region_name: "{{ region_name }}"
|
||||
wait: true
|
||||
register: created_server
|
||||
|
||||
- name: Add VM to inventory
|
||||
add_host:
|
||||
name: "{{ cloud }}.{{ region_name }}.demo"
|
||||
ansible_host: "{{ created_server.interface_ip }}"
|
||||
group: demo_servers
|
||||
|
||||
- name: Print Interface IP for created server
|
||||
debug:
|
||||
var: created_server.interface_ip
|
||||
|
||||
- hosts: demo_servers
|
||||
tasks:
|
||||
|
||||
- name: Install webserver
|
||||
package:
|
||||
name: apache2
|
||||
state: installed
|
||||
become: yes
|
||||
|
||||
- name: Write content
|
||||
template:
|
||||
src: templates/setup.json.j2
|
||||
dest: /var/www/html/setup.json
|
||||
become: yes
|
||||
|
||||
- name: Ensure webserver is running
|
||||
service:
|
||||
name: apache2
|
||||
state: started
|
||||
become: yes
|
||||
|
||||
- name: Get Info from Server
|
||||
uri:
|
||||
url: "http://{{ ansible_host }}/setup.json"
|
||||
register: server_info
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Print FQDN information about host
|
||||
debug:
|
||||
var: server_info.json.ansible_fqdn
|
|
@ -0,0 +1 @@
|
|||
localhost
|
|
@ -0,0 +1,6 @@
|
|||
- hosts: localhost
|
||||
gather_facts: false
|
||||
roles:
|
||||
- get-cloud-config
|
||||
- build-image
|
||||
- upload-image
|
|
@ -0,0 +1,3 @@
|
|||
distro: debian
|
||||
image_formats:
|
||||
- qcow2
|
|
@ -0,0 +1,19 @@
|
|||
- block:
|
||||
|
||||
- name: Check for existing image
|
||||
stat:
|
||||
path: "{{ distro }}.{{ image_formats[0] }}"
|
||||
register: image_file
|
||||
|
||||
- name: Build image
|
||||
command: |
|
||||
disk-image-create -o {{ distro }} -t {{ image_formats | join(',') }} {{ distro }}-minimal simple-init growroot
|
||||
when: not image_file.stat.exists
|
||||
|
||||
- rescue:
|
||||
|
||||
- name: Clean up after a build failure
|
||||
file:
|
||||
path: "{{ distro }}.{{ item }}"
|
||||
state: absent
|
||||
with_items: "{{ image_formats }}"
|
|
@ -0,0 +1,6 @@
|
|||
- name: Grab OpenStack cloud config from clouds.yaml
|
||||
os_client_config:
|
||||
|
||||
- name: Get list of needed image formats
|
||||
set_fact:
|
||||
image_formats: "{{ openstack.clouds|json_query('[*].image_format') | unique }}"
|
|
@ -0,0 +1,3 @@
|
|||
distro: debian
|
||||
image_formats:
|
||||
- qcow2
|
|
@ -0,0 +1,25 @@
|
|||
# All three are marked no_log because auth info from clouds.yaml is being
|
||||
# extracted and passed around
|
||||
|
||||
- name: Check for existing images
|
||||
os_image_facts:
|
||||
cloud: "{{ item.name }}"
|
||||
region_name: "{{ item.region_name }}"
|
||||
image: "three-minute-demo-image"
|
||||
with_items: "{{ openstack.clouds }}"
|
||||
no_log: true
|
||||
register: image_records
|
||||
|
||||
- name: Get list of clouds without image
|
||||
set_fact:
|
||||
clouds_without_image: "{{ image_records.results|json_query('[?ansible_facts.openstack_image==null].item') }}"
|
||||
no_log: true
|
||||
|
||||
- name: Upload image if it's not there
|
||||
os_image:
|
||||
cloud: "{{ item.name }}"
|
||||
region_name: "{{ item.region_name }}"
|
||||
name: "three-minute-demo-image"
|
||||
filename: "{{ distro }}.{{ item.image_format }}"
|
||||
no_log: true
|
||||
with_items: "{{ clouds_without_image }}"
|
|
@ -0,0 +1 @@
|
|||
{{ hostvars[inventory_hostname]|to_json }}
|
Loading…
Reference in New Issue