Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Ова е транскриптот настапи на DevOps-40 2020:

Почнувајќи од вториот commit, секој код станува наследство, бидејќи првичните идеи почнуваат да се оддалечуваат од суровата реалност. Ова не е ниту добро, ниту лошо, тоа е дадено со кое тешко се расправа и мора да се живее. Дел од овој процес е рефакторирање. Рефакторирање на инфраструктурата како код. Нека започне приказната за тоа како да се рефакторира Ансибл за една година и да не полудите.

Раѓањето на наследството

Ден # 1: Пациент нула

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Некогаш имаше условен проект. Имаше тим за развој на Dev и инженери на Ops. Тие го решаваа истиот проблем: како да распоредите сервери и да стартувате апликација. Проблемот беше што секој тим го реши овој проблем на свој начин. На проектот, беше одлучено да се користи Ansible за синхронизирање на знаењето помеѓу тимовите Dev и Ops.

Ден #89: Раѓањето на наследството

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Без да забележат самите, сакаа да го направат тоа што е можно подобро, но се покажа како наследство. Како се случува ова?

  • Имаме итна задача овде, ајде да направиме валкано хакирање и потоа да го поправиме.
  • Не треба да пишувате документација и сè е јасно што се случува овде.
  • Знам Ansible/Python/Bash/Terraform! Погледнете како можам да избегам!
  • Јас сум развивач на Full Stack Overflow и го копирав ова од stackoverflow, не знам како функционира, но изгледа кул и го решава проблемот.

Како резултат на тоа, можете да добиете неразбирлив тип на код за кој нема документација, не е јасно што прави, дали е потребен, но проблемот е што треба да го развиете, да го измените, да додадете патерици и потпори , што ја влошува ситуацијата уште повеќе.

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

Ден #109: Свесност за проблемот

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Првично замислениот и имплементиран IaC модел повеќе не ги задоволува барањата на корисниците / бизнисот / другите тимови и времето за правење промени во инфраструктурата престанува да биде прифатливо. Во овој момент доаѓа до разбирање дека е време да се преземе акција.

IaC рефакторирање

Ден #139: Дали навистина ви треба рефакторирање?

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Пред да брзате со рефактор, мора да одговорите на голем број важни прашања:

  1. Зошто ви треба сето ова?
  2. Имаш ли време?
  3. Дали знаењето е доволно?

Ако не знаете како да одговорите на прашањата, тогаш рефакторирањето ќе заврши уште пред да започне, или може само да се влоши. Бидејќи имав искуство ( Што научив од тестирањето на 200 линии на инфраструктурен код), потоа проектот доби барање за помош за да се поправат улогите и да се покријат со тестови.

Ден #149: Подготовка на рефакторирање

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Првото нешто е да се подготвите. Одлучете што ќе правиме. За да го направите ова, ние комуницираме, наоѓаме проблематични области и наоѓаме начини да ги решиме. Добиените концепти ги снимаме некако, на пример статија во спојување, така што кога ќе се постави прашањето „што е најдобро?“ или "што е точно?" Не сме го изгубиле патот. Во нашиот случај, останавме на идејата раздели па владеј: ја распаѓаме инфраструктурата на мали парчиња/тули. Овој пристап ви овозможува да земете изолиран дел од инфраструктурата, да разберете што прави, да го покриете со тестови и да го промените без страв дека нешто ќе скршите.

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Излегува дека инфраструктурното тестирање станува камен-темелник и тука вреди да се спомене пирамидата за тестирање на инфраструктурата. Точно истата идеја што е во развој, но за инфраструктурата: преминуваме од евтини брзи тестови кои проверуваат едноставни работи, како што е вдлабнувањето, кон скапи полноправни тестови кои ја распоредуваат целата инфраструктура.

Разумни обиди за тестирање

Пред да одиме да опишеме како ги покривавме Ansible тестовите на проектот, ќе ги опишам обидите и пристапите што имав можност да ги користам порано за да го разберам контекстот на донесените одлуки.

