Zipyinthenet¡ WebSite !

Zipyinthenet¡ WebSite with a lot of info.

——-Inicio/Home——-Posts-Guias-Por-Fecha-Publicación——-Posts-Guias-Por-Categorias——-Links——-

ANSIBLE FOR BEGGINERS (ROOKIES)

Ansible Documentation

link-documentation-ansible


Setting up Ansible

Ansible needs:

Install ansible:

link-install-ansible

ansible --version

Inventory Files

Ansible usa predeterminada mente , su fichero de inventario en /etc/ansible/hosts

Un inventario se define en formato ini:

server1.company.com
server2.company.com

Se pueden listar servidores , agruparlos por grupos:

[grupo1]
server1.company.com
server2.company.com

También se pueden añadir alias:

[grupo1]
web  server1.company.com
db   server2.company.com
mail server3.company.com
web2 server4.company.com

Parametros de inventario:

ansible_connection – ssh/winrm/localhost ansible_port – 22/5986 ansible_user – root/administrator ansible_ssh_pass – password

Como usar los parametros de inventario:

web  server1.company.com ansible_conection=ssh ansible_user=root ansible_ssh_pass=p@$$w0rd!!
db   server2.company.com ansible_conection=winrm ansible_user=admin ansible_ssh_pass=p@$$w0rd!!
mail server3.company.com ansible_conection=ssh ansible_port=56826 ansible_user=root ansible_ssh_pass=p@$$w0rd!!
web2 server4.company.com ansible_conection=winrm ansible_user=admin ansible_ssh_pass=p@$$w0rd!!
localhost ansible_conection=localhost
[grupo1]
web  server1.company.com ansible_conection=ssh ansible_user=root ansible_ssh_pass=p@$$w0rd!!
db   server2.company.com ansible_conection=winrm ansible_user=admin ansible_ssh_pass=p@$$w0rd!!
[grupo2]
mail server3.company.com ansible_conection=ssh ansible_port=56826 ansible_user=root ansible_ssh_pass=p@$$w0rd!!
web2 server4.company.com ansible_conection=winrm ansible_user=admin ansible_ssh_pass=p@$$w0rd!!
[grupo3]
localhost ansible_conection=localhost

DEMO

cat inventory.txt
target1 ansible_host=192.168.0.122 ansible_ssh_pass=p@$$w0rd!!

Comprobar con modulo ping:

ansible target1 -m ping -i inventory.txt
cat inventory.txt
target1 ansible_host=192.168.0.122 ansible_ssh_pass=p@$$w0rd!!
target2 ansible_host=192.168.0.123 ansible_ssh_pass=p@$$w0rd!!

Comprobar con modulo ping:

ansible target2 -m ping -i inventory.txt

FALLA , NO TENEMOS fingerprint de KEY HOST remoto

Iniciar sesion manualmente para aceptar , la key , es lo mejor y mas habitual.

NO es lo mas habitual.

vim /etc/ansible/ansible.cfg

Editar y descomentar –> host_key_checking


Introduction to YAML

YAML , se usa para representar datos.

Dictionary

Banana:
  Calories: 105
  Fat: 0.3g
  Carbs: 27g
Grapes:
  Calories: 200
  Fat: 0.83g
  Carbs: 16g

list

Fruits:
-  Oranges
-  Apples
-  Bananas
Vegetables:
-  carrot
-  cauliflower
-  tomatoes

list of dictionaries

- Color: red
  model: 
    name: corvette
    model: 1995
  Price: 20.000$
- Color: grey
  model: 
    name: corvette
    model: 2000
  Price: 80.000$

PLAYBOOKS

Los playbooks se escriben en YAML , definicion playbook: - playbook is a single YAML file - Play , define set of activities (tasks) to be run on hosts - task is an action to be performed on the host - execute command - run script - install package - shutdown/restart

---
- name: Play 1
  hosts: localhost
  tasks:
    - name: Execute command ‘date’
    command: date

    - name: Execute script on server
    script: test_script.sh

    - name: Install httpd service
    yum:
     name: httpd
     state: present

    - name: Start web server
    service:
     name: httpd
     state: started
