Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Багато хто знає та використовують Terraform у повсякденній роботі, але для нього досі не сформувалися найкращі практики. Кожній команді доводиться винаходити свої підходи, методи.

Ваша інфраструктура майже, напевно, починається просто: кілька ресурсів + кілька розробників. Згодом вона росте у всілякі сторони. Ви знаходите способи згрупувати ресурси в Terraform-модулі, організувати код по папках, і що взагалі може піти не так? (відомі останні слова)

Минає час, і ви відчуваєте, що ваша інфраструктура – ​​це ваш новий вихованець, але чому? Вас турбують незрозумілі зміни в інфраструктурі, ви боїтеся торкатися інфраструктури та коду — у результаті ви затримуєте новий функціонал або знижуєте якість…

Після трьох років управління на Github колекцією community-модулів Terraform для AWS та довгостроковій підтримці Terraform у продакшені, Антон Бабенко готовий поділитися своїм досвідом: як писати TF-модулі, щоб не було боляче в майбутньому.

До кінця доповіді учасники будуть краще знайомі з принципами управління ресурсами в Terraform, кращими практиками, пов'язаними з модулями Terraform, та деякими принципами безперервної інтеграції, пов'язаними з управлінням інфраструктурою.

Відмова від відповідальності: Зауважу, що доповідь ця датована листопадом 2018 року — минуло вже 2 роки. Версія Terraform 0.11, що розглядається в доповіді, вже не підтримується. За минулі 2 роки вийшло 2 нових релізів, у яких з'явилася маса нововведень, покращень та змін. Прошу на це звернути увагу та звіряться з документацією.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Посилання:

Мене звуть Антон Бабенко. Хтось із вас напевно використав код, який я писав. Я зараз про це говоритиму з більшою впевненістю, ніж будь-коли, тому що в мене є доступ до статистики.

Я займаюся Terraform і є активним учасником та контриб'ютором у великій кількості open source проектів, пов'язаних з Terraform та Amazon з 2015 року.

Приблизно з того часу я написав достатньо коду, щоб викласти це у цікавому вигляді. І про це я спробую зараз розповісти.

Я розповідатиму про тонкощі і про специфіку роботи з Terraform. Але насправді це не є предметом для HighLoad. І зараз ви зрозумієте чому.

Згодом я почав писати Terraform-модулі. Користувачі писали запитання, я їх переписував. Потім я написав різні утиліти для форматування коду за допомогою pre-commit hook і т.д.

Було багато цікавих проектів. Мені подобається займатися кодогенеруванням, тому що я люблю, щоб комп'ютер робив все більше і більше роботи за мене та за програміста, тому зараз працюю над генератором Terraform-коду із візуальних діаграм. Можливо, хтось із вас їх бачив. Це гарні коробочки зі стрілочками. І я вважаю, що це чудово, якщо можна натиснути кнопку «Експорт» і отримати це все як код.

Я з України. Я живу багато років у Норвегії.

Також інформація для цієї доповіді була зібрана від людей, які знають моє ім'я та знаходять мене у соціальних мережах. У мене майже завжди той самий нік.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

https://github.com/terraform-aws-modules
https://registry.terraform.io/namespaces/terraform-aws-modules

Як я згадав, я головний мейнтейнер Terraform AWS modules, який є однією з найбільших репозиторій на GitHub, де ми хостимо модулі для найпоширеніших завдань: VPC, Autoscaling, RDS.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

І те, що ви чули зараз, це базове. Якщо ви сумніваєтеся, що ви розумієте, що таке Terraform, краще проводити час де-небудь в іншому місці. Тут буде багато технічних термінів. І рівень доповіді я не посоромився заявити наймаксимальнішим. Це означає, що я можу розповідати, використовуючи всі можливі терміни без особливого пояснення.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Terraform з'явився у 2014-му році як утиліта, яка дозволяла писати, планувати та керувати інфраструктурою як код. Ключове поняття тут "інфраструктура як код".

Вся документація, як я сказав, написана на terraform.io. Я сподіваюся, що більшість знають про цей сайт і прочитали документацію. Якщо так, то ви у потрібному місці.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Так виглядає звичайний Terraform-конфігураційний файл, де ми спочатку визначаємо якісь змінні.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

У разі ми визначаємо «aws_region».

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Потім ми описуємо, які ресурси хочемо створити.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Запускаємо якісь команди, зокрема terraform init для того, щоб завантажити залежності, провайдери.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

