This will be Part 2 out of 2 of the Ansible primer series.
Having covered the basics in Part 1, we can now move on to more advanced aspects of Ansible.
We were able to run an Ansible playbook on our localhost, but not much can be done with localhost. It’s now time to connect to and manage external hosts and perform some configuration management there.
Let’s get familiar with more Ansible terms.
The machine is running Ansible and connecting to remote/external hosts to perform configuration management.
The machine Ansible accesses via SSH to configure. It does not need to have Ansible installed. The only requirements are SSH and Python.
For the rest of the post, the remote host is an Ubuntu 14.04 EC2 host launched on AWS.
Let’s go ahead and update our inventory.
The updated inventory file tells Ansible we now have a group of remote hosts called webservers with one host.
Accessing Remote Hosts
As mentioned, Ansible connects to remote hosts via SSH. To access the external remote hosts, we need to setup password-less SSH access, i.e. the control host have to be able to access the remote host without it asking for a password.
There’re plenty of tutorials online on how to do this and below are some links;
By default, SSH will look for a private key in
˜/.ssh/id_rsa. However, we want to be able to tell Ansible where to look for the private key of each host, so we have flexibility later when different hosts use different keys.
Route 1: One key for all hosts
Add an option to ansible.cfg file under [defaults] section:
Route 2: One key per host
In your inventory file, add a variable to the host:
[webservers] 18.104.22.168 ansible_ssh_private_key_file=/etc/ansible/keys/web.pem
Route 3: One key per group of hosts
Also in your inventory file, but using group variables:
Route 4: Use SSH config
Since Ansible uses SSH, you can let the SSH service to decide which key to use in each host. This is the least prefered option.
Host 22.214.171.124 *.awesomecompany.ly IdentityFile /etc/ansible/keys/access.pem
We will go with Route 3. Our inventory file now looks like this;
[webservers] 126.96.36.199 [webservers:vars] ansible_ssh_private_key_file=/etc/ansible/keys/web.pem
Configure Remote Hosts
Let’s update our playbook to target the webservers and install Apache on the remote hosts. Save the updated file as
--- - name: ansible playground hosts: webservers sudo: yes tasks: - apt: name=apache2 state=present
- hosts: webservers : We’re targeting the webservers group
- sudo: yes : Ansible will perform tasks as root
- apt : This is the Ansible module and takes the name and state parameters
We can now run the playbook.
Let’s rerun our playbook.
As you can see from the second run, the result is different, but nothing happens.
Tasks should always be idempotent which means that once our desired state has been reached, nothing should change when we repeat the same task.
Looking at the language we used, we say state=present instead of install. This way the Ansible apt module is going to make sure it is present and install only if it must.
Now that you can create and run playbooks, they need to do something useful. Ansible has many (hundreds?) of modules to perform actions in the operational system.
And that’s it for this primer series.
At OSO DevOps, our experts can maintain your DevOps platform and be responsible for day-to-day operational issues, allowing you to develop and ship your product without the need for internal DevOps hires.