ансибле девопс цодестиле
Хеј! Моје име је Радим као инжењер у одељењу за аутоматизацију развојних процеса. Сваког дана се нове верзије апликација постављају на стотине сервера кампање. И у овом чланку делим своје искуство коришћења Ансибле-а у ове сврхе.
Овај водич нуди начин организовања варијабли у примени. Овај водич је намењен онима који већ користе улоге у својим играма и читају , али се суочава са сличним проблемима:
- Након што смо пронашли променљиву у коду, немогуће је одмах разумети за шта је она одговорна;
- Постоји неколико улога, а променљиве морају бити повезане са једном вредношћу, али то једноставно не функционише;
- Имате потешкоћа да објасните другима како функционише логика варијабли у вашим приручницима
Са овим проблемима смо се сусрели на пројектима у нашој компанији, услед чега смо дошли до правила за пројектовање варијабли у нашим плаибооковима, што је донекле решило ове проблеме.

Променљиве у улогама
Улога је посебан објекат система распоређивања. Као и сваки системски објекат, он мора имати интерфејс за интеракцију са остатком система. Такав интерфејс је променљива улога.
Узмимо, на пример, улогу api, који инсталира Јава апликацију на сервер. Које варијабле може имати?

Променљиве улоге се могу поделити у 2 типа према типу:
1. Свойства
a) независимые от среды
б) зависимые от среды
2. Связи
a) слушатели
б) запросы внутри системы
в) запросы в среду
Променљива својства су варијабле које одређују понашање улоге.
Куери Вариаблес - ово су варијабле чија се вредност користи за означавање ресурса ван улоге.
Променљиви слушаоци - ово су променљиве чија се вредност користи за формирање променљивих захтева.
С друге стране, 1а, 2а, 2б су променљиве које не зависе од окружења (хардвер, екстерни ресурси, итд.) и могу се попунити подразумеваним вредностима у улози подразумеваних вредности. Међутим, немогуће је попунити варијабле типа 1.б и 2.ц другим вредностима осим 'пример', пошто ће се оне мењати од постоља до постоља у зависности од окружења.
Стил кода
- Име променљиве мора да почиње именом улоге. Ово ће олакшати да се у будућности схвати из које је улоге променљива и за шта је одговорна.
- Када користите променљиве у улогама, морате бити сигурни да пратите принцип енкапсулације и користите променљиве дефинисане или у самој улози или у улогама од којих зависи тренутна.
Избегавајте коришћење речника за променљиве. Ансибле вам не дозвољава да једноставно замените појединачне вредности у речнику.
Пример лоше променљиве:
myrole_user: login: admin password: adminОвде је логин независна променљива, а лозинка је зависна варијабла. Али
пошто су комбиновани у речник, мораћете да га у потпуности наведете
Увек. Што је веома незгодно. Боље овако:myrole_user_login: admin myrole_user_password: admin
Променљиве у приручницима за примену
Приликом састављања приручника за имплементацију (у даљем тексту плаибоок), придржавамо се правила да га треба ставити у посебно спремиште. Исто као и улоге: свака у свом гит спремишту. Ово вам омогућава да схватите да су улоге и приручник различити независни објекти система за примену и да промене у једном објекту не би требало да утичу на рад другог. Ово се постиже променом подразумеваних вредности променљивих.
Приликом састављања плаибоок-а, да резимирамо, могуће је заобићи подразумеване вредности променљивих улога на два места: у варијаблама плаибоок-а и у променљивим инвентара.
mydeploy # Каталог деплоя
├── deploy.yml # Плейбук деплоя
├── group_vars # Каталог переменных плейбука
│ ├── all.yml # Файл для переменных связи всей системы
│ └── myapi.yml # Файл переменных свойств группы myapi
└── inventories #
└── prod # Каталог окружения prod
├── prod.ini # Инвентори файл
└── group_vars # Каталог для переменных инвентори
└── myapi #
├── vars.yml # Средозависимые переменные группы myapi
└── vault.yml # Секреты (всегда средозависимы) ** -
Разлика је у томе што се варијабле плаибоок увек користе када се позивају плаибоокс који се налазе на истом нивоу као и она. То значи да су ове варијабле одличне за промену подразумеваних вредности варијабли независних од окружења. Насупрот томе, варијабле инвентара ће се користити само за одређено окружење, што је идеално за варијабле специфичне за окружење.
Важно је напоменути да вам приоритет променљивих неће дозволити да пређете на променљиве прво у варијаблама из приручника, а затим одвојено у једном инвентару.
То значи да је већ у овој фази потребно одлучити да ли је варијабла зависна од средине или не и поставити је на одговарајуће место.
На пример, у једном пројекту, варијабла одговорна за омогућавање ССЛ-а је дуго зависила од окружења, пошто нисмо могли да омогућимо ССЛ из разлога ван наше контроле на једном од штандова. Након што смо решили овај проблем, постао је независан од окружења и прешао је на варијабле из књиге.
Променљиве својства за групе
Хајде да проширимо наш модел на слици 1 додавањем 2 групе сервера са другом Јава апликацијом, али са различитим подешавањима.