І запускаємо команду «terraform apply» для того, щоб перевірити чи вказана конфігурація відповідає тим ресурсам, які створили. Оскільки ми нічого не створювали до цього, то Terraform пропонує нам створити ці ресурси.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Ми підтверджуємо це. Таким чином ми створюємо bucket, який називається seasnail.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Є також кілька схожих утиліт. Багато хто з вас, хто користується Amazon, знає AWS CloudFormation або Google Cloud Deployment Manager або Azure Resource Manager. У кожного з них є своя реалізація для управління ресурсами всередині кожного з цих public cloud провайдерів. Terraform особливо корисний у тому зв'язку, що він дозволяє керувати понад 100 провайдерами. (Детальніше тут)

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Цілі, які переслідував Terraform з самого початку:

  • Terraform дає єдиний вид ресурсів.
  • Дозволяє підтримувати усі сучасні платформи.
  • І Terraform із самого початку замислювався як утиліта, яка дозволяє змінювати інфраструктуру безпечно та передбачувано.

У 2014 році слово «передбачувано» звучало дуже незвичайно в даному контексті.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Terraform є універсальною утилітою. Якщо у вас є API, то можна керувати всім:

  • Можна використовувати більше 120 провайдерів для керування всім, до чого душа лежить.
  • Наприклад, можна використовувати Terraform для опису доступу до GitHub репозиторій.
  • Можна навіть баги у Jira створювати та закривати.
  • Можна керувати New Relic-метриками.
  • Можна навіть файли в dropbox створювати, якщо дуже хочеться.

Це все досягається за допомогою Terraform-провайдерів, які мають відкритий API, які можна описати на Go.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Припустимо, ми почали використовувати Terraform, прочитали якусь документацію на сайті, переглянули якесь відео, почали писати main.tf, як я показував на попередніх слайдах.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

І у вас все класно, у вас вийшов файл, який створює VPC.

Якщо ви хочете створити VPC, то ви вказуєте приблизно ці 12 рядків. Описуєте в якому регіоні ви хочете створити, який IP-адрес cidr_block використовувати. І все.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Звісно, ​​поступово проект зростатиме.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

І ви додаватимете туди купу нового всього: ресурси, джерела даних, ви інтегруватиметеся з новими провайдерами, несподівано ви захочете використовувати Terraform для того, щоб керувати користувачами у вашому GitHub-акаунті і т. д. Ви можете захотіти використовувати різні DNS-провайдери схрещувати все поспіль. Terraform легко дозволяє це робити.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Розглянемо наступний приклад.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Ви поступово додаєте internet_gateway, тому що ви хочете, щоб ресурси вашого VPC мали доступ в інтернет. Це гарна ідея.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

У результаті виходить такий main.tf:

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Це є верхня частина main.tf.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Це нижня частина main.tf.

Потім додаєте subnet. До того моменту, коли ви захочете додати NAT gateways, routes, routing tables та купу інших subnets, у вас буде не 38 рядків, а приблизно 200-300 рядків.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Т. е. ваш main.tf файл поступово зростає. І часто люди складають все в один файл. На main.tf з'являється 10-20 Kb. Уявіть, що 10-20 Kb це текстовий контент. І все пов'язано з усім. Із цим працювати поступово стає складно. 10-20 Kb – це добрий user case, буває і більше. І не завжди люди вважають, що це погано.

Як і у звичайному програмуванні, тобто не інфраструктура як код, ми звикли використовувати купу різних класів, пакетів, модулів, угруповання. Terraform дозволяє робити приблизно те саме.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

  • Код зростає.
  • Залежності між ресурсами також зростають.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

І в нас виникає велика потреба. Ми розуміємо, що так жити далі не можемо. У нас код стає неосяжним. 10-20 Kb – це, звичайно, не дуже неосяжний, але це ми говоримо лише про network stack, тобто ви додали лише мережеві ресурси. Ми не говоримо ще про Application Load Balancer, deployment ES cluster, Kubernetes і т. д., куди легко можна вплести 100 Kb. Якщо ви все це напишіть, то ви скоро дізнаєтеся, що Terraform надає Terraform-модулі.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Terraform-модулі - це самодостатня Terraform-конфігурація, яка управляється як група. Це все, що треба знати про Terraform-модулі. Вони ніякі не розумні, вони не дозволяють робити вам якісь складні підключення залежно від чогось. Це все лягає на плечі розробників. Т. е. це просто якась Terraform-конфігурація, яку ви вже написали. І можна просто викликати її як групу.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Таким чином ми намагаємося зрозуміти, як ми будемо оптимізувати наші 10-20-30 Kb коди. Ми поступово розуміємо, що треба використовувати якісь модулі.

