Terraform pitfalls

Terraform pitfalls
Bari mu haskaka ƴan matsaloli, gami da waɗanda ke da alaƙa da madaukai, idan bayanai da dabarun turawa, da ƙarin batutuwan da suka shafi Terraform gabaɗaya:

  • ƙidaya kuma don_kowane sigogi suna da iyaka;
  • ƙayyadadden lokacin ƙaddamarwa na sifili;
  • ko da kyakkyawan shiri na iya gazawa;
  • refactoring na iya samun ramummuka;
  • haɗin kai da aka jinkirta ya yi daidai... tare da jinkirtawa.

Ƙidaya da ga_kowane sigogi suna da iyaka

Misalai a cikin wannan babin suna yin amfani da yawa na ma'aunin ƙidaya da ma'anar_kowace magana a madaukai da dabaru na sharaɗi. Suna aiki da kyau, amma suna da iyakoki biyu masu mahimmanci waɗanda kuke buƙatar sani.

  • Ƙidaya kuma don_kowa ba zai iya yin la'akari da kowane ma'auni na fitarwa na albarkatu ba.
  • ƙidaya kuma don_kowa ba za a iya amfani da shi ba a cikin tsarin tsarin.

ƙirga kuma don_kowa ba zai iya yin la'akari da kowane ma'auni na fitarwa na albarkatu ba

Ka yi tunanin kana buƙatar tura sabar EC2 da yawa kuma saboda wasu dalilai ba kwa son amfani da ASG. Lambar ku na iya zama kamar haka:

resource "aws_instance" "example_1" {
   count             = 3
   ami                = "ami-0c55b159cbfafe1f0"
   instance_type = "t2.micro"
}

Mu duba su daya bayan daya.

Tunda an saita ma'aunin ƙidaya zuwa ƙima mai mahimmanci, wannan lambar za ta yi aiki ba tare da matsala ba: lokacin da kake gudanar da umarnin da aka yi, zai ƙirƙiri sabar EC2 guda uku. Amma menene idan kuna son tura sabar guda ɗaya a cikin kowane Wurin Samun Samun (AZ) a cikin yankin AWS ɗinku na yanzu? Kuna iya samun lambar ku ta loda jerin yankuna daga tushen bayanan aws_availability_zones sannan ku latsa kowane ɗayan kuma ƙirƙirar sabar EC2 a ciki ta amfani da ma'aunin ƙidayar da isa ga jeri:

resource "aws_instance" "example_2" {
   count                   = length(data.aws_availability_zones.all.names)
   availability_zone   = data.aws_availability_zones.all.names[count.index]
   ami                     = "ami-0c55b159cbfafe1f0"
   instance_type       = "t2.micro"
}

data "aws_availability_zones" "all" {}

Wannan lambar kuma za ta yi aiki da kyau, tunda ma'aunin ƙidayar na iya yin la'akari da tushen bayanai ba tare da wata matsala ba. Amma menene zai faru idan adadin sabar da kuke buƙatar ƙirƙira ya dogara da fitowar wasu albarkatu? Don nuna wannan, hanya mafi sauƙi ita ce amfani da albarkatun random_integer, wanda, kamar yadda sunan ke nunawa, ya dawo da adadin bazuwar:

resource "random_integer" "num_instances" {
  min = 1
  max = 3
}

Wannan lambar tana haifar da bazuwar lamba tsakanin 1 da 3. Bari mu ga abin da zai faru idan muka yi ƙoƙarin yin amfani da fitar da wannan albarkatu a cikin ma'aunin ƙidaya na albarkatun aw_instance:

resource "aws_instance" "example_3" {
   count             = random_integer.num_instances.result
   ami                = "ami-0c55b159cbfafe1f0"
   instance_type = "t2.micro"
}

