Answers: <p>I have achieved the same goal but a bit more securely, by forwarding the unix socket (but not a tcp socket). However it is a bit convoluted. The following example contains everything from starting an example container, forwarding the socket and tearing down everything afterwards.</p>
  <p>In this scenario I have 3 &quot;hosts&quot; (in the sense of ansible hosts), localhost, the server and the container.
  Docker-cli must be present on localhost.</p>
  <p>My inventory looks like this, I've explicitly specified the forwarded docker socket for the connection to the container:</p>
  <pre><code>---
  all:
    hosts:
      server:
      container:
        ansible_connection: docker
        ansible_docker_extra_args: &quot;-H unix:///tmp/remote_docker.sock&quot;
    vars:
      docker_sock_path: &quot;/tmp/remote_docker.sock&quot;
  </code></pre>
  <p>The playbook consists of multiple plays, as it needs to apply to different hosts.</p>
  <ol>
  <li>At first an <a href="https://medium.com/@dperny/forwarding-the-docker-socket-over-ssh-e6567cfab160" rel="nofollow noreferrer">ssh-forwarding of the unix-socket</a> is setup. This is done on localhost (however it's not a separate play, just delegated</li>
  <li>The docker container is started (this is done on the server).
  The container is started with <code>interactive: true</code> so it stays alive without anything to do.</li>
  <li>Tasks are run in the Container</li>
  <li>The SSH Process is killed and the socket file is deleted (this is done on localhost)</li>
  </ol>
  <pre><code>---
  - name: &quot;Preparing SSH, starting the container&quot;
    hosts: server
    tasks:
    - name: Create SSH tunnel for the unix docker socket
      command: 
        cmd: &quot;ssh -fnNT -L {{ docker_sock_path }}:/var/run/docker.sock {{ ansible_user }}@{{ ansible_host }}&quot;
      delegate_to: localhost
    - name: create connection container
      community.docker.docker_container:
        name: container
        image: python:3.12-slim-bookworm
        state: started
        interactive: true
        entrypoint: &quot;/bin/sh&quot;
  
  - name: &quot;Executing steps in docker container&quot;
    hosts: container
    tasks:
      [...]
  - name: &quot;Shutting down proxy container&quot;
    hosts: server
    tasks:
    - name: stop connection container
      community.docker.docker_container:
        name: server
        state: stopped
  - name: &quot;Shutting down socket forwarding&quot;
    hosts: localhost
    connection: local
    tasks:
    - name: get process ids
      shell: ps xf
      register: all_pid
    - name: extract pid of our ssh process
      ansible.builtin.set_fact:
       ssh_pid: &quot;{{ item | trim | split | first }}&quot;
      loop: &quot;{{ all_pid.stdout_lines }}&quot;
      when: item is match(&quot;^.*{{docker_sock_path }}:/var/run/docker.sock.*$&quot;)
    - name: kill ssh process
      ansible.builtin.command:
        cmd: &quot;kill {{ ssh_pid }}&quot;
    - name: Remove socket file
      ansible.builtin.file:
        path: &quot;{{ docker_sock_path }}&quot;
        state: absent
  </code></pre>
  
Answers: CC BY-SA 4.0
Answers: 2023-11-13T16:01:52.110Z
Answers: 2023-11-13T16:01:52.110Z
Answers: BenjaminH
Answers: <p>With the help of <a href="https://devops.stackexchange.com/users/4427/levi">@Levi</a> (refered to <a href="https://stackoverflow.com/questions/32878795/run-command-inside-of-docker-container-using-ansible/41626257#41626257">Stackoverflow</a>) I managed to find a way to connect straigt into the docker containers using ansibles docker connection driver and the remote API capability of Docker. </p>
  
  <p>First of all you have to expose the API which is by default not the case. Simply add <code>-H tcp://0.0.0.0:1337</code> to the <code>ExecStart</code> constant of the systemd script. Then reload the start script and restart the docker service. (From <a href="https://www.ivankrizsan.se/2016/05/18/enabling-docker-remote-api-on-ubuntu-16-04/" rel="noreferrer">this</a> blogpost) </p>
  
  <p>Then you can list the containers in the inventory file like this:</p>
  
  <pre><code>[containers]
  container-name ansible_connection=docker ansible_docker_extra_args="-H tcp://1.2.3.4:1337"
  </code></pre>
  
  <p>And execute any playbook like your used to.</p>
  
  <pre><code>ansible-playbook -i docker_inventory playbooks/my_playbook.yml
  </code></pre>
  
  <p>The upside of this way of implementing it this way is that you can mix up "real" hosts/vms that are maintained through SSH and Docker containers. One negative thing I have to mention is that the docker API is much slower than using SSH as a control tunnel.</p>
  
  <p><strong>This setup is of cause horribly insecure and its only purpose is to explain the concept. Before using it in production you should read into the security features and limit access to the daemon as far as possible.</strong></p>
  
Answers: CC BY-SA 4.0
Answers: 2020-04-04T15:13:03.740Z
Answers: As you said insecure for remote, but for local development is a great solution! +1
Answers: Matteo Gaggiano
Answers: CC BY-SA 4.0
Answers: 2018-07-04T19:52:51.877Z
Answers: 2018-07-04T20:03:05.653Z
Answers: 2018-07-04T20:03:05.653Z
Answers: davidb
Body: <p>I have automated the setup of several docker containers with ansible. This works pretty well but there are certain recurring tasks that have to be executed within the docker containers.</p>
  <p>It is possible to implement this using the <a href="https://docs.ansible.com/ansible/latest/scenario_guides/guide_docker.html" rel="nofollow noreferrer">docker connection driver</a> for ansible but this only seems to work when ansible is running on the host that is the docker runner. This is not the case and I don't want to run ansible on multiple hosts if possible. Is there a better way to use ansible to execute playbooks within containers?</p>
  <p>Notes:</p>
  <ul>
  <li>I know how I can execute commands in a docker container from the host system but I don't only want to execute commands. I want to be able to use Ansible for docker containers as if they where standalone hosts.</li>
  <li>I tried it out of curiosity and it works pretty well using ansible directly on the docker runner,... anyway not my favorite solution.</li>
  </ul>
  
Comments: CC BY-SA 4.0
Comments: 2018-07-04T16:45:39.157Z
Comments: How about this https://stackoverflow.com/a/41626257/3888850 ?
Comments: Levi
Comments: CC BY-SA 4.0
Comments: 2018-07-04T18:02:02.667Z
Comments: Well thank you! Wonder why I didn't find that post on my own,.... o.O That would have some security implications but I could deal with that! Im going to report back on it when I had the opportunity to try it out,...
Comments: davidb
Comments: CC BY-SA 4.0
Comments: 2018-07-04T19:54:10.177Z
Comments: @Levi: thanks for your help I answered my own post describing it in a more understandable way.
Comments: davidb
Comments: CC BY-SA 4.0
Comments: 2018-07-05T05:05:02.417Z
Comments: In my opinion docker images should be immutable and stateless.
Comments: 030
Comments: CC BY-SA 4.0
Comments: 2018-07-05T06:05:40.607Z
Comments: @030 Well I think that depends on the application in the container. In my scenario signature updates & actions of the application need to be triggered centrally and I need to validate if the progress of the process in the docker container from the outside to trigger SDN Functionallities
Comments: davidb
Tags: <docker><ansible>
Title: Applying ansible playbook to a docker container on a remote host
UserDisplayName: davidb
ThreadText: # Applying ansible playbook to a docker container on a remote host
  
  (Asked by: username_0 on 2018-07-04)
  
  I have automated the setup of several docker containers with ansible. This works pretty well but there are certain recurring tasks that have to be executed within the docker containers.
  
  It is possible to implement this using the [docker connection driver](https://docs.ansible.com/ansible/latest/scenario_guides/guide_docker.html) for ansible but this only seems to work when ansible is running on the host that is the docker runner. This is not the case and I don't want to run ansible on multiple hosts if possible. Is there a better way to use ansible to execute playbooks within containers?
  
  Notes:
  
  * I know how I can execute commands in a docker container from the host system but I don't only want to execute commands. I want to be able to use Ansible for docker containers as if they where standalone hosts.
  * I tried it out of curiosity and it works pretty well using ansible directly on the docker runner,... anyway not my favorite solution.
  
  **Tags:** docker, ansible
  
  > **Comments:**
  > **username_1**: How about this https://stackoverflow.com/a/41626257/3888850 ?  
  > **username_0**: Well thank you! Wonder why I didn't find that post on my own,.... o.O That would have some security implications but I could deal with that! Im going to report back on it when I had the opportunity to try it out,...  
  > **username_0**: @username_1: thanks for your help I answered my own post describing it in a more understandable way.  
  > **username_2**: In my opinion docker images should be immutable and stateless.  
  > **username_0**: @username_2 Well I think that depends on the application in the container. In my scenario signature updates & actions of the application need to be triggered centrally and I need to validate if the progress of the process in the docker container from the outside to trigger SDN Functionallities  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_0 on 2018-07-04. Score: 14 | Accepted answer
  
  With the help of [@username_1](https://devops.stackexchange.com/users/4427/username_1) (refered to [Stackoverflow](https://stackoverflow.com/questions/32878795/run-command-inside-of-docker-container-using-ansible/41626257#41626257)) I managed to find a way to connect straigt into the docker containers using ansibles docker connection driver and the remote API capability of Docker.
  
  First of all you have to expose the API which is by default not the case. Simply add `-H tcp://0.0.0.0:1337` to the `ExecStart` constant of the systemd script. Then reload the start script and restart the docker service. (From [this](https://www.ivankrizsan.se/2016/05/18/enabling-docker-remote-api-on-ubuntu-16-04/) blogpost)
  
  Then you can list the containers in the inventory file like this:
  
  ```
  [containers]
  container-name ansible_connection=docker ansible_docker_extra_args="-H tcp://1.2.3.4:1337"
  
  ```
  
  And execute any playbook like your used to.
  
  ```
  ansible-playbook -i docker_inventory playbooks/my_playbook.yml
  
  ```
  
  The upside of this way of implementing it this way is that you can mix up "real" hosts/vms that are maintained through SSH and Docker containers. One negative thing I have to mention is that the docker API is much slower than using SSH as a control tunnel.
  
  **This setup is of cause horribly insecure and its only purpose is to explain the concept. Before using it in production you should read into the security features and limit access to the daemon as far as possible.**
  
  > **Comments:**
  > **username_4**: As you said insecure for remote, but for local development is a great solution! +1  
  
  ---
  
  ### Answer by username_3 on 2023-11-13. Score: 0
  
  I have achieved the same goal but a bit more securely, by forwarding the unix socket (but not a tcp socket). However it is a bit convoluted. The following example contains everything from starting an example container, forwarding the socket and tearing down everything afterwards.
  
  In this scenario I have 3 "hosts" (in the sense of ansible hosts), localhost, the server and the container.
  Docker-cli must be present on localhost.
  
  My inventory looks like this, I've explicitly specified the forwarded docker socket for the connection to the container:
  
  ```
  ---
  all:
    hosts:
      server:
      container:
        ansible_connection: docker
        ansible_docker_extra_args: "-H unix:///tmp/remote_docker.sock"
    vars:
      docker_sock_path: "/tmp/remote_docker.sock"
  
  ```
  
  The playbook consists of multiple plays, as it needs to apply to different hosts.
  
  1. At first an [ssh-forwarding of the unix-socket](https://medium.com/@dperny/forwarding-the-docker-socket-over-ssh-e6567cfab160) is setup. This is done on localhost (however it's not a separate play, just delegated
  2. The docker container is started (this is done on the server).
     The container is started with `interactive: true` so it stays alive without anything to do.
  3. Tasks are run in the Container
  4. The SSH Process is killed and the socket file is deleted (this is done on localhost)
  
  ```
  ---
  - name: "Preparing SSH, starting the container"
    hosts: server
    tasks:
    - name: Create SSH tunnel for the unix docker socket
      command: 
        cmd: "ssh -fnNT -L {{ docker_sock_path }}:/var/run/docker.sock {{ ansible_user }}@{{ ansible_host }}"
      delegate_to: localhost
    - name: create connection container
      community.docker.docker_container:
        name: container
        image: python:3.12-slim-bookworm
        state: started
        interactive: true
        entrypoint: "/bin/sh"
  
  - name: "Executing steps in docker container"
    hosts: container
    tasks:
      [...]
  - name: "Shutting down proxy container"
    hosts: server
    tasks:
    - name: stop connection container
      community.docker.docker_container:
        name: server
        state: stopped
  - name: "Shutting down socket forwarding"
    hosts: localhost
    connection: local
    tasks:
    - name: get process ids
      shell: ps xf
      register: all_pid
    - name: extract pid of our ssh process
      ansible.builtin.set_fact:
       ssh_pid: "{{ item | trim | split | first }}"
      loop: "{{ all_pid.stdout_lines }}"
      when: item is match("^.*{{docker_sock_path }}:/var/run/docker.sock.*$")
    - name: kill ssh process
      ansible.builtin.command:
        cmd: "kill {{ ssh_pid }}"
    - name: Remove socket file
      ansible.builtin.file:
        path: "{{ docker_sock_path }}"
        state: absent
  
  ```
  
  
  ---
  
  