Перший тип модулів, що зустрічається, це ресурсні модулі. Вони не розуміють, про що ваша інфраструктура, про що ваш бізнес, де та які умови. Це саме ті модулі, які я разом з open source спільнотою адмініструємо, і які ми висуваємо як найперший building blocks для вашої інфраструктури.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

приклад ресурсного модуля.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Коли ми викликаємо ресурсний модуль, ми вказуємо, з якого шляху ми повинні завантажити його вміст.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Ми вказуємо яку версію ми хочемо завантажити.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Ми передаємо купу аргументів туди. І все. Це все, що нам потрібно знати, коли ми використовуємо цей модуль.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Багато хто думає, що якщо використовувати останню версію, то все буде стабільно. Але немає. Інфраструктура має бути версійною, ми чітко повинні відповісти, якій версії було задеплоєно той чи інший компонент.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Перед вами код, який знаходиться усередині цього модуля. Модуль security-group. Тут скролл йде до 640-го рядка. Створення security-croup ресурсу в Amazon у всілякій конфігурації - це дуже нетривіальне завдання. Недостатньо просто створити security-group та сказати, які правила їй передавати. Це було б дуже просто. Усередині Amazon є мільйон різних обмежень. Наприклад, якщо ви використовуєте VPC endpoint, prefix list, різні API і намагається це все з усім схрестити, Terraform не дозволяє вам це зробити. І Amazon API також не дозволяє це. Тому треба сховати всю цю страшну логіку в модуль і користувачеві видавати код, який виглядає тільки ось так.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Користувачеві не треба знати, як усередині воно зроблено.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Другий тип модулів, що складається з ресурсних модулів, вже вирішує завдання, які більш застосовні для вашого бізнесу. Часто це місце, яке є розширенням для Terraform і задає якісь жорсткі значення для тегів, стандартів компанії. Також можна додавати функціонал, який Terraform не дозволяє зараз використовувати. Це саме зараз. Зараз версія 0.11, яка ось-ось відійде у минуле. Але все одно препроцесори, jsonnet, cookiecutter та купа інших речей є тим допоміжним механізмом, який треба використовувати для повноцінної роботи.

Далі я покажу деякі приклади цього.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Інфраструктурний модуль викликається таким самим способом.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Вказується джерело звідки завантажити контент.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Передається купа значень, які передаються до цього модуля.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Далі всередині цього модуля викликається купа ресурсних модулів для створення VPC або Application Load Balancer, або створення security-group або Elastic Container Service кластера.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Є два типи модулів. Це важливо розуміти, тому що більшість інформації, яку я згрупував у цій доповіді, не написана у документації.

І документація в Terraform прямо зараз досить проблематична, тому що вона просто каже, що такі фічі, ви можете їх використовувати. Але вона не каже, як ці фічі використовувати, чому так краще використовувати. Тому дуже багато людей пишуть щось, з чим потім не можна жити.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Давайте подивимося, як писати ці модулі. Потім подивимося, як їх викликати та як працювати з кодом.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Terraform Registry - https://registry.terraform.io/

Порада № 0 – це писати ресурсні модулі. Більшість цих модулів вже написано за вас. Як я говорив, вони open source, вони не містять жодної вашої бізнес-логіки, у них немає захардшкірених значень для IP-адрес, паролів і т. д. Модуль є дуже flexible. І він, швидше за все, написаний. Для ресурсів від Amazon модулів багато. Близько 650. І більшість із них гарної якості.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

На цьому прикладі до вас прийшов хтось і сказав: «Я хочу мати можливість керувати базою даних. Створи модуль, щоб я міг створювати базу даних». Людина не знає подробиць реалізації ні Amazon, ні Terraform. Він просто каже: "Я хочу керувати MSSQL". Т. е. ми маємо на увазі, що він буде викликати наш модуль, передасть туди тип двигуна, вкаже time-зону.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

І людина не повинна знати, що ми всередині цього модуля створюватимемо два різні ресурси: один для MSSQL, другий для всього іншого тільки тому, що в Terraform 0.11 не можна вказувати значення time-зони необов'язковим.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

