Ko'rsatmalar: qanday qilib aniq rollarni sinab ko'rish va ishlab chiqarishdan oldin muammolarni aniqlash

Hammaga salom!

Men mehmonxonani bron qilish xizmatida DevOps muhandisi sifatida ishlayman. Ostrovok.ru. Ushbu maqolada men aniq rollarni sinab ko'rish tajribamiz haqida gapirmoqchiman.

Ostrovok.ru saytida biz konfiguratsiya menejeri sifatida ansible-dan foydalanamiz. Yaqinda biz rollarni sinab ko'rish zarurati tug'ildi, ammo ma'lum bo'lishicha, buning uchun juda ko'p vositalar mavjud emas - eng mashhuri, ehtimol, Molekulyar ramka, shuning uchun biz undan foydalanishga qaror qildik. Ammo ma'lum bo'lishicha, uning hujjatlari ko'plab tuzoqlar haqida sukut saqlamoqda. Biz rus tilida etarlicha batafsil qo'llanmani topa olmadik, shuning uchun biz ushbu maqolani yozishga qaror qildik.

Ko'rsatmalar: qanday qilib aniq rollarni sinab ko'rish va ishlab chiqarishdan oldin muammolarni aniqlash

Molekula

Molekula - aniq rollarni sinab ko'rishga yordam beradigan ramka.

Soddalashtirilgan tavsif: Molekula siz ko'rsatgan platformada namuna yaratadi (bulut, virtual mashina, konteyner; batafsil ma'lumot uchun bo'limga qarang. haydovchi), undagi rolingizni ishga tushiradi, so'ngra testlarni o'tkazadi va misolni o'chiradi. Bosqichlardan birida muvaffaqiyatsizlikka uchragan taqdirda, Molekula sizga bu haqda xabar beradi.

Endi ko'proq.

Bir oz nazariya

Molekulaning ikkita asosiy ob'ektini ko'rib chiqing: stsenariy va haydovchi.

Stsenariy

Skriptda nima, qaerda, qanday va qanday ketma-ketlikda bajarilishi tavsifi mavjud. Bitta rolda bir nechta skriptlar bo'lishi mumkin va ularning har biri yo'l bo'ylab katalogdir <role>/molecule/<scenario>, unda test uchun zarur bo'lgan harakatlarning tavsiflari mavjud. Skript kiritilishi kerak defaultRolni Molekula bilan ishga tushirsangiz, avtomatik ravishda yaratiladi. Quyidagi skriptlarning nomlari sizga bog'liq.

Skriptdagi sinov harakatlarining ketma-ketligi deyiladi Matritsa, va sukut bo'yicha u:

(Qadamlar belgilangan ?, agar foydalanuvchi tomonidan belgilanmagan bo'lsa, sukut bo'yicha o'tkazib yuborilgan)

  • lint - ishlaydigan linters. Odatiy bo'lib foydalaniladi yamllint и flake8,
  • destroy - Molekulaning so'nggi ishga tushirilishidan misollarni o'chirish (agar mavjud bo'lsa),
  • dependency? - sinovdan o'tgan rolning ishonchli bog'liqligini o'rnatish;
  • syntax - yordamida rol sintaksisini tekshirish ansible-playbook --syntax-check,
  • create - misol yaratish,
  • prepare? — namunani tayyorlash; masalan, python2 ni tekshiring/o'rnating
  • converge - sinovdan o'tkazilayotgan o'yin kitobini ishga tushirish;
  • idempotence - identifikatsiya testi uchun o'yin kitobini qayta ishga tushirish,
  • side_effect? - rolga bevosita bog'liq bo'lmagan, ammo testlar uchun zarur bo'lgan harakatlar;
  • verify - yordamida olingan konfiguratsiyani sinovdan o'tkazish testinfra(standart) /goss/inspec,
  • cleanup? - (yangi versiyalarda) - taxminan aytganda, Molekula ta'sir qiladigan tashqi infratuzilmani "tozalash",
  • destroy - Bir misolni o'chirish.

Ushbu ketma-ketlik ko'p holatlarni qamrab oladi, ammo kerak bo'lganda o'zgartirilishi mumkin.

Yuqoridagi qadamlarning har biri bilan alohida bajarilishi mumkin molecule <command>. Ammo shuni tushunish kerakki, har bir bunday cli-buyruq uchun o'ziga xos harakatlar ketma-ketligi bo'lishi mumkin, siz buni bajarish orqali bilib olishingiz mumkin. molecule matrix <command>. Masalan, buyruqni ishga tushirganda converge (test ostidagi o'yin kitobini ishga tushirish), quyidagi harakatlar amalga oshiriladi:

$ molecule matrix converge
...
└── default         # название сценария
    ├── dependency  # установка зависимостей
    ├── create      # создание инстанса
    ├── prepare     # преднастройка инстанса
    └── converge    # прогон плейбука

Ushbu harakatlar ketma-ketligini tahrirlash mumkin. Agar ro'yxatdagi biror narsa allaqachon bajarilgan bo'lsa, u o'tkazib yuboriladi. Joriy holat, shuningdek namunalar konfiguratsiyasi, Molekula katalogda saqlanadi $TMPDIR/molecule/<role>/<scenario>.

bilan qadamlar qo'shing ? siz kerakli harakatlarni ansible-playbook formatida tasvirlashingiz va fayl nomini bosqichga ko'ra qilishingiz mumkin: prepare.yml/side_effect.yml. Ushbu fayllarni kuting Molekula skript papkasida bo'ladi.

haydovchi

Haydovchi - bu sinov namunalari yaratiladigan ob'ekt.
Molecule shablonlari tayyor bo'lgan standart drayverlar ro'yxati quyidagicha: Azure, Docker, EC2, GCE, LXC, LXD, OpenStack, Vagrant, Delegated.

Aksariyat hollarda shablonlar fayllardir create.yml и destroy.yml mos ravishda namunani yaratish va o'chirishni tavsiflovchi skript papkasida.
Istisnolar Docker va Vagrant hisoblanadi, chunki ularning modullari bilan o'zaro aloqalar yuqorida aytib o'tilgan fayllarsiz sodir bo'lishi mumkin.

Delegatsiya qilingan drayverni ta'kidlash kerak, chunki agar u misol yaratish va o'chirish uchun fayllarda ishlatilsa, faqat misollar konfiguratsiyasi bilan ishlash tavsiflanadi, qolganini muhandis tasvirlab berishi kerak.

Standart drayver Docker hisoblanadi.

Keling, amaliyotga o'tamiz va u erda boshqa xususiyatlarni ko'rib chiqamiz.

Ishga kirishish

"Salom dunyo" sifatida oddiy nginx o'rnatish rolini sinab ko'raylik. Biz haydovchi sifatida dockerni tanlaymiz - menimcha, ko'pchiligingiz uni o'rnatgansiz (va docker standart drayver ekanligini unutmang).

Tayyor bo'ling virtualenv va unga o'rnating molecule:

> pip install virtualenv
> virtualenv -p `which python2` venv
> source venv/bin/activate
> pip install molecule docker  # molecule установит ansible как зависимость; docker для драйвера

Keyingi qadam yangi rolni ishga tushirishdir.
Yangi rolni, shuningdek, yangi skriptni ishga tushirish buyruq yordamida amalga oshiriladi molecule init <params>:

> molecule init role -r nginx
--> Initializing new role nginx...
Initialized role in <path>/nginx successfully.
> cd nginx
> tree -L 1
.
├── README.md
├── defaults
├── handlers
├── meta
├── molecule
├── tasks
└── vars

6 directories, 1 file

Bu odatiy rol bo'lib chiqdi. Bundan tashqari, CLI molekulalari bilan barcha o'zaro ta'sirlar rolning ildizidan amalga oshiriladi.

Keling, rollar katalogida nima borligini ko'rib chiqaylik:

> tree molecule/default/
molecule/default/
├── Dockerfile.j2  # Jinja-шаблон для Dockerfile
├── INSTALL.rst.   # Немного информации об установке зависимостей сценария
├── molecule.yml   # Файл конфигурации
├── playbook.yml   # Плейбук запуска роли
└── tests          # Директория с тестами стадии verify
    └── test_default.py

1 directory, 6 files

Keling, konfiguratsiyani tahlil qilaylik molecule/default/molecule.yml (faqat docker tasvirini almashtiring):

---
dependency:
  name: galaxy
driver:
  name: docker
lint:
  name: yamllint
platforms:
  - name: instance
    image: centos:7
provisioner:
  name: ansible
  lint:
    name: ansible-lint
scenario:
  name: default
verifier:
  name: testinfra
  lint:
    name: flake8

qaramlik

Ushbu bo'limda bog'liqliklar manbai tasvirlangan.

Tanlovlar: Galaxy, zar, qobiq.

Shell shunchaki buyruq qobig'i bo'lib, u galaxy va gilt sizning ehtiyojlaringizni qondira olmasa ishlatiladi.

Men bu erda uzoq vaqt turmayman, bu etarli darajada tasvirlangan hujjatlar.

haydovchi

Haydovchining ismi. Bizniki doker.

zig'ir

Linter - yallint.

Konfiguratsiyaning ushbu qismidagi foydali variantlar yamllint uchun konfiguratsiya faylini belgilash, atrof-muhit o'zgaruvchilarini yo'naltirish yoki linterni o'chirish qobiliyatidir:

lint:
  name: yamllint
  options:
    config-file: foo/bar
  env:
    FOO: bar
  enabled: False

Platformalar

Namunalarning konfiguratsiyasini tavsiflaydi.
Docker haydovchi sifatida bo'lsa, Molekula ushbu bo'limda takrorlanadi va ro'yxatning har bir elementi mavjud. Dockerfile.j2 o'zgaruvchi sifatida item.

Talab qiladigan haydovchi bo'lsa create.yml и destroy.yml, bo'lim ularda sifatida mavjud molecule_yml.platforms, va uning ustidagi takrorlashlar allaqachon ushbu fayllarda tasvirlangan.

Molekula mos modullarga misollarni boshqarishni ta'minlaganligi sababli, mumkin bo'lgan sozlamalar ro'yxatini ham u erda izlash kerak. Masalan, docker uchun modul ishlatiladi docker_container_module. Boshqa drayverlarda qaysi modullar qo'llanilishini topish mumkin hujjatlar.

Shuningdek, turli drayverlardan foydalanish misollarini topish mumkin Molekulaning o'zi sinovlarida.

Bu yerda almashtiring centos: 7 haqida Ubuntu.

provayder

"Yetkazib beruvchi" - misollarni boshqaradigan ob'ekt. Molekulaga kelsak, bu mumkin, boshqalarni qo'llab-quvvatlash rejalashtirilmagan, shuning uchun bu bo'limni ogohlantirish bilan kengaytirilgan konfiguratsiya deb atash mumkin.
Bu erda siz ko'p narsalarni belgilashingiz mumkin, men asosiy fikrlarni ta'kidlayman, menimcha:

  • o'yin kitoblari: muayyan bosqichlarda qaysi o'yin kitoblaridan foydalanish kerakligini belgilashingiz mumkin.

provisioner:
  name: ansible
  playbooks:
    create: create.yml
    destroy: ../default/destroy.yml
    converge: playbook.yml
    side_effect: side_effect.yml
    cleanup: cleanup.yml

provisioner:
  name: ansible
  config_options:
    defaults:
      fact_caching: jsonfile
    ssh_connection:
      scp_if_ssh: True

  • ulanish_opsiyalari: variantlar ulanish

provisioner:
  name: ansible  
  connection_options:
    ansible_ssh_common_args: "-o 'UserKnownHostsFile=/dev/null' -o 'ForwardAgent=yes'"

  • imkoniyatlari: Ansable variantlar va muhit o'zgaruvchilari

provisioner:
  name: ansible  
  options:
    vvv: true
    diff: true
  env:
    FOO: BAR

senariy

Skript ketma-ketliklarining nomi va tavsifi.
Kalitni qo'shish orqali har qanday buyruqning standart harakatlar matritsasini o'zgartirishingiz mumkin <command>_sequence va bizga kerak bo'lgan qadamlar ro'yxatini belgilash orqali uning qiymati sifatida.
Aytaylik, biz o'yin kitobini ishga tushirish buyrug'ini bajarayotganda harakatlar ketma-ketligini o'zgartirmoqchimiz: molecule converge

# изначально:
# - dependency
# - create
# - prepare
# - converge
scenario:
  name: default
  converge_sequence:
    - create
    - converge

nazorat

Sinovlar uchun ramka va unga linterni o'rnatish. Standart linter testinfra и flake8. Mumkin variantlar yuqoridagi bilan bir xil:

verifier:
  name: testinfra
  additional_files_or_dirs:
    - ../path/to/test_1.py
    - ../path/to/test_2.py
    - ../path/to/directory/*
  options:
    n: 1
  enabled: False
  env:
    FOO: bar
  lint:
    name: flake8
    options:
      benchmark: True
    enabled: False
    env:
      FOO: bar

Keling, rolimizga qaytaylik. Keling, faylni tahrir qilaylik tasks/main.yml bu turga:

---
- name: Install nginx
  apt:
    name: nginx
    state: present

- name: Start nginx
  service:
    name: nginx
    state: started

Va testlarni qo'shing molecule/default/tests/test_default.py

def test_nginx_is_installed(host):
    nginx = host.package("nginx")
    assert nginx.is_installed

def test_nginx_running_and_enabled(host):
    nginx = host.service("nginx")
    assert nginx.is_running
    assert nginx.is_enabled

def test_nginx_config(host):
    host.run("nginx -t")

Bajarildi, faqat yugurish qoladi (rolning ildizidan, sizga eslatib o'taman):

> molecule test

Spoyler ostida uzoq egzoz:

--> Validating schema <path>/nginx/molecule/default/molecule.yml.
Validation completed successfully.
--> Test matrix

└── default
    ├── lint
    ├── destroy
    ├── dependency
    ├── syntax
    ├── create
    ├── prepare
    ├── converge
    ├── idempotence
    ├── side_effect
    ├── verify
    └── destroy

--> Scenario: 'default'
--> Action: 'lint'
--> Executing Yamllint on files found in <path>/nginx/...
Lint completed successfully.
--> Executing Flake8 on files found in <path>/nginx/molecule/default/tests/...
Lint completed successfully.
--> Executing Ansible Lint on <path>/nginx/molecule/default/playbook.yml...
Lint completed successfully.
--> Scenario: 'default'
--> Action: 'destroy'

    PLAY [Destroy] *****************************************************************

    TASK [Destroy molecule instance(s)] ********************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Wait for instance(s) deletion to complete] *******************************
    ok: [localhost] => (item=None)
    ok: [localhost]

    TASK [Delete docker network(s)] ************************************************

    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0

--> Scenario: 'default'
--> Action: 'dependency'
Skipping, missing the requirements file.
--> Scenario: 'default'
--> Action: 'syntax'

    playbook: <path>/nginx/molecule/default/playbook.yml

--> Scenario: 'default'
--> Action: 'create'

    PLAY [Create] ******************************************************************

    TASK [Log into a Docker registry] **********************************************
    skipping: [localhost] => (item=None)

    TASK [Create Dockerfiles from image names] *************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Discover local Docker images] ********************************************
    ok: [localhost] => (item=None)
    ok: [localhost]

    TASK [Build an Ansible compatible image] ***************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Create docker network(s)] ************************************************

    TASK [Create molecule instance(s)] *********************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Wait for instance(s) creation to complete] *******************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    PLAY RECAP *********************************************************************
    localhost                  : ok=5    changed=4    unreachable=0    failed=0

--> Scenario: 'default'
--> Action: 'prepare'
Skipping, prepare playbook not configured.
--> Scenario: 'default'
--> Action: 'converge'

    PLAY [Converge] ****************************************************************

    TASK [Gathering Facts] *********************************************************
    ok: [instance]

    TASK [nginx : Install nginx] ***************************************************
    changed: [instance]

    TASK [nginx : Start nginx] *****************************************************
    changed: [instance]

    PLAY RECAP *********************************************************************
    instance                   : ok=3    changed=2    unreachable=0    failed=0

--> Scenario: 'default'
--> Action: 'idempotence'
Idempotence completed successfully.
--> Scenario: 'default'
--> Action: 'side_effect'
Skipping, side effect playbook not configured.
--> Scenario: 'default'
--> Action: 'verify'
--> Executing Testinfra tests found in <path>/nginx/molecule/default/tests/...
    ============================= test session starts ==============================
    platform darwin -- Python 2.7.15, pytest-4.3.0, py-1.8.0, pluggy-0.9.0
    rootdir: <path>/nginx/molecule/default, inifile:
    plugins: testinfra-1.16.0
collected 4 items

    tests/test_default.py ....                                               [100%]

    ========================== 4 passed in 27.23 seconds ===========================
Verifier completed successfully.
--> Scenario: 'default'
--> Action: 'destroy'

    PLAY [Destroy] *****************************************************************

    TASK [Destroy molecule instance(s)] ********************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Wait for instance(s) deletion to complete] *******************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Delete docker network(s)] ************************************************

    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=2    unreachable=0    failed=0

Bizning oddiy rolimiz muammosiz sinovdan o'tdi.
Shuni esda tutish kerakki, agar ish paytida muammolar mavjud bo'lsa molecule test, agar siz standart ketma-ketlikni o'zgartirmagan bo'lsangiz, Molekula misolni o'chirib tashlaydi.

Nosozliklarni tuzatish uchun quyidagi buyruqlar foydalidir:

> molecule --debug <command> # debug info. При обычном запуске Молекула скрывает логи.
> molecule converge          # Оставляет инстанс после прогона тестируемой роли.
> molecule login             # Зайти в созданный инстанс.
> molecule --help            # Полный список команд.

Mavjud rol

Mavjud rolga yangi skript qo'shish rollar katalogidan quyidagi buyruqlar bilan:

# полный список доступных параметров
> molecule init scenarion --help
# создание нового сценария
> molecule init scenario -r <role_name> -s <scenario_name>

Agar bu roldagi birinchi stsenariy bo'lsa, keyin parametr -s o'tkazib yuborilishi mumkin, chunki u skript yaratadi default.

xulosa

Ko'rib turganingizdek, molekula unchalik murakkab emas va o'zingizning shablonlaringizdan foydalanib, yangi skriptni o'rnatish misol yaratish va o'chirish kitoblarida o'zgaruvchilarni tahrirlashga qisqartirilishi mumkin. Molekula CI tizimlari bilan muammosiz birlashadi, bu sizga o'yin kitoblarini qo'lda tekshirish vaqtini qisqartirish orqali rivojlanish tezligini oshirishga imkon beradi.

E'tiboringiz uchun rahmat. Agar sizda aniq rollarni sinab ko'rish bo'yicha tajribangiz bo'lsa va u Molekula bilan bog'liq bo'lmasa, bu haqda bizga izohlarda aytib bering!

Manba: www.habr.com

a Izoh qo'shish