Need mitu pilti on olemas? Osa neist oli tellitud, üks oli kokku pandud ja järgmine on vähese kuue valiku levinud rakendus.

Alustasin töötamist cloudformationiga neli aastat tagasi. Selle aja jooksul olen purustanud palju infrastruktuure, sealhulgas ka neid, mis olid juba tootmises. Kuid iga kord, kui ma midagi purustasin, õppisin ma midagi uut. Selle kogemuse põhjal jagan mõningaid kõige olulisemaid õppetunde, mille olen õppinud.

Need mitu pilti on olemas? Osa neist oli tellitud, üks oli kokku pandud ja järgmine on vähese kuue valiku levinud rakendus.

Õppetund 1: kontrollige muudatusi enne nende käivitamist

Selle õppetunni õppisin peaaegu kohe, kui alustasin töötamist cloudformationiga. Ei mäleta, mida ma tol hetkel purustasin, aga mäletan, et kasutasin käsku aws cloudformation update. See käsk lihtsalt rakendab mall ilma igasuguste muudatuste kontrollimiseta, mis kraavi tõugatakse. Ma ei arva, et vajate selgitusi, miks on vajalik kõik muudatused enne nende käivitamist kontrollida.

Pärast seda ebaõnnestumist muutsin ma kohe deployment pipeline'i, asendades käsku update käsuga create-change-set

# OPERATION is either "UPDATE" or "CREATE"
changeset_id=$(aws cloudformation create-change-set 
    --change-set-name "$CHANGE_SET_NAME" 
    --stack-name "$STACK_NAME" 
    --template-body "$TPL_PATH" 
    --change-set-type "$OPERATION" 
    --parameters "$PARAMETERS" 
    --output text 
    --query Id)

aws cloudformation wait 
    change-set-create-complete --change-set-name "$changeset_id"

Kuna muudatuste komplekt on loodud, ei mõjuta see olemasolevat steki. Erinevalt käsklusest update ei põhjusta muudatuste komplekt tegelikku juurutamist. Selle asemel loob see nimekirja muudatustest, mida saate vaadata enne juurutamist. Saate muudatusi vaadata AWS konsoli liideses. Kui eelistate aga automatiseerida kõike, kontrollige neid CLI-s:

# this command is presented only for demonstrational purposes.
# the real command should take pagination into account
aws cloudformation describe-change-set 
    --change-set-name "$changeset_id" 
    --query 'Changes[*].ResourceChange.{Action:Action,Resource:ResourceType,ResourceId:LogicalResourceId,ReplacementNeeded:Replacement}' 
    --output table

See käsklus peaks andma väljundi, mis sarnaneb järgmisele:

--------------------------------------------------------------------
|                         DescribeChangeSet                        |
+---------+--------------------+----------------------+------------+
| Action  | ReplacementNeeded  |      Resource        | ResourceId |
+---------+--------------------+----------------------+------------+
|  Modify | True               |  AWS::ECS::Cluster   |  MyCluster |
|  Replace| True               |  AWS::RDS::DBInstance|  MyDB      |
|  Add    | None               |  AWS::SNS::Topic     |  MyTopic   |
+---------+--------------------+----------------------+------------+

Pöörake erilist tähelepanu muudatustele, kus Action on Replace, Delete või kus ReplacementNeeded — True. Need on kõige ohtlikumad muudatused ja tavaliselt toovad nad kaasa teabe kaotuse.

Kui muudatused on üle vaadatud, saab need juurutada.

aws cloudformation execute-change-set --change-set-name "$changeset_id"

operation_lowercase=$(echo "$OPERATION" | tr '[:upper:]' '[:lower:]')
aws cloudformation wait "stack-${operation_lowercase}-complete" 
    --stack-name "$STACK_NAME"

Tund 2: kasutage stack policy'd, et vältida ressursside asendamist või kustutamist oleku säilitamisega

Mõnikord ei piisa lihtsalt muudatuste ülevaatusest. Me kõik oleme inimesed ja teeme vigu. Peagi pärast seda, kui hakkasime kasutama muudatuseteemasid, tegi minu meeskonnakaaslane alateadlikult juurutuse, mis tõi kaasa andmebaasi värskendamise. Suurt midagi ei juhtunud, sest see oli testimis keskkond.

Kuigi meie skriptid näitasid muudatuste loetelu ja küsisid kinnitust, jäi Replace muudatus tähelepanuta, sest muudatuste loetelu oli nii pikk, et see ei mahtunud ekraanile. Ja kuna see oli tavaline värskendus testimis keskkonnas, ei pööratud muudatustele nii palju tähelepanu.

On olemas ressursse, mida te kunagi ei soovi asendada ega kustutada. Need on stateful teenused, nagu RDS andmebaasiinstants või elastichsearch klaster jne. Oleks hea, kui aws keelaks automaatselt juurutamise, kui teostatav operatsioon nõuab sellise ressursi kustutamist. Õnneks on cloudformationil sisseehitatud viis seda teha. Seda nimetatakse stack policy'ks ja rohkem teavet selle kohta leiate dokumentatsioonis:

STACK_NAME=$1
RESOURCE_ID=$2

POLICY_JSON=$(cat <<EOF
{
    "Statement" : [{
        "Effect" : "Deny",
        "Action" : [
            "Update:Replace",
            "Update:Delete"
        ],
        "Principal": "*",
        "Resource" : "LogicalResourceId/$RESOURCE_ID"
    }]
}
EOF
)

aws cloudformation set-stack-policy --stack-name "$STACK_NAME" 
    --stack-policy-body "$POLICY_JSON"

Õppetund 3: kasutage UsePreviousValue, kui värskendate steeki salajaste parameetritega

Kui loote RDS MySQL üksuse, nõuab AWS teilt MasterUsername ja MasterUserPassword esitamise. Kuna on parem mitte salvestada salajasi andmeid lähtekoodi, ja kuna soovisin automatiseerida absoluutselt kõike, olen rakendanud "nutikat mehhanismi", kus enne juurutamist saadakse mandaadid S3-st ja kui mandaate ei leita, genereeritakse uued mandaadid ja salvestatakse S3-sse.

See andmed edastatakse järgnevalt cloudformation create-change-set käsule parameetritena. Skripti katsetamise ajal juhtus, et ühendus s3-ga kadus ning minu „nutikas mehhanism” tõlgendas seda kui signaali uute andmete genereerimiseks.

Kui ma oleksin hakanud seda skripti tootmiskeskkonnas kasutama ja ühenduse probleem oleks uuesti ilmnenud, oleks see uuendanud steki uute andmetega. Selles konkreetses olukorras ei juhtuks midagi halba. Kuid ma loobusin sellisest lähenemisest ja hakkasin kasutama teistsugust, andes andmed ainult üks kord — steki loomisel. Ja hiljem, kui stek nõuab uuendamist, kasutaksin ma saladusväärtuse parameetri näitamise asemel lihtsalt UsePreviousValue=true:

aws cloudformation create-change-set 
    --change-set-name "$CHANGE_SET_NAME" 
    --stack-name "$STACK_NAME" 
    --template-body "$TPL_PATH" 
    --change-set-type "UPDATE" 
    --parameters "ParameterKey=MasterUserPassword,UsePreviousValue=true"

Tund 4: kasutage rollback configuration

Teine käsk, millega ma töötasin, kasutas funktsiooni cloudformationiga, mida nimetatakse rollback configuration. Ma pole varem temaga kohtunud ja mõistsin kiiresti, et see muudab minu stekkide juurutamise veelgi ägedamaks. Nüüd kasutan seda iga kord, kui juurutatakse oma koodi lambda või ECS kaudu cloudformationi abil.

Kuidas see töötab: te näitate CloudWatch alarmi ARN parameetris —rollback-configuration, kui loote muudatusete kogumit. Hiljem, kui te muudatusete kogumit täidate, jälgib AWS alarmi vähemalt ühe minuti. See tühistab juurutamise, kui selle aja jooksul alarm muutub seisundisse ALARM.