---
- name: Play 1
  hosts: localhost
  tasks:
    - name: Execute command ‘date’
    command: date

    - name: Execute script on server
    script: test_script.sh

- name: Play 2
  hosts: localhost
  tasks:
    - name: Install httpd service
    yum:
     name: httpd
     state: present

    - name: Start web server
    service:
     name: httpd
     state: started

DEMO1 - ANSIBLE COMMANDS vs ANSIBLE-PLAYBOOK COMMANDS

ANSIBLE COMMANDS ansible -a ansible all -a “/sbin/reboot” ansible -m ansible target1 -m ping

ANSIBLE-PLAYBOOK COMMANDS ansible-playbook ansible-playbook playbook-webserver.yaml

Para comprobar que la sintaxis del playbook esta bien escrita: link-comprobar-sintaxis

En caso de no tener git , podemos usar ‘remote-sync’ de gitea , en visual studio code se utiliza ‘Remote Development’

Desde el explorador remoto , podremos conectar a otras maquinas virtuales y editar los ficheros con visual studio code , remotamente.

DEMO2 - List of all modules list-of-all-modules Module-Copy

touch /tmp/test-file.txt
---
- name: Copy files to target servers
  hosts: all
  tasks:
    - name: Copy file
      copy:
        src: /tmp/test-file.txt
        dest: /tmp/test-file.txt
ansible-playbook playbook-copyfile.yaml -i inventory.txt

Modules

Los módulos son acciones a realizarse y pueden clasificarse en:

Ejemplo command Module(command modules)

---
- name: Play 1
  hosts: localhost
  tasks:
   - name: Execute command ‘date’
     command: date

   - name: Display resolv.conf contents
     command: cat /etc/ resolv.conf

   - name: Display resolv.conf contents
     command: cat resolv.confchdir =/etc

   - name: Display resolv.conf contents
     command: mkdir/folder creates=/folder

   - name: Copy file from source to destination
     copy: src=/source_file dest=/destination

Ejemplo script Module(command modules)

---
- name: Play 1
  hosts: localhost
  tasks:
   - name: Run a script on remote server
     script: /some/local/script.sh -arg1 -arg2

Ejemplo service Module(system modules)

---
- name: Start Services in order
  hosts: localhost
  tasks:
   - name: Start the database service
     service: name= postgresql state=started

   - name: Start the httpd service
     service: name=httpd state=started

   - name: Start the nginx service
     service:
       name: nginx
       state: started
---
- name: Start Services in order
  hosts: localhost
  tasks:
   - name: Start the database service
     service:
      name: postgresql
      state: started

Ejemplo lineinfile Module(files modules)

#Sample script
echo “nameserver 10.1.250.10” >> /etc/resolv.conf
---
- name: Add DNS server to resolv.conf
  hosts: localhost
  tasks:
   - lineinfile:
        path: /etc/resolv.conf
        line: 'nameserver 10.1.250.10'

Variables

Las variables sirven para guardar datos y usarlos. Para usar variables , podemos declara variables en playbooks y usarlas en alguna tasks , las variables para usarlas , se declaran con ‘’ , ejemplo:

---
- name: Add DNS server to resolv.conf
  hosts: localhost
  vars:
    dns_server : 10.1.250.10
  tasks:
      - lineinfile:
          path: /etc/resolv.conf
          line: 'nameserver '

También , podemos usar ficheros que solo contengan variables:

#Sample variable File
variable1: value1
variable2: value2

Ejemplo ficheros variables:

---
- name: Set Firewall Configurations
  hosts: web
  tasks:
  - firewalld :
      service: https
      permanent: true
      state: enabled

  - firewalld :
      port: ''/tcp
      permanent: true
      state: disabled

  - firewalld :
      port: ''/udp
      permanent: true
      state: disabled

  - firewalld :
      source: ''/24
      Zone: internal
      state: enabled
#Sample Inventory File
Web http_port= snmp_port= inter_ip_range=
#Sample variable File - web.yml
http_port: 8081
snmp_port: 161-162
inter_ip_range: 192.0.2.0

Conditionals