І на виході з цього модуля людина матиме можливість просто отримувати адресу. Він не знатиме з якої бази даних, з якого ресурсу ми всередині це все створюємо. Це дуже важливий елемент приховування. І це застосовно не тільки для тих модулів, які знаходяться в public в open source, а також для тих модулів, які ви писатимете всередині своїх проектів, команд.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Ось це другий аргумент, який є досить важливим, якщо ви використовуєте Terraform якийсь час. У вас є репозиторій, в якому ви складаєте всі свої модулі Terraform для вашої компанії. І цілком нормально, що згодом цей проект зросте до розміру одного-двох мегабайт. Це нормально.

Але проблема полягає в тому, як Terraform викликає ці модулі. Наприклад, якщо ви будете викликати модуль для створення кожного індивідуального користувача, то Terraform спочатку завантажуватиме весь репозиторій, а потім переходитиме в папку, де знаходяться конкретно цей модуль. Таким чином ви щоразу завантажуватимете по одному мегабайту. Якщо ви керуєте 100 або 200 користувачами, ви завантажите 100 або 200 мегабайт, а потім вже перейдете в ту папку. Таким чином, природно, ви не хочете щоразу, коли натискаєте «Terraform init» завантажувати купу всього.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

https://github.com/mbtproject/mbt

Є два вирішення цієї проблеми. Перше полягає у тому, щоб використовувати відносні шляхи. Таким чином, ви в коді вказуєте, що папка локальна (./). Та перед тим, як щось запускати, ви робите Git clone цього репозиторію локально. Таким чином, ви робите це один раз.

Є, звичайно, купа downsides. Наприклад, що не можна використовувати versioning. І з цим іноді важко жити.

Друге рішення. Якщо у вас багато підмодулів і у вас вже є якийсь устаканний pipeline, тобто проект MBT, який дозволяє збирати з монорепозиторію багато різних пакетів і завантажувати їх на S3. Це дуже добрий спосіб. Таким чином файл iam-user-1.0.0.zip буде важити лише 1 Kb, тому що код для створення цього ресурсу дуже маленький. І це набагато швидше працюватиме.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Поговоримо про те, що не можна використовувати у модулях.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Чому у модулях це зло? Найстрашніша річ – це assume user. Assume user – це такий варіант автентифікації в провайдері, який можуть використовувати різні люди. Наприклад, ми всі будемо осюміти роль. Це означає, що Terraform прийматиме цю роль. І потім із цією роллю виконуватиме інші дії.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

І зло полягає в тому, що якщо Вася любить підключатися до Amazon одним способом, наприклад, використовуючи за умовчанням змінне оточення, а Петя любить використовувати свій shared key, який у нього знаходиться в секретному місці, то Terraform не можна вказувати і те й інше. І для того, щоб вони не мали страждань, не треба цей блок вказувати в модулі. Це треба вказувати вище рівнем. Т. е. у нас є ресурсний модуль, інфраструктурний модуль і композиція зверху. І десь вище це треба вказувати.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Друге зло полягає в провіднику. Тут зло не настільки тривіальне, тому що якщо пишіть код і для вас він працює, ви можете подумати, що якщо він працює, то навіщо міняти.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Зло полягає в тому, що цей provisioner ви не завжди контролюєте, коли він конкретно запускатиметься, по-перше. І, по-друге, ви не контролюєте, що означає aws ec2, тобто ми говоримо зараз про Linux або Windows. Таким чином, ви не можете писати щось, що працюватиме однаково в різних операційних системах або для різних користувачів.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Найпоширеніший приклад, в тому числі вказаний в офіційній документації, це те, що якщо ви пишите aws_instance, вказуєте купу аргументів, то нічого поганого в цьому немає, якщо ви вкажете там і provisioner «local-exec» і запустіть свій ansible-playbook .

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Насправді так, нічого поганого в цьому немає. Але буквально скоро ви усвідомлюєте, що ця штука local-exec не існує, наприклад, в launch_configuration.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

І коли ви використовуєте launch_configuration, і ви хочете з одного instance створити autoscaling group, то в launch_configuration немає поняття «provisioner». Там є поняття "user data".

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Тому універсальним рішенням є використання user data. І буде запускатися або на самому instance, коли instance включиться, або в цьому ж user data, коли autoscaling group буде використовувати цей launch_configuration.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Якщо все-таки є бажання запустити provisioner, тому що він є компонентом, що склеює, коли один ресурс буде створений і в цей момент треба запустити свій provisioner, свою команду. Таких ситуацій дуже багато.