Allpool on näide mallist cloudformationiga, kus ma loon cloudwatch alarmi, mis jälgib kohandatud pilvemeetrit vigade arvu cloudi logides (meetrit luuakse läbi MetricFilter):

Ressursid:
  # see näitaja jälgib vigade arvu cloudwatch logides. Antud
  # juhul eeldatakse, et logid on json vormingus ja veateated on
  # määratletud tasemega "error". Vaata FilterPattern
  ErrorMetricFilter:
    Tüüp: AWS::Logs::MetricFilter
    Atribuudid:
      LogGroupName: !Ref LogGroup
      FilterPattern: !Sub '{$.level = "error"}'
      MetricTransformations:
      - MetricNamespace: !Sub "${AWS::StackName}-log-errors"
        MetricName: Errors
        MetricValue: 1
        DefaultValue: 0

  ErrorAlarm:
    Tüüp: AWS::CloudWatch::Alarm
    Atribuudid:
      AlarmName: !Sub "${AWS::StackName}-errors"
      Namespace: !Sub "${AWS::StackName}-log-errors"
      MetricName: Errors
      Statistic: Maximum
      ComparisonOperator: GreaterThanThreshold
      Period: 1 # 1 minut
      EvaluationPeriods: 1
      Threshold: 0
      TreatMissingData: notBreaching
      ActionsEnabled: jah

Praegu alarm võib olla kasutatud kui rollback trigger komplekti tööriistade täitmiseks:

ALARM_ARN=$1

ROLLBACK_TRIGGER=$(cat <<EOF
{
  "RollbackTriggers": [
    {
      "Arn": "$ALARM_ARN",
      "Type": "AWS::CloudWatch::Alarm"
    }
  ],
  "MonitoringTimeInMinutes": 1
}
EOF
)

aws cloudformation create-change-set 
    --change-set-name "$CHANGE_SET_NAME" 
    --stack-name "$STACK_NAME" 
    --template-body "$TPL_PATH" 
    --change-set-type "UPDATE" 
    --rollback-configuration "$ROLLBACK_TRIGGER"

Tund 5: veenduge, et te juurutate kõige uuema versiooni malli

Cloudformation'i šablooni paigaldamine ei ole keeruline, kuid see võib põhjustada suuri probleeme. Meil oli kunagi selline olukord: arendaja ei saatnud viimaseid muudatusi Gitist ja käivitas tahtmatult eelmise versiooni virna. See viis rakenduse seiskumiseni, mis kasutas seda virna.

Midagi lihtsat, näiteks haru kehtivuse kontrollimine enne juurutamist, oleks hea mõte (eeldades, et git on teie versioonihaldusvahend):

git fetch
HEADHASH=$(git rev-parse HEAD)
UPSTREAMHASH=$(git rev-parse master@{upstream})

if [[ "$HEADHASH" != "$UPSTREAMHASH" ]] ; then
   echo "Haru ei ole asjakohane. Katkestan"
   exit 1
fi

Õppetund 6: ära leiuta ratast

Juurutamine võib tunduda, et cloudformationiga — on lihtne. Teil on lihtsalt vaja hunnikut bash-skripte, mis täidavad aws cli käske.

Neli aastat tagasi alustasin ma lihtsate skriptidega, mis kutsusid aws cloudformation create-stack käsku. Varsti ei olnud skript enam lihtne. Iga õpitud õppetund muutis skripti järjest keerukamaks. See polnud mitte ainult keeruline, vaid ka täis vigu.

Praegu töötan ma väikeses IT-osakonnas. Kogemus näitab, et igal meeskonnal on oma viis cloudformationi virnade juurutamiseks. Ja see on halb. Oleks parem, kui kõik kasutaksid ühtset lähenemist. Õnneks on palju tööriistu, mis aitavad juurutada ja seadistada cloudformationi virnu.

Need õppetunnid aitavad teil vältida vigu.

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster