Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple improvements #100

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,18 @@ Listen port for the Swarm raft API.
skip_engine: false
skip_cli: false
skip_swarm: false
skip_swarm_cert: false
skip_group: false
skip_docker_py: false
skip_docker_compose: false

Switches allowing to disable specific functionalities of the role.
If you want to use this role to install `docker-engine` without enabling `swarm-mode` set `skip_swarm: true`.

If you want to use this role to gen API certs, set `skip_swarm_cert: true`

If you want to keep certs to local folder, set `docker_api_certs_docker_local_cert_path: /your/local/path`

Swarm node labels
-----------------

Expand Down
34 changes: 34 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,33 @@ docker_service_enabled: "yes"
# Docker Deamon configuration
docker_daemon_config: {}

##
# Docker API cert
##

# Generate new cert on groups['docker_swarm_manager'][0]
docker_api_certs_cert_gen: False

# Base dir docker
docker_api_certs_docker_base_path: /etc/docker
# Base dir for cert.pem key.pem ca.pem (used for deamon.json)
docker_api_certs_docker_cert_path: "{{ docker_api_certs_docker_base_path }}/cert"

# used for deamon.json
docker_api_certs_ca_name: ca.pem
docker_api_certs_cert_name: cert.pem
docker_api_certs_key_name: key.pem

# Openssl config for generate CA
docker_api_certs_openssl_domain: swarm.localdomain.local
docker_api_certs_openssl_state: Ile-de-France
docker_api_certs_openssl_country: FR
docker_api_certs_openssl_email: docker@localhost
docker_api_certs_openssl_org: My ORG
docker_api_certs_openssl_ou: My OU

docker_api_certs_docker_certificate_validity: 365

##
# Docker CLI
##
Expand Down Expand Up @@ -121,6 +148,12 @@ docker_group_users:
# swarm cluster doesn't overlap with you infrastructure
# docker_swarm_network: 10.10.8.0/24

# Custom swarm init args. ex: customize default-addr-pool
# docker_swarm_init_extra_options: |
# --default-addr-pool 10.184.32.0/19 \
# --default-addr-pool-mask-length 28
docker_swarm_init_extra_options: ""

# You can set any interface, that is listened by docker engine.
# e.g. docker_swarm_interface: "eth1"
docker_swarm_interface: "{{ ansible_default_ipv4['interface'] }}"
Expand All @@ -137,6 +170,7 @@ skip_containerd: false # if true, skips the setup of containerd
skip_engine: false # if true, skips the docker engine installation
skip_cli: false # if true, skips the docker cli installation
skip_swarm: false # if true, skips the swarm setup
skip_swarm_cert: false # if true, skips the swarm cert gen and deploy
skip_group: false # if true, does not add the docker_admin_users to the docker_group_name
skip_docker_py: false # if true, skips the installation of docker-py
skip_docker_compose: false # if true, skips the installation of docker-compose
18 changes: 10 additions & 8 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@
# Install python-pip
- include_tasks: setup-python-pip.yml

# Install docker-py
- include_tasks: setup-docker-py.yml
when: not skip_docker_py

# Install docker-compose
- include_tasks: setup-docker-compose.yml
when: not skip_docker_compose

# Install the Docker repository
- include_tasks: "repo-{{ ansible_os_family }}.yml"
when: not skip_repo
Expand Down Expand Up @@ -41,16 +49,10 @@
- block:
- include_tasks: setup-swarm-cluster.yml
- include_tasks: setup-swarm-labels.yml
- include_tasks: setup-docker-swarm-api-certs.yml
when: not skip_swarm_cert
when: not skip_swarm

# Adds the Docker admin users to the Docker group
- include_tasks: setup-docker-group.yml
when: not skip_group

# Install docker-py
- include_tasks: setup-docker-py.yml
when: not skip_docker_py

