Parentah: kumaha carana nguji peran ansible sarta manggihan masalah saméméh produksi

Hello dulur!

Abdi damel salaku insinyur DevOps pikeun jasa booking hotél. Ostrovok.ru. Dina artikel ieu, abdi hoyong ngobrol ngeunaan pangalaman urang dina nguji peran ansible.

Di Ostrovok.ru kami nganggo ansible salaku manajer konfigurasi. Anyar-anyar ieu, urang kedah nguji peran, tapi sakumaha tétéla, teu aya seueur alat pikeun ieu - anu paling populér, sigana, nyaéta kerangka Molekul, ku kituna urang mutuskeun pikeun ngagunakeunana. Tapi tétéla yén dokuméntasi na jempé ngeunaan loba pitfalls. Kami henteu mendakan manual anu cukup lengkep dina basa Rusia, janten kami mutuskeun nyerat tulisan ieu.

Parentah: kumaha carana nguji peran ansible sarta manggihan masalah saméméh produksi

Molekul

Molekul - kerangka pikeun mantuan nguji peran ansible.

Katerangan saderhana: Molekul nyiptakeun conto dina platform anu anjeun setel (awan, mesin virtual, wadahna; pikeun langkung rinci, tingali bagian nu nyetir), ngajalankeun peran anjeun dina éta, teras ngajalankeun tés sareng ngahapus conto. Upami aya kagagalan dina salah sahiji léngkah, Molekul bakal ngabéjaan anjeun ngeunaan éta.

Ayeuna langkung.

Bit téori

Hayu urang nganggap dua éntitas konci Molekul: Skenario sareng Supir.

Skenario

Naskah ngandung pedaran ngeunaan naon, dimana, kumaha jeung dina urutan naon anu bakal dilakukeun. Hiji peran tiasa gaduh sababaraha naskah, sareng masing-masing mangrupikeun diréktori sapanjang jalur <role>/molecule/<scenario>, anu ngandung déskripsi ngeunaan tindakan anu diperyogikeun pikeun tés. Skrip kudu kaasup default, nu bakal otomatis dijieun mun anjeun initialize peran maké Molecule. Ngaran-ngaran naskah di handap ieu terserah anjeun.

Runtuyan tindakan nguji dina naskah disebut matrix, sareng sacara standar sapertos kieu:

(Léngkah-léngkah dilabélan ?, skipped sacara standar lamun teu dieusian ku pamaké)

  • lint - ngajalankeun linters. Sacara standar dipaké yamllint и flake8,
  • destroy - mupus instansi tina peluncuran Molekul anu terakhir (upami aya),
  • dependency? - pamasangan katergantungan ansible tina peran anu diuji,
  • syntax - mariksa sintaksis peran ngagunakeun ansible-playbook --syntax-check,
  • create - nyieun conto,
  • prepare? - persiapan conto; misalna pariksa / install python2
  • converge - peluncuran playbook anu diuji,
  • idempotence - balikan deui playbook pikeun uji idempotensi,
  • side_effect? - tindakan anu henteu langsung aya hubunganana sareng peran, tapi dipikabutuh pikeun tés,
  • verify - ngajalankeun tés tina konfigurasi hasilna ngagunakeun testinfra(standar) /goss/inspec,
  • cleanup? - (dina versi anyar) - kasarna nyarios, "ngabersihkeun" infrastruktur éksternal anu kapangaruhan ku Molekul,
  • destroy - Ngahapus hiji conto.

Sekuen ieu nyertakeun kalolobaan kasus, tapi tiasa dirobih upami diperyogikeun.

Unggal léngkah di luhur tiasa dijalankeun nyalira molecule <command>. Tapi anjeun kedah ngartos yén pikeun tiap paréntah cli sapertos kitu meureun aya urutan tindakan sorangan, anu anjeun tiasa terang ku ngajalankeun. molecule matrix <command>. Contona, nalika ngajalankeun paréntah converge (ngajalankeun playbook dina tés), tindakan di handap ieu bakal dilakukeun:

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

Runtuyan lampah ieu bisa diédit. Lamun hiji hal tina daptar geus rengse, eta bakal skipped. Kaayaan ayeuna, kitu ogé konfigurasi instansi, Molekul disimpen dina diréktori $TMPDIR/molecule/<role>/<scenario>.

Tambahkeun léngkah kalawan ? Anjeun tiasa ngajelaskeun tindakan anu dipikahoyong dina format playbook Ansible, sareng ngadamel nami file dumasar kana léngkah: prepare.yml/side_effect.yml. Nyangka file Molekul ieu aya dina folder skrip.

nu nyetir

Supir mangrupikeun éntitas dimana instansi pikeun tés diciptakeun.
Daptar supir standar anu Molekul ngagaduhan témplat siap nyaéta kieu: Azure, Docker, EC2, GCE, LXC, LXD, OpenStack, Vagrant, Delegated.

Dina kalolobaan kasus, témplat nyaéta file create.yml и destroy.yml dina folder skrip, anu ngajelaskeun nyiptakeun sareng ngahapus conto masing-masing.
Pangecualian nyaéta Docker sareng Vagrant, sabab interaksi sareng modulna tiasa lumangsung tanpa file di luhur.

Perlu nyorot supir Delegated, sabab upami dianggo dina file pikeun nyiptakeun sareng ngahapus conto, ngan ukur tiasa dianggo sareng konfigurasi instansi anu dijelaskeun, sésana kedah dijelaskeun ku insinyur.

