296

Is it possible to run commands on the Ansible controller node?

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.

8 Answers 8

409

Yes, you can run commands on the Ansible host. You can specify that all tasks in a play run on the Ansible host, or you can mark individual tasks to run on the Ansible host.

If you want to run an entire play on the Ansible host, then specify hosts: 127.0.0.1 and connection:local in the play, for example:

    - name: a play that runs entirely on the ansible host
      hosts: 127.0.0.1
      connection: local
      tasks:
      - name: check out a git repository
        git: repo=git://foosball.example.org/path/to/repo.git dest=/local/path

See Local Playbooks in the Ansible documentation for more details.

If you just want to run a single task on your Ansible host, you can use local_action to specify that a task should be run locally. For example:

    - name: an example playbook
      hosts: webservers
      tasks:
      - ...

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

See "Controlling where tasks run: delegation and local actions" in the Ansible documentation for more details.


You can avoid having to type connection: local in your play by adding this to your inventory:

localhost ansible_connection=local

(Here you'd use "localhost" instead of "127.0.0.1" to refer to the play).


In newer versions of Ansible, you no longer need to add the above line to your inventory, Ansible assumes it's already there.

3
  • 8
    I also needed sudo: no in the delegation scenario
    – Danimal
    Commented Mar 17, 2016 at 18:02
  • how to run local connection as a root user? Commented Feb 15, 2017 at 8:33
  • 2
    @BilalUsean ansible-playbook -K playbook.yml where -K for root
    – Kush
    Commented Jun 23, 2018 at 14:34
99

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
3
  • 3
    Interesting, how would that work with command? Because as far as I know we cannot use the param free_form to define the command that will be executed
    – Ander
    Commented Sep 8, 2016 at 4:40
  • @Ander The same applys to the shell module.
    – ceving
    Commented Jan 26, 2017 at 12:27
  • 7
    for use with command/shell, what you want is the "_raw_params"
    – mvr
    Commented Apr 5, 2017 at 2:10
67

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

2
  • 2
    What is the significance of comma (,) after localhost. I noticed it's vital for command to work Commented Oct 6, 2016 at 7:44
  • 3
    the trailing comma is to define a simple inventory with pointing to a file. It's sort of an undocumented hack, and could go away (iirc).
    – senorsmile
    Commented Jan 6, 2017 at 5:40
28

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
1
  • 2
    Agree. Least new syntax, most flexible (delegate elsewhere too). One item to note - if become is True for the task, it will complain about sudo and such. That could happen directly on the task or be inherited for elsewhere.
    – JL Peyret
    Commented Sep 5, 2018 at 2:21
5

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"
4

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.

1
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
0
0

Use this command: ansible-playbook -i "localhost," -c local your_file_name.yml

Note that the comma after "localhost," is required.

EXAMPLE:

We’re using shell module to run ‘echo hello world’ in localhost. Now lets write a playbook helloworld.yml

---
- hosts: all
  tasks:
    - shell: echo "hello world"

Running the playbook:

ansible-playbook -i "localhost," -c local helloworld.yml 

Output:

PLAY [all] *********

GATHERING FACTS *********
ok: [localhost]

TASK: [shell echo "hello world"] *********
changed: [localhost]

PLAY RECAP *********
localhost                  : ok=2    changed=1    unreachable=0    failed=0   

REFERENCES:

Running ansible playbook in localhost: https://web.archive.org/web/20180513205612/http://ansible.pickle.io/post/86598332429/running-ansible-playbook-in-localhost

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.