# Install docker-compose
- include_tasks: setup-docker-compose.yml
when: not skip_docker_compose
182 changes: 182 additions & 0 deletions tasks/setup-docker-swarm-api-certs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
---
##
# check prerequisites
- name: Create certificate directory
file: path="{{ docker_api_certs_docker_cert_path }}" state=directory recurse=yes owner=root group=root mode=0755
become: True

- name: Create CA certificate directory
file: path="{{ docker_api_certs_docker_cert_path }}/ca" state=directory recurse=yes owner=root group=root mode=0755
become: True

- name: Create client certificate directory
file: path="{{ docker_api_certs_docker_cert_path }}/client" state=directory recurse=yes owner=root group=root mode=0755
become: True

- name: Install OpenSSL
package:
name: openssl
state: present
become: True

##
# Gen cert files
- name: copy openssl configuration
template:
src: templates/openssl.cnf.j2
dest: "{{ docker_api_certs_docker_cert_path }}/openssl-ca.cnf"
owner: root
group: root
mode: 0644
when: inventory_hostname == groups['docker_swarm_manager'][0] and docker_api_certs_cert_gen
run_once: True
become: True

- name: generate CA private key
command: openssl genrsa -out {{ docker_api_certs_docker_cert_path }}/ca/ca-key.pem 2048
when: inventory_hostname == groups['docker_swarm_manager'][0] and docker_api_certs_cert_gen
run_once: True
become: True

- name: generate CA public key
command: |
openssl req -config {{ docker_api_certs_docker_cert_path }}/openssl-ca.cnf -new -x509 \
-days {{ docker_api_certs_docker_certificate_validity }} \
-key {{ docker_api_certs_docker_cert_path }}/ca/ca-key.pem -sha256 \
-out {{ docker_api_certs_docker_cert_path }}/ca.pem
when: inventory_hostname == groups['docker_swarm_manager'][0] and docker_api_certs_cert_gen
run_once: True
become: True

- name: generate private keys
command: openssl genrsa -out {{ docker_api_certs_docker_cert_path }}/{{ docker_api_certs_key_name }} 2048
when: inventory_hostname == groups['docker_swarm_manager'][0] and docker_api_certs_cert_gen
run_once: True
notify: restart docker
become: True

- name: generate server csr (server.csr)
command: |
openssl req -subj "/CN={{ docker_api_certs_openssl_domain }}" -sha256 -new \
-key {{ docker_api_certs_docker_cert_path }}/{{ docker_api_certs_key_name }} \
-out {{ docker_api_certs_docker_cert_path }}/server.csr
when: inventory_hostname == groups['docker_swarm_manager'][0] and docker_api_certs_cert_gen
run_once: True
become: True

- name: generate public key
command: |
openssl x509 -req -days {{ docker_api_certs_docker_certificate_validity }} -sha256 \
-in {{ docker_api_certs_docker_cert_path }}/server.csr \
-CA {{ docker_api_certs_docker_cert_path }}/{{ docker_api_certs_ca_name }} \
-CAkey {{ docker_api_certs_docker_cert_path }}/ca/ca-key.pem \
-CAcreateserial -out {{ docker_api_certs_docker_cert_path }}/{{ docker_api_certs_cert_name }} \
-extfile {{ docker_api_certs_docker_cert_path }}/openssl-ca.cnf
when: inventory_hostname == groups['docker_swarm_manager'][0] and docker_api_certs_cert_gen
run_once: True
notify: restart docker
become: True

- name: generate client key
command: openssl genrsa -out {{ docker_api_certs_docker_cert_path }}/client/client-{{ docker_api_certs_key_name }} 2048
when: inventory_hostname == groups['docker_swarm_manager'][0] and docker_api_certs_cert_gen
run_once: True
notify: restart docker
become: True

- name: generate client csr (cert.csr)
command: |
openssl req -subj '/CN=client' -new \
-key {{ docker_api_certs_docker_cert_path }}/client/client-{{ docker_api_certs_key_name }} \
-out {{ docker_api_certs_docker_cert_path }}/client/client.csr
when: inventory_hostname == groups['docker_swarm_manager'][0] and docker_api_certs_cert_gen
run_once: True
become: True

