Здравей, Хабр! По-рано се оплаквах от живота в парадигмата на Infrastructure as code и не предлагах решения на създалата се ситуация. Днес се върнах, за да споделя кои подходи и практики могат да помогнат да се измъкнем от бездната на отчаянието и да насочим ситуацията в правилната посока.

В предишната статия Споделях впечатленията си от тази сфера, опитвах се да разсъждавам за текущата ситуация в тази област и дори предположих, че стандартните, известни на всички разработчици практики, могат да помогнат. Може да е изглеждало, че има много оплаквания от живота, но нямаше предложения за изход от създалата се ситуация.
Кои сме ние, къде сме и какви проблеми имаме
В момента сме в екипа за SRE onboarding, който се състои от шест програмисти и трима инженери по инфраструктура. Всички ние се опитваме да пишем Infrastructure as code (IaC). Правим това, защото в принцип сме способни да пишем код и в миналото сме били разработчици на ниво "над средното".
- Имаме набор от предимства: определен бекграунд, познания за практиките, умение да пишем код, желание да учим новото.
- И имаме и недостатък: липса на знания по материята на инфраструктурата.
Стек технологии, които използваме в нашето IaC.
- Terraform за създаване на ресурси.
- Packer за изграждане на имиджи. Това са Windows, CentOS 7 образи.
- Jsonnet, за да направим мощна сборка в drone.io, както и за генериране на packer json и нашите Terraform модули.
- Azure.
- Ansible при подготовка на образи.
- Python за помощни услуги, а също и за скриптове за provisioning.
- И всичко това в VSCode с плъгини, споделени между членовете на екипа.
Изводът от моята беше такъв: опитвах се да вдъхна (в първата линия в себе си) оптимизъм, исках да кажа, че ще пробваме известните ни подходи и практики, за да се справим с трудностите и сложностите, които съществуват в тази сфера.
В момента се борим с такива проблеми в IaC:
- Несъвършенство на инструментите, средствата за разработка на код.
- Бавно разгръщане. Инфраструктурата е част от реалния свят, а той може да не е бърз.
- Недостиг на подходи и практики.
- Ние сме нови и не знаем много.
Екстремното програмиране (XP) идва на помощ
На всички разработчици им е известен екстремното програмиране (XP) и практиките, които стоят зад него. Мнозина от нас са работили по този подход и той е бил успешен. Така че защо да не се възползваме от принципите и практиките, заложени в него, за да преодолеем трудностите в инфраструктурата? Решихме да приложим този подход и да видим какво ще излезе от него.
Оценка на приложимостта на подхода XP във вашата сфераПредставям описание на средата, за която XP е подходящ, и как това се отнася до нас:
1. Динамично променящи се изисквания за софтуер. Ясно ни беше каква е крайната цел. Но в детайлите можем да варираме. Ние сами решаваме къде да насочим усилията си, затова изискванията периодично се променят (главно от нас самите). Когато става въпрос за екип SRE, който сам прави автоматизация и същевременно ограничава изискванията и обхвата на работата, то този пункт е много подходящ.
2. Рискът от фиксирани времеви проекти с нова технология. Могат да възникнат рискове при използването на някои неща, които не сме познавали. И това е 100% нашият случай. Целият ни проект е свързан с технологии, с които не бяхме напълно запознати. Всъщност, това е постоянен проблем, тъй като в сферата на инфраструктурата постоянно възникват нови технологии.
3,4. Малък, координиран разширен екип за разработка. Технологията, която използвате, позволява автоматизирани модулни и функционални тестове. Тези два пункта не са съвсем подходящи за нас. Първо, ние не сме координиран екип, а второ, сме деветима човекa, което може да се счита за голям екип. Въпреки това, по някои определения за „голям“ екип, много е 14+ души.
Нека разгледаме някои практики от XP и как те влияят на скоростта и качеството на обратната връзка.
Принцип на цикъла на обратна връзка в XP
В моето разбиране обратната връзка е отговор на въпроса, правя ли го правилно, в правилната посока ли вървим? В XP за това има чудесна схема: цикъл на обратна връзка с времето. Интересното е, че колкото по-ниско сме, толкова по-бързо можем да получим ОС, за да отговорим на необходимите въпроси.