Ejemplo uso condiciones en playbook. Tenemos 2 playbooks , los cuales usan 2 modulos distintos para instalar paquetes, en este caso nginx , en una maquina debian y otra redhat.

---
- name: Install NGINX
  hosts: debian_hosts
  tasks:
  - name: Install NGINX on Debian
    apt:
      name: nginx
      state: present
---
- name: Install NGINX
  hosts: redhat_hosts
  tasks:
  - name: Install NGINX on Redhat
    yum:
      name: nginx
      state: present

Condicional when

Podemos usar el condicional ‘when’ para que solo se ejecute en maquinas cuando sea cierto , cuando el sistema operativo sea debian o redhat en todas las maquinas. Ansible_os_family , es una variable interna de ansible que obtiene la familia de os.

---
- name: Install NGINX
  hosts:
  tasks:
  - name: Install NGINX on Debian
    apt:
      name: nginx
      state: present
    when: ansible_os_family == 'Debian'

  - name: Install NGINX on Redhat
    yum:
      name: nginx
      state: present
    when: ansible_os_family == 'RedHat'

Operador or

Podemos usar tambien , la condición ‘or’. En este caso se instalar el paquete cuando sea redhat o suse:

---
- name: Install NGINX
  hosts:
  tasks:
  - name: Install NGINX on Debian
    apt:
      name: nginx
      state: present
    when: ansible_os_family == 'Debian'

  - name: Install NGINX on Redhat
    yum:
      name: nginx
      state: present
    when: ansible_os_family == 'RedHat' or
          ansible_os_family == 'SUSE'

Operador and

Otro operador es ‘and’ , podemos usar ‘and’ , cuando queremos que se cumplan 2 condiciones para ejecutar lo deseado. Por ejemplo , solo cuando sea debian y tambien sea 16.04 , solo se ejecutara en ese caso:

---
- name: Install NGINX
  hosts:
  tasks:
  - name: Install NGINX on Debian
    apt:
      name: nginx
      state: present
    when: ansible_os_family == 'Debian'  and
          ansible_distribution_version == '16.04'

  - name: Install NGINX on Redhat
    yum:
      name: nginx
      state: present
    when: ansible_os_family == 'RedHat' or
          ansible_os_family == 'SUSE'

Condicionales con loops

Es posible usar condicionales con loops , por ejemplo , solo se instalaran aquellos que esten en ‘true’:

Tambien podemos añadir un condicional when a la tarea tasks , para que solo se ejecute cuando sea true, en loop.

---
- name: Install Softwares
  hosts:
  vars:
     packages:
        - name: nginx
          required: True
        - name: mysql
          required: True
        - name: apache
          required: False
  tasks:
  - name: Install "" on Debian
    apt:
      name: ""
      state: present

    when: item.required == True

    loop: ""

Condicionales y registros

Revisa el estado del servicio , guarda en ‘register’ una variable llamada ‘result’ con el estado de la tarea(salida del comando se guarda en result) , y enviá email si esta caído(si hace un find de down y NO obtiene -1 , es por que esta caido y down si que lo ha encontrado , de otra forma , si encuentra down , entonces notifica , en caso de no encontrar down , entonces el resultado es -1).

---
- name: Check status of a service and email if its down
  hosts: localhost
  tasks:
    - command: service httpd status
      register: result

    - mail:
       to: admin@company.com
       subject: Service Alert
       body: Httpd Service is down

       when: result.stdout.find('down') != -1

Loops

Los loops sirven para repetir tareas. Por ejemplo si tenemos que crear usuarios con el modulo user , podemos correr muchas veces el mismo modulo:

---
- name: Create users
  hosts: localhost
  tasks:
   - user: name= " { { item } } " state=present
   - user: name=george state=present
   - user: name=ravi state=present
   - user: name=mani state=present
   - user: name=kiran state=present
   - user: name=jazlan state=present
   - user: name=emaan state=present
   - user: name=mazin state=present
   - user: name=izaan state=present
   - user: name=mike state=present
   - user: name=menaal state=present
   - user: name=shoeb state=present
   - user: name=rani state=present

También , podemos organizar de otra manera , repitiendo la tarea con un ‘loop’(la ejecución se podria visualizar tarea derecha):

