Азбаски параметри ҳисоб ба арзиши статикӣ муқаррар карда шудааст, ин код бе мушкилот кор мекунад: вақте ки шумо фармони татбиқро иҷро мекунед, он се сервери EC2 эҷод мекунад. Аммо чӣ мешавад, агар шумо хоҳед, ки як серверро дар ҳар як минтақаи дастрас (AZ) дар минтақаи ҳозираи AWS-и худ ҷойгир кунед? Шумо метавонед коди худро бигузоред, ки рӯйхати минтақаҳоро аз манбаи маълумоти aws_availability_zones бор кунед ва сипас тавассути ҳар яки онҳо давр занед ва дар он бо истифода аз параметри ҳисоб ва дастрасии индекси массив сервери EC2 эҷод кунед:
Агар шумо нақшаи terraform-ро дар ин код иҷро кунед, шумо хатои зеринро мегиред:
Error: Invalid count argument
on main.tf line 30, in resource "aws_instance" "example_3":
30: count = random_integer.num_instances.result
The "count" value depends on resource attributes that cannot be determined until apply, so Terraform cannot predict how many instances will be created. To work around this, use the -target argument to first apply only the resources that the count depends on.
Terraform талаб мекунад, ки ҳисоб ва for_each дар марҳилаи банақшагирӣ пеш аз эҷод ё тағир додани ҳама гуна захираҳо ҳисоб карда шаванд. Ин маънои онро дорад, ки count ва for_each метавонанд ба литералҳо, тағирёбандаҳо, манбаъҳои додаҳо ва ҳатто рӯйхатҳои захираҳо (то даме ки дарозии онҳо дар вақти банақшагирӣ муайян карда шавад) ишора мекунанд, аммо на ба тағирёбандаҳои баромади ҳисобшудаи захираҳо.
count ва for_each наметавонанд дар конфигуратсияи модул истифода шаванд
Ин код кӯшиш мекунад, ки ҳисобро дар дохили модул истифода барад, то се нусхаи манбаи веб-сервер-кластер эҷод кунад. Ё шумо метавонед пайваст кардани модулро дар асоси баъзе шартҳои мантиқӣ бо гузоштани параметри ҳисобаш ба 0 ихтиёрӣ гардонед. Ин метавонад ба рамзи оқилона монанд бошад, аммо ҳангоми иҷро кардани нақшаи terraform шумо ин хаторо пайдо мекунед:
Error: Reserved argument name in module block
on main.tf line 13, in module "count_example":
13: count = 3
The name "count" is reserved for use in a future version of Terraform.
resource "aws_iam_user" "existing_user" {
# Подставьте сюда имя уже существующего пользователя IAM,
# чтобы попрактиковаться в использовании команды terraform import
name = "yevgeniy.brikman"
}
Ҳоло, агар шумо фармони нақшаро иҷро кунед, Terraform нақшаи ба назар оқилонаи ҷойгиркуниро мебарорад:
Terraform will perform the following actions:
# aws_iam_user.existing_user will be created
+ resource "aws_iam_user" "existing_user" {
+ arn = (known after apply)
+ force_destroy = false
+ id = (known after apply)
+ name = "yevgeniy.brikman"
+ path = "/"
+ unique_id = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
Агар шумо фармони татбиқро иҷро кунед, шумо хатои зеринро мегиред:
Error: Error creating IAM User yevgeniy.brikman: EntityAlreadyExists:
User with name yevgeniy.brikman already exists.
on main.tf line 10, in resource "aws_iam_user" "existing_user":
10: resource "aws_iam_user" "existing_user" {
Мушкилот, албатта, дар он аст, ки корбари IAM бо ин ном аллакай вуҷуд дорад. Ва ин метавонад на танҳо бо корбарони IAM, балки қариб ба ҳама гуна манбаъҳо рӯй диҳад. Мумкин аст, ки касе ин захираро дастӣ ё бо истифода аз сатри фармон эҷод кунад, аммо дар ҳар сурат, мувофиқати ID-ҳо боиси ихтилофот мегардад. Вариантҳои зиёди ин хато вуҷуд доранд, ки аксар вақт навкоронро ба Terraform ба ҳайрат меорад.
Нуқтаи асосӣ дар он аст, ки фармони нақшаи terraform танҳо он захираҳоеро, ки дар файли давлатии Terraform нишон дода шудаанд, ба назар мегирад. Агар захираҳо бо ягон роҳи дигар сохта шаванд (масалан, ба таври дастӣ бо клик дар консоли AWS), онҳо дар файли давлатӣ ҷамъ намешаванд ва аз ин рӯ Terraform ҳангоми иҷрои фармони нақша онҳоро ба назар намегирад. Дар натича плане, ки дар назари аввал дуруст ба назар мерасад, бебарор мегардад.
Аз ин ду сабақ гирифтан лозим аст.
Агар шумо аллакай кор бо Terraform оғоз карда бошед, дигар чизеро истифода набаред. Агар як қисми инфрасохтори шумо бо истифода аз Terraform идора карда шавад, шумо дигар онро дастӣ тағир дода наметавонед. Дар акси ҳол, шумо на танҳо хатари хатогиҳои аҷиби Terraform доред, балки шумо инчунин бисёре аз бартариҳои IaC-ро рад мекунед, зеро код дигар муаррифии дақиқи инфрасохтори шумо нахоҳад буд.
Terraform ба AWS API занг мезанад, то корбари IAM-и шуморо пайдо кунад ва дар конфигуратсияи Terraform-и шумо ассотсиатсияи файли давлатӣ байни он ва манбаи aws_iam_user.existing_user эҷод кунад. Минбаъд, вақте ки шумо фармони нақшаро иҷро мекунед, Terraform медонад, ки корбари IAM аллакай вуҷуд дорад ва кӯшиш намекунад, ки онро дубора эҷод кунад.
Қобили зикр аст, ки агар шумо аллакай захираҳои зиёде дошта бошед, ки мехоҳед ба Terraform ворид кунед, ба таври дастӣ навиштани рамз ва ворид кардани ҳар яке аз онҳо як вақт метавонад душвор бошад. Аз ин рӯ, зарур аст, ки асбоберо ба мисли Terraforming (http://terraforming.dtan4.net/) ҷустуҷӯ кунед, ки метавонад ба таври худкор код ва давлатро аз ҳисоби AWS-и шумо ворид кунад.
Рефакторинг метавонад домҳои худро дошта бошад
Рефакторинг як таҷрибаи маъмул дар барномасозӣ аст, ки дар он шумо сохтори дохилии кодро тағир медиҳед ва рафтори беруниро бетағйир мегузоред. Ин барои равшантар, тозатар ва осонтар нигоҳ доштани код аст. Рефакторинг як усули ҳатмист, ки бояд мунтазам истифода шавад. Аммо вақте ки сухан дар бораи Terraform ё ягон асбоби дигари IaC меравад, шумо бояд хеле эҳтиёткор бошед, ки шумо аз "рафтори беруна" -и код чӣ дар назар доред, вагарна мушкилоти ғайричашмдошт ба миён меоянд.
Масалан, як намуди маъмули рефакторинг иваз кардани номҳои тағирёбанда ё функсияҳо бо номҳои фаҳмотар аст. Бисёре аз IDE-ҳо барои рефакторинг пуштибонии дохилӣ доранд ва метавонанд ба таври худкор тағирёбандаҳо ва функсияҳоро дар тамоми лоиҳа тағир диҳанд. Дар забонҳои барномасозии таъиноти умумӣ, ин як тартиби ночиз аст, ки шумо шояд дар бораи он фикр накунед, аммо дар Terraform шумо бояд бо ин хеле эҳтиёткор бошед, вагарна шумо метавонед қатъро эҳсос кунед.
Масалан, модули вебсервер-кластер дорои тағирёбандаи вуруди cluster_name:
variable "cluster_name" {
description = "The name to use for all the cluster resources"
type = string
}
Тасаввур кунед, ки шумо ин модулро барои ҷойгиркунии микросервис бо номи foo оғоз кардед. Баъдтар, шумо мехоҳед хидмати худро ба бар иваз кунед. Ин тағирот метавонад ночиз ба назар расад, аммо дар асл он метавонад боиси халалдор шудани хидмат гардад.
Далели он аст, ки модули вебсервер-кластер тағирёбандаи cluster_name-ро дар як қатор захираҳо, аз ҷумла параметри номи ду гурӯҳи амниятӣ ва ALB истифода мебарад:
Terraform ҳар як ID-и манбаъро бо ID провайдери абр пайваст мекунад. Масалан, iam_user бо ID корбари AWS IAM ва aws_instance бо ID сервери AWS EC2 алоқаманд аст. Агар шумо ID-и манбаъро иваз кунед (бигӯед, ки аз мисол ба cluster_instance, чунон ки дар aws_security_group аст), ба Terraform он гӯё пайдо мешавад, ки шумо манбаи кӯҳнаро нест кардаед ва манбаи навро илова кардаед. Агар шумо ин тағиротҳоро татбиқ кунед, Terraform гурӯҳи бехатарии кӯҳнаро нест мекунад ва як гурӯҳи нав эҷод мекунад, дар ҳоле ки серверҳои шумо ҳама гуна трафики шабакаро рад мекунанд.