diff --git a/group_vars/all.example b/group_vars/all.example index ae1942a..0848d08 100644 --- a/group_vars/all.example +++ b/group_vars/all.example @@ -12,7 +12,8 @@ chosen_timezone: "America/New_York" # this will allow automatic dns for for things like dokuwiki.test.com and portainer.test.com root_domain: test.com - +# interface for the swarm network +swarm_network_interface: eth1 ### Persistent storage if you are doing a single machine deploy, local is an option. If you are doing multi instance deploy, choose one of the following: # nfs diff --git a/playbooks/site.yml b/playbooks/site.yml index 30930e0..8d4883a 100644 --- a/playbooks/site.yml +++ b/playbooks/site.yml @@ -19,6 +19,8 @@ tasks: - include: ../roles/common/tasks/main.yml +- import_playbook: swarm.yml + # - name: Deploy startup-infrastructure swarm stack # hosts: bootstrap # user: root diff --git a/playbooks/swarm.yml b/playbooks/swarm.yml new file mode 100644 index 0000000..3184402 --- /dev/null +++ b/playbooks/swarm.yml @@ -0,0 +1,64 @@ +--- +- name: Initialize the swarm + hosts: bootstrap + user: root + gather_facts: true + serial: 100% + tasks: + - name: Print ansible interfaces + debug: + msg: "{{ ansible_interfaces }}" + + # - name: Get ip of swarm_network_interface by parsing all interfaces + # set_fact: + # swarm_init_ip={{hostvars[inventory_hostname]['ansible_item']['ipv4']['address']}} + # when: (item == swarm_network_interface) + # with_items: + # - "{{ ansible_interfaces }}" + - name: Set interface var name fact + set_fact: + swarm_interface_var_name: "ansible_{{ swarm_network_interface }}" + + - name: Set swarm advertise ip address + set_fact: + swarm_init_ip: "{{ hostvars[inventory_hostname][swarm_interface_var_name]['ipv4']['address'] }}" + + - name: Print swarm init ip address + debug: + msg: "{{ swarm_init_ip }}" + + - include_tasks: ../tasks/swarm-bootstrap.yml + vars: + join_addr: "{{ swarm_init_ip }}" + +- name: Add additional managers to the swarm + hosts: managers + user: root + gather_facts: false + serial: 100% + vars: + manager_join_key: + "{{ hostvars[groups['bootstrap'][0]]['manager_key']['stdout'] }}" + swarm_init_ip: + "{{ hostvars[groups['bootstrap'][0]]['swarm_init_ip'] }}" + tasks: + - include_tasks: ../tasks/swarm-join.yml + vars: + join_addr: "{{ swarm_init_ip }}" + join_key: "{{ manager_join_key }}" + +- name: Add workers to the swarm + hosts: workers + user: root + gather_facts: false + serial: 100% + vars: + worker_join_key: + "{{ hostvars[groups['bootstrap'][0]]['worker_key']['stdout'] }}" + swarm_init_ip: + "{{ hostvars[groups['bootstrap'][0]]['swarm_init_ip'] }}" + tasks: + - include_tasks: ../tasks/swarm-join.yml + vars: + join_addr: "{{ swarm_init_ip }}" + join_key: "{{ worker_join_key }}" \ No newline at end of file diff --git a/tasks/swarm-bootstrap.yml b/tasks/swarm-bootstrap.yml index 410f309..14ad10c 100644 --- a/tasks/swarm-bootstrap.yml +++ b/tasks/swarm-bootstrap.yml @@ -1,22 +1,23 @@ ---- -- name: Initialize swarm on the bootstrap manager - command: > - docker swarm init --advertise-addr "{{ ansible_eth1.ipv4.address }}" - register: docker_swarm_init - changed_when: docker_swarm_init.rc == 0 - ignore_errors: true - -- name: Set manager key variable - command: docker swarm join-token -q manager - register: manager_key - changed_when: manager_key.rc == 0 - -- name: Set worker key variable - command: docker swarm join-token -q worker - register: worker_key - changed_when: worker_key.rc == 0 - -- name: Set work and manager key facts - set_fact: - manager_key: "{{ manager_key }}" - worker_key: "{{ worker_key }}" \ No newline at end of file +--- +- name: Initialize swarm on the bootstrap manager + command: > + docker swarm init --advertise-addr "{{ join_addr }}" + register: docker_swarm_init + changed_when: docker_swarm_init.rc == 0 + ignore_errors: true + +- name: Set manager key variable + command: docker swarm join-token -q manager + register: manager_key + changed_when: manager_key.rc == 0 + +- name: Set worker key variable + command: docker swarm join-token -q worker + register: worker_key + changed_when: worker_key.rc == 0 + +- name: Set work and manager key facts + set_fact: + manager_key: "{{ manager_key }}" + worker_key: "{{ worker_key }}" + swarm_init_ip: "{{ join_addr }}" \ No newline at end of file diff --git a/tasks/swarm-join.yml b/tasks/swarm-join.yml new file mode 100644 index 0000000..a43c01a --- /dev/null +++ b/tasks/swarm-join.yml @@ -0,0 +1,7 @@ +--- +- name: Add swarm node to the cluster + command: > + docker swarm join --token "{{ join_key }}" "{{ join_addr }}":2377 + register: docker_swarm_join + changed_when: docker_swarm_join.rc == 0 + ignore_errors: true \ No newline at end of file diff --git a/tests/files/group_vars_all b/tests/files/group_vars_all index ae1942a..336cc02 100644 --- a/tests/files/group_vars_all +++ b/tests/files/group_vars_all @@ -12,7 +12,8 @@ chosen_timezone: "America/New_York" # this will allow automatic dns for for things like dokuwiki.test.com and portainer.test.com root_domain: test.com - +# interface for the swarm network +swarm_network_interface: enp0s8 ### Persistent storage if you are doing a single machine deploy, local is an option. If you are doing multi instance deploy, choose one of the following: # nfs diff --git a/tests/lib/test-function.sh b/tests/lib/test-function.sh index 910c060..8e2f285 100644 --- a/tests/lib/test-function.sh +++ b/tests/lib/test-function.sh @@ -5,7 +5,7 @@ green=`tput setaf 2` reset=`tput sgr0` #echo "${red}red text ${green}green text${reset}" -function test { +function testbash() { local name="${1}" shift local command="${@}" diff --git a/tests/vagrant-tests.sh b/tests/vagrant-tests.sh index 1009523..5f1929d 100644 --- a/tests/vagrant-tests.sh +++ b/tests/vagrant-tests.sh @@ -8,19 +8,42 @@ function main { run-tests destroy-infrastructure } + function run-tests { trap "destroy-infrastructure; exit 1" ERR echo Building vagrant infrastructure vagrant up - test "Running command on a vagrant node should not fail." \ + testbash "Running command on a vagrant node should not fail." \ "vagrant ssh client -c 'ls /vagrant'" - test "Client vagrant machine can ssh into bootstrap." \ + testbash "Client vagrant machine can ssh into bootstrap." \ "vagrant ssh client -c 'ssh -o StrictHostKeyChecking=no -i /home/vagrant/test_rsa vagrant@192.168.254.2 ls'" - test "Running deploy script should not fail." \ + testbash "Running deploy script should not fail." \ "vagrant ssh client -c 'bash /vagrant/tests/files/run-test-deploy.sh'" + + local -r node_ls_output=$(vagrant ssh bootstrap \ + -c "docker node ls --format '{{.Hostname}} {{.Status}} {{.Availability}} {{.ManagerStatus}}'" + ) + echo docker node ls output is: + echo $node_ls_output + local -r number_of_docker_leaders=$(echo "${node_ls_output}" \ + | grep -v 'Connection' \ + | awk '{ print $4 }' \ + | grep '^Leader$' \ + | wc -l) + local -r number_of_docker_nodes=$(echo "${node_ls_output}" \ + | grep -v 'Connection' \ + | awk '{ print $1 }' \ + | wc -l) + + testbash "There are 2 docker swarm nodes" \ + "test ${number_of_docker_nodes} -eq 2" + + testbash "The swarm has a leader" \ + "test ${number_of_docker_leaders} -eq 1" + } function destroy-infrastructure {