Това е доста интересна тема за обсъждане, тъй като в IT индустрията е възможно бързо да се получи ОС. Представете си колко е болезнено сложно да работите по проект в продължение на шест месеца и едва след това да разберете, че в самото начало е допусната грешка. Такова нещо се случва както в проектирането, така и в изграждането на сложни системи.
В нашия случай IaC ни помага обратната връзка. Веднага внасям малка корекция в схемата по-горе: планът за релиз не е месечен цикъл, а се извършва няколко пъти на ден. Към този цикъл са свързани някои практики, които ще разгледаме по-подробно.
Важно: обратната връзка може да стане решение за всички посочени по-горе проблеми. В съчетание с практиките на XP, тя може да ни извади от бездната на отчаянието.
Как да се извадим от бездната на отчаянието: три практики
Тестове
Тестовете се споменават два пъти в цикъла на обратната връзка на XP. Това не е случайно. Те са изключително важни за цялата техника на екстремното програмиране.
Предполага се, че имаш Unit и Acceptance тестове. Едните ти дават обратна връзка за няколко минути, другите за няколко дни, затова те се пишат по-дълго, а се изпълняват по-рядко.
Има класическа пирамида на тестването, която показва, че трябва да има повече от определени тестове.

Как тази схема е приложима в нашия проект IaC? Всъщност… по никакъв начин.
- Не може да има много Unit тестове, въпреки че трябва да има. Или те много косвено тестват нещо. Всъщност можем да кажем, че изобщо не ги пишем. Но ето няколко приложения за такива тестове, които все пак успяхме да направим:
- Тестването на кода на jsonnet. Това, например, е нашият пайплайн за изграждане в drone, който е доста сложен. Кодът на jsonnet е добре покрит с тестове.
Използваме този . - Тестове за скриптове, които се изпълняват при стартиране на ресурс. Скриптовете на Python, а следователно и тестовете за тях могат да се пишат.
- Тестването на кода на jsonnet. Това, например, е нашият пайплайн за изграждане в drone, който е доста сложен. Кодът на jsonnet е добре покрит с тестове.
- Потенциално е възможно проверка на конфигурацията в тестовете, но ние не правим така. Има възможност за настройка на проверка на правилата за конфигуриране на ресурси чрез . Въпреки това, просто за терраформа там са прекалено основни проверки, но много проверителни сценарии са написани за AWS. А ние сме на Azure, така че това отново не подхожда.
- Компонентни интеграционни тестове: тук зависи от това как ги класифицираш и къде ги разпределяш. Но те принципно работят.
Ето как изглеждат интеграционните тестове.

Това е пример при изграждане на образи в Drone CI. За да стигнем до тях, трябва да чакаме 30 минути, докато образът Packer бъде сглобен, след това още 15 минути, докато преминат. Но те съществуват!Алгоритъм за проверка на образите
- Първо, Packer трябва напълно да подготви образа.
- До теста има терраформ с локален статус, с който развиваме този образ.
- При разгръщането се използва малък модул, който е близо до него, за да улесни работата с образа.
- Когато образът е разположен във VM, можем да започнем проверките. Основно проверките се извършват на машината. Проверява се как са стартирали скриптовете, как работят демо системите. За целта чрез ssh или winrm влизаме в току-що създадената машина и проверяваме състоянието на конфигурацията или дали услугите са стартирани.
- Същата ситуация е и с интеграционните тестове и в модулите за терраформ. Ето една кратка таблица, обясняваща особеностите на такива тестове.

Обратната връзка в пайплайна е около 40 минути. Всичко става много бавно. Може да се използва за регресивно тестване, но за нова разработка е напълно невъзможно. Ако се подготвим изключително, подготвим работещите скриптове, можем да намалим до 10 минути. Но това все пак не са юнит тестове, които могат да се извършат за 5 секунди на 100.
Липсата на юнит тестове при сборката на образи или модули на терраформ ни принуждава да прехвърлим работата на отделни услуги, които просто могат да бъдат извикани по REST или на Python скриптове.
Например, трябваше да направим така, че при стартиране на виртуалната машина да се регистрира в услугата , а при унищожаване на виртуалката да се изтрива.
Тъй като ScaleFT е услуга, ние сме принудени да работим с него чрез API. Написана е обвивка, която можем да извикаме и да кажем: "Влез и изтрий това и това". Тя съхранява всички необходими настройки и достъпи.
На това можем да пишем нормални тестове, тъй като не се различава от обикновения софтуер: моква се някаква API, извикваш и гледаш какво се случва.

Резюме от тестовете: юнит тестването, което ОС трябва да предоставя за минута, не го прави. А по-горните нива на тестовете дават ефект, но покриват само част от проблемите.
Парно програмиране
Тестовете са, разбира се, невероятно полезни. Можете да напишете много, те могат да бъдат от различни видове. Те ще работят на собствените си нива и ще ни дават обратна връзка. Но проблемът с лошите Unit тестове, които дават най-бързата ОС, остава. Въпреки това продължава да се желае бърза ОС, която е лесна и приятна за работа. Да не говорим за качеството на полученото решение. За щастие, има техники, които позволяват да се получи дори по-бърза обратна връзка от модулните тестове. Това е парното програмиране.
Когато пишете код, искате да получите обратна връзка за качеството му възможно най-бързо. Да, можете да напишете всичко в функционалния клон (за да не повредите нищо на никого), да създадете pull request в GitHub, да назначите на някой, чийто мнение има тежест, и да чакате отговор.
Но чакането може да бъде дълго. Хората са заети, а отговорът, дори и да дойде, може да не е с най-високо качество. Да предположим, че отговорът е пристигнал веднага, рецензентът мигновено е разбрал целия замисъл, но отговорът пак идва със забавяне, постфактум. А искаме по-рано. Ето защо парното програмиране е насочено към това – да получим веднага, в момента на писане.
По-долу представям стиловете на парното програмиране и тяхната приложимост в работата по IaC:
1. Класически, Опитен+опитен, смяна по таймер. Две роли – шофьор и навигатор. Два човека. Те работят върху един и същи код и сменят ролите си на определен предварително обозначен интервал от време.
Нека разгледаме съвместимостта на нашите проблеми със стила:
- Проблема: несъвършенство на инструментите, средствата за разработка на код.
Негативно влияние: по-дълго развитие, забавяме се, нарушава се темпът/ритъмът на работа.
Как се справяме: прилагаме различни инструменти, общ IDE и учим шорткъти. - Проблема: бавно разгръщане.
Негативно влияние: увеличава времето за създаване на работеща част от кода. Скучаем докато чакаме, ръцете ни се протягат да направим нещо друго, докато чакаме.
Как се справяме: не успяхме да се справим. - Проблема: недостатък на подходи и практики.
Негативно влияние: няма знание как да направим нещата добре и как да ги направим лошо. Удължава времето за получаване на обратна връзка.
Как се справяме: взаимният обмен на мнения и практики в парната работа почти решава проблема.
Основният проблем при прилагането на този стил в IaC е неравномерният работен темп. В традиционната разработка на софтуер имаш много равномерно движение. Можеш да отделиш пет минути и да напишеш N. Да отделиш десет минути и да напишеш 2N, петнадесет минути – 3N. Тук обаче можеш да прекараш пет минути и да напишеш N, а след това да отделиш още 30 минути и да напишеш десета част от N. Тук нищо не знаеш, имаш задръжка, блокиране. Изясняването отнема време и отклонява от самото програмиране.
Извод: в чист вид не ни подхожда.
2. Ping-pong. Този подход предполага, че един участник пише тест, а другият прави реализация за него. Като се има предвид, че с Unit тестовете всичко е сложно и трябва да пишем дълъг по време интеграционен тест, цялата лекота на ping-pong изчезва.
Мога да кажа, че сме опитвали разделение на задълженията при проектиране на тестовия сценарий и реализация на кода под него. Един участник измисляше сценария, в тази част от работата той носеше отговорност и думата му беше последната. Другият бе отговорен за реализацията. Това се получаваше добре. Качеството на сценария при такъв подход се увеличава.
Извод: уви, темпът на работа не позволява да използваме ping-pong като практика на парно програмиране в IaC.
3. Strong Style. . Идеята е, че един участник става директивен навигатор, а вторият поема ролята на изпълнителен драйвер. При това правото на решения е изцяло на навигатора. Драйверът само пише и може със словото да повлияе на случващото се. Ролите не се сменят дълго време.
Подходящо е за обучение, но изисква силни умения за взаимодействие. На това и се спънахме. Техниката прозвуча трудно. И става дума дори не за инфраструктурата.
Извод: потенциално може да се прилага, не оставяме опити.
4. Mobbing, swarming и всички известни, но не изброени тук стилове не разглеждаме, тъй като не сме опитвали и не можем да кажем за това в контекста на нашата работа.
Общи изводи за използването на парно програмиране:
- Имаме неравномерен темп на работа, който разсейва.
- Упирахме се в недостатъчно добри умения за взаимодействие. А предметната област не спомага за преодоляване на тези наши недостатъци.
- Дългите тестове, проблемите с инструментите правят парното програмиране тромаво.
5. Въпреки това, имаше и успехи. Измислихме собствен метод „Схождане – Разминаване“. Накратко ще опиша как работи.
Имаме постоянни партньори за няколко дни (по-малко от седмица). Изпълняваме една задача заедно. Някакво време седим заедно: един пише, вторият стои и наблюдава, като е на длъжност поддръжка. После се разпускаме за известно време, всеки прави нещо независимо, след това отново се събираме, синхронизирайки се много бързо, правим нещо заедно и отново се разпускаме.
Планиране и комуникация
Последният блок практики, чрез които се решават проблеми с ОС, е организация на работата с самите задачи. Това включва и обмен на опит, който е извън двойната работа. Нека разгледаме три практики:
1. Задачи чрез дърво на целите. Общото управление на проекта организирахме чрез дърво, което безкрайно продължава в бъдещето. Технически, работата се управлява в Miro. Има една задача – тя е междинна цел. От нея излизат или по-малки цели, или групи от задачи. От тях вече идват самите задачи. Всички задачи се създават и управляват на тази дъска.

Тази схема също дава обратна връзка, която се случва веднъж на ден, когато се синхронизираме на срещите. Наличието на общ план пред всички, който е структурирано и напълно открит, позволява на всеки да е в течение на случващото се и на прогреса, който сме постигнали.
Предимства на визуализацията на задачите:
- Причинност. Всяка задача води до някаква глобална цел. Задачите се групират по по-малки цели. Домейнът на инфраструктурата сам по себе си е доста технически. Не винаги е очевидно какво конкретно влияние оказва, например, написването на ръчен проект за миграция на друг nginx. Наличието на целева карта до нея прави това по-разбираемо.

Причинността е важно свойство на задачите. То директно отговаря на въпроса: „Това ли правя?“ - Паралелност. Нас девет човека, и невъзможно е всички да се съсредоточим върху една задача. Не винаги има достатъчно задачи от една и съща област. Затова сме принудени да паралелим работата между малки работни групи. По време на това групите известно време работят върху собствената си задача, а можещи да бъдат подсилени от още някого. От тази работна група понякога се отървават хора. Някой отива в отпуск, някой прави доклад за конференцията DevOps conf, някой пише статия за Хабр. Знанието за това какви цели и задачи могат да се извършват паралелно става много важно.
2. Смяна на водещите на утринните митинги. На стендапите възникна такъв проблем – много задачи се извършват паралелно. Понякога задачите слабо са свързани и няма разбиране кой какво прави. Мнението на още един член на екипа е много важно. Това е допълнителна информация, която може да промени хода на решаването на задачата. Разбира се, обикновено имаш някого до теб, но консултациите и съветите никога не са излишни.
За да подобрим ситуацията, приложихме техниката „Смяна на водещия на стендапа“. Сега те се ротира по определен списък и това носи определен ефект. Когато дойде твой ред, ти си принуден да се потопиш и да разбереш какво се случва, за да проведеш добър скрам митинг.

3. Вътрешно демо. Помощта в решаването на задачата чрез парно програмиране, визуализация на дървото на задачите и помощ на скрам митингите сутрин – е добра, но не идеална. В двойка си ограничен само с твоето знание. Дървото на задачите помага глобално да се разбере кой какво прави. Водещият и колегите на утряната среща не вникват дълбоко в твоите проблеми. Определено могат да пропуснат нещо.
Решението беше намерено в демонстрирането на направените работи помежду ни и последващото обсъждане на тях. Събираме се веднъж седмично за час и показваме детайлите на решенията по задачите, които сме работили през последната седмица.
По време на демонстрацията е необходимо да се разкрият детайлите на задачата и задължително да се демонстрира работата й.
Докладът може да се води по чеклист.1. Въведете в контекста. Откъде е дошла задачата, за какво е нужна?
2. Как е била решавана задачата до сега? Например, било необходимо масово кликване с мишка или е било невъзможно нещо да се направи.
3. Как подобряваме това. Например: „Вижте, сега имаме скриптосик, ето и ридми“.
4. Покажете как работи това. Желателно е да се извърши конкретен сценарий на потребител. Искам X, правя Y, виждам Й (или Z). Например, деплойвам NGINX, проверявам url, получавам 200 OK. Ако действието е по-дълго, подгответе предварително, за да можете да го покажете. Желателно е поне час преди демото да не разграждате нещата, ако са крехки.
5. Обяснете доколко удачно е решена проблематиката, какви трудности остават, какво не е завършено, какви подобрения са възможни в бъдеще. Например, сега е CLI, след това ще има пълно автоматизиране в CI.
Желателно е всеки лектор да се вмести в 5-10 минути. Ако вашето изказване е особено важно и отнема повече време, предварително уговорете това в канала sre-takeover.
След частта на живо задължително следва обсъждане в треда. Тук се появява необходимата ни обратна връзка относно задачите.

В крайна сметка се провежда анкета за определяне на полезността на събитията. Това вече е обратна връзка за самата презентация и важността на задачата.

Дълги заключения и какво по-напред
Може да изглежда, че тонът на статията е леко песимистичен. Това не е така. Двата основни слоя за получаване на обратна връзка, а именно тестовете и парното програмиране, работят. Не съвсем както в традиционната разработка, но положителният ефект очевидно съществува.
Тестовете, в сегашния им вид, дават само частично покритие на кода. Много функции за конфигуриране остават непроверени. Влиянието им върху непосредствената работа при написване на код е слабо. Въпреки това, ефектът от интегративните тестове е реален и именно те позволяват безстрашно извършване на рефакторинг. Това е голямо постижение. Също така, с преноса на фокуса към разработката на високоуровневи езици (при нас python, go) проблемът изчезва. А за „лепилото“ много проверки не са нужни, достатъчно е общо интегрирано.
Работата в двойка зависи повече от конкретните хора. Има фактор задача и нашите софтуерни умения. С някои се получава много добре, с други - по-лошо. Ползата от това е очевидна. Ясно е, че дори при недостатъчно спазване на правилата за парна работа, самият факт на съвместно изпълнение на задачи оказва положително влияние на качеството на резултата. Лично на мен в двойка работи по-лесно и приятно.
По-високите нива на влияние върху ОС – планиране и работа с задачи определено дават ефекти: качествен обмен на знания и подобрение на качеството на разработката.
Кратки изводи на един ред
- Практиките на XP работят в IaC, но с по-ниска ефективност.
- Усилвайте това, което работи.
- Създавайте свои компенсаторни механизми и практики.
Източник: habr.com



