General Information

The command ansible-pull, inverts the way that ansible works. Instead of sending commands from a central location, a client can pull down a playbook from a version controlled repository and run it locally.


  • A software repo setup that can be reached by the client system (such as git or svn)

Pre-Req: The VCS Repo

You will need access to a software repo in order to commit/push your ansible-pull playbook into.

This repo will be used by the clients to pull from.

The repo visibility (public/private) doesn't matter, as long as there is a way for the client to access it over https or ssh.

Playbook: About

The ansible-pull playbook file will be the only part that looks different than a normal playbook/role setup.

The entire role directory structure/files can remain the same as if it were being deployed via normal ansible-playbook commands.

The directory structure for an Ansible Pull repo does not look that much different than Ansible's best practices for playbooks.

If this method is followed, the same role can also be used on the system that does regular ansible-playbook push commands (referenced from a different playbook file).

├── myplaybook.yml
└── myrole
    ├── files
    ├── handlers
    │   └── main.yml
    ├── tasks
    │   └── main.yml
    └── vars
        └── main.yml

Example of a playbook tailored for pulling.

# File: myplaybook.yml
# Description: Playbook used to execute on the local system via ansible-pull
# hosts to run on
- hosts:
    - localhost
  # roles: located in same directory
    # role: role to assign to hosts, tags: tag(s) to give entire role
    - { role: myrole, tags: myrole }
  # Do not gather host facts for this playbook (comment out/remove if you need facts)
  gather_facts: no

Example of a role that can be used with either a pull playbook or normal playbook.

File: myrole/tasks/main.yml → Installs a list of applications using the variable “my_awesome_apps” and notifies a handler if anything changes

- name: Install my awesome app list
    name: "{{ my_awesome_apps }}"
    state: present
  notify: restart my awesome service

File: myrole/vars/main.yml → Variable that contains a list of applications to install

 - myapp1
 - myapp2

File: myrole/vars/handlers.yml → Handler that restarts a service when triggered

- name: restart my awesome service
    name: my-awesome-service
    state: restarted

The Client: Putting It All Together

Steps for the client to run the playbook via ansible-pull.

Example with a git repo

  • Install ansible and git
    yum -y install ansible git
  • If Using SSH Key Login
    • Copy private ssh key to root's .ssh directory
      cp /mnt/remote-mount/share/id_rsa_ansible-pull /root/.ssh/id_rsa_ansible-pull
    • Ensure proper permissions
      chown root:root /root/.ssh/id_rsa_ansible-pull
      chmod 600 /root/.ssh/id_rsa_ansible-pull
  • Create a directory for ansible-pull to clone into
    mkdir -p /root/.ansible/pull
  • Run the ansible-pull command
    • SSH Key Example
      ansible-pull --directory /root/.ansible/pull --url --key-file /root/.ssh/id_rsa_ansible-pull --accept-host-key --clean myplaybook.yml
    • HTTPS Example
      ansible-pull --directory /root/.ansible/pull --url --clean myplaybook.yml

Options Used

  • –directory → Use this directory to checkout/clone repo to
  • –url → SSH or HTTPS url to clone from
  • –key-file → Use this private ssh key (ssh method)
  • –accept-host-key → Auto add the host identification for the url if not added (ssh method)
  • –clean → Files modified in the local copy of the repo are discarded
  • myplaybook.yml → Playbook to execute in the repo

Beyond: Continuous Deployment

Using ansible-pull, there is now the capability to make changes to systems via repo pushes.

Automation Ideas

  • Create a cron that runs an ansible-pull script
    • The script could provide logging for ansible-pull command output
    • Have the cron run frequently enough to pick up changes fast (every 15 minutes or so)
  • Add an argument to the ansible-pull command to only execute if the remote repo has been updated
  • Create a branch for each type of environment systems are in.
    • Examples:
      • Unstable
      • Development
      • Testing
      • Production
    • Add protection to Development, Testing, and Production to force merge requests (peer review) prior to updates being pushed.
    • Use Unstable to test changes to a small group of systems
  • Add an argument to the ansible-pull command to include the branch name for each environment. Development branch example
    --checkout 'development'

  • linux_wiki/ansible-pull.txt
  • Last modified: 2019/05/25 23:50
  • (external edit)