Ansible is an IT automation tool. It can configure systems, deploy software, and orchestrate more advanced IT tasks such as continuous deployments or zero downtime rolling updates.
One of the main reason why I choose Ansible over other IT automation tools like Puppet, Chef etc. – It manages machines in an agentless manner. As OpenSSH is one of the most peer reviewed open source components, the security exposure of using the tool is greatly reduced. Ansible is decentralized – it relies on your existing OS credentials to control access to remote machines; if needed it can easily connect with Kerberos, LDAP, and other centralized authentication management systems.
Today we are going to start with Ansible. This guide is basically built for begineers and novice who want to dirty their hands with Ansible. Let’s begin.
Setting up Ansible Server and Client:
We have three machines. I assume that there is already ansible running on machine1. We are going to install packages and few configuration changes on DB(machine2) under this post. I will discuss Web part on next post.
Here are the machine details:
Machine1> – 192.168.1.5(Ansible)
Machine2> – 192.168.1.6 ( DB)
Machine3> – 192.168.1.7(Web)
As shown below, create two folders – db and web under /etc/ansible/roles.
The handlers , tasks and templates are recommended directory structure for ansible to place respective YAML files.
Don’t worry about the contents as of now. We just need empty directory and file structure.
Let’s start creating a first file called playbook.yml:
root@ansible-host:/etc/ansible# cat playbook.xml—# Common role playbook- hosts: alltasks: []
– hosts: 192.168.1.6 sudo: yes roles: – db |
As shown above, playbook.yml sits under /etc/ansible and contains list of ansible machines where the deployment has to be done. A small typo above – the second .194 machine is actually 196.
Under each hosts, we need to mention roles name so that the specific role is called upon while the deployment phase is initiated on each hosts.
Let’s talk about DB contents first:
Folder: handlers
root@ansible-host:/etc/ansible/roles/db# cat handlers/main.yml—- name: start mysqlservice: name=mysql state=started- name: restart mysqlservice: name=mysql state=restarted |
root@ansible-host:/etc/ansible/roles/db/tasks# cat install.yml—- name: Install mysqlapt: name={{ item }} state=latestwith_items:- mysql-server
– python-mysqldb – php5-mysql – libapache2-mod-auth-mysql notify: start mysql |
root@ansible-host:/etc/ansible/roles/db/tasks# cat mysql_secure_installation.yml—- name: create mysql root passcommand: /usr/bin/openssl rand -base64 16register: mysql_root_passwd
– name: update mysql root passwd mysql_user: name=root host={{ item }} password={{ mysql_root_passwd.stdout }} with_items: – “{{ ansible_hostname }}” – 127.0.0.1 – ::1 – localhost – name: copy user my.cnf file with root passwd credentials template: src=dotmy.cnf.j2 dest=/root/.my.cnf owner=root group=root mode=0600 – name: delete anonymous mysql user mysql_user: name=”” state=absent – name: remove mysql test database mysql_db: name=test state=absent – name: create database blog mysql_db: name=blog state=present – name: create database user with name ‘blog’ and password ‘blog’ with all DB privileges and with GRANT options mysql_user: name=blog password=blog priv=*.*:ALL,GRANT state=present |
root@ansible-host:/etc/ansible/roles/db/tasks# cat main.yml—- include: install.yml- include: mysql_secure_installation.yml |
cat dotmy.cnf.j2[client]user=rootpassword={{ mysql_root_passwd.stdout }}root@ansible-host:/etc/ansible/roles/db/templates# cat my.cnf.j2[client]
user=root password={{ mysql_root_passwd.stdout }} |
That’s all for DB to function well.
Hence, we are ready to execute the commands on remote 192.168.1.6 machine through ansible.
[simterm]
root@ansible-host:/etc/ansible# ansible-playbook playbook.yml
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.1.6]
PLAY [192.168.1.6] **********************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.1.6]
TASK: [db | Install mysql] ****************************************************
changed: [192.168.1.6] => (item=mysql-server,python-mysqldb,php5-mysql,libapache2-mod-auth-mysql)
TASK: [db | create mysql root pass] *******************************************
changed: [192.168.1.6]
TASK: [db | update mysql root passwd] *****************************************
changed: [192.168.1.6] => (item=ansible-client)
changed: [192.168.1.6] => (item=127.0.0.1)
changed: [192.168.1.6] => (item=::1)
changed: [192.168.1.6] => (item=localhost)
TASK: [db | copy user my.cnf file with root passwd credentials] ***************
changed: [192.168.1.6]
TASK: [db | delete anonymous mysql user] **************************************
ok: [192.168.1.6]
TASK: [db | remove mysql test database] ***************************************
ok: [192.168.1.6]
TASK: [db | create database blog] *********************************************
changed: [192.168.1.6]
TASK: [db | create database user with name ‘blog’ and password ‘blog’ with all DB privileges and with GRANT options] ***
changed: [192.168.1.6]
NOTIFIED: [db | start mysql] **************************************************
ok: [192.168.1.6]
PLAY [192.168.1.6] **********************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.1.6]
TASK: [web | Install web] *****************************************************
changed: [192.168.1.6] => (item=python-pip,python-mysqldb)
TASK: [web | install tornado and torndb] **************************************
192.168.1.6 : ok=13 changed=7 unreachable=0 failed=0
[/simterm]
Done. Now you can easily SSH and check on the remote DB machine that MySQL is successfully installed.
Isn’t the magic? You didn’t need any agent running on the remote machine. Just OpenSSH enables the IT automation.
In my next blog post, I will discuss how does Ansible and Docker work together for DevOps environment.