І найправильніший ресурс для цього називається null_resource. Null_resource – це фіктивний ресурс, який насправді ніколи не створюється. Він нічого не чіпає, немає API, немає autoscaling. Але він дозволяє регулювати коли запускати команду. У цьому випадку команда запускається під час створення.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Посилання http://bit.ly/common-traits-in-terraform-modules

Є кілька ознак. Я не зупинятимуся на всіх ознаках дуже детально. Є стаття про це. Але якщо ви працювали з Terraform або використовували чужі модулі, то ви часто помічали, що багато модулів, як і більшість коду в open source, люди пишуть для якихось потреб. Людина його написала, вирішила своє завдання. Заковбасив його в GitHub, нехай живе. Він житиме, але якщо там немає жодної документації та прикладів, то ніхто ним користуватися не буде. І якщо там немає функціоналу, який дозволяє вирішувати трохи більше, ніж його конкретне завдання, то ним теж ніхто не користуватиметься. Є багато способів втратити користувачів.

Якщо ви хочете написати щось, щоб люди цим користувалися, то я рекомендую дотримуватися цих ознак.

Це:

  • Документація та приклади.
  • Повний функціонал.
  • Розумні значення за промовчанням.
  • Чистий код.
  • Тести.

Тести – це окрема ситуація, бо їх досить складно написати. Я більше вірю в документацію та приклади.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Отже, ми переглянули, як писати модулі. Є два аргументи. Перший, який найважливіший, це не пиши, якщо можеш, тому що купа-купа людей вже зробили ці завдання до вас. І другий, якщо все ж таки зважився, то провайдери в модулях і provisioner намагайся не використовувати.

Це сіра частина документації. Ви можете зараз подумати: «Щось незрозуміло. Не переконав». Але подивимося за півроку.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Тепер поговоримо про те, як викликати ці модулі.

Ми розуміємо, що згодом наш код зростає. Ми вже не один файл, у нас вже 20 файлів. Усі вони лежать у одній папці. Або, може, у п'яти папках. Можливо, ми починаємо їх якось розбивати регіонами, якимись компонентами. Потім ми розуміємо, що тепер маємо якісь зачатки синхронізації, оркестрації повинні виникати. Т. е. повинні зрозуміти, що робити, якщо ми змінили мережеві ресурси, що робити з іншими нашими ресурсами, як викликати ці залежності тощо.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Є дві крайнощі. Перша крайність – це все в одному. Ми маємо один майстер-файл. До певного часу це був офіційна best practice на сайті Terraform.

Але зараз це написано як deprecated та прибрано. Згодом Terraform-спільнота зрозуміла, що це далеко не best practice, тому що люди починають використовувати проект у різних видах. І є проблеми. Наприклад, коли ми вказуємо усі залежності в одному місці. Буває ситуація, коли ми натискаємо «Terraform plan» і поки Terraform оновить стан всіх ресурсів, може пройти купа часу.

Купа часу – це, наприклад, 5 хвилин. Для когось це багато часу. Я бачив випадки коли це займало 15 хвилин. 15 хвилин AWS API смикався для того, щоб зрозуміти, що зі станом кожного ресурсу. Це дуже велика область.

І, звісно, ​​з'явиться пов'язана проблема, коли ви захочете поміняти щось в одному місці, потім почекали 15 хвилин, а воно вам видало полотно якихось змін. Ви плюнули, написали Yes, і щось пішло не так. Це реальний приклад. Terraform не намагається відгородити вас від проблем. Т. е. пишіть, що хочете. Будуть проблеми – ваші проблеми. Поки що Terraform 0.11 не намагається вам допомогти ніяк. У 0.12 є певні цікаві місця, які дозволяють вам сказати: "Вася, ти дійсно цього хочеш, можеш одуматись?".

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Другий спосіб полягає у зменшення цієї області, тобто можна менше зв'язувати виклики одного місця з іншого місця.

Єдина проблема в тому, що потрібно писати більше коду, тобто потрібно описувати змінні у великій кількості файлів, оновлювати це. Комусь це не подобається. Для мене це гаразд. А дехто думає: «Навіщо це писати в різних місцях, я це все в одному місці заковбасю». Можна й так, але це друга крайність.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

У кого це все мешкає в одному місці? Одна, дві, три людини, тобто хтось використовує.

