ansible command to list all known hosts - ansible

Ansible is already installed in a seperated ec2 instance.
I need to install apache on an ec2 instance.
Trying to find a list of known hosts
I run this command
ansible -i hosts all --list-hosts
and get this message
[WARNING]: Host file not found: hosts
[WARNING]: provided hosts list is empty, only localhost is available
[WARNING]: No hosts matched, nothing to do

--list-hosts lists hosts that match a --limit. The input is the -i, inventory. Your inventory is a file named hosts, which doesn't exist.
You need to create or generate an inventory file from somewhere. Ansible can't intuit what your inventory is.

If you installed Ansible by Pip, you need to create a directory with ansible.cfg and hosts file. For it, use:
sudo mkdir /etc/ansible/
sudo touch /etc/ansible/hosts
So you will be able to use the command below:
cat /etc/ansible/hosts

Got permission to ssh to the target server. Now i can install on this target server.
If I can login as an ec2-user by being part of a management domain then I can access any server

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

How to execute an ansible ad-hoc command only once when there are several hosts under the same category

I would like to run a certain ansible ad-hoc command only on one host from a group of hosts. Say in the hosts file I have a few hosts under group name [webserver], I want to be able to run the command only on one of the hosts in that group, no matter which.
I wasn't able to find an answer for that in ansible ad-hoc doc
You can specify the list of inventory as comma separated values or gorup in command line with ad-hoc command .
ansible-playbook -i emample-host.com, -a <ad hoc command>
Refer Introduction to Ad hoc command
Solution:
Say I have under hosts file
[webserver]
wserver-1
wserver-2
wserver-3
And I want to choose the webserver that comes first (doesn't matter which)
and run some command on it.
The way to do that is as follows:
ansible -i /etc/ansible/hosts webserver[0] -m shell -a 'hostname'
This will run 'hostname' on wserver-1

How to format a simple Ansible inventory file for amazon ec2 hosts?

I am unable to run the example ad hoc command:
ansible -m ping hosts --private-key=~/home/ec2-user/ -u ec2-user
the error is:
[WARNING]: Could not match supplied host pattern, ignoring: hosts
[WARNING]: No hosts matched, nothing to do
The hostname is: ip-10-200-2-21.us-west-2.compute.internal
I can ping the host from my ansible control node by this hostname.
I created the hosts file with the touch command and it looks like this:
ip-10-200-2-21.us-west-2.compute.internal
Do I need to include something more? Do I need to save it with a particular extension? Thank You much for any help.
To run an ad-hoc command you can run a command in the following syntax
ansible <HOST_GROUP> -m <MODULE_NAME>
This is assuming your inventory file is in /etc/ansible/hosts. If your inventory file is located in a different spot we can use the command
ansible <HOST_GROUP> -m <MODULE_NAME> -i <LOCATION_TO_INVENTORY_FILE>
to change the location of the inventory file
Now whats missing is that your inventory file should have a host group in it. Something like:
[ec2]
ip-10-200-2-21.us-west-2.compute.internal
other-ec2-host-that-needs-to-be-pinged.us-west-2.compute.internal
The host group is the text inbetween the square brackets [], which in this case is ec2. Now we can reference all ec2 hosts using the host group of ec2.
To ping all the hosts in the ec2 group (assuming the inventory file is /etc/ansible/hosts) run
ansible ec2 -m ping -i /etc/ansible/hosts

Ansible Run Command

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

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