Server Orchestration with Ansible
Why use Ansible? #
Before Ansible I knew three ways of how to (remotely) manage a server:
- Using shell scripts and SSH.
- MCollective
- Using a configuration management tool like Puppet or Chef.
While using the first with many servers quickly can become chaotic, the second and third options are just too heavy weight for my taste considering smaller ad-hoc installations.
That is where Ansible fits in perfectly. Easy and fast to setup. Easy to scale in case an installation grows bigger.
In this post I will show how to set up Ansible and perform some tasks with it.
Preparing the Playground #
Create two Vagrantboxes that have a fixed IP:
{% highlight none %}
-- mode: ruby -- #
vi: set ft=ruby : #
VAGRANTFILE_API_VERSION = “2”
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = “centos_70” config.vm.define “foo” do |foo| foo.vm.network “private_network”, ip: “192.168.10.10” end
config.vm.define “bar” do |bar| bar.vm.network “private_network”, ip: “192.168.10.20” end end {% endhighlight %}
I am using my own base box here, that I called “centos_7”. Feel free to roll your own. You can find a guide here.
Start both of them with vagrant up
. You can access the Vagrant boxes individually with vagrant ssh foo
and vagrant ssh bar
respectively.
An SSH key-pair is needed, because all Ansible communication goes via SSH.
{% highlight none %} ssh-keygen -t rsa eval ‘ssh-agent -s’ ssh-add /vagrant/id_rsa {% endhighlight %}
Put the private key file into /home/vagrant/.ssh/id_rsa
on foo
, and on bar
, copy and paste the public key into /home/vagrant/.ssh/authorized_keys
.
Install and Configure Ansible #
Let’s deal with Ansible itself now.
Install it with:
{% highlight none %} cd /tmp wget https://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm yum install epel-release-7-5.noarch.rpm yum -y install ansible {% endhighlight %}
On box “foo” edit the file /etc/ansible/hosts
so it contains the IP-address of box bar
.
{% highlight none %} 192.160.10.20 {% endhighlight %}
A first Test #
Now, if everything is correct, you could try the following test on foo
.
{% highlight none %} ansible 192.168.10.20 -m ping {% endhighlight %}
The result should be something like:
{% highlight none %} 192.168.10.20 | success » { “changed”: false, “ping”: “pong” } {% endhighlight %}
A real-world Example (more or less …) #
Let’s create a fictitious deployment process that consists of the following two steps:
- Copy the “deployment artifact” from the deployment server
foo
to the deployment targetbar
- Execute a script on the deployment target
bar
.
My little deployment playbook deploy.yml
looks like:
{% highlight none %} {% raw %}
- hosts: 192.168.10.20
tasks:
-
name: copies a file from a to b copy: src=/vagrant/hello.txt dest=/home/vagrant
-
name: executes a script command: /home/vagrant/hello_world.sh register: hello
-
debug: msg="{{hello.stdout}}" {% endraw %} {% endhighlight %}
-
The only thing that the script hello_world.sh
does is
{% highlight none %} #!/usr/bin/bash printf “Hello World!\n” {% endhighlight %}
The file hello.txt
is just empty.
Lets’s trigger the deployment on foo
with
{% highlight none %} ansible-playbook deploy.yml {% endhighlight %}
The resulting output should be :
{% highlight none %} PLAY [192.168.10.20] **********************************************************
GATHERING FACTS *************************************************************** ok: [192.168.10.20]
TASK: [copies a file from a to b] ********************************************* ok: [192.168.10.20]
TASK: [executes a script] ***************************************************** changed: [192.168.10.20]
TASK: [debug msg="{{hello.stdout}}"] ****************************************** ok: [192.168.10.20] => { “msg”: “Hello World!” }
PLAY RECAP ******************************************************************** 192.168.10.20 : ok=4 changed=1 unreachable=0 failed=0 {% endhighlight %}
Nice, very nice!
What’s next? #
Now, for those who already have a bunch of scripts and that are logging into server after server, using Ansible is a revelation! Integrating those scripts with Ansibles shell
or command
modules is a breeze.
After playing around for a while I have realized there is one important page that I visit all the time, it is the module index. This page provides a nice general intro about Ansible modules.
Done for today!