Kam fillova të punoj cloudformation 4 vjet më parë. Që atëherë kam prishur shumë infrastrukturë, përfshirë ato që ishin tashmë në prodhim. Por çdo herë që prisja diçka, mësova diçka të re. Falë këtij përvoje, do të ndaj disa nga mësimet më të rëndësishme që kam mësuar.

Mësimi 1: kontrolloni ndryshimet para se t'i publikoni ato
E kam kuptuar këtë mësim shpejt sapo fillova të punoj me cloudformation. Nuk e mbaj mend se çfarë kam prishur atëherë, por e mbaj mend me siguri që kam përdorur komandën aws cloudformation update. Kjo komandë thjesht e hedh modelin pa asnjë kontroll që ndryshimet do të publikohen. Nuk mendoj se nevojiten shpjegime përse është e rëndësishme të kontrolloni të gjitha ndryshimet para publikimit të tyre.
Pas asaj dështimi, menjëherë e kam ndërruar pipeline e publikimit, duke e zëvendësuar komandën update me komandën 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" Kur është krijuar një grup ndryshimesh, ai nuk ndikon në flokun ekzistues. Ndryshe nga komandën update, qasja me grupin e ndryshimeve nuk shkakton publikimin faktik. Në vend të kësaj, krijon një listë ndryshimesh që mund t'i kontrolloni para publikimit. Mund të shihni ndryshimet në ndërfaqen e konsolës aws. Por nëse preferoni të automatizoni gjithçka që është e mundur, kontrolloni ato në CLI:
# 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 tableKjo komandë duhet të japë një rezultat të ngjashëm me këtë:
--------------------------------------------------------------------
| DescribeChangeSet |
+---------+--------------------+----------------------+------------+
| Veprimi | Nevojitet Zëvendësim | Burimi | IdBurimi |
+---------+--------------------+----------------------+------------+
| Modifiko | E vërtetë | AWS::ECS::Cluster | MyCluster |
| Zëvendëso| E vërtetë | AWS::RDS::DBInstance| MyDB |
| Shto | Asnjë | AWS::SNS::Topic | MyTopic |
+---------+--------------------+----------------------+------------+Kujdesuni veçanĂ«risht pĂ«r ndryshimet ku Veprimi Ă«shtĂ« ZĂ«vendĂ«so, Delete ose ku Nevojitet ZĂ«vendĂ«sim â E vĂ«rtetĂ«. KĂ«to janĂ« ndryshimet mĂ« tĂ« rrezikshme dhe zakonisht çojnĂ« nĂ« humbje informacioni.
Kur ndryshimet të jenë kontrolluar, ato mund të publikohen
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"Mësimi 2: përdorni politikën e stack për të parandaluar zëvendësimin ose fshirjen e burimeve me ruajtjen e gjendjes
Ndonjëherë, thjesht shikimi i ndryshimeve nuk mjafton. Të gjithë jemi njerëz dhe të gjithë bëjmë gabime. Shumë shpejt pas fillimit të përdorimit të grupeve të ndryshimeve, shoku im i ekipit pa të vetëdijshëm realizoi një deploy, që rezultoi në përditësimin e bazës së të dhënave. Asgjë e keqe nuk ndodhi, sepse ishte një ambient testi.
Megjithatë, edhe pse skriptet tona shfaqnin një listë ndryshimesh dhe kërkonin konfirmim, ndryshimi 'Replace' u la pa u vënë re, sepse lista e ndryshimeve ishte kaq e gjatë sa nuk shkonte në ekran. Dhe sepse kjo ishte një përditësim rutinë në ambientin e testimit, ndryshimeve nuk iu kushtua shumë vëmendje.
Ka burime që nuk do të donit kurrë t'i zevëndësoni ose t'i fshini. Këto janë shërbimet 'stateful', siç janë instanca e bazës së të dhënave RDS ose klasteri Elasticsearch etj. Do të ishte mirë nëse AWS automatikisht do të refuzonte deploy-n nëse operacioni i kryer kërkonte fshirjen e tillë të burimit. Fatmirësisht, CloudFormation ka një mënyrë të ndërtuar për ta bërë këtë. Kjo quhet politika e stack-ut, dhe mund të mësoni më shumë për të tek :
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"Mësimi 3: përdorni UsePreviousValue kur përditësoni stack-un me parametra sekretë.
Kur krijoni një entitet RDS MySQL, AWS kërkon nga ju të jepni MasterUsername dhe MasterUserPassword. Përsa i përket ruajtjes së sekretëve në kodin burimor, dhe unë doja të automatizoja gjithçka, implementova një "mekanizëm inteligjent", ku para deployment-it, akreditimet do të merren nga S3, dhe nëse akreditimet nuk do të gjenden, do të gjeneroheshin të reja dhe do të ruheshin në S3.
Pastaj këto akreditime do të kalohen si parametra në komandën cloudformation create-change-set. Gjatë eksperimentimit me skriptin ndodhi që lidhja me S3 u humb, dhe "mekanizmi im inteligjent" e shqyrtoi atë si një sinjal për të gjeneruar akreditime të reja.
NĂ«se do tĂ« filloja ta pĂ«rdorja kĂ«tĂ« skript nĂ« njĂ« mjedis pune dhe problemi me lidhjen do tĂ« ndodhte pĂ«rsĂ«ri, ai do tĂ« pĂ«rditĂ«sonte grumbullin me tĂ« dhĂ«na tĂ« reja. NĂ« kĂ«tĂ« rast tĂ« veçantĂ«, nuk do tĂ« ndodhte asgjĂ« e keqe. MegjithatĂ«, unĂ« kam hequr dorĂ« nga kjo qasje dhe kam filluar tĂ« pĂ«rdor njĂ« tjetĂ«r, duke ofruar tĂ« dhĂ«nat vetĂ«m njĂ« herĂ« â gjatĂ« krijimit tĂ« grumbullit. MĂ« vonĂ«, kur grumbulli tĂ« kĂ«rkonte pĂ«rditĂ«sim, unĂ« do tĂ« pĂ«rdorja 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"Shkolla 4: përdorni konfigurimin e rikthimit
Një komandë tjetër me të cilën kam punuar përdorte funksionin cloudformation, i quajtur rollback configuration. Nuk isha takuar me të më parë dhe shpejt kuptova se kjo do ta bënte shpërndarjen e grumbujve të mi edhe më të lehtë. Tani e përdor çdo herë kur shpërndaj kodin tim në lambda ose ECS përmes cloudformation.
Si funksionon: ju specifikoni CloudWatch alarm arn nĂ« parametrin ârollback-configuration, kur krijoni njĂ« grup ndryshimesh. MĂ« vonĂ«, kur tĂ« ekzekutoni grupin e ndryshimeve, aws ndjek alarmi pĂ«r tĂ« paktĂ«n njĂ« minutĂ«. Ai e rikthen shpĂ«rndarjen nĂ« tĂ« kaluarĂ«n nĂ«se gjatĂ« kĂ«saj kohe alarmi ndryshon gjendjen nĂ« ALARM.
Më poshtë është një shembull i një pjesë të shabllonit cloudformation, ku krijoj cloudwatch alarm, që ndjek një metrikë të përdoruesit në formën e numrit të gabimeve në regjistrat e reja të cloud (metrika krijohet përmes MetricFilter):
Resources:
# kjo metrikë ndjek numrin e gabimeve në regjistrat cloudwatch. Në këtë
# rast të veçantë supozohet se regjistrat janë në formatin json dhe regjistrat e gabimeve janë
# të identifikuar nga niveli "gabim". Shihni FilterPattern
ErrorMetricFilter:
Type: AWS::Logs::MetricFilter
Properties:
LogGroupName: !Ref LogGroup
FilterPattern: !Sub '{$.level = "error"}'
MetricTransformations:
- MetricNamespace: !Sub "${AWS::StackName}-log-errors"
MetricName: Errors
MetricValue: 1
DefaultValue: 0
ErrorAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
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: yesTani alarm mund të përdoret si rollback trigjer gjatë ekzekutimit të grupit të ndryshimeve:
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"Mësimi 5: sigurohuni që po zhvilloni versionin më të fundit të modelit
ĂshtĂ« e lehtĂ« tĂ« zhvillosh njĂ« version jo tĂ« fundit tĂ« modelit cloudformation, por kjo do tĂ« shkaktojĂ« dĂ«me tĂ« mĂ«dha. NjĂ« herĂ« ndodhi kĂ«shtu: njĂ« zhvillues nuk dĂ«rgoi ndryshimet e fundit nga Git dhe pa e kuptuar zhvilloi versionin e mĂ«parshĂ«m tĂ« stack-ut. Kjo çoi nĂ« ndalesĂ«n e aplikacionit qĂ« pĂ«rdorte kĂ«tĂ« stack.
Diçka e thjeshtë, siç është shtimi i një kontrolli nëse dega është e përditësuar, para se të kryhet zhvillimi, do të ishte e mirë (nëse supozojmë se git është mjeti juaj i kontrollit të versioneve):
git fetch
HEADHASH=$(git rev-parse HEAD)
UPSTREAMHASH=$(git rev-parse master@{upstream})
if [[ "$HEADHASH" != "$UPSTREAMHASH" ]] ; then
echo "Dega nuk është e përditësuar me origjinën. Duke e ndaluar."
exit 1
fiMësimi 6: mos shpikni ndonjë biçikletë
Mund të duket se zhvillimi me cloudformation është i lehtë. Ju nevojiten thjesht disa skripte bash që ekzekutojnë komanda aws cli.
4 vjet mĂ« parĂ« fillova me skripte tĂ« thjeshta qĂ« thĂ«rrisnin komandĂ«n aws cloudformation create-stack. Shpejt, skripti nuk ishte mĂ« i thjeshtĂ«. Ădo mĂ«sim tĂ« nxjerrĂ« e bĂ«nte skriptin gjithnjĂ« e mĂ« tĂ« komplikuar. Kishte jo vetĂ«m vĂ«shtirĂ«si, por edhe shumĂ« defekte.
Tani punoj në një departament të vogël IT. Eksperienca tregon se çdo ekip ka mënyrën e vet të zhvillimit të stack-ut cloudformation. Dhe kjo është e keqe. Do të ishte më mirë nëse të gjithë do të përdornin një qasje të njëjtë. Fatmirësisht, ekzistojnë shumë mjete që ndihmojnë në zhvillimin dhe konfigurimin e stekëve cloudformation.
Këto mësime do t'ju ndihmojnë të shmangni gabimet.
Burimi: habr.com