Supir standar nyaéta Docker.

Ayeuna hayu urang teraskeun latihan sareng pertimbangkeun fitur salajengna di dinya.

Ngalalanyahan

Salaku "halo dunya", hayu urang nguji peran instalasi nginx basajan. Hayu urang milih docker salaku supir - Jigana kalolobaan anjeun parantos dipasang (sareng émut yén docker mangrupikeun supir standar).

Nyiapkeun virtualenv tur masang di dinya molecule:

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

Lengkah saterusna nyaéta pikeun ngamimitian peran anyar.
Initialization tina peran anyar, kitu ogé skrip anyar, dipigawé maké paréntah 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

hasilna mangrupa peran ansible has. Salajengna, sadaya interaksi sareng Molekul CLI didamel tina akar peran.

Hayu urang tingali naon anu aya dina diréktori peran:

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

1 directory, 6 files

Hayu urang analisa config molecule/default/molecule.yml (ganti ngan gambar docker):

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

gumantungna

Bagian ieu ngajelaskeun sumber kagumantungan.

Pilihan anu mungkin: galaksi, sepuh, cangkang.

Shell ngan saukur cangkang paréntah pikeun dianggo upami galaksi sareng gilt henteu nutupan kabutuhan anjeun.

Kuring moal cicing di dieu pikeun lila, éta cukup dijelaskeun dina dokuméntasi.

nu nyetir

Ngaran supir. Urang docker.

linen

Yamllint dianggo salaku linter.

Pilihan anu gunana dina bagian ieu konfigurasi nyaéta kamampuan pikeun netepkeun file konfigurasi pikeun yamllint, variabel lingkungan maju, atanapi nganonaktipkeun linter:

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

platform

Ngajelaskeun konfigurasi tina instansi.
Dina kasus Docker salaku supir, Molekul ngulang dina bagian ieu, sareng unggal unsur daptar sayogi di Dockerfile.j2 salaku variabel item.

Dina kasus supir anu merlukeun create.yml и destroy.yml, bagian nu sadia di antarana salaku molecule_yml.platforms, sareng iterasi dina éta parantos dijelaskeun dina file ieu.

Kusabab Molekul nyadiakeun kadali instansi ka modul ansible, daptar setelan mungkin ogé kudu néangan aya. Pikeun docker, contona, modul dipaké docker_container_module. Modul mana anu dianggo dina supir sanés tiasa dipendakan di dokuméntasi.

Kitu ogé conto pamakéan rupa drivers bisa kapanggih dina tés Molekul sorangan.

Ganti di dieu centos:7 dina Ubuntu.

panyadia

"Supplier" - hiji éntitas nu ngatur instansi. Dina kasus Molekul, ieu ansible, rojongan pikeun batur teu rencanana, jadi bagian ieu bisa disebut ansible ngalegaan konfigurasi kalawan caveat a.
Aya seueur anu anjeun tiasa nunjukkeun di dieu, tapi kuring bakal nyorot poin utama, dina pendapat kuring:

  • buku kaulinan: Anjeun bisa nangtukeun mana playbooks kudu dipake dina tahapan nu tangtu.

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

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

  • pilihan: Parameter ansible sareng variabel lingkungan

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

skenario

Judul jeung pedaran runtuyan naskah.
Anjeun tiasa ngarobih matriks tindakan standar tina paréntah naon waé ku cara nambihan konci <command>_sequence sareng salaku nilai pikeun éta ku netepkeun daptar léngkah anu urang peryogikeun.
Anggap urang hoyong ngarobih sekuen tindakan nalika ngajalankeun paréntah playbook run: molecule converge

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

cek

Nyetél kerangka pikeun tés sareng linter pikeun éta. Sacara standar, linter dianggo testinfra и flake8. Pilihan anu mungkin sami sareng di luhur:

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

Hayu urang balik deui ka peran urang. Hayu urang ngédit file tasks/main.yml kana jenis ieu:

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

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

Sareng tambahkeun tés kana 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")

Réngsé, éta ngan ukur ngajalankeun (tina akar peran, hayu atuh ngingetkeun anjeun):

> molecule test

knalpot panjang handapeun spoiler:

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

Peran basajan urang diuji tanpa masalah.
Eta sia remembering yén lamun aya masalah salila gawé molecule test, teras upami anjeun henteu ngarobih sekuen standar, Molekul bakal ngahapus conto.

Paréntah di handap ieu mangpaat pikeun debugging:

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

Peran anu aya

Nambahkeun naskah anyar kana peran anu aya nyaéta ti diréktori peran kalayan paréntah di handap ieu:

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

Bisi ieu skenario kahiji dina peran, lajeng parameter -s bisa dileungitkeun sabab bakal nyieun naskah default.

kacindekan

Sakumaha anjeun tiasa tingali, Molekul henteu rumit pisan, sareng ku ngagunakeun témplat anjeun nyalira, nyebarkeun skrip énggal tiasa dikirangan pikeun ngédit variabel dina nyiptakeun conto sareng ngahapus playbooks. Molekul ngahiji sacara lancar sareng sistem CI, anu ngamungkinkeun anjeun ningkatkeun laju pangwangunan ku cara ngirangan waktos pikeun nguji manual playbooks.

Nuhun kana perhatosanana. Upami Anjeun gaduh pangalaman dina nguji peran ansible, sarta teu patali jeung Molekul, ngabejaan urang ngeunaan eta dina komentar!

sumber: www.habr.com

Tambahkeun komentar