Какво представляват модулите 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 Registry, тогава вече разбирате идеята
  • хранилище на Git (персонализирано или GitHub / BitBucket)
  • HTTP URL към .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да се използва по-късно като вход:

This explicit declaration of the output is the way to expose some resource (or information about it) outside — to the scope of the 'root' module, hence to make it available for other modules.

Next, when we call the child module "server" in the root module, we should assign the output from the "network" module to the variable of the "server" module:

network_id = module.network.network_id

Here's what the final code for calling our child modules will look like:

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 }

This example configuration would create 5 instances of the same server, with all the necessary resources, in the network we created with as a separate module.

Wrapping up

Now you should understand what modules are and what do they do.

If you're at the beginning of your Terraform journey, here are some suggestions for the next steps.

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.