Idan kun gudanar da shirin terraform akan wannan lambar, zaku sami kuskure mai zuwa:

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 yana buƙatar ƙididdigewa kuma don_kowanne a ƙididdige shi yayin lokacin tsarawa, kafin a ƙirƙiri ko gyara kowane albarkatu. Wannan yana nufin ƙidaya kuma don_kowane na iya komawa zuwa ga zahiri, masu canji, tushen bayanai, har ma da jerin abubuwan albarkatu (muddin ana iya ƙayyade tsayin su a lokacin tsarawa), amma ba don ƙididdige sauye-sauyen fitarwa na albarkatu ba.

ƙidaya kuma don_kowa ba za a iya amfani da shi ba a cikin tsarin tsarin

Wata rana za a iya jarabtar ku don ƙara ma'aunin ƙidaya zuwa tsarin tsarin ku:

module "count_example" {
     source = "../../../../modules/services/webserver-cluster"

     count = 3

     cluster_name = "terraform-up-and-running-example"
     server_port = 8080
     instance_type = "t2.micro"
}

Wannan lambar tana ƙoƙarin yin amfani da ƙidaya a cikin tsari don ƙirƙirar kwafi uku na albarkatun yanar gizo-cluster. Ko kuna iya haɗa haɗin module ɗin zaɓi na zaɓi dangane da wasu yanayin Boolean ta hanyar saita ma'aunin ƙidayar sa zuwa 0. Wannan na iya zama kamar lamba mai ma'ana, amma zaku sami wannan kuskure yayin aiwatar da shirin 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.

Abin baƙin ciki, kamar na Terraform 0.12.6, yin amfani da ƙidayar ko don_kowanne a cikin kayan masarufi ba a tallafawa. Dangane da bayanan sakin Terraform 0.12 (http://bit.ly/3257bv4), HashiCorp yana shirin ƙara wannan damar nan gaba, don haka ya danganta da lokacin da kuka karanta wannan littafin, ƙila ya riga ya kasance. Don sanin tabbas, karanta Terraform changelog nan.

Ƙayyadaddun Ƙididdiga na Sifili na Downtime

Yin amfani da block_before_destroy toshe a hade tare da ASG shine babban mafita don ƙirƙirar jigilar lokaci-lokaci, sai dai fa'ida ɗaya: ba a goyan bayan ƙa'idodin autoscaling. Ko don zama madaidaici, wannan yana sake saita girman ASG zuwa min_size akan kowane turawa, wanda zai iya zama matsala idan kuna amfani da ƙa'idodin autoscaling don ƙara yawan sabar da ke gudana.

Misali, tsarin sabar yanar gizo-cluster yana ƙunshe da wasu albarkatun aws_autoscaling_schedule, wanda da ƙarfe 9 na safe yana ƙara adadin sabar a cikin tarin daga biyu zuwa goma. Idan ka tura a, ka ce, 11 na safe, sabon ASG zai tashi da sabobin biyu kawai maimakon goma kuma ya kasance a haka har zuwa karfe 9 na safe washegari.

Ana iya kewaye wannan iyakance ta hanyoyi da yawa.

  • Canja ma'aunin maimaitawa a cikin aws_autoscaling_schedule daga 0 9 * * * ("gudu a karfe 9 na safe") zuwa wani abu kamar 0-59 9-17 * * * ("gudu kowane minti daga 9 na safe zuwa 5 na yamma"). Idan ASG ta riga tana da sabobin goma, sake gudanar da wannan doka ta atomatik ba zai canza komai ba, wanda shine abin da muke so. Amma idan kwanan nan aka tura ASG, wannan doka za ta tabbatar da cewa a cikin mafi girman minti daya adadin sabar sa zai kai goma. Wannan ba hanya ce mai kyau gaba ɗaya ba, kuma manyan tsalle daga sabar goma zuwa biyu da baya kuma na iya haifar da matsala ga masu amfani.
  • Ƙirƙirar rubutun al'ada wanda ke amfani da API na AWS don ƙayyade adadin sabar masu aiki a cikin ASG, kira shi ta amfani da tushen bayanan waje (duba "Tsarin Bayanai na waje" a shafi na 249), kuma saita ma'aunin ƙarfin ikon ASG zuwa ƙimar da aka dawo da shi. rubutun. Ta wannan hanyar, kowane sabon misali na ASG koyaushe zai gudana a daidai ƙarfin da lambar Terraform ɗin da ke akwai kuma yana sa ya fi wahalar kiyayewa.

Tabbas, da kyau Terraform zai sami ginanniyar tallafi don jigilar lokaci-lokaci, amma har zuwa Mayu 2019, ƙungiyar HashiCorp ba ta da shirin ƙara wannan aikin (cikakken bayani - nan).

Za a iya yin rashin nasarar aiwatar da madaidaicin shirin

Wani lokaci umurnin shirin yana samar da daidaitaccen shirin turawa, amma umarnin da aka yi yana mayar da kuskure. Gwada, misali, ƙara albarkatun aws_iam_user tare da suna ɗaya da kuka yi amfani da shi don mai amfani da IAM da kuka ƙirƙira a baya a Babi na 2:

resource "aws_iam_user" "existing_user" {
   # Подставьте сюда имя уже существующего пользователя IAM,
   # чтобы попрактиковаться в использовании команды terraform import
   name = "yevgeniy.brikman"
}

Yanzu, idan kuna gudanar da umarnin shirin, Terraform zai fitar da tsarin turawa da alama mai ma'ana:

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.

Idan kun gudanar da umarnin da aka yi amfani da shi za ku sami kuskure mai zuwa:

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" {

Matsalar, ba shakka, ita ce mai amfani da IAM mai wannan sunan ya riga ya wanzu. Kuma wannan na iya faruwa ba kawai ga masu amfani da IAM ba, amma ga kusan kowane albarkatu. Yana yiwuwa wani ya ƙirƙiri wannan albarkatun da hannu ko kuma ya yi amfani da layin umarni, amma ko ta yaya, ID ɗin da ya dace yana haifar da rikici. Akwai bambance-bambancen wannan kuskure da yawa waɗanda galibi ke kama sabbin zuwa Terraform da mamaki.

Mahimmin mahimmin batu shine umarnin tsarin terraform yana la'akari da waɗannan albarkatun da aka ƙayyade a cikin fayil ɗin Terraform. Idan an ƙirƙiri albarkatu ta wata hanya (misali, da hannu ta danna cikin na'ura wasan bidiyo na AWS), ba za su ƙare a cikin fayil ɗin jihar ba don haka Terraform ba zai yi la'akari da su ba yayin aiwatar da umarnin shirin. A sakamakon haka, shirin da ya yi kama da daidai a kallon farko zai zama rashin nasara.