Ден бр. -997: Одредба на СДС

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Првиот пат кога го тестирав Ansible беше на проект за развој на SDS (Software Defined Storage). Постои посебна статија на оваа тема
Како да ги кршите велосипедите преку патерици кога ја тестирате вашата дистрибуција, но накратко, завршивме со превртена пирамида за тестирање и тестирање потрошивме 60-90 минути на една улога, што е долго време. Основата беа тестовите e2e, т.е. распоредивме полноправна инсталација и потоа ја тестиравме. Она што беше уште поотежнувачки е измислувањето на сопствениот велосипед. Но, морам да признаам, ова решение функционираше и овозможи стабилно ослободување.

Ден # -701: Подготвена и тест кујна

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Развојот на идејата за тестирање на Ansible беше употребата на готови алатки, имено тест кујна / кујна-ци и инспекција. Изборот беше одреден од познавањето на Руби (за повеќе детали, видете ја статијата на Хабре: Дали YML програмерите сонуваат да го тестираат Ansible?) работеше побрзо, околу 40 минути за 10 улоги. Создадовме пакет виртуелни машини и извршивме тестови внатре.

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Во принцип, решението функционираше, но имаше одреден талог поради хетерогеноста. Кога бројот на тестираните луѓе се зголеми на 13 основни улоги и 2 мета улоги комбинирајќи помали улоги, тогаш одеднаш тестовите почнаа да траат 70 минути, што е речиси 2 пати подолго. Беше тешко да се зборува за XP (екстремно програмирање) практики бидејќи ... никој не сака да чека 70 минути. Ова беше причината за промена на пристапот

Ден # -601: Ансибилна и молекула

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Концептуално, ова е слично на тест-кујната, само што го префрливме тестирањето на улоги во docker и го сменивме стекот. Како резултат на тоа, времето беше намалено на стабилни 20-25 минути за 7 улоги.

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Со зголемување на бројот на тестирани улоги на 17 и со обложување на 45 улоги, го извршивме ова за 28 минути на 2 џенкинс робови.

Ден #167: Додавање Ansible тестови на проектот

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Најверојатно, нема да биде можно да се изврши задачата за рефакторирање набрзина. Задачата мора да биде мерлива за да можете да ја скршите на мали парчиња и да го јадете слонот парче по парче со лажичка. Мора да има разбирање дали се движите во вистинската насока, колку долго да одите.

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Во принцип, не е важно како ќе се направи, можете да пишувате на парче хартија, можете да ставите налепници на плакарот, можете да креирате задачи во Jira или можете да отворите Google Docs и да го запишете моменталниот статус таму. Нозете растат од фактот дека процесот не е моментален, ќе биде долг и досаден. Малку е веројатно дека некој сака да изгорите од идеи, да се изморите и да се преоптоварите за време на рефакторирањето.

Рефакторирањето е едноставно:

  • Јадете.
  • Спие.
  • Код.
  • IaC тест.
  • Повторете

и тоа го повторуваме додека не ја достигнеме зацртаната цел.

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Можеби нема да биде возможно веднаш да започнеме со тестирање на сè, па нашата прва задача беше да започнеме со лакирање и проверка на синтаксата.

Ден #181: Мајстор за зелена градба

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Linting е мал прв чекор кон Green Build Master. Ова нема да скрши речиси ништо, но ќе ви овозможи да ги дебагирате процесите и да направите зелени градби во Џенкинс. Идејата е да се развијат навики меѓу тимот:

  • Црвените тестови се лоши.
  • Дојдов да поправам нешто и во исто време да го направам кодот малку подобар отколку што беше пред вас.

Ден # 193: Од лајнинг до единечни тестови

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Откако ќе го изградите процесот на внесување на кодот во мастерот, можете да го започнете процесот на чекор-по-чекор подобрување - заменувајќи ја влакненцата со улоги за стартување, можете дури и да го направите без идепотенција. Треба да разберете како да ги применувате улогите и како тие функционираат.

