smeeb
smeeb

Reputation: 29507

Managing Docker containers from Ansible plays

I am in the process of writing my first ever Ansible playbook and am in need of a bit of steering. I have a simple network that consists of 3 VMs:

I have configured my /etc/ansible/hosts file like so:

[databases]
db01.example.com

[app_servers]
myapp01.example.com
myapp02.example.com

I have configured SSH correctly, and I can run ansible all ping -m and Ansible is able to ping the DB and app server nodes. So far so good.

I’m trying to write three (3) Docker-related playbooks that will accomplish the following:

I believe these belong in three separate playbooks (correct me if I’m wrong or if there’s a better way). I took a stab at them. The first is setup_docker.yml:

- name: ensure docker engine is installed and running
  docker:
    name: *
    state: started

Then for restarting all [databases], in restart_app_servers.yml:

- name: restart app servers
  docker:
    name: app_servers
    state: restarted

And for restarting an arbitrary container on a single node (restart_container.yml):

- name: restart a specific container
  docker:
    name: %name_of_container_and node%
    state: restarted

But several problems here:

  1. In setup_docker.yml, how do I specify that all node types ([databases] and [app_servers]) should be affected? I know that asterisk (“*”) isn’t correct.
  2. In restart_app_servers.yml, what is the proper value for the name field? How do I actually tell Ansible to restart all app_server nodes?
  3. In restart_container.yml, how do I “inject” (pass in as arguments/variables) the node's and container’s names? Ideally I’d like to run this playbook against any node and any container.
  4. Anything else jumping out at you as wrong?

Thanks in advance!

Upvotes: 5

Views: 3246

Answers (1)

catagon87
catagon87

Reputation: 558

I think you have Plays and Playbooks mixed up in meaning here. The three things you have specified above, setup_docker.yml, restart_app_servers.yml, and restart_container.yml appear to be Plays. I recommend creating a Docker role which contains the tasks you have detailed here.

To address your problems:

  1. In setup_docker.yml, how do I specify that all node types ([databases] and [app_servers]) should be affected? I know that asterisk (“*”) isn’t correct.

This is done at the Playbook level. You can specify which hosts you want to be effected by which tasks, e.g:

#docker.yml
- hosts: all
  user: {{ privileged_user }} 
  gather_facts: false
  roles: 
    - install_docker

Then in your install_docker role, you would have something along the lines of:

- name: Add docker apt keys
  apt_key: keyserver=keyserver.ubuntu.com id=36A1D7869245C8950F966E92D8576A8BA88D21E9
- name: update apt 
  apt_repository: repo='deb https://get.docker.com/ubuntu docker main' state=present
- name: Install docker
  apt: pkg=lxc-docker update_cache=yes
  1. In restart_app_servers.yml, what is the proper value for the name field? How do I actually tell Ansible to restart all app_server nodes?

I'm assuming you mean you wish to restart all Docker containers on each of the nodes which belong to the app-server group? I would keep an inventory of all of the container names for each group (since this example is relatively simple). e.g:

#group_vars/app-server
all_containers: [ 'container1', 'container2', 'container3',.. 'containern' ]

From here you can use this inventory in your Play to restart each container. In your Playbook:

#restart_app_containers.yml
- hosts: app_server
  user: {{ privileged_user }}
  gather_facts: false
  roles: 
    - restart_app_servers

Then in the Play itself:

#restart_app_servers.yml
- name: restart app servers
  docker:
    name: {{ item }}
    state: restarted
  with_items: all_containers
  1. In restart_container.yml, how do I “inject” (pass in as arguments/variables) the node's and container’s names? Ideally I’d like to run this playbook against any node and any container.

For this portion you would need to reference your container directly which you need to act against. This can be done with Dynamic Inventory, e.g

#sample.yml
- hosts: Tag_name_{{ public_name }}
  user: {{ privileged_user }}
  gather_facts: false
  roles:
    - example

In the event you are on AWS. The hosts dictionary would vary by infrastructure. Then in your actual play you listed, you can pass in the specific variable. Since it's a single container on a single host, you could do this via the command line:

ansible-playbook -i $INVENTORY_FILE -e container_name=$CONTAINER_NAME restart_single_container_on_single_host.yml 

Where your Play would look something like:

- name: restart a specific container
  docker:
    name: {{ container_name }}
    state: restarted

Upvotes: 6

Related Questions