Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Aquesta és la transcripció actuacions en DevOps-40 2020-03-18:

A partir del segon commit, qualsevol codi es converteix en llegat, perquè les idees inicials comencen a divergir de la dura realitat. Això no és ni bo ni dolent, és un fet difícil de discutir i amb el qual s'ha de viure. Part d'aquest procés és la refactorització. Refactorització de la infraestructura com a codi. Que comenci la història sobre com refactoritzar Ansible en un any i no tornar-se boig.

El naixement del llegat

Dia #1: Pacient Zero

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Hi havia una vegada un projecte condicional. Tenia un equip de desenvolupament de desenvolupament i enginyers d'operacions. Estaven resolent el mateix problema: com desplegar servidors i executar una aplicació. El problema era que cada equip resolia aquest problema a la seva manera. En el projecte, es va decidir utilitzar Ansible per sincronitzar el coneixement entre els equips de desenvolupament i operacions.

Dia #89: El naixement del llegat

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Sense adonar-se'n ells mateixos, van voler fer-ho de la millor manera possible, però va resultar llegat. Com passa això?

  • Tenim una tasca urgent aquí, fem un pirateig brut i després arreglem-ho.
  • No cal escriure documentació i tot està clar què passa aquí.
  • Conec Ansible/Python/Bash/Terraform! Mira com puc esquivar!
  • Sóc un desenvolupador de Full Stack Overflow i ho vaig copiar de stackoverflow, no sé com funciona, però sembla genial i resol el problema.

Com a resultat, pots aconseguir un tipus de codi incomprensible del qual no hi ha documentació, no està clar què fa, si és necessari, però el problema és que cal desenvolupar-lo, modificar-lo, afegir crosses i suports. , empitjorant encara més la situació.

- hosts: localhost
  tasks:
    - shell: echo -n Z >> a.txt && cat a.txt
      register: output
      delay: 1
      retries: 5
      until: not output.stdout.find("ZZZ")

Dia #109: Consciència del problema

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

El model IaC concebut i implementat inicialment ja no compleix els requisits dels usuaris/empresa/altres equips, i el temps per fer canvis a la infraestructura deixa de ser acceptable. En aquest moment, s'entén que és hora d'actuar.

Refactorització de IaC

Dia #139: realment necessites refactorització?

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Abans d'apressar-vos a refactoritzar, heu de respondre una sèrie de preguntes importants:

  1. Per què necessites tot això?
  2. Tens temps?
  3. És suficient el coneixement?

Si no sabeu com respondre a les preguntes, aleshores la refactorització s'acabarà abans que comenci, o potser només empitjorarà. Perquè tenia experiència ( Què he après provant 200 línies de codi d'infraestructura), aleshores el projecte va rebre una sol·licitud d'ajuda per solucionar els rols i cobrir-los amb proves.

Dia #149: Preparant la refactorització

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

El primer és preparar. Decidiu què farem. Per fer-ho, ens comuniquem, busquem àrees problemàtiques i busquem maneres de resoldre'ls. Enregistrem els conceptes resultants d'alguna manera, per exemple un article en confluència, de manera que quan sorgeixi la pregunta "què és el millor?" o "Quin és correcte?" No hem perdut el camí. En el nostre cas, vam seguir la idea divideix i governa: dividim la infraestructura en petits trossos/maons. Aquest enfocament permet agafar una peça aïllada d'infraestructura, entendre què fa, cobrir-la amb proves i canviar-la sense por de trencar res.

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Resulta que les proves d'infraestructura es converteixen en la pedra angular i aquí val la pena esmentar la piràmide de proves d'infraestructures. Exactament la mateixa idea que està en desenvolupament, però per a la infraestructura: estem passant de proves ràpides barates que comproven coses senzilles, com ara el sagnat, a proves cares i completes que despleguen tota la infraestructura.

Intents de prova Ansible

Abans d'anar a descriure com vam cobrir les proves d'Ansible al projecte, descriuré els intents i els enfocaments que vaig tenir l'oportunitat d'utilitzar anteriorment per entendre el context de les decisions preses.

Dia núm. -997: subministrament SDS

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

La primera vegada que vaig provar Ansible va ser en un projecte per desenvolupar SDS (Software Defined Storage). Hi ha un article separat sobre aquest tema
Com trencar bicicletes amb crosses en provar la distribució, però en resum, vam acabar amb una piràmide de proves invertida i vam passar entre 60 i 90 minuts en un paper, que és molt de temps. La base eren les proves e2e, és a dir. vam desplegar una instal·lació completa i després la vam provar. El que va ser encara més agreujant va ser la invenció de la seva pròpia bicicleta. Però he d'admetre que aquesta solució va funcionar i va permetre un llançament estable.

Dia # -701: Ansible i cuina de prova

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

El desenvolupament de la idea de proves Ansible va ser l'ús d'eines ja fetes, és a dir, prova cuina / cuina-ci i inspecció. L'elecció va ser determinada pel coneixement de Ruby (per a més detalls, vegeu l'article sobre Habré: Els programadors YML somien amb provar Ansible?) va funcionar més ràpid, uns 40 minuts per a 10 papers. Vam crear un paquet de màquines virtuals i vam fer proves dins.

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

En general, la solució va funcionar, però hi havia una mica de sediment per heterogeneïtat. Quan el nombre de persones provades es va augmentar a 13 rols bàsics i 2 rols meta combinant rols més petits, de sobte les proves van començar a executar-se durant 70 minuts, que és gairebé 2 vegades més llarg. Era difícil parlar de pràctiques de XP (programació extrema) perquè... ningú vol esperar 70 minuts. Aquest va ser el motiu del canvi d'enfocament

Dia # -601: Ansible i molècula

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Conceptualment, això és similar a testkitchen, només que vam traslladar les proves de rol a Docker i vam canviar la pila. Com a resultat, el temps es va reduir a uns 20-25 minuts estables per a 7 rols.

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

En augmentar el nombre de rols provats a 17 i amb 45 rols, ho vam executar en 28 minuts amb 2 esclaus Jenkins.

Dia #167: Afegint proves Ansible al projecte

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Molt probablement, no serà possible fer la tasca de refactorització amb pressa. La tasca ha de ser mesurable perquè pugueu trencar-la en trossos petits i menjar l'elefant peça per peça amb una culleradeta. Hi ha d'haver una comprensió de si s'està movent en la direcció correcta, quant més temps queda per recórrer.

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

En general, no importa com es farà, pots escriure en un paper, pots posar adhesius a l'armari, pots crear tasques a Jira, o pots obrir Google Docs i anotar l'estat actual. allà. Les cames creixen pel fet que el procés no és immediat, serà llarg i tediós. És poc probable que algú vulgui que us esgoteu les idees, us canseu i us desbordeu durant la refactorització.

La refactorització és senzilla:

  • Menjar.
  • Somni.
  • Codi.
  • Prova IaC.
  • Repetir

i ho repetim fins a arribar a l'objectiu previst.

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

És possible que no sigui possible començar a provar-ho tot immediatament, de manera que la nostra primera tasca va ser començar amb llisting i comprovar la sintaxi.

Dia #181: Mestre de construcció verda

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Linting és un petit primer pas cap a Green Build Master. Això no trencarà gairebé res, però us permetrà depurar processos i fer construccions verdes a Jenkins. La idea és desenvolupar hàbits entre l'equip:

  • Les proves vermelles són dolentes.
  • Vaig venir a arreglar alguna cosa i, al mateix temps, fer el codi una mica millor del que era abans.

Dia #193: De la pelusa a les proves unitàries

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Després d'haver creat el procés d'incorporació del codi al mestre, podeu començar el procés de millora pas a pas: substituint el filting per rols de llançament, fins i tot podeu fer-ho sense idempotència. Cal entendre com aplicar els rols i com funcionen.

