[deployment] Run command on the Ansible host

Is it possible to run commands on the Ansible host?

My scenario is that I want to take a checkout from a git server that is hosted internally (and isn't accessible outside the company firewall). Then I want to upload the checkout (tarballed) to the production server (hosted externally).

At the moment, I'm looking at running a script that does the checkout, tarballs it, and then runs the deployment script - but if I could integrate this into Ansible that would be preferable.

This question is related to deployment ansible

The answer is


From the Ansible documentation:

Delegation This isn’t actually rolling update specific but comes up frequently in those cases.

If you want to perform a task on one host with reference to other hosts, use the ‘delegate_to’ keyword on a task. This is ideal for placing nodes in a load balanced pool, or removing them. It is also very useful for controlling outage windows. Be aware that it does not make sense to delegate all tasks, debug, add_host, include, etc always get executed on the controller. Using this with the ‘serial’ keyword to control the number of hosts executing at one time is also a good idea:

---

- hosts: webservers
  serial: 5

  tasks:

  - name: take out of load balancer pool
    command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
    delegate_to: 127.0.0.1

  - name: actual steps would go here
    yum:
      name: acme-web-stack
      state: latest

  - name: add back to load balancer pool
    command: /usr/bin/add_back_to_pool {{ inventory_hostname }}
    delegate_to: 127.0.0.1

These commands will run on 127.0.0.1, which is the machine running Ansible. There is also a shorthand syntax that you can use on a per-task basis: ‘local_action’. Here is the same playbook as above, but using the shorthand syntax for delegating to 127.0.0.1:

---

# ...

  tasks:

  - name: take out of load balancer pool
    local_action: command /usr/bin/take_out_of_pool {{ inventory_hostname }}

# ...

  - name: add back to load balancer pool
    local_action: command /usr/bin/add_back_to_pool {{ inventory_hostname }}

A common pattern is to use a local action to call ‘rsync’ to recursively copy files to the managed servers. Here is an example:

---
# ...
  tasks:

  - name: recursively copy files from management server to target
    local_action: command rsync -a /path/to/files {{ inventory_hostname }}:/path/to/target/

Note that you must have passphrase-less SSH keys or an ssh-agent configured for this to work, otherwise rsync will need to ask for a passphrase.


Expanding on the answer by @gordon, here's an example of readable syntax and argument passing with shell/command module (these differ from the git module in that there are required but free-form arguments, as noted by @ander)

- name: "release tarball is generated"
  local_action:
    module: shell
    _raw_params: git archive --format zip --output release.zip HEAD
    chdir: "files/clones/webhooks"

ansible your_server_name -i custom_inventory_file_name -m -a "uptime"

The default module is command module, hence command keyword is not required.

If you need to issue any command with elevated privileges use -b at the end of the same command.

ansible your_server_name -i custom_inventory_file_name -m -a "uptime" -b

You can use delegate_to to run commands on your Ansible host (admin host), from where you are running your Ansible play. For example:

Delete a file if it already exists on Ansible host:

 - name: Remove file if already exists
   file:
    path: /tmp/logfile.log
    state: absent
    mode: "u+rw,g-wx,o-rwx"
   delegate_to: 127.0.0.1

Create a new file on Ansible host :

 - name: Create log file
   file:
    path: /tmp/logfile.log
    state: touch
    mode: "u+rw,g-wx,o-rwx"
   delegate_to: 127.0.0.1

you can try this way


I've found a couple other ways you can write these which are a bit more readable IMHO.

- name: check out a git repository
  local_action: 
    module: git
    repo: git://foosball.example.org/path/to/repo.git
    dest: /local/path

OR

- name: check out a git repository
  local_action: git
  args:
    repo: git://foosball.example.org/path/to/repo.git
    dest: /local/path

I'd like to share that Ansible can be run on localhost via shell:

ansible all -i "localhost," -c local -m shell -a 'echo hello world'

This could be helpful for simple tasks or for some hands-on learning of Ansible.

The example of code is taken from this good article:

Running ansible playbook in localhost