Ansible - Guida rapida
Ansible è un semplice motore IT open source che automatizza la distribuzione delle applicazioni, l'orchestrazione intra-servizio, il provisioning del cloud e molti altri strumenti IT.
Ansible è facile da implementare perché non utilizza agenti o infrastrutture di sicurezza personalizzate.
Ansible utilizza il playbook per descrivere i lavori di automazione e il playbook utilizza un linguaggio molto semplice, ad es YAML(È un linguaggio di serializzazione dei dati leggibile dall'uomo ed è comunemente utilizzato per i file di configurazione, ma potrebbe essere utilizzato in molte applicazioni in cui vengono archiviati i dati) che è molto facile da capire, leggere e scrivere per gli esseri umani. Quindi il vantaggio è che anche i ragazzi del supporto dell'infrastruttura IT possono leggere e comprendere il playbook ed eseguire il debug se necessario (YAML - È in formato leggibile dall'uomo).
Ansible è progettato per la distribuzione a più livelli. Ansible non gestisce un sistema alla volta, modella l'infrastruttura IT descrivendo che tutti i tuoi sistemi sono correlati. Ansible è completamente senza agenti, il che significa che Ansible funziona collegando i tuoi nodi tramite ssh (per impostazione predefinita). Ma se vuoi un altro metodo per la connessione come Kerberos, Ansible ti offre questa opzione.
Dopo essersi connessi ai propri nodi, Ansible invia piccoli programmi chiamati "moduli Ansible". Ansible esegue quei moduli sui tuoi nodi e li rimuove al termine. Ansible gestisce il tuo inventario in semplici file di testo (questi sono i file hosts). Ansible utilizza il file hosts in cui è possibile raggruppare gli host e controllare le azioni su un gruppo specifico nei playbook.
File host di esempio
Questo è il contenuto del file hosts -
#File name: hosts
#Description: Inventory file for your application. Defines machine type abc
node to deploy specific artifacts
# Defines machine type def node to upload
metadata.
[abc-node]
#server1 ansible_host = <target machine for DU deployment> ansible_user = <Ansible
user> ansible_connection = ssh
server1 ansible_host = <your host name> ansible_user = <your unix user>
ansible_connection = ssh
[def-node]
#server2 ansible_host = <target machine for artifact upload>
ansible_user = <Ansible user> ansible_connection = ssh
server2 ansible_host = <host> ansible_user = <user> ansible_connection = ssh
Cos'è la gestione della configurazione
La gestione della configurazione in termini di Ansible significa che mantiene la configurazione delle prestazioni del prodotto mantenendo un registro e aggiornando le informazioni dettagliate che descrivono l'hardware e il software di un'azienda.
Tali informazioni in genere includono le versioni e gli aggiornamenti esatti applicati ai pacchetti software installati e le posizioni e gli indirizzi di rete dei dispositivi hardware. Ad esempio, se si desidera installare la nuova versione diWebLogic/WebSphere server su tutte le macchine presenti nella tua azienda, non è possibile per te andare manualmente ad aggiornare ogni macchina.
È possibile installare WebLogic / WebSphere in una volta sola su tutte le macchine con playbook Ansible e inventario scritti nel modo più semplice. Tutto quello che devi fare è elencare gli indirizzi IP dei tuoi nodi nell'inventario e scrivere un playbook per installare WebLogic / WebSphere. Esegui il playbook dalla tua macchina di controllo e verrà installato su tutti i tuoi nodi.
Come funziona Ansible?
L'immagine sotto mostra il funzionamento di Ansible.
Ansible works collegandoti ai tuoi nodi e spingendo fuori piccoli programmi, chiamati "Ansible moduli "a loro. Ansiblequindi esegue questi moduli (su SSH per impostazione predefinita) e li rimuove al termine. La tua libreria di moduli può risiedere su qualsiasi macchina e non sono richiesti server, daemon o database.
Il nodo di gestione nell'immagine sopra è il nodo di controllo (nodo di gestione) che controlla l'intera esecuzione del playbook. È il nodo da cui stai eseguendo l'installazione. Il file di inventario fornisce l'elenco degli host in cui devono essere eseguiti i moduli Ansible e il nodo di gestione esegue una connessione SSH ed esegue i piccoli moduli sulla macchina host e installa il prodotto / software.
Beauty di Ansible è che rimuove i moduli una volta installati in modo così efficace da connettersi alla macchina host, esegue le istruzioni e se è installato correttamente rimuove il codice che è stato copiato sulla macchina host che è stato eseguito.
In questo capitolo impareremo la configurazione dell'ambiente di Ansible.
Processo di installazione
Principalmente, ci sono due tipi di macchine quando parliamo di distribuzione:
Control machine - Macchina da cui possiamo gestire altre macchine.
Remote machine - Macchine gestite / controllate da macchina di controllo.
Possono esserci più macchine remote gestite da una macchina di controllo. Quindi, per la gestione delle macchine remote dobbiamo installare Ansible sulla macchina di controllo.
Requisiti della macchina di controllo
Ansible può essere eseguito da qualsiasi macchina con Python 2 (versioni 2.6 o 2.7) o Python 3 (versioni 3.5 e successive) installato.
Note - Windows non supporta la macchina di controllo.
Per impostazione predefinita, Ansible utilizza ssh per gestire la macchina remota.
Ansible non aggiunge alcun database. Non richiede alcun demone per avviarlo o mantenerlo in esecuzione. Durante la gestione di macchine remote, Ansibledoes notlasciare qualsiasi software installato o in esecuzione su di essi. Quindi, non c'è dubbio su come aggiornarlo quando si passa a una nuova versione.
Ansible può essere installato su macchine di controllo che hanno i requisiti sopra menzionati in diversi modi. Puoi installare l'ultima versione tramite Apt, yum, pkg, pip, OpenCSW, pacman, ecc.
Installazione tramite Apt su macchina Ubuntu
Per installare Ansible devi configurare PPA sulla tua macchina. Per questo, devi eseguire la seguente riga di codice:
$ sudo apt-get update $ sudo apt-get install software-properties-common
$ sudo apt-add-repository ppa:ansible/ansible $ sudo apt-get update
$ sudo apt-get install ansible
Dopo aver eseguito la riga di codice precedente, sei pronto per gestire le macchine remote tramite Ansible. Basta eseguire Ansible – version per controllare la versione e solo per verificare se Ansible è stato installato correttamente o meno.
Ansible utilizza la sintassi YAML per esprimere i playbook Ansible. Questo capitolo fornisce una panoramica di YAML. Ansible utilizza YAML perché è molto facile per gli esseri umani capire, leggere e scrivere rispetto ad altri formati di dati come XML e JSON.
Ogni YAML file opzionalmente inizia con "---" e finisce con "...".
Capire YAML
In questa sezione impareremo i diversi modi in cui vengono rappresentati i dati YAML.
coppia chiave-valore
YAML utilizza una semplice coppia chiave-valore per rappresentare i dati. Il dizionario è rappresentato nella coppia chiave: valore.
Note - Dovrebbe esserci uno spazio tra: e value.
Esempio: un record dello studente
--- #Optional YAML start syntax
james:
name: james john
rollNo: 34
div: B
sex: male
… #Optional YAML end syntax
Abbreviazione
È inoltre possibile utilizzare l'abbreviazione per rappresentare i dizionari.
Esempio
James: {name: james john, rollNo: 34, div: B, sex: male}
Elenco rappresentativo
Possiamo anche rappresentare List in YAML. Ogni elemento (membro) della lista dovrebbe essere scritto in una nuova riga con lo stesso rientro che inizia con "-" (- e spazio).
Esempio
---
countries:
- America
- China
- Canada
- Iceland
…
Abbreviazione
È inoltre possibile utilizzare l'abbreviazione per rappresentare gli elenchi.
Esempio
Countries: [‘America’, ‘China’, ‘Canada’, ‘Iceland’]
Elenco all'interno dei dizionari
Possiamo usare list all'interno dei dizionari, cioè il valore della chiave è list.
Esempio
---
james:
name: james john
rollNo: 34
div: B
sex: male
likes:
- maths
- physics
- english
…
Elenco dei dizionari
Possiamo anche fare un elenco di dizionari.
Esempio
---
- james:
name: james john
rollNo: 34
div: B
sex: male
likes:
- maths
- physics
- english
- robert:
name: robert richardson
rollNo: 53
div: B
sex: male
likes:
- biology
- chemistry
…
YAML utilizza "|" per includere le nuove righe durante la visualizzazione di più righe e ">" per sopprimere le nuove righe durante la visualizzazione di più righe. Per questo motivo possiamo leggere e modificare righe grandi. In entrambi i casi l'intenzione verrà ignorata.
Possiamo anche rappresentare BooleanValori (Vero / Falso) in YAML. doveboolean i valori possono non fare distinzione tra maiuscole e minuscole.
Esempio
---
- james:
name: james john
rollNo: 34
div: B
sex: male
likes:
- maths
- physics
- english
result:
maths: 87
chemistry: 45
biology: 56
physics: 70
english: 80
passed: TRUE
messageIncludeNewLines: |
Congratulation!!
You passed with 79%
messageExcludeNewLines: >
Congratulation!!
You passed with 79%
Alcune parole comuni relative ad Ansible.
Service/Server - Un processo sulla macchina che fornisce il servizio.
Machine - Un server fisico, una vm (macchina virtuale) o un contenitore.
Target machine - Una macchina che stiamo per configurare con Ansible.
Task - Un'azione (esegui questo, elimina quello) ecc. Gestito da Ansible.
Playbook - Il file yml in cui vengono scritti i comandi Ansible e yml viene eseguito su una macchina.
I comandi ad hoc sono comandi che possono essere eseguiti individualmente per eseguire funzioni rapide. Questi comandi non devono essere eseguiti in seguito.
Ad esempio, devi riavviare tutti i server della tua azienda. Per questo, eseguirai i comandi Adhoc da '/usr/bin/ansible'.
Questi comandi ad-hoc non vengono utilizzati per la gestione e la distribuzione della configurazione, poiché questi comandi vengono utilizzati una sola volta.
ansible-playbook viene utilizzato per la gestione e la distribuzione della configurazione.
Parallelismo e comandi shell
Riavvia il tuo server aziendale in 12 fork paralleli alla volta. Per questo, dobbiamo configurare SSHagent per la connessione.
$ ssh-agent bash
$ ssh-add ~/.ssh/id_rsa
Per eseguire il riavvio di tutti i server della tua azienda in un gruppo, "abc", in 12 fork paralleli:
$ Ansible abc -a "/sbin/reboot" -f 12
Per impostazione predefinita, Ansible eseguirà i comandi Ad-hoc di cui sopra dall'account utente corrente. Se vuoi cambiare questo comportamento, dovrai passare il nome utente nei comandi Ad-hoc come segue:
$ Ansible abc -a "/sbin/reboot" -f 12 -u username
Trasferimento di file
Puoi usare i comandi ad-hoc per fare SCP (Secure Copy Protocol) molti file in parallelo su più macchine.
Trasferimento di file su molti server / macchine
$ Ansible abc -m copy -a "src = /etc/yum.conf dest = /tmp/yum.conf"
Creazione di una nuova directory
$ Ansible abc -m file -a "dest = /path/user1/new mode = 777 owner = user1 group = user1 state = directory"
Eliminazione dell'intera directory e file
$ Ansible abc -m file -a "dest = /path/user1/new state = absent"
Gestione dei pacchetti
I comandi ad-hoc sono disponibili per yum e apt. Di seguito sono riportati alcuni comandi ad-hoc che utilizzano yum.
Il seguente comando controlla se il pacchetto yum è installato o meno, ma non lo aggiorna.
$ Ansible abc -m yum -a "name = demo-tomcat-1 state = present"
Il seguente comando verifica che il pacchetto non sia installato.
$ Ansible abc -m yum -a "name = demo-tomcat-1 state = absent"
Il comando seguente verifica che l'ultima versione del pacchetto sia installata.
$ Ansible abc -m yum -a "name = demo-tomcat-1 state = latest"
Raccolta di fatti
I fatti possono essere usati per implementare le istruzioni condizionali nel playbook. Puoi trovare informazioni ad hoc di tutti i tuoi fatti tramite il seguente comando ad-hoc:
$ Ansible all -m setup
In questo capitolo impareremo a conoscere i playbook in Ansible.
I playbook sono i file in cui viene scritto il codice Ansible. I playbook sono scritti in formato YAML. YAML sta per Yet Another Markup Language.Playbookssono una delle caratteristiche principali di Ansible e dicono ad Ansible cosa eseguire. Sono come un elenco di cose da fare per Ansible che contiene un elenco di attività.
I playbook contengono i passaggi che l'utente desidera eseguire su una particolare macchina. I playbook vengono eseguiti in sequenza. I playbook sono gli elementi costitutivi di tutti i casi d'uso di Ansible.
Struttura del playbook
Ogni playbook è un'aggregazione di uno o più giochi in esso contenuti. I playbook sono strutturati utilizzando le riproduzioni. Possono esserci più giochi all'interno di un playbook.
La funzione di un gioco è quella di mappare un insieme di istruzioni definite rispetto a un particolare host.
YAML è un linguaggio tipizzato rigoroso; quindi, è necessario prestare particolare attenzione durante la scrittura dei file YAML. Esistono diversi editor YAML ma preferiremo utilizzare un editor semplice come notepad ++. Basta aprire notepad ++ e copiare e incollare lo yaml sottostante e cambiare la lingua in YAML (Lingua → YAML).
Uno YAML inizia con --- (3 trattini)
Crea un playbook
Cominciamo scrivendo un file YAML di esempio. Esamineremo ogni sezione scritta in un file yaml.
---
name: install and configure DB
hosts: testServer
become: yes
vars:
oracle_db_port_value : 1521
tasks:
-name: Install the Oracle DB
yum: <code to install the DB>
-name: Ensure the installed service is enabled and running
service:
name: <your service name>
The above is a sample Playbook where we are trying to cover the basic syntax of a playbook. Save the above content in a file as test.yml. A YAML syntax needs to follow the correct indentation and one needs to be a little careful while writing the syntax.
The Different YAML Tags
Let us now go through the different YAML tags. The different tags are described below −
name
This tag specifies the name of the Ansible playbook. As in what this playbook will be doing. Any logical name can be given to the playbook.
hosts
This tag specifies the lists of hosts or host group against which we want to run the task. The hosts field/tag is mandatory. It tells Ansible on which hosts to run the listed tasks. The tasks can be run on the same machine or on a remote machine. One can run the tasks on multiple machines and hence hosts tag can have a group of hosts’ entry as well.
vars
Vars tag lets you define the variables which you can use in your playbook. Usage is similar to variables in any programming language.
tasks
All playbooks should contain tasks or a list of tasks to be executed. Tasks are a list of actions one needs to perform. A tasks field contains the name of the task. This works as the help text for the user. It is not mandatory but proves useful in debugging the playbook. Each task internally links to a piece of code called a module. A module that should be executed, and arguments that are required for the module you want to execute.
Roles provide a framework for fully independent, or interdependent collections of variables, tasks, files, templates, and modules.
In Ansible, the role is the primary mechanism for breaking a playbook into multiple files. This simplifies writing complex playbooks, and it makes them easier to reuse. The breaking of playbook allows you to logically break the playbook into reusable components.
Each role is basically limited to a particular functionality or desired output, with all the necessary steps to provide that result either within that role itself or in other roles listed as dependencies.
Roles are not playbooks. Roles are small functionality which can be independently used but have to be used within playbooks. There is no way to directly execute a role. Roles have no explicit setting for which host the role will apply to.
Top-level playbooks are the bridge holding the hosts from your inventory file to roles that should be applied to those hosts.
Creating a New Role
The directory structure for roles is essential to create a new role.
Role Structure
Roles have a structured layout on the file system. The default structure can be changed but for now let us stick to defaults.
Each role is a directory tree in itself. The role name is the directory name within the /roles directory.
$ ansible-galaxy -h
Usage
ansible-galaxy [delete|import|info|init|install|list|login|remove|search|setup] [--help] [options] ...
Options
-h, --help − Show this help message and exit.
-v, --verbose − Verbose mode (-vvv for more, -vvvv to enable connection debugging)
--version − Show program's version number and exit.
Creating a Role Directory
The above command has created the role directories.
$ ansible-galaxy init vivekrole
ERROR! The API server (https://galaxy.ansible.com/api/) is not responding, please try again later.
$ ansible-galaxy init --force --offline vivekrole - vivekrole was created successfully $ tree vivekrole/
vivekrole/
├── defaults
│ └── main.yml
├── files ├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md ├── tasks
│ └── main.yml
├── templates ├── tests │ ├── inventory
│ └── test.yml
└── vars
└── main.yml
8 directories, 8 files
Not all the directories will be used in the example and we will show the use of some of them in the example.
Utilizing Roles in Playbook
This is the code of the playbook we have written for demo purpose. This code is of the playbook vivek_orchestrate.yml. We have defined the hosts: tomcat-node and called the two roles – install-tomcat and start-tomcat.
The problem statement is that we have a war which we need to deploy on a machine via Ansible.
---
- hosts: tomcat-node
roles:
- {role: install-tomcat}
- {role: start-tomcat}
Contents of our directory structure from where we are running the playbook.
$ ls
ansible.cfg hosts roles vivek_orchestrate.retry vivek_orchestrate.yml
There is a tasks directory under each directory and it contains a main.yml. The main.yml contents of install-tomcat are −
---
#Install vivek artifacts
-
block:
- name: Install Tomcat artifacts
action: >
yum name = "demo-tomcat-1" state = present
register: Output
always:
- debug:
msg:
- "Install Tomcat artifacts task ended with message: {{Output}}"
- "Installed Tomcat artifacts - {{Output.changed}}"
The contents of main.yml of the start tomcat are −
#Start Tomcat
-
block:
- name: Start Tomcat
command: <path of tomcat>/bin/startup.sh"
register: output
become: true
always:
- debug:
msg:
- "Start Tomcat task ended with message: {{output}}"
- "Tomcat started - {{output.changed}}"
The advantage of breaking the playbook into roles is that anyone who wants to use the Install tomcat feature can call the Install Tomcat role.
Breaking a Playbook into a Role
If not for the roles, the content of the main.yml of the respective role can be copied in the playbook yml file. But to have modularity, roles were created.
Any logical entity which can be reused as a reusable function, that entity can be moved to role. The example for this is shown above
Ran the command to run the playbook.
-vvv option for verbose output – verbose output
$ cd vivek-playbook/
This is the command to run the playbook
$ sudo ansible-playbook -i hosts vivek_orchestrate.yml –vvv
-----------------------------------------------------------------
-----------------------------------------------------------------------
Output
The generated output is as seen on the screen −
Using /users/demo/vivek-playbook/ansible.cfg as config file.
PLAYBOOK: vivek_orchestrate.yml *********************************************************
***********************************************************
1 plays in vivek_orchestrate.yml
PLAY [tomcat-node] **********************************************************************
******** *************************************************
TASK [Gathering Facts] *************************************************
****************************** *********************************************
Tuesday 21 November 2017 13:02:05 +0530 (0:00:00.056) 0:00:00.056 ******
Using module file /usr/lib/python2.7/sitepackages/ansible/modules/system/setup.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249525.88-259535494116870 `" &&
echo ansible-tmp-1511249525.88-259535494116870="`
echo /root/.ansible/tmp/ansibletmp-1511249525.88-259535494116870 `" ) && sleep 0'
<localhost> PUT /tmp/tmpPEPrkd TO
/root/.ansible/tmp/ansible-tmp-1511249525.88259535494116870/setup.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249525.88-259535494116870/
/root/.ansible/tmp/ansible-tmp-1511249525.88259535494116870/setup.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249525.88-259535494116870/setup.py; rm -rf
"/root/.ansible/tmp/ansible-tmp1511249525.88-259535494116870/" > /dev/null 2>&1 && sleep 0'
ok: [server1]
META: ran handlers
TASK [install-tomcat : Install Tomcat artifacts] ***********************************
***************************************************************
task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:5
Tuesday 21 November 2017 13:02:07 +0530 (0:00:01.515) 0:00:01.572 ******
Using module file /usr/lib/python2.7/sitepackages/ansible/modules/packaging/os/yum.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249527.34-40247177825302 `" && echo
ansibletmp-1511249527.34-40247177825302="` echo
/root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302 `" ) && sleep 0'
<localhost> PUT /tmp/tmpu83chg TO
/root/.ansible/tmp/ansible-tmp-1511249527.3440247177825302/yum.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302/
/root/.ansible/tmp/ansible-tmp-1511249527.3440247177825302/yum.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302/yum.py; rm -rf
"/root/.ansible/tmp/ansible-tmp1511249527.34-40247177825302/" > /dev/null 2>
&1 && sleep 0'
changed: [server1] => {
"changed": true,
"invocation": {
"module_args": {
"conf_file": null,
"disable_gpg_check": false,
"disablerepo": null,
"enablerepo": null,
"exclude": null,
"install_repoquery": true,
"installroot": "/",
"list": null,
"name": ["demo-tomcat-1"],
"skip_broken": false,
"state": "present",
"update_cache": false,
"validate_certs": true
}
},
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: product-id,
search-disabled-repos,
subscriptionmanager\nThis system is not registered to Red Hat Subscription Management.
You can use subscription-manager to register.\nResolving Dependencies\n-->
Running transaction check\n--->
Package demo-tomcat-1.noarch 0:SNAPSHOT-1 will be installed\n--> Finished Dependency
Resolution\n\nDependencies Resolved\n
\n================================================================================\n
Package Arch Version Repository
Size\n==================================================================\nInstalling:\n
demo-tomcat-1 noarch SNAPSHOT-1 demo-repo1 7.1 M\n\nTransaction
Summary\n==================================================================\nInstall 1
Package\n\nTotal download size: 7.1 M\nInstalled size: 7.9 M\nDownloading
packages:\nRunning transaction
check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n Installing :
demotomcat-1-SNAPSHOT-1.noarch 1/1 \n Verifying :
demo-tomcat-1-SNAPSHOT-1.noarch 1/1 \n\nInstalled:\n
demo-tomcat-1.noarch 0:SNAPSHOT-1 \n\nComplete!\n"
]
}
TASK [install-tomcat : debug] **********************************************************
***************************************************************************
task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:11
Tuesday 21 November 2017 13:02:13 +0530 (0:00:06.757) 0:00:08.329 ******
ok: [server1] => {
"changed": false,
"msg": [
"Install Tomcat artifacts task ended with message: {
u'msg': u'', u'changed': True, u'results':
[u'Loaded plugins: product-id,
search-disabledrepos,
subscription-manager\\nThis system is not registered to Red Hat Subscription Management.
You can use subscription-manager to register.\\nResolving Dependencies\\n-->
Running transaction check\\n--->
Package demo-tomcat-1.noarch 0:SNAPSHOT-1 will be installed\\n-->
Finished Dependency Resolution\\n
\\nDependencies
Resolved\\n\\n==================================================================\\n
Package Arch Version Repository
Size\\n========================================================================
=====\\nInstalling:\\n demo-tomcat-1 noarch SNAPSHOT-1 demo-repo1 7.1 M\\n\\nTransaction
Summary\\n=========================================================\\nInstall 1
Package\\n\\nTotal download size: 7.1 M\\nInstalled size: 7.9 M\\nDownloading
packages:\\nRunning
transaction check\\nRunning transaction test\\nTransaction test succeeded\\nRunning
transaction\\n
Installing : demo-tomcat-1-SNAPSHOT-1.noarch 1/1 \\n Verifying :
demo-tomcat-1-SNAPSHOT-1.noarch
1/1 \\n\\nInstalled:\\n demo-tomcat-1.noarch 0:SNAPSHOT-1 \\n\\nComplete!\\n'], u'rc': 0
}",
"Installed Tomcat artifacts - True"
]
}
TASK [install-tomcat : Clean DEMO environment] ****************************************
************************************************************
task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:19
Tuesday 21 November 2017 13:02:13 +0530 (0:00:00.057) 0:00:08.387 ******
[WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or
{% %}. Found: {{installationOutput.changed}}
Using module file /usr/lib/python2.7/sitepackages/ansible/modules/files/file.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249534.13-128345805983963 `" && echo
ansible-tmp-1511249534.13-128345805983963="` echo
/root/.ansible/tmp/ansibletmp-1511249534.13-128345805983963 `" ) && sleep 0'
<localhost> PUT /tmp/tmp0aXel7 TO
/root/.ansible/tmp/ansible-tmp-1511249534.13128345805983963/file.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249534.13-128345805983963/
/root/.ansible/tmp/ansible-tmp-1511249534.13128345805983963/file.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249534.13-128345805983963/file.py; rm -rf
"/root/.ansible/tmp/ansible-tmp1511249534.13-128345805983963/" > /dev/null 2>&1
&& sleep 0'
changed: [server1] => {
"changed": true,
"diff": {
"after": {
"path": "/users/demo/DEMO",
"state": "absent"
},
"before": {
"path": "/users/demo/DEMO",
"state": "directory"
}
},
"invocation": {
"module_args": {
"attributes": null,
"backup": null,
"content": null,
"delimiter": null,
"diff_peek": null,
"directory_mode": null,
"follow": false,
"force": false,
"group": null,
"mode": null,
"original_basename": null,
"owner": null,
"path": "/users/demo/DEMO",
"recurse": false,
"regexp": null,
"remote_src": null,
"selevel": null,
"serole": null,
"setype": null,
"seuser": null,
"src": null,
"state": "absent",
"unsafe_writes": null,
"validate": null
}
},
"path": "/users/demo/DEMO",
"state": "absent"
}
TASK [install-tomcat : debug] ********************************************************
*************************************************************
task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:29
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.257) 0:00:08.645 ******
ok: [server1] => {
"changed": false,
"msg": [
"Clean DEMO environment task ended with message:{u'diff': {u'after': {u'path':
u'/users/demo/DEMO', u'state': u'absent'},
u'before': {u'path': u'/users/demo/DEMO', u'state': u'directory'}}, u'state': u'absent',
u'changed': True, u'path': u'/users/demo/DEMO'}",
"check value :True"
]
}
TASK [install-tomcat : Copy Tomcat to user home] *************************************
********************************************************
task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:37
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.055) 0:00:08.701 ******
[WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or
{% %}. Found: {{installationOutput.changed}}
Using module file /usr/lib/python2.7/sitepackages/ansible/modules/commands/command.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249534.43-41077200718443 `" && echo
ansibletmp-1511249534.43-41077200718443="` echo
/root/.ansible/tmp/ansible-tmp1511249534.43-41077200718443 `" ) && sleep 0'
<localhost> PUT /tmp/tmp25deWs TO
/root/.ansible/tmp/ansible-tmp-1511249534.4341077200718443/command.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249534.43-41077200718443/
/root/.ansible/tmp/ansible-tmp-1511249534.4341077200718443/command.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249534.43-41077200718443/command.py; rm -rf
"/root/.ansible/tmp/ansibletmp-1511249534.43-41077200718443/" > /dev/null 2>&1
&& sleep 0'
changed: [server1] => {
"changed": true,
"cmd": [
"cp",
"-r",
"/opt/ansible/tomcat/demo",
"/users/demo/DEMO/"
],
"delta": "0:00:00.017923",
"end": "2017-11-21 13:02:14.547633",
"invocation": {
"module_args": {
"_raw_params": "cp -r /opt/ansible/tomcat/demo /users/demo/DEMO/",
"_uses_shell": false,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
}
},
"rc": 0,
"start": "2017-11-21 13:02:14.529710",
"stderr": "",
"stderr_lines": [],
"stdout": "",
"stdout_lines": []
}
TASK [install-tomcat : debug] ********************************************************
**********************************************************
task path: /users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:47
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.260) 0:00:08.961 ******
ok: [server1] => {
"changed": false,
"msg": "Copy Tomcat to user home task ended with message {
'stderr_lines': [], u'changed': True, u'end': u'2017-11-21 13:02:14.547633', u'stdout':
u'', u'cmd': [u'cp', u'-r', u'/opt/ansible/tomcat/demo', u'/users/demo/DEMO/'], u'rc': 0,
u'start': u'2017-11-21 13:02:14.529710', u'stderr': u'', u'delta': u'0:00:00.017923',
'stdout_lines': []}"
}
TASK [start-tomcat : Start Tomcat] **************************************************
**********************************************************
task path: /users/demo/vivek-playbook/roles/start-tomcat/tasks/main.yml:5
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.044) 0:00:09.006 ******
Using module file /usr/lib/python2.7/sitepackages/ansible/modules/commands/command.py
<localhost> ESTABLISH LOCAL CONNECTION FOR USER: root
<localhost> EXEC /bin/sh -c 'echo ~ && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo
/root/.ansible/tmp/ansible-tmp-1511249534.63-46501211251197 `" && echo
ansibletmp-1511249534.63-46501211251197="` echo
/root/.ansible/tmp/ansible-tmp1511249534.63-46501211251197 `" ) && sleep 0'
<localhost> PUT /tmp/tmp9f06MQ TO
/root/.ansible/tmp/ansible-tmp-1511249534.6346501211251197/command.py
<localhost> EXEC /bin/sh -c 'chmod u+x
/root/.ansible/tmp/ansible-tmp1511249534.63-46501211251197/
/root/.ansible/tmp/ansible-tmp-1511249534.6346501211251197/command.py && sleep 0'
<localhost> EXEC /bin/sh -c '/usr/bin/python
/root/.ansible/tmp/ansible-tmp1511249534.63-46501211251197/command.py; rm -rf
"/root/.ansible/tmp/ansibletmp-1511249534.63-46501211251197/" > /dev/null 2>&1
&& sleep 0'
changed: [server1] => {
"changed": true,
"cmd": [ "/users/demo/DEMO/bin/startup.sh" ],
"delta": "0:00:00.020024",
"end": "2017-11-21 13:02:14.741649",
"invocation": {
"module_args": {
"_raw_params": "/users/demo/DEMO/bin/startup.sh",
"_uses_shell": false,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"warn": true
}
},
"rc": 0,
"start": "2017-11-21 13:02:14.721625",
"stderr": "",
"stderr_lines": [],
"stdout": "Tomcat started.",
"stdout_lines": [ "Tomcat started." ]
}
TASK [start-tomcat : debug] *************************************************
**********************************************************************
task path: /users/demo/vivek-playbook/roles/start-tomcat/tasks/main.yml:10
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.150) 0:00:09.156 ******
ok: [server1] => {
"changed": false,
"msg": [
"Start Tomcat task ended with message: {'
stderr_lines': [], u'changed': True, u'end': u'2017-11-21 13:02:14.741649', u'stdout':
u'Tomcat started.', u'cmd': [u'/users/demo/DEMO/bin/startup.sh'], u'rc': 0, u'start':
u'2017-11-21 13:02:14.721625', u'stderr': u'', u'delta': u'0:00:00.020024',
'stdout_lines': [u'Tomcat started.']}",
"Tomcat started - True"
]
}
META: ran handlers
META: ran handlers
PLAY RECAP *******************************************************************************
*********************************************************
server1 : ok = 9 changed = 4 unreachable = 0 failed = 0
Tuesday 21 November 2017 13:02:14 +0530 (0:00:00.042) 0:00:09.198 ******
===============================================================================
install-tomcat : Install Tomcat artifacts ------------------------------- 6.76s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:5 --------------
Gathering Facts --------------------------------------------------------- 1.52s
------------------------------------------------------------------------------
install-tomcat : Copy Tomcat to user home ------------------------------- 0.26s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:37 -------------
install-tomcat : Clean DEMO environment --------------------------------- 0.26s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:19 -------------
start-tomcat : Start Tomcat --------------------------------------------- 0.15s
/users/demo/vivek-playbook/roles/start-tomcat/tasks/main.yml:5 ----------------
install-tomcat : debug -------------------------------------------------- 0.06s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:11 -------------
install-tomcat : debug -------------------------------------------------- 0.06s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:29 -------------
install-tomcat : debug -------------------------------------------------- 0.04s
/users/demo/vivek-playbook/roles/install-tomcat/tasks/main.yml:47 -------------
start-tomcat : debug ---------------------------------------------------- 0.04s
/users/demo/vivek-playbook/roles/start-tomcat/tasks/main.yml:10 ---------------
Hit the following URL and you will be directed to a page as shown below − http://10.76.0.134:11677/HelloWorld/HelloWorld
The deployed war just has a servlet which displays “Hello World”. The detailed output shows the time taken by each and every task because of the entry added in ansible.cfg file −
[defaults]
callback_whitelist = profile_tasks
Variable in playbooks are very similar to using variables in any programming language. It helps you to use and assign a value to a variable and use that anywhere in the playbook. One can put conditions around the value of the variables and accordingly use them in the playbook.
Example
- hosts : <your hosts>
vars:
tomcat_port : 8080
In the above example, we have defined a variable name tomcat_port and assigned the value 8080 to that variable and can use that in your playbook wherever needed.
Now taking a reference from the example shared. The following code is from one of the roles (install-tomcat) −
block:
- name: Install Tomcat artifacts
action: >
yum name = "demo-tomcat-1" state = present
register: Output
always:
- debug:
msg:
- "Install Tomcat artifacts task ended with message: {{Output}}"
- "Installed Tomcat artifacts - {{Output.changed}}"
Here, the output is the variable used.
Let us walk through all the keywords used in the above code −
block − Ansible syntax to execute a given block.
name − Relevant name of the block - this is used in logging and helps in debugging that which all blocks were successfully executed.
action − The code next to action tag is the task to be executed. The action again is a Ansible keyword used in yaml.
register − The output of the action is registered using the register keyword and Output is the variable name which holds the action output.
always − Again a Ansible keyword , it states that below will always be executed.
msg − Displays the message.
Usage of variable - {{Output}} -->
This will read the value of variable Output. Also as it is used in the msg tab, it will print the value of the output variable.
Additionally, you can use the sub properties of the variable as well. Like in the case checking {{Output.changed}} whether the output got changed and accordingly use it.
Exception Handling in Playbooks
Exception handling in Ansible is similar to exception handling in any programming language. An example of the exception handling in playbook is shown below.
tasks:
- name: Name of the task to be executed
block:
- debug: msg = 'Just a debug message , relevant for logging'
- command: <the command to execute>
rescue:
- debug: msg = 'There was an exception.. '
- command: <Rescue mechanism for the above exception occurred)
always:
- debug: msg = "this will execute in all scenarios. Always will get logged"
Following is the syntax for exception handling.
rescue and always are the keywords specific to exception handling.
Block is where the code is written (anything to be executed on the Unix machine).
If the command written inside the block feature fails, then the execution reaches rescue block and it gets executed. In case there is no error in the command under block feature, then rescue will not be executed.
Always gets executed in all cases.
So if we compare the same with java, then it is similar to try, catch and finally block.
Here, Block is similar to try block where you write the code to be executed and rescue is similar to catch block and always is similar to finally.
Loop
Di seguito è riportato l'esempio per dimostrare l'utilizzo dei loop in Ansible.
Il compito è copiare il set di tutti i file war da una directory alla cartella webapps di tomcat.
La maggior parte dei comandi utilizzati nell'esempio seguente sono già stati trattati in precedenza. Qui ci concentreremo sull'uso dei loop.
Inizialmente nel comando 'shell' abbiamo eseguito ls * .war. Quindi, elencherà tutti i file war nella directory.
L'output di quel comando viene preso in una variabile denominata output.
Per eseguire il ciclo, viene utilizzata la sintassi "with_items".
with_items: "{{output.stdout_lines}}" -> output.stdout_lines ci fornisce l'output riga per riga e quindi eseguiamo un loop sull'output con il comando with_items di Ansible.
Alleghiamo l'output di esempio solo per far capire come abbiamo usato stdout_lines nel comando with_items.
---
#Tsting
- hosts: tomcat-node
tasks:
- name: Install Apache
shell: "ls *.war"
register: output
args:
chdir: /opt/ansible/tomcat/demo/webapps
- file:
src: '/opt/ansible/tomcat/demo/webapps/{{ item }}'
dest: '/users/demo/vivek/{{ item }}'
state: link
with_items: "{{output.stdout_lines}}"
Blocchi
Il playbook nella sua totalità è suddiviso in blocchi. Il più piccolo passo da eseguire è scritto in blocco. Scrivere l'istruzione specifica in blocchi aiuta a separare la funzionalità e gestirla con la gestione delle eccezioni, se necessario.
L'esempio di blocchi è trattato nell'uso delle variabili, nella gestione delle eccezioni e nei cicli sopra.
Condizionali
I condizionali vengono utilizzati quando è necessario eseguire un passaggio specifico in base a una condizione.
---
#Tsting
- hosts: all
vars:
test1: "Hello Vivek"
tasks:
- name: Testing Ansible variable
debug:
msg: "Equals"
when: test1 == "Hello Vivek"
In questo caso, Equals verrà stampato poiché la variabile test1 è uguale come indicato nella condizione when. when può essere utilizzato con un OR logico e una condizione AND logico come in tutti i linguaggi di programmazione.
Basta cambiare il valore della variabile test1 da Hello Vivek per dire Hello World e vedere l'output.
In questo capitolo, impareremo cos'è l'esecuzione avanzata con Ansible.
Come limitare l'esecuzione per attività
Questa è una strategia di esecuzione molto importante in cui è necessario eseguire solo un'esecuzione e non l'intero playbook. For example, supponi di voler solo arrestare un server (nel caso in cui si verifichi un problema di produzione) e quindi applicare una patch per postare solo per avviare il server.
Qui nel playbook originale l'arresto e l'avvio facevano parte di ruoli diversi nello stesso playbook, ma questo può essere gestito con l'utilizzo di tag. Possiamo fornire tag diversi a ruoli diversi (che a loro volta avranno compiti) e quindi in base ai tag forniti dall'esecutore viene eseguito solo quel ruolo / compito specificato. Quindi, per l'esempio sopra fornito, possiamo aggiungere tag come il seguente:
- {role: start-tomcat, tags: ['install']}}
Il seguente comando aiuta nell'utilizzo dei tag:
ansible-playbook -i hosts <your yaml> --tags "install" -vvv
Con il comando precedente, verrà chiamato solo il ruolo start-tomcat. Il tag fornito fa distinzione tra maiuscole e minuscole. Assicurati che la corrispondenza esatta venga passata al comando.
Come limitare l'esecuzione da parte degli host
Esistono due modi per ottenere l'esecuzione di passaggi specifici su host specifici. Per un ruolo specifico, si definiscono gli host, in base a quali host specifici deve essere eseguito quel ruolo specifico.
Esempio
- hosts: <A>
environment: "{{your env}}"
pre_tasks:
- debug: msg = "Started deployment.
Current time is {{ansible_date_time.date}} {{ansible_date_time.time}} "
roles:
- {role: <your role>, tags: ['<respective tag>']}
post_tasks:
- debug: msg = "Completed deployment.
Current time is {{ansible_date_time.date}} {{ansible_date_time.time}}"
- hosts: <B>
pre_tasks:
- debug: msg = "started....
Current time is {{ansible_date_time.date}} {{ansible_date_time.time}} "
roles:
- {role: <your role>, tags: ['<respective tag>']}
post_tasks:
- debug: msg = "Completed the task..
Current time is {{ansible_date_time.date}} {{ansible_date_time.time}}"
Come nell'esempio precedente, a seconda degli host forniti, verranno chiamati solo i rispettivi ruoli. Ora i miei host A e B sono definiti negli host (file di inventario).
Soluzione alternativa
Una soluzione diversa potrebbe essere la definizione degli host del playbook utilizzando una variabile, quindi il passaggio di un indirizzo host specifico tramite --extra-vars -
# file: user.yml (playbook)
---
- hosts: '{{ target }}'
user: ...
playbook contd….
Esecuzione del Playbook
ansible-playbook user.yml --extra-vars "target = "<your host variable>"
Se {{target}} non è definito, il playbook non fa nulla. Se necessario, è anche possibile passare un gruppo dal file hosts. Ciò non nuoce se non vengono fornite le variabili aggiuntive.
Playbook rivolto a un singolo host
$ ansible-playbook user.yml --extra-vars "target = <your hosts variable>" --listhosts
Le strategie più comuni per il debug dei playbook Ansible utilizzano i moduli indicati di seguito:
Eseguire il debug e la registrazione
Questi due sono i moduli disponibili in Ansible. A scopo di debug, dobbiamo usare i due moduli con giudizio. Di seguito sono illustrati esempi.
Usa Verbosità
Con il comando Ansible, è possibile fornire il livello di verbosità. Puoi eseguire i comandi con livello di verbosità uno (-v) o due (-vv).
Punti importanti
In questa sezione, esamineremo alcuni esempi per comprendere alcuni concetti.
Se non stai citando un argomento che inizia con una variabile. Per esempio,
vars:
age_path: {{vivek.name}}/demo/
{{vivek.name}}
Questo genererà un errore.
Soluzione
vars:
age_path: "{{vivek.name}}/demo/" – marked in yellow is the fix.
How to use register -> Copy this code into a yml file say test.yml and run it
---
#Tsting
- hosts: tomcat-node
tasks:
- shell: /usr/bin/uptime
register: myvar
- name: Just debugging usage
debug: var = myvar
Quando eseguo questo codice tramite il comando Ansible-playbook -i hosts test.yml, ottengo l'output come mostrato di seguito.
Se vedi lo yaml, abbiamo registrato l'output di un comando in una variabile - myvar e ha appena stampato l'output.
Il testo contrassegnato in giallo, ci informa sulla proprietà della variabile –myvar che può essere utilizzata per un ulteriore controllo del flusso. In questo modo possiamo scoprire le proprietà che sono esposte di una particolare variabile. Il seguente comando di debug aiuta in questo.
$ ansible-playbook -i hosts test.yml
PLAY [tomcat-node] ***************************************************************
**************** ****************************************************************
*************** ******************************
TASK [Gathering Facts] *****************************************************************
************** *****************************************************************
************** **************************
Monday 05 February 2018 17:33:14 +0530 (0:00:00.051) 0:00:00.051 *******
ok: [server1]
TASK [command] ******************************************************************
************* ******************************************************************
************* **********************************
Monday 05 February 2018 17:33:16 +0530 (0:00:01.697) 0:00:01.748 *******
changed: [server1]
TASK [Just debugging usage] ******************************************************************
************* ******************************************************************
************* *********************
Monday 05 February 2018 17:33:16 +0530 (0:00:00.226) 0:00:01.974 *******
ok: [server1] => {
"myvar": {
"changed": true,
"cmd": "/usr/bin/uptime",
"delta": "0:00:00.011306",
"end": "2018-02-05 17:33:16.424647",
"rc": 0,
"start": "2018-02-05 17:33:16.413341",
"stderr": "",
"stderr_lines": [],
"stdout": " 17:33:16 up 7 days, 35 min, 1 user, load average: 0.18, 0.15, 0.14",
"stdout_lines": [
" 17:33:16 up 7 days, 35 min, 1 user, load average: 0.18, 0.15, 0.14"
]
}
}
PLAY RECAP ****************************************************************************
**********************************************************************************
**************************************
server1 : ok = 3 changed = 1 unreachable = 0 failed = 0
Problemi comuni del Playbook
In questa sezione, impareremo alcuni problemi comuni del playbook. I problemi sono:
- Quoting
- Indentation
Playbook è scritto in formato yaml e i due precedenti sono i problemi più comuni in yaml / playbook.
Yaml non supporta il rientro basato su tabulazioni e supporta il rientro basato sullo spazio, quindi è necessario fare attenzione allo stesso.
Note - una volta che hai finito di scrivere lo yaml, apri questo sito (https://editor.swagger.io/) e copia incolla il tuo yaml sul lato sinistro per assicurarti che lo yaml venga compilato correttamente. Questo è solo un suggerimento.
Swagger qualifica gli errori sia nell'avvertimento che nell'errore.