Akwai darussa guda biyu da za mu koya daga wannan.

  • Idan kun riga kun fara aiki tare da Terraform, kada ku yi amfani da wani abu dabam. Idan ana sarrafa ɓangaren kayan aikin ku ta amfani da Terraform, ba za ku iya sake gyara shi da hannu ba. In ba haka ba, ba wai kawai kuna haɗarin kurakuran Terraform masu ban mamaki ba, amma kuna yin watsi da yawancin fa'idodin IaC tunda lambar ba za ta zama cikakkiyar wakilcin kayan aikin ku ba.
  • Idan kuna da wasu abubuwan more rayuwa, yi amfani da umarnin shigo da kaya. Idan kuna fara amfani da Terraform tare da abubuwan more rayuwa, zaku iya ƙara shi zuwa fayil ɗin jihar ta amfani da umarnin shigo da terraform. Ta wannan hanyar Terraform zai san abubuwan da ake buƙatar sarrafa kayan aikin. Umurnin shigo da kaya yana ɗaukar gardama biyu. Na farko shine adireshin albarkatu a cikin fayilolin daidaitawar ku. Rubuce-rubucen a nan iri ɗaya ne da hanyoyin haɗin yanar gizo: _. (kamar aws_iam_user.existing_user). Hujja ta biyu ita ce ID na albarkatun da za a shigo da su. Bari mu ce ID albarkatun aws_iam_user shine sunan mai amfani (misali, yevgeniy.brikman), kuma aws_instance ID na albarkatun shine ID ɗin sabar EC2 (kamar i-190e22e5). Yadda ake shigo da albarkatun yawanci ana nuna su a cikin takaddun da ke ƙasan shafin sa.

    A ƙasa akwai umarnin shigo da kaya wanda ke aiki tare da albarkatun aws_iam_user wanda kuka ƙara zuwa tsarin Terraform ɗinku tare da mai amfani da IAM a Babi na 2 (musanya sunan ku ga yevgeniy.brikman, ba shakka):

    $ terraform import aws_iam_user.existing_user yevgeniy.brikman

    Terraform zai kira API AWS don nemo mai amfani da IAM ɗin ku kuma ya ƙirƙiri ƙungiyar fayil ɗin jiha tsakaninsa da albarkatun aws_iam_user.existing_user a cikin tsarin Terraform ɗin ku. Daga yanzu, lokacin da kuke gudanar da umarnin shirin, Terraform zai san cewa mai amfani da IAM ya riga ya wanzu kuma ba zai sake ƙoƙarin ƙirƙirar shi ba.

    Yana da kyau a lura cewa idan har kuna da albarkatu masu yawa waɗanda kuke son shigo da su cikin Terraform, rubuta lambar da hannu da shigo da kowane ɗaya a lokaci ɗaya na iya zama matsala. Don haka yana da daraja duba cikin kayan aiki kamar Terraforming (http://terraforming.dtan4.net/), wanda zai iya shigo da lamba ta atomatik daga asusun AWS na ku.

    Refactoring na iya samun ramummuka

    Refactoring al'ada ce ta gama gari a cikin shirye-shirye inda kuke canza tsarin ciki na lambar yayin barin halayen waje ba canzawa. Wannan shine don sanya lambar ta ƙara bayyana, tsafta, da sauƙin kiyayewa. Refactoring wata dabara ce da ba makawa wacce yakamata a yi amfani da ita akai-akai. Amma idan ya zo ga Terraform ko duk wani kayan aikin IaC, dole ne ku yi taka tsantsan game da abin da kuke nufi da “halayen waje” na wani yanki, in ba haka ba matsalolin da ba zato ba tsammani zasu taso.

    Misali, nau'in sake fasalin gama gari shine maye gurbin sunayen masu canji ko ayyuka tare da waɗanda za a iya fahimta. Yawancin IDEs suna da ginanniyar tallafi don sake fasalin kuma suna iya sake suna masu canji da ayyuka ta atomatik cikin aikin. A cikin yarukan shirye-shirye na gaba ɗaya, wannan ƙaramin tsari ne wanda ƙila ba za ku yi tunani akai ba, amma a cikin Terraform dole ne ku yi taka tsantsan da wannan, in ba haka ba kuna iya fuskantar matsala.

    Misali, tsarin sabar yanar gizo-cluster yana da madaidaicin shigarwar cluster_name:

    variable "cluster_name" {
       description = "The name to use for all the cluster resources"
       type          = string
    }

    Ka yi tunanin ka fara amfani da wannan tsarin don tura microservice da ake kira foo. Daga baya, kuna son sake suna sabis ɗin ku zuwa mashaya. Wannan canjin yana iya zama kamar ba shi da mahimmanci, amma a zahiri yana iya haifar da rushewar sabis.

    Gaskiyar ita ce, rukunin yanar gizo-cluster module yana amfani da madaidaicin cluster_name a cikin adadin albarkatu, gami da sigar sunan ƙungiyoyin tsaro guda biyu da ALB:

    resource "aws_lb" "example" {
       name                    = var.cluster_name
       load_balancer_type = "application"
       subnets = data.aws_subnet_ids.default.ids
       security_groups      = [aws_security_group.alb.id]
    }

    Idan ka canza siginar suna a kan hanya, Terraform zai share tsohuwar sigar wannan albarkatun kuma ya ƙirƙiri sabo a wurinsa. Amma idan wannan albarkatun ALB ne, tsakanin goge shi da zazzage sabon sigar, ba za ku sami hanyar da za a tura zirga-zirga zuwa sabar gidan yanar gizon ku ba. Hakanan, idan an goge ƙungiyar tsaro, sabar ɗin ku za ta fara ƙin duk wata hanyar sadarwa har sai an ƙirƙiri sabuwar ƙungiya.

    Wani nau'in sake fasalin da zaku yi sha'awar shine canza ID na Terraform. Bari mu ɗauki albarkatun aws_security_group a cikin tsarin sabar-cluster a matsayin misali:

    resource "aws_security_group" "instance" {
      # (...)
    }

    Ana kiran mai gano wannan albarkatun misali. Ka yi tunanin cewa yayin sake fasalin ka yanke shawarar canza shi zuwa mafi fahimtar (a ra'ayinka) suna cluster_instance:

    resource "aws_security_group" "cluster_instance" {
       # (...)
    }

    Menene zai faru a ƙarshe? Haka ne: rushewa.

    Terraform yana haɗa kowane ID na albarkatu tare da ID na mai ba da girgije. Misali, iam_user yana da alaƙa da ID na mai amfani na AWS IAM, kuma aws_instance yana da alaƙa da ID ɗin sabar AWS EC2. Idan ka canza ID na albarkatu (ka ce daga misali zuwa cluster_intance, kamar yadda yake a cikin aws_security_group), zuwa Terraform zai bayyana kamar ka goge tsohuwar albarkatun kuma ƙara sabo. Idan kun yi amfani da waɗannan canje-canje, Terraform zai share tsohuwar ƙungiyar tsaro kuma ya ƙirƙiri sabo, yayin da sabobin ku suka fara ƙin duk wani zirga-zirgar hanyar sadarwa.

    Ga muhimman darussa guda huɗu da ya kamata ku ɗauka daga wannan tattaunawa.

    • Yi amfani da umarnin tsari koyaushe. Yana iya bayyana duk waɗannan snags. Yi nazarin abubuwan da aka fitar a hankali kuma ku kula da yanayin da Terraform ke shirin share albarkatun da wataƙila bai kamata a share su ba.
    • Ƙirƙiri kafin ka goge. Idan kana son maye gurbin kayan aiki, yi tunani a hankali game da ko kana buƙatar ƙirƙirar maye kafin share asalin. Idan amsar eh, ƙirƙirar_before_destroy na iya taimakawa. Za'a iya samun sakamako iri ɗaya da hannu ta hanyar aiwatar da matakai biyu: da farko ƙara sabon albarkatu a cikin daidaitawar kuma gudanar da umarnin da aka yi amfani da shi, sannan cire tsohon albarkatun daga tsarin sai a sake amfani da umarnin nema.
    • Canza masu ganowa yana buƙatar canza yanayi. Idan kuna son canza ID ɗin da ke da alaƙa da albarkatu (misali, sake suna aws_security_group daga misali zuwa cluster_intance) ba tare da share albarkatun da ƙirƙirar sabon sigar sa ba, dole ne ku sabunta fayil ɗin Terraform daidai da haka. Kar a taɓa yin wannan da hannu - yi amfani da umarnin jihar terraform maimakon. Lokacin canza masu gano suna, ya kamata ku gudanar da umarnin mv na jihar terraform, wanda ke da ma'ana mai zuwa:
      terraform state mv <ORIGINAL_REFERENCE> <NEW_REFERENCE>

      ORIGINAL_REFERENCE magana ce da ke nuni da albarkatun da ake da su a halin yanzu, kuma NEW_REFERENCE shine inda kake son motsa shi. Misali, lokacin canza sunan kungiyar aws_security_group daga misali zuwa cluster_intance, kuna buƙatar gudanar da umarni mai zuwa:

      $ terraform state mv 
         aws_security_group.instance 
         aws_security_group.cluster_instance

      Wannan yana gaya wa Terraform cewa jihar da a baya ke da alaƙa da aws_security_group.intance ya kamata a haɗa shi da aws_security_group.cluster_instance. Idan bayan sake suna da gudanar da wannan tsarin terraform na umarni bai nuna wani canje-canje ba, to kun yi komai daidai.

    • Ba za a iya canza wasu saitunan ba. Ma'auni na albarkatu da yawa ba su canzawa. Idan kuna ƙoƙarin canza su, Terraform zai share tsohuwar albarkatun kuma ya ƙirƙiri wani sabo a wurinsa. Kowane shafi na albarkatu yawanci zai nuna abin da zai faru lokacin da kuka canza takamaiman saiti, don haka tabbatar da duba takaddun. Yi amfani da umarnin tsari koyaushe kuma la'akari da amfani da dabarun ƙirƙirar_before_destroy.

    Daidaiton da aka jinkirta ya yi daidai... tare da jinkirtawa

    Wasu API ɗin masu samar da girgije, kamar AWS, ba su daidaita kuma sun jinkirta daidaito. Asynchony yana nufin cewa keɓancewar za ta iya dawo da martani nan da nan ba tare da jiran aikin da aka nema ya kammala ba. Daidaitaccen jinkiri yana nufin cewa canje-canje na iya ɗaukar lokaci don yaduwa cikin tsarin; yayin da wannan ke faruwa, martanin ku na iya zama rashin daidaituwa kuma ya dogara da abin da tushen bayanan ke amsa kiran API ɗin ku.

    Ka yi tunanin, alal misali, ka yi kiran API zuwa AWS yana tambayarsa don ƙirƙirar sabar EC2. API ɗin zai dawo da amsa “nasara” (201 Created) kusan nan take, ba tare da jiran sabar da kanta ba. Idan kayi ƙoƙarin haɗawa da shi nan da nan, kusan tabbas zai gaza saboda a wannan lokacin AWS har yanzu yana ƙaddamar da albarkatu ko kuma, a madadin, uwar garken bai riga ya tashi ba. Bugu da ƙari, idan kun sake yin kira don samun bayani game da wannan uwar garken, za ku iya samun kuskure (404 Ba a samo ba). Abun shine cewa bayanin game da wannan uwar garken EC2 na iya har yanzu ana yada shi cikin AWS kafin ya zama ko'ina, dole ne ku jira ƴan daƙiƙa guda.

    Duk lokacin da kuka yi amfani da API asynchronous tare da daidaiton kasala, dole ne ku sake gwada buƙatarku lokaci-lokaci har sai aikin ya cika kuma ya yaɗu ta cikin tsarin. Abin takaici, AWS SDK ba ya samar da kowane kayan aiki masu kyau don wannan, kuma aikin Terraform da aka yi amfani da shi ya sha wahala daga kwari da yawa kamar 6813 (https://github.com/hashicorp/terraform/issues/6813):

    $ terraform apply
    aws_subnet.private-persistence.2: InvalidSubnetID.NotFound:
    The subnet ID 'subnet-xxxxxxx' does not exist

    A wasu kalmomi, kuna ƙirƙira albarkatun (kamar subnet) sannan ku yi ƙoƙarin samun wasu bayanai game da shi (kamar ID na sabon gidan yanar gizo), kuma Terraform ba zai iya samunsa ba. Yawancin waɗannan kwari (ciki har da 6813) an gyara su, amma har yanzu suna girma daga lokaci zuwa lokaci, musamman lokacin da Terraform ya ƙara tallafi don sabon nau'in albarkatu. Wannan abin ban haushi ne, amma a mafi yawan lokuta baya haifar da wata illa. Lokacin da kuka sake yin amfani da terraform, komai ya kamata yayi aiki, tunda a wannan lokacin bayanan sun riga sun yadu cikin tsarin.

    An gabatar da wannan yanki daga littafin Evgeniy Brikman "Teraform: kayayyakin more rayuwa a matakin lambar".

source: www.habr.com

Add a comment