how to specify user name in host file of ansible - ansible

I am using the host file as below,
[qa-workstations]
10.39.19.190 ansible_user=test ansible_ssh_pass=test
I am using below command to execute "whoami" command in host
root#Svr:~/ansible# ansible all -a "whoami" -i /etc/ansible/host
10.39.19.190 | success | rc=0 >>
root
ansible by default trying to use user name in which I have logged in, i.e root instead of test user which I have specified in host file
It works fine when I try to pass the username in ansible cli command
root#Svr:~/ansible# ansible all -a "whoami" -i /etc/ansible/host -u test
10.39.19.190 | success | rc=0 >>
test
But its not possible for me to pass username every time in CLI as different host uses different username. Also I don't have a key pair generated for each host, because host machine keeps changing often
version used:
ansible 1.5.4
Ubuntu 14.04 LTS

With recent versions of Ansible, you can use the ansible_user parameter in the host definition.
For example, on the host mysql-host.mydomain the user I need to connect with is mysql :
[docker-hosts]
mysql-host.mydomain ansible_user=mysql
But as you are using an older version of ansible, you might need to use ansible_ssh_user instead
http://docs.ansible.com/ansible/faq.html#how-do-i-handle-different-machines-needing-different-user-accounts-or-ports-to-log-in-with

Create an ansible.cfg in your playbook directory or modify the "global" ansible.cfg
Note: Only 1 configuration file is processed. First one wins in the below list.
https://docs.ansible.com/ansible/latest/reference_appendices/config.html
ANSIBLE_CONFIG (an environment variable)
ansible.cfg (in the current directory)
.ansible.cfg (in the home directory)
/etc/ansible/ansible.cfg
[defaults]
remote_user=test

Related

Ansible root/password login

I'm trying to use Ansible to provision a server and the first thing I want to do is test the ssh access. If I use ssh directly I can log in fine...
ssh root#server
root#backups's password:
If I use Ansible I can't...
user#ansible:~$ ansible backups -m ping --user root --ask-pass
SSH password:
backups | UNREACHABLE! => {
"changed": false,
"msg": "Invalid/incorrect password: Permission denied, please try again.",
"unreachable": true
}
The password I'm using is correct - 100%.
Before anyone suggests using SSH keys - that's what part of what I'm looking to automate.
The issue was caused by the getting started documentation setting a trap.
It instructs you to create an inventory file with servers, use ansible all -m ping to ping those servers and to use the -u switch to change the remote user.
What it doesn't tell you is that if like me not all you servers have the same user, the advised way to specify a user per server is in the inventory file...
server1 ansible_connection=ssh ansible_user=user1
server2 ansible_connection=ssh ansible_user=user2
server3 ansible_connection=ssh ansible_user=user3
I was provisioning a server, and the only user I had available to me at the time was root. But trying to do ansible server3 -user root --ask-pass failed to authenticate. After a couple of wasted hours I discovered the -user switch is only effective if the inventory file doesn't have a user. This is intended precedence behaviour. There are a few gripes about this in GitHub issues but a firm 'intended behaviour' mantra is the response you get if you challenge it. It seems to go against the grain to me.
I subsequently discovered that you can specify -e 'ansible_ssh_user=root' to override the inventory user - I will see about creating a pull request to improve the docs.
While you're here, I might be able to save you some time with some further gotchas. This behaviour is the same if you use playbooks. In there you can specify a remote_user but this isn't honoured - presumably also because of precedence. Again you can override the inventory user with -e 'ansible_ssh_user=root'
Finally, until I realised Linode could provision a server with an SSH key deployed, I was trying to specify the root password to an ad-hoc command. You have to encrypt the password and this gives you a long string and this is almost certainly going to include $ in it which bash will treat as substitutions. Make sure you escape these.
The lineinfile module behaviour isn't intuitive either.
Write your hosts file like this. It will work.
192.168.2.4
192.168.1.4
[all:vars]
ansible_user=azureuser
Then execute the following command: ansible-playbook --ask-pass -i hosts main.yml --check to check before configuration.
Also create a ansible.cfg file. Then paste the following contents there:
[defaults]
inventory = hosts
host_key_checking = False
Note: All the 3 files namely, main.yml,ansible.cfg & hosts must be in the same folder.
Also, the code is tested for devices connected to a private network using Private IPs. I haven't checked using Public IPs. If using Azure/AWS, create a test VM and connect it to the VPN of the other devices.
Note: You need to install the SSHPass package to be able to authenticate with Password.
For Ubuntu: apt-get install sshpass

Ansible: include group vars .yml file from command line

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).

Writing a string to file using Ad-Hoc Commands in Ansible

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.

Ansible 2.0.0.2: ansible doesn't respect the "- u" switch

