Asible
Today we will talk about Ansible.
This is software management system. It requires only SSH connection to the target host for a management purpose.
The main Ansible task – to perform several commands on target hosts. We can manage many target hosts at the same time.
Playbook
- Let’s start. We will save all our commands at a special Ansible-script. This is called ‘playbook‘. It’s like a regular bash script, which executed step-by-step but written on Ansible-language. Playbook file uses jaml-format. It’s look like this:
- name: "First step"
hosts: localhost
tasks:
- taskA
- taskB
Here is the group of the tasks with the name: “First step”.
-
This group will be executed on localhost ( hosts: localhost ). And we have 2 commands: tasks: taskA, taskB. This group called ‘ **play **’. It’s a similar to a block of tasks united by one logic.
-
You can have a many groups (plays) in one Ansible-script (playbook):
- name: "First step"
hosts: localhost
tasks:
- taskA
- taskB
- name: "Second step"
hosts: all
tasks:
- taskC
- taskD
Note: Second step will be executed on the all hosts (hosts: all). We can prepare some files on the localhost at the First step, upload it, and apply it on the all hosts at the Second step for example.
Task
- Let’s talk about tasks. Usually it’s nothing but Ansible module. So by running Ansible command we just executing Ansible module with some parameters. To execute task we can just call it by name. For example set variable for host (set_fact) :
- set_fact: mytext="Hello world"
Our playbook with this task:
- name: "First step"
hosts: localhost
tasks:
- set_fact: mytext="Hello world"
In this playbook we just define variable mytext=”Hello world” for localhost.
- Let’s add another command. debug it will print our variable:
- name: "First step"
hosts: localhost
tasks:
- set_fact: mytext="Hello world"
- debug: var: mytext
But we can define tasks in the extended mode by defining it names, similar to plays:
- name: "First step"
hosts: localhost
tasks:
- name: "Set variable"
set_fact:
mytext="Hello world"
- name: "Show variable"
debug:
var: mytext
I like it! Very comfortable for reading. We have one group of tasks called “First step“. And two tasks in this group: “Set variable” and “Show variable”. Perfect!
Run
Let’s play our playbook. Save the text above in the “first.yml” file and run it:
ansible-playbook ./first.yml
You’ll see something like this:
PLAY [First step] *************************************************************************************************************
TASK [Gathering Facts] ********************************************************************************************************
ok: [localhost]
TASK [Set variable] ***********************************************************************************************************
ok: [localhost]
TASK [Show variable] **********************************************************************************************************
ok: [localhost] => {
"mytext": "Hello world"
}
PLAY RECAP ********************************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0
Here you can see our group of tasks (PLAY), called “First step”, and our tasks (TASK) : [Set variable] and [Show variable]. All tasks was completed successfully (ok=3, failed=0). Nothing changed (changed=0), because we change nothing 🙂 (no files changed, no software installed). Also you can se addition task “
Gathering Facts“. This is system task that was called automatically. It required for gathering some system variables that you can use in your scripts. You can turn off this feature by defining gather_facts : false
- name: "First step"
hosts: localhost
gather_facts: false
....
Inventory
Do you remember that we was defined the variable hosts: all for the Second step? What does it means? Where is all this hosts? This is a hosts file. It called ‘inventory‘ file. And you can put it on the same directory. It’s looks like this:
[mail]
mail-01.burlutsky.su
mail-02.myserver.lan ansible_host=10.10.10.6
[web]
web-01.myserver.lan ansible_host=10.10.10.12
Here you can see groups of hosts (mail, web). Also you can define some variables for hosts. You can also define global variables for all groups:
[all:vars]
ansible_user=root
For more information see official
documentation about inventory file. We can use this groups in our playbooks:
- name: "First step"
hosts: web
...
Then run our playbook with inventory (hosts) file:
ansible-playbook ./first.yml -i ./hosts
Roles
You can split your groups of tasks into different playbook-files. For example you can move common configuration tasks in common.yml. Apache installation in apache.yml, MySQL installation in mysql.yml. PHP installation in php.yml. *Then include it all into your main playbook (lamp.yaml*):
- name: "LAMP"
hosts: web
tasks:
- name: "Include common"
include: common.yml
...
Checkout more
here and here. But I recommend you to use role-based model. Because your LAMP is just a role for server. To define role we need to create special file hierarchy. Here is example of “common” role:
playbooks
├── roles
│ ├── common
│ │ ├── defaults
│ │ │ └── main.yml
│ │ ├── files
│ │ │ └── text.txt
│ │ └── tasks
│ │ └── main.yml
The main idea is to split logic into separate directories. For example default variables in defaults directory. Additional files, that you can transfer into server in files directory. There are some additional directories: templates, handlers (to handle task results), vars **(other variables), meta (metadata like dependencies). But main file in each directory is main.yml**. You don’t need to create all this folders. To create role you just need to create at least one file: roles/ROLE_NAME/tasks/main.yml . Later you can use your roles in our playbook:
- name: "LAMP deployment"
hosts: web
become: true
roles:
- role: "common"
- role: "php"
- role: "apache"
- role: "mysql"
Here is example of your LAMP playbook. Now you can execute it on a few hosts (defined in web group in inventory file) at the same time! Thats all for now. Good luck with Ansible!