Ден #211: Од единица до тестови за интеграција

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Кога повеќето улоги се покриени со единечни тестови и сè е обложено, можете да продолжите со додавање тестови за интеграција. Оние. не тестирајќи ниту една тула во инфраструктурата, туку комбинација од нив, на пример, целосна конфигурација на примерок.

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Користејќи џенкинс, генериравме многу фази кои паралелно ги исцртуваа улогите/тетратките, потоа единечните тестови во контејнери и на крајот тестовите за интеграција.

Џенкинс + Докер + Ансибл = Тестови

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

  1. Проверете го репото и генерирајте фази на изградба.
  2. Паралелно стартувајте ги фазите на плејбук со линт.
  3. Паралелно направете ги фазите на улогата на влакненца.
  4. Паралелно извршувајте ги фазите на улоги за проверка на синтаксата.
  5. Паралелно извршете ги фазите на тест-улоги.
    1. Линт улога.
    2. Проверете ја зависноста од други улоги.
    3. Проверете ја синтаксата.
    4. Креирајте примерок на докер
    5. Стартувај molecule/default/playbook.yml.
    6. Проверете ја идемотенцијата.
  6. Извршете тестови за интеграција
  7. Заврши

Ден #271: Автобуски фактор

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Во почетокот, рефакторирањето го вршеше мала група од две или три лица. Тие го прегледаа кодот во мајсторот. Со текот на времето, тимот разви знаење за тоа како да се пишува код и преглед на кодови придонесе за ширење на знаењето за инфраструктурата и како таа функционира. Врвот овде беше што рецензентите беа избрани еден по еден, според распоред, т.е. со одреден степен на веројатност ќе се качите во ново парче инфраструктура.

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

И тука треба да биде удобно. Удобно е да се направи преглед, да се види во рамките на која задача е направена и историјата на дискусиите. Имаме интегрирано jenkins + bitbucket + jira.

Но, како таков, прегледот не е лек; некако, влеговме во главниот код, што нè натера да тестираме флоп:

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

Потоа го поправале, но талогот останал.

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

Ден #311: Забрзување на тестовите

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Со текот на времето, имаше повеќе тестови, градбите работеа побавно, до еден час во најлош случај. На едно од ретрото имаше фраза како „добро е што има тестови, но тие се бавни“. Како резултат на тоа, ги напуштивме тестовите за интеграција на виртуелните машини и ги приспособивме за Docker да го направи побрз. Ние, исто така, го заменивме testinfra со ансибилен проверувач за да го намалиме бројот на користени алатки.

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Строго кажано, имаше збир на мерки:

  1. Префрлете се на докер.
  2. Отстранете го тестирањето за улоги, кое е дуплирано поради зависности.
  3. Зголемете го бројот на робови.
  4. Редоследот за тестирање.
  5. Способност за влакненца СИТЕ локално со една команда.

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Како резултат на тоа, гасоводот на џенкинс исто така беше обединет

  1. Генерирајте фази на градење.
  2. Линт сите паралелно.
  3. Паралелно извршете ги фазите на тест-улоги.
  4. Заврши.

Научени лекции

Избегнувајте глобални променливи

Ansible користи глобални променливи, постои делумен заобиколување во формата приватни_улоги, но ова не е лек.

Дозволете ми да ви дадам пример. Дозволете ни да имаме 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}}

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Смешното е што резултатот од книгите за игра ќе зависи од работи кои не се секогаш очигледни, како што е редоследот по кој се наведени улогите. За жал, таква е природата на Ansible и најдоброто нешто што може да се направи е да се користи некој вид на договор, на пример, во рамките на улогата, да се користи само променливата опишана во оваа улога.

BAD: користете глобална променлива.

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

