Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override hosts variable of Ansible playbook from the command line

People also ask

How do I skip hosts in Ansible?

By using –limit argument with ansible-playbook command we can exclude a host from playbook execution. If hostname starts with “!” it will excluded from host execution.

How do you override extra variables in Ansible?

You can override all other settings from all other sources in all other precedence categories at the command line by Using -e extra variables at the command line, but that is not a command-line option, it is a way of passing a variable. The help for each command-line tool lists available options for that tool.

How do you pass variables in Ansible playbook command?

To pass a value to nodes, use the --extra-vars or -e option while running the Ansible playbook, as seen below. This ensures you avoid accidental running of the playbook against hardcoded hosts.

How do you define variables in the command line interface while executing playbook?

You can define variables when you run your playbook by passing variables at the command line using the --extra-vars (or -e ) argument. You can also request user input with a vars_prompt (see Interactive input: prompts).


I don't think Ansible provides this feature, which it should. Here's something that you can do:

hosts: "{{ variable_host | default('web') }}"

and you can pass variable_host from either command-line or from a vars file, e.g.:

ansible-playbook server.yml --extra-vars "variable_host=newtarget(s)"

For anyone who might come looking for the solution.
Play Book

- hosts: '{{ host }}'
  tasks:
  - debug: msg="Host is {{ ansible_fqdn }}"

Inventory

[web]
x.x.x.x

[droplets]
x.x.x.x

Command: ansible-playbook deplyment.yml -i hosts --extra-vars "host=droplets" So you can specify the group name in the extra-vars


This is a bit late, but I think you could use the --limit or -l command to limit the pattern to more specific hosts. (version 2.3.2.0)

You could have - hosts: all (or group) tasks: - some_task

and then ansible-playbook playbook.yml -l some_more_strict_host_or_pattern and use the --list-hosts flag to see on which hosts this configuration would be applied.


We use a simple fail task to force the user to specify the Ansible limit option, so that we don't execute on all hosts by default/accident.

The easiest way I found is this:

---
- name: Force limit
  # 'all' is okay here, because the fail task will force the user to specify a limit on the command line, using -l or --limit
  hosts: 'all'

  tasks:
  - name: checking limit arg
    fail:
      msg: "you must use -l or --limit - when you really want to use all hosts, use -l 'all'"
    when: ansible_limit is not defined
    run_once: true

Now we must use the -l (= --limit option) when we run the playbook, e.g.

ansible-playbook playbook.yml -l www.example.com

Limit option docs:

Limit to one or more hosts This is required when one wants to run a playbook against a host group, but only against one or more members of that group.

Limit to one host

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit "host1"

Limit to multiple hosts

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit "host1,host2"

Negated limit.
NOTE: Single quotes MUST be used to prevent bash interpolation.

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit 'all:!host1'

Limit to host group

ansible-playbook playbooks/PLAYBOOK_NAME.yml --limit 'group1'


I'm using another approach that doesn't need any inventory and works with this simple command:

ansible-playbook site.yml -e working_host=myhost

To perform that, you need a playbook with two plays:

  • first play runs on localhost and add a host (from given variable) in a known group in inmemory inventory
  • second play runs on this known group

A working example (copy it and runs it with previous command):

- hosts: localhost
  connection: local
  tasks:
  - add_host:
      name: "{{ working_host }}"
      groups: working_group
    changed_when: false

- hosts: working_group
  gather_facts: false
  tasks:
  - debug:
      msg: "I'm on {{ ansible_host }}"

I'm using ansible 2.4.3 and 2.3.3


I changed mine to default to no host and have a check to catch it. That way the user or cron is forced to provide a single host or group etc. I like the logic from the comment from @wallydrag. The empty_group contains no hosts in the inventory.

- hosts: "{{ variable_host | default('empty_group') }}"

Then add the check in tasks:

   tasks:
   - name: Fail script if required variable_host parameter is missing
     fail:
       msg: "You have to add the --extra-vars='variable_host='"
     when: (variable_host is not defined) or (variable_host == "")

An other solution is to use the special variable ansible_limit which is the contents of the --limit CLI option for the current execution of Ansible.

- hosts: "{{ ansible_limit | default(omit) }}"

If the --limit option is omitted, then Ansible issues a warning, but does nothing since no host matched.

[WARNING]: Could not match supplied host pattern, ignoring: None

PLAY ****************************************************************
skipping: no hosts matched