Reputation: 29507
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:
ansible01
- my Ansible server (Ubuntu)db01
- a DB (again, Ubuntu)myapp01
- an Ubuntu VM hosting a Java appI 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:
[databases]
nodes as well as all [app_servers]
nodes; if it is not installed and running, then install Docker engine and start running it. If it is installed but not running, restart it.[app_servers]
nodes.myapp01
has 2 containers running on it, fizz
and buzz
. I’d like to be able to tell Ansible to restart (specifically) myapp01
’s fizz
container, but not its buzz
container, nor any myapp02
containers.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:
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.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?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.Thanks in advance!
Upvotes: 5
Views: 3246
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:
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
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
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