Що таке модулі Terraform і як вони працюють?

Дивно, але багато початківців пропускають модулі Terraform заради простоти, або так вони вважають.

Пізніше вони опиняються в сотнях рядків конфігураційного коду.

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

Зверніть увагу: я не використовую реальні приклади коду з якимись конкретними постачальниками, такими як AWS або Google, навмисно, просто для спрощення.

Модулі тераформа

Ви вже пишете модулі

Навіть коли ви не створюєте модуль навмисно, якщо ви використовуєте Terraform, ви вже пишете модуль - так званий " кореневий " модуль.

Будь-який конфігураційний файл Terraform ( .tf) в каталозі, навіть лише один, утворює модуль.

Що робить модуль?

Модуль Terraform дозволяє створювати логічну абстракцію вгорі деякого набору ресурсів. Іншими словами, модуль дозволяє згрупувати ресурси разом і повторно використовувати цю групу пізніше, можливо, багато разів.

Припустимо, у нас є віртуальний сервер з деякими функціями, розміщеними в хмарі. Який набір ресурсів може описати цей сервер? Наприклад:

  • сама віртуальна машина, створена з якогось образу
  • прикріплений блоковий пристрій певного розміру для додаткового зберігання
  • статичний загальнодоступний IP, зіставлений із віртуальним мережевим інтерфейсом сервера
  • набір правил брандмауера, що підключаються до сервера
  • інші речі, такі як інший блок-пристрій, додатковий мережевий інтерфейс тощо

Тепер припустимо, що вам потрібно створити цей сервер із набором ресурсів багато разів. Тут модулі дійсно корисні - ви не хочете повторювати той самий код конфігурації знову і знову, правда?

Ось приклад, який ілюструє, як може називатися наш «серверний» модуль.

" Викликати модуль " означає використовувати його у файлі конфігурації.

Тут ми створюємо 5 екземплярів "сервера", використовуючи один набір конфігурацій (в модулі):

module "server" { count = 5 source = "./module_server" some_variable = some_value }

Організація модуля: дочірній і кореневий

Звичайно, ви, мабуть, захочете створити більше одного модуля. Ось кілька загальних прикладів:

  • така мережа, як віртуальна приватна хмара (VPC)
  • хостинг статичного вмісту (тобто відра)
  • балансування навантаження та пов'язані з ним ресурси
  • конфігурація журналювання
  • або що ще ви вважаєте окремим логічним компонентом інфраструктури

Скажімо, у нас є два різних модулі: «серверний» і «мережевий» модулі. Модуль під назвою "мережа" - це місце, де ми визначаємо та налаштовуємо нашу віртуальну мережу та розміщуємо в ній сервери:

module "server" { source = "./module_server" some_variable = some_value } module "network" { source = "./module_network" some_other_variable = some_other_value }

Коли у нас є деякі користувацькі модулі, ми можемо називати їх "дочірніми" модулями. А файл конфігурації, де ми називаємо дочірні модулі, відноситься до кореневого модуля.

Дочірній модуль можна отримати з багатьох місць:

  • місцеві стежки
  • офіційний реєстр Terraform - якщо ви знайомі з іншими реєстрами, такими як реєстр Docker, то ви вже розумієте ідею
  • сховище Git (власне або GitHub / BitBucket)
  • URL-адресу HTTP до архіву .zip з модулем

Але як можна передавати деталі ресурсів між модулями?

У нашому прикладі сервери слід створювати в мережі. То як ми можемо сказати модулю "сервер" створювати віртуальні машини в мережі, яка була створена в модулі, який називається "мережа"?

Тут відбувається інкапсуляція .

Інкапсуляція модуля

Інкапсуляція в Terraform складається з двох основних концепцій: обсягу модуля та явного впливу ресурсів.

Сфера застосування модуля

Усі екземпляри ресурсів, імена і, отже, видимість ресурсів, ізольовані в області модуля. Наприклад, модуль "A" не бачить і не знає про ресурси в модулі "B" за замовчуванням.

Видимість ресурсів, яку іноді називають ізоляцією ресурсів, гарантує, що ресурси матимуть унікальні імена в просторі імен модуля. Наприклад, з нашими 5 примірниками модуля "сервер":

module.server[0].resource_type.resource_name module.server[1].resource_type.resource_name module.server[2].resource_type.resource_name ...

З іншого боку, ми могли б створити два екземпляри одного модуля з різними іменами:

module "server-alpha" { source = "./module_server" some_variable = some_value } module "server-beta" { source = "./module_server" some_variable = some_value }

У цьому випадку найменування або адреса ресурсів буде таким:

module.server-alpha.resource_type.resource_name module.server-beta.resource_type.resource_name

Явний вплив ресурсів

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

За замовчуванням наш модуль "сервер" не знає про мережу, яка була створена в модулі "мережа".

Тому ми повинні оголосити outputзначення в модулі "мережа" для експорту його ресурсу або атрибута ресурсу до інших модулів.

Модуль "сервер" повинен оголосити a variableдля подальшого використання як вхід:

Це явне оголошення вихідних даних - це спосіб виставити якийсь ресурс (або інформацію про нього) зовні - до сфери дії «кореневого» модуля, отже, зробити його доступним для інших модулів.

Далі, коли ми називаємо дочірній модуль "сервером" у кореневому модулі, нам слід призначити вихідні дані з "мережевого" модуля змінній модуля "сервер":

network_id = module.network.network_id

Ось як виглядатиме остаточний код для виклику наших дочірніх модулів:

module "server" { count = 5 source = "./module_server" some_variable = some_value network_id = module.network.network_id } module "network" { source = "./module_network" some_other_variable = some_other_value }

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

Підведенню

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

Якщо ви знаходитесь на початку своєї подорожі Terraform, ось кілька порад щодо подальших кроків.

I encourage you to take this short tutorial from HashiCorp, the creators of Terraform, about modules: "Organize Configuration".

Also, there is a great comprehensive study guide which covers everything from beginner to advanced concepts about Terraform: "Study Guide - Terraform Associate Certification".

The modular code structure makes your configuration more flexible and yet easy to be understood by others. The latter is especially useful for a team.

If you liked the article, follow me on Twitter (@vasylenko) where I occasionally share my findings and tips about Terraform, AWS, Ansible, and other DevOps-related technologies.