Our vendor sends us Ansible playbooks and scripts for deployment. I need to check availability of some IP for ansible inventory groups, like:
ansible mgm -i inventories/vrxinventory -m shell -a 'ping http://10.33.63.66/vrx/' -u user -k -v.
The destination is changing depending on the environment. Those destination IPs to ping are in group vars .yml file.
Is it possible to use variables from this group_var.yml file, through command line like:
ansible mgm -i inventories/vrxinventory -m shell -a "ping {{ vrm_repo_url }}" -u user -k -v ?
I really don't want to mess with their playbooks modification using sed/awk, during CI.
Is it possible to use variables from this group_var.yml file, through command line like: ansible mgm -i inventories/vrxinventory -m shell -a "ping {{ vrm_repo_url }}" -u user -k -v
Yes, group variables will be read by ansible command for ad-hoc commands.
No, it makes no sense to execute ping {{ vrm_repo_url }} through shell module in Ansible:
firstly, because by default ping runs infinitely (this can be mitigated with parameters);
secondly, because you won't see any output of the ping command.
What you most likely want is to use:
a wait_for module with low connect_timeout parameter to check the connectivity between the target and some other machine;
or a get_url module (as you seemingly want to check availability of web services).
Related
I am trying to use ansible dynamic inventory.
I am getting the results when I run,
$ ./ec2.py --list
...
...
"ec2": [
"xx.xx.xx.xx"
]
}
But when I try to run it with ansible command, it does not run successfully.
$ ansible -i ec2.py -e "ansible_ssh_port=3003" -m ping
Usage: ansible <host-pattern> [options]
Define and run a single task 'playbook' against a set of hosts
Options:
-a MODULE_ARGS, --args=MODULE_ARGS
module arguments
--ask-vault-pass ask for vault password
-B SECONDS, --background=SECONDS
run asynchronously, failing after X seconds
(default=N/A)
-C, --check don't make any changes; instead, try to predict some
of the changes that may occur
-D, --diff when changing (small) files and templates, show the
differences in those files; works great with --check
-e EXTRA_VARS, --extra-vars=EXTRA_VARS
set additional variables as key=value or YAML/JSON, if
filename prepend with #
-f FORKS, --forks=FORKS
specify number of parallel processes to use
(default=5)
-h, --help show this help message and exit
-i INVENTORY, --inventory=INVENTORY, --inventory-file=INVENTORY
specify inventory host path or comma separated host
list. --inventory-file is deprecated
-l SUBSET, --limit=SUBSET
further limit selected hosts to an additional pattern
--list-hosts outputs a list of matching hosts; does not execute
anything else
-m MODULE_NAME, --module-name=MODULE_NAME
module name to execute (default=command)
-M MODULE_PATH, --module-path=MODULE_PATH
prepend colon-separated path(s) to module library (def
ault=['/Users/luvpreetsingh/.ansible/plugins/modules',
'/usr/share/ansible/plugins/modules'])
-o, --one-line condense output
--playbook-dir=BASEDIR
Since this tool does not use playbooks, use this as a
subsitute playbook directory.This sets the relative
path for many features including roles/ group_vars/
etc.
-P POLL_INTERVAL, --poll=POLL_INTERVAL
set the poll interval if using -B (default=15)
--syntax-check perform a syntax check on the playbook, but do not
execute it
-t TREE, --tree=TREE log output to this directory
--vault-id=VAULT_IDS the vault identity to use
--vault-password-file=VAULT_PASSWORD_FILES
vault password file
-v, --verbose verbose mode (-vvv for more, -vvvv to enable
connection debugging)
--version show program's version number and exit
Connection Options:
control as whom and how to connect to hosts
-k, --ask-pass ask for connection password
--private-key=PRIVATE_KEY_FILE, --key-file=PRIVATE_KEY_FILE
use this file to authenticate the connection
-u REMOTE_USER, --user=REMOTE_USER
connect as this user (default=None)
-c CONNECTION, --connection=CONNECTION
connection type to use (default=smart)
-T TIMEOUT, --timeout=TIMEOUT
override the connection timeout in seconds
(default=10)
--ssh-common-args=SSH_COMMON_ARGS
specify common arguments to pass to sftp/scp/ssh (e.g.
ProxyCommand)
--sftp-extra-args=SFTP_EXTRA_ARGS
specify extra arguments to pass to sftp only (e.g. -f,
-l)
--scp-extra-args=SCP_EXTRA_ARGS
specify extra arguments to pass to scp only (e.g. -l)
--ssh-extra-args=SSH_EXTRA_ARGS
specify extra arguments to pass to ssh only (e.g. -R)
Privilege Escalation Options:
control how and which user you become as on target hosts
-s, --sudo run operations with sudo (nopasswd) (deprecated, use
become)
-U SUDO_USER, --sudo-user=SUDO_USER
desired sudo user (default=root) (deprecated, use
become)
-S, --su run operations with su (deprecated, use become)
-R SU_USER, --su-user=SU_USER
run operations with su as this user (default=None)
(deprecated, use become)
-b, --become run operations with become (does not imply password
prompting)
--become-method=BECOME_METHOD
privilege escalation method to use (default=sudo),
valid choices: [ sudo | su | pbrun | pfexec | doas |
dzdo | ksu | runas | pmrun | enable ]
--become-user=BECOME_USER
run operations as this user (default=root)
--ask-sudo-pass ask for sudo password (deprecated, use become)
--ask-su-pass ask for su password (deprecated, use become)
-K, --ask-become-pass
ask for privilege escalation password
Some modules do not make sense in Ad-Hoc (include, meta, etc)
ERROR! Missing target hosts
I get this long statement with the error of missing target hosts.
Then, when I run by specifying the region, it does not give any error but does not return any instances.
$ ansible -i ec2.py us-west-2 -e "ansible_ssh_port=3003" -m ping
[WARNING]: Could not match supplied host pattern, ignoring: us-west-2
[WARNING]: No hosts matched, nothing to do
Firstly, why is it not running? what am I doing wrong?
Secondly, why do the error changes when I specify the region? Is specifying region mandatory? shouldn't it pick the region from ec2.ini?
You do not have any hosts listed. Try adding all at the end of your ansible command:
ansible -i ec2.py -e "ansible_ssh_port=3003" -m ping all
The above command is partly right. The inventory has been specified with the -i argument but the target host group has not been specified. The command should be
ansible all -i ec2.py -e "ansible_ssh_port=3003" -m ping
# The command syntax could be written as below
ansible <target_host_group> -i <inventory> -e "extra_vars" -m "module_name" -a "module_arguments"
Please refer to the documentation on Working with patterns and Ad-Hoc Commands from the ansible documentation.
I would like to know how can I pass multiple show commands in ios_command module in ad-hoc mode.
Sample with just one command:
ansible all -m ios_command -a "commands='show version'"
Now here I would like to send another command, say show run or any other.
Any suggestions on this would be appreciated.
You need to pass a list and you can do it using JSON string:
ansible all -m ios_command -a "commands='[ \"show version\", \"show run\" ]'"
If you leave the spaces out, you can squeeze to 'commands=["show version","show run"]'
I use the following:
ansible ios-device -m ios_command -a commands="{{ lookup('file', 'commands.txt') }}" -u username -k
where commands.txt contains
show version
You can add more commands on each line of the 'commands.txt' file.
Fairly new to Ansible.
I have a text file which contains a list of ec2 instance ip addresses. Secondly, I have a .yml file which applies tags to an array of ec2 ips.
Does anyone what run command I would use to pass the list of ips stored as a text file? I did it once a while back before. I forgot the run command, and cannot find it in my history.
I have a text file which contains a list of ec2 instance ip addresses: you probably mean an inventory file.
to include it in your ansible command execution, add -i <file name>
example:
ansible-playbook -i <inventory file> <yml file>
You could create an inventory with your IP's, for example, something like /tmp/my-ec2-vms:
[my-ec2-vms]
10.1.2.10
10.1.2.11
10.1.2.12
10.1.2.13
...
[my-ec2-vms:vars]
ansible_python_interpreter=/usr/local/bin/python
Then for testing, you could use the ping module, for example:
ansible -i /tmp/my-ec2-vms -m ping all
If that works later you could just run your playbooks:
ansible-playbook -i /tmp/my-ec2-vms my-playbook.yml
I'm trying to execute this on the Master Node
ansible all -m shell -a "/bin/ping -c3 `hostname`"
And instead of pinging remote hostname, it's pinging Master Node
e.g., Master Node hostname = Master
Remote Node hostname = Slave
The above command does this
/bin/ping -c3 Master (instead of /bin/ping -c3 Slave)
Please suggest on how to achieve this in Ansible.
If you backquote the hostname like this: `hostname` then it is a command that will be executed on the localhost. If you really want to execute it on remote host, then use inventory_hostname
Try:
ansible all -m shell -a "/bin/ping -c3 {{inventory_hostname}}"
If you want to execute hostname in the target host, then escape the backquote so that it is not interpreted by the shell on local machine.
ansible all -m shell -a "/bin/ping -c3 \`hostname\`"
Adding to helloV answer,while inventory_hostname is taken from your inventory files, you might also want to look at
{{ ansible_nodename }} - hostname as the system reports it
{{ ansible_hostname }} - unqualified hostname that shows the string before the first period(.)
If you really want to use output of hostname command instead of ansible gathered facts, you should use single quotes in your command, like
ansible all -m shell -a '/bin/ping -c3 `hostname`'
Single quotes will preserve exact syntax to be passed to remote hosts, while when you are using double quotes, expression will be evaluated on master node before passed forward to managed hosts
See Difference between single and double quotes in Bash for future reference.
Also, so please use $(command) syntax instead of `command`, see https://unix.stackexchange.com/questions/126927/have-backticks-i-e-cmd-in-sh-shells-been-deprecated
I'm a beginner with Ansible and trying to write a string to a file with an Ad-Hoc command I'm trying to play around with the replace module. The file I'm trying to write to is /etc/motd/.
ansible replace --sudo /etc/motd "This server is managed by Ansible"
Any help would be appreciated thanks!
Have a look at the lineinfile module usage and a general syntax for Ad hoc commands.
What you are looking for is:
ansible target_node -b -m lineinfile -a 'dest=/etc/motd line="This server is managed by Ansible"'
in extended form:
ansible target_node --become --module-name=lineinfile --args='dest=/etc/motd line="This server is managed by Ansible"'
Explanation:
target_node is the hostname or group name as defined in the Ansible inventory file
--become (-b) instructs Ansible to use sudo
-module-name (-m) specifies the module to run (lineinfile here)
--args (-a) passes arguments to the module (these change depending on a module)
dest points to the destination file
line instructs Ansible to ensure a particular line is in the file
If you would like to replace the whole contents of the /etc/motd you should use copy module.
ansible target_node -b -m copy -a 'dest=/etc/motd content="This server is managed by Ansible"'
Notice one of the arguments is changed accordingly.