Ansible with Docker

Set up two containers: deb and arch, add them to an ansible hosts file, then do a 'ping' to see if they respond.

Required Packages

  • ansible
  • jq
  • docker

Debian Container

1docker run -di --rm --name deb --hostname deb debian
2docker exec -it deb sh -c 'apt update && apt -y install openssh-server python3 sudo'

Generate the host's ssh keys, then start the ssh daemon:

1docker exec -it deb sh -c 'ssh-keygen -A'
2docker exec -d deb /usr/sbin/sshd -D

Arch Linux Container

1docker run -di --rm --name arch --hostname arch archlinux
2docker exec -it arch sh -c 'pacman -Syu --noconfirm python sudo openssh'
3docker exec -it arch sh -c 'ssh-keygen -A'
4docker exec -d arch /usr/sbin/sshd -D

ssh Keys

Copy across your public ssh key to the container's authorized_keys file:

1pubkey=~/.ssh/id_rsa.pub
2for hostname in arch deb; do
3    docker cp $pubkey $hostname:/root/.ssh/authorized_keys
4    docker exec -it $hostname sh -c "chown -R root:root /root/.ssh/"
5    docker exec -it $hostname sh -c "chmod -R 700 /root/.ssh/"
6done

Hosts File

Find name of containers' IPv4 addresses.

1docker network inspect bridge

The output is awful. Use jq to parse the json:

1docker network inspect bridge  | jq -r '.[].Containers | .[].IPv4Address'

Now put those into a host file:

1docker_hosts=hosts.txt
2echo '[containers]' > $docker_hosts
3
4docker network inspect bridge  | \
5    jq -r '.[].Containers | .[] | "root@" + .IPv4Address' | \
6    cut -d/ -f1 >> $docker_hosts

You may need to add those host keys to your known hosts file. Either connect interactively, or (for scripts):

 1hosts="$(docker network inspect bridge  | jq -r '.[].Containers | .[] | .Name + " " + .IPv4Address' | \
 2    cut -d/ -f1)"
 3
 4echo "$hosts"
 5
 6echo "$hosts" | while read hostname ip; do
 7    printf "%s" "$ip"
 8    key="$(docker exec $hostname cat /etc/ssh/ssh_host_ed25519_key.pub)"
 9    echo "$ip $key" >> ~/.ssh/known_hosts
10done

Check if they ping:

1ansible -i $docker_hosts all -m ping

This command produces an irritating warning about the python interpreter (i.e., python3).

Make the warning shut-up:

1echo '
2[containers:vars]
3ansible_python_interpreter=/usr/bin/python3.13' >> $docker_hosts

Now the ping is cleaner:

1ansible -i $docker_hosts all -m ping