Dia #211: De les proves unitàries a les proves d'integració

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Quan la majoria de funcions es cobreixen amb proves unitàries i tot està enganxat, podeu passar a afegir proves d'integració. Aquells. provant no un sol maó a la infraestructura, sinó una combinació d'ells, per exemple, una configuració d'instància completa.

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Mitjançant jenkins, vam generar moltes etapes que enfilaven rols/playbooks en paral·lel, després proves unitàries en contenidors i, finalment, proves d'integració.

Jenkins + Docker + Ansible = Proves

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

  1. Fes un repo de compra i genera etapes de construcció.
  2. Executeu les etapes del llibre de pelusa en paral·lel.
  3. Executeu les etapes de rol de pelusa en paral·lel.
  4. Executeu les etapes del rol de comprovació de sintaxi en paral·lel.
  5. Executeu fases de rol de prova en paral·lel.
    1. Paper de pelusa.
    2. Comproveu la dependència d'altres rols.
    3. Comproveu la sintaxi.
    4. Crea una instància de Docker
    5. Executeu molecule/default/playbook.yml.
    6. Comproveu la idempotència.
  6. Executar proves d'integració
  7. Finish

Dia #271: Bus Factor

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Al principi, la refactorització la feia un petit grup de dues o tres persones. Van revisar el codi al màster. Amb el temps, l'equip va desenvolupar coneixements sobre com escriure codi i la revisió del codi va contribuir a la difusió del coneixement sobre la infraestructura i el seu funcionament. El més destacat aquí va ser que els revisors van ser seleccionats un per un, segons un calendari, és a dir. amb cert grau de probabilitat pujaràs a una nova peça d'infraestructura.

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

I aquí hauria de ser còmode. És convenient fer una revisió, veure en el marc de quina tasca es va fer i l'historial de les discussions. Hem integrat jenkins + bitbucket + jira.

Però, com a tal, una revisió no és una panacea, ens vam endinsar en el codi mestre, que ens va fer proves de fracàs:

- get_url:
    url: "{{ actk_certs }}/{{ item.1 }}"
    dest: "{{ actk_src_tmp }}/"
    username: "{{ actk_mvn_user }}"
    password: "{{ actk_mvn_pass }}"
  with_subelements:
    - "{{ actk_cert_list }}"
    - "{{ actk_certs }}"
  delegate_to: localhost

- copy:
    src: "{{ actk_src_tmp }}/{{ item.1 }}"
    dest: "{{ actk_dst_tmp }}"
  with_subelements:
    - "{{ actk_cert_list }}"
    - "{{ actk_certs }}"

Després ho van arreglar, però el sediment va quedar.

get_url:
    url: "{{ actk_certs }}/{{ actk_item }}"
    dest: "{{ actk_src_tmp }}/{{ actk_item }}"
    username: "{{ actk_mvn_user }}"
    password: "{{ actk_mvn_pass }}"
  loop_control:
    loop_var: actk_item
  with_items: "{{ actk_cert_list }}"
  delegate_to: localhost

- copy:
    src: "{{ actk_src_tmp }}/{{ actk_item }}"
    dest: "{{ actk_dst_tmp }}"
  loop_control:
    loop_var: actk_item
  with_items: "{{ actk_cert_list }}"

Dia #311: Acceleració de les proves

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Amb el temps, hi va haver més proves, les compilacions van anar més lenta, fins a una hora en el pitjor dels casos. En un dels retros hi havia una frase com "està bé que hi hagi proves, però són lentes". Com a resultat, vam abandonar les proves d'integració a les màquines virtuals i les vam adaptar a Docker perquè fos més ràpid. També hem substituït testinfra per un verificador ansible per reduir el nombre d'eines utilitzades.

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

En sentit estricte, hi havia un conjunt de mesures:

  1. Canvia a Docker.
  2. Elimineu la prova de rol, que es duplica a causa de les dependències.
  3. Augmentar el nombre d'esclaus.
  4. Ordre d'execució de prova.
  5. Capacitat de deixar pelusa TOTS localment amb una comanda.

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

Com a resultat, Pipeline on jenkins també es va unificar

  1. Generar etapes de construcció.
  2. Pelusa tot en paral·lel.
  3. Executeu fases de rol de prova en paral·lel.
  4. Finalitza.

