# Структура кода

Пытанні, звязаныя са структурай кода Terraform, нашмат больш частыя ў супольнасці. Кожны ў пэўны момант таксама задумваўся пра найлепшую структуру кода для праекта.

## Як мне структураваць свае канфігурацыі Terraform?

Гэта адно з тых пытанняў, дзе існуе шмат рашэнняў, і даць універсальную параду вельмі складана, таму давайце пачнём з таго, каб зразумець, з чым мы маем справу.

* Якая складанасць вашага праекта?
  * Колькасць звязаных рэсурсаў
  * Колькасць Terraform правайдэраў (гл. заўвагу ніжэй пра "logical providers")
* Як часта змяняецца ваша інфраструктура?
  * **Ад** аднаго разу на месяц/тыдзень/дзень
  * **Да** пастаяннага (кожны раз, калі з'яўляецца новая каміт)
* Ініцыятары змены кода? *Ці дазваляеце вы CI-серверу абнаўляць рэпазіторый, калі будуецца новы артыфакт?*
  * Толькі распрацоўшчыкі могуць рабіць push ў інфраструктурны рэпазіторый
  * Кожны можа прапанаваць змены ў што заўгодна, адкрыўшы PR (у тым ліку аўтаматызаваныя задачы, што выконваюцца на CI-серверы)
* Якую платформу разгортвання або сэрвіс разгортвання вы выкарыстоўваеце?
  * AWS CodeDeploy, Kubernetes або OpenShift патрабуюць крыху іншага падыходу
* Як групуюцца асяроддзі?
  * Па асяроддзі, рэгіёне, праекце

{% hint style="info" %}
*Logical providers* працуюць цалкам у рамках логікі Terraform і вельмі часта не ўзаемадзейнічаюць з іншымі сэрвісамі, таму мы можам лічыць іх складанасць O(1). Самыя распаўсюджаныя logical providers уключаюць [random](https://registry.terraform.io/providers/hashicorp/random/latest/docs), [local](https://registry.terraform.io/providers/hashicorp/local/latest/docs), [terraform](https://www.terraform.io/docs/providers/terraform/index.html), [null](https://registry.terraform.io/providers/hashicorp/null/latest/docs), [time](https://registry.terraform.io/providers/hashicorp/time/latest).
{% endhint %}

## Пачатак працы з структураваннем канфігурацый Terraform

Размяшчэнне ўсяго кода ў файле `main.tf` ёсць добрай ідэяй, калі вы пачынаеце працу або пішаце прыклад коду. Ва ўсіх іншых выпадках лепш мець некалькі файлаў, лагічна падзеленых наступным чынам:

* `main.tf` - выклікае модулі, locals і крыніц даных для стварэння ўсіх рэсурсаў
* `variables.tf` - змяшчае дэкларацыі пераменных, якія выкарыстоўваюцца ў `main.tf`
* `outputs.tf` - змяшчае outputs ад рэсурсаў, створаных у `main.tf`
* `versions.tf` - змяшчае патрабаванні да версій для Terraform і правайдэраў

`terraform.tfvars` не павінен выкарыстоўвацца нідзе, акрамя [кампазіцыі](https://www.terraform-best-practices.com/be/key-concepts#composition).

## Як разважаць пра структуру канфігурацыі Terraform?

{% hint style="info" %}
Калі ласка, пераканайцеся, што вы разумееце ключавыя паняцці - [рэсурсны модуль](https://www.terraform-best-practices.com/be/key-concepts#resource-module), [інфраструктурны модуль](https://www.terraform-best-practices.com/be/key-concepts#infrastructure-module), і [кампазіцыю](https://www.terraform-best-practices.com/be/key-concepts#composition), бо яны выкарыстоўваюцца ў наступных прыкладах.
{% endhint %}

### Агульныя рэкамендацыі па структураванні кода

* З меншай колькасцю рэсурсаў працаваць лягчэй і хутчэй
  * Абедзве `terraform plan` і `terraform apply` робяць выклікі воблачнага API для праверкі статусу рэсурсаў
  * Калі ваша інфраструктура знаходзіцца цалкам ў адзінай кампазіцыі, гэта можа заняць некаторы час
* Радыус разрыву (у выпадку парушэння бяспекі) меншы пры меншай колькасці рэсурсаў
  * Ізаляцыя не звязаных рэсурсаў адно ад аднаго шляхам размяшчэння іх у асобных кампазіцыях зніжае рызыку, калі нешта пойдзе не так
* Пачынайце праект з выкарыстаннем дыстанцыйнага стану, таму што:
  * Ваш ноўтбук ня ёсць месцам для асноўнай крыніцы праўды вашай інфраструктуры
  * Кіраванне `tfstate` файлам у git — гэта кашмар
  * Пазней, калі слаі інфраструктуры пачнуць расці ў розных напрамках (колькасць залежнасцей або рэсурсаў), будзе лягчэй падтрымліваць усё пад кантролем
* Выкарыстоўвайце паслядоўную структуру і канвенцыю [наймення](https://www.terraform-best-practices.com/be/naming):
  * Як і працэдурны код, код Terraform павінен пісацца ў першую чаргу для людзей, якія яго чытаюць; паслядоўнасць дапаможа, калі змены адбудуцца праз шэсць месяцаў
  * У стане Terraform магчыма перамяшчаць рэсурсы, але гэта можа быць складаней, калі ў вас несумяшчальныя структура і назва
* Захоўвайце модулі рэсурсаў максімальна простымі
* Не кадуйце жорстка значэнні, якія можна перадаць праз пераменныя або атрымаць з дапамогай крыніц дадзеных
* Выкарыстоўвайце крыніцы даных і `terraform_remote_state` у прыватнасці як злучальны элемент паміж модулямі інфраструктуры ў кампазіцыі

У гэтай кнізе прыклады праектаў аб'яднаны паводле *складанасці* - ад невялікіх да вельмі буйных інфраструктур. Гэты падзел не з'яўляецца строгім, таму праверце і іншыя структуры.

### Аркестрацыя інфраструктурных модуляў і кампазіцый

Малая інфраструктура азначае невялікую колькасць залежнасцей і рэсурсаў. З ростам праекта становіцца відавочнай неабходнасць у ланцуговым выкананні канфігурацый Terraform, злучэнні розных інфраструктурных модуляў і перадачы значэнняў у межах кампазіцыі.

Існуе прынамсі 5 асобных груп рашэнняў для аркестрацыі, якія выкарыстоўваюць распрацоўшчыкі:

1. Толькі Terraform. Вельмі прамалінейнае рашэнне, распрацоўшчыкам трэба ведаць толькі Terraform, каб выканаць працу.
2. Terragrunt. Чысты інструмент для аркестрацыі, які можна выкарыстоўваць для аркестрацыі ўсёй інфраструктуры, а таксама для кіравання залежнасцямі. Terragrunt працуе з модулямі інфраструктуры і кампазіцыямі натуральным чынам, таму ён змяншае дубліраванне кода.
3. Уласныя скрыпты. Часта гэта з'яўляецца адпраўной кропкай у пераходзе да аркестрацыі і выкарыстоўваецца да таго, як распрацоўшчыкі адкрыюць для сябе Terragrunt.
4. Ansible або іншыя падобныя інструменты аўтаматызацыі агульнага прызначэння. Звычайна выкарыстоўваюцца, калі Terraform укараняецца пасля Ansible або калі актыўна выкарыстоўваецца графічны інтэрфейс Ansible.
5. [Crossplane](https://crossplane.io) і іншыя рашэнні, натхнёныя Kubernetes. Часам мае сэнс выкарыстоўваць экасістэму Kubernetes і прымяняць функцыю reconciliation loop, каб дасягнуць жаданага стану вашых канфігурацый Terraform. Каб даведацца больш, паглядзіце відэа [Crossplane vs Terraform](https://www.youtube.com/watch?v=ELhVbSdcqSY).

Улічваючы гэта, у гэтай кнізе разглядаюцца першыя дзве з гэтых структур праектаў: толькі Terraform і Terragrunt.

Прыклады структур кода для [Terraform](https://www.terraform-best-practices.com/be/examples/terraform) або [Terragrunt](https://www.terraform-best-practices.com/be/examples/terragrunt) глядзіце ў наступным раздзеле.
