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
Related
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.
Ansible Version: 2.8.3
I have the following hosts.yaml file for use in Ansible
I have applications that I want to deploy on potentially both rp_1 and rp_2
---
all:
vars:
docker_network_name: devopsNet
http_protocol: http
http_host: ansiblenode01_new.example.com
http_url: "{{ http_protocol }}://{{ http_host }}:{{ http_port }}/{{ http_context }}"
hosts:
ansiblenode01_new.example.com:
ansiblenode02_new.example.com:
children:
##################################################################
rp_1:
children:
httpd:
hosts:
ansiblenode01_new.example.com:
vars:
number_of_tools: 6
outside_port: 443
jenkins:
hosts:
ansiblenode01_new.example.com:
vars:
http_port: 4444
http_context: jenkins
artifactory:
hosts:
ansiblenode01_new.example.com:
vars:
http_port: 8000
http_context: artifactory
rp_2:
children:
httpd:
hosts:
ansiblenode02_new.example.com:
vars:
number_of_tools: 4
outside_port: 7090
jenkins:
hosts:
ansiblenode02_new.example.com:
vars:
http_port: 7990
http_context: jenkins
artifactory:
hosts:
ansiblenode02_new.example.com:
vars:
http_port: 8000
http_context: artifactory
The following python wrapper script is calling ansible-playbook in a loop to deploy the applications
#!/usr/bin/python
import yaml
import os
import getpass
with open('hosts.yaml') as f:
var = yaml.load(f)
sudo_pass = getpass.getpass(prompt="Please enter sudo password: ")
# Running individual ansible-playbook deployment for each application listed and uncommented under 'applications' object.
for network in var['all']['children']:
for app in var['all']['children'][network]['children']:
os.system('ansible-playbook deploy.yml --extra-vars "application='+app+' ansible_sudo_password='+sudo_pass+'"')
The problem I recognize is that both Ansible and Python will use the hosts.yaml file, but not use it the way I thought it would as I'm not too familiar with Ansible.
The hosts.yaml was written in a format that is required by Ansible.
The Python script will open the yaml file, make a dictionary out of it, and step through the dictionary and look for the application names to pass to the command line call. The problem is then that Python only passes the name of the app as a string to the invocation of ansible-playbook, the dictionary structure obviously doesn't get passed, so Ansible will then open the hosts.yaml file as well, but all it does is step through the yaml and look for the first occurrence of the app name that was passed as an argument when ansible-playbook was invoked, completely disregarding the structure I've created in the yaml file.
So basically only the rp_1 group in the yaml file will be executed since Ansible, I think reads through the yaml from top down and stops at the first occurrence, therefore all or parts of the rp_2 group will never be processed by Ansible if the group contains all or some of the same apps as rp_1, therefore running the same deployment twice.
Is there a way to invoke Ansible or some ways to set the playbooks up so that Ansible will recognize that in my hosts file, I have networks (rp_1, rp_2) that I want to setup and executes the playbooks in the grouping that I've created in the yaml file?
Ansible already has this built-in. You do not need a wrapper script.
To run the deploy.yml playbook on all hosts in your hosts.yaml (this is called "inventory" btw.) do this:
ansible-playbook -i hosts.yaml deploy.yml -bK
To only run it on rp_1, do this:
ansible-playbook -i hosts.yaml deploy.yml --limit rp_1 -bK
-b makes ansible become root
-K will make ansible ask for the password to become root
-i <file> specifies the inventory file
--limit <host/group> limits the execution to certain hosts or groups, you can also add more than one, as a comma-separated list (e.g., pr_1,rp_2)
You can also specify a list of hosts/groups in your playbook like this:
- name: do whatever you like
hosts:
- rp_1
- rp_2
become: yes
tasks:
- debug:
msg: "I'm running on {{ inventory_hostname }}!"
Further reading:
Discovering variables: facts and magic variables
How to build your inventory
Special variables
Using variables
Ansible examples
Accessing variables of "other" hosts: on serverfault and stackoverflow
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 would like to apply playbook to a subset of hosts. To all dbservers hosts under 'atlanta', not under 'raleigh
but I cannot figure out how to use --limit to point to a specific subtree of hosts in the inventory
ansible all -i ./testhosts.yml --limit atlanta --list-hosts
hosts (4):
host1-atlanta
host2-atlanta
host1-raleigh
host2-raleigh
ansible all -i ./testhosts.yml --limit 'atlanta:&dbservers' --list-hosts
hosts (4):
host1-atlanta
host2-atlanta
host1-raleigh
host2-raleigh
what I am hoping to get is
host1-atlanta
host2-atlanta
(in my case the 'logical' path to the subtree is: all:usa:southeast:atlanta:dbservers)
My example testhosts.yml
all:
children:
usa:
children:
southeast:
children:
atlanta:
children:
dbservers:
hosts:
host1-atlanta:
ansible_port: 11022
ansible_host: 11.0.1.2
host2-atlanta:
ansible_port: 11022
ansible_host: 11.0.1.3
raleigh:
children:
dbservers:
hosts:
host1-raleigh:
ansible_port: 11022
ansible_host: 10.0.1.2
host2-raleigh:
ansible_port: 11022
ansible_host: 10.0.1.3
northeast:
northwest:
southwest:
is it possible to get the --limit command line option to filter out everything, except a particular subtree ?
My higher level ansible invocation scripts already know what site they will operate on, so I was hoping I could somehow have a common hosts file but be able to specify groups using some sort of a tree-navigation 'selector'.
I realize that I could do
ansible atlanta -i ./testhosts.yml --limit atlanta --list-hosts
but the problem I am running into with that, is that this type of 'selector' is not available when I use ansible-playbook.
And the only selector (filter) that I could find was --limit, and that does not seem to work for me.
Despite appearances, groups in ansible are not hierarchical. You have a single dbservers group, and members of that group also belong to both atlanta and raleigh. With a small change in your inventory you can get closer to what you want:
all:
children:
dbservers:
children:
dbservers-atl:
dbservers-ral:
usa:
children:
southeast:
children:
atlanta:
children:
dbservers-atl:
hosts:
host1-atlanta:
ansible_port: 11022
ansible_host: 11.0.1.2
host2-atlanta:
ansible_port: 11022
ansible_host: 11.0.1.3
raleigh:
children:
dbservers-ral:
hosts:
host1-raleigh:
ansible_port: 11022
ansible_host: 10.0.1.2
host2-raleigh:
ansible_port: 11022
ansible_host: 10.0.1.3
northeast:
northwest:
southwest:
With this inventory, each region has a seperate dbservers-<tag> group. There is a global dbservers group outside of your region hierarchy that includes all dbservers-<tag> groups. With this, you can ask for:
ansible all --list-hosts --limit dbservers-atl
And get:
hosts (2):
host1-atlanta
host2-atlanta
Or you can ask for the dbservers group:
ansible all --list-hosts --limit dbservers
And get:
hosts (4):
host1-raleigh
host2-raleigh
host1-atlanta
host2-atlanta
Your statement about the '--limit' option is not correct:
... this type of 'selector' is not available when I use ansible-playbook.
Quoting from 'man ansible', or 'man ansible-playbook':
-l 'SUBSET', --limit 'SUBSET'
further limit selected hosts to an additional pattern
Details are available in Working with Patterns. For example an equivalent of running ansible
ansible all --limit '!dbservers' ...
is declaring 'hosts' in a playbook.yml
- hosts: all:!dbservers
and running
ansible-playbook playbook.yml
Next equivalent is declaring all 'hosts' in the playbook.yml
- hosts: all
and running
ansible-playbook --limit '!dbservers' playbook.yml
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