Lliçons apreses

Eviteu les variables globals

Ansible utilitza variables globals, hi ha una solució parcial al formulari variables_de_rol_privades, però això no és una panacea.

Permeteu-me que us posi un exemple. Deixa'ns tenir role_a и role_b

# cat role_a/defaults/main.yml
---
msg: a

# cat role_a/tasks/main.yml
---
- debug:
    msg: role_a={{ msg }}

# cat role_b/defaults/main.yml
---
msg: b

# cat role_b/tasks/main.yml
---
- set_fact:
    msg: b
- debug:
    msg: role_b={{ msg }}

- hosts: localhost
  vars:
    msg: hello
  roles:
    - role: role_a
    - role: role_b
  tasks:
    - debug:
        msg: play={{msg}}

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

El més curiós és que el resultat dels playbooks dependrà de coses que no sempre són evidents, com ara l'ordre en què s'enumeren els papers. Malauradament, aquesta és la naturalesa d'Ansible i el millor que es pot fer és utilitzar algun tipus d'acord, per exemple, dins d'un rol, utilitzar només la variable descrita en aquest rol.

BAD: utilitza una variable global.

# cat roles/some_role/tasks/main.yml
---
debug:
  var: java_home

BONA: EN defaults definir les variables necessàries i després utilitzar-les només.

# cat roles/some_role/defaults/main.yml
---
r__java_home:
 "{{ java_home | default('/path') }}"

# cat roles/some_role/tasks/main.yml
---
debug:
  var: r__java_home

Prefixar variables de rol

BAD: utilitza una variable global.

# cat roles/some_role/defaults/main.yml
---
db_port: 5432

BONA: En els rols per a variables, utilitzeu variables amb el prefix del nom de la funció, això, mirant l'inventari, facilitarà la comprensió del que està passant.

# cat roles/some_role/defaults/main.yml
---
some_role__db_port: 5432

Utilitzeu la variable de control de bucle

BAD: Utilitzeu la variable estàndard en bucles item, si aquesta tasca o llibre de jocs s'inclou en algun lloc, això pot provocar un comportament inesperat

---
- hosts: localhost
  tasks:
    - debug:
        msg: "{{ item }}"
      loop:
        - item1
        - item2

BONA: Redefinir una variable en un bucle via loop_var.

---
- hosts: localhost
  tasks:
    - debug:
        msg: "{{ item_name }}"
      loop:
        - item1
        - item2
      loop_control:
        loop_var: item_name

Comproveu les variables d'entrada

Vam acceptar utilitzar prefixos variables no seria superflu comprovar que es defineixen com esperàvem i, per exemple, no s'han substituït per un valor buit;

BONA: Comprova les variables.

- name: "Verify that required string variables are defined"
  assert:
    that: ahs_var is defined and ahs_var | length > 0 and ahs_var != None
    fail_msg: "{{ ahs_var }} needs to be set for the role to work "
    success_msg: "Required variables {{ ahs_var }} is defined"
  loop_control:
    loop_var: ahs_var
  with_items:
    - ahs_item1
    - ahs_item2
    - ahs_item3

Eviteu els diccionaris de hashes, utilitzeu una estructura plana

Si un rol espera un hash/diccionari en un dels seus paràmetres, aleshores si volem canviar un dels paràmetres secundaris, haurem d'anul·lar tot el hash/diccionari, la qual cosa augmentarà la complexitat de la configuració.

BAD: Utilitzeu hash/diccionari.

---
user:
  name: admin
  group: admin

BONA: Utilitzeu una estructura variable plana.

---
user_name: admin
user_group: "{{ user_name }}"

Crea llibres de joc i rols idempotents

Els rols i els llibres de joc han de ser idempotents, perquè redueix la deriva de la configuració i la por a trencar alguna cosa. Però si utilitzeu molècula, aquest és el comportament predeterminat.

Eviteu utilitzar mòduls de l'intèrpret d'ordres

