--- # Docker Swarm Deployment Playbook # This playbook initializes Docker Swarm cluster and deploys services - name: Initialize Docker Swarm Manager hosts: swarm_managers become: yes gather_facts: yes tasks: - name: Check if Docker Swarm is already initialized command: docker info --format "{{ '{{' }}.Swarm.LocalNodeState{{ '}}' }}" register: swarm_status_check changed_when: false failed_when: false - name: Initialize Docker Swarm command: docker swarm init --advertise-addr 192.168.56.10 register: swarm_init_result changed_when: swarm_init_result.rc == 0 failed_when: swarm_init_result.rc not in [0, 1] when: swarm_status_check.stdout != "active" - name: Get worker join token command: docker swarm join-token worker register: worker_token_result changed_when: false - name: Extract worker join command set_fact: worker_join_token: "{{ worker_token_result.stdout_lines[2] }}" - name: Display worker join command debug: msg: "Worker join command: {{ worker_join_token }}" - name: Get manager join token command: docker swarm join-token manager register: manager_token_result changed_when: false - name: Display manager join command debug: msg: "Manager join command: {{ manager_token_result.stdout_lines[2] }}" - name: Copy Docker Compose stack file copy: src: docker-stack.yml dest: /home/vagrant/docker-stack.yml mode: '0644' - name: Deploy Docker Swarm stack command: docker stack deploy -c docker-stack.yml swarm-stack register: stack_result changed_when: stack_result.rc == 0 failed_when: stack_result.rc not in [0, 1] - name: Check Docker Swarm status command: docker node ls register: swarm_status changed_when: false - name: Display Swarm status debug: msg: "{{ swarm_status.stdout_lines }}" - name: Check Docker stack services command: docker stack services swarm-stack register: services_status changed_when: false - name: Display stack services status debug: msg: "{{ services_status.stdout_lines }}" - name: Join Docker Swarm Workers hosts: swarm_workers become: yes gather_facts: no tasks: - name: Join Docker Swarm as worker command: "{{ hostvars[groups['swarm_managers'][0]]['worker_join_token'] | replace('10.0.2.15:2377', '192.168.56.10:2377') }}" register: join_result changed_when: join_result.rc == 0 failed_when: join_result.rc not in [0, 1] - name: Verify node joined successfully command: docker node ls register: node_status changed_when: false ignore_errors: yes - name: Display node status debug: msg: "{{ node_status.stdout_lines if node_status.rc == 0 else 'Node not accessible' }}" - name: Verify Docker Swarm Cluster hosts: swarm_managers become: yes gather_facts: no tasks: - name: Wait for all nodes to be ready command: docker node ls register: nodes_check until: nodes_check.stdout_lines | length >= 5 # Header + 4 nodes retries: 10 delay: 5 changed_when: false - name: Check all nodes are active command: docker node ls --format "{{ '{{' }}.Status{{ '}}' }}" register: node_statuses changed_when: false - name: Verify all nodes are ready assert: that: - "'Ready' in node_statuses.stdout" - "'Active' in node_statuses.stdout" fail_msg: "Not all nodes are ready and active" - name: Check stack service health command: docker stack services swarm-stack --format "table {{.Name}}\t{{.Replicas}}" register: service_replicas changed_when: false - name: Display stack service replicas debug: msg: "{{ service_replicas.stdout_lines }}" - name: Create cluster info file copy: content: | Docker Swarm Cluster Information ================================ Manager: {{ groups['swarm_managers'][0] }} Workers: {{ groups['swarm_workers'] | join(', ') }} Total Nodes: {{ groups['swarm_nodes'] | length }} Services Deployed: - Portainer (Management UI): http://{{ ansible_default_ipv4.address }}:9000 - Traefik Dashboard: http://{{ ansible_default_ipv4.address }}:8080 - Web Application: http://{{ ansible_default_ipv4.address }} Network: swarm-network (overlay) Created: {{ ansible_date_time.iso8601 }} dest: /opt/swarm-cluster-info.txt mode: '0644' - name: Display cluster information command: cat /opt/swarm-cluster-info.txt register: cluster_info changed_when: false - name: Show cluster information debug: msg: "{{ cluster_info.stdout_lines }}"