- name: Generate client crt
shell: |
echo extendedKeyUsage = clientAuth > {{ docker_api_certs_docker_cert_path }}/client/extfile.cnf \
&& openssl x509 -req -days {{ docker_api_certs_docker_certificate_validity }} -sha256 \
-in {{ docker_api_certs_docker_cert_path }}/client/client.csr \
-CA {{ docker_api_certs_docker_cert_path }}/{{ docker_api_certs_ca_name }} \
-CAkey {{ docker_api_certs_docker_cert_path }}/ca/ca-key.pem -CAcreateserial \
-out {{ docker_api_certs_docker_cert_path }}/client/client-{{ docker_api_certs_cert_name }} \
-extfile {{ docker_api_certs_docker_cert_path }}/client/extfile.cnf
when: inventory_hostname == groups['docker_swarm_manager'][0] and docker_api_certs_cert_gen
run_once: True
become: True

##
# Get cert files if exist
- name: get {{ docker_api_certs_ca_name }} from {{ groups['docker_swarm_manager'][0] }}
slurp:
src: "{{ docker_api_certs_docker_cert_path }}/{{ docker_api_certs_ca_name }}"
delegate_to: "{{ groups['docker_swarm_manager'][0] }}"
register: docker_api_certs_ca
run_once: True
become: True

- name: get {{ docker_api_certs_cert_name }} from {{ groups['docker_swarm_manager'][0] }}
slurp:
src: "{{ docker_api_certs_docker_cert_path }}/{{ docker_api_certs_cert_name }}"
delegate_to: "{{ groups['docker_swarm_manager'][0] }}"
register: docker_api_certs_cert
run_once: True
become: True

- name: get ca.pem from {{ groups['docker_swarm_manager'][0] }}
slurp:
src: "{{ docker_api_certs_docker_cert_path }}/{{ docker_api_certs_key_name }}"
delegate_to: "{{ groups['docker_swarm_manager'][0] }}"
register: docker_api_certs_key
run_once: True
become: True

##
# Push cert files if don't exist
- name: write ca.pem
copy:
dest: "{{ docker_api_certs_docker_cert_path }}/{{ docker_api_certs_ca_name }}"
content: "{{ docker_api_certs_ca['content'] | b64decode }}"
owner: root
group: root
mode: 0644
when: inventory_hostname != groups['docker_swarm_manager'][0]
notify: restart docker
become: True

- name: write cert.pem
copy:
dest: "{{ docker_api_certs_docker_cert_path }}/{{ docker_api_certs_cert_name }}"
content: "{{ docker_api_certs_cert['content'] | b64decode }}"
owner: root
group: root
mode: 0644
when: inventory_hostname != groups['docker_swarm_manager'][0]
notify: restart docker
become: True

- name: write key.pem
copy:
dest: "{{ docker_api_certs_docker_cert_path }}/{{ docker_api_certs_key_name }}"
content: "{{ docker_api_certs_key['content'] | b64decode }}"
owner: root
group: root
mode: 0644
when: inventory_hostname != groups['docker_swarm_manager'][0]
notify: restart docker
become: True

##
# get a local copy of certs

- name: get certs to localdir from {{ groups['docker_swarm_manager'][0] }}
fetch:
src: "{{ docker_api_certs_docker_cert_path }}/{{ item }}"
dest: "{{ docker_api_certs_docker_local_cert_path }}/"
with_items:
- "{{ docker_api_certs_ca_name }}"
- "{{ docker_api_certs_cert_name }}"
- "{{ docker_api_certs_key_name }}"
when: docker_api_certs_docker_local_cert_path is defined and inventory_hostname == groups['docker_swarm_manager'][0]
become: True
12 changes: 6 additions & 6 deletions tasks/setup-swarm-cluster.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
---

