From 22e9aad745aad3e3e7ee86060e5a0cc2cab7bfbb Mon Sep 17 00:00:00 2001 From: Tong Li Date: Tue, 13 Sep 2016 12:51:11 -0400 Subject: [PATCH] Remove hardcoded volume point and tenant network issues This patch set fixed the following problems 1. Using hardcoded device names such as eth0, /dev/vdb. These names are configurable now 2. Requires tenant networks to be avaialbe. No longer required now 3. Terraform multiple endpoints issue can not be overcame. Recreated the docker swarm workload test using ansible Change-Id: Ic4bcd07caa7f7a27f7cb520fb3302fb547f085f0 --- ansible/dockerswarm/.gitignore | 4 + ansible/dockerswarm/README.md | 128 ++++++++++++++++++ ansible/dockerswarm/ansible.cfg | 2 + ansible/dockerswarm/hosts | 1 + .../roles/post_apply/tasks/main.yml | 11 ++ .../roles/post_destroy/tasks/main.yml | 23 ++++ .../roles/prep_apply/tasks/main.yml | 88 ++++++++++++ .../roles/prep_apply/templates/cloudinit.j2 | 47 +++++++ .../roles/prep_destroy/tasks/main.yml | 13 ++ .../roles/prov_apply/tasks/main.yml | 34 +++++ .../roles/prov_apply/templates/bootstrap1.j2 | 31 +++++ .../roles/prov_apply/templates/bootstrap2.j2 | 32 +++++ .../prov_apply/templates/dockerservice.j2 | 2 + .../roles/prov_apply/templates/openssl.cnf | 8 ++ .../roles/prov_destroy/tasks/main.yml | 12 ++ .../dockerswarm/roles/vm_apply/tasks/main.yml | 19 +++ ansible/dockerswarm/site.yml | 33 +++++ ansible/dockerswarm/vars/bluebox.yml | 21 +++ ansible/dockerswarm/vars/leap.yml | 22 +++ ansible/dockerswarm/vars/osic.yml | 22 +++ ansible/dockerswarm/vars/ovh.yml | 21 +++ ansible/lampstack/.gitignore | 6 + ansible/lampstack/README.md | 1 + ansible/lampstack/roles/apply/tasks/main.yml | 16 ++- .../roles/apply/templates/userdata.j2 | 4 +- .../lampstack/roles/balancer/tasks/main.yml | 8 +- .../lampstack/roles/cleaner/tasks/apply.yml | 6 + .../lampstack/roles/database/tasks/main.yml | 41 +++--- .../lampstack/roles/destroy/tasks/main.yml | 9 ++ .../lampstack/roles/webserver/tasks/main.yml | 31 ++++- ansible/lampstack/site.yml | 8 +- ansible/lampstack/vars/bluebox.yml | 6 +- ansible/lampstack/vars/leap.yml | 6 +- terraform/dockerswarm-coreos/README.md | 1 + terraform/dockerswarm-coreos/swarm.tf | 3 + .../templates/10-docker-service.conf | 2 +- .../dockerswarm-coreos/vars-openstack.tf | 5 + 37 files changed, 690 insertions(+), 37 deletions(-) create mode 100755 ansible/dockerswarm/.gitignore create mode 100755 ansible/dockerswarm/README.md create mode 100755 ansible/dockerswarm/ansible.cfg create mode 100755 ansible/dockerswarm/hosts create mode 100755 ansible/dockerswarm/roles/post_apply/tasks/main.yml create mode 100755 ansible/dockerswarm/roles/post_destroy/tasks/main.yml create mode 100755 ansible/dockerswarm/roles/prep_apply/tasks/main.yml create mode 100755 ansible/dockerswarm/roles/prep_apply/templates/cloudinit.j2 create mode 100755 ansible/dockerswarm/roles/prep_destroy/tasks/main.yml create mode 100755 ansible/dockerswarm/roles/prov_apply/tasks/main.yml create mode 100755 ansible/dockerswarm/roles/prov_apply/templates/bootstrap1.j2 create mode 100755 ansible/dockerswarm/roles/prov_apply/templates/bootstrap2.j2 create mode 100755 ansible/dockerswarm/roles/prov_apply/templates/dockerservice.j2 create mode 100755 ansible/dockerswarm/roles/prov_apply/templates/openssl.cnf create mode 100755 ansible/dockerswarm/roles/prov_destroy/tasks/main.yml create mode 100755 ansible/dockerswarm/roles/vm_apply/tasks/main.yml create mode 100755 ansible/dockerswarm/site.yml create mode 100755 ansible/dockerswarm/vars/bluebox.yml create mode 100755 ansible/dockerswarm/vars/leap.yml create mode 100755 ansible/dockerswarm/vars/osic.yml create mode 100755 ansible/dockerswarm/vars/ovh.yml create mode 100755 ansible/lampstack/.gitignore mode change 100644 => 100755 terraform/dockerswarm-coreos/swarm.tf mode change 100644 => 100755 terraform/dockerswarm-coreos/templates/10-docker-service.conf diff --git a/ansible/dockerswarm/.gitignore b/ansible/dockerswarm/.gitignore new file mode 100755 index 0000000..550a804 --- /dev/null +++ b/ansible/dockerswarm/.gitignore @@ -0,0 +1,4 @@ +*.out +*/**/*.log +*/**/.DS_Store +*/**/._ diff --git a/ansible/dockerswarm/README.md b/ansible/dockerswarm/README.md new file mode 100755 index 0000000..13fabf3 --- /dev/null +++ b/ansible/dockerswarm/README.md @@ -0,0 +1,128 @@ +# Docker Swarm Ansible deployments on OpenStack Cloud + +## Status + +This will install a 3 node lampstack. Once the script finishes, a set of +environment varialbes will be displayed, export these environment variable +then you can run docker commands against the swarm + +## Requirements + +- [Install Ansible](http://docs.ansible.com/ansible/intro_installation.html) +- [Install openstack shade] (http://docs.openstack.org/infra/shade/installation.html) +- Make sure there is an openstack coreos image available on your cloud. +- Clone this project into a directory. +- To run docker commands, you will need to install docker client. Following + the following steps if you are using ubuntu to run the script, if you are + using some other environment run the script, then the steps setting up + docker client may be different:: + + apt-get update + apt-get -y install docker.io + ln -sf /usr/bin/docker.io /usr/local/bin/docker + +## Ansible + +Ansible and OpenStack Shade are used to provision all of the OpenStack +resources. + +### Prep + +#### Deal with ssh keys for Openstack Authentication + +If you do not have a ssh key, then you should create one by using a tool. +An example command to do that is provided below. Once you have a key pair, +ensure your local ssh-agent is running and your ssh key has been added. +This step is required. Not doing this, you will have to manually give +passphrase when script runs, and script can fail. If you really do not want +to deal with passphrase, you can create a key pair without passphrase:: + + ssh-keygen -t rsa + eval $(ssh-agent -s) + ssh-add ~/.ssh/id_rsa + +#### General Openstack Settings + +Ansible's OpenStack cloud module is used to provision compute resources +against an OpenStack cloud. Before you run the script, the cloud environment +will have to be specified. Sample files have been provided in vars directory. +You may create one such file per cloud for your tests. The following is an +example:: + + auth: { + auth_url: "http://x.x.x.x:5000/v3", + username: "demo", + password: "{{ password }}", + domain_name: "default", + project_name: "demo" + } + + app_env: { + image_name: "coreos", + region_name: "", + private_net_name: "", + net_device: "eth0", + flavor_name: "m1.small", + swarm_version: "latest", + swarm_size: 3, + fqdn: "swarm.example.com", + public_key_file: "/home/tong/.ssh/id_rsa.pub" + } + + +The values of these variables should be provided by your cloud provider. When +use keystone 2.0 API, you will not need to setup domain name. If your account +only has more than one regions available, specify the region_name to be used. +If there is only one, you can leave it blank or use the correct name. If your +cloud does not expose tenant network, leave private_net_name blank as well. +However, if your cloud supports tenant network and you have more than one +tenant networks in your account, you will need to specify which tenant network +to be used, otherwise, the script will error out. To create a large docker +swarm, change the swarm_size to a large value like 20, the script will create +a docker swarm with 20 coreos nodes. + + +## Run the script + +With your cloud environment set, you should be able to run the script:: + + ansible-playbook -e "action=apply env=leap password=XXXXX" site.yml + +The command will stand up the nodes using a cloud named leap (vars/leap.yml). +If you run the test against other cloud, you can create a new file use same +structure and specify that cloud attributes such as auth_url, etc. Then you +can simply replace work leap with that file name. Replace xxxxx with your +own cloud account password, you can also simply put your password in the +configuration file (vars/leap.yml in this case) and avoid to specify it from +the command line. + +If everything goes well, it will accomplish the following:: + + 1. Provision 3 coreos nodes on your cloud + 2. Create security group + 3. Add security rules to allow ping, ssh, docker access + 4. Setup ssl keys, certificates + 5. Display a set of environment variables that you can use to run docker + commands + + +## Next Steps + +### Check its up + +If there are no errors, you can export the environment variables shown by +the script at the end. Then you can start running docker commands, here are +few examples:: + + docker info + docker images + docker pull ubuntu:vivid + + +## Cleanup + +Once you're done with the swarm, don't forget to nuke the whole thing:: + + ansible-playbook -e "action=destroy env=leap password=XXXXX" site.yml + +The above command will destroy all the resources created by the script. diff --git a/ansible/dockerswarm/ansible.cfg b/ansible/dockerswarm/ansible.cfg new file mode 100755 index 0000000..34662e9 --- /dev/null +++ b/ansible/dockerswarm/ansible.cfg @@ -0,0 +1,2 @@ +[defaults] +inventory = ./hosts diff --git a/ansible/dockerswarm/hosts b/ansible/dockerswarm/hosts new file mode 100755 index 0000000..325d1c9 --- /dev/null +++ b/ansible/dockerswarm/hosts @@ -0,0 +1 @@ +cloud ansible_host=127.0.0.1 diff --git a/ansible/dockerswarm/roles/post_apply/tasks/main.yml b/ansible/dockerswarm/roles/post_apply/tasks/main.yml new file mode 100755 index 0000000..177dedf --- /dev/null +++ b/ansible/dockerswarm/roles/post_apply/tasks/main.yml @@ -0,0 +1,11 @@ +--- +- debug: + msg: >- + export DOCKER_HOST=tcp://{{ hostvars.swarmnode1.swarmnode.openstack.public_v4 }}:2375; + export DOCKER_TLS_VERIFY=1; + export DOCKER_CERT_PATH=/tmp/{{ env }}/keys + +- debug: + msg: >- + The work load test started at {{ starttime.time }}, + ended at {{ ansible_date_time.time }} diff --git a/ansible/dockerswarm/roles/post_destroy/tasks/main.yml b/ansible/dockerswarm/roles/post_destroy/tasks/main.yml new file mode 100755 index 0000000..0f8b173 --- /dev/null +++ b/ansible/dockerswarm/roles/post_destroy/tasks/main.yml @@ -0,0 +1,23 @@ +--- +- name: Remove security group + os_security_group: + state: absent + auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" + name: dockerswarm_sg + description: secuirty group for dockerswarm + +- name: Delete discovery url directory + file: path="/tmp/{{ env }}" state=absent + +- name: Delete a key-pair + os_keypair: + state: absent + auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" + name: "dockerswarm" + +- debug: + msg: >- + The work load test started at {{ starttime.time }}, + ended at {{ ansible_date_time.time }} \ No newline at end of file diff --git a/ansible/dockerswarm/roles/prep_apply/tasks/main.yml b/ansible/dockerswarm/roles/prep_apply/tasks/main.yml new file mode 100755 index 0000000..6c75eda --- /dev/null +++ b/ansible/dockerswarm/roles/prep_apply/tasks/main.yml @@ -0,0 +1,88 @@ +--- +- name: Get start timestamp + set_fact: starttime="{{ ansible_date_time }}" + +- name: Create certificate directory + file: path="/tmp/{{ env }}/keys" state=directory + +- stat: path="/tmp/{{ env }}/discovery_url" + register: discovery_url_flag + +- name: Get docker discovery url + get_url: + url: "https://discovery.etcd.io/new?size={{ app_env.swarm_size }}" + dest: "/tmp/{{ env }}/discovery_url" + when: discovery_url_flag.stat.exists == false + +- shell: openssl genrsa -out "/tmp/{{ env }}/keys/ca-key.pem" 2048 +- shell: openssl genrsa -out "/tmp/{{ env }}/keys/key.pem" 2048 + +- shell: >- + openssl req -x509 -new -nodes -key /tmp/{{ env }}/keys/ca-key.pem + -days 10000 -out /tmp/{{ env }}/keys/ca.pem -subj '/CN=docker-CA' + +- shell: >- + openssl req -new -key /tmp/{{ env }}/keys/key.pem + -out /tmp/{{ env }}/keys/cert.csr + -subj '/CN=docker-client' -config ./roles/prov_apply/templates/openssl.cnf + +- shell: >- + openssl x509 -req -in /tmp/{{ env }}/keys/cert.csr + -CA /tmp/{{ env }}/keys/ca.pem -CAkey /tmp/{{ env }}/keys/ca-key.pem + -CAcreateserial -out /tmp/{{ env }}/keys/cert.pem -days 365 + -extensions v3_req -extfile ./roles/prov_apply/templates/openssl.cnf + +- name: Retrieve specified flavor + os_flavor_facts: + auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" + name: "{{ app_env.flavor_name }}" + +- name: Create a key-pair + os_keypair: + state: "present" + auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" + name: "dockerswarm" + public_key_file: "{{ app_env.public_key_file }}" + +- name: Create security group + os_security_group: + state: present + auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" + name: dockerswarm_sg + description: secuirty group for dockerswarm + +- name: Add security rules + os_security_group_rule: + state: present + auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" + security_group: dockerswarm_sg + protocol: "{{ item.protocol }}" + direction: "{{ item.dir }}" + port_range_min: "{{ item.p_min }}" + port_range_max: "{{ item.p_max }}" + remote_ip_prefix: 0.0.0.0/0 + with_items: + - { p_min: 22, p_max: 22, dir: ingress, protocol: tcp } + - { p_min: 2375, p_max: 2376, dir: ingress, protocol: tcp } + - { p_min: 2379, p_max: 2380, dir: ingress, protocol: tcp } + - { p_min: 2379, p_max: 2380, dir: egress, protocol: tcp } + - { p_min: -1, p_max: -1, dir: ingress, protocol: icmp } + - { p_min: -1, p_max: -1, dir: egress, protocol: icmp } + +- name: Create cloudinit file for all nodes + template: + src: templates/cloudinit.j2 + dest: "/tmp/{{ env }}/cloudinit" + +- name: Add nodes to host group + add_host: + name: "swarmnode{{ item }}" + hostname: "127.0.0.1" + groups: dockerswarm + host_no: "{{ item }}" + with_sequence: count={{ app_env.swarm_size }} + no_log: True diff --git a/ansible/dockerswarm/roles/prep_apply/templates/cloudinit.j2 b/ansible/dockerswarm/roles/prep_apply/templates/cloudinit.j2 new file mode 100755 index 0000000..bb42133 --- /dev/null +++ b/ansible/dockerswarm/roles/prep_apply/templates/cloudinit.j2 @@ -0,0 +1,47 @@ +#cloud-config +coreos: + units: + - name: etcd.service + mask: true + - name: etcd2.service + command: start + - name: docker.service + command: start + - name: swarm-agent.service + content: | + [Unit] + Description=swarm agent + Requires=docker.service + After=docker.service + + [Service] + EnvironmentFile=/etc/environment + TimeoutStartSec=20m + ExecStartPre=/usr/bin/docker pull swarm:latest + ExecStartPre=-/usr/bin/docker rm -f swarm-agent + ExecStart=/bin/sh -c "/usr/bin/docker run --rm --name swarm-agent swarm:latest join --addr=$COREOS_PRIVATE_IPV4:2376 etcd://$COREOS_PRIVATE_IPV4:2379/docker" + ExecStop=/usr/bin/docker stop swarm-agent + - name: swarm-manager.service + content: | + [Unit] + Description=swarm manager + Requires=docker.service + After=docker.service + + [Service] + EnvironmentFile=/etc/environment + TimeoutStartSec=20m + ExecStartPre=/usr/bin/docker pull swarm:latest + ExecStartPre=-/usr/bin/docker rm -f swarm-manager + ExecStart=/bin/sh -c "/usr/bin/docker run --rm --name swarm-manager -v /etc/docker/ssl:/etc/docker/ssl --net=host swarm:latest manage --tlsverify --tlscacert=/etc/docker/ssl/ca.pem --tlscert=/etc/docker/ssl/cert.pem --tlskey=/etc/docker/ssl/key.pem etcd://$COREOS_PRIVATE_IPV4:2379/docker" + ExecStop=/usr/bin/docker stop swarm-manager + etcd2: + discovery: {{ lookup('file', '/tmp/'+env+'/discovery_url') }} + advertise-client-urls: http://$private_ipv4:2379 + initial-advertise-peer-urls: http://$private_ipv4:2380 + listen-client-urls: http://0.0.0.0:2379 + listen-peer-urls: http://$private_ipv4:2380 + data-dir: /var/lib/etcd2 + initial-cluster-token: openstackinterop + update: + reboot-strategy: "off" diff --git a/ansible/dockerswarm/roles/prep_destroy/tasks/main.yml b/ansible/dockerswarm/roles/prep_destroy/tasks/main.yml new file mode 100755 index 0000000..931b80f --- /dev/null +++ b/ansible/dockerswarm/roles/prep_destroy/tasks/main.yml @@ -0,0 +1,13 @@ +--- +- name: Get start timestamp + set_fact: starttime="{{ ansible_date_time }}" + +- name: Add web servers to webservers host group + add_host: + name: "swarmnode{{ item }}" + hostname: "127.0.0.1" + groups: dockerswarm + host_no: "{{ item }}" + with_sequence: count={{ app_env.swarm_size }} + no_log: True + \ No newline at end of file diff --git a/ansible/dockerswarm/roles/prov_apply/tasks/main.yml b/ansible/dockerswarm/roles/prov_apply/tasks/main.yml new file mode 100755 index 0000000..08fb615 --- /dev/null +++ b/ansible/dockerswarm/roles/prov_apply/tasks/main.yml @@ -0,0 +1,34 @@ +--- +- name: Get public IP + set_fact: node_ip="{{ swarmnode.openstack.public_v4 }}" + +- name: Make certificate configuration file + copy: + src: templates/openssl.cnf + dest: "/tmp/{{ env }}/{{ node_ip }}/keys/" + +- name: Make service file + template: + src: templates/dockerservice.j2 + dest: "/tmp/{{ env }}/{{ node_ip }}/keys/dockerservice.cnf" + +- name: Create bootstrap file + template: + src: templates/bootstrap1.j2 + dest: "/tmp/{{ env }}/{{ node_ip }}/keys/bootstrap.sh" + when: swarmnode.openstack.private_v4 == "" + +- name: Create bootstrap file + template: + src: templates/bootstrap2.j2 + dest: "/tmp/{{ env }}/{{ node_ip }}/keys/bootstrap.sh" + when: swarmnode.openstack.private_v4 != "" + +- name: Transfer configureation + shell: scp -r "/tmp/{{ env }}/{{ node_ip }}/keys" "core@{{ node_ip }}:/home/core" + +- name: Transfer certificate file over to the nodes + shell: scp -r "/tmp/{{ env }}/keys" "core@{{ node_ip }}:/home/core" + +- name: Start services + shell: ssh "core@{{ node_ip }}" "sh keys/bootstrap.sh" diff --git a/ansible/dockerswarm/roles/prov_apply/templates/bootstrap1.j2 b/ansible/dockerswarm/roles/prov_apply/templates/bootstrap1.j2 new file mode 100755 index 0000000..5c7d26d --- /dev/null +++ b/ansible/dockerswarm/roles/prov_apply/templates/bootstrap1.j2 @@ -0,0 +1,31 @@ +mkdir -p /home/core/.docker +cp /home/core/keys/ca.pem /home/core/.docker/ +cp /home/core/keys/cert.pem /home/core/.docker/ +cp /home/core/keys/key.pem /home/core/.docker/ + +echo 'subjectAltName = @alt_names' >> /home/core/keys/openssl.cnf +echo '[alt_names]' >> /home/core/keys/openssl.cnf + +cd /home/core/keys + +echo 'IP.1 = {{ swarmnode.openstack.public_v4 }}' >> openssl.cnf +echo 'DNS.1 = {{ app_env.fqdn }}' >> openssl.cnf +echo 'DNS.2 = {{ swarmnode.openstack.public_v4 }}.xip.io' >> openssl.cnf + +openssl req -new -key key.pem -out cert.csr -subj '/CN=docker-client' -config openssl.cnf +openssl x509 -req -in cert.csr -CA ca.pem -CAkey ca-key.pem \ + -CAcreateserial -out cert.pem -days 365 -extensions v3_req -extfile openssl.cnf + +sudo mkdir -p /etc/docker/ssl +sudo cp ca.pem /etc/docker/ssl/ +sudo cp cert.pem /etc/docker/ssl/ +sudo cp key.pem /etc/docker/ssl/ + +# Apply localized settings to services +sudo mkdir -p /etc/systemd/system/{docker,swarm-agent,swarm-manager}.service.d + +sudo mv /home/core/keys/dockerservice.cnf /etc/systemd/system/docker.service.d/10-docker-service.conf +sudo systemctl daemon-reload +sudo systemctl restart docker.service +sudo systemctl start swarm-agent.service +sudo systemctl start swarm-manager.service diff --git a/ansible/dockerswarm/roles/prov_apply/templates/bootstrap2.j2 b/ansible/dockerswarm/roles/prov_apply/templates/bootstrap2.j2 new file mode 100755 index 0000000..c0be6cc --- /dev/null +++ b/ansible/dockerswarm/roles/prov_apply/templates/bootstrap2.j2 @@ -0,0 +1,32 @@ +mkdir -p /home/core/.docker +cp /home/core/keys/ca.pem /home/core/.docker/ +cp /home/core/keys/cert.pem /home/core/.docker/ +cp /home/core/keys/key.pem /home/core/.docker/ + +echo 'subjectAltName = @alt_names' >> /home/core/keys/openssl.cnf +echo '[alt_names]' >> /home/core/keys/openssl.cnf + +cd /home/core/keys + +echo 'IP.1 = {{ swarmnode.openstack.private_v4 }}' >> openssl.cnf +echo 'IP.2 = {{ swarmnode.openstack.public_v4 }}' >> openssl.cnf +echo 'DNS.1 = {{ app_env.fqdn }}' >> openssl.cnf +echo 'DNS.2 = {{ swarmnode.openstack.public_v4 }}.xip.io' >> openssl.cnf + +openssl req -new -key key.pem -out cert.csr -subj '/CN=docker-client' -config openssl.cnf +openssl x509 -req -in cert.csr -CA ca.pem -CAkey ca-key.pem \ + -CAcreateserial -out cert.pem -days 365 -extensions v3_req -extfile openssl.cnf + +sudo mkdir -p /etc/docker/ssl +sudo cp ca.pem /etc/docker/ssl/ +sudo cp cert.pem /etc/docker/ssl/ +sudo cp key.pem /etc/docker/ssl/ + +# Apply localized settings to services +sudo mkdir -p /etc/systemd/system/{docker,swarm-agent,swarm-manager}.service.d + +sudo mv /home/core/keys/dockerservice.cnf /etc/systemd/system/docker.service.d/10-docker-service.conf +sudo systemctl daemon-reload +sudo systemctl restart docker.service +sudo systemctl start swarm-agent.service +sudo systemctl start swarm-manager.service diff --git a/ansible/dockerswarm/roles/prov_apply/templates/dockerservice.j2 b/ansible/dockerswarm/roles/prov_apply/templates/dockerservice.j2 new file mode 100755 index 0000000..01f5086 --- /dev/null +++ b/ansible/dockerswarm/roles/prov_apply/templates/dockerservice.j2 @@ -0,0 +1,2 @@ +[Service] +Environment="DOCKER_OPTS=-H=0.0.0.0:2376 -H unix:///var/run/docker.sock --tlsverify --tlscacert=/etc/docker/ssl/ca.pem --tlscert=/etc/docker/ssl/cert.pem --tlskey=/etc/docker/ssl/key.pem --cluster-advertise {{app_env.net_device}}:2376 --cluster-store etcd://127.0.0.1:2379/docker" diff --git a/ansible/dockerswarm/roles/prov_apply/templates/openssl.cnf b/ansible/dockerswarm/roles/prov_apply/templates/openssl.cnf new file mode 100755 index 0000000..67b3864 --- /dev/null +++ b/ansible/dockerswarm/roles/prov_apply/templates/openssl.cnf @@ -0,0 +1,8 @@ +[req] +req_extensions = v3_req +distinguished_name = req_distinguished_name +[req_distinguished_name] +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +extendedKeyUsage = clientAuth, serverAuth diff --git a/ansible/dockerswarm/roles/prov_destroy/tasks/main.yml b/ansible/dockerswarm/roles/prov_destroy/tasks/main.yml new file mode 100755 index 0000000..f43cd79 --- /dev/null +++ b/ansible/dockerswarm/roles/prov_destroy/tasks/main.yml @@ -0,0 +1,12 @@ +--- +- name: Remove docker swarm nodes + os_server: + state: "absent" + auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" + name: docker-swarm-{{ host_no }} + key_name: "dockerswarm" + timeout: 200 + security_groups: dockerswarm_sg + meta: + hostname: docker-swarm-{{ host_no }} \ No newline at end of file diff --git a/ansible/dockerswarm/roles/vm_apply/tasks/main.yml b/ansible/dockerswarm/roles/vm_apply/tasks/main.yml new file mode 100755 index 0000000..57cb1d2 --- /dev/null +++ b/ansible/dockerswarm/roles/vm_apply/tasks/main.yml @@ -0,0 +1,19 @@ +--- +- name: Create docker swarm nodes + os_server: + state: "present" + auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" + name: docker-swarm-{{ host_no }} + image: "{{ app_env.image_name }}" + key_name: "dockerswarm" + timeout: 200 + flavor: "{{ hostvars.cloud.openstack_flavors[0].id }}" + network: "{{ app_env.private_net_name }}" + auto_ip: yes + userdata: "{{ lookup('file', '/tmp/' +env+ '/cloudinit') }}" + security_groups: dockerswarm_sg + meta: + hostname: docker-swarm-{{ host_no }} + register: swarmnode + diff --git a/ansible/dockerswarm/site.yml b/ansible/dockerswarm/site.yml new file mode 100755 index 0000000..54247d6 --- /dev/null +++ b/ansible/dockerswarm/site.yml @@ -0,0 +1,33 @@ +--- +- name: prepare for provision + hosts: cloud + connection: local + vars_files: + - "vars/{{ env }}.yml" + roles: + - "prep_{{ action }}" + +- name: provision swarm nodes + hosts: dockerswarm + serial: 1 + connection: local + vars_files: + - "vars/{{ env }}.yml" + roles: + - "vm_{{ action }}" + +- name: setup swarm nodes + hosts: dockerswarm + connection: local + vars_files: + - "vars/{{ env }}.yml" + roles: + - "prov_{{ action }}" + +- name: post provisioning + hosts: cloud + connection: local + vars_files: + - "vars/{{ env }}.yml" + roles: + - "post_{{ action }}" diff --git a/ansible/dockerswarm/vars/bluebox.yml b/ansible/dockerswarm/vars/bluebox.yml new file mode 100755 index 0000000..46f837c --- /dev/null +++ b/ansible/dockerswarm/vars/bluebox.yml @@ -0,0 +1,21 @@ +--- +horizon_url: "https://salesdemo-sjc.openstack.blueboxgrid.com" + +auth: { + auth_url: "https://salesdemo-sjc.openstack.blueboxgrid.com:5000/v2.0", + username: "litong01", + password: "{{ password }}", + project_name: "Interop" +} + +app_env: { + image_name: "coreos", + region_name: "", + private_net_name: "interopnet", + net_device: "eth0", + flavor_name: "m1.small", + swarm_version: "latest", + swarm_size: 3, + fqdn: "swarm.example.com", + public_key_file: "/home/tong/.ssh/id_rsa.pub" +} diff --git a/ansible/dockerswarm/vars/leap.yml b/ansible/dockerswarm/vars/leap.yml new file mode 100755 index 0000000..45ae80d --- /dev/null +++ b/ansible/dockerswarm/vars/leap.yml @@ -0,0 +1,22 @@ +--- +horizon_url: "http://9.30.217.9" + +auth: { + auth_url: "http://9.30.217.9:5000/v3", + username: "demo", + password: "{{ password }}", + domain_name: "default", + project_name: "demo" +} + +app_env: { + image_name: "CoreOS", + region_name: "", + private_net_name: "Bluebox", + net_device: "eth0", + flavor_name: "m1.small", + swarm_version: "latest", + swarm_size: 3, + fqdn: "swarm.example.com", + public_key_file: "/home/tong/.ssh/id_rsa.pub" +} diff --git a/ansible/dockerswarm/vars/osic.yml b/ansible/dockerswarm/vars/osic.yml new file mode 100755 index 0000000..c9b23db --- /dev/null +++ b/ansible/dockerswarm/vars/osic.yml @@ -0,0 +1,22 @@ +--- +horizon_url: "https://cloud1.osic.org" + +auth: { + auth_url: "https://cloud1.osic.org:5000/v3", + username: "litong01", + password: "{{ password }}", + domain_name: "default", + project_name: "interop_challenge" +} + +app_env: { + image_name: "coreos", + region_name: "", + private_net_name: "interopnet", + net_device: "eth0", + flavor_name: "m1.small", + swarm_version: "latest", + swarm_size: 3, + fqdn: "swarm.example.com", + public_key_file: "/home/tong/.ssh/id_rsa.pub" +} diff --git a/ansible/dockerswarm/vars/ovh.yml b/ansible/dockerswarm/vars/ovh.yml new file mode 100755 index 0000000..e73ccd9 --- /dev/null +++ b/ansible/dockerswarm/vars/ovh.yml @@ -0,0 +1,21 @@ +--- +horizon_url: "https://horizon.cloud.ovh.net" + +auth: { + auth_url: "https://auth.cloud.ovh.net/v2.0", + username: "SXYbmFhC4aqQ", + password: "{{ password }}", + project_name: "2487610196015734" +} + +app_env: { + image_name: "coreos", + region_name: "BHS1", + private_net_name: "", + net_device: "eth0", + flavor_name: "eg-15-ssd", + swarm_version: "latest", + swarm_size: 3, + fqdn: "swarm.example.com", + public_key_file: "/home/tong/.ssh/id_rsa.pub" +} diff --git a/ansible/lampstack/.gitignore b/ansible/lampstack/.gitignore new file mode 100755 index 0000000..5ab4be3 --- /dev/null +++ b/ansible/lampstack/.gitignore @@ -0,0 +1,6 @@ +*.out +vars/* +*/**/*.log +*/**/.DS_Store +*/**/._ +*/**/*.tfstate* diff --git a/ansible/lampstack/README.md b/ansible/lampstack/README.md index 452126f..c1b9432 100755 --- a/ansible/lampstack/README.md +++ b/ansible/lampstack/README.md @@ -59,6 +59,7 @@ You may create one such file per cloud for your tests. public_key_file: "/home/ubuntu/.ssh/id_rsa.pub", stack_size: 4, volume_size: 2, + block_device_name: "/dev/vdb", wp_theme: "https://downloads.wordpress.org/theme/iribbon.2.0.65.zip", wp_posts: "http://wpcandy.s3.amazonaws.com/resources/postsxml.zip" } diff --git a/ansible/lampstack/roles/apply/tasks/main.yml b/ansible/lampstack/roles/apply/tasks/main.yml index d14d09e..ac61b83 100755 --- a/ansible/lampstack/roles/apply/tasks/main.yml +++ b/ansible/lampstack/roles/apply/tasks/main.yml @@ -1,13 +1,18 @@ --- +- name: Get start timestamp + set_fact: starttime="{{ ansible_date_time }}" + - name: Retrieve specified flavor os_flavor_facts: auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" name: "{{ app_env.flavor_name }}" - name: Create a key-pair os_keypair: state: "present" auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" name: "lampstack" public_key_file: "{{ app_env.public_key_file }}" @@ -15,6 +20,7 @@ os_volume: state: present auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" size: "{{ app_env.volume_size }}" wait: yes display_name: db_volume @@ -23,6 +29,7 @@ os_security_group: state: present auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" name: lampstack_sg description: secuirty group for lampstack @@ -30,6 +37,7 @@ os_security_group_rule: state: present auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" security_group: lampstack_sg protocol: "{{ item.protocol }}" direction: "{{ item.dir }}" @@ -49,6 +57,7 @@ os_server: state: "present" auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" name: database image: "{{ app_env.image_name }}" key_name: "lampstack" @@ -71,6 +80,7 @@ os_server: state: "present" auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" name: balancer image: "{{ app_env.image_name }}" key_name: "lampstack" @@ -93,14 +103,16 @@ os_server_volume: state: present auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" server: database volume: db_volume - device: /dev/vdb + device: "{{ app_env.block_device_name }}" - name: Create web server nodes to host application os_server: state: "present" auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" name: apache-{{ item }} image: "{{ app_env.image_name }}" key_name: "lampstack" @@ -120,8 +132,10 @@ name: "{{ item.openstack.public_v4 }}" groups: webservers with_items: "{{ webserver.results }}" + no_log: True - name: Add one web servers to wps host group add_host: name: "{{ webserver.results[0].openstack.public_v4 }}" groups: wps + no_log: True diff --git a/ansible/lampstack/roles/apply/templates/userdata.j2 b/ansible/lampstack/roles/apply/templates/userdata.j2 index d22d10c..a4079c9 100755 --- a/ansible/lampstack/roles/apply/templates/userdata.j2 +++ b/ansible/lampstack/roles/apply/templates/userdata.j2 @@ -1,4 +1,4 @@ #cloud-config runcmd: - - ip=$(ifconfig eth0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1) - - echo $ip `hostname` >> /etc/hosts \ No newline at end of file + - addr=$(ip -4 -o addr | grep -v '127.0.0.1' | awk 'NR==1{print $4}' | cut -d '/' -f 1) + - echo $addr `hostname` >> /etc/hosts \ No newline at end of file diff --git a/ansible/lampstack/roles/balancer/tasks/main.yml b/ansible/lampstack/roles/balancer/tasks/main.yml index d0901cc..968d2b4 100755 --- a/ansible/lampstack/roles/balancer/tasks/main.yml +++ b/ansible/lampstack/roles/balancer/tasks/main.yml @@ -24,8 +24,12 @@ - name: Add web servers to the haproxy lineinfile: dest: /etc/haproxy/haproxy.cfg - line: " server ws{{ item.openstack.private_v4 }} {{ item.openstack.private_v4 }}:80 check" - with_items: "{{ hostvars.cloud.webserver.results }}" + line: " server ws{{ item[0].openstack[item[1]] }} {{ item[0].openstack[item[1]] }}:80 check" + with_nested: + - "{{ hostvars.cloud.webserver.results }}" + - ["private_v4", "public_v4"] + when: item[0].openstack[item[1]] != '' + no_log: True - service: name=haproxy state=restarted enabled=yes diff --git a/ansible/lampstack/roles/cleaner/tasks/apply.yml b/ansible/lampstack/roles/cleaner/tasks/apply.yml index c3791ca..cbc3af8 100755 --- a/ansible/lampstack/roles/cleaner/tasks/apply.yml +++ b/ansible/lampstack/roles/cleaner/tasks/apply.yml @@ -1,13 +1,19 @@ --- - os_floating_ip: auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" state: absent floating_ip_address: "{{ database.openstack.public_v4 }}" server: "{{ database.openstack.name }}" + when: database.openstack.private_v4 != "" + no_log: True - os_floating_ip: auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" state: absent floating_ip_address: "{{ item.openstack.public_v4 }}" server: "{{ item.openstack.name }}" with_items: "{{ webserver.results }}" + when: item.openstack.private_v4 != "" + no_log: True \ No newline at end of file diff --git a/ansible/lampstack/roles/database/tasks/main.yml b/ansible/lampstack/roles/database/tasks/main.yml index e6a6fd1..089570d 100755 --- a/ansible/lampstack/roles/database/tasks/main.yml +++ b/ansible/lampstack/roles/database/tasks/main.yml @@ -2,32 +2,20 @@ - stat: path=/tmp/diskflag register: diskflag -- shell: parted -s /dev/vdb mklabel msdos +- shell: parted -s "{{ app_env.block_device_name }}" mklabel msdos when: diskflag.stat.exists == false -- shell: parted -s /dev/vdb mkpart primary ext4 1049kb 100% +- shell: parted -s "{{ app_env.block_device_name }}" mkpart primary ext4 1049kb 100% when: diskflag.stat.exists == false - lineinfile: dest=/tmp/diskflag line="disk is now partitioned!" create=yes -- filesystem: fstype=ext4 dev=/dev/vdb1 -- mount: name=/storage src=/dev/vdb1 fstype=ext4 state=mounted +- filesystem: fstype=ext4 dev="{{ app_env.block_device_name }}1" +- mount: name=/storage src="{{ app_env.block_device_name }}1" fstype=ext4 state=mounted -- shell: ifconfig eth0 | grep 'inet addr:' | cut -d ':' -f 2 | cut -d ' ' -f 1 +- shell: ip -4 -o addr | grep -v '127.0.0.1' | awk 'NR==1{print $4}' | cut -d '/' -f 1 register: local_ip -- name: Install sipcalc - apt: - name=sipcalc - state=latest - update_cache=yes - -- shell: sipcalc eth0 | grep 'Network address' | cut -d "-" -f 2 | xargs - register: net_addr - -- shell: sipcalc eth0 | grep 'Network mask (bits)' | cut -d "-" -f 2 | xargs - register: net_bit - - name: Creates share directory for database file: path=/storage/sqldatabase state=directory @@ -43,15 +31,20 @@ state=latest update_cache=yes -- name: Setup NFS shares +- name: Setup NFS database access lineinfile: dest: /etc/exports - line: "{{ item.name }} {{ item.net }}(rw,sync,no_root_squash,no_subtree_check)" - with_items: - - { name: "/storage/wpcontent", - net: "{{ net_addr.stdout }}/{{ net_bit.stdout }}" } - - { name: "/storage/sqldatabase", - net: "{{ net_addr.stdout }}/{{ net_bit.stdout }}" } + line: "/storage/sqldatabase {{ local_ip.stdout }}/32(rw,sync,no_root_squash,no_subtree_check)" + +- name: Setup NFS webserver access + lineinfile: + dest: /etc/exports + line: "/storage/wpcontent {{ item[0].openstack[item[1]] }}/32(rw,sync,no_root_squash,no_subtree_check)" + with_nested: + - "{{ hostvars.cloud.webserver.results }}" + - ["private_v4", "public_v4"] + when: item[0].openstack[item[1]] != '' + no_log: True - name: nfs export shell: exportfs -a diff --git a/ansible/lampstack/roles/destroy/tasks/main.yml b/ansible/lampstack/roles/destroy/tasks/main.yml index 30e3446..ae2a2c7 100755 --- a/ansible/lampstack/roles/destroy/tasks/main.yml +++ b/ansible/lampstack/roles/destroy/tasks/main.yml @@ -1,8 +1,12 @@ --- +- name: Get start timestamp + set_fact: starttime="{{ ansible_date_time }}" + - name: Delete key pairs os_keypair: state: "absent" auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" name: "lampstack" public_key_file: "{{ app_env.public_key_file }}" @@ -10,6 +14,7 @@ os_server: state: "absent" auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" name: database image: "{{ app_env.image_name }}" key_name: "lampstack" @@ -22,6 +27,7 @@ os_server: state: "absent" auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" name: balancer image: "{{ app_env.image_name }}" key_name: "lampstack" @@ -34,6 +40,7 @@ os_server: state: "absent" auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" name: apache-{{ item }} image: "{{ app_env.image_name }}" key_name: "lampstack" @@ -47,6 +54,7 @@ os_security_group: state: absent auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" name: lampstack_sg description: secuirty group for lampstack @@ -54,5 +62,6 @@ os_volume: state: absent auth: "{{ auth }}" + region_name: "{{ app_env.region_name }}" wait: yes display_name: db_volume diff --git a/ansible/lampstack/roles/webserver/tasks/main.yml b/ansible/lampstack/roles/webserver/tasks/main.yml index 273574e..908d6ef 100755 --- a/ansible/lampstack/roles/webserver/tasks/main.yml +++ b/ansible/lampstack/roles/webserver/tasks/main.yml @@ -23,12 +23,21 @@ owner: www-data group: www-data -- name: Mount the directory +- name: Mount the directory using private IP mount: name: /var/www/html/wp-content/uploads src: "{{ hostvars.cloud.database.openstack.private_v4 }}:/storage/wpcontent" state: mounted fstype: nfs + when: hostvars.cloud.database.openstack.private_v4 != "" + +- name: Mount the directory using public IP + mount: + name: /var/www/html/wp-content/uploads + src: "{{ hostvars.cloud.database.openstack.public_v4 }}:/storage/wpcontent" + state: mounted + fstype: nfs + when: hostvars.cloud.database.openstack.private_v4 == "" - lineinfile: dest=/etc/apache2/apache2.conf line="ServerName localhost" @@ -47,7 +56,7 @@ args: warn: no -- name: Configure wordpress +- name: Configure wordpress database, username and password replace: dest: /var/www/html/wp-config.php regexp: "'{{ item.then }}'" @@ -57,8 +66,22 @@ - { then: 'database_name_here', now: 'decision2016' } - { then: 'username_here', now: "{{ db_user }}" } - { then: 'password_here', now: "{{ db_pass }}" } - - { then: 'localhost', - now: "{{ hostvars.cloud.database.openstack.private_v4 }}"} + +- name: Configure wordpress network access using private IP + replace: + dest: /var/www/html/wp-config.php + regexp: "'localhost'" + replace: "'{{ hostvars.cloud.database.openstack.private_v4 }}'" + backup: no + when: hostvars.cloud.database.openstack.private_v4 != "" + +- name: Configure wordpress network access using public IP + replace: + dest: /var/www/html/wp-config.php + regexp: "'localhost'" + replace: "'{{ hostvars.cloud.database.openstack.public_v4 }}'" + backup: no + when: hostvars.cloud.database.openstack.private_v4 == "" - name: Change ownership of wordpress shell: chown -R www-data:www-data /var/www/html diff --git a/ansible/lampstack/site.yml b/ansible/lampstack/site.yml index f8bb9cd..6f16d1f 100755 --- a/ansible/lampstack/site.yml +++ b/ansible/lampstack/site.yml @@ -12,6 +12,8 @@ user: ubuntu become: true become_user: root + vars_files: + - "vars/{{ env }}.yml" roles: - database @@ -60,4 +62,8 @@ Access wordpress at http://{{ hostvars.cloud.balancer.openstack.public_v4 }}. wordpress userid is wpuser, password is {{ db_pass }} - when: hostvars.cloud.balancer is defined \ No newline at end of file + when: hostvars.cloud.balancer is defined + - debug: + msg: >- + The work load test started at {{ hostvars.cloud.starttime.time }}, + ended at {{ ansible_date_time.time }} \ No newline at end of file diff --git a/ansible/lampstack/vars/bluebox.yml b/ansible/lampstack/vars/bluebox.yml index f780d2b..025bef0 100755 --- a/ansible/lampstack/vars/bluebox.yml +++ b/ansible/lampstack/vars/bluebox.yml @@ -1,4 +1,6 @@ --- +horizon_url: "https://salesdemo-sjc.openstack.blueboxgrid.com" + auth: { auth_url: "https://salesdemo-sjc.openstack.blueboxgrid.com:5000/v2.0", username: "litong01", @@ -8,12 +10,14 @@ auth: { app_env: { image_name: "ubuntu-15.04", + region_name: "", private_net_name: "interopnet", public_net_name: "external", flavor_name: "m1.small", public_key_file: "/home/tong/.ssh/id_rsa.pub", stack_size: 4, - volume_size: 10, + volume_size: 2, + block_device_name: "/dev/vdb", wp_theme: "https://downloads.wordpress.org/theme/iribbon.2.0.65.zip", wp_posts: "http://wpcandy.s3.amazonaws.com/resources/postsxml.zip" } diff --git a/ansible/lampstack/vars/leap.yml b/ansible/lampstack/vars/leap.yml index d5af5a8..2a6f7c9 100755 --- a/ansible/lampstack/vars/leap.yml +++ b/ansible/lampstack/vars/leap.yml @@ -1,4 +1,6 @@ --- +horizon_url: "http://9.30.217.9" + auth: { auth_url: "http://9.30.217.9:5000/v3", username: "demo", @@ -8,13 +10,15 @@ auth: { } app_env: { - image_name: "vivid 1504", + image_name: "ubuntu-15.04", + region_name: "", private_net_name: "Bluebox", public_net_name: "internet", flavor_name: "m1.small", public_key_file: "/home/tong/.ssh/id_rsa.pub", stack_size: 4, volume_size: 2, + block_device_name: "/dev/vdb", wp_theme: "https://downloads.wordpress.org/theme/iribbon.2.0.65.zip", wp_posts: "http://wpcandy.s3.amazonaws.com/resources/postsxml.zip" } diff --git a/terraform/dockerswarm-coreos/README.md b/terraform/dockerswarm-coreos/README.md index 0a4f190..aba3e2a 100644 --- a/terraform/dockerswarm-coreos/README.md +++ b/terraform/dockerswarm-coreos/README.md @@ -53,6 +53,7 @@ You also want to specify the name of your CoreOS `glance` image as well as flavo ``` image_name = "coreos-alpha-884-0-0" network_name = "internal" +net_device = "eth0" floatingip_pool = "external" flavor = "m1.medium" public_key_path = "~/.ssh/id_rsa.pub" diff --git a/terraform/dockerswarm-coreos/swarm.tf b/terraform/dockerswarm-coreos/swarm.tf old mode 100644 new mode 100755 index 6342abf..a331ef3 --- a/terraform/dockerswarm-coreos/swarm.tf +++ b/terraform/dockerswarm-coreos/swarm.tf @@ -30,6 +30,9 @@ resource "template_file" "cloud_init" { resource "template_file" "10_docker_service" { template = "templates/10-docker-service.conf" + vars { + net_device = "${ var.net_device }" + } } resource "openstack_networking_floatingip_v2" "coreos" { diff --git a/terraform/dockerswarm-coreos/templates/10-docker-service.conf b/terraform/dockerswarm-coreos/templates/10-docker-service.conf old mode 100644 new mode 100755 index 9c99d85..21fd9c8 --- a/terraform/dockerswarm-coreos/templates/10-docker-service.conf +++ b/terraform/dockerswarm-coreos/templates/10-docker-service.conf @@ -1,2 +1,2 @@ [Service] -Environment="DOCKER_OPTS=-H=0.0.0.0:2376 -H unix:///var/run/docker.sock --tlsverify --tlscacert=/etc/docker/ssl/ca.pem --tlscert=/etc/docker/ssl/cert.pem --tlskey=/etc/docker/ssl/key.pem --cluster-advertise eth0:2376 --cluster-store etcd://127.0.0.1:2379/docker" +Environment="DOCKER_OPTS=-H=0.0.0.0:2376 -H unix:///var/run/docker.sock --tlsverify --tlscacert=/etc/docker/ssl/ca.pem --tlscert=/etc/docker/ssl/cert.pem --tlskey=/etc/docker/ssl/key.pem --cluster-advertise ${net_device}:2376 --cluster-store etcd://127.0.0.1:2379/docker" diff --git a/terraform/dockerswarm-coreos/vars-openstack.tf b/terraform/dockerswarm-coreos/vars-openstack.tf index 9dcf312..1e2addd 100644 --- a/terraform/dockerswarm-coreos/vars-openstack.tf +++ b/terraform/dockerswarm-coreos/vars-openstack.tf @@ -10,6 +10,11 @@ variable "floatingip_pool" { default = "external" } +variable "net_device" { + description = "Network interface device in the system" + default = "eth0" +} + variable "flavor" { default = "m1.medium" }