this is my first ansible playbook.
it installs docker in swarm mode and automatically joins the cluster.
could you guys please review my code and show me where it can be improved?
- hosts: all
tasks:
- name: Add apt key
apt_key:
url: https://download.docker.com/linux/raspbian/gpg
state: present
- name: Remove some packages
apt:
autoclean: yes
autoremove: yes
state: absent
pkg: [python2, python-configparser, python-is-python2]
- name: Install a list of packages
apt:
update_cache: yes
pkg:
- apt-transport-https
- aptitude
- ca-certificates
- curl
- libffi-dev
- libssl-dev
- python3
- python-is-python3
- software-properties-common
- name: Get docker convenience script
shell: curl -fsSL https://get.docker.com -o get-docker.sh
args:
creates: ~/get-docker.sh
- name: Install docker
shell: sh ~/get-docker.sh
args:
creates: /usr/bin/docker
- name: Config user permissions
user: name="{{ ansible_user_id }}" groups=docker append=yes generate_ssh_key=yes
#shell: usermod -aG docker $(whoami)
- name: Install docker-compose
pip: name=docker-compose state=latest
#shell: pip3 -v install -U docker-compose
#args:
# creates: /usr/local/bin/docker-compose
- name: Start service
service: name=docker enabled=yes state=started
- name: Get docker info
shell: docker info
register: docker_info
changed_when: False
- hosts: docker_swarm_manager
tasks:
- name: Create primary swarm manager
shell: docker swarm init --advertise-addr {{ ansible_default_ipv4.address }}
when: "docker_info.stdout.find('Swarm: inactive') > 0"
- name: Get docker swarm manager ip
copy:
content: '{{ ansible_default_ipv4.address }}'
dest: '/tmp/dsm_ip'
- name: Get docker swarm manager token
shell: docker swarm join-token -q manager
register: swarm_manager_token
- copy:
content: '{{ swarm_manager_token.stdout }}'
dest: '/tmp/dsm_mt'
- name: Get docker swarm worker token
shell: docker swarm join-token -q worker
register: swarm_worker_token
- copy:
content: '{{ swarm_worker_token.stdout }}'
dest: '/tmp/dsm_wt'
- hosts: all
tasks:
- name: Join the swarm
shell: "docker swarm join --token {{ lookup('file', '/tmp/dsm_mt') }} {{ lookup('file', '/tmp/dsm_ip') }}:2377"
when: "docker_info.stdout.find('Swarm: inactive') > 0"
retries: 5
delay: 5
A couple queries: 1. What version of ansible are you using? 2. Why are you not using the docker_swarm module? – 0xSheepdog
- ansible [core 2.11.6]
root@minipc:~# ansible --version
ansible [core 2.11.6]
config file = None
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.8/dist-packages/ansible
ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/local/bin/ansible
python version = 3.8.10 (default, Sep 28 2021, 16:10:42) [GCC 9.3.0]
jinja version = 3.0.3
libyaml = True
- i didnt even know there was a docker_swarm module. maybe you could post an answer showing how you would write the playbook using this module? my playbook was pretty simple to write, if using the module can save time, i dont mind changing.
-
\$\begingroup\$ A couple queries: 1. What version of ansible are you using? 2. Why are you not using the docker_swarm module? \$\endgroup\$0xSheepdog– 0xSheepdog2021年11月30日 02:48:32 +00:00Commented Nov 30, 2021 at 2:48
-
\$\begingroup\$ @0xSheepdog i updated my post to answer your questions \$\endgroup\$yodog– yodog2021年11月30日 12:41:29 +00:00Commented Nov 30, 2021 at 12:41
1 Answer 1
I have done some Ansible tasks 5 years ago, so I looked at your code just out of interest, and I didn't read any documentation. Here are some things I noted by just looking at the code:
The task apt_key
looks strange to me. The basic idea of a GPG key is that it provides a trust anchor. You currently trust the URL of that task to always provide the correct GPG key. Instead, I would download this key and verify offline that it comes from the person it says. Then I'd compute a hash of the file and use that to verify the download. Since the hash by itself does not tell a story, I'd write a comment along it, summarizing the information from the GPG key, something like:
# 2021年11月30日: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88
# Docker Release (CE deb) <[email protected]>
hash: sha256:abcdef12345678
Verifying the download is something that the apt_key
module should provide out-of-the-box, or its documentation must warn about the practice of downloading an untrusted key, otherwise its authors have no clue of IT security.
The task apt
looks strange as well. You are basing the system on a Linux distribution that still has Python 2 installed as default. That seems old to me. Isn't there some newer release of that distribution?
Talking of the distribution: From reading the Ansible file, I have no idea what base system I should install before applying Ansible to it. Is it a Debian, Ubuntu, Alpine, Arch, Red Hat (probably not)? This should be documented somewhere. In case the hosts die all of a sudden, it should be possible to set up the exact same setup as before.
Speaking of which, you don't specify which versions of the packages you want to have installed. This also provides possible variance.
Over to get-docker.sh
. You trust get.docker.com to always serve you the file you expect. You should verify this download as well, just as you do with the Debian packages above. Also, downloading the now-current file prevents the setup from being reproducible.
Same for pip3
, Python packages also have versions, and if you want a reproducible setup, you must use fixed version numbers instead of always taking the latest versions.
I found the filenames in /tmp
a bit short. When you wrote the code, it was immediately clear to you what they are supposed to mean, but will that still be the case in 2 years? I'd choose longer, more expressive names.
All the rest looks good, and it serves as a nice and brief instruction how to set up a Docker Swarm cluster.
I wonder how many hosts all
means. But that probably depends on how you use this Ansible file. It should definitely not mean "all 2000 reachable hosts that are accidentally reachable". :)
Further reading: