Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Цей приклад містить код як приклад структурування конфігурацій Terraform для інфраструктури великого розміру, яка використовує:
2 AWS акаунти
2 регіона
2 окремих середовища (prod
та stage, у яких немає нічого спільного
). Кожне середовище живе в окремому акаунті AWS і охоплює ресурси між 2 регіонами
Кожне середовище використовує одинакову версію модулів/мережі внутрішнього модуля, оскільки джерело отримане з локального каталогу.
Ідеально підходить для проектів, де інфраструктура логічно розділена (окремі акаунти AWS)
Добре, коли немає необхідності змінювати ресурси, спільні між акаунтами AWS (одне середовище = один акаунт AWS = один файл стану)
Добре, коли немає потреби в оркестровці змін між середовищами
Добре, коли ресурси інфраструктури відрізняються для кожного середовища спеціально і не можуть бути узагальнені (наприклад, деякі ресурси відсутні в одному середовищі або в деяких регіонах)
Із розвитком проекту буде все важче підтримувати ці середовища в актуальному стані одне з одним. Подумайте про використання інфраструктурних модулів (готових або внутрішніх) для повторюваних завдань.
Приклади та модулі Terraform повинні містити документацію, яка пояснює функції та як їх використовувати.
Усі посилання у файлах README.md мають бути абсолютними, щоб веб-сайт Terraform Registry відображав їх правильно.
З конфігураціями Terraform pre-commit
можна використовувати для форматування та перевірки коду, а також для оновлення документації.
@todo: Document module versions, release, GH actions
Питання, пов’язані зі структурою коду 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 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 активно використовується.
З огляду на це, у книзі розглядаються перші два з цих структурних проектів, тобто лише 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" {}
Завжди використовуйте іменники в однині для назв.
Використання - всередині значень аргументів і в місцях, де значення буде доступне для людини (наприклад, всередині імені DNS екземпляра RDS).
Включайте аргумент count
/ for_each
всередині блоку ресурсу або джерела даних як перший аргумент угорі та розділяйте новим рядком після нього.
Включайте аргумент tags,
якщо це підтримується ресурсом, як останній реальний аргумент, наступний за depends_on
та lifecycle
, якщо необхідно. Всі вони повинні бути розділені одним порожнім рядком.
При використанні умов в аргументіcount
/ for_each
віддавайте перевагу логічним значенням замість використання length
або інших виразів.
count
/ for_each
count
Не винаходьте велосипед у ресурсних модулях: використовуйте name
, description
, і default
значення для змінних, як зазначено в розділі «Довідник аргументів» для ресурсу, з яким ви працюєте.
Підтримка перевірки змінних досить обмежена (наприклад, не можна отримати доступ до інших змінних або виконати пошук). Плануйте відповідно, тому що в багатьох випадках ця функція не корисна.