Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Jen la transskribo prezentoj sur DevOps-40 2020-03-18:

Komencante de la dua komit, ajna kodo fariĝas heredaĵo, ĉar komencaj ideoj komencas deturni de severa realeco. Ĉi tio estas nek bona nek malbona, ĝi estas donitaĵo kun kiu estas malfacile disputebla kaj kun kiu oni devas vivi. Parto de ĉi tiu procezo estas refactoring. Refactoring Infrastructure kiel Kodo. Komencu la rakonton pri kiel refaktorigi Ansible en unu jaro kaj ne freneziĝi.

La Naskiĝo de Heredaĵo

Tago #1: Paciento Nulo

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Iam estis kondiĉa projekto. Ĝi havis Dev-evoluan teamon kaj Ops-inĝenierojn. Ili solvis la saman problemon: kiel disfaldi servilojn kaj ruli aplikaĵon. La problemo estis, ke ĉiu teamo solvis ĉi tiun problemon laŭ sia maniero. Ĉe la projekto, estis decidite uzi Ansible por sinkronigi scion inter la Dev kaj Ops-teamoj.

Tago #89: La Naskiĝo de Heredaĵo

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Sen rimarki ĝin mem, ili volis fari ĝin kiel eble plej bone, sed ĝi montriĝis heredaĵo. Kiel tio okazas?

  • Ni havas urĝan taskon ĉi tie, ni faru malpuran hakon kaj poste riparu ĝin.
  • Vi ne devas skribi dokumentadon kaj ĉio estas klara, kio okazas ĉi tie.
  • Mi konas Ansible/Python/Bash/Terraform! Rigardu, kiel mi povas eviti!
  • Mi estas Full Stack Overflow Developer kaj kopiis ĉi tion de stackoverflow, mi ne scias kiel ĝi funkcias, sed ĝi aspektas bonega kaj solvas la problemon.

Kiel rezulto, vi povas akiri nekompreneblan tipon de kodo, por kiu ne ekzistas dokumentado, ne estas klare, kion ĝi faras, ĉu ĝi bezonas, sed la problemo estas, ke vi devas disvolvi ĝin, modifi ĝin, aldoni lambastonojn kaj subtenojn. , igante la situacion eĉ pli malbona.

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

Tago #109: Konscio pri la problemo

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

La komence konceptita kaj efektivigita IaC-modelo ne plu plenumas la postulojn de uzantoj/komercaj/aliaj teamoj, kaj la tempo por fari ŝanĝojn al la infrastrukturo ĉesas esti akceptebla. En ĉi tiu momento, venas la kompreno, ke estas tempo ekagi.

IaC refactoring

Tago #139: Ĉu vi vere bezonas refaktorigon?

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Antaŭ ol vi rapidu refaktori, vi devas respondi kelkajn gravajn demandojn:

  1. Kial vi bezonas ĉion ĉi?
  2. Ĉu vi havas tempon?
  3. Ĉu scio sufiĉas?

Se vi ne scias kiel respondi la demandojn, tiam la refaktorado finiĝos antaŭ ol ĝi eĉ komenciĝos, aŭ ĝi eble nur plimalboniĝos. Ĉar havis sperton ( Kion mi Lernis el Testado de 200 Linioj de Infrastruktura Kodo), tiam la projekto ricevis peton pri helpo por ripari la rolojn kaj kovri ilin per testoj.

Tago #149: Preparante la refaktorigon

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

La unua afero estas prepari. Decidu kion ni faros. Por fari tion, ni komunikas, trovas problemajn areojn kaj eltrovas manierojn solvi ilin. Ni registras la rezultajn konceptojn iel, ekzemple artikolon en kunfluo, tiel ke kiam la demando ekestas "kio estas plej bona?" aŭ "kio estas ĝusta?" Ni ne perdis la vojon. En nia kazo, ni restis al la ideo dividu kaj regu: ni disigas la infrastrukturon en malgrandajn pecojn/brikojn. Ĉi tiu aliro permesas al vi preni izolitan infrastrukturon, kompreni kion ĝi faras, kovri ĝin per testoj kaj ŝanĝi ĝin sen timo rompi ion ajn.

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Rezultas, ke infrastruktura testado fariĝas la bazŝtono kaj ĉi tie indas mencii la infrastrukturan testan piramidon. Ĝuste la sama ideo, kiu estas en disvolviĝo, sed por infrastrukturo: ni transiras de malmultekostaj rapidaj testoj, kiuj kontrolas simplajn aferojn, kiel indentaĵon, al multekostaj plenrajtaj testoj, kiuj deplojas la tutan infrastrukturon.