I'm probing a freshly installed Archlinux installation on a Raspberry PI 2 like so:
ansible -i PI2 arch -m setup -c paramiko -k -u alarm -vvvv
This reads to me: Fire the setup module against the IP connecting with the user "alarm" asking for the password of this specific user. However the user that eventually attempts to connect is "root".
Here's the debug response:
Loaded callback minimal of type stdout, v2.0
<192.168.1.18> ESTABLISH CONNECTION FOR USER: root on PORT 22 TO 192.168.1.18
192.168.1.18 | UNREACHABLE! => {
"changed": false,
"msg": "ERROR! Authentication failed.",
"unreachable": true
}
The inventory looks like this:
[arch]
192.168.1.18
Some things that may or may not be relevant are the following:
ssh logins via root are not permitted
sudo is not installed
default user and pass are "alarm" : "alarm"
no ssh key being copied to the machine hence the paramiko connection attempt
What is NOT ignored and leads to a successful connection is adding ansible_user=alarm to the IP line in the inventory file.
EDIT
Found this interesting passage in the official docs: http://docs.ansible.com/ansible/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable which states:
Another important thing to consider (for all versions) is that connection specific variables override config, command line and play specific options and directives. For example:
ansible_user will override-u andremote_user: `
The original question seems to remain though. Without any mention of ansible_user in the inventory, why is root being used instead of the explicitly mentioned user via - u?
EDIT_END
Is this expected behaviour?
Thanks
You don't need to specify paramiko as the connection type, Ansible will figure that part out. You may have a group_vars directory with an ansible_user or ansible_ssh_user variable defined for this host which could be overriding the alarm user.
I was able to replicate your test on ansible 2.0.0.2 without any issues against a raspberry pi 2 running Raspian:
➜ ansible ansible -i PI2 arch -m setup -u alarm -vvvv -k
Using /etc/ansible/ansible.cfg as config file
SSH password:
Loaded callback minimal of type stdout, v2.0
<192.168.1.84> ESTABLISH CONNECTION FOR USER: alarm on PORT 22 TO 192.168.1.84
CONNECTION: pid 78534 waiting for lock on 9
CONNECTION: pid 78534 acquired lock on 9
paramiko: The authenticity of host '192.168.1.84' can't be established.
The ssh-rsa key fingerprint is 54e12e8153e0319f450934d606dca7df.
Are you sure you want to continue connecting (yes/no)?
yes
CONNECTION: pid 78534 released lock on 9
<192.168.1.84> EXEC ( umask 22 && mkdir -p "$( echo $HOME/.ansible/tmp/ansible-tmp-1454502995.07-263327298967895 )" && echo "$( echo $HOME/.ansible/tmp/ansible-tmp-1454502995.07-263327298967895 )" )
<192.168.1.84> PUT /var/folders/39/t0dm88q50dbcshd5nc5m5c640000gn/T/tmp5DqywL TO /home/alarm/.ansible/tmp/ansible- tmp-1454502995.07-263327298967895/setup
<192.168.1.84> EXEC LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 /usr/bin/python /home/alarm/.ansible/ tmp/ansible-tmp-1454502995.07-263327298967895/setup; rm -rf "/home/alarm/.ansible/tmp/ansible-tmp-1454502995. 07-263327298967895/" > /dev/null 2>&1
192.168.1.84 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.1.84"
],
I virtualenv'd myself a Ansible 1.9.4 sandbox, copied over the ansible.cfg and the inventory and ran the command again. Kinda worked as expected:
⤷ ansible --version
ansible 1.9.4
configured module search path = None
(ANS19TEST)~/Documents/Code/VENVS/ANS19TEST
⤷ ansible -i PI2 arch -m setup -c paramiko -k -u alarm -vvvv
SSH password:
<192.168.1.18> ESTABLISH CONNECTION FOR USER: alarm on PORT 22 TO 192.168.1.18
<192.168.1.18> REMOTE_MODULE setup
From where I'm standing I'd say this is a bug. Maybe somebody can confirm?! This goes to the bugtracker then...
Cheers
EDIT
For brevity I omitted a important part of my inventory file, which ultimately is responsible for the behavior. It looks like this:
[hypriot]
192.168.1.18 ansible_user=root
[arch]
192.168.1.18
Quote from the Ansible bugtracker:
The names used in the inventory is the key in a dictionary. So everything you put in there as host-specific variables will be merged into one big dictionary. That means that in some conflicting cases variables are superseded by other values.
You can prevent this by using different names for the same host (e.g. using IP address and hostname, or an alias or DNS-alias) and in that case you can still do what you like to do.
So my inventory looks like this now:
[hypriot]
hypriot_local ansible_host=192.168.1.18 ansible_user=root
[archlinux]
arch_local ansible_host=192.168.1.18
This works fine. The corresponding issue on the Ansible tracker is here: https://github.com/ansible/ansible/issues/14268

System specific variables in ansible

Ansible expects python 2. On my system (Arch Linux), "python" is Python 3, so I have to pass -e "ansible_python_interpreter=/usr/bin/python2" with every command.
ansible-playbook my-playbook.yml -e "ansible_python_interpreter=/usr/bin/python2"
Is there a away to set ansible_python_interpreter globally on my system, so I don't have to pass it to every command? I don't want to add it to my playbooks, as not all systems that runs the playbook has a setup similar to mine.
Well you can set in three ways
http://docs.ansible.com/intro_inventory.html#list-of-behavioral-inventory-parameters ansible_python_interpreter=/usr/bin/python2 this will set it per host
Set it host_vars/ ansible_python_interpreter: "/usr/bin/python2" this will set it per host
set it for all nodes in the file group_vars/all (you may need to create the directory group_vars and the file all) as ansible_python_interpreter: "/usr/bin/python2"
Hope that helps
I opted to use Ansible's ability to source inventory from a directory. In this manner I could define the ansible_python_interpreter for localhost only for the local machine
inventory_dir/local
[local]
localhost ansible_python_interpreter="/path/to/alternate/bin/python"
And then just use the directory as you would an inventory file.
ansible-playbook -i inventory_dir playbook.yml
For who want use local activated virtualenv python interpreter
in inventory file set
[local]
localhost ansible_python_interpreter=python

Resources