- name: Create a custom Swarm network.
- name: Create a custom Swarm network
docker_network:
name: docker_gwbridge
driver_options:
com.docker.network.bridge.enable_icc: "false"
com.docker.network.bridge.enable_ip_masquerade: "true"
com.docker.network.bridge.name: docker_gwbridge
ipam_options:
subnet: "{{ docker_swarm_network }}"
gateway: "{{ docker_swarm_network | ipaddr('net') | ipaddr('1') | ipaddr('ip') }}"
when: docker_swarm_network is defined and docker_swarm_network | ipaddr('net')
ipam_config:
- subnet: "{{ docker_swarm_network }}"
gateway: "{{ docker_swarm_network | ansible.utils.ipaddr('net') | ansible.utils.ipaddr('1') | ansible.utils.ipaddr('ip') }}"
when: docker_swarm_network is defined and docker_swarm_network | ansible.utils.ipaddr('net')

- name: Check if "Swarm Mode" is enabled.
shell: docker info
Expand All @@ -22,7 +22,7 @@
- name: Init "Swarm Mode" on the first manager.
shell: docker swarm init
--listen-addr {{ docker_swarm_addr }}:{{ docker_swarm_port }}
--advertise-addr {{ docker_swarm_addr }}
--advertise-addr {{ docker_swarm_addr }} {{ docker_swarm_init_extra_options }}
when: "docker_info.stdout.find('Swarm: active') == -1
and inventory_hostname == groups['docker_swarm_manager'][0]"
tags:
Expand Down
6 changes: 3 additions & 3 deletions tasks/setup-swarm-labels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
command: >-
docker inspect
--format {% raw %}'{{ range $key, $value := .Spec.Labels }}{{ printf "%s\n" $key }}{{ end }}'{% endraw %}
{{ ansible_fqdn|lower }}
{{ ansible_hostname|lower }}
register: docker_swarm_labels
changed_when: false
delegate_to: "{{ groups['docker_swarm_manager'][0] }}"
Expand All @@ -13,7 +13,7 @@
- swarm_labels

- name: Remove labels from swarm node.
command: docker node update --label-rm {{ item }} {{ ansible_fqdn|lower }}
command: docker node update --label-rm {{ item }} {{ ansible_hostname|lower }}
with_items: "{{ docker_swarm_labels.stdout_lines }}"
when: item not in swarm_labels
delegate_to: "{{ groups['docker_swarm_manager'][0] }}"
Expand All @@ -22,7 +22,7 @@
- swarm_labels

- name: Assign labels to swarm nodes if any.
command: docker node update --label-add {{ item }}=true {{ ansible_fqdn|lower }}
command: docker node update --label-add {{ item }}=true {{ ansible_hostname|lower }}
when: item not in docker_swarm_labels.stdout_lines
with_items:
- "{{ swarm_labels | default([]) }}"
Expand Down
11 changes: 11 additions & 0 deletions templates/openssl.cnf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[ req ]
prompt = no
distinguished_name = req_distinguished_name

[ req_distinguished_name ]
commonName = {{ docker_api_certs_openssl_domain }}
stateOrProvinceName = {{ docker_api_certs_openssl_state }}
countryName = {{ docker_api_certs_openssl_country }}
emailAddress = {{ docker_api_certs_openssl_email }}
organizationName = {{ docker_api_certs_openssl_org }}
organizationalUnitName = {{ docker_api_certs_openssl_ou }}
4 changes: 2 additions & 2 deletions vars/Debian.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---

python_pip_packages:
- python-pip
- "{% if ansible_facts.python.version.major is version('3', '=') %}python3-pip{% else %}python-pip{% endif %}"

python_sni_support_packages:
- python-dev
- "{% if ansible_facts.python.version.major is version('3', '=') %}python3-dev{% else %}python-dev{% endif %}"
- libssl-dev
- libffi-dev

Expand Down