Ansible provaj provoj

Antaŭ ol ni priskribi kiel ni kovris Ansible-testojn pri la projekto, mi priskribos la provojn kaj alirojn, kiujn mi havis la ŝancon uzi pli frue por kompreni la kuntekston de la decidoj faritaj.

Tago n-ro -997: SDS-provizo

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

La unua fojo, kiam mi testis Ansible, estis projekto por evoluigi SDS (Software Defined Storage). Estas aparta artikolo pri ĉi tiu temo
Kiel rompi biciklojn super lambastonoj dum testado de via distribuo, sed mallonge, ni finis kun inversa testa piramido kaj testado ni pasigis 60-90 minutojn en unu rolo, kio estas longa tempo. La bazo estis e2e-testoj, t.e. ni deplojis plenrajtan instalaĵon kaj poste testis ĝin. Kio eĉ pli malbonigis estis la invento de sia propra biciklo. Sed mi devas konfesi, ĉi tiu solvo funkciis kaj permesis stabilan liberigon.

Tago # -701: Ansible kaj prova kuirejo

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

La evoluo de la Ansible-testideo estis la uzo de pretaj iloj, nome testa kuirejo / kuirejo-ci kaj inspec. La elekto estis determinita de scio pri Ruby (por pli da detaloj, vidu la artikolon pri Habré: Ĉu YML-programistoj revas testi Ansible?) funkciis pli rapide, ĉirkaŭ 40 minutojn por 10 roloj. Ni kreis pakon da virtualaj maŝinoj kaj faris testojn interne.

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Ĝenerale, la solvo funkciis, sed estis iom da sedimento pro heterogeneco. Kiam la nombro de testitaj homoj pliiĝis al 13 bazaj roloj kaj 2 metaroloj kombinantaj pli malgrandajn rolojn, tiam subite la testoj ekfunkciis dum 70 minutoj, kio estas preskaŭ 2 fojojn pli longaj. Estis malfacile paroli pri XP (ekstrema programado) praktikoj ĉar... neniu volas atendi 70 minutojn. Ĉi tio estis la kialo por ŝanĝi la aliron

Tago # -601: Ansible kaj molekulo

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Koncipe, ĉi tio similas al testkitchen, nur ni movis roltestadon al docker kaj ŝanĝis la stakon. Kiel rezulto, la tempo estis reduktita al stabilaj 20-25 minutoj por 7 roloj.

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Pliigante la nombron da testitaj roloj al 17 kaj lintigante 45 rolojn, ni prizorgis ĉi tion en 28 minutoj sur 2 jenkinsklavoj.

Tago #167: Aldono de Ansible-testoj al la projekto

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Plej verŝajne, ne eblos fari la refaktorigan taskon haste. La tasko devas esti mezurebla, por ke vi povu rompi ĝin en malgrandajn pecojn kaj manĝi la elefanton pecon post peco per kulereto. Devas esti kompreno ĉu vi moviĝas en la ĝusta direkto, kiom longe iri.

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Ĝenerale, ne gravas kiel ĝi estos farita, vi povas skribi sur papero, vi povas meti glumarkojn sur la ŝranko, vi povas krei taskojn en Jira, aŭ vi povas malfermi Google Docs kaj noti la nunan staton. tie. La kruroj kreskas pro tio, ke la procezo ne estas tuja, ĝi estos longa kaj teda. Estas neverŝajne, ke iu volas, ke vi elbruliĝu de ideoj, laciĝu kaj superfortiĝu dum refactorado.

La refaktorado estas simpla:

  • Manĝi.
  • Dormi
  • Kodo.
  • IaC-testo.
  • Ripeti

kaj ni ripetas ĉi tion ĝis ni atingos la celitan celon.

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Eble ne eblas tuj komenci provi ĉion, do nia unua tasko estis komenci per linting kaj kontrolado de la sintakso.

Tago #181: Verda Konstruo Majstro

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Linting estas malgranda unua paŝo al Green Build Master. Ĉi tio ne rompos preskaŭ ion ajn, sed ĝi permesos al vi sencimigi procezojn kaj fari verdajn konstruojn en Jenkins. La ideo estas evoluigi kutimojn inter la teamo:

  • Ruĝaj provoj estas malbonaj.
  • Mi venis por ripari ion kaj samtempe fari la kodon iom pli bona ol ĝi estis antaŭ vi.