Замислимо како ће свеска изгледати у овом случају:
- hosts: myapi
roles:
- api
- hosts: bbauth
roles:
- auth
- hosts: ghauth
roles:
- authИмамо три групе у плаибоок-у, тако да се одмах препоручује да се креира исти број групних фајлова у променљивим инвентара гроуп_варс и варијаблама плаибоок-а. Једна групна датотека у овом случају је опис једне компоненте горње апликације у приручнику. Када отворите групну датотеку у варијаблама плаибоок-а, одмах видите све разлике у односу на подразумевано понашање улога инсталираних у групи. У варијаблама инвентара: разлике у понашању групе од штанда до штанда.
Цоде Стиле
- Покушајте да уопште не користите хост_варс променљиве, јер оне не описују систем, већ само посебан случај, што ће у будућности довести до питања: „Зашто се овај хост разликује од осталих?“, на који одговор није увек лако пронаћи.
Комуникационе варијабле
Међутим, то је оно о чему се ради о променљивим својствима, али шта је са комуникационим варијаблама?
Њихова разлика је у томе што би требало да имају исто значење у различитим групама.
У почетку је било користите монструозну конструкцију као што је:
hostvars[groups['bbauth'][0]]['auth_bind_port'], али су га одмах одбили
јер има недостатке. Прво, гломазност. Друго, зависност од одређеног домаћина у групи. Треће, пре почетка имплементације, потребно је прикупити чињенице са свих хостова ако не желимо да добијемо грешку недефинисане променљиве.
Као резултат тога, одлучено је да се користе комуникационе варијабле.
Комуникационе варијабле - то су варијабле које припадају плаибоок-у и потребне су за повезивање системских објеката.
Комуникационе варијабле су попуњене у општим системским варијаблама group_vars/all/vars и формирају се уклањањем свих променљивих слушаоца из сваке групе, и додавањем имена групе из које је слушалац уклоњен на почетак променљиве.
Тиме се обезбеђује уједначеност и непреклапање назива.
Хајде да покушамо да повежемо варијабле из примера изнад:

Замислимо да имамо променљиве које зависе једна од друге:
# roles/api/defaults:
# Переменная запроса
api_auth1_address: "http://example.com:80"
api_auth2_address: "http://example2.com:80"
# roles/auth/defaults:
# Переменная слушатель
auth_bind_port: "20000"Ставимо то у уобичајене варијабле group_vars/all/vars свим слушаоцима и додајте назив групе у наслов:
# group_vars/all/vars
bbauth_auth_bind_port: "20000"
ghauth_auth_bind_port: "30000"
# group_vars/bbauth/vars
auth_bind_port: "{{ bbauth_auth_bind_port }}"
# group_vars/ghauth/vars
auth_bind_port: "{{ ghauth_auth_bind_port }}"
# group_vars/myapi/vars
api_auth1_address: "http://{{ bbauth_auth_service_name }}:{{ bbauth_auth_bind_port }}"
api_auth2_address: "http://{{ ghauth_auth_service_name }}:{{ ghauth_auth_bind_port }}"Сада, променом вредности конектора, бићемо сигурни да ће захтев ићи на исто место где се налази порт.
Цоде Стиле
- Пошто су улоге и групе различити системски објекти, морају имати различита имена, онда ће променљиве везе тачно указати да припадају одређеној групи сервера, а не улози у систему.
Датотеке зависне од окружења
Улоге могу да користе датотеке које се разликују од окружења до окружења.
Пример таквих датотека су ССЛ сертификати. Чувајте их у текстуалном облику
у променљивој није баш згодно. Али згодно је сачувати путању до њих унутар променљиве.
На пример, користимо променљиву api_ssl_key_file: "/path/to/file".
Пошто је очигледно да ће се сертификат кључа мењати из окружења у окружење, ово је променљива која зависи од окружења, што значи да треба да се налази у датотеци
group_vars/myapi/vars инвентар променљивих, и садрже вредност 'на пример'.
Најприкладнији начин у овом случају је да ставите кључну датотеку у репозиторијум плаибоок-а дуж путање
files/prod/certs/myapi.key, тада ће вредност променљиве бити:
api_ssl_key_file: "prod/certs/myapi.key". Погодност лежи у чињеници да људи одговорни за постављање система на одређеном штанду такође имају свој наменски простор у спремишту за складиштење својих датотека. Истовремено, остаје могуће одредити апсолутну путању до сертификата на серверу, у случају да сертификате испоручује други систем.
Више штандова у једном окружењу
Често постоји потреба за постављањем неколико готово идентичних штандова у истом окружењу са минималним разликама. У овом случају делимо варијабле зависне од окружења на оне које се не мењају унутар овог окружења и оне које се мењају. И ово последње преносимо директно у саме датотеке инвентара. Након ове манипулације, постаје могуће креирати још један инвентар директно у директоријуму окружења.
Поново ће користити инвентар гроуп_варс, а такође ће моћи да редефинише неке варијабле директно за себе.
Коначна структура директоријума за пројекат имплементације:
mydeploy # Каталог деплоя
├── deploy.yml # Плейбук деплоя
├── files # Каталог для файлов деплоя
│ ├── prod # Католог для средозависимых файлов стенда prod
│ │ └── certs #
│ │ └── myapi.key #
│ └── test1 # Каталог для средозависимых файлов стенда test1
├── group_vars # Каталог переменных плейбука
│ ├── all.yml # Файл для переменных связи всей системы
│ ├── myapi.yml # Файл переменных свойств группы myapi
│ ├── bbauth.yml #
│ └── ghauth.yml #
└── inventories #
├── prod # Каталог окружения prod
│ ├── group_vars # Каталог для переменных инвентори
│ │ ├── myapi #
│ │ │ ├── vars.yml # Средозависимые переменные группы myapi
│ │ │ └── vault.yml # Секреты (всегда средозависимы)
│ │ ├── bbauth #
│ │ │ ├── vars.yml #
│ │ │ └── vault.yml #
│ │ └── ghauth #
│ │ ├── vars.yml #
│ │ └── vault.yml #
│ └── prod.ini # Инвентори стенда prod
└── test # Каталог окружения test
├── group_vars #
│ ├── myapi #
│ │ ├── vars.yml #
│ │ └── vault.yml #
│ ├── bbauth #
│ │ ├── vars.yml #
│ │ └── vault.yml #
│ └── ghauth #
│ ├── vars.yml #
│ └── vault.yml #
├── test1.ini # Инвентори стенда test1 в среде test
└── test2.ini # Инвентори стенда test2 в среде testСумирајући
Након организовања променљивих у складу са чланком: свака датотека променљиве је одговорна за одређени задатак. А пошто фајл има одређене задатке, постало је могуће доделити неког одговорног за исправност сваког фајла. На пример, програмер имплементације система постаје одговоран за исправно попуњавање променљивих плаибоок-а, док је администратор чији је став описан у инвентару директно одговоран за попуњавање инвентара варијабли.
Улоге су постале сопствена развојна јединица са сопственим интерфејсом, омогућавајући програмеру улоге да развије способности уместо да прилагођава улогу систему. Овај проблем се посебно односио на заједничке улоге свих система у кампањи.
Администратори система више не морају да разумеју код за примену. Све што је потребно од њих за успешну примену је да попуне датотеке варијабли зависних од окружења.
Литература
Аутор
Каљужни Денис Александрович
Извор: ввв.хабр.цом