L'ús d'un mòdul d'intèrpret d'ordres dóna com a resultat un paradigma de descripció imperatiu, en lloc d'un de declaratiu, que és el nucli d'Ansible.

Posa a prova els teus rols mitjançant molècules

La molècula és una cosa molt flexible, mirem alguns escenaris.

Molècula Múltiples instàncies

В molecule.yml a la secció platforms podeu descriure molts amfitrions que podeu implementar.

---
    driver:
      name: docker
    platforms:
      - name: postgresql-instance
        hostname: postgresql-instance
        image: registry.example.com/postgres10:latest
        pre_build_image: true
        override_command: false
        network_mode: host
      - name: app-instance
        hostname: app-instance
        pre_build_image: true
        image: registry.example.com/docker_centos_ansible_tests
        network_mode: host

En conseqüència, aquests amfitrions poden ser-ho converge.yml utilitzar:

---
- name: Converge all
  hosts: all
  vars:
    ansible_user: root
  roles:
    - role: some_role

- name: Converge db
  hosts: db-instance
  roles:
    - role: some_db_role

- name: Converge app
  hosts: app-instance
  roles:
    - role: some_app_role

Verificador Ansible

A molecule és possible utilitzar ansible per comprovar que la instància s'ha configurat correctament, a més, aquesta és la predeterminada des de la versió 3. No és tan flexible com testinfra/inspec, però podem comprovar que el contingut del fitxer coincideix amb les nostres expectatives:

---
- name: Verify
  hosts: all
  tasks:
    - name: copy config
      copy:
        src: expected_standalone.conf
        dest: /root/wildfly/bin/standalone.conf
        mode: "0644"
        owner: root
        group: root
      register: config_copy_result

    - name: Certify that standalone.conf changed
      assert:
        that: not config_copy_result.changed

O implementeu el servei, espereu que estigui disponible i feu una prova de fum:

---
  - name: Verify
    hosts: solr
    tasks:
      - command: /blah/solr/bin/solr start -s /solr_home -p 8983 -force
      - uri:
          url: http://127.0.0.1:8983/solr
          method: GET
          status_code: 200
        register: uri_result
        until: uri_result is not failed
        retries: 12
        delay: 10
      - name: Post documents to solr
        command: /blah/solr/bin/post -c master /exampledocs/books.csv

Posa lògica complexa en mòduls i connectors

Ansible defensa un enfocament declaratiu, de manera que quan feu ramificacions de codi, transformació de dades, mòduls de shell, el codi es fa difícil de llegir. Per combatre-ho i mantenir-ho senzill d'entendre, no seria superflu combatre aquesta complexitat creant els vostres propis mòduls.

Resum de consells i trucs

  1. Eviteu les variables globals.
  2. Prefixar variables de rol.
  3. Utilitzeu la variable de control de bucle.
  4. Comproveu les variables d'entrada.
  5. Eviteu els diccionaris de hashes, utilitzeu una estructura plana.
  6. Crea llibres de joc i rols idempotents.
  7. Eviteu utilitzar mòduls de l'intèrpret d'ordres.
  8. Posa a prova els teus rols mitjançant molècules.
  9. Posa lògica complexa en mòduls i connectors.

Conclusió

Com començar a provar Ansible, refactoritzar el projecte en un any i no tornar-se boig

No podeu anar a refactoritzar la infraestructura en un projecte, encara que tingueu IaC. Aquest és un procés llarg que requereix paciència, temps i coneixement.

UPD1 2020.05.01/20/30 XNUMX:XNUMX — Per a la creació de perfils principals de llibres de jugades que podeu utilitzar callback_whitelist = profile_tasks per entendre què funciona exactament durant molt de temps. Després passem Clàssics de l'acceleració Ansible. També pots provar mitògen
UPD2 2020.05.03/16/34 XNUMX:XNUMX - versió en anglès

Font: www.habr.com

Compreu allotjament fiable per a llocs amb protecció DDoS, servidors VPS VDS 🔥 Compra allotjament web fiable amb protecció DDoS, servidors VPS VDS | ProHoster