Tago #193: De linting ĝis unuotestoj

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Konstruinte la procezon enigi la kodon en la majstron, vi povas komenci la procezon de paŝo-post-paŝa plibonigo - anstataŭigi linting per lanĉaj roloj, vi povas eĉ fari ĝin sen idempotenco. Vi devas kompreni kiel apliki rolojn kaj kiel ili funkcias.

Tago #211: De unuo ĝis integrigaj testoj

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Kiam la plej multaj roloj estas kovritaj per unuotestoj kaj ĉio estas ligita, vi povas pluiri al aldoni integrigajn testojn. Tiuj. provante ne ununuran brikon en la infrastrukturo, sed kombinaĵon de ili, ekzemple, plenan instancon agordon.

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Uzante jenkins, ni generis multajn stadiojn, kiuj ligis rolojn/ludlibrojn paralele, poste unutestojn en ujoj, kaj finfine integrigajn testojn.

Jenkins + Docker + Ansible = Testoj

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

  1. Kontrolu repo kaj generu konstruajn etaĝojn.
  2. Kuru lint-ludajn etaĝojn paralele.
  3. Kuru lint-rolstadiojn paralele.
  4. Ruli sintaksajn kontrolajn rolstadiojn paralele.
  5. Kuru testajn rolajn stadiojn paralele.
    1. Lint rolo.
    2. Kontrolu dependecon de aliaj roloj.
    3. Kontrolu sintakson.
    4. Kreu docker-instancon
    5. Rulu molecule/default/playbook.yml.
    6. Kontrolu idempotencon.
  6. Rulu integriĝajn testojn
  7. finpoluro

Tago #271: Bus-Faktoro

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Komence, refaktorado estis farita fare de grupeto de du aŭ tri homoj. Ili reviziis la kodon en la majstro. Kun la tempo, la teamo evoluigis scion pri kiel skribi kodon kaj koda revizio kontribuis al la disvastigo de scio pri la infrastrukturo kaj kiel ĝi funkcias. La kulminaĵo ĉi tie estis, ke la recenzistoj estis elektitaj unu post la alia, laŭ horaro, t.e. kun certa grado de probableco vi grimpos en novan pecon de infrastrukturo.

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Kaj ĝi devus esti komforta ĉi tie. Estas oportune fari recenzon, vidi en la kadro de kia tasko ĝi estis farita, kaj la historion de diskutoj. Ni integris jenkins + bitbucket + jira.

Sed kiel tia, recenzo ne estas panaceo; iel, ni eniris la majstran kodon, kiu faris al ni malsukcesajn provojn:

- 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 }}"

Tiam ili fiksis ĝin, sed la restaĵo restis.

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 }}"

Tago #311: Akceli testojn

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Kun la tempo, estis pli da testoj, konstruoj kuris pli malrapide, ĝis horo en la plej malbona kazo. Sur unu el la retros estis frazo kiel "estas bone, ke estas testoj, sed ili estas malrapidaj." Kiel rezulto, ni forlasis integrigajn testojn sur virtualaj maŝinoj kaj adaptis ilin por Docker por fari ĝin pli rapida. Ni ankaŭ anstataŭigis testinfra per ansible kontrolilo por redukti la nombron da uzataj iloj.

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Strikte parolante, estis aro da mezuroj:

  1. Ŝanĝu al docker.
  2. Forigu roltestadon, kiu estas duobligita pro dependecoj.
  3. Pliigu la nombron da sklavoj.
  4. Prova kurado ordo.
  5. Kapablo peli ĈIUJ loke kun unu komando.

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Kiel rezulto, Pipeline sur jenkins ankaŭ estis unuigita

  1. Generu konstruajn etaĝojn.
  2. Lint ĉio paralele.
  3. Kuru testajn rolajn stadiojn paralele.
  4. Fini.

Lecionoj lernitaj

Evitu tutmondajn variablojn

Ansible uzas tutmondajn variablojn, ekzistas parta solvo en la formo private_role_vars, sed ĉi tio ne estas panaceo.

Mi donu al vi ekzemplon. Ni havu 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}}

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

La amuza afero estas, ke la rezulto de ludlibroj dependos de aferoj, kiuj ne ĉiam estas evidentaj, kiel la ordo en kiu roloj estas listigitaj. Bedaŭrinde, ĉi tio estas la naturo de Ansible kaj la plej bona afero farebla estas uzi ian interkonsenton, ekzemple, ene de rolo, uzu nur la variablon priskribitan en ĉi tiu rolo.