А хто викликає один конкретно компонент, один блок чи один інфраструктурний модуль? Чоловік п'ять-сім. Це здорово.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Найчастіша відповідь – це десь посередині. Якщо проект великий, то у вас часто буде ситуація, коли жодне рішення не годиться і там не все виходить, тому у вас виходить суміш. У цьому нічого поганого немає, аби ви розуміли, що є перевага і в того, і в того.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Якщо щось змінилося в stack VPC і ви захотіли застосувати ці зміни EC2, тобто ви захотіли оновити autoscaling group, тому що у вас з'явилася нова subnet, то такого роду залежності я називаю оркестрацією. Є якісь рішення: хто як використовує?

Я можу підказати які є рішення. Можна використовувати Terraform для того, щоб робити магію, а можна використовувати make-файли для використання Terraform. І дивитися, якщо там щось змінилося, можна запустити.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Як вам таке рішення? Хтось вірить, що це класне рішення? Я бачу посмішку, мабуть сумніви закралися.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Звісно, ​​не повторюйте це вдома. Terraform ніколи не був створений для запуску з Terraform.

Мені на одній доповіді сказали: Ні, це не буде працювати. Справа в тому, що вона й не повинна працювати. Хоч воно і виглядає так ефектно, коли ти можеш із Terraform запустити Terraform, а там ще Terraform, але не треба робити так. Terraform повинен завжди запускатись дуже просто.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

https://github.com/gruntwork-io/terragrunt/

Якщо у вас потрібна оркестрація викликів, коли змінилося щось в одному місці, тобто Terragrunt.

Terragrunt – це утиліта, це надбудова над Terraform, яка дозволяє координувати та оркеструвати виклики інфраструктурних модулів.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Типовий Terraform-конфігураційний файл виглядає так.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Ви вказуєте, який модуль ви хочете викликати.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Які модулі мають залежність.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

І які аргументи цей модуль сприймає. Це все, що вам потрібно знати про Terragrunt.

Документація там є, 1 зірочок на GitHub теж є. Але здебільшого це те, що треба знати. І це дуже легко вживити в компанії, які почали працювати з Terraform.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Таким чином, оркестрація – це Terragrunt. Інші варіанти є.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Тепер поговоримо, як працювати з кодом.

Якщо у вас є необхідність додати нові фічі в код, в більшості випадків це легко. Ви пишете новий ресурс, тут все просто.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Якщо у вас є якийсь ресурс, який ви створили заздалегідь, наприклад, ви про Terraform дізналися після того, як ви відкрили AWS-аккаунт і хочете використовувати ті ресурси, які у вас вже є, то буде доречно розширити свій модуль таким чином, щоб він підтримував використання наявних ресурсів.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

І підтримував створення нових ресурсів, використовуючи ресурс block.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

На виході ми завжди повертаємо output id залежно від того, що було використано.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Друга дуже суттєва проблема у Terraform 0.11 – це робота зі списками.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Складність полягає в тому, якщо ми маємо такий список users.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

І коли ми створюємо цих users, використовуючи block resource, то все відбувається нормально. Ми проходимо по всьому списку, створюємо кожному файлу. Все нормально. І потім, наприклад, user3, який посередині, повинен бути прибраний звідси, то всі ресурси, які були створені після нього, вони будуть перетворюватися, тому що індекс зміниться.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Робота зі списками в stateful-оточенні. Що таке stateful-оточення? Це ситуація, коли виникає нове значення при створенні цього ресурсу. Наприклад, AWS Access Key або AWS Secret Key, тобто коли ми створюємо user'а, нам приходить новий Access або Secret Key. І щоразу, коли ми видалятимемо якогось user'а, у цього user'а буде новий ключ. Але це не по феншуй, тому що user не захоче з нами дружити, якщо ми щоразу створюватимемо нового user'а для нього, коли хтось залишає команду.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Рішення таке. Це код написаний на Jsonnet. Jsonnet – це мова створення шаблонів від Google.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Ця команда дозволяє прийняти цей шаблон і на виході він повертає json-файл, зроблений за вашим шаблоном.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Шаблон виглядає так.

Terraform дозволяє працювати і з HCL, і з Json однаково, тому якщо у вас є можливість генерувати Json, ви можете його підсунути в Terraform. Файл із розширенням .tf.json буде успішно завантажено.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

І потім ми працюємо з цим як завжди: terraform init, terramorm apply. І ми створюємо двох user'ів.