---
- name: Create users
  hosts: localhost
  tasks:
   - user: name= " { { item } } " state=present
     loop:
       - joe
       - george
       - ravi
       - mani
       - kiran
       - jazlan
       - emaan
       - mazin
       - izaan
       - mike
       - menaal
       - shoeb
       - rani
---
- name: Create users
  hosts: localhost
  tasks:

  - var: item=joe
    user: name= “” state=present
  - var: item=george
    user: name= “” state=present
  - var: item=ravi
    user: name= “” state=present
  - var: item=mani
    user: name= “” state=present
  - var: item=kiran
    user: name= “” state=present
  - var: item=jazlan
    user: name= “” state=present
  - var: item=emaan
    user: name= “” state=present
  - var: item=mazin
    user: name= “” state=present
  - var: item=izaan
    user: name= “” state=present

En caso de querer pasar 2 valores , se podrían pasar de la siguiente forma(derecha forma visual):

---
- name: Create users
  hosts: localhost
  tasks:
   - user: name=‘’ state=present uid=''
     loop:
       - name: joe    - { name: joe, uid: 1010 }
         uid: 1010
       - name: george - { name: george, uid: 1011 }
         uid: 1011
       - name: ravi   - { name: ravi, uid: 1012 }
         uid: 1012
       - name: mani   - { name: mani, uid: 1013 }
         uid: 1013
       - name: kiran  - { name: kiran, uid: 1014 }
         uid: 1014
       - name: jazlan - { name: jazlan, uid: 1015 }
         uid: 1015
       - name: emaan  - { name: emaan, uid: 1016 }
         uid: 1016
       - name: mazin  - { name: mazin, uid: 1017 }
         uid: 1017
       - name: izaan  - { name: izaan, uid: 1018 }
         uid: 1018
       - name: mike   - { name: mike, uid: 1019 }
         uid: 1019

Antes de existir ‘loops’ , se usaba ‘with_*’. Ejemplo:

---
- name: Create users
  hosts: localhost
  tasks:
   - user: name='' state=present
     with_items:
       - joe
       - george
       - ravi
       - mani
---
- name: Create users
  hosts: localhost
  tasks:
   - user: name='' state=present
     loop:
       - joe
       - george
       - ravi
       - mani

Ejemplos:

---
- name: Create users
  hosts: localhost
  tasks:
   - user: name='' state=present
     with_items:
       - joe
       - george
       - ravi
       - mani
---
- name: View Config FIles
  hosts: localhost
  tasks:
   - debug: var=item
     with_file:
       - "/etc/hosts"
       - "/etc/resolv.conf"
       - "/etc/ntp.conf"
---
- name: Get from multiple URLs
  hosts: localhost
  tasks:
   - debug: var=item
     with_url:
       - "https://site1.com/get-servers"
       - "https://site2.com/get-servers"
       - "https://site3.com/get-servers""
---
- name: Check multiple mongodbs
  hosts: localhost
  tasks:
   - debug: msg="DB= PID="
     with_mongodb:
       - database: dev
         connection_string: "mongodb://dev.mongo/"
       - database: prod
         connection_string: "mongodb://prod.mongo/"

Otros plugins para usar con ‘with_*’:

with_items
with_file
with_url
with_mongodb

with_dict
with_etcd
with_env
with_filetree
With_ini
With_inventory_hostnames
With_k8s
With_manifold
With_nested
With_nios
With_openshift
With_password
With_pipe
With_rabbitmq

With_redis
With_sequence
With_skydive
With_subelements
With_template
With_together
With_varnames

Roles

Roles en ansible. En automatización , un rol significa hacer todo lo que es necesario para cumplir las tareas de ese rol. Por ejemplo , cumplir un rol de base de datos , seria instalar y configurar toda una base de datos. Tareas muy comunes , se puede crear un playbook:

bash```

El playbook que hemos creado , se puede usar para instalar tareas de ese mismo playbook.

De forma que , un playbook , lo usamos como rol , en otro playbook para hacer esas tareas:

bash```


Advanced topics



ZipyintheNet¡