BAD: uzu tutmondan variablon.

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

BONA: V defaults difini la necesajn variablojn kaj poste uzi nur ilin.

# 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

Prefiksaj rolvariabloj

BAD: uzu tutmondan variablon.

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

BONA: En roloj por variabloj, uzu variablojn antaŭfiksitajn kun la rolnomo; ĉi tio, rigardante inventaron, faciligos kompreni kio okazas.

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

Uzu cirkla kontrolo variablo

BAD: Uzu norman variablon en bukloj item, se ĉi tiu tasko/ludlibro estas inkluzivita ie, tio povas konduki al neatendita konduto

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

BONA: Redifini variablon en buklo per loop_var.

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

Kontrolu enigajn variablojn

Ni konsentis uzi variajn prefiksojn; ne estus superflue kontroli, ke ili estas difinitaj kiel ni atendas kaj, ekzemple, ne anstataŭitaj de malplena valoro.

BONA: Kontrolu variablojn.

- 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

Evitu hashvortarojn, uzu platan strukturon

Se rolo atendas hash/vortaron en unu el siaj parametroj, tiam se ni volas ŝanĝi unu el la infanaj parametroj, ni devos superregi la tutan hash/vortaron, kio pliigos agordan kompleksecon.

BAD: Uzu haŝiŝon/vortaron.

---
user:
  name: admin
  group: admin

BONA: Uzu platan varian strukturon.

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

Krei idempotentajn ludlibrojn kaj rolojn

Roloj kaj ludlibroj devas esti idempotentaj, ĉar reduktas agordon kaj timon rompi ion. Sed se vi uzas molekulon, tiam ĉi tiu estas la defaŭlta konduto.

Evitu uzi komandŝelajn modulojn

Uzado de ŝelmodulo rezultas en imperativa priskriba paradigmo, anstataŭ la deklara, kiu estas la kerno de Ansible.

Testu viajn rolojn per molekulo

Molekulo estas tre fleksebla afero, ni rigardu kelkajn scenarojn.

Molekulo Multoblaj okazoj

В molecule.yml en sekcio platforms vi povas priskribi multajn gastigantojn, kiujn vi povas disfaldi.

---
    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

Sekve, ĉi tiuj gastigantoj povas tiam esti converge.yml uzi:

---
- 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

Ansible kontrolilo

En molekulo eblas uzi ansible por kontroli, ke la petskribo estis agordita ĝuste, krome, ĉi tio estas la defaŭlta ekde la eldono 3. Ĝi ne estas tiel fleksebla kiel testinfra/inspec, sed ni povas kontroli, ke la enhavo de la dosiero kongruas kun niaj atendoj:

---
- 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

Aŭ disfaldi la servon, atendu, ke ĝi fariĝos disponebla kaj faru fumteston:

---
  - 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

Metu kompleksan logikon en modulojn kaj kromaĵojn

Ansible rekomendas deklaran aliron, do kiam vi faras kodbranĉigon, datumtransformon, ŝelmodulojn, la kodo fariĝas malfacile legebla. Por batali ĉi tion kaj teni ĝin simple komprenebla, ne estus superflue batali ĉi tiun kompleksecon kreante viajn proprajn modulojn.

Resumu Konsiletojn kaj Trukojn

  1. Evitu tutmondajn variablojn.
  2. Prefiksaj rolvariabloj.
  3. Uzu cirkla kontrolo variablo.
  4. Kontrolu enigajn variablojn.
  5. Evitu hashvortarojn, uzu platan strukturon.
  6. Krei idempotentajn ludlibrojn kaj rolojn.
  7. Evitu uzi komandŝelajn modulojn.
  8. Testu viajn rolojn per molekulo.
  9. Metu kompleksan logikon en modulojn kaj kromaĵojn.

konkludo

Kiel komenci testi Ansible, refactorigi la projekton post jaro kaj ne freneziĝi

Vi ne povas simple iri kaj refaktori la infrastrukturon en projekto, eĉ se vi havas IaC. Ĉi tio estas longa procezo postulanta paciencon, tempon kaj scion.

UPD1 2020.05.01 20:30 — Por ĉefa profilado de ludlibroj vi povas uzi callback_whitelist = profile_tasks por kompreni kio ekzakte funkcias dum longa tempo. Tiam ni trairu Ansible-akcelaj klasikaĵoj. Vi ankaŭ povas provi mitogeno
UPD2 2020.05.03 16:34 - Esperanta versio

fonto: www.habr.com

Aldoni komenton