Тепер нам не страшно, якщо хтось покине команду. Ми просто відредагуємо файл json. Вася Пупкін пішов, Петя П'яточкін залишився. Петя П'яточкін не отримає нового ключа.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Інтеграція Terraform з іншими засобами по суті не є завданням Terraform. Terraform створювався як платформа для створення ресурсів та все. І все, що підходить потім – це не турбота Terraform. І не треба туди вплітати його. Є Ansible, який робить все, що треба.

Але виникають ситуації, коли ми хочемо доповнити Terraform та викликати якусь команду після того, як щось виконалося.

Перший метод. Ми створюємо output, де ми пишемо цю команду.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

А потім цю команду викликаємо із shell terraform output і вказуємо це значення, яке ми хочемо. Таким чином виконується команда з усіма значеннями. Це дуже зручно.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Другий спосіб. Це використання null_resource залежно від змін у нашій інфраструктурі. Ми можемо викликати той самий local-exeс, щойно зміниться ID якогось ресурсу.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Природно, це все гладко на папері, тому що Amazon, як і решта public-провайдерів, має купу своїх edge cases.

Найпоширеніший edge cases полягає в тому, що коли ви відкрили AWS-аккаунт, важливо, які ви регіони використовуєте; чи включена ця фіча там; можливо, ви його відкрили після грудня 2013 року; можливо, ви використовуєте дефолт в VPC і т.д. Є багато обмежень. І Amazon розкидав їх у всій документації.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Є кілька речей, які я рекомендую уникати.

Для початку уникайте всіх нетаємних аргументів усередині Terraform plan або Terraform CLI. Все це можна скласти або в tfvars-файл, або змінне оточення.

Але не треба запам'ятовувати всю цю магічну команду. Terraform plan – var і помчала. Перша змінна – var, друга – var, третя, четверта. Найважливіший принцип інфраструктури як код, який я найчастіше використовую, це те, що, просто поглянувши на код, я маю чудово розуміти, що там задеплоєно, в якому стані та з якими значеннями. І тому мені не треба читати документацію чи запитувати Васю про те, які параметри він використав для створення кластера. Мені достатньо відкрити файл з розширенням tfvars, який часто збігається з оточенням, і переглянути все там.

Також не потрібно використовувати аргументи target для зменшення сфери дії. Для цього набагато простіше використовувати невеликі інфраструктурні модулі.

Також не треба обмежувати та збільшувати parallelism. Якщо я маю 150 ресурсів і я хочу збільшити parallelism Amazon з 10, які за замовчуванням, до 100, то, швидше за все, щось піде не так. Або може піти добре зараз, але коли Amazon скаже, що ви занадто багато робите викликів, у вас посиплються проблеми.

Terraform більшість цих проблем буде намагатися перезапустити, але ви не досягнете майже нічого. Parallelism=1 – це важлива річ, яку потрібно використовувати, якщо ви спіткнулися про якийсь баг усередині AWS API або всередині провайдера Terraform. І тоді треба зазначити: parallelism=1 і чекати, поки Terraform закінчить один виклик, потім другий, потім третій. По черзі він їх запускатиме.

Часто мене запитують: "Чому я вважаю, що Terraform workspaces - це зло?" Я вірю, що принцип інфраструктури як код полягає у тому, щоб бачити, яка інфраструктура була створена та з якими значеннями.

Workspaces було створено не з боку користувачів. Це не означає, що користувачі написали в GitHub issues, що жити не можемо без Terraform workspaces. Ні, не так. Terraform Enterprise – це комерційне рішення. Terraform від HashiCorp вирішило, що нам треба workspaces, тому ми це запиляємо. Я вважаю, що набагато простіше покласти це в окрему папку. Тоді буде трохи більше файлів, але буде зрозумілішим.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Як працювати з кодом? По суті робота зі списками – єдиний біль. І сприймайте Terraform простіше. Це не та річ, яка вам робитиме все класно. Не треба пхати туди все, що написано у документації.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

У темі доповіді було написано "на майбутнє". Я дуже коротко про це скажу. На майбутнє - це означає, що скоро вийде 0.12.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

0.12 - це купа всього нового. Якщо ви прийшли зі звичайного програмування, то ви сумуєте за будь-якими динамічними блоками, циклами, за правильними та умовними операціями порівняння, де ліва і права частина обчислюються не одночасно, а залежно від ситуації. Ви дуже за цим сумуєте, тому 0.12 вам вирішить це.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Але! Якщо ви писатимете менше і простіше, використовуючи готові модулі, сторонні рішення, то вам не треба буде чекати і сподіватися, що 0.12 прийде і все за вас полагодить.

