Three options to Safely Limit Ansible Playbooks Execution to a Single Machine.

Today we’re going to talk about the three options to limit the execution of a potentially harmful Ansible Playbook to only one host. I’m Luca Berton and welcome to today’s episode of Ansible Pilot.

Limit Ansible Playbook to only one HOSTNAME

  • use --limit at runtime
  • hosts: HOSTNAME Ansible Playbook
  • hosts: "{{ HOSTS }}" Ansible Playbook

Let’s deep dive into our use case to Limit Ansible Playbook to only one HOSTNAME. I’m going to show three different ways to achieve this result: using the --limit parameter at runtime, limit the HOSTNAME in the Playbook code and the most advanced way is to define a variable in the Ansible Playbook that you could populate on-demand. Let’s discuss the pros and cons of each option.

Join 50+ hours of courses in our exclusive community

Playbook

In the following Playbook scenarios, I’d like to execute my harmful Ansible Playbook ONLY against demo.example.com host. This is my Playbook inventory file:

[linux]
demo.example.com
Playbook2.example.com
[all:vars]
ansible_connection=ssh
ansible_user=devops
ansible_ssh_private_key_file=~/.ssh/id_rsa

Ansible command limit option

  • --limit
  • ansible-playbook - limit HOSTNAME PLAYBOOK

Using the --limit parameter of the ansible-playbook command is the easiest option to limit the execution of the code to only one host. The advantage is that you don’t need to edit the Ansible Playbook code before executing to only one host. The drawback is that you should remember every time you execute the command and sometimes humans are not so reliable.

code

  • playbook.yml
---
- name: harmful playbook
  hosts: all
  tasks:
    - name: harmful task
      ansible.builtin.debug:
        msg: "harmful task"

execution

ansible-pilot $ ansible-playbook --limit demo.example.com -i limit/inventory limit/playbook.yml
PLAY [harmful playbook] ***************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [demo.example.com]
TASK [harmful task] *******************************************************************************
ok: [demo.example.com] => {
    "msg": "harmful task"
}
PLAY RECAP ****************************************************************************************
demo.example.com           : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
ansible-pilot $

wrong execution

If we forgot the --limit option the result could be very harmful.

ansible-pilot $ ansible-playbook -i limit/inventory limit/playbook.yml
PLAY [harmful playbook] ***************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [demo.example.com]
ok: [Playbook2.example.com]
TASK [harmful task] *******************************************************************************
ok: [demo.example.com] => {
    "msg": "harmful task"
}
ok: [Playbook2.example.com] => {
    "msg": "harmful task"
}
PLAY RECAP ****************************************************************************************
demo.example.com           : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
Playbook2.example.com          : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
ansible-pilot $

Ansible Playbook hosts

  • hosts: HOSTNAME
  • ansible-playbook PLAYBOOK

Using the hosts statement in the Ansible Playbook allows you to specify a host or a group of hosts for the execution. The advantage is that is more reliable than manually specifying the hostname than using the --limit parameter from the command line. The drawback is that you need to remember to edit the Ansible Playbook code every time. If you don’t you’re going to execute the code on the specified host, still a potential manual issue.

code

  • playbook2.yml
---
- name: harmful playbook
  hosts: demo.example.com
  tasks:
    - name: harmful task
      ansible.builtin.debug:
        msg: "harmful task"

execution

ansible-pilot $ ansible-playbook -i limit/inventory limit/playbook2.yml
PLAY [harmful playbook] ***************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [demo.example.com]
TASK [harmful task] *******************************************************************************
ok: [demo.example.com] => {
    "msg": "harmful task"
}
PLAY RECAP ****************************************************************************************
demo.example.com           : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
ansible-pilot $

Ansible Playbook hosts advanced

  • hosts: "{{ HOSTS }}"
  • ansible-playbook -e "HOSTS=demo.example.com" PLAYBOOK

Using the hosts statement in the Ansible Playbook allows you to specify also a variable that you could populate with a host or a group of host for the execution. Basically, if you blindly execute the Ansible Playbook code on the command line is doing nothing. The only way is to process is to populate the host variable via an extra variable via the console line. The advantage is that is more reliable than manually specifying the hostname than using the --limit parameter from the command line. This option combines the advantages of the previous option and my favorite as well.

code

  • playbook3.yml
---
- name: harmful playbook
  hosts: "{{ HOSTS }}"
  tasks:
    - name: harmful task
      ansible.builtin.debug:
        msg: "harmful task"

execution

ansible-pilot $ ansible-playbook -i limit/inventory -e "HOSTS=demo.example.com" limit/playbook3.yml
PLAY [harmful playbook] ***************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [demo.example.com]
TASK [harmful task] *******************************************************************************
ok: [demo.example.com] => {
    "msg": "harmful task"
}
PLAY RECAP ****************************************************************************************
demo.example.com           : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
ansible-pilot $

wrong execution

ansible-pilot $ ansible-playbook -i limit/inventory limit/playbook3.yml 
[WARNING]: Could not match supplied host pattern, ignoring: HOSTS
PLAY [harmful playbook] ***************************************************************************
skipping: no hosts matched
PLAY RECAP ****************************************************************************************
ansible-pilot $

code with ❤️ in GitHub

Conclusion

Now you know the Three options to Safely Limit Ansible Playbooks Execution to a Single Machine that you could apply to your everyday journey based on your use case.

Subscribe to the YouTube channel, Medium, and Website, X (formerly Twitter) to not miss the next episode of the Ansible Pilot.

Academy

Learn the Ansible automation technology with some real-life examples in my Udemy 300+ Lessons Video Course.

BUY the Complete Udemy 300+ Lessons Video Course

My book Ansible By Examples: 200+ Automation Examples For Linux and Windows System Administrator and DevOps

BUY the Complete PDF BOOK to easily Copy and Paste the 250+ Ansible code

Want to keep this project going? Please donate

Patreon Buy me a Pizza