├── roles ├── ansible-etc-hosts │ ├── tests │ │ ├── inventory │ │ └── test.yml │ ├── vars │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── defaults │ │ └── main.yml │ ├── .travis.yml │ ├── tasks │ │ └── main.yml │ ├── README.md │ ├── meta │ │ └── main.yml │ └── templates │ │ └── etc │ │ └── hosts.j2 ├── ansible-docker-swarm │ ├── tests │ │ ├── inventory │ │ └── test.yml │ ├── vars │ │ └── main.yml │ ├── handlers │ │ └── main.yml │ ├── requirements.yml │ ├── tasks │ │ ├── debian.yml │ │ ├── redhat.yml │ │ ├── pre-reqs.yml │ │ ├── main.yml │ │ ├── settings.yml │ │ ├── networks.yml │ │ └── cluster.yml │ ├── .travis.yml │ ├── defaults │ │ └── main.yml │ ├── README.md │ └── meta │ │ └── main.yml └── ansible-docker │ ├── tests │ ├── inventory │ └── test.yml │ ├── vars │ └── main.yml │ ├── templates │ └── etc │ │ ├── default │ │ └── docker.j2 │ │ ├── docker │ │ ├── daemon.json.j2 │ │ └── daemon.json.j2.orig │ │ └── yum.repos.d │ │ └── docker.repo.j2 │ ├── handlers │ └── main.yml │ ├── tasks │ ├── service.yml │ ├── users.yml │ ├── images.yml │ ├── alpine.yml │ ├── config_docker.yml │ ├── main.yml │ ├── redhat.yml │ ├── manage_python_modules.yml │ ├── debian.yml │ └── set_facts.yml │ ├── meta │ └── main.yml │ ├── .travis.yml │ ├── LICENSE │ ├── defaults │ └── main.yml │ └── README.md ├── group_vars ├── all │ ├── all.yml │ └── etc-hosts.yml └── docker-nodes │ └── docker.yml ├── hosts ├── .gitignore ├── cleanup.sh ├── requirements.yml ├── playbook.yml ├── bootstrap.sh ├── docker-management.py ├── README.md ├── nodes.yml ├── Vagrantfile ├── bootstrap.yml └── ansible.cfg /roles/ansible-etc-hosts/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost -------------------------------------------------------------------------------- /roles/ansible-docker/tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | -------------------------------------------------------------------------------- /group_vars/all/all.yml: -------------------------------------------------------------------------------- 1 | --- 2 | pri_domain_name: 'test.vagrant.local' 3 | -------------------------------------------------------------------------------- /group_vars/docker-nodes/docker.yml: -------------------------------------------------------------------------------- 1 | --- 2 | docker_version: 18.03.1 3 | -------------------------------------------------------------------------------- /hosts: -------------------------------------------------------------------------------- 1 | .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory -------------------------------------------------------------------------------- /roles/ansible-docker/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for ansible-docker 3 | -------------------------------------------------------------------------------- /roles/ansible-etc-hosts/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for ansible-etc-hosts 3 | -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/vars/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # vars file for ansible-docker-swarm 3 | -------------------------------------------------------------------------------- /roles/ansible-etc-hosts/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for ansible-etc-hosts 3 | -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for ansible-docker-swarm 3 | -------------------------------------------------------------------------------- /roles/ansible-docker/templates/etc/default/docker.j2: -------------------------------------------------------------------------------- 1 | DOCKER_OPTS="--config-file=/etc/docker/daemon.json" 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant 2 | host_vars/ 3 | # group_vars/ 4 | *.retry 5 | .galaxy_install_info 6 | *cloudimg-console.log 7 | -------------------------------------------------------------------------------- /roles/ansible-etc-hosts/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - ansible-etc-hosts -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | remote_user: root 4 | roles: 5 | - ansible-docker-swarm -------------------------------------------------------------------------------- /roles/ansible-docker/templates/etc/docker/daemon.json.j2: -------------------------------------------------------------------------------- 1 | {% if docker_opts is defined %} 2 | {{ docker_opts|to_nice_json }} 3 | {% endif %} 4 | -------------------------------------------------------------------------------- /group_vars/all/etc-hosts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | etc_hosts_add_all_hosts: true 3 | etc_hosts_pri_dns_name: '{{ pri_domain_name }}' 4 | etc_hosts_static_ip: true 5 | -------------------------------------------------------------------------------- /cleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | vagrant destroy -f 3 | if [ -d host_vars ]; then 4 | rm -rf host_vars 5 | fi 6 | if [ -d .vagrant ]; then 7 | rm -rf .vagrant 8 | fi 9 | -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - src: https://github.com/mrlesmithjr/ansible-docker.git 3 | - src: https://github.com/mrlesmithjr/ansible-docker-swarm.git 4 | -------------------------------------------------------------------------------- /roles/ansible-docker/tests/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | connection: local 4 | remote_user: root 5 | vars: 6 | roles: 7 | - role: ansible-docker 8 | tasks: 9 | -------------------------------------------------------------------------------- /roles/ansible-docker/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # handlers file for ansible-docker 3 | - name: restart docker 4 | service: 5 | name: "docker" 6 | state: restarted 7 | become: true 8 | -------------------------------------------------------------------------------- /requirements.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - src: https://github.com/mrlesmithjr/ansible-docker.git 3 | - src: https://github.com/mrlesmithjr/ansible-docker-swarm.git 4 | - src: https://github.com/mrlesmithjr/ansible-etc-hosts.git 5 | -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/tasks/debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: debian | Installing Pre-Reqs 3 | apt: 4 | name: "python-pip" 5 | state: "present" 6 | become: true 7 | when: ansible_os_family == "Debian" 8 | -------------------------------------------------------------------------------- /roles/ansible-docker/tasks/service.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: service | Ensuring Docker Service Is Started And Enabled On Boot 3 | service: 4 | name: "docker" 5 | state: "started" 6 | enabled: yes 7 | become: true 8 | -------------------------------------------------------------------------------- /roles/ansible-docker/tasks/users.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: users | adding docker users (for use without sudo) 3 | user: 4 | name: "{{ item }}" 5 | append: yes 6 | groups: docker 7 | become: true 8 | with_items: '{{ docker_users }}' 9 | -------------------------------------------------------------------------------- /playbook.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | roles: 4 | - role: ansible-etc-hosts 5 | 6 | - hosts: docker-nodes 7 | roles: 8 | - role: ansible-docker 9 | 10 | - hosts: docker-nodes 11 | roles: 12 | - role: ansible-docker-swarm 13 | -------------------------------------------------------------------------------- /roles/ansible-docker/tasks/images.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: images | ensuring docker images are present 3 | docker_image: 4 | name: "{{ item['name'] }}" 5 | state: "{{ item['state'] }}" 6 | become: true 7 | with_items: '{{ docker_images }}' 8 | -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/tasks/redhat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: redhat | Installing EPEL Repo (RedHat) 3 | yum: 4 | name: "epel-release" 5 | state: "present" 6 | become: true 7 | when: > 8 | ansible_os_family == "RedHat" and 9 | ansible_distribution != "Fedora" 10 | -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/tasks/pre-reqs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: pre-reqs | Installing Python Pre-Reqs 3 | pip: 4 | name: "{{ item }}" 5 | state: "present" 6 | become: true 7 | with_items: 8 | - 'docker-py' 9 | 10 | - name: pre-reqs | Ensuring Docker Engine Is Running 11 | service: 12 | name: "docker" 13 | state: "started" 14 | become: true 15 | -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for ansible-docker-swarm 3 | 4 | - include: debian.yml 5 | when: ansible_os_family == "Debian" 6 | 7 | - include: redhat.yml 8 | when: ansible_os_family == "RedHat" 9 | 10 | - include: pre-reqs.yml 11 | 12 | - include: cluster.yml 13 | 14 | - include: networks.yml 15 | when: > 16 | docker_swarm_config_networks and 17 | docker_swarm_networks is defined 18 | 19 | - include: settings.yml 20 | when: docker_swarm_config_settings 21 | -------------------------------------------------------------------------------- /roles/ansible-docker/meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: Larry Smith Jr. 4 | description: An [Ansible](https://www.ansible.com) role to install/configure [Docker](https://www.docker.com) 5 | 6 | license: license (MIT) 7 | min_ansible_version: 1.2 8 | 9 | platforms: 10 | - name: EL 11 | versions: 12 | - 7 13 | - name: Ubuntu 14 | versions: 15 | - precise 16 | - trusty 17 | - xenial 18 | - zesty 19 | - name: Debian 20 | versions: 21 | - jessie 22 | - stretch 23 | 24 | categories: 25 | - cloud 26 | - development 27 | - packaging 28 | - system 29 | dependencies: [] 30 | -------------------------------------------------------------------------------- /roles/ansible-docker/tasks/alpine.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: alpine | Ensuring Edge Repo Is Enabled 3 | lineinfile: 4 | path: "/etc/apk/repositories" 5 | regexp: "^http://dl-cdn.alpinelinux.org/alpine/edge/community" 6 | line: "http://dl-cdn.alpinelinux.org/alpine/edge/community" 7 | state: "present" 8 | register: "_apk_repos_updated" 9 | become: true 10 | 11 | - name: alpine | Updating APK Cache 12 | apk: 13 | update_cache: true 14 | become: true 15 | when: _apk_repos_updated['changed'] 16 | 17 | - name: alpine | Installing Docker 18 | apk: 19 | name: "docker" 20 | state: "present" 21 | become: true 22 | -------------------------------------------------------------------------------- /roles/ansible-etc-hosts/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for ansible-etc-hosts 3 | # Defines if all nodes in play should be added to each hosts /etc/hosts 4 | etc_hosts_add_all_hosts: false 5 | 6 | # Defines if ipv6 info is included in /etc/hosts 7 | etc_hosts_enable_ipv6: true 8 | 9 | # Defines your primary dns suffix 10 | etc_hosts_pri_dns_name: 'vagrant.local' 11 | 12 | # Defines if node has static IP. 13 | etc_hosts_static_ip: false 14 | 15 | # Defines if ansible_host is used for defining hosts 16 | etc_hosts_use_ansible_ssh_host: true 17 | 18 | # Defines if ansible_default_ipv4.address is used for defining hosts 19 | etc_hosts_use_default_ip_address: false 20 | -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | python: "2.7" 4 | 5 | # Use the new container infrastructure 6 | sudo: false 7 | 8 | # Install ansible 9 | addons: 10 | apt: 11 | packages: 12 | - python-pip 13 | 14 | install: 15 | # Install ansible 16 | - pip install ansible 17 | 18 | # Check ansible version 19 | - ansible --version 20 | 21 | # Create ansible.cfg with correct roles_path 22 | - printf '[defaults]\nroles_path=../' >ansible.cfg 23 | 24 | script: 25 | # Basic role syntax check 26 | - ansible-playbook tests/test.yml -i tests/inventory --syntax-check 27 | 28 | notifications: 29 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ -------------------------------------------------------------------------------- /roles/ansible-etc-hosts/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | python: "2.7" 4 | 5 | # Use the new container infrastructure 6 | sudo: false 7 | 8 | # Install ansible 9 | addons: 10 | apt: 11 | packages: 12 | - python-pip 13 | 14 | install: 15 | # Install ansible 16 | - pip install ansible 17 | 18 | # Check ansible version 19 | - ansible --version 20 | 21 | # Create ansible.cfg with correct roles_path 22 | - printf '[defaults]\nroles_path=../' >ansible.cfg 23 | 24 | script: 25 | # Basic role syntax check 26 | - ansible-playbook tests/test.yml -i tests/inventory --syntax-check 27 | 28 | notifications: 29 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ -------------------------------------------------------------------------------- /roles/ansible-docker/tasks/config_docker.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: config_docker | Configuring Docker Service (Debian) 3 | template: 4 | src: "etc/default/docker.j2" 5 | dest: "/etc/default/docker" 6 | owner: "root" 7 | group: "root" 8 | mode: 0644 9 | notify: "restart docker" 10 | become: true 11 | when: ansible_os_family == "Debian" 12 | 13 | - name: config_docker | Ensuring /etc/docker Folder Exists 14 | file: 15 | path: "/etc/docker" 16 | state: "directory" 17 | become: true 18 | 19 | - name: config_docker | Configuring Docker 20 | template: 21 | src: "etc/docker/daemon.json.j2" 22 | dest: "/etc/docker/daemon.json" 23 | notify: "restart docker" 24 | become: true 25 | -------------------------------------------------------------------------------- /roles/ansible-etc-hosts/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for ansible-etc-hosts 3 | - name: pre-reqs (RedHat) 4 | yum: 5 | name: "{{ item }}" 6 | state: "present" 7 | become: true 8 | with_items: 9 | - libselinux-python 10 | when: > 11 | ansible_os_family == "RedHat" and 12 | ansible_distribution != "Fedora" 13 | 14 | - name: pre-reqs (RedHat) 15 | dnf: 16 | name: "{{ item }}" 17 | state: "present" 18 | become: true 19 | with_items: 20 | - libselinux-python 21 | when: > 22 | ansible_os_family == "RedHat" and 23 | ansible_distribution == "Fedora" 24 | 25 | - name: main | updating /etc/hosts (localhost) 26 | template: 27 | src: "etc/hosts.j2" 28 | dest: "/etc/hosts" 29 | owner: root 30 | group: root 31 | mode: 0644 32 | become: true 33 | -------------------------------------------------------------------------------- /roles/ansible-docker/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # tasks file for ansible-docker 3 | - include: set_facts.yml 4 | 5 | - include: alpine.yml 6 | when: ansible_os_family == "Alpine" 7 | 8 | - include: debian.yml 9 | when: ansible_os_family == "Debian" 10 | 11 | - include: redhat.yml 12 | when: ansible_os_family == "RedHat" 13 | 14 | - include: config_docker.yml 15 | when: docker_config_service 16 | 17 | - include: service.yml 18 | 19 | - include: users.yml 20 | when: > 21 | docker_config_users is defined and 22 | docker_config_users 23 | 24 | - include: manage_python_modules.yml 25 | when: > 26 | docker_manage_python_modules is defined and 27 | docker_manage_python_modules 28 | 29 | - include: images.yml 30 | when: > 31 | docker_manage_images and 32 | docker_images is defined 33 | -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/tasks/settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: settings | Updating Docker Swarm Dispatch Heartbeat Duration 3 | command: "docker swarm update --dispatcher-heartbeat {{ docker_swarm_dispatcher_heartbeat_duration }}" 4 | become: true 5 | when: > 6 | inventory_hostname == docker_swarm_primary_manager 7 | 8 | - name: settings | Updating Docker Swarm Certificate Expiry Duration 9 | command: "docker swarm update --cert-expiry {{ docker_swarm_cert_expiry }}" 10 | become: true 11 | when: > 12 | inventory_hostname == docker_swarm_primary_manager 13 | 14 | - name: settings | Updating Docker Swarm Task History Limit 15 | command: "docker swarm update --task-history-limit {{ docker_swarm_task_history_limit }}" 16 | become: true 17 | when: > 18 | inventory_hostname == docker_swarm_primary_manager 19 | -------------------------------------------------------------------------------- /roles/ansible-docker/.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: python 3 | python: "2.7" 4 | 5 | # Use the new container infrastructure 6 | sudo: required 7 | 8 | # Install ansible 9 | addons: 10 | apt: 11 | packages: 12 | - python-pip 13 | 14 | install: 15 | # Install ansible 16 | - pip install ansible 17 | 18 | # Check ansible version 19 | - ansible --version 20 | 21 | # Create ansible.cfg with correct roles_path 22 | - printf '[defaults]\nroles_path=../' >ansible.cfg 23 | 24 | script: 25 | # Basic role syntax check 26 | - ansible-playbook tests/test.yml -i tests/inventory --syntax-check 27 | # Install role 28 | # - ansible-playbook tests/test.yml -i tests/inventory 29 | # # Check idempotence 30 | # - "ansible-playbook tests/test.yml -i tests/inventory | grep -q 'changed=0.*failed=0' && (echo 'Idempotence test: pass' && exit 0) || (echo 'Idempotence test: fail' && exit 1)" 31 | 32 | notifications: 33 | webhooks: https://galaxy.ansible.com/api/v1/notifications/ 34 | -------------------------------------------------------------------------------- /roles/ansible-docker/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Larry Smith Jr. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /roles/ansible-docker/templates/etc/yum.repos.d/docker.repo.j2: -------------------------------------------------------------------------------- 1 | [docker-ce-{{ docker_release_channel }}] 2 | name=Docker CE {{ docker_release_channel }} - $basearch 3 | baseurl=https://download.docker.com/linux/{{ ansible_distribution|lower }}/{{ ansible_distribution_major_version }}/$basearch/{{ docker_release_channel }} 4 | enabled=1 5 | gpgcheck=1 6 | gpgkey=https://download.docker.com/linux/{{ ansible_distribution|lower }}/gpg 7 | 8 | [docker-ce-{{ docker_release_channel }}-debuginfo] 9 | name=Docker CE {{ docker_release_channel }} - Debuginfo $basearch 10 | baseurl=https://download.docker.com/linux/{{ ansible_distribution|lower }}/{{ ansible_distribution_major_version }}/debug-$basearch/{{ docker_release_channel }} 11 | enabled=0 12 | gpgcheck=1 13 | gpgkey=https://download.docker.com/linux/{{ ansible_distribution|lower }}/gpg 14 | 15 | [docker-ce-{{ docker_release_channel }}-source] 16 | name=Docker CE {{ docker_release_channel }} - Sources 17 | baseurl=https://download.docker.com/linux/{{ ansible_distribution|lower }}/{{ ansible_distribution_major_version }}/source/{{ docker_release_channel }} 18 | enabled=0 19 | gpgcheck=1 20 | gpgkey=https://download.docker.com/linux/{{ ansible_distribution|lower }}/gpg 21 | -------------------------------------------------------------------------------- /roles/ansible-etc-hosts/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | An [Ansible] role that Configures /etc/hosts 5 | 6 | Requirements 7 | ------------ 8 | 9 | None 10 | 11 | Role Variables 12 | -------------- 13 | 14 | ``` 15 | --- 16 | # defaults file for ansible-etc-hosts 17 | # Defines if all nodes in play should be added to each hosts /etc/hosts 18 | etc_hosts_add_all_hosts: false 19 | 20 | # Defines if ipv6 info is included in /etc/hosts 21 | etc_hosts_enable_ipv6: true 22 | 23 | # Defines your primary dns suffix 24 | etc_hosts_pri_dns_name: 'vagrant.local' 25 | 26 | # Defines if node has static IP. 27 | etc_hosts_static_ip: false 28 | 29 | # Defines if ansible_host is used for defining hosts 30 | etc_hosts_use_ansible_ssh_host: true 31 | 32 | # Defines if ansible_default_ipv4.address is used for defining hosts 33 | etc_hosts_use_default_ip_address: false 34 | ``` 35 | 36 | Dependencies 37 | ------------ 38 | 39 | None 40 | 41 | Example Playbook 42 | ---------------- 43 | 44 | ``` 45 | - hosts: all 46 | become: true 47 | vars: 48 | roles: 49 | - role: ansible-etc-hosts 50 | ``` 51 | 52 | License 53 | ------- 54 | 55 | BSD 56 | 57 | Author Information 58 | ------------------ 59 | 60 | Larry Smith Jr. 61 | - @mrlesmithjr 62 | - http://everythingshouldbevirtual.com 63 | - mrlesmithjr [at] gmail.com 64 | 65 | [Ansible]: 66 | -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for ansible-docker-swarm 3 | docker_swarm_addr: "{{ hostvars[inventory_hostname]['ansible_' + docker_swarm_interface]['ipv4']['address'] }}" 4 | 5 | # Validity period for node certificates (default 2160h0m0s) 6 | docker_swarm_cert_expiry: '2160h0m0s' 7 | 8 | # Dispatcher heartbeat period (default 5s) 9 | docker_swarm_dispatcher_heartbeat_duration: '5s' 10 | 11 | docker_swarm_interface: "enp0s8" 12 | # docker_swarm_managers_ansible_group: 'docker-swarm-managers' 13 | 14 | docker_swarm_config_networks: false 15 | docker_swarm_config_settings: false 16 | 17 | # Define Ansible group which contains your Docker swarm managers 18 | docker_swarm_managers_ansible_group: 'docker-swarm-managers' 19 | 20 | docker_swarm_networks: [] 21 | # - name: 'my_net' 22 | # driver: 'overlay' 23 | # state: 'present' 24 | # - name: 'test' 25 | # driver: 'overlay' 26 | # state: 'absent' 27 | docker_swarm_port: "2377" 28 | 29 | # Defines first node in docker_swarm_managers_ansible_group as primary 30 | docker_swarm_primary_manager: '{{ groups[docker_swarm_managers_ansible_group][0] }}' 31 | 32 | # Task history retention limit (default 5) 33 | docker_swarm_task_history_limit: '5' 34 | 35 | # Define Ansible group which contains you Docker swarm workers 36 | docker_swarm_workers_ansible_group: 'docker-swarm-workers' 37 | -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/tasks/networks.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: networks | Capturing Docker Swarm Networks 3 | command: "docker network ls" 4 | changed_when: false 5 | register: "docker_networks" 6 | become: true 7 | when: > 8 | inventory_hostname == docker_swarm_primary_manager 9 | 10 | - name: networks | Creating Docker Swarm Networks 11 | command: "docker network create --driver {{ item.driver }} {{ item.name }}" 12 | become: true 13 | with_items: '{{ docker_swarm_networks }}' 14 | when: > 15 | inventory_hostname == docker_swarm_primary_manager and 16 | item.state|lower == "present" and 17 | item.name not in docker_networks.stdout 18 | 19 | - name: networks | Removing Docker Swarm Networks 20 | command: "docker network rm {{ item.name }}" 21 | become: true 22 | with_items: '{{ docker_swarm_networks }}' 23 | when: > 24 | inventory_hostname == docker_swarm_primary_manager and 25 | item.state|lower == "absent" and 26 | item.name in docker_networks.stdout 27 | 28 | ## Below is for Ansible 2.2 29 | # - name: docker_swarm | Managing Docker Swarm Networks 30 | # docker_network: 31 | # name: "{{ item.name }}" 32 | # driver: "{{ item.driver }}" 33 | # state: "{{ item.state }}" 34 | # with_items: '{{ docker_swarm_networks }}' 35 | # when: > 36 | # inventory_hostname == docker_swarm_primary_manager 37 | -------------------------------------------------------------------------------- /roles/ansible-docker/tasks/redhat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: redhat | Installing Pre-Reqs (Fedora) 3 | dnf: 4 | name: "{{ item }}" 5 | state: "present" 6 | become: true 7 | with_items: 8 | - 'device-mapper-persistent-data' 9 | - 'libselinux-python' 10 | - 'lvm2' 11 | - 'yum-utils' 12 | when: ansible_distribution == "Fedora" 13 | 14 | - name: redhat | Installing Pre-Reqs (!=Fedora) 15 | yum: 16 | name: "{{ item }}" 17 | state: "present" 18 | become: true 19 | with_items: 20 | - 'device-mapper-persistent-data' 21 | - 'libselinux-python' 22 | - 'lvm2' 23 | - 'yum-utils' 24 | when: ansible_distribution != "Fedora" 25 | 26 | - name: redhat | Uninstalling Old Docker Package (if exists) 27 | yum: 28 | name: "{{ item }}" 29 | state: "absent" 30 | become: true 31 | with_items: 32 | - 'container-selinux' 33 | - 'docker-common' 34 | - 'docker-engine' 35 | - 'docker-selinux' 36 | - 'docker' 37 | 38 | - name: redhat | adding Docker repo 39 | template: 40 | src: "etc/yum.repos.d/docker.repo.j2" 41 | dest: "/etc/yum.repos.d/docker.repo" 42 | become: true 43 | 44 | - name: redhat | installing Docker 45 | yum: 46 | name: "docker-ce-{{ docker_version_redhat }}" 47 | state: present 48 | become: true 49 | when: ansible_distribution != "Fedora" 50 | 51 | - name: redhat | installing Docker 52 | dnf: 53 | name: "docker-ce-{{ docker_version_redhat }}" 54 | state: present 55 | become: true 56 | when: ansible_distribution == "Fedora" 57 | -------------------------------------------------------------------------------- /bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Alpine 3 | if [ -f /etc/alpine-release ]; then 4 | sudo apk update && \ 5 | sudo apk add python 6 | fi 7 | 8 | # Arch 9 | if [ -f /etc/arch-release ]; then 10 | sudo pacman -Sy --noconfirm ca-certificates glibc libffi python \ 11 | python-boto python-pyopenssl python-pip python-setuptools 12 | fi 13 | 14 | # Ubuntu 15 | if [ -f /etc/debian_version ]; then 16 | codename="$(lsb_release -c | awk '{print $2}')" 17 | if [[ $codename == "vivid" ]]; then 18 | test -e /usr/bin/python || (sudo apt-get update && sudo apt-get -y install python-minimal) 19 | fi 20 | if [[ $codename == "wily" ]]; then 21 | test -e /usr/bin/python || (sudo apt-get update && sudo apt-get -y install python-minimal) 22 | fi 23 | if [[ $codename == "xenial" ]]; then 24 | test -e /usr/bin/python || (sudo apt-get update && sudo apt-get -y install python-minimal) 25 | fi 26 | if [[ $codename == "yakkety" ]]; then 27 | test -e /usr/bin/python || (sudo apt-get update && sudo apt-get -y install python-minimal) 28 | fi 29 | if [[ $codename == "zesty" ]]; then 30 | test -e /usr/bin/python || (sudo apt-get update && sudo apt-get -y install python-minimal) 31 | fi 32 | fi 33 | 34 | # RHEL 35 | if [ -f /etc/redhat-release ]; then 36 | if [ -f /etc/os-release ]; then 37 | codename="$(gawk -F= '/^NAME/{print $2}' /etc/os-release)" 38 | if [[ $codename == "Fedora" ]]; then 39 | sudo dnf -y install python-devel python-dnf && \ 40 | sudo dnf -y group install "C Development Tools and Libraries" 41 | fi 42 | fi 43 | fi 44 | -------------------------------------------------------------------------------- /roles/ansible-docker/tasks/manage_python_modules.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: manage_python_modules | installing python pre-req packages (Debian) 3 | apt: 4 | name: "{{ item }}" 5 | state: present 6 | become: true 7 | with_items: 8 | - 'build-essential' 9 | - 'libffi-dev' 10 | - 'libssl-dev' 11 | - 'python-dev' 12 | - 'python-pip' 13 | - 'python-setuptools' 14 | when: ansible_os_family == "Debian" 15 | 16 | - name: manage_python_modules | installing python pre-req packages (RedHat) 17 | yum: 18 | name: "{{ item }}" 19 | state: present 20 | become: true 21 | with_items: 22 | - 'gmp-devel' 23 | - 'libffi-devel' 24 | - 'openssl-devel' 25 | - 'python-crypto' 26 | - 'python-devel' 27 | - 'python-pip' 28 | - 'python-setuptools' 29 | - 'redhat-rpm-config' 30 | when: > 31 | ansible_os_family == "RedHat" and 32 | ansible_distribution != "Fedora" 33 | 34 | - name: manage_python_modules | Installing Ansible Pre-Reqs (Fedora) 35 | dnf: 36 | name: "python-dnf" 37 | state: "present" 38 | become: true 39 | when: > 40 | ansible_os_family == "RedHat" and 41 | ansible_distribution == "Fedora" 42 | 43 | - name: manage_python_modules | installing python pre-req packages (Fedora) 44 | dnf: 45 | name: "{{ item }}" 46 | state: present 47 | become: true 48 | with_items: 49 | - 'gmp-devel' 50 | - 'libffi-devel' 51 | - 'openssl-devel' 52 | - 'python-crypto' 53 | - 'python-devel' 54 | - 'python-pip' 55 | - 'python-setuptools' 56 | - 'redhat-rpm-config' 57 | when: > 58 | ansible_os_family == "RedHat" and 59 | ansible_distribution == "Fedora" 60 | 61 | - name: manage_python_modules | installing python modules 62 | pip: 63 | name: "{{ item }}" 64 | state: present 65 | become: true 66 | with_items: 67 | - 'docker-compose' 68 | # - 'docker-py' 69 | -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/README.md: -------------------------------------------------------------------------------- 1 | Role Name 2 | ========= 3 | 4 | An [Ansible] role to provision a [Docker] swarm cluster. 5 | 6 | Requirements 7 | ------------ 8 | 9 | Install [Ansible] roles required: 10 | ``` 11 | sudo ansible-galaxy install -r requirements.yml 12 | ``` 13 | 14 | Role Variables 15 | -------------- 16 | 17 | ``` 18 | --- 19 | # defaults file for ansible-docker-swarm 20 | docker_swarm_addr: "{{ hostvars[inventory_hostname]['ansible_' + docker_swarm_interface]['ipv4']['address'] }}" 21 | 22 | # Validity period for node certificates (default 2160h0m0s) 23 | docker_swarm_cert_expiry: '2160h0m0s' 24 | 25 | # Dispatcher heartbeat period (default 5s) 26 | docker_swarm_dispatcher_heartbeat_duration: '5s' 27 | 28 | docker_swarm_interface: "enp0s8" 29 | # docker_swarm_managers_ansible_group: 'docker-swarm-managers' 30 | 31 | docker_swarm_config_networks: false 32 | docker_swarm_config_settings: false 33 | 34 | # Define Ansible group which contains your Docker swarm managers 35 | docker_swarm_managers_ansible_group: 'docker-swarm-managers' 36 | 37 | docker_swarm_networks: [] 38 | # - name: 'my_net' 39 | # driver: 'overlay' 40 | # state: 'present' 41 | # - name: 'test' 42 | # driver: 'overlay' 43 | # state: 'absent' 44 | docker_swarm_port: "2377" 45 | 46 | # Defines first node in docker_swarm_managers_ansible_group as primary 47 | docker_swarm_primary_manager: '{{ groups[docker_swarm_managers_ansible_group][0] }}' 48 | 49 | # Task history retention limit (default 5) 50 | docker_swarm_task_history_limit: '5' 51 | 52 | # Define Ansible group which contains you Docker swarm workers 53 | docker_swarm_workers_ansible_group: 'docker-swarm-workers' 54 | ``` 55 | 56 | Dependencies 57 | ------------ 58 | 59 | None 60 | 61 | Example Playbook 62 | ---------------- 63 | 64 | ``` 65 | - hosts: docker_hosts 66 | become: true 67 | vars: 68 | roles: 69 | - role: ansible-docker 70 | - role: ansible-docker-swarm 71 | tasks: 72 | ``` 73 | 74 | License 75 | ------- 76 | 77 | BSD 78 | 79 | Author Information 80 | ------------------ 81 | 82 | 83 | Larry Smith Jr. 84 | - @mrlesmithjr 85 | - http://everythingshouldbevirtual.com 86 | - mrlesmithjr [at] gmail.com 87 | 88 | [Ansible]: 89 | [Docker]: 90 | -------------------------------------------------------------------------------- /roles/ansible-docker/templates/etc/docker/daemon.json.j2.orig: -------------------------------------------------------------------------------- 1 | {% set docker_options = {} %} 2 | {% if docker_opts.bridge is defined %} 3 | {% set _opts = docker_options.update({"bridge": docker_opts.bridge}) %} 4 | {% endif %} 5 | {% if docker_opts.bridge_ip is defined %} 6 | {% set _opts = docker_options.update({"bip": docker_opts.bridge_ip}) %} 7 | {% endif %} 8 | {% if docker_opts.dns is defined %} 9 | {% set _dns_servers = [] %} 10 | {% for item in docker_opts.dns %} 11 | {% set _opts = _dns_servers.append(item) %} 12 | {% endfor %} 13 | {% set _opts = docker_options.update({"dns": _dns_servers}) %} 14 | {% endif %} 15 | {% if docker_opts.dns_search is defined %} 16 | {% set _dns_search = [] %} 17 | {% for item in docker_opts.dns_search %} 18 | {% set _opts = _dns_search.append(item) %} 19 | {% endfor %} 20 | {% set _opts = docker_options.update({"dns-search": _dns_search}) %} 21 | {% endif %} 22 | {% if docker_opts.insecure_registries is defined %} 23 | {% set _insecure_registries = [] %} 24 | {% for item in docker_opts.insecure_registries %} 25 | {% set _opts = _insecure_registries.append(item) %} 26 | {% endfor %} 27 | {% set _opts = docker_options.update({"insecure-registries": _insecure_registries}) %} 28 | {% endif %} 29 | {% if docker_opts.ip is defined %} 30 | {% set _opts = docker_options.update({"ip": docker_opts.ip}) %} 31 | {% endif %} 32 | {% if docker_opts.ip_forward is defined %} 33 | {% set _opts = docker_options.update({"ip-forward": docker_opts.ip_forward}) %} 34 | {% endif %} 35 | {% if docker_opts.ip_masq is defined %} 36 | {% set _opts = docker_options.update({"ip-masq": docker_opts.ip_masq}) %} 37 | {% endif %} 38 | {% if docker_opts.iptables is defined %} 39 | {% set _opts = docker_options.update({"iptables": docker_opts.iptables}) %} 40 | {% endif %} 41 | {% if docker_opts.labels is defined %} 42 | {% set _labels = [] %} 43 | {% for item in docker_opts.labels %} 44 | {% set _opts = _labels.append(item.key+"="+item.value) %} 45 | {% endfor %} 46 | {% set _opts = docker_options.update({"labels": _labels}) %} 47 | {% endif %} 48 | {% if docker_opts.log_driver is defined %} 49 | {% set _opts = docker_options.update({"log-driver": docker_opts.log_driver}) %} 50 | {% endif %} 51 | {% if docker_opts.log_level is defined %} 52 | {% set _opts = docker_options.update({"log-level": docker_opts.log_level}) %} 53 | {% endif %} 54 | {% if docker_opts.max_concurrent_downloads is defined %} 55 | {% set _opts = docker_options.update({"max-concurrent-downloads": docker_opts.max_concurrent_downloads|int}) %} 56 | {% endif %} 57 | {% if docker_opts.max_concurrent_uploads is defined %} 58 | {% set _opts = docker_options.update({"max-concurrent-uploads": docker_opts.max_concurrent_uploads|int}) %} 59 | {% endif %} 60 | {% if docker_opts.storage_driver is defined %} 61 | {% set _opts = docker_options.update({"storage-driver": docker_opts.storage_driver}) %} 62 | {% endif %} 63 | {% if docker_opts.tls is defined %} 64 | {% set _opts = docker_options.update({"tls": docker_opts.tls}) %} 65 | {% endif %} 66 | {{ docker_options| to_nice_json }} 67 | -------------------------------------------------------------------------------- /docker-management.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | # docker_hostname = '192.168.202.200' 4 | # docker_port = '2377' 5 | # docker_protocol = 'tcp' 6 | 7 | import argparse 8 | import json 9 | from docker import Client 10 | #cli = Client(base_url=docker_protocol+'://'+docker_hostname+':'+docker_port) 11 | cli = Client(base_url='unix://var/run/docker.sock') 12 | 13 | class DOCKERMGMT(object): 14 | def __init__(self): 15 | self.read_cli_args() 16 | self.decide_action() 17 | 18 | def decide_action(self): 19 | if self.args.action == 'containers': 20 | self.docker_containers() 21 | if self.args.action == 'info': 22 | self.docker_info() 23 | if self.args.action == 'images': 24 | self.docker_images() 25 | if self.args.action == "inspect_node": 26 | self.docker_inspect_node() 27 | if self.args.action == 'networks': 28 | self.docker_networks() 29 | if self.args.action == "nodes": 30 | self.docker_nodes() 31 | if self.args.action == "services": 32 | self.docker_services() 33 | 34 | def docker_containers(self): 35 | dc = cli.containers() 36 | print json.dumps(dc, indent=4) 37 | 38 | def docker_images(self): 39 | dimg = cli.images() 40 | print json.dumps(dimg, indent=4) 41 | 42 | def docker_info(self): 43 | di = cli.info() 44 | print json.dumps(di, indent=4) 45 | 46 | def docker_inspect_node(self): 47 | dis = cli.inspect_node(self.args.node) 48 | print json.dumps(dis, indent=4) 49 | 50 | def docker_networks(self): 51 | dnets = cli.networks() 52 | print json.dumps(dnets, indent=4) 53 | 54 | def docker_nodes(self): 55 | if self.args.role is None: 56 | if self.args.node is None: 57 | dn = cli.nodes() 58 | elif self.args.node is not None: 59 | dn = cli.nodes(filters={'name': self.args.node}) 60 | elif self.args.role is not None: 61 | if self.args.node is None: 62 | dn = cli.nodes(filters={'role': self.args.role}) 63 | elif self.args.node is not None: 64 | dn = cli.nodes(filters={'role': self.args.role, 'name': self.args.node}) 65 | print json.dumps(dn, indent=4) 66 | 67 | def docker_services(self): 68 | if self.args.name is None: 69 | svcs = cli.services() 70 | elif self.args.name is not None: 71 | svcs = cli.services(filters={'name': self.args.name}) 72 | print json.dumps(svcs, indent=4) 73 | 74 | def read_cli_args(self): 75 | parser = argparse.ArgumentParser(description='Docker Management') 76 | parser.add_argument('action', help='Define action to take', 77 | choices=['containers', 'info', 'images', 'inspect_node', 'networks', 'nodes', 'services']) 78 | parser.add_argument('--name', help='Define name to use as filter') 79 | parser.add_argument('--node', help='Define node to inspect') 80 | parser.add_argument('--role', choices=['manager', 'worker']) 81 | self.args = parser.parse_args() 82 | 83 | if __name__ == '__main__': 84 | DOCKERMGMT() 85 | -------------------------------------------------------------------------------- /roles/ansible-docker/tasks/debian.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: debian | updating apt-cache 3 | apt: 4 | update_cache: yes 5 | cache_valid_time: 86400 6 | become: true 7 | 8 | - name: debian | installing pre-reqs 9 | apt: 10 | name: "{{ item }}" 11 | state: present 12 | become: true 13 | with_items: 14 | - 'apt-transport-https' 15 | - 'ca-certificates' 16 | - 'software-properties-common' 17 | 18 | # We are removing the old Docker info 19 | - name: debian | Removing Legacy Docker apt-key 20 | apt_key: 21 | keyserver: "hkp://p80.pool.sks-keyservers.net:80" 22 | id: "58118E89F3A912897C070ADBF76221572C52609D" 23 | state: "absent" 24 | become: true 25 | 26 | # We are removing the old Docker info 27 | - name: debian | Removing Legacy Docker Repo 28 | apt_repository: 29 | repo: "deb https://apt.dockerproject.org/repo {{ ansible_distribution | lower }}-{{ ansible_distribution_release }} main" 30 | state: "absent" 31 | become: true 32 | 33 | - name: debian | adding docker apt-key 34 | apt_key: 35 | url: "{{ docker_ubuntu_repo_info['url'] }}" 36 | id: "{{ docker_ubuntu_repo_info['id'] }}" 37 | state: "present" 38 | become: true 39 | 40 | - name: debian | adding docker repo 41 | apt_repository: 42 | repo: "{{ docker_ubuntu_repo_info['repo'] }}" 43 | state: present 44 | become: true 45 | 46 | # We remove docker-engine as this is old package to install. The new package is 47 | # docker-ce 48 | - name: debian | uninstalling old docker package (if exists) 49 | apt: 50 | name: "{{ item }}" 51 | state: "absent" 52 | purge: yes 53 | become: true 54 | with_items: 55 | - 'docker-engine' 56 | - 'lxc-docker' 57 | 58 | - name: debian | installing docker pre-reqs 59 | apt: 60 | name: "linux-image-extra-{{ ansible_kernel }}" 61 | state: present 62 | become: true 63 | when: > 64 | ansible_distribution == "Ubuntu" and 65 | (ansible_distribution_version >= '14.04') and 66 | docker_linux_image_extra is defined and 67 | docker_linux_image_extra 68 | 69 | - name: debian | checking for existing docker 70 | shell: dpkg-query -W 'docker-ce' 71 | ignore_errors: true 72 | register: has_docker 73 | 74 | - name: debian | installing docker 75 | apt: 76 | name: "docker-ce={{ docker_version_debian }}" 77 | state: "present" 78 | become: true 79 | when: has_docker|failed 80 | 81 | - name: debian | setting grub memory limit (if set) 82 | lineinfile: 83 | dest: /etc/default/grub 84 | regexp: "^GRUB_CMDLINE_LINUX_DEFAULT" 85 | line: 'GRUB_CMDLINE_LINUX_DEFAULT="cgroup_enable=memory swapaccount=1"' 86 | register: grub_updated 87 | become: true 88 | when: > 89 | docker_set_grub_memory_limit is defined and 90 | docker_set_grub_memory_limit 91 | 92 | - name: debian | updating grub (if updated) 93 | command: update-grub 94 | become: true 95 | when: grub_updated['changed'] 96 | 97 | - name: debian | installing additonal packages 98 | apt: 99 | name: "{{ item }}" 100 | state: "present" 101 | become: true 102 | with_items: 103 | - bridge-utils 104 | when: > 105 | docker_install_bridge_utils is defined and 106 | docker_install_bridge_utils 107 | -------------------------------------------------------------------------------- /roles/ansible-docker/tasks/set_facts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: set_facts | Setting Docker Version To Install (Debian) 3 | set_fact: 4 | docker_version_debian: '{{ docker_version }}-0~{{ ansible_distribution_release|lower }}' 5 | when: > 6 | ansible_os_family == "Debian" and 7 | (docker_version < '1.12.4') 8 | 9 | - name: set_facts | Setting Docker Version To Install (Debian) 10 | set_fact: 11 | docker_version_debian: '{{ docker_version }}-0~{{ ansible_distribution|lower }}-{{ ansible_distribution_release|lower }}' 12 | when: > 13 | ansible_os_family == "Debian" and 14 | (docker_version >= '1.12.4' and 15 | docker_version <= '1.13.1') 16 | 17 | - name: set_facts | Setting Docker Version To Install (Debian) 18 | set_fact: 19 | docker_version_debian: '{{ docker_version }}~ce-0~{{ ansible_distribution|lower }}-{{ ansible_distribution_release|lower }}' 20 | when: > 21 | ansible_os_family == "Debian" and 22 | (docker_version >= '17.03' and 23 | docker_version < '17.06') 24 | 25 | - name: set_facts | Setting Docker Version To Install (Debian) 26 | set_fact: 27 | docker_version_debian: '{{ docker_version }}~ce-0~{{ ansible_distribution|lower }}' 28 | when: > 29 | ansible_os_family == "Debian" and 30 | (docker_version >= '17.06' and 31 | docker_version < '17.09') 32 | 33 | - name: set_facts | Setting Docker Version To Install (Debian) 34 | set_fact: 35 | docker_version_debian: '{{ docker_version }}~ce-0~{{ ansible_distribution|lower }}' 36 | when: > 37 | ansible_os_family == "Debian" and 38 | (docker_version >= '17.09') 39 | 40 | - name: set_facts | Setting Docker Version To Install (Fedora) 41 | set_fact: 42 | docker_version_redhat: '{{ docker_version }}-1.el7.centos' 43 | when: > 44 | (ansible_os_family == "RedHat" and 45 | ansible_distribution == "Fedora") and 46 | (docker_version < '17.03') 47 | 48 | - name: set_facts | Setting Docker Version To Install (Fedora) 49 | set_fact: 50 | docker_version_redhat: '{{ docker_version }}.ce-1.fc{{ ansible_distribution_major_version }}' 51 | when: > 52 | (ansible_os_family == "RedHat" and 53 | ansible_distribution == "Fedora") and 54 | (docker_version >= '17.03') 55 | 56 | - name: set_facts | Setting Docker Version To Install (RedHat) 57 | set_fact: 58 | docker_version_redhat: '{{ docker_version }}-1.el7.centos' 59 | when: > 60 | (ansible_os_family == "RedHat" and 61 | ansible_distribution != "Fedora") and 62 | (docker_version < '17.03') and 63 | ansible_distribution_major_version == '7' 64 | 65 | - name: set_facts | Setting Docker Version To Install (RedHat) 66 | set_fact: 67 | docker_version_redhat: '{{ docker_version }}.ce-1.el7.centos' 68 | when: > 69 | (ansible_os_family == "RedHat" and 70 | ansible_distribution != "Fedora") and 71 | (docker_version >= '17.03') and 72 | ansible_distribution_major_version == '7' 73 | 74 | - name: Installing Docker Version On Debian 75 | debug: msg="Installing Docker Version {{ docker_version_debian }}" 76 | when: ansible_os_family == "Debian" 77 | 78 | - name: Installing Docker Version On RedHat 79 | debug: msg="Installing Docker Version {{ docker_version_redhat }}" 80 | when: ansible_os_family == "RedHat" 81 | -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/tasks/cluster.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: cluster | Checking Swarm Mode Status 3 | command: "docker info" 4 | register: "docker_info" 5 | changed_when: false 6 | check_mode: no 7 | become: true 8 | 9 | - name: cluster | Init Docker Swarm Mode On First Manager 10 | command: > 11 | docker swarm init 12 | --listen-addr {{ docker_swarm_addr }}:{{ docker_swarm_port }} 13 | --advertise-addr {{ docker_swarm_addr }} 14 | become: true 15 | when: > 16 | 'Swarm: inactive' in docker_info.stdout and 17 | inventory_hostname == docker_swarm_primary_manager 18 | 19 | - name: cluster | Capturing Docker Swarm Worker join-token 20 | command: "docker swarm join-token -q worker" 21 | changed_when: false 22 | register: "docker_swarm_worker_token" 23 | become: true 24 | when: > 25 | inventory_hostname == docker_swarm_primary_manager 26 | 27 | - name: cluster | Capturing Docker Swarm Manager join-token 28 | command: "docker swarm join-token -q manager" 29 | changed_when: false 30 | register: "docker_swarm_manager_token" 31 | become: true 32 | when: > 33 | inventory_hostname == docker_swarm_primary_manager 34 | 35 | - name: cluster | Defining Docker Swarm Manager Address 36 | set_fact: 37 | docker_swarm_manager_address: "{{ docker_swarm_addr }}:{{ docker_swarm_port }}" 38 | changed_when: false 39 | when: > 40 | inventory_hostname == docker_swarm_primary_manager 41 | 42 | - name: cluster | Defining Docker Swarm Manager Address 43 | set_fact: 44 | docker_swarm_manager_address: "{{ hostvars[docker_swarm_primary_manager]['docker_swarm_manager_address'] }}" 45 | changed_when: false 46 | when: > 47 | inventory_hostname != docker_swarm_primary_manager 48 | 49 | - name: cluster | Defining Docker Swarm Manager join-token 50 | set_fact: 51 | docker_swarm_manager_token: "{{ hostvars[docker_swarm_primary_manager]['docker_swarm_manager_token'] }}" 52 | changed_when: false 53 | when: > 54 | inventory_hostname != docker_swarm_primary_manager 55 | 56 | - name: cluster | Defining Docker Swarm Worker join-token 57 | set_fact: 58 | docker_swarm_worker_token: "{{ hostvars[docker_swarm_primary_manager]['docker_swarm_worker_token'] }}" 59 | changed_when: false 60 | when: > 61 | inventory_hostname != docker_swarm_primary_manager 62 | 63 | - name: cluster | Joining Additional Docker Swarm Managers To Cluster 64 | command: > 65 | docker swarm join 66 | --listen-addr {{ docker_swarm_addr }}:{{ docker_swarm_port }} 67 | --advertise-addr {{ docker_swarm_addr }} 68 | --token {{ docker_swarm_manager_token.stdout }} 69 | {{ docker_swarm_manager_address }} 70 | become: true 71 | when: > 72 | inventory_hostname != docker_swarm_primary_manager and 73 | inventory_hostname not in groups[docker_swarm_workers_ansible_group] and 74 | 'Swarm: active' not in docker_info.stdout and 75 | 'Swarm: pending' not in docker_info.stdout 76 | 77 | - name: cluster | Joining Docker Swarm Workers To Cluster 78 | command: > 79 | docker swarm join 80 | --listen-addr {{ docker_swarm_addr }}:{{ docker_swarm_port }} 81 | --advertise-addr {{ docker_swarm_addr }} 82 | --token {{ docker_swarm_worker_token.stdout }} 83 | {{ docker_swarm_manager_address }} 84 | become: true 85 | when: > 86 | inventory_hostname in groups[docker_swarm_workers_ansible_group] and 87 | 'Swarm: active' not in docker_info.stdout and 88 | 'Swarm: pending' not in docker_info.stdout 89 | -------------------------------------------------------------------------------- /roles/ansible-etc-hosts/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: Larry Smith Jr. 3 | description: An Ansible role that configures /etc/hosts 4 | #company: your company (optional) 5 | 6 | # If the issue tracker for your role is not on github, uncomment the 7 | # next line and provide a value 8 | # issue_tracker_url: http://example.com/issue/tracker 9 | 10 | # Some suggested licenses: 11 | # - BSD (default) 12 | # - MIT 13 | # - GPLv2 14 | # - GPLv3 15 | # - Apache 16 | # - CC-BY 17 | license: license (GPLv2, CC-BY, etc) 18 | 19 | min_ansible_version: 1.2 20 | 21 | # Optionally specify the branch Galaxy will use when accessing the GitHub 22 | # repo for this role. During role install, if no tags are available, 23 | # Galaxy will use this branch. During import Galaxy will access files on 24 | # this branch. If travis integration is cofigured, only notification for this 25 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 26 | # (usually master) will be used. 27 | #github_branch: 28 | 29 | # 30 | # Below are all platforms currently available. Just uncomment 31 | # the ones that apply to your role. If you don't see your 32 | # platform on this list, let us know and we'll get it added! 33 | # 34 | platforms: 35 | - name: EL 36 | versions: 37 | # - all 38 | # - 5 39 | - 6 40 | - 7 41 | #- name: GenericUNIX 42 | # versions: 43 | # - all 44 | # - any 45 | #- name: Solaris 46 | # versions: 47 | # - all 48 | # - 10 49 | # - 11.0 50 | # - 11.1 51 | # - 11.2 52 | # - 11.3 53 | - name: Fedora 54 | versions: 55 | # - all 56 | # - 16 57 | # - 17 58 | # - 18 59 | # - 19 60 | - 20 61 | - 21 62 | - 22 63 | #- name: Windows 64 | # versions: 65 | # - all 66 | # - 2012R2 67 | #- name: SmartOS 68 | # versions: 69 | # - all 70 | # - any 71 | #- name: opensuse 72 | # versions: 73 | # - all 74 | # - 12.1 75 | # - 12.2 76 | # - 12.3 77 | # - 13.1 78 | # - 13.2 79 | #- name: Amazon 80 | # versions: 81 | # - all 82 | # - 2013.03 83 | # - 2013.09 84 | #- name: GenericBSD 85 | # versions: 86 | # - all 87 | # - any 88 | #- name: FreeBSD 89 | # versions: 90 | # - all 91 | # - 8.0 92 | # - 8.1 93 | # - 8.2 94 | # - 8.3 95 | # - 8.4 96 | # - 9.0 97 | # - 9.1 98 | # - 9.1 99 | # - 9.2 100 | - name: Ubuntu 101 | versions: 102 | - all 103 | # - lucid 104 | # - maverick 105 | # - natty 106 | # - oneiric 107 | # - precise 108 | # - quantal 109 | # - raring 110 | # - saucy 111 | # - trusty 112 | # - utopic 113 | # - vivid 114 | #- name: SLES 115 | # versions: 116 | # - all 117 | # - 10SP3 118 | # - 10SP4 119 | # - 11 120 | # - 11SP1 121 | # - 11SP2 122 | # - 11SP3 123 | #- name: GenericLinux 124 | # versions: 125 | # - all 126 | # - any 127 | - name: Debian 128 | versions: 129 | - all 130 | # - etch 131 | # - jessie 132 | # - lenny 133 | # - squeeze 134 | # - wheezy 135 | 136 | galaxy_tags: 137 | # List tags for your role here, one per line. A tag is 138 | # a keyword that describes and categorizes the role. 139 | # Users find roles by searching for tags. Be sure to 140 | # remove the '[]' above if you add tags to this list. 141 | # 142 | # NOTE: A tag is limited to a single word comprised of 143 | # alphanumeric characters. Maximum 20 tags per role. 144 | - system 145 | 146 | dependencies: [] 147 | # List your role dependencies here, one per line. 148 | # Be sure to remove the '[]' above if you add dependencies 149 | # to this list. 150 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* 4 | 5 | - [Purpose](#purpose) 6 | - [Requirements](#requirements) 7 | - [Information](#information) 8 | - [Usage](#usage) 9 | - [License](#license) 10 | - [Author Information](#author-information) 11 | 12 | 13 | 14 | # Purpose 15 | 16 | Spins up a [Docker](https://www.docker.com) Swarm mode cluster within a 17 | [Vagrant](https://www.vagrantup.com) environment and uses 18 | [Ansible](https://www.ansible.com) to provision the whole environment. 19 | 20 | ## Requirements 21 | 22 | - [Ansible](https://www.ansible.com) 23 | - [VirtualBox](https://www.virtualbox.org) 24 | - [Vagrant](https://www.vagrantup.com) 25 | 26 | ## Information 27 | 28 | This environment will consist of the following: 29 | 30 | - 7 [Ubuntu](https://www.ubuntu.com) `16.04` nodes 31 | - 3 [Docker](https://www.docker.com) Swarm Managers (node0-node2) 32 | - 4 [Docker](https://www.docker.com) Swarm Workers (node3-node6) 33 | 34 | I have also included a [Python script](docker-management.py) that will be 35 | worked on over time to do some initial various things but will have more 36 | functionality over time. 37 | 38 | ## Usage 39 | 40 | Easily spin up the [Vagrant](https://www.vagrantup.com) environment. 41 | 42 | ```bash 43 | vagrant up 44 | ``` 45 | 46 | Once everything provisions you are now ready to begin using your [Docker](https://www.docker.com) Swarm 47 | mode cluster. 48 | 49 | Connect to one of the [Docker](https://www.docker.com) Swarm Managers to begin creating services and etc. 50 | 51 | ```bash 52 | vagrant ssh node0 53 | ``` 54 | 55 | Validate that the [Docker](https://www.docker.com) Swarm cluster is functional: 56 | 57 | ```bash 58 | sudo docker node ls 59 | ``` 60 | 61 | You should something similar to below: 62 | 63 | ```bash 64 | ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 65 | 0bp91mlgswsl19chkudasptxt node3 Ready Active 66 | 0uyl5ms4lb543d6284vrycuh1 node5 Ready Active 67 | 1trucugnb1gmu35tmjt4jc2om node4 Ready Active 68 | 4y83hx5ywpkn65tp268huipyz * node0 Ready Active Leader 69 | 5suz75nggempf5984cx99e6sx node6 Ready Active 70 | 60qm8mohj517vovv7id5p7l6s node2 Ready Active Reachable 71 | cwnkijv7f8gzsvwltnomgmmea node1 Ready Active Reachable 72 | ``` 73 | 74 | Create a new [Docker](https://www.docker.com) service: 75 | 76 | ```bash 77 | sudo docker service create --name web --publish 8080:80 --replicas 1 mrlesmithjr/nginx 78 | ``` 79 | 80 | List the current [Docker](https://www.docker.com) services: 81 | 82 | ```bash 83 | sudo docker service ls 84 | ... 85 | ID NAME REPLICAS IMAGE COMMAND 86 | 016psrb2tb7y web 1/1 mrlesmithjr/nginx 87 | ``` 88 | 89 | List the tasks of a service: 90 | 91 | ```bash 92 | sudo docker service ps web 93 | ... 94 | ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 95 | 9n3yq6k2ig71kkldzrs2zfqb3 web.1 mrlesmithjr/nginx node0 Running Running about a minute ago 96 | ``` 97 | 98 | Scale the service to increase the number of replicas: 99 | 100 | ```bash 101 | sudo docker service scale web=4 102 | ... 103 | web scaled to 4 104 | ``` 105 | 106 | Now list the current [Docker](https://www.docker.com) services: 107 | 108 | ```bash 109 | sudo docker service ls 110 | ... 111 | ID NAME REPLICAS IMAGE COMMAND 112 | 016psrb2tb7y web 4/4 mrlesmithjr/nginx 113 | ``` 114 | 115 | Now list the tasks of the service: 116 | 117 | ```bash 118 | sudo docker service ps web 119 | ... 120 | ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 121 | 9n3yq6k2ig71kkldzrs2zfqb3 web.1 mrlesmithjr/nginx node0 Running Running 5 minutes ago 122 | bisd4qcaxsx66u6zeuomykkr3 web.2 mrlesmithjr/nginx node3 Running Running 41 seconds ago 123 | 8u940el4iomekvsfkqvpz75ox web.3 mrlesmithjr/nginx node4 Running Running 43 seconds ago 124 | dhjjumf7auf6s5k8uqwjo6wbx web.4 mrlesmithjr/nginx node1 Running Running 40 seconds ago 125 | ``` 126 | 127 | Now go and enjoy your [Docker](https://www.docker.com) Swarm mode cluster and do some learning. 128 | 129 | ## License 130 | 131 | MIT 132 | 133 | ## Author Information 134 | 135 | Larry Smith Jr. 136 | 137 | - [@mrlesmithjr](https://www.twitter.com/mrlesmithjr) 138 | - [EverythingShouldBeVirtual](http://everythingshouldbevirtual.com) 139 | - [mrlesmithjr@gmail.com](mailto:mrlesmithjr@gmail.com) -------------------------------------------------------------------------------- /roles/ansible-etc-hosts/templates/etc/hosts.j2: -------------------------------------------------------------------------------- 1 | 127.0.0.1 localhost 2 | 3 | {% if not etc_hosts_add_all_hosts %} 4 | {% if (ansible_domain == etc_hosts_pri_dns_name) or ansible_domain == '' %} 5 | {% if not etc_hosts_static_ip %} 6 | {% if inventory_hostname == inventory_hostname_short %} 7 | {% if ansible_fqdn != (ansible_hostname + '.' + etc_hosts_pri_dns_name) %} 8 | 127.0.1.1 {{ ansible_hostname }}.{{ etc_hosts_pri_dns_name }} {{ ansible_hostname }} 9 | {% elif ansible_fqdn == (ansible_hostname + '.' + etc_hosts_pri_dns_name) %} 10 | 127.0.1.1 {{ ansible_fqdn }} {{ ansible_hostname }} 11 | {% endif %} 12 | {% endif %} 13 | {% if inventory_hostname != inventory_hostname_short %} 14 | {% if ansible_fqdn != inventory_hostname %} 15 | 127.0.1.1 {{ inventory_hostname }} {{ ansible_hostname }} 16 | {% elif ansible_fqdn == inventory_hostname %} 17 | 127.0.1.1 {{ ansible_fqdn }} {{ ansible_hostname }} 18 | {% endif %} 19 | {% endif %} 20 | {% elif etc_hosts_static_ip %} 21 | {% if ansible_ssh_host is defined %} 22 | {{ ansible_ssh_host }} {{ ansible_fqdn }} {{ ansible_hostname }} 23 | {% elif ansible_host is defined %} 24 | {{ ansible_host }} {{ ansible_fqdn }} {{ ansible_hostname }} 25 | {% endif %} 26 | {% endif %} 27 | {% elif (ansible_domain != etc_hosts_pri_dns_name) and ansible_domain != '' %} 28 | {% if (ansible_fqdn == inventory_hostname) and (inventory_hostname != inventory_hostname_short) %} 29 | {% if not etc_hosts_static_ip %} 30 | 127.0.1.1 {{ inventory_hostname }} {{ ansible_hostname }} 31 | {% elif etc_hosts_static_ip %} 32 | {% if ansible_ssh_host is defined %} 33 | {{ ansible_ssh_host }} {{ inventory_hostname }} {{ ansible_hostname }} 34 | {% elif ansible_host is defined %} 35 | {{ ansible_host }} {{ inventory_hostname }} {{ ansible_hostname }} 36 | {% endif %} 37 | {% endif %} 38 | {% endif %} 39 | {% endif %} 40 | {% elif etc_hosts_add_all_hosts %} 41 | {% for host in play_hosts %} 42 | {% if (hostvars[host]['ansible_domain'] == etc_hosts_pri_dns_name) or hostvars[host]['ansible_domain'] == '' %} 43 | {% if etc_hosts_use_default_ip_address and not etc_hosts_use_ansible_ssh_host %} 44 | {{ hostvars[host]['ansible_default_ipv4']['address'] }} {{ hostvars[host]['ansible_fqdn'] }}.{{ etc_hosts_pri_dns_name }} {{ hostvars[host]['ansible_hostname'] }} 45 | {% elif not etc_hosts_use_default_ip_address and etc_hosts_use_ansible_ssh_host %} 46 | {% if hostvars[host]['ansible_fqdn'] != (hostvars[host]['ansible_hostname']+ '.' + etc_hosts_pri_dns_name) %} 47 | {% if hostvars[host]['ansible_ssh_host'] is defined %} 48 | {{ hostvars[host]['ansible_ssh_host'] }} {{ hostvars[host]['ansible_hostname'] }}.{{ etc_hosts_pri_dns_name }} {{ hostvars[host]['ansible_hostname'] }} 49 | {% elif hostvars[host]['ansible_host'] is defined %} 50 | {{ hostvars[host]['ansible_host'] }} {{ hostvars[host]['ansible_hostname'] }}.{{ etc_hosts_pri_dns_name }} {{ hostvars[host]['ansible_hostname'] }} 51 | {% endif %} 52 | {% elif hostvars[host]['ansible_fqdn'] == (hostvars[host]['ansible_hostname']+ '.' + etc_hosts_pri_dns_name) %} 53 | {% if hostvars[host]['ansible_ssh_host'] is defined %} 54 | {{ hostvars[host]['ansible_ssh_host'] }} {{ hostvars[host]['ansible_fqdn'] }} {{ hostvars[host]['ansible_hostname'] }} 55 | {% elif hostvars[host]['ansible_host'] is defined %} 56 | {{ hostvars[host]['ansible_host'] }} {{ hostvars[host]['ansible_fqdn'] }} {{ hostvars[host]['ansible_hostname'] }} 57 | {% endif %} 58 | {% endif %} 59 | {% endif %} 60 | {% elif (hostvars[host]['ansible_domain'] != etc_hosts_pri_dns_name) and ansible_domain != '' %} 61 | {% if (hostvars[host]['ansible_fqdn'] == inventory_hostname) and (inventory_hostname != inventory_hostname_short) %} 62 | {% if etc_hosts_use_default_ip_address and not etc_hosts_use_ansible_ssh_host %} 63 | {{ hostvars[host]['ansible_default_ipv4']['address'] }} {{ hostvars[host]['ansible_fqdn'] }} {{ hostvars[host]['ansible_hostname'] }} 64 | {% elif not etc_hosts_use_default_ip_address and etc_hosts_use_ansible_ssh_host %} 65 | {% if hostvars[host]['ansible_ssh_host'] is defined %} 66 | {{ hostvars[host]['ansible_ssh_host'] }} {{ hostvars[host]['ansible_fqdn'] }} {{ hostvars[host]['ansible_hostname'] }} 67 | {% elif hostvars[host]['ansible_host'] is defined %} 68 | {{ hostvars[host]['ansible_host'] }} {{ hostvars[host]['ansible_fqdn'] }} {{ hostvars[host]['ansible_hostname'] }} 69 | {% endif %} 70 | {% endif %} 71 | {% endif %} 72 | {% endif %} 73 | {% endfor %} 74 | {% endif %} 75 | 76 | {% if etc_hosts_enable_ipv6 %} 77 | # The following lines are desirable for IPv6 capable hosts 78 | ::1 localhost ip6-localhost ip6-loopback 79 | ff02::1 ip6-allnodes 80 | ff02::2 ip6-allrouters 81 | {% endif %} 82 | -------------------------------------------------------------------------------- /nodes.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: node0 3 | ansible_groups: 4 | - docker-nodes 5 | - docker-swarm-managers 6 | box: mrlesmithjr/xenial64 7 | desktop: false 8 | # disks: 9 | # - size: 10 10 | # controller: "SATA Controller" 11 | # - size: 10 12 | # controller: "SATA Controller" 13 | interfaces: 14 | - ip: 192.168.250.10 15 | auto_config: true 16 | method: static 17 | # - ip: 192.168.1.10 18 | # auto_config: false 19 | # method: static 20 | # network_name: network-1 21 | mem: 512 22 | provision: true 23 | vcpu: 1 24 | # port_forwards: 25 | # - guest: 80 26 | # host: 8080 27 | # - guest: 443 28 | # host: 4433 29 | - name: node1 30 | ansible_groups: 31 | - docker-nodes 32 | - docker-swarm-managers 33 | box: mrlesmithjr/xenial64 34 | desktop: false 35 | # disks: 36 | # - size: 10 37 | # controller: "SATA Controller" 38 | # - size: 10 39 | # controller: "SATA Controller" 40 | interfaces: 41 | - ip: 192.168.250.11 42 | auto_config: true 43 | method: static 44 | # - ip: 192.168.1.10 45 | # auto_config: false 46 | # method: static 47 | # network_name: network-1 48 | mem: 512 49 | provision: true 50 | vcpu: 1 51 | # port_forwards: 52 | # - guest: 80 53 | # host: 8080 54 | # - guest: 443 55 | # host: 4433 56 | - name: node2 57 | ansible_groups: 58 | - docker-nodes 59 | - docker-swarm-managers 60 | box: mrlesmithjr/xenial64 61 | desktop: false 62 | # disks: 63 | # - size: 10 64 | # controller: "SATA Controller" 65 | # - size: 10 66 | # controller: "SATA Controller" 67 | interfaces: 68 | - ip: 192.168.250.12 69 | auto_config: true 70 | method: static 71 | # - ip: 192.168.1.10 72 | # auto_config: false 73 | # method: static 74 | # network_name: network-1 75 | mem: 512 76 | provision: true 77 | vcpu: 1 78 | # port_forwards: 79 | # - guest: 80 80 | # host: 8080 81 | # - guest: 443 82 | # host: 4433 83 | - name: node3 84 | ansible_groups: 85 | - docker-nodes 86 | - docker-swarm-workers 87 | box: mrlesmithjr/xenial64 88 | desktop: false 89 | # disks: 90 | # - size: 10 91 | # controller: "SATA Controller" 92 | # - size: 10 93 | # controller: "SATA Controller" 94 | interfaces: 95 | - ip: 192.168.250.13 96 | auto_config: true 97 | method: static 98 | # - ip: 192.168.1.10 99 | # auto_config: false 100 | # method: static 101 | # network_name: network-1 102 | mem: 512 103 | provision: true 104 | vcpu: 1 105 | # port_forwards: 106 | # - guest: 80 107 | # host: 8080 108 | # - guest: 443 109 | # host: 4433 110 | - name: node4 111 | ansible_groups: 112 | - docker-nodes 113 | - docker-swarm-workers 114 | box: mrlesmithjr/xenial64 115 | desktop: false 116 | # disks: 117 | # - size: 10 118 | # controller: "SATA Controller" 119 | # - size: 10 120 | # controller: "SATA Controller" 121 | interfaces: 122 | - ip: 192.168.250.14 123 | auto_config: true 124 | method: static 125 | # - ip: 192.168.1.10 126 | # auto_config: false 127 | # method: static 128 | # network_name: network-1 129 | mem: 512 130 | provision: true 131 | vcpu: 1 132 | # port_forwards: 133 | # - guest: 80 134 | # host: 8080 135 | # - guest: 443 136 | # host: 4433 137 | - name: node5 138 | ansible_groups: 139 | - docker-nodes 140 | - docker-swarm-workers 141 | box: mrlesmithjr/xenial64 142 | desktop: false 143 | # disks: 144 | # - size: 10 145 | # controller: "SATA Controller" 146 | # - size: 10 147 | # controller: "SATA Controller" 148 | interfaces: 149 | - ip: 192.168.250.15 150 | auto_config: true 151 | method: static 152 | # - ip: 192.168.1.10 153 | # auto_config: false 154 | # method: static 155 | # network_name: network-1 156 | mem: 512 157 | provision: true 158 | vcpu: 1 159 | # port_forwards: 160 | # - guest: 80 161 | # host: 8080 162 | # - guest: 443 163 | # host: 4433 164 | - name: node6 165 | ansible_groups: 166 | - docker-nodes 167 | - docker-swarm-workers 168 | box: mrlesmithjr/xenial64 169 | desktop: false 170 | # disks: 171 | # - size: 10 172 | # controller: "SATA Controller" 173 | # - size: 10 174 | # controller: "SATA Controller" 175 | interfaces: 176 | - ip: 192.168.250.16 177 | auto_config: true 178 | method: static 179 | # - ip: 192.168.1.10 180 | # auto_config: false 181 | # method: static 182 | # network_name: network-1 183 | mem: 512 184 | provision: true 185 | vcpu: 1 186 | # port_forwards: 187 | # - guest: 80 188 | # host: 8080 189 | # - guest: 443 190 | # host: 4433 191 | -------------------------------------------------------------------------------- /roles/ansible-docker-swarm/meta/main.yml: -------------------------------------------------------------------------------- 1 | galaxy_info: 2 | author: Larry Smith Jr. 3 | description: An Ansible role to provision a Docker Swarm Cluster 4 | # company: your company (optional) 5 | 6 | # If the issue tracker for your role is not on github, uncomment the 7 | # next line and provide a value 8 | # issue_tracker_url: http://example.com/issue/tracker 9 | 10 | # Some suggested licenses: 11 | # - BSD (default) 12 | # - MIT 13 | # - GPLv2 14 | # - GPLv3 15 | # - Apache 16 | # - CC-BY 17 | license: license (GPLv2, CC-BY, etc) 18 | 19 | min_ansible_version: 1.2 20 | 21 | # Optionally specify the branch Galaxy will use when accessing the GitHub 22 | # repo for this role. During role install, if no tags are available, 23 | # Galaxy will use this branch. During import Galaxy will access files on 24 | # this branch. If travis integration is cofigured, only notification for this 25 | # branch will be accepted. Otherwise, in all cases, the repo's default branch 26 | # (usually master) will be used. 27 | #github_branch: 28 | 29 | # 30 | # Below are all platforms currently available. Just uncomment 31 | # the ones that apply to your role. If you don't see your 32 | # platform on this list, let us know and we'll get it added! 33 | # 34 | platforms: 35 | #- name: OpenBSD 36 | # versions: 37 | # - all 38 | # - 5.6 39 | # - 5.7 40 | # - 5.8 41 | # - 5.9 42 | # - 6.0 43 | #- name: Fedora 44 | # versions: 45 | # - all 46 | # - 16 47 | # - 17 48 | # - 18 49 | # - 19 50 | # - 20 51 | # - 21 52 | # - 22 53 | # - 23 54 | # - 24 55 | # - 25 56 | #- name: DellOS 57 | # versions: 58 | # - all 59 | # - 10 60 | # - 6 61 | # - 9 62 | #- name: MacOSX 63 | # versions: 64 | # - all 65 | # - 10.10 66 | # - 10.11 67 | # - 10.12 68 | # - 10.7 69 | # - 10.8 70 | # - 10.9 71 | #- name: Synology 72 | # versions: 73 | # - all 74 | # - any 75 | #- name: Junos 76 | # versions: 77 | # - all 78 | # - any 79 | #- name: GenericBSD 80 | # versions: 81 | # - all 82 | # - any 83 | #- name: Void Linux 84 | # versions: 85 | # - all 86 | # - any 87 | #- name: GenericLinux 88 | # versions: 89 | # - all 90 | # - any 91 | #- name: NXOS 92 | # versions: 93 | # - all 94 | # - any 95 | #- name: IOS 96 | # versions: 97 | # - all 98 | # - any 99 | #- name: Amazon 100 | # versions: 101 | # - all 102 | # - 2013.03 103 | # - 2013.09 104 | # - 2016.03 105 | # - 2016.09 106 | #- name: ArchLinux 107 | # versions: 108 | # - all 109 | # - any 110 | #- name: FreeBSD 111 | # versions: 112 | # - all 113 | # - 10.0 114 | # - 10.1 115 | # - 10.2 116 | # - 10.3 117 | # - 11.0 118 | # - 8.0 119 | # - 8.1 120 | # - 8.2 121 | # - 8.3 122 | # - 8.4 123 | # - 9.0 124 | # - 9.1 125 | # - 9.1 126 | # - 9.2 127 | # - 9.3 128 | - name: Ubuntu 129 | versions: 130 | # - all 131 | # - lucid 132 | # - maverick 133 | # - natty 134 | # - oneiric 135 | # - precise 136 | # - quantal 137 | # - raring 138 | # - saucy 139 | - trusty 140 | # - utopic 141 | # - vivid 142 | # - wily 143 | - xenial 144 | # - yakkety 145 | - name: Debian 146 | versions: 147 | # - all 148 | # - etch 149 | - jessie 150 | # - lenny 151 | # - sid 152 | # - squeeze 153 | # - stretch 154 | # - wheezy 155 | #- name: Alpine 156 | # versions: 157 | # - all 158 | # - any 159 | - name: EL 160 | versions: 161 | # - all 162 | # - 5 163 | # - 6 164 | - 7 165 | #- name: Windows 166 | # versions: 167 | # - all 168 | # - 2012R2 169 | #- name: SmartOS 170 | # versions: 171 | # - all 172 | # - any 173 | #- name: opensuse 174 | # versions: 175 | # - all 176 | # - 12.1 177 | # - 12.2 178 | # - 12.3 179 | # - 13.1 180 | # - 13.2 181 | #- name: SLES 182 | # versions: 183 | # - all 184 | # - 10SP3 185 | # - 10SP4 186 | # - 11 187 | # - 11SP1 188 | # - 11SP2 189 | # - 11SP3 190 | # - 11SP4 191 | # - 12 192 | # - 12SP1 193 | #- name: GenericUNIX 194 | # versions: 195 | # - all 196 | # - any 197 | #- name: Solaris 198 | # versions: 199 | # - all 200 | # - 10 201 | # - 11.0 202 | # - 11.1 203 | # - 11.2 204 | # - 11.3 205 | #- name: eos 206 | # versions: 207 | # - all 208 | # - Any 209 | 210 | galaxy_tags: 211 | # List tags for your role here, one per line. A tag is 212 | # a keyword that describes and categorizes the role. 213 | # Users find roles by searching for tags. Be sure to 214 | # remove the '[]' above if you add tags to this list. 215 | # 216 | # NOTE: A tag is limited to a single word comprised of 217 | # alphanumeric characters. Maximum 20 tags per role. 218 | - cloud 219 | 220 | dependencies: [] 221 | # List your role dependencies here, one per line. 222 | # Be sure to remove the '[]' above if you add dependencies 223 | # to this list. 224 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # All Vagrant configuration is done below. The "2" in Vagrant.configure 5 | # configures the configuration version (we support older styles for 6 | # backwards compatibility). Please don't change it unless you know what 7 | # you're doing. 8 | 9 | # Ensure yaml module is loaded 10 | require 'yaml' 11 | 12 | # Read yaml node definitions to create 13 | # **Update nodes.yml to reflect any changes 14 | nodes = YAML.load_file(File.join(File.dirname(__FILE__), 'nodes.yml')) 15 | 16 | # Define global variables 17 | # 18 | 19 | Vagrant.configure(2) do |config| 20 | # Iterate over nodes to get a count 21 | # Define as 0 for counting the number of nodes to create from nodes.yml 22 | groups = [] # Define array to hold ansible groups 23 | num_nodes = 0 24 | populated_ansible_groups = {} # Create hash to contain iterated groups 25 | 26 | # Create array of Ansible Groups from iterated nodes 27 | nodes.each do |node| 28 | num_nodes = node 29 | node['ansible_groups'].each do |group| 30 | groups.push(group) 31 | end 32 | end 33 | 34 | # Remove duplicate Ansible Groups 35 | groups = groups.uniq 36 | 37 | # Iterate through array of Ansible Groups 38 | groups.each do |group| 39 | group_nodes = [] 40 | # Iterate list of nodes 41 | nodes.each do |node| 42 | node['ansible_groups'].each do |nodegroup| 43 | # Check if node is a member of iterated group 44 | group_nodes.push(node['name']) if nodegroup == group 45 | end 46 | populated_ansible_groups[group] = group_nodes 47 | end 48 | end 49 | 50 | # Dynamic Ansible Groups iterated from nodes.yml 51 | ansible_groups = populated_ansible_groups 52 | 53 | # Define Ansible groups statically for more control 54 | # ansible_groups = { 55 | # "spines" => ["node0", "node7"], 56 | # "leafs" => ["node[1:2]", "node[8:9]"], 57 | # "quagga-routers:children" => ["spines", "leafs", "compute-nodes"], 58 | # "compute-nodes" => ["node[3:6]"], 59 | # "docker-swarm:children" => ["docker-swarm-managers", "docker-swarm-workers"], 60 | # "docker-swarm-managers" => ["node[3:4]"], 61 | # "docker-swarm-workers" => ["node[5:6]"] 62 | # } 63 | 64 | # Iterate over nodes 65 | nodes.each do |node_id| 66 | # Below is needed if not using Guest Additions 67 | # config.vm.synced_folder ".", "/vagrant", type: "rsync", 68 | # rsync__exclude: "hosts" 69 | config.vm.define node_id['name'] do |node| 70 | unless node_id['synced_folder'].nil? 71 | unless node_id['synced_folder']['type'].nil? 72 | config.vm.synced_folder '.', '/vagrant', type: node_id['synced_folder']['type'] 73 | end 74 | end 75 | node.vm.box = node_id['box'] 76 | node.vm.hostname = node_id['name'] 77 | node.vm.provider 'virtualbox' do |vb| 78 | vb.memory = node_id['mem'] 79 | vb.cpus = node_id['vcpu'] 80 | 81 | # Setup desktop environment 82 | unless node_id['desktop'].nil? 83 | if node_id['desktop'] 84 | vb.gui = true 85 | vb.customize ['modifyvm', :id, '--graphicscontroller', 'vboxvga'] 86 | vb.customize ['modifyvm', :id, '--accelerate3d', 'on'] 87 | vb.customize ['modifyvm', :id, '--ioapic', 'on'] 88 | vb.customize ['modifyvm', :id, '--vram', '128'] 89 | vb.customize ['modifyvm', :id, '--hwvirtex', 'on'] 90 | end 91 | end 92 | 93 | # Add additional disk(s) 94 | unless node_id['disks'].nil? 95 | dnum = 0 96 | node_id['disks'].each do |disk_num| 97 | dnum = (dnum.to_i + 1) 98 | ddev = "#{node_id['name']}_Disk#{dnum}.vdi" 99 | dsize = disk_num['size'].to_i * 1024 100 | unless File.exist?(ddev.to_s) 101 | vb.customize ['createhd', '--filename', ddev.to_s, \ 102 | '--variant', 'Fixed', '--size', dsize] 103 | end 104 | vb.customize ['storageattach', :id, '--storagectl', \ 105 | (disk_num['controller']).to_s, '--port', dnum, '--device', 0, \ 106 | '--type', 'hdd', '--medium', ddev.to_s] 107 | end 108 | end 109 | end 110 | 111 | # Provision network interfaces 112 | unless node_id['interfaces'].nil? 113 | node_id['interfaces'].each do |int| 114 | if int['method'] == 'dhcp' 115 | if int['network_name'] == 'None' 116 | node.vm.network :private_network, \ 117 | type: 'dhcp' 118 | end 119 | if int['network_name'] != 'None' 120 | node.vm.network :private_network, \ 121 | virtualbox__intnet: int['network_name'], \ 122 | type: 'dhcp' 123 | end 124 | end 125 | next unless int['method'] == 'static' 126 | if int['network_name'] == 'None' 127 | node.vm.network :private_network, \ 128 | ip: int['ip'], \ 129 | auto_config: int['auto_config'] 130 | end 131 | next unless int['network_name'] != 'None' 132 | node.vm.network :private_network, \ 133 | virtualbox__intnet: int['network_name'], \ 134 | ip: int['ip'], \ 135 | auto_config: int['auto_config'] 136 | end 137 | end 138 | 139 | # Port Forwards 140 | unless node_id['port_forwards'].nil? 141 | node_id['port_forwards'].each do |pf| 142 | node.vm.network :forwarded_port, \ 143 | guest: pf['guest'], \ 144 | host: pf['host'] 145 | end 146 | end 147 | 148 | # Provisioners 149 | unless node_id['provision'].nil? 150 | if node_id['provision'] 151 | # runs initial shell script 152 | config.vm.provision :shell, path: 'bootstrap.sh', keep_color: 'true' 153 | if node_id == num_nodes 154 | node.vm.provision 'ansible' do |ansible| 155 | ansible.limit = 'all' 156 | # runs bootstrap Ansible playbook 157 | ansible.playbook = 'bootstrap.yml' 158 | end 159 | node.vm.provision 'ansible' do |ansible| 160 | ansible.limit = 'all' 161 | # runs Ansible playbook for installing roles/executing tasks 162 | ansible.playbook = 'playbook.yml' 163 | ansible.groups = ansible_groups 164 | end 165 | end 166 | end 167 | end 168 | end 169 | end 170 | end 171 | -------------------------------------------------------------------------------- /roles/ansible-docker/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # defaults file for ansible-docker 3 | 4 | # Ensure this exists if setting docker to alternate data directory 5 | # We do not create this to ensure any add'l mounts do not overlay this path 6 | # Service may fail to start if not. 7 | docker_alt_data_dir: '/mnt/docker' 8 | 9 | # Defines address of cluster address 10 | # Not the same as Swarm Cluster address 11 | # Ex. Consul 12 | docker_cluster_addr: "{{ hostvars[inventory_hostname]['ansible_' + docker_cluster_interface]['ipv4']['address'] }}" 13 | 14 | # Defines interface to capture address from for docker_cluster_addr 15 | docker_cluster_interface: "{{ docker_swarm_interface }}" 16 | 17 | docker_cluster_port: 2376 18 | 19 | # Defines if docker should be configured to store data in alternate location 20 | # ensure to enable -g option in docker_opts if true 21 | docker_config_alt_data_dir: false 22 | 23 | # Defines if docker service should be configured 24 | docker_config_service: false 25 | 26 | # Defines if users defined in docker_users should be added to docker group 27 | docker_config_users: false 28 | 29 | # Defines if various Python based Docker packages should get installed 30 | docker_manage_python_modules: true 31 | 32 | # Defines docker images to be installed 33 | docker_images: [] 34 | # # Defines image name 35 | # # ex. docker hub image name 36 | # - name: 'centos' 37 | # # Defines state of image 38 | # # present|absent 39 | # state: 'present' 40 | # - name: 'elasticsearch' 41 | # state: 'present' 42 | # - name: 'fedora' 43 | # state: 'present' 44 | # - name: 'ubuntu' 45 | # state: 'present' 46 | 47 | # Defines if images defined in docker_images are managed 48 | docker_manage_images: false 49 | 50 | # Defines docker service options to be configured in /etc/docker/daemon.json 51 | # Configure each option the same naming/format as the variables are set as at 52 | # https://docs.docker.com/engine/reference/commandline/dockerd/ 53 | # The values are converted directly to proper JSON using the Jinja2 template 54 | docker_opts: 55 | # Only define bridge or bip if you want to use either one of these 56 | # They cannot be used together 57 | # Specify network bridge IP 58 | # bip: '172.17.0.1/8' 59 | # Attach containers to a network bridge 60 | # bridge: 'docker0' 61 | # Address or interface name to advertise 62 | # cluster-advertise: '{{ docker_cluster_addr }}:{{ docker_cluster_port }}' 63 | # Set cluster store options 64 | # cluster-store: 'consul://192.168.250.10:8500' 65 | # Enable debug mode 66 | debug: false 67 | # Container default gateway IPv4 address 68 | # default-gateway: '10.10.10.1' 69 | # Default ulimits for containers 70 | # default-ulimit: 71 | # - nofile: '64000:64000' 72 | # DNS server to use 73 | # dns: 74 | # - '8.8.8.8' 75 | # - '8.8.4.4' 76 | # DNS search domains to use 77 | # dns-search: 78 | # - 'etsbv.internal' 79 | # - 'etsbv.test' 80 | # Enable insecure registry communication 81 | # insecure-registries: 82 | # - 'gitlab.etsbv.internal:5000' 83 | # Default IP when binding container ports 84 | # ip: '0.0.0.0' 85 | # Enable net.ipv4.ip_forward 86 | ip-forward: true 87 | # Enable IP masquerading 88 | ip-masq: true 89 | # Enable addition of iptables rules 90 | iptables: true 91 | # Set key=value labels to the daemon 92 | # label: 93 | # - environment: 'test' 94 | # - datacenter: 'atlanta' 95 | # Default driver for container logs 96 | # Default is json-file 97 | log-driver: 'json-file' 98 | # Fluentd log driver setup 99 | # log-driver: 'fluentd' 100 | # log-opts: 101 | # fluentd-address: 'fluentdhost:24224' 102 | # # fluentd-address: tcp://fluentdhost:24224 103 | # End of Fluentd log driver setup 104 | # GELF (Graylog) log driver setup 105 | # log-driver: 'gelf' 106 | # log-opts: 107 | # gelf-address: 'udp://1.2.3.4:12201' 108 | # tag: '{% raw %}{{.Name}}/{{.FullID}}{% endraw %}' 109 | # labels: 'location' 110 | # env: 'TEST' 111 | # End of GELF (Graylog) log driver setup 112 | # Splunk log driver setup 113 | # log-driver: 'splunk' 114 | # log-opts: 115 | # splunk-token: '176FCEBF-4CF5-4EDF-91BC-703796522D20' 116 | # splunk-url: 'https://splunkhost:8088' 117 | # splunk-capath: '/path/to/cert/cacert.pem' 118 | # splunk-caname: 'SplunkServerDefaultCert' 119 | # tag: '{% raw %}{{.Name}}/{{.FullID}}{% endraw %}' 120 | # labels: 'location' 121 | # env: 'TEST' 122 | # End of Splunk log driver setup 123 | # Syslog log driver setup 124 | # log-driver: 'syslog' 125 | # log-opts: 126 | # # Define syslog address or leave commented out for logging to host local 127 | # # syslog. 128 | # # syslog-address: 'udp://1.2.3.4:1111' 129 | # tag: '{% raw %}{{.Name}}/{{.FullID}}{% endraw %}' 130 | # labels: 'location' 131 | # env: 'TEST' 132 | # Set the logging level 133 | log-level: 'info' 134 | # Set the max concurrent downloads for each pull 135 | max-concurrent-downloads: 3 136 | # Set the max concurrent uploads for each push 137 | max-concurrent-uploads: 5 138 | # Set the containers network MTU 139 | # mtu: 1500 140 | # Enable selinux support 141 | selinux-enabled: false 142 | # Storage driver to use 143 | # aufs, devicemapper, btrfs, zfs, overlay and overlay2 144 | # storage-driver: 'aufs' 145 | # Set default address or interface for swarm advertised address 146 | swarm-default-advertise-addr: "{{ docker_swarm_addr }}" 147 | # Use TLS; implied by –tlsverify 148 | # tls: false 149 | 150 | # Defines which repo to install from 151 | # Stable gives you reliable updates every quarter 152 | # Edge gives you new features every month 153 | # define as stable or edge 154 | docker_release_channel: 'stable' 155 | 156 | # Defines if the linux-image-extra-{{ ansible_kernel }} package should get installed (only >= Ubuntu 14.04). 157 | docker_linux_image_extra: true 158 | 159 | # Defines if docker memory limits should be added to grub boot loader 160 | docker_set_grub_memory_limit: true 161 | 162 | # Defines if Linux birdge-utils will get installed. 163 | docker_install_bridge_utils: true 164 | 165 | docker_swarm_addr: "{{ hostvars[inventory_hostname]['ansible_' + docker_swarm_interface]['ipv4']['address'] }}" 166 | 167 | docker_swarm_interface: 'enp0s8' 168 | 169 | # Defines docker ubuntu repo info for installing from 170 | docker_ubuntu_repo_info: 171 | id: '0EBFCD88' 172 | # keyserver: 'hkp://p80.pool.sks-keyservers.net:80' 173 | repo: 'deb [arch=amd64] https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} {{ docker_release_channel }}' 174 | url: 'https://download.docker.com/linux/ubuntu/gpg' 175 | 176 | # Defines users to be added to docker group to allow non sudo access to docker 177 | docker_users: [] 178 | # - 'vagrant' 179 | 180 | # Define Docker version to install 181 | # 1.11.0|1.11.1|1.11.2|1.12.0|1.12.1|1.12.2|1.12.3|1.12.4|1.12.5|1.12.6|1.13.0|1.13.1 182 | # 17.03.0|17.03.1|17.03.2|17.04.0|17.05.0|17.06.0|17.12.0 183 | # Currently as of 06/03/2017 17.04.0 and 17.05.0 must be installed from the 184 | # edge channel. Change docker_release_channel: 'edge' 185 | docker_version: 17.12.0 186 | -------------------------------------------------------------------------------- /roles/ansible-docker/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | **Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)* 4 | 5 | - [ansible-docker](#ansible-docker) 6 | - [Build Status](#build-status) 7 | - [Requirements](#requirements) 8 | - [Role Variables](#role-variables) 9 | - [Dependencies](#dependencies) 10 | - [Example Playbook](#example-playbook) 11 | - [License](#license) 12 | - [Author Information](#author-information) 13 | 14 | 15 | 16 | # ansible-docker 17 | 18 | An [Ansible](https://www.ansible.com) role to install/configure [Docker](https://www.docker.com) 19 | 20 | ## Build Status 21 | 22 | [![Build Status](https://travis-ci.org/mrlesmithjr/ansible-docker.svg?branch=master)](https://travis-ci.org/mrlesmithjr/ansible-docker) 23 | 24 | ## Requirements 25 | 26 | None 27 | 28 | ## Role Variables 29 | 30 | ```yaml 31 | --- 32 | # defaults file for ansible-docker 33 | 34 | # Ensure this exists if setting docker to alternate data directory 35 | # We do not create this to ensure any add'l mounts do not overlay this path 36 | # Service may fail to start if not. 37 | docker_alt_data_dir: '/mnt/docker' 38 | 39 | # Defines address of cluster address 40 | # Not the same as Swarm Cluster address 41 | # Ex. Consul 42 | docker_cluster_addr: "{{ hostvars[inventory_hostname]['ansible_' + docker_cluster_interface]['ipv4']['address'] }}" 43 | 44 | # Defines interface to capture address from for docker_cluster_addr 45 | docker_cluster_interface: "{{ docker_swarm_interface }}" 46 | 47 | docker_cluster_port: 2376 48 | 49 | # Defines if docker should be configured to store data in alternate location 50 | # ensure to enable -g option in docker_opts if true 51 | docker_config_alt_data_dir: false 52 | 53 | # Defines if docker service should be configured 54 | docker_config_service: false 55 | 56 | # Defines if users defined in docker_users should be added to docker group 57 | docker_config_users: false 58 | 59 | # Defines docker images to be installed 60 | docker_images: [] 61 | # # Defines image name 62 | # # ex. docker hub image name 63 | # - name: 'centos' 64 | # # Defines state of image 65 | # # present|absent 66 | # state: 'present' 67 | # - name: 'elasticsearch' 68 | # state: 'present' 69 | # - name: 'fedora' 70 | # state: 'present' 71 | # - name: 'ubuntu' 72 | # state: 'present' 73 | 74 | # Defines if images defined in docker_images are managed 75 | docker_manage_images: false 76 | 77 | # Defines docker service options to be configured in /etc/docker/daemon.json 78 | # Configure each option the same naming/format as the variables are set as at 79 | # https://docs.docker.com/engine/reference/commandline/dockerd/ 80 | # The values are converted directly to proper JSON using the Jinja2 template 81 | docker_opts: 82 | # Only define bridge or bip if you want to use either one of these 83 | # They cannot be used together 84 | # Specify network bridge IP 85 | # bip: '172.17.0.1/8' 86 | # Attach containers to a network bridge 87 | # bridge: 'docker0' 88 | # Address or interface name to advertise 89 | # cluster-advertise: '{{ docker_cluster_addr }}:{{ docker_cluster_port }}' 90 | # Set cluster store options 91 | # cluster-store: 'consul://192.168.250.10:8500' 92 | # Enable debug mode 93 | debug: false 94 | # Container default gateway IPv4 address 95 | # default-gateway: '10.10.10.1' 96 | # Default ulimits for containers 97 | # default-ulimit: 98 | # - nofile: '64000:64000' 99 | # DNS server to use 100 | # dns: 101 | # - '8.8.8.8' 102 | # - '8.8.4.4' 103 | # DNS search domains to use 104 | # dns-search: 105 | # - 'etsbv.internal' 106 | # - 'etsbv.test' 107 | # Enable insecure registry communication 108 | # insecure-registries: 109 | # - 'gitlab.etsbv.internal:5000' 110 | # Default IP when binding container ports 111 | # ip: '0.0.0.0' 112 | # Enable net.ipv4.ip_forward 113 | ip-forward: true 114 | # Enable IP masquerading 115 | ip-masq: true 116 | # Enable addition of iptables rules 117 | iptables: true 118 | # Set key=value labels to the daemon 119 | # label: 120 | # - environment: 'test' 121 | # - datacenter: 'atlanta' 122 | # Default driver for container logs 123 | # Default is json-file 124 | log-driver: 'json-file' 125 | # Fluentd log driver setup 126 | # log-driver: 'fluentd' 127 | # log-opts: 128 | # fluentd-address: 'fluentdhost:24224' 129 | # # fluentd-address: tcp://fluentdhost:24224 130 | # End of Fluentd log driver setup 131 | # GELF (Graylog) log driver setup 132 | # log-driver: 'gelf' 133 | # log-opts: 134 | # gelf-address: 'udp://1.2.3.4:12201' 135 | # tag: '{% raw %}{{.Name}}/{{.FullID}}{% endraw %}' 136 | # labels: 'location' 137 | # env: 'TEST' 138 | # End of GELF (Graylog) log driver setup 139 | # Splunk log driver setup 140 | # log-driver: 'splunk' 141 | # log-opts: 142 | # splunk-token: '176FCEBF-4CF5-4EDF-91BC-703796522D20' 143 | # splunk-url: 'https://splunkhost:8088' 144 | # splunk-capath: '/path/to/cert/cacert.pem' 145 | # splunk-caname: 'SplunkServerDefaultCert' 146 | # tag: '{% raw %}{{.Name}}/{{.FullID}}{% endraw %}' 147 | # labels: 'location' 148 | # env: 'TEST' 149 | # End of Splunk log driver setup 150 | # Syslog log driver setup 151 | # log-driver: 'syslog' 152 | # log-opts: 153 | # # Define syslog address or leave commented out for logging to host local 154 | # # syslog. 155 | # # syslog-address: 'udp://1.2.3.4:1111' 156 | # tag: '{% raw %}{{.Name}}/{{.FullID}}{% endraw %}' 157 | # labels: 'location' 158 | # env: 'TEST' 159 | # Set the logging level 160 | log-level: 'info' 161 | # Set the max concurrent downloads for each pull 162 | max-concurrent-downloads: 3 163 | # Set the max concurrent uploads for each push 164 | max-concurrent-uploads: 5 165 | # Set the containers network MTU 166 | # mtu: 1500 167 | # Enable selinux support 168 | selinux-enabled: false 169 | # Storage driver to use 170 | # aufs, devicemapper, btrfs, zfs, overlay and overlay2 171 | # storage-driver: 'aufs' 172 | # Set default address or interface for swarm advertised address 173 | swarm-default-advertise-addr: "{{ docker_swarm_addr }}" 174 | # Use TLS; implied by –tlsverify 175 | # tls: false 176 | 177 | # Defines which repo to install from 178 | # Stable gives you reliable updates every quarter 179 | # Edge gives you new features every month 180 | # define as stable or edge 181 | docker_release_channel: 'stable' 182 | 183 | # Defines if docker memory limits should be added to grub boot loader 184 | docker_set_grub_memory_limit: true 185 | 186 | docker_swarm_addr: "{{ hostvars[inventory_hostname]['ansible_' + docker_swarm_interface]['ipv4']['address'] }}" 187 | 188 | docker_swarm_interface: 'enp0s8' 189 | 190 | # Defines docker ubuntu repo info for installing from 191 | docker_ubuntu_repo_info: 192 | id: '0EBFCD88' 193 | # keyserver: 'hkp://p80.pool.sks-keyservers.net:80' 194 | repo: 'deb [arch=amd64] https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} {{ docker_release_channel }}' 195 | url: 'https://download.docker.com/linux/ubuntu/gpg' 196 | 197 | # Defines users to be added to docker group to allow non sudo access to docker 198 | docker_users: [] 199 | # - 'vagrant' 200 | 201 | # Define Docker version to install 202 | # 1.11.0|1.11.1|1.11.2|1.12.0|1.12.1|1.12.2|1.12.3|1.12.4|1.12.5|1.12.6|1.13.0|1.13.1 203 | # 17.03.0|17.03.1|17.03.2|17.04.0|17.05.0|17.06.0 204 | # Currently as of 06/03/2017 17.04.0 and 17.05.0 must be installed from the 205 | # edge channel. Change docker_release_channel: 'edge' 206 | docker_version: 17.06.0 207 | ``` 208 | 209 | ## Dependencies 210 | 211 | None 212 | 213 | ## Example Playbook 214 | 215 | ```yaml 216 | --- 217 | - hosts: docker_hosts 218 | vars: 219 | docker_swarm_interface: "eth1" 220 | docker_config_service: true 221 | pri_domain_name: 'test.vagrant.local' 222 | roles: 223 | - role: ansible-docker 224 | tasks: 225 | ``` 226 | 227 | ## License 228 | 229 | MIT 230 | 231 | ## Author Information 232 | 233 | Larry Smith Jr. 234 | 235 | - [@mrlesmithjr](https://www.twitter.com/mrlesmithjr) 236 | - [EverythingShouldBeVirtual](http://everythingshouldbevirtual.com) 237 | - [mrlesmithjr.com](http://mrlesmithjr.com) 238 | - mrlesmithjr [at] gmail.com 239 | -------------------------------------------------------------------------------- /bootstrap.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | remote_user: vagrant 4 | vars: 5 | alpine_packages: 6 | - alpine-sdk 7 | - libffi-dev 8 | - openssl-dev 9 | - py-setuptools 10 | ansible_ver: 2.2.0.0 11 | debian_packages: 12 | - build-essential 13 | - libffi-dev 14 | - libssl-dev 15 | - python-dev 16 | - python-pip 17 | - python-setuptools 18 | host_vars_directory: ./host_vars 19 | host_vars_file: '{{ host_vars_directory }}/{{ inventory_hostname }}.yml' 20 | pri_domain_name: vagrant.local 21 | redhat_packages: 22 | - gmp-devel 23 | - libffi-devel 24 | - openssl-devel 25 | - python-crypto 26 | - python-devel 27 | - python-pip 28 | - python-setuptools 29 | - redhat-rpm-config 30 | ssh_key_path: '.vagrant/machines/{{ inventory_hostname }}/virtualbox/private_key' 31 | suse_packages: 32 | - gmp-devel 33 | - libffi-devel 34 | - openssl-devel 35 | - python-crypto 36 | - python-devel 37 | - python-pip 38 | - python-setuptools 39 | update_host_vars: true 40 | roles: 41 | tasks: 42 | # Update apt-cache to ensure up to date 43 | - name: Updating Apt Cache (Debian) 44 | apt: 45 | update_cache: yes 46 | cache_valid_time: 3600 47 | become: true 48 | when: ansible_os_family == "Debian" 49 | 50 | # Install pre-reqs for Ansible install 51 | - name: Installing Ansible Pre-Reqs (Alpine) 52 | apk: 53 | name: "{{ item }}" 54 | state: "present" 55 | become: true 56 | with_items: '{{ alpine_packages }}' 57 | when: ansible_os_family == "Alpine" 58 | 59 | - name: Installing Python Packages (Alpine) 60 | apk: 61 | name: "{{ item }}" 62 | state: "present" 63 | become: true 64 | with_items: 65 | - py-pip 66 | - python-dev 67 | when: > 68 | ansible_os_family == "Alpine" and 69 | ansible_distribution_version < '3.5' 70 | 71 | - name: Installing Python Packages (Alpine) 72 | apk: 73 | name: "{{ item }}" 74 | state: "present" 75 | become: true 76 | with_items: 77 | - py2-pip 78 | - python2-dev 79 | when: > 80 | ansible_os_family == "Alpine" and 81 | ansible_distribution_version >= '3.5' 82 | 83 | # Install pre-reqs for Ansible install 84 | - name: Installing Ansible Pre-Reqs (Debian) 85 | apt: 86 | name: "{{ item }}" 87 | state: "present" 88 | become: true 89 | with_items: '{{ debian_packages }}' 90 | when: ansible_os_family == "Debian" 91 | 92 | - name: Installing EPEL Repo (RedHat) 93 | yum: 94 | name: "epel-release" 95 | state: "present" 96 | become: true 97 | when: > 98 | ansible_os_family == "RedHat" and 99 | ansible_distribution != "Fedora" 100 | 101 | # Install pre-reqs for Ansible install 102 | - name: Installing Ansible Pre-Reqs (RedHat) 103 | yum: 104 | name: "{{ item }}" 105 | state: "present" 106 | become: true 107 | with_items: '{{ redhat_packages }}' 108 | when: > 109 | ansible_os_family == "RedHat" and 110 | ansible_distribution != "Fedora" 111 | 112 | # Install pre-reqs for Ansible install 113 | - name: Installing Ansible Pre-Reqs (Fedora) 114 | dnf: 115 | name: "python-dnf" 116 | state: "present" 117 | become: true 118 | when: > 119 | ansible_os_family == "RedHat" and 120 | ansible_distribution == "Fedora" 121 | 122 | # Install pre-reqs for Ansible install 123 | - name: Installing Ansible Pre-Reqs (Fedora) 124 | dnf: 125 | name: "{{ item }}" 126 | state: "present" 127 | become: true 128 | with_items: '{{ redhat_packages }}' 129 | when: > 130 | ansible_os_family == "RedHat" and 131 | ansible_distribution == "Fedora" 132 | 133 | # Install pre-reqs for Ansible install 134 | - name: Installing Ansible Pre-Reqs (openSUSE) 135 | zypper: 136 | name: "{{ item }}" 137 | state: "present" 138 | become: true 139 | with_items: '{{ suse_packages }}' 140 | when: ansible_os_family == "Suse" 141 | 142 | # Upgrading these packages to ensure a successful Ansible install 143 | - name: Updating Python Modules 144 | pip: 145 | name: "{{ item }}" 146 | state: "latest" 147 | become: true 148 | with_items: 149 | - pip 150 | - cffi 151 | 152 | # Install Ansible to run Ansible related tasks within guest 153 | - name: Installing Ansible 154 | pip: 155 | name: "ansible" 156 | state: "present" 157 | version: "{{ ansible_ver }}" 158 | become: true 159 | 160 | # Check/create host_vars on localhost 161 | - name: Ensuring host_vars Directory Exists 162 | file: 163 | path: "./host_vars" 164 | state: "directory" 165 | delegate_to: "localhost" 166 | run_once: true 167 | become: false 168 | when: > 169 | update_host_vars is defined and 170 | update_host_vars 171 | 172 | - name: Ensuring Host File Exists In host_vars 173 | stat: 174 | path: "{{ host_vars_file }}" 175 | delegate_to: "localhost" 176 | register: "host_var" 177 | become: false 178 | when: > 179 | update_host_vars is defined and 180 | update_host_vars 181 | 182 | - name: Creating Missing host_vars 183 | file: 184 | path: "{{ host_vars_file }}" 185 | state: "touch" 186 | delegate_to: "localhost" 187 | become: false 188 | when: not host_var['stat']['exists'] 189 | 190 | - name: Updating ansible_ssh_host 191 | lineinfile: 192 | dest: "{{ host_vars_file }}" 193 | regexp: "^ansible_ssh_host{{ ':' }}" 194 | line: "ansible_ssh_host{{ ':' }} {{ ansible_eth1['ipv4']['address'] }}" 195 | delegate_to: "localhost" 196 | become: false 197 | register: "ansible_host_updated_eth1" 198 | when: > 199 | ansible_os_family != "Alpine" and 200 | (update_host_vars is defined and 201 | update_host_vars) and 202 | (ansible_eth1 is defined and 203 | ansible_eth1['ipv4']['address'] is defined) 204 | 205 | - name: Updating ansible_ssh_host 206 | lineinfile: 207 | dest: "{{ host_vars_file }}" 208 | regexp: "^ansible_ssh_host{{ ':' }}" 209 | line: "ansible_ssh_host{{ ':' }} {{ ansible_enp0s8['ipv4']['address'] }}" 210 | delegate_to: "localhost" 211 | become: false 212 | register: "ansible_host_updated_enp0s8" 213 | when: > 214 | ansible_os_family != "Alpine" and 215 | (update_host_vars is defined and 216 | update_host_vars) and 217 | (ansible_enp0s8 is defined and 218 | ansible_enp0s8['ipv4']['address'] is defined) 219 | 220 | - name: Capturing eth1 IP Address (Alpine) 221 | shell: "ifconfig eth1 | grep 'inet addr:' | cut -d: -f2 | awk '{print $1}'" 222 | register: "_alpine_eth1_ip" 223 | become: true 224 | when: ansible_os_family == "Alpine" 225 | 226 | - name: Updating ansible_ssh_host (Alpine) 227 | lineinfile: 228 | dest: "{{ host_vars_file }}" 229 | regexp: "^ansible_ssh_host{{ ':' }}" 230 | line: "ansible_ssh_host{{ ':' }} {{ _alpine_eth1_ip['stdout'] }}" 231 | delegate_to: "localhost" 232 | become: false 233 | register: "ansible_host_updated_alpine" 234 | when: > 235 | (update_host_vars is defined and 236 | update_host_vars) and 237 | ansible_os_family == "Alpine" 238 | 239 | - name: Updating ansible_ssh_port 240 | lineinfile: 241 | dest: "{{ host_vars_file }}" 242 | regexp: "^ansible_ssh_port{{ ':' }}" 243 | line: "ansible_ssh_port{{ ':' }} 22" 244 | delegate_to: "localhost" 245 | become: false 246 | when: > 247 | (update_host_vars is defined and 248 | update_host_vars) and 249 | (ansible_host_updated_eth1['changed'] or 250 | ansible_host_updated_enp0s8['changed'] or 251 | ansible_host_updated_alpine['changed']) 252 | 253 | - name: Updating ansible_ssh_key 254 | lineinfile: 255 | dest: "{{ host_vars_file }}" 256 | regexp: "^ansible_ssh_private_key_file{{ ':' }}" 257 | line: "ansible_ssh_private_key_file{{ ':' }} {{ ssh_key_path }}" 258 | delegate_to: "localhost" 259 | become: false 260 | when: > 261 | update_host_vars is defined and 262 | update_host_vars 263 | 264 | - name: Ensuring host_vars Is YAML Formatted 265 | lineinfile: 266 | dest: "{{ host_vars_file }}" 267 | regexp: "---" 268 | line: "---" 269 | insertbefore: "BOF" 270 | delegate_to: "localhost" 271 | become: false 272 | when: > 273 | update_host_vars is defined and 274 | update_host_vars 275 | -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | # config file for ansible -- http://ansible.com/ 2 | # ============================================== 3 | 4 | # nearly all parameters can be overridden in ansible-playbook 5 | # or with command line flags. ansible will read ANSIBLE_CONFIG, 6 | # ansible.cfg in the current working directory, .ansible.cfg in 7 | # the home directory or /etc/ansible/ansible.cfg, whichever it 8 | # finds first 9 | 10 | [defaults] 11 | 12 | # some basic default values... 13 | 14 | #inventory = /etc/ansible/hosts 15 | #library = /usr/share/my_modules/ 16 | #remote_tmp = ~/.ansible/tmp 17 | #local_tmp = ~/.ansible/tmp 18 | #forks = 5 19 | #poll_interval = 15 20 | #sudo_user = root 21 | #ask_sudo_pass = True 22 | #ask_pass = True 23 | #transport = smart 24 | #remote_port = 22 25 | #module_lang = C 26 | #module_set_locale = False 27 | 28 | # plays will gather facts by default, which contain information about 29 | # the remote system. 30 | # 31 | # smart - gather by default, but don't regather if already gathered 32 | # implicit - gather by default, turn off with gather_facts: False 33 | # explicit - do not gather by default, must say gather_facts: True 34 | #gathering = implicit 35 | 36 | # This only affects the gathering done by a play's gather_facts directive, 37 | # by default gathering retrieves all facts subsets 38 | # all - gather all subsets 39 | # network - gather min and network facts 40 | # hardware - gather hardware facts (longest facts to retrieve) 41 | # virtual - gather min and virtual facts 42 | # facter - import facts from facter 43 | # ohai - import facts from ohai 44 | # You can combine them using comma (ex: network,virtual) 45 | # You can negate them using ! (ex: !hardware,!facter,!ohai) 46 | # A minimal set of facts is always gathered. 47 | #gather_subset = all 48 | 49 | # some hardware related facts are collected 50 | # with a maximum timeout of 10 seconds. This 51 | # option lets you increase or decrease that 52 | # timeout to something more suitable for the 53 | # environment. 54 | # gather_timeout = 10 55 | 56 | # additional paths to search for roles in, colon separated 57 | #roles_path = /etc/ansible/roles 58 | 59 | # uncomment this to disable SSH key host checking 60 | host_key_checking = False 61 | 62 | # change the default callback 63 | #stdout_callback = skippy 64 | # enable additional callbacks 65 | #callback_whitelist = log_plays 66 | 67 | # Determine whether includes in tasks and handlers are "static" by 68 | # default. As of 2.0, includes are dynamic by default. Setting these 69 | # values to True will make includes behave more like they did in the 70 | # 1.x versions. 71 | #task_includes_static = True 72 | #handler_includes_static = True 73 | 74 | # Controls if a missing handler for a notification event is an error or a warning 75 | #error_on_missing_handler = True 76 | 77 | # change this for alternative sudo implementations 78 | #sudo_exe = sudo 79 | 80 | # What flags to pass to sudo 81 | # WARNING: leaving out the defaults might create unexpected behaviours 82 | #sudo_flags = -H -S -n 83 | 84 | # SSH timeout 85 | #timeout = 10 86 | 87 | # default user to use for playbooks if user is not specified 88 | # (/usr/bin/ansible will use current user as default) 89 | #remote_user = root 90 | 91 | # logging is off by default unless this path is defined 92 | # if so defined, consider logrotate 93 | #log_path = /var/log/ansible.log 94 | 95 | # default module name for /usr/bin/ansible 96 | #module_name = command 97 | 98 | # use this shell for commands executed under sudo 99 | # you may need to change this to bin/bash in rare instances 100 | # if sudo is constrained 101 | #executable = /bin/sh 102 | 103 | # if inventory variables overlap, does the higher precedence one win 104 | # or are hash values merged together? The default is 'replace' but 105 | # this can also be set to 'merge'. 106 | #hash_behaviour = replace 107 | 108 | # by default, variables from roles will be visible in the global variable 109 | # scope. To prevent this, the following option can be enabled, and only 110 | # tasks and handlers within the role will see the variables there 111 | #private_role_vars = yes 112 | 113 | # list any Jinja2 extensions to enable here: 114 | #jinja2_extensions = jinja2.ext.do,jinja2.ext.i18n 115 | 116 | # if set, always use this private key file for authentication, same as 117 | # if passing --private-key to ansible or ansible-playbook 118 | #private_key_file = /path/to/file 119 | 120 | # If set, configures the path to the Vault password file as an alternative to 121 | # specifying --vault-password-file on the command line. 122 | #vault_password_file = /path/to/vault_password_file 123 | 124 | # format of string {{ ansible_managed }} available within Jinja2 125 | # templates indicates to users editing templates files will be replaced. 126 | # replacing {file}, {host} and {uid} and strftime codes with proper values. 127 | #ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host} 128 | # {file}, {host}, {uid}, and the timestamp can all interfere with idempotence 129 | # in some situations so the default is a static string: 130 | ansible_managed = Ansible managed 131 | 132 | # by default, ansible-playbook will display "Skipping [host]" if it determines a task 133 | # should not be run on a host. Set this to "False" if you don't want to see these "Skipping" 134 | # messages. NOTE: the task header will still be shown regardless of whether or not the 135 | # task is skipped. 136 | #display_skipped_hosts = True 137 | 138 | # by default, if a task in a playbook does not include a name: field then 139 | # ansible-playbook will construct a header that includes the task's action but 140 | # not the task's args. This is a security feature because ansible cannot know 141 | # if the *module* considers an argument to be no_log at the time that the 142 | # header is printed. If your environment doesn't have a problem securing 143 | # stdout from ansible-playbook (or you have manually specified no_log in your 144 | # playbook on all of the tasks where you have secret information) then you can 145 | # safely set this to True to get more informative messages. 146 | #display_args_to_stdout = False 147 | 148 | # by default (as of 1.3), Ansible will raise errors when attempting to dereference 149 | # Jinja2 variables that are not set in templates or action lines. Uncomment this line 150 | # to revert the behavior to pre-1.3. 151 | #error_on_undefined_vars = False 152 | 153 | # by default (as of 1.6), Ansible may display warnings based on the configuration of the 154 | # system running ansible itself. This may include warnings about 3rd party packages or 155 | # other conditions that should be resolved if possible. 156 | # to disable these warnings, set the following value to False: 157 | #system_warnings = True 158 | 159 | # by default (as of 1.4), Ansible may display deprecation warnings for language 160 | # features that should no longer be used and will be removed in future versions. 161 | # to disable these warnings, set the following value to False: 162 | #deprecation_warnings = True 163 | 164 | # (as of 1.8), Ansible can optionally warn when usage of the shell and 165 | # command module appear to be simplified by using a default Ansible module 166 | # instead. These warnings can be silenced by adjusting the following 167 | # setting or adding warn=yes or warn=no to the end of the command line 168 | # parameter string. This will for example suggest using the git module 169 | # instead of shelling out to the git command. 170 | # command_warnings = False 171 | 172 | 173 | # set plugin path directories here, separate with colons 174 | #action_plugins = /usr/share/ansible/plugins/action 175 | #cache_plugins = /usr/share/ansible/plugins/cache 176 | #callback_plugins = /usr/share/ansible/plugins/callback 177 | #connection_plugins = /usr/share/ansible/plugins/connection 178 | #lookup_plugins = /usr/share/ansible/plugins/lookup 179 | #inventory_plugins = /usr/share/ansible/plugins/inventory 180 | #vars_plugins = /usr/share/ansible/plugins/vars 181 | #filter_plugins = /usr/share/ansible/plugins/filter 182 | #test_plugins = /usr/share/ansible/plugins/test 183 | #strategy_plugins = /usr/share/ansible/plugins/strategy 184 | 185 | 186 | # by default, ansible will use the 'linear' strategy but you may want to try 187 | # another one 188 | #strategy = free 189 | 190 | # by default callbacks are not loaded for /bin/ansible, enable this if you 191 | # want, for example, a notification or logging callback to also apply to 192 | # /bin/ansible runs 193 | #bin_ansible_callbacks = False 194 | 195 | 196 | # don't like cows? that's unfortunate. 197 | # set to 1 if you don't want cowsay support or export ANSIBLE_NOCOWS=1 198 | #nocows = 1 199 | 200 | # set which cowsay stencil you'd like to use by default. When set to 'random', 201 | # a random stencil will be selected for each task. The selection will be filtered 202 | # against the `cow_whitelist` option below. 203 | #cow_selection = default 204 | #cow_selection = random 205 | 206 | # when using the 'random' option for cowsay, stencils will be restricted to this list. 207 | # it should be formatted as a comma-separated list with no spaces between names. 208 | # NOTE: line continuations here are for formatting purposes only, as the INI parser 209 | # in python does not support them. 210 | #cow_whitelist=bud-frogs,bunny,cheese,daemon,default,dragon,elephant-in-snake,elephant,eyes,\ 211 | # hellokitty,kitty,luke-koala,meow,milk,moofasa,moose,ren,sheep,small,stegosaurus,\ 212 | # stimpy,supermilker,three-eyes,turkey,turtle,tux,udder,vader-koala,vader,www 213 | 214 | # don't like colors either? 215 | # set to 1 if you don't want colors, or export ANSIBLE_NOCOLOR=1 216 | #nocolor = 1 217 | 218 | # if set to a persistent type (not 'memory', for example 'redis') fact values 219 | # from previous runs in Ansible will be stored. This may be useful when 220 | # wanting to use, for example, IP information from one group of servers 221 | # without having to talk to them in the same playbook run to get their 222 | # current IP information. 223 | #fact_caching = memory 224 | 225 | 226 | # retry files 227 | # When a playbook fails by default a .retry file will be created in ~/ 228 | # You can disable this feature by setting retry_files_enabled to False 229 | # and you can change the location of the files by setting retry_files_save_path 230 | 231 | #retry_files_enabled = False 232 | #retry_files_save_path = ~/.ansible-retry 233 | 234 | # squash actions 235 | # Ansible can optimise actions that call modules with list parameters 236 | # when looping. Instead of calling the module once per with_ item, the 237 | # module is called once with all items at once. Currently this only works 238 | # under limited circumstances, and only with parameters named 'name'. 239 | #squash_actions = apk,apt,dnf,homebrew,pacman,pkgng,yum,zypper 240 | 241 | # prevents logging of task data, off by default 242 | #no_log = False 243 | 244 | # prevents logging of tasks, but only on the targets, data is still logged on the master/controller 245 | #no_target_syslog = False 246 | 247 | # controls whether Ansible will raise an error or warning if a task has no 248 | # choice but to create world readable temporary files to execute a module on 249 | # the remote machine. This option is False by default for security. Users may 250 | # turn this on to have behaviour more like Ansible prior to 2.1.x. See 251 | # https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user 252 | # for more secure ways to fix this than enabling this option. 253 | #allow_world_readable_tmpfiles = False 254 | 255 | # controls the compression level of variables sent to 256 | # worker processes. At the default of 0, no compression 257 | # is used. This value must be an integer from 0 to 9. 258 | #var_compression_level = 9 259 | 260 | # controls what compression method is used for new-style ansible modules when 261 | # they are sent to the remote system. The compression types depend on having 262 | # support compiled into both the controller's python and the client's python. 263 | # The names should match with the python Zipfile compression types: 264 | # * ZIP_STORED (no compression. available everywhere) 265 | # * ZIP_DEFLATED (uses zlib, the default) 266 | # These values may be set per host via the ansible_module_compression inventory 267 | # variable 268 | #module_compression = 'ZIP_DEFLATED' 269 | 270 | # This controls the cutoff point (in bytes) on --diff for files 271 | # set to 0 for unlimited (RAM may suffer!). 272 | #max_diff_size = 1048576 273 | 274 | # This controls how ansible handles multiple --tags and --skip-tags arguments 275 | # on the CLI. If this is True then multiple arguments are merged together. If 276 | # it is False, then the last specified argument is used and the others are ignored. 277 | #merge_multiple_cli_flags = False 278 | 279 | # Controls showing custom stats at the end, off by default 280 | #show_custom_stats = True 281 | 282 | [privilege_escalation] 283 | #become=True 284 | #become_method=sudo 285 | #become_user=root 286 | #become_ask_pass=False 287 | 288 | [paramiko_connection] 289 | 290 | # uncomment this line to cause the paramiko connection plugin to not record new host 291 | # keys encountered. Increases performance on new host additions. Setting works independently of the 292 | # host key checking setting above. 293 | #record_host_keys=False 294 | 295 | # by default, Ansible requests a pseudo-terminal for commands executed under sudo. Uncomment this 296 | # line to disable this behaviour. 297 | #pty=False 298 | 299 | [ssh_connection] 300 | 301 | # ssh arguments to use 302 | # Leaving off ControlPersist will result in poor performance, so use 303 | # paramiko on older platforms rather than removing it, -C controls compression use 304 | #ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s 305 | 306 | # The base directory for the ControlPath sockets. 307 | # This is the "%(directory)s" in the control_path option 308 | # 309 | # Example: 310 | # control_path_dir = /tmp/.ansible/cp 311 | #control_path_dir = ~/.ansible/cp 312 | 313 | # The path to use for the ControlPath sockets. This defaults to 314 | # "%(directory)s/ansible-ssh-%%h-%%p-%%r", however on some systems with 315 | # very long hostnames or very long path names (caused by long user names or 316 | # deeply nested home directories) this can exceed the character limit on 317 | # file socket names (108 characters for most platforms). In that case, you 318 | # may wish to shorten the string below. 319 | # 320 | # Example: 321 | # control_path = %(directory)s/%%h-%%r 322 | #control_path = %(directory)s/ansible-ssh-%%h-%%p-%%r 323 | 324 | # Enabling pipelining reduces the number of SSH operations required to 325 | # execute a module on the remote server. This can result in a significant 326 | # performance improvement when enabled, however when using "sudo:" you must 327 | # first disable 'requiretty' in /etc/sudoers 328 | # 329 | # By default, this option is disabled to preserve compatibility with 330 | # sudoers configurations that have requiretty (the default on many distros). 331 | # 332 | pipelining = True 333 | 334 | # Control the mechanism for transferring files 335 | # * smart = try sftp and then try scp [default] 336 | # * True = use scp only 337 | # * False = use sftp only 338 | #scp_if_ssh = smart 339 | 340 | # if False, sftp will not use batch mode to transfer files. This may cause some 341 | # types of file transfer failures impossible to catch however, and should 342 | # only be disabled if your sftp version has problems with batch mode 343 | #sftp_batch_mode = False 344 | 345 | [accelerate] 346 | #accelerate_port = 5099 347 | #accelerate_timeout = 30 348 | #accelerate_connect_timeout = 5.0 349 | 350 | # The daemon timeout is measured in minutes. This time is measured 351 | # from the last activity to the accelerate daemon. 352 | #accelerate_daemon_timeout = 30 353 | 354 | # If set to yes, accelerate_multi_key will allow multiple 355 | # private keys to be uploaded to it, though each user must 356 | # have access to the system via SSH to add a new key. The default 357 | # is "no". 358 | #accelerate_multi_key = yes 359 | 360 | [selinux] 361 | # file systems that require special treatment when dealing with security context 362 | # the default behaviour that copies the existing context or uses the user default 363 | # needs to be changed to use the file system dependent context. 364 | #special_context_filesystems=nfs,vboxsf,fuse,ramfs 365 | 366 | # Set this to yes to allow libvirt_lxc connections to work without SELinux. 367 | #libvirt_lxc_noseclabel = yes 368 | 369 | [colors] 370 | #highlight = white 371 | #verbose = blue 372 | #warn = bright purple 373 | #error = red 374 | #debug = dark gray 375 | #deprecate = purple 376 | #skip = cyan 377 | #unreachable = red 378 | #ok = green 379 | #changed = yellow 380 | #diff_add = green 381 | #diff_remove = red 382 | #diff_lines = cyan 383 | --------------------------------------------------------------------------------