Ansible-playbook run against arbitrary host which is not in inventory file and include group vars - ansible

When I run a playbook runrole.yml this way:
ansible-playbook -i '192.168.0.7,' runrole.yml -e "ROLE=allwindows" -e "TARGETIP=192.168.0.7" -e "ansible_port=5986" --ask-vault-pass
runrole.yml has:
- hosts: '{{TARGETIP}}'
roles:
- { role: '{{ROLE}}' }
It works (i.e. it runs against 192.168.0.7), but it fails because I have not provided all additional arguments
ansible_user: Administrator
ansible_password: SecretPasswordGoesHere
ansible_connection: winrm
I would like Ansible to use variables which are defined in group-vars/allwindows.yml.
It will work, If I add into inventory file into a group [allwindows] host 192.168.0.7:
[allwindows]
host1
...
hostN
192.168.0.7
and run using:
ansible-playbook runrole.yml -e "ROLE=allwindows" -e "TARGETIP=192.168.0.7" -e "ansible_port=5986" --ask-vault-pass
It works fine as it detects that 192.168.0.7 belongs to a group allwindows.
In certain scenarios I would like to run a role against a host without touching the inventory file. How do I specify to include group allwindows to use all variables from group_vars/allwindows.yml without modifying the inventory file?

I have found a hack how to do that. It is not nice as #techraf's answer but it works with ansible-playbook
ATARGETIP=192.168.0.7 && echo "[allwindows]" > tmpinventory && echo "$ATARGETIP" >> tmpinventory && ansible-playbook -i tmpinventory runrole.yml -e "ROLE=allwindows" -e "TARGETIP=$ATARGETIP" -e "ansible_port=5986" --ask-vault-pass && rm tmpinventory

Related

ansible-inventory --list host groups command line

I would like to obtain the list of host group names (only) from ansible-inventory, however I'm having to use grep to trim down the list based on known group name patterns - e.g.
Clean output but messy command line and need to know group name pattern ahead of time:
ansible-inventory -i inventory/production --list --yaml | grep webserver_.*:$
Clean command line and don't need to know group name pattern, but messy output:
ansible-playbook my-playbook.yml -i inventory/production --list-hosts
Is there a clean way to extract just the group names from inventory?
Example hosts.yml:
# NGINX
webserver_1:
hosts:
ws1.public.example.com
webserver_2:
hosts:
ws2.public.example.com
webserver_2:
hosts:
ws2.public.example.com
# EC2 back-ends
backend_ec2_1:
hosts:
be1.internal.example.com
backend_ec2_2:
hosts:
be2.internal.example.com
backend_ec2_3:
hosts:
be3.internal.example.com
[Ansible v2.9.7]
You could use the jq command to parse the json output from ansible-inventory --list, like this:
$ ansible-inventory -i hosts --list | jq .all.children
[
"backend_ec2_1",
"backend_ec2_2",
"backend_ec2_3",
"ungrouped",
"webserver_1",
"webserver_2"
]
Or if you want just bare names:
$ ansible-inventory -i hosts --list | jq -r '.all.children[]'
backend_ec2_1
backend_ec2_2
backend_ec2_3
ungrouped
webserver_1
webserver_2
This command lists the groups defined in the inventory
ansible localhost -m debug -a 'var=groups.keys()' -i inventory/production/

Ansible / Limit tag to group and localhost

Im trying to run my playbook on all machines with tag: mytag with additional param my-zone and on the localhost which is executed the playbook. I tried this:
ansible-playbook myplaybook.yml -i myinventory -e --limit localhost,tag_mytag:&my-zone
but it gives me the next error:
ERROR! Specified --limit does not match any hosts
How can I do it?
Please try as below::
ansible-playbook myplaybook.yml -i myinventory --limit localhost --tag mytag -e var=x
assuming here that, i am limiting my playbook to run only to localhost(--limit).
with tag "mytag" (--tag ) and passing an extra variable ( -e ) as "var=x"

