Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Джерело: https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/medium-terraform
Цей приклад містить код як приклад структурування конфігурацій Terraform для інфраструктури середнього розміру, яка використовує:
2 AWS акаунти
2 окремих середовища (prod
та stage,
які не мають нічого спільного). Кожне середовище живе в окремому акаунті AWS
Кожне середовище використовує різну версію готового інфраструктурного модуля (alb), отриманого з Terraform Registry
Кожне середовище використовує одинакову версію модулів/мережі внутрішнього модуля, оскільки джерело отримане з локального каталогу
Ідеально підходить для проектів, де інфраструктура логічно розділена (окремі акаунти AWS)
Добре, коли немає необхідності змінювати ресурси, спільні для акаунтів AWS (одне середовище = один акаунт AWS = один файл стану)
Добре, коли немає потреби в оркестровці змін між середовищами
Добре, коли ресурси інфраструктури відрізняються для кожного середовища спеціально і не можуть бути узагальнені (наприклад, деякі ресурси відсутні в одному середовищі або в деяких регіонах)
Із розвитком проекту буде все важче підтримувати ці середовища в актуальному стані одне з одним. Подумайте про використання інфраструктурних модулів (готових або внутрішніх) для повторюваних завдань.
Питання, пов’язані зі структурою коду Terraform, є найпоширенішими у спільноті. Кожен також думав про найкращу структуру коду для проекту.
Це одне з питань, де існує багато рішень і дуже важко дати якусь одну універсальну пораду, тож почнемо з розуміння того, з чим ми маємо справу.
Яка складність вашого проекту?
Кількість супутніх ресурсів
Кількість Terraform провайдерів (див. примітку нижче про "логічних провайдерів")
Як часто змінюється ваша інфраструктура?
Від раз на місяць/тиждень/день
До безперервно (щоразу, коли є новий коміт)
Ініціатори зміни коду? Чи дозволяєте ви серверу CI оновлювати репозиторій, коли створюється новий артефакт?
Тільки розробники можуть пушати до репозиторію інфраструктури
Кожен може запропонувати змінити будь-що, відкривши PR (включаючи автоматизовані завдання, що виконуються на сервері CI)
Яку платформу або сервіс для деплою ви використовуєте?
AWS CodeDeploy, Kubernetes, чи OpenShift вимагає дещо іншого підходу
Як згруповані середовища?
За середовищем, регіоном, проектом
Ведення всього коду в main.tf
- гарна ідея, якщо ви починаєте роботу або пишете приклад коду. У всіх інших випадках вам буде краще, якщо декілька файлів розділити логічно так:
main.tf
- викликає modules, locals, а також data sources, щоб створювати всі ресурси
variables.tf
- містить оголошення змінних, які використовуються в main.tf
outputs.tf
- містить outputs з ресурсів, які були створені в main.tf
versions.tf
- містить вимоги до версії для Terraform і провайдерів
terraform.tfvars
не слід використовувати ніде, крім композиції.
Будь ласка, переконайтеся, що ви розумієте ключові поняття - ресурсний модуль, інтфраструктурний модуль, а також композицію, так як вони використовуються в наступних прикладах.
Загальні рекомендації щодо структурування коду
З меншою кількістю ресурсів працювати легше і швидше
terraform plan
та terraform apply
обидва здійснюють виклики хмарного API для перевірки стану ресурсів
Якщо у вас вся інфраструктура в одній композиції, це може зайняти деякий час
Радіус вибуху менший при меншій кількості ресурсів
Ізоляція ресурсів, непов'язаних один від одного, шляхом розміщення їх в окремих композиціях, зменшує ризик, якщо щось піде не так
Почніть свій проект, використовуючи віддалений стан, тому що:
Ваш ноутбук – це не місце для джерела ресурсів усієї інфраструктури
Управління файлом tfstate в git — кошмар
Пізніше, коли рівні інфраструктури почнуть зростати в кількох напрямках (кількість залежностей або ресурсів), буде легше тримати все під контролем.
Практикуйте послідовну структуру і умови найменувань:
Як і процедурний код, код Terraform повинен бути написаний для того, щоб люди спочатку прочитали; узгодженість допоможе потім, коли будуть зміни через шість місяців
Можна переміщати ресурси у файлі стану Terraform, але це буде важче зробити, якщо у вас непослідовна структура та імена
Робіть модулі ресурсів максимально простими
Не "хардкодьте" значення, які можна передати через змінні або виявити за допомогою джерел даних
Використовуйте джерела даних та terraform_remote_state
спеціально як з'єднувальники між модулями інфраструктури у межах композиції
У цій книзі приклади проектів згруповано за складністю - від малих до дуже великих інфраструктур. Цей поділ не є суворим, тому перевірте також інші конструкції.
Наявність невеликої інфраструктури означає, що існує невелика кількість залежностей і мало ресурсів. У міру розвитку проекту стає очевидною необхідність пов’язати виконання конфігурацій Terraform, під’єднуючи різні модулі інфраструктури та передаючи значення в межах композиції.
Існує принаймні 5 окремих груп рішень для оркестровки, які використовують розробники:
Лише Terraform. Дуже просто, розробники повинні знати тільки Terraform, щоб виконати роботу.
Terragrunt. Чистий інструмент оркестрування, який можна використовувати для оркестрування всієї інфраструктури, а також для обробки залежностей. Terragrunt працює з інфраструктурними модулями та композиціями, тому зменшує дублювання коду.
In-house скрипти. Часто це відбувається як відправна точка для оркестрування і перед відкриттям Terragrunt.
Ansible або подібний інструмент автоматизації загального призначення. Зазвичай використовується, коли Terraform адаптований після Ansible, або коли Ansible UI активно використовується.
Crossplane та інші Kubernetes-натхненні рішення. Іноді має сенс використовувати екосистему Kubernetes і використовувати функцію циклу узгодження для досягнення бажаного стану ваших конфігурацій Terraform. Перегляньте відео Crossplane vs Terraform для додаткової інформації.
З огляду на це, у книзі розглядаються перші два з цих структурних проектів, тобто лише Terraform і Terragrunt.
Дивіться приклади структур коду для Terraform чи Terragrunt у наступних частинах.
Не повинно бути ніяких причин не дотримуватися принаймні цих умов :)
Майте на увазі, що реальні хмарні ресурси часто мають обмеження у дозволених іменах. Деякі ресурси, наприклад, не можуть містити тире, деякі мають бути у формі camel-cased стилю. Умови в цій книзі посилаються на самі імена Terraform.
Використовуйте _
(підкреслення) замість -
(тире) всюди (імена ресурсів, імена джерел даних, імена змінних, вихідні дані тощо).
Віддавайте перевагу використанню малих літер і цифр (навіть якщо підтримується UTF-8).
Не повторюйте тип ресурсу в назві ресурсу (ні частково, ні повністю):
resource "aws_route_table" "public" {}
resource "aws_route_table" "public_route_table" {}
resource "aws_route_table" "public_aws_route_table" {}
Ім'я ресурсу повинно називатись this,
якщо немає більш описової та загальної назви, або якщо модуль ресурсів створює один ресурс цього типу (наприклад, у існує єдиний ресурс типу aws_nat_gateway
і декілька типів ресурсівaws_route_table
, так що aws_nat_gateway
має бути названий this
і aws_route_table
повинен мати більш описову назву - наприклад - приватний, публічний, база даних).
Завжди використовуйте іменники в однині для назв.
Використання - всередині значень аргументів і в місцях, де значення буде доступне для людини (наприклад, всередині імені DNS екземпляра RDS).
Включайте аргумент count
/ for_each
всередині блоку ресурсу або джерела даних як перший аргумент угорі та розділяйте новим рядком після нього.
Включайте аргумент tags,
якщо це підтримується ресурсом, як останній реальний аргумент, наступний за depends_on
та lifecycle
, якщо необхідно. Всі вони повинні бути розділені одним порожнім рядком.
При використанні умов в аргументіcount
/ for_each
віддавайте перевагу логічним значенням замість використання length
або інших виразів.
count
/ for_each
count
Не винаходьте велосипед у ресурсних модулях: використовуйте name
, description
, і default
значення для змінних, як зазначено в розділі «Довідник аргументів» для ресурсу, з яким ви працюєте.
Підтримка перевірки змінних досить обмежена (наприклад, не можна отримати доступ до інших змінних або виконати пошук). Плануйте відповідно, тому що в багатьох випадках ця функція не корисна.
Використовуйте форму множини в імені змінної, якщо тип є list(...)
або map(...)
.
Упорядковуйте ключі у змінному блоці, як описано далі: description
, type
, default
, validation
.
Завжди включайте description
для всіх змінних, навіть якщо ви думаєте, що це очевидно (це знадобиться вам у майбутньому).
Віддавайте перевагу використанню простих типів (number
, string
, list(...)
, map(...),
над спеціальними, як наприклад object(),
якщо вам не потрібні жорсткі обмеження для кожного ключа.
Використовуйте спеціальні типи, наприклад map(map(string))
якщо всі елементи у map мають одинаковий тип (наприклад, string
) або можна конвертувати в нього (наприклад тип number
можна конвертувати у string
).
Використовуйте тип any
щоб відключити перевірку типу, починаючи з певної глибини або коли має підтримуватися декілька типів.
Значенння {}
це іноді map, а іноді - object. Використовуйте tomap(...)
щоб зробити map, тому що немає можливості зробити об'єкт.
Робіть вихідні дані узгодженими і зрозумілими за межами їх області (коли користувач використовує модуль, має бути очевидним, який тип і атрибут значення він повертає).
Ім’я виводу має описувати властивість, яку він містить, і бути менш вільною формою, ніж ви зазвичай хотіли б.
Хороша структура назви виводу виглядає так {name}_{type}_{attribute}
, де:
{name} -
це ім’я ресурсу або джерела даних без префікса постачальника. {name}
для aws_subnet
- це subnet
, дляaws_vpc
- це vpc
.
{type}
є різновидом джерела ресурсів.
{attribute}
є атрибутом, який повертає вихідні дані.
Завжди включайте description
для всіх результатів, навіть якщо ви думаєте, що це очевидно.
Уникайте налаштування чутливих
аргументів, якщо ви повністю не контролюєте використання цього виводу в усіх місцях і у всіх модулях.
Віддавайте перевагуtry()
(доступний з Terraform 0.13) над element(concat(...))
(застарілий підхід для версій до 0.13)
Повертає щонайбільше один ідентифікатор із групи безпеки:
Якщо є декілька ресурсів одного типу, це слід пропустити в назві виводу:
FTP (Frequent Terraform Problems)
- Інструмент оркестрування
- Код лінтер
- Менеджер версій
- Автоматизація Pull Request
- Колекція git хуків для Terraform, щоб використовувати із
- Оцінка вартості інфраструктури для Terraform в pull requests. Працює з Terragrunt, Atlantis, й pre-commit-terraform.
Необхідно вказувати версії ресурсних та інфраструктурних модулів. Постачальники повинні бути налаштовані за межами модулів, але тільки у композиції. Також можна заблокувати версії провайдерів і Terraform.
Головного інструменту керування залежностями немає, але є декілька порад, щоб зробити пекло залежностей менш проблематичним. Наприклад, можна використовувати для автоматизації оновлень залежностей. Dependabot створює pull requests, щоб підтримувати ваші залежності в безпеці та актуальності. Dependabot підтримує конфігурації Terraform.
Цей документ - спроба систематично описати найкращі методи використання Terraform та надати рекомендації щодо найбільш частих проблем, які виникають у його користувачів.
- це досить новий проект (як і більшість інструментів DevOps), який було розпочато у 2014 році.
Terraform є одним із найпотужніших і найбільш використовуваних на даний момент інтрументів, які дозволяють керувати інфраструктурою як кодом. Це дозволяє розробникам робити багато речей і не обмежує їх у створенні того, що, можливо, буде важко підтримувати або інтегрувати.
Деяка інформація, описана в цій книзі, на перший погляд може здатися не найкращою практикою. Я знаю це, і, щоб допомогти читачам відокремити, що є загальноприйнятими найкращими практиками, а що - просто додатковим упевненим способом робити речі, я іноді використовую підказки, щоб надати деякий контекст, а також піктограми, щоб визначити рівень відповідності найкращим практикам.
Книга вийшла в сонячному Мадриді у 2018 році і доступна безкоштовно за цим посиланням -
Кілька років потому вона була оновлена більш актуальними передовими методами, доступними з Terraform 1.0. Зрештою, ця книга має містити більшість незаперечних найкращих практик та рекомендацій для користувачів Terraform.
Please if you want to become a sponsor.
Зв’яжіться зі мною, якщо ви хочете допомогти перекласти цю книгу іншими мовами.
Я завжди хочу отримувати відгуки та оновлювати цю книгу, коли спільнота росте, а нові ідеї втілюються та перевіряються часом.
Ця робота ліцензована згідно з Apache 2 License. Дивіться ЛІЦЕНЗІЯ для повної інформації.
Автори та учасники цього контенту не можуть гарантувати достовірність інформації, що міститься тут. Будь ласка, переконайтеся, що ви розумієте, що надана тут інформація надається безкоштовно, і що між вами та будь-якими особами, пов’язаними з цим контентом або проектом, не укладається жодна угода чи контракт. Автори та учасники не приймають і відмовляються від будь-якої відповідальності перед будь-якою стороною за будь-які втрати, пошкодження або порушення, спричинені помилками або упущеннями в інформації з цього контенту, або пов’язані з ним, незалежно від того, чи є ці помилки або упущення внаслідок недбалості, випадково чи за будь-якої іншої причини.
Copyright © 2018-2023 Anton Babenko.
Джерело:
Цей приклад містить код як приклад структурування конфігурацій Terraform для інфраструктури великого розміру, яка використовує:
2 AWS акаунти
2 регіона
2 окремих середовища (prod
та stage, у яких немає нічого спільного
). Кожне середовище живе в окремому акаунті AWS і охоплює ресурси між 2 регіонами
Кожне середовище використовує різну версію готового інфраструктурного модуля (alb), отриманого з
Кожне середовище використовує одинакову версію модулів/мережі внутрішнього модуля, оскільки джерело отримане з локального каталогу.
У великому проекті, як описано тут, переваги використання Terragrunt стають дуже помітними. Перегляньте .
Ідеально підходить для проектів, де інфраструктура логічно розділена (окремі акаунти AWS)
Добре, коли немає необхідності змінювати ресурси, спільні між акаунтами AWS (одне середовище = один акаунт AWS = один файл стану)
Добре, коли немає потреби в оркестровці змін між середовищами
Добре, коли ресурси інфраструктури відрізняються для кожного середовища спеціально і не можуть бути узагальнені (наприклад, деякі ресурси відсутні в одному середовищі або в деяких регіонах)
Із розвитком проекту буде все важче підтримувати ці середовища в актуальному стані одне з одним. Подумайте про використання інфраструктурних модулів (готових або внутрішніх) для повторюваних завдань.
Приклади та модулі Terraform повинні містити документацію, яка пояснює функції та як їх використовувати.
Усі посилання у файлах README.md мають бути абсолютними, щоб веб-сайт Terraform Registry відображав їх правильно.
Документація може включати схеми, створені за допомогою і креслення, створені за допомогою .
Використовуйте щоб переконатися, що код валідний, правильно відформатований і автоматично задокументований, перш ніж запушати його на git і надати для подальшого код рев'ю.
- це фреймворк для керування та підтримки багатомовних pre-commit хуків. Він написаний на Python і є потужним інструментом для автоматичного виконання завдань на машині розробника до того, як код буде передано в репозиторій git. Зазвичай він використовується для запуску лінтерів і форматування коду (дивіться ).
З конфігураціями Terraform pre-commit
можна використовувати для форматування та перевірки коду, а також для оновлення документації.
Перегляньте , щоб ознайомитися з ним та існуючими репозиторіями (наприклад, ), де це вже використовується.
- це інструмент, який створює документацію з модулів Terraform у різних вихідних форматах. Ви можете запускати його вручну (без pre-commit хуків, або ж використовувати , щоб документація оновлювалася автоматично).
@todo: Document module versions, release, GH actions
Блог пост від :
Офіційна документація Terraform описує . Уважно прочитайте її, щоб зрозуміти решту цього розділу.
У цьому розділі описуються ключові поняття, які використовуються в книзі.
Ресурс - це aws_vpc
, aws_db_instance і т.д.
Ресурс належить провайдеру, включаючи аргументи, вихідні дані; він також має життєвий цикл . Ресурс можна створювати, отримувати, оновлювати та видаляти.
Ресурсний модуль - це колекція підключених ресурсів, які разом виконують спільну дію (наприклад, створює VPC, сабнети, NAT gateway і т.д.). Він залежить від конфігурації провайдера, яка може бути визначена в ньому або в структурах вищого рівня (наприклад, в модулі інфраструктури).
Інфраструктурний модуль - це колекція ресурсних модулів, які можуть бути логічно не підключені, але в поточній ситуації/проекті/налаштуваннях служать єдиній меті. Він визначає конфігурацію для провайдерів, які передаються до поточних ресурсних модулів і до ресурсів. Зазвичай він обмежується роботою в одній сутності на один логічний роздільник (наприклад, AWS регіон, Google проект).
Наприклад, модуль використовує ресурсні модулі ( та ) щоб керувати інфраструктурою, необхідною для роботи на .
Інший приклад - , де численні модулі використовуються разом для керування інфраструктурою, а також для використання ресурсів Docker, щоб мати змогу створювати, пушати та розгортати образи Docker. Все в одному наборі.
Композиція - це колекція інфраструктурних модулів, які можуть охоплювати декілька логічно відокремлених областей (наприклад, декілька AWS регіонів або декілька AWS акаунтів). Композиція використовується для опису повної інфраструктури, необхідної для всієї організації або проекту.
Композиція складається з інфраструктурних модулів, які, в свою чергу, складаються з ресурсних модулів, які потім реалізують індивідуальні ресурси.
Джерело даних виконує лише read-only операції та залежить від конфігурації постачальника, використовується в ресурсних та інфраструктурних модулях.
Джерело даних terraform_remote_state
діє як з'єднувальник для модулів і композицій вищого рівня.
Провайдери, постачальники та деякі інші терміни дуже добре описані в офіційній документації, тому немає сенсу повторювати їх тут. На мою думку вони мають мало спільного з написанням якісних Terraform модулів.
Доступ до даних між молекулами (ресурсними та інфраструктурними модулями) здійснюється за допомогою вихідних даних модулів та джерел даних.
Якщо спробувати описати вище зазначені поняття у псевдовідношеннях, це може виглядати так:
Джерело:
Цей приклад містить код як приклад структурування конфігурацій Terraform для невеликої інфраструктури, де не використовуються зовнішні залежності.
Ідеально підходить для початку та реорганізації у процесі
Ідеально підходить для невеликих ресурсних модулів
Добре підходить для невеликих і лінійних інфраструктурних модулів (наприклад, )
Добре для невеликої кількості ресурсів (менше ніж 20-30)
Єдиний файл стану для всіх ресурсів може уповільнити процес роботи з Terraform, якщо кількість ресурсів зростає (подумайте про використання аргументу-target
щоб обмежити кількість ресурсів)
Існує також workshop для людей, які хочуть практикувати речі, описані в цьому посібнику.
Знаходиться тут -
.
Якщо вихідні дані повертають значення з функціями інтерполяції та кількома ресурсами, {name}
і {type},вони
мають бути якомога загальнішими (це як префікс слід пропустити). .
Якщо повертається значення у вигляді списка, воно повинно мати назву у множині. .
Якщо вас цікавлять конкретні теми, будь ласка , або опишіть проблему, яку ви найбільше хочете прояснити. Якщо ви думаєте, що маєте контент, і хочете зробити внесок, напишіть чернетку та зробіть Pull Request (не турбуйтеся про написання гарного тексту на цьому етапі!)
Ця книга підтримується за допомогою інших дописувачів і перекладачів.
data source дозволяє зовнішній програмі діяти, відкриваючи довільні дані для використання в інших місцях конфігурації Terraform. Як приклад можна назвати , де ім'я файлу обчислюється шляхом виклику зовнішнього Python скрипта.
Інший приклад - джерело даних робить HTTP GET запит на заданий URL і експортує інформацію про відповідь, яка часто корисна для отримання інформації з кінцевих точок, де рідний Terraform провайдер не існує.
Інфраструктурні модулі та композиції повинні зберігати свої у віддаленому місці, де їх зможуть отримати інші керованим способом (наприклад через ACL, версії, журналювання).
У той час як окремі ресурси – це атоми в інфраструктурі, ресурсні модулі - це молекули. Модуль — це найменший версійний блок, який можна спільно використовувати. Він має точний список аргументів, реалізує базову логіку, щоб виконувати потрібну функцію. Наприклад, модуль створює aws_security_group
і aws_security_group_rule
ресурси на основі вхідних даних. Цей ресурсний модуль сам по собі можна використовувати разом з іншими модулями для створення модуля інфраструктури.
Доступ між композиціями часто виконується використовуючи віддалений стан джерел даних. Існує .
Мало ресурсів, немає зовнішніх залежностей. Єдиний AWS акаунт. Єдиний регіон. Єдине середовище.
Так
Декілька середовищ та AWS акаунтів, готові інфраструктурні модулі з використанням Terraform.
Так
Багато AWS акаунтів, багато регіонів, нагальна потреба скоротити копі-пасти, власні модулі інфраструктури, інтенсивне використання композицій. Використання Terraform.
WIP
Декілька провайдерів (AWS, GCP, Azure). Багатохмарне розгортання. Використання Terraform.
Ні
середня
Декілька акаунтів і середовищ AWS, готові інфраструктурні модулі, шаблони композиції за допомогою Terragrunt.
Ні
велика
Багато AWS акаунтів, багато регіонів, нагальна потреба скоротити копі-пасти, кастомні модулі інфраструктури, інтенсивне використання композицій. Використання Terragrunt.
Ні
дуже велика
Декілька постачальників (AWS, GCP, Azure). Багатохмарне розгортання. Використання Terragrunt.
Ні