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.

Õ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 tableSee 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 :
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: jahPraegu 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
