Install Ansible
Reminder, Ansible is agentless-ssh. It’s a tool for doing the Continuous Delivery. It communicates with host by exchanging keys, so you need to authorize hosts to be controlled by ansible. See here for how to do this : https://java8fx.wordpress.com/2017/07/01/ansible-mysql5-7-for-centos7-2/
Quick install
Install extra package for CentOs-like linux before, and Ansible after.
sudo yum install epel-release sudo yum install ansible
How Ansible work
I spent few hours to manipulate Ansible. Below in this article you’ll find basic concepts behind terms and vocabulary. You can also find some examples on the Github : https://github.com/ansible/ansible-examples . And a quick presentation, by the unavoidable wiki, here : https://en.wikipedia.org/wiki/Ansible_(software)
Playbook : is a yaml and/or tree folders file structure, containing all Ansible declaration and notably tasks to execute against hosts. The purpose to reach, being to use/reuse “tasks” in a modular manner. Role helps in that way.
Example of a simple playbook, reusing two roles --- # This playbook deploys a simple standalone Tomcat 7 server. # list of servers targeted - hosts: tomcat-servers remote_user: root become: yes become_method: sudo # tasks are not written in the playbook but in the two roles selinux, tomcat roles: - selinux - tomcat
Tasks : a simple command coming from Modules directly embed in a playbook, or a yaml file belonging to a role.
Example, install with apt-get git and Apache servers, note the loop on items : - name Install services apt: pkg{{item}} state=installed with_items: - git - apache2
Modules : bring us the capability to execute tasks on hosts.
Example : module crypto, network, notification, ... above it's the module apt in the task
Inventories (hosts) : static or dynamic list of targeted systems to be manipulated by Ansible. Could be declared on a hosts file (Ansible not linux), or in file somewhere in the tree file/folder structures.
Example: [production] 10.0.10.1 prod1.milano.org 10.0.10.2 prod2.milano.org
Roles : role is a major concept in Ansible, see it as a self-repository of fine granular tasks you use to assemble playbook. The roles repository could be global, local to user or project, or in the galaxy repo as well.
Example of roles : install netty, block all incoming trafic, ... You can create role structure, with this script : $ ansible-galaxy init acme --force This creates the directory structure needed for organizing your code: acme/ .travis.yml README.md defaults/ files/ handlers/ meta/ tasks/ templates/ tests/ vars/
Tags : allow to mark some task or role with specific label. For building modular deliveries, this concept is essential, only executing tasks marked with tags.
Example: - name: Copy file configuration copy: src: "app.yml" dest: "/home/user/app.yml" tags: - configure
Template : jinja2 j2 file, very useful, you could rewrite resource, conf, yaml files, … everything.
Example: # {{ ansible_managed }} # Manual customization of this file is not recommended. *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] {% if (inventory_hostname in groups['lb_servers']) %} -A INPUT -p tcp --dport {{ nginx_http_port }} -j ACCEPT {% endif %} -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT COMMIT
Thoughts about Ansible and Continuous Delivery in general
DevOps
Firstly, this is my vision of DevOps in my Project/Product development industry.
Ops :
Provision : scale up/down machines
Example: add frontend servers , add security rules, ssh keys, users, …
Even we try globally to be the more “agnostic” as possible, the granularity is linked to the machine provider and the purpose of the machine. Docker helps to keep things more simple for anonymizing and uniforming resources. So we would be able to provision a CentOS with 4cpu/16GB , 32BG os SSD for the OS and 1TB of disk for the rest. That’s it. The Configure step will do the rest.
Configure : add/remove capabilities to machines
Example: container or not, it’s install tomcat, apache, mysql node… whatever kind of standardized server it is, it must be in a repository somewhere in the world … it’s also add/remove rules allowing services working properly.
I divide Configure step in 3 categories : frontend servers, backend and persistence servers. Every configure options fit in these 3 categories.
Now Dev
Deploy : add/remove/configure project
Example: apply an update on schema, deploy a new version of GUIs, apply quality environments tests, checks, reporting, …
Close to Configure, this step is related to a project, that means it’s highly tight to developers team, and our business agenda. As usual for all custom development tests, checks are to be done regularly. The repository is in-house. Mocking services are common practice, .. also sort of instability as well.
Release : release the product.
Example: get all master github branches from repository, stop all servers one-by-one, install new release, start servers one-by-one, inform users before, after successful release …
It’s mainly a step for qualification and production environments, dedicated for final user which focuses on Product and not on project. This step is not often automatic, and occurs after all projects Deployments are successfully done, it’s highly a phase of orchestration and consolidation, that brings all Deploy projects in qualification or production.
What about Ansible and DevOps
According to me Ansible misses high level abstraction of DevOps, also we should have execution of playbooks as Maven does for projects through pom.xml.
I expected something like : ansible-playbook provision|configure|deploy|release product.yml
Dev and Ops are separated with Ansible. The purpose of Ansible is to modify hundred of hosts with module/task commands. It’s batching process, in the opposite Dev needs orchestration, fine granularity when commanding hosts.
Ansible Pro’s & Con’s
Good :
- role and tags
- yaml file for configuring
- json for result of commands (better integration)
- template engine
- parent playbook, child (role)
- Convention Over Configuration oriented
- unique yaml file or multiple tree folders/files structure for playbook
- happy to discover notions of handler, pre-task, post-task, require, include
Bad :
- no rollback management
- no orchestration at all
- compose and reuse Ansible objects are not as straight forward
no central repository for playbooks with versioning and dependencies- note I just discovered ansible-galaxy, roles sharing site
- no local repository (similar to maven repo)
- no lifecycle !
- playbooks difficult to manage, lot of files and folders !
Final word. Even I’m still searching a better way to compose playbooks and orchestrate the release of my Products. Ansible is the better choice by now to delegate the Continuous Delivery in collaboration with Bamboo, Artifactory, Maven and Bitbucket. It forces us to standardized our Ops and Dev.
To be continued.
References :
About modular roles : https://opencredo.com/reusing-ansible-roles-with-private-git-repos-and-dependencies/