Im trying to use ansible-pull locally on a remote host where ansible retrieve a playbook on a git repo with an inventory.
I dont know how to point to the remote host in the inventory and in group vars. I have tried with the machine_name (user#machine_name in bash) but it tells me
[WARNING]: Could not match supplied host pattern, ignoring:
this is my inventory :
all:
children:
webserver:
hosts:
ip-172-31-21-218: #this is the machine name
dbserver:
hosts:
node2:
ansible_host: 34.201.53.127
I want the playbook to use the host machine to play the playbook locally with ansible pull but using the inventory to understand the inventory machine name matches the host machine name...
this is sample from official documentation and keep reading the comments :)
all:
hosts: # you ignore this line
mail.example.com: # and this line also
children:
webservers:
hosts:
foo.example.com:
bar.example.com:
dbservers:
hosts:
one.example.com:
two.example.com:
three.example.com:
Regards.
I am having a strange issue. I have a 'hosts' file with multiple groups in it.
For some reason, when I am using 'ansible-playbook playbook.yml -l GROUPNAME', ansible applies the playbook to all hosts in the 'hosts' file.
hosts file
all:
children:
GROUP1:
children:
webservers:
hosts:
hostname1:
sqlservers:
hosts:
hostname2:
GROUP2:
children:
webservers:
hosts:
hostname3:
hostname4:
GROUP3:
children:
webservers:
hosts:
hostname5:
hostname6:
sqlservers:
hosts:
hostname7:
ansible log:
Positional arguments: playbook.yml
verbosity: 4
connection: smart
timeout: 10
become_method: sudo
tags: ('all',)
inventory: ('hostsfile',)
subset: GROUP1
forks: 5
1 plays in playbook.yml
In the 'playbook.yml' file I do have 'hosts: all' but in a different job I don't have this issue.
Ansible does notice the Subset I indicated but is not filtering it, instead it is running the playbook successfully against all hosts.
I combed through the web for the entire day yesterday and could not find the problem.
Any help will be greatly appreciated.
I think I found the solution to this problem on my own.
By default, Ansible is parsing the hosts file using a set of inventory plugins until it will succeed.
By specifying the plugin in 'ansible.cfg':
[inventory]
enable_plugins = yaml
The problem was solved, I am not sure why.
https://docs.ansible.com/ansible/latest/plugins/inventory.html
Following is simple playbook
- name: Create VM and associated resources
hosts: linux
connection: local
vars_files:
- vars_files/{{ env_name }}_vars.yml
- vars_files/base_vars.yml
roles:
- linux
And my inventory File is TEST.yml
all:
vars:
env_name: TEST
linux:
hosts:
TEST-SERVER:
ansible_host: 10.10.10.10
When I run the playbook ansible-playbook -vvv plabook_test.yml, I am receiving the following error.
skipping vars_file 'vars_files/{{ env_name }}_vars.yml' due to an undefined variable
Any Idea how can I used a variable from my inventory in the file name?
Any help is greatly appreciated.
Thanks,
The inventory file is wrong because of the key "host"
all:
vars:
env_name: TEST
linux:
host:
TEST-SERVER:
ansible_host: 10.10.10.10
You should have seen a warning
[WARNING]: Skipping unexpected key (host) in group (linux), only "vars", "children" and "hosts" are valid
Fix the inventory
all:
vars:
env_name: TEST
linux:
hosts:
TEST-SERVER:
ansible_host: 10.10.10.10
I'm trying to perform tasks in the playbook for the hosts mentioned in my inventory file which are grouped under "Jira" But for some reason my group is not being identified to pick. for the content of the files please look below.
How can I run all the tasks mentioned in the playbook with all the hosts in the inventory?
I have an Inventory file with the below contents: Hosts.yml
all: # the all group contains all hosts
hosts:
ansible:
ansible_host: #{ansible-controller}
ansible_user: root
crowd:
ansible_host: #{crowd}
ansible_user: root
jira:
ansible_host1: 53.31.54.56
ansible_host2: 53.31.54.55
I have playbook with content:
---
- name: Install Jira Application
hosts: jira
gather_facts: true
become: true
remote_user: root
roles:
- ansible-preparation
#- jira-applicationsetup
I always get below error message:
root#sedcagse0550:/usr/Anil/InfraAutomation/gsep-infrastructure-automation : ansible-playbook jira-fullinstall.yml
[WARNING]: Could not match supplied host pattern, ignoring: jira
PLAY [Install Jira Application] *************************************************************
skipping: no hosts matched
PLAY RECAP **********************************************************************************
How can I perform all the tasks to all the hosts mentioned in the inventory file?
You should run the ansible-playbook with inventory parameter(-i) like this:
ansible-playbook -i Hosts.yml jira-fullinstall.yml
Otherwise, ansible checks the default inventory file location which is "/etc/ansible/hosts".
If your Hosts.yml already in that location, check your inventory file. In Ansible 2.7 User Guide YAML inventory files look like this:
all:
jira:
hosts:
53.31.54.56:
53.31.54.55:
If i understood it correct, Your inventory file should look like as below::
ansible: # Group Name
hosts:
ansible_host: #Host name
ansible_user: root # Host Variable
crowd:
hosts:
ansible_host: #{crowd}
ansible_user: root
jira:
hosts:
ansible_host1:
ansible_host: 53.31.54.56
ansible_host2:
ansible_host: 53.31.54.55`
Please refer this link for detailed formatting about yaml based inventory
This is a fragment of a playbook that I'm using (server.yml):
- name: Determine Remote User
hosts: web
gather_facts: false
roles:
- { role: remote-user, tags: [remote-user, always] }
My hosts file has different groups of servers, e.g.
[web]
x.x.x.x
[droplets]
x.x.x.x
Now I want to execute ansible-playbook -i hosts/<env> server.yml and override hosts: web from server.yml to run this playbook for [droplets].
Can I just override as a one time off thing, without editing server.yml directly?
Thanks.
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
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'
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.
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
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 == "")
Just came across this googling for a solution. Actually, there is one in Ansible 2.5. You can specify your inventory file with --inventory, like this: ansible --inventory configs/hosts --list-hosts all
If you want to run a task that's associated with a host, but on different host, you should try delegate_to.
In your case, you should delegate to your localhost (ansible master) and calling ansible-playbook command
I am using ansible 2.5 (2.5.3 exactly), and it seems that the vars file is loaded before the hosts param is executed. So you can set the host in a vars.yml file and just write hosts: {{ host_var }} in your playbook
For example, in my playbook.yml:
---
- hosts: "{{ host_name }}"
become: yes
vars_files:
- vars/project.yml
tasks:
...
And inside vars/project.yml:
---
# general
host_name: your-fancy-host-name
Here's a cool solution I came up to safely specify hosts via the --limit option. In this example, the play will end if the playbook was executed without any hosts specified via the --limit option.
This was tested on Ansible version 2.7.10
---
- name: Playbook will fail if hosts not specified via --limit option.
# Hosts must be set via limit.
hosts: "{{ play_hosts }}"
connection: local
gather_facts: false
tasks:
- set_fact:
inventory_hosts: []
- set_fact:
inventory_hosts: "{{inventory_hosts + [item]}}"
with_items: "{{hostvars.keys()|list}}"
- meta: end_play
when: "(play_hosts|length) == (inventory_hosts|length)"
- debug:
msg: "About to execute tasks/roles for {{inventory_hostname}}"
This worked for me as I am using Azure devops to deploy an application using CICD pipelines. I had to make this hosts (in yml file) more dynamic so in release pipeline I can add it's value, for example:
--extra-vars "host=$(target_host)"
pipeline_variable
My ansible playbook looks like this
- name: Apply configuration to test nodes
hosts: '{{ host }}'