Ansible playbook gating facts in a temporary folder

There are a useful ansible command that gathing the facts and store them, like this,
ansible -m setup --tree out/ all
But how could do it by ansible-playbook -i inventory.ini ? just store the facts but not actually run the playbook and only for diagnosis.
Thanks
James.
Very strange request, but...
To execute only fact-gathering part of your playbook you can execute it with a tag that doesn't exist:
ansible-playbook -i inventory.ini -vv -t zzzz myplaybook.yml
This will dump gathered facts to stdout.
If you want to store it into file, you should do something like this:
ANSIBLE_STDOUT_CALLBACK=json \
ansible-playbook -i inventory.ini -t zzzz myplaybook.yml 2>/dev/null \
| jq '.plays[].tasks[].hosts[]' > tmp_hosts_facts

Ansible adhoc command in sequence

I want to run ansible adhoc command on a list of EC2 instances. I want ansible to run it in sequence but ansible runs them in random. For example:
13:42:21 #cnayak ansible :► ansible aws -a "hostname"
ec2 | SUCCESS | rc=0 >>
ip-172-31-36-255
ec3 | SUCCESS | rc=0 >>
ip-172-31-45-174
13:42:26 #cnayak ansible :► ansible aws -a "hostname"
ec3 | SUCCESS | rc=0 >>
ip-172-31-45-174
ec2 | SUCCESS | rc=0 >>
ip-172-31-36-255
Any way to make them run in order?
By default ansible runs tasks in parallel. If you want them to be executed serially then you can limit number of workers running at the same time by using "--forks" option.
Adding "--forks 1" to your ansible invocation should run your command sequentially on all hosts (in order defined by inventory).
You can use the forks with adhoc command and serial: 1 inside the playbook.
On adhoc command:
ansible aws -a "hostname" --forks=1
Inside the playbook:
- hosts: aws
become: yes
gather_facts: yes
serial: 1
tasks:
- YOUR TASKS HERE
--forks=1 hasn't been sorting inventory for me in recent versions of ansible (2.7)
Another approach I find useful is using the "oneline" output callback, so I can use the standard sort and grep tools on the output:
ANSIBLE_LOAD_CALLBACK_PLUGINS=1 \
ANSIBLE_STDOUT_CALLBACK=oneline \
ansible \
-m debug -a "msg={{ansible_host}}\t{{inventory_hostname}}" \
| sort \
| grep -oP '"msg": \K"[^"]*"' \
| xargs -n 1 echo -e
This has been useful for quick-n-dirty reports on arbitrary vars or (oneline) shell command outputs.

Ansible - List available hosts

I got some hosts in my ansible inventory which the ansible server cannot connect to (there is no pubkey deployed).
How do I list all of them? (List unreachable hosts)
Maybe there is a way to generate an inventory file with all of the hosts?
(the less elegant way is to write a playbook and to copy the command line output, but is there a better way?)
To list them, you can use the ping module, and pipe the output :
ANSIBLE_NOCOWS=1 ansible -m ping all 2>&1 | grep 'FAILED => SSH' | cut -f 1 -d' '
If you want to generate an inventory, you can just redirect the output in a file :
ANSIBLE_NOCOWS=1 ansible -m ping all 2>&1 | grep 'FAILED => SSH' | cut -f 1 -d' ' > hosts_without_key
Then, you can use it later providing the -i switch to ansible commands :
ansible-playbook -i hosts_without_key deploy_keys.yml
If you can ssh using passwords, and assuming you have a key deploying playbook (e.g. deploy_keys.yml), you can issue :
ansible-playbook -i hosts_without_key deploy_keys.yml -kKu someuser
But if the point is to deploy keys on hosts that don't have them, remember Ansible is idempotent. It does no harm to execute the deploy_keys.yml playbook everywhere (it's just a bit longer).
Good luck.

Resources