My first steps with Ansible
Posted in automation, linux on September 28, 2016 by Adrian Wyssmann ‐ 10 min read
What is Ansible
Update 20. Sep. 2017: Fix typo in Set-Item -Path "WSMan:\localhost\Service\AllowUnencrypted" -value True
According to the official homepage
Ansible is a radically simple IT automation engine that automates cloud provisioning,configuration management, application deployment, intra-service orchestration, and many other IT needs.
The really cool thing is, no agents are needed as all activities go over ssh. I will not go into details here as it is indeed very good explained in the intro video from the Ansible website and the intro getting started
Test Setup
For my first steps, I will setup a virtual test environment on my computer, using Virtualbox. Here you can see the details:
arch001 to arch003 are the managed nodes, which I orchestrate with control node “master”.
Master
Master is running Antergos Linux. To install and configure ansible the following steps have to be performed
1. Install Ansible
Ansible should be available in your package repository, otherwise checkout the Ansible Website for more info.
2. Create ssh key
It’s recommended to use ssh keys to do the authentication rather than using passwords. So let’s create the necessary rsa key pair. I choose not to use a passphrase.
3 Configure network stuff
In my test setup, all nodes are connected in a private network 10.10.10.0/24 without any infrastructure services like dhcp or dns. Therefore I will configure all nodes using static addresses.
Specify hostname “master” in /etc/hostname
Specify host names for control node and client nodes in
/etc/host
Configure interface enp0s3 to have a fix IP. I just use the NetworkManger (GUI) in this case.
Managed Linux Nodes
At the ansible into you can find details about the requirements for the managed node. In my case I have ssh running, so that I remotely can connect to the managed node from the control node. The easiest way to do so is by using the ssh-key generated above.
1. Configure network stuff
Again, I use static ip addresses and the hosts file for name resolution.
Configure a network interface for the internal network 10.10.10.0/24. I do this according to ArchWiki by using systemd-networkd by providing appropriate network configuration in /etc/systemd/network/wired.network.
Specify hostname “master” in
/etc/hostname
Specify host names for control node and client nodes in /etc/hosts
2. Copy public key to managed node(s)
To use my recently created public key to authenticate on the node, I need to copy it to the managed node(s). On the managed nodes I currently only have one user “root” which I will use for further activities. Therefore, the key is copied to root user:
3. Python Installation
My managed nodes are using Arch, which uses Python3 by default. Therefore I need to ensure that python2 is installed on my managed nodes. I can do this by installing directly on the nodes or via the raw module from ansible.
As you can see I provide the “-noconfirm” parameter to pacman as otherwise the process simply waits for confirming the installation of the package.
ansible configuration and test
After the initial setup, my nodes are up and running and connected via the virtual network. Now I need to start configuring ansible.
A central point for ansible is the inventory file (/etc/ansible/hosts) from which ansible knows the systems which it orchestrates. I uses an INI-like format in which you can provide groups of hosts. Ansible may then address single nodes or even group of nodes. Here is my example
You can see that I have also specified group variables, that is due to the fact that my nodes arch001 to arch003 are running Arch Linux which uses Python3 as default Python interpreter at /usr/bin/python. Therefore I have specified ansible_python_interpreter=/usr/bin/python2
in my groups so for this nodes, the python interpreter used is /usr/bin/python2
.
I run ansible as user papanito
and not as root, but my managed nodes only have root user. So if I run a command, ansible will complain.
Therefore I have to specify the remote user either as parameter or in /etc/ansible/ansible.cfg
, then the command will succeed:
Done with my Linux nodes.
Managed Windows Nodes
Now this was quite easy. But usually you do not have a homogeneous environment with only Linux nodes but most probably also Windows hosts. Therefore I want to also manage a Windows node, more precisely a Windows 2012 Server core (no GUI). Let’s name our host win001
and give it an ip 10.10.10.21
. I recommend to checkout the wiki from Ansible regarding Windows support: http://docs.ansible.com/ansible/intro_windows.html.
Setup should be simple, as I do not have an Active Directory for user authentication nor do I have any windows domain policies which prohibits me to enable power-shell remoting or even a company firewall in between which could play into the setup. You should not forget theses things when you want to setup something like ansible in your company’s environment.
However, I will do some security tradeoff and only setup un-encrypted basic authentication via http. The ansible wiki does show much more details for setting up a windows host considering security relevant authentication. It also provides Powershell script to ease the setup of a windows node.
1. Install “winrm” python module
That ansible can talk with Windows nodes it needs the “winrm” module. It can be installed with pip. As my control node uses Arch Linux (default Python3) we need to install the package “python2-pip” before we can install the module.
2. Update ansible inventory file
The new Windows node needs to be added to the inventory file. We put it in a separate group for obvious reasons:
For the [windows] group we now create the group variables under group_vars/windows.yml
. It is recommended to encrypt the file as it contains sensitive information (Admin password). However I will skip this for my test
3. Configure network stuff
As the Linux nodes, the Windows node also needs a static ip address. Additionally we will turn the firewall of. Sure, in a real environment I would probably do a more sophisticated configuration rather than just switching the firewall off, but for my testing that’s fine.
Configure the network interface for the internal network 10.10.10.0/24 and Hostname using sconfig.cmd
Disable firewall
Add host name win001 on control node in __/etc/hosts
Now let’s test the connection and ping the windows host from the control node
4. Enable Remote Access
A prerequisite is that Powershell which should be at least version 3.0. Let’s check that
So far so good, now let’s enable Remote-Powershell as described at https://technet.microsoft.com/en-us/library/jj592692(v=ws.11).aspx#BKMK_1.7
4. Test Remote Access
Now it seems we are done, so let’s test it
Oops, something went wrong. The error message sounds a bit confusing, but with help of the command winrm get winrm/config on the windows node, I can easily see the problem(s)
As I already mentioned above, I want to use basic authentication over http, but basic authentication is not enabled on the Windows node and in group_vars/windows.yml
the wrong port (https instead http) is specified. So let’s fix both. Enabling the basic mode on the Windows node can be done with the Set-Item command
Does it work now? Let’s see …
No it does not. Now, this error message is also very confusing, as I am sure my credentials in the group_vars/windows.yml
are fine. It turns out they are. The problem is actually, that the connection is un-encrypted but this is not allowed by the service (see above). Therefore we also have to fix this:
After this I finally succeed:
Now I can start doing the real stuff using Playbooks etc. Stay tuned for more.