Ansible is open-source software that automates software provisioning, configuration management, and application deployment. Ansible connects via SSH, remote PowerShell or via other remote APIs.
You can use Ansible to automate three types of tasks:
- Provisioning: Set up the various servers you need in your infrastructure.
- Configuration management: Change the configuration of an application, OS, or device; start and stop services; install or update applications; implement a security policy; or perform a wide variety of other configuration tasks.
- Application deployment: Make DevOps easier by automating the deployment of internally developed applications to your production systems.
By using Ansible, we can specify certain tasks like ensuring the apache to be on the latest version by using some playbook which can be coded in basic YAML language. Puppet and Chef, on the other hand, use Ruby, which is more difficult to learn.
A basic YAML code for ensuring the apache on client servers to be on the latest version is given below.
hosts: webservers vars: http_port: 80 max_clients: 200 remote_user: root tasks: name: ensure apache is at the latest version yum: name=httpd state=latest write the apache config file template: src=/srv/httpd.j2 dest=/etc/httpd.conf notify: restart apache ensure apache is running (and enable it at boot) service: name=httpd state=started enabled=yes handlers: name: restart apache service: name=httpd state=restarted
We can set up this with the master server and ansible will ensure that all of the client-server is on the latest version.
Why Choose Ansible?
- The major automation tools available other than ansible is Puppet and Chef. The main reason to choose ansible over these tools is the simplicity of ansible. The use of YAML language is the reason for this simplicity.
- Another difference between Ansible and Puppet/Chef is that Ansible doesn’t need a client to be installed on the servers as needed by Puppet/Chef. Ansible just requires that systems have Python (on Linux servers) or PowerShell (on Windows servers) and SSH. The working is shown in the below image.
Basic Ansible Commands
- The command to check connectivity of hosts is,
$ ansible <group> -m ping - Rebooting hosts
$ ansible <group> -a “/sbin/reboot” - For transferring files we use a module ‘copy’ & complete command that is used is
$ ansible <group> -m copy -a “src=/home/dan dest=/tmp/home” - Creating a new user
$ ansible <group> -m user -a “name=testuser password=<encrypted password>” - Deleting a user
$ ansible <group> -m user -a “name=testuser state=absent” - Changing permission of a file
$ ansible <group> -m file -a “dest=/home/dan/file1.txt mode=777” - Changing ownership of a file
$ ansible <group> -m file -a “dest=/home/dan/file1.txt mode=777 owner=dan group=dan” - Check if package is installed & update it
$ ansible <group> -m yum -a “name=ntp state=latest” - Starting a service
$ ansible <group> -m service -a “name=httpd state=started” - Stopping a service
$ ansible <group> -m service -a “name=httpd state=stopped” - Restarting a service
$ ansible <group> -m service -a “name=httpd state=restarted” - We can use –syntax-check for checking the syntax of the playbooks
Eg: ansible-playbook playbooks/PLAYBOOK_NAME.yml –syntax-check - We can use below syntax to limit the playbook for one host or multiple hosts.
1) Limit to one host
ansible-playbook playbooks/PLAYBOOK_NAME.yml –limit “host1”
2) Limit to multiple hosts
ansible-playbook playbooks/PLAYBOOK_NAME.yml –limit “host1,host2”
Playbooks
Ansible playbooks are a way to send commands to remote computers in a scripted way. Instead of using Ansible commands individually to remotely configure computers from the command line, you can configure entire complex environments by passing a script to one or more systems.
Ansible playbooks are written in the YAML data serialization format. JSON is another popular data serialization format, but YAML is much easier to read. Each playbook contains one or more plays, which map hosts to a certain function. Ansible does this through something called tasks, which are basically module calls.
A basic playbook will look like below.
--- - hosts: droplets tasks: - name: Installs nginx web server apt: pkg=nginx state=installed update_cache=true notify: - start nginx handlers: - name: start nginx service: name=nginx state=started
The File Starts With: —
This is a requirement for YAML to interpret the file as a proper document. YAML allows multiple “documents” to exist in one file, each separated by —, but Ansible only wants one per file, so this should only be present at the top of the file.
YAML is very sensitive to white-space and uses that to group different pieces of information together. You should use only spaces and not tabs and you must use consistent spacing for your file to be read correctly. Items at the same level of indentation are considered sibling elements.
Items that begin with a – are considered list items. Items that have the format of key: value operates as hashes or dictionaries. That’s pretty much all there is to basic YAML.
We can save this playbook into a file called something like “name.yml”.
Once the playbook is built, you can call it easily using the format below:
$ ansible-playbook playbook.yml
Since the playbook itself specifies the hosts that it should run against, we do not have to specify a host to run against.
However, if we would like to filter the host list to only apply to one of those hosts, we can add a flag to specify a subset of the hosts in the file:
$ ansible-playbook -l host_subset playbook.yml
Basics of Playbooks
- The file starts with: —
- For each task, we can optionally register its result (failure or success) in a variable that we can check later on. If we want to check whether a task has failed or not to decide on subsequent steps, we can use the register functionality.
- The hosts’ line is a list of one or more groups or host patterns, separated by colons, as described in the Working with Patterns documentation. The remote_user is just the name of the user account:
Eg:- hosts: webservers remote_user: root
- Each play contains a list of tasks. Tasks are executed in order, one at a time, against all machines matched by the host pattern, before moving on to the next task. It is important to understand that, within a play, all hosts are going to get the same task directives. It is the purpose of a play to map a selection of hosts to tasks.
- When running the playbook, which runs top to bottom, hosts with failed tasks are taken out of the rotation for the entire playbook. If things fail, simply correct the playbook file and rerun.
Handlers
Modules in Ansible should be idempotent and can relay when they have made a change on the remote system. Playbooks recognize this and have a basic event system that can be used to respond to change.
These ‘notify’ actions are triggered at the end of each block of tasks in a play, and will only be triggered once even if notified by multiple different tasks.
For instance, multiple resources may indicate that apache needs to be restarted because they have changed a config file, but apache will only be bounced once to avoid unnecessary restarts.
Here’s an example of restarting two services when the contents of a file change, but only if the file changes:
- name: template configuration file template: src: template.j2 dest: /etc/foo.conf notify: - restart memcached - restart apache
The things listed in the notify section of a task are called handlers.
Handlers are lists of tasks, not really any different from regular tasks, that are referenced by a globally unique name, and are notified by notifiers. If nothing notifies a handler, it will not run. Regardless of how many tasks notify a handler, it will run only once, after all of the tasks completed in a particular play.
- The ansible-pull is a small script that will check out a repo of configuration instructions from git, and then run ansible-playbook against that content.
If you require help, contact SupportPRO Server Admin