ДОБРО: ВО defaults дефинирајте ги потребните променливи и подоцна користете само нив.

# 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

Променливи за улоги на префикс

BAD: користете глобална променлива.

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

ДОБРО: Во улогите за променливи, користете променливи со префикс со името на улогата; ова, со гледање на инвентарот, ќе го олесни разбирањето што се случува.

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

Користете ја променливата за контрола на јамката

BAD: Користете стандардна променлива во јамките item, ако оваа задача/игротека е вклучена некаде, тоа може да доведе до неочекувано однесување

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

ДОБРО: Редефинирајте променлива во јамка преку loop_var.

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

Проверете ги влезните променливи

Се согласивме да користиме префикси на променливи; не би било излишно да провериме дали тие се дефинирани како што очекуваме и, на пример, не се отфрлени со празна вредност

ДОБРО: Проверете ги променливите.

- 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

Избегнувајте речници со хеш, користете рамна структура

Ако улогата очекува хаш/речник во еден од неговите параметри, тогаш ако сакаме да промениме еден од параметрите за деца, ќе треба да го замениме целиот хаш/речник, што ќе ја зголеми сложеноста на конфигурацијата.

BAD: Користете хаш/речник.

---
user:
  name: admin
  group: admin

ДОБРО: Користете рамна променлива структура.

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

Создадете идемпотентни книги и улоги

Улогите и играчките мора да бидат немоќни, затоа што го намалува поместувањето на конфигурацијата и стравот да не се скрши нешто. Но, ако користите молекула, тогаш ова е стандардното однесување.

Избегнувајте користење на модули на командната школка

Користењето на модул на школка резултира со императивна парадигма за опис, наместо декларативна, која е јадрото на Ansible.

Тестирајте ги вашите улоги преку молекула

Молекулата е многу флексибилна работа, ајде да погледнеме неколку сценарија.

Молекула Повеќекратни случаи

В molecule.yml во делот platforms можете да опишете многу хостови што можете да ги распоредите.

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

Соодветно на тоа, овие домаќини тогаш може да бидат converge.yml користи:

---
- 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 за да се провери дали примерокот е правилно конфигуриран, згора на тоа, ова е стандардно од објавувањето 3. Не е толку флексибилен како testinfra/inspec, но можеме да провериме дали содржината на датотеката одговара на нашите очекувања:

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

Или распоредете ја услугата, почекајте да стане достапна и направете тест за чад:

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

Ставете сложена логика во модулите и приклучоците

Ansible се залага за декларативен пристап, па кога правите разгранување на код, трансформација на податоци, модули на школка, кодот станува тежок за читање. За да се борите против ова и да го одржите едноставно за разбирање, не би било излишно да се борите против оваа сложеност со создавање на свои модули.

Сумирајте совети и трикови

  1. Избегнувајте глобални променливи.
  2. Променливи за улоги на префикс.
  3. Користете ја променливата за контрола на јамката.
  4. Проверете ги влезните променливи.
  5. Избегнувајте речници со хеш, користете рамна структура.
  6. Создадете идемпотентни книги и улоги.
  7. Избегнувајте користење на модули на командната школка.
  8. Тестирајте ги вашите улоги преку молекула.
  9. Ставете сложена логика во модулите и приклучоците.

Заклучок

Како да започнете со тестирање на Ansible, рефакторирајте го проектот за една година и да не полудите

Не можете едноставно да одите и да ја рефакторирате инфраструктурата на некој проект, дури и ако имате IaC. Ова е долг процес кој бара трпение, време и знаење.

UPD1 2020.05.01 20:30 — За примарно профилирање на игротеки што можете да ги користите callback_whitelist = profile_tasks да се разбере што точно функционира долго време. Потоа поминуваме Класици за неподносливо забрзување. Можете исто така да се обидете митоген
UPD2 2020.05.03 16:34 - англиска верзија

Извор: www.habr.com

Додадете коментар