Опис інфраструктури у Terraform на майбутнє. Антон Бабенко (2018р)

Дякую за доповідь! Ти говорив про інфраструктуру як код та про тести сказав буквально одне слово. Чи потрібні тести у модулях? Чия це відповідальність? Чи потрібно самому писати чи це відповідальність модулів?

Наступний рік буде засипано доповідями про те, що ми вирішили все тестувати. Що тестувати – це найбільше питання. Є купа залежностей, купа обмежень різних провайдерів. Коли ми з тобою розмовляємо, і ти кажеш: «Мені потрібні тести», то я питаю: «Що ти тестуватимеш?». Ти кажеш, що тестуватимеш у своєму регіоні. Тоді я говорю, що в моєму регіоні це не працює. Т. е. ми навіть на цьому з тобою не зможемо домовитися. Не кажучи вже про те, що є безліч технічних проблем. Т. е. як написати ці тести, щоб вони були адекватними.

Я досліджую цю тему активно, тобто, як автоматично генерувати тести на основі тієї інфраструктури, яку ти написав. Т. е. якщо ти написав цей код, то мені треба його запустити, на підставі цього я зможу створити тести.

Терратест – це одна з найпоширеніших бібліотек, яка дозволяє писати тести інтеграційні для Terraform. Це одна з утиліт. Мені більше подобається тип DSL, наприклад rspec.

Антоне, дякую за доповідь! Мене звуть Валерій. Дозволю себе трохи філософське питання. Є, умовно, provisioning, є deployment. Provisioning мою інфраструктуру створює, у deployment ми її чимось наливаємо корисним, наприклад, серверами, додатками тощо. І в мене в голові сидить, що Terraform більше для provisioning, а Ansible більше для deployment, тому що Ansible і на фізичну інфраструктуру дозволяє поставити Nginx, Postgres. Але при цьому і Ansible начебто дозволяє зробити пропозицію, наприклад, амазонських або гуглових ресурсів. Але і Terraform дозволяє за допомогою своїх модулів задеплоїти якийсь софт. На твою думку, чи є якась межа, яка проходить між Terraform і Ansible, де і що краще використовувати? Або, наприклад, ти думаєш, що Ansible – це вже фігня, чи треба намагатися Terraform для всього використовувати?

Гарне питання, Валерію. Я вважаю, що Terraform з 2014 року не змінився в плані призначення. Він створений для інфраструктури та помер для інфраструктури. У нас, як і раніше, була і буде потреба в configuration management Ansible. Виклик у тому, що є user data всередині launch_configuration. І там ти смикаєш Ansible і т. д. Ось це стандартне розмежування, яке мені найбільше подобається.

Якщо ми говоримо про in beautiful infrastructure, то є утиліти типу Packer, яка збирає цей образ. І далі Terraform використовує data source для пошуку цього образу та оновлення своєї launch_configuration. Тобто таким чином pipeline полягає в тому, що ми смикаємо спочатку Tracker, потім смикаємо Terraform. І якщо стався build, то відбувається нова зміна.

Вітаю! Дякую за доповідь! Мене звуть Мишко, компанія RBS. Можна Ansible викликати через provisioner під час створення ресурсу. А також у Ansible є така тема, як динамічний інвентар. І можна спочатку викликати Terraform, а потім викликати Ansible, який із state візьме ресурси і виконає. Що краще?

І те й те люди використовують із однаковим успіхом. Мені здається, що динамічний інвентар у Ansible – це зручна річ, якщо ми не говоримо про autoscaling group. Тому що в autoscaling group ми вже маємо свій інструментарій, який називається launch_configuration. Ми у launch_configuration записуємо все, що треба запускати, коли створюємо новий ресурс. Тому з Amazon використовувати динамічний інвентар і читати Terraform ts файл, на мою думку, це зайве. А якщо ви використовуєте інші засоби, де немає поняття «autoscaling group», наприклад, ви використовуєте DigitalOcean або якийсь інший провайдер, де немає autoscaling group, то там вам треба буде ручками смикати API, знаходити IP-адреси, формувати dynamic inventory файл , і Ansible буде вже ним блукати. Т. е. для Amazon є launch_configuration, а для решти є dynamic inventory.

Джерело: habr.com

Додати коментар або відгук