Začel sem delati z oblačnost pred 4 leti. Od takrat sem pokvaril veliko infrastruktur, tudi tistih, ki so že bile v proizvodnji. Toda vsakič, ko sem kaj zamočil, sem se naučil nekaj novega. S to izkušnjo bom delil nekaj najpomembnejših lekcij, ki sem se jih naučil.
1. lekcija: preizkusite spremembe, preden jih uvedete
Te lekcije sem se naučil kmalu po začetku dela z oblačnost. Ne spomnim se, kaj točno sem takrat pokvaril, vsekakor pa se spomnim, da sem uporabil ukaz aws cloudformation posodobitev. Ta ukaz preprosto uvede predlogo brez potrditve sprememb, ki bodo uvedene. Mislim, da ni potrebna nobena razlaga, zakaj bi morali preizkusiti vse spremembe, preden jih uvedete.
Po tem neuspehu sem se takoj spremenil cevovod za uvajanje, ki zamenja ukaz za posodobitev z ukazom ustvari-spremeni-nastavi
# 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"
Ko je nabor sprememb ustvarjen, ne vpliva na obstoječi sklad. Za razliko od ukaza za posodobitev pristop nabora sprememb ne sproži dejanske uvedbe. Namesto tega ustvari seznam sprememb, ki jih lahko pregledate pred uvedbo. Spremembe si lahko ogledate v vmesniku konzole aws. Če pa raje avtomatizirate vse, kar lahko, jih preverite v 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 table
Ta ukaz bi moral ustvariti izhod, podoben naslednjemu:
--------------------------------------------------------------------
| DescribeChangeSet |
+---------+--------------------+----------------------+------------+
| Action | ReplacementNeeded | Resource | ResourceId |
+---------+--------------------+----------------------+------------+
| Modify | True | AWS::ECS::Cluster | MyCluster |
| Replace| True | AWS::RDS::DBInstance| MyDB |
| Add | None | AWS::SNS::Topic | MyTopic |
+---------+--------------------+----------------------+------------+
Posebno pozornost posvetite spremembam, kjer je Action Zamenjaj, Brisanje ali kje Potrebna zamenjava - res. To so najnevarnejše spremembe in običajno povzročijo izgubo informacij.
Ko so spremembe pregledane, jih je mogoče uvesti
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"
Lekcija 2: Uporabite politiko sklada, da preprečite zamenjavo ali odstranitev virov s stanjem
Včasih samo ogled sprememb ni dovolj. Vsi smo ljudje in vsi delamo napake. Kmalu po tem, ko smo začeli uporabljati nabore sprememb, je moj soigralec nevede izvedel uvedbo, ki je povzročila posodobitev baze podatkov. Nič slabega se ni zgodilo, ker je bilo testno okolje.
Čeprav so naši skripti prikazali seznam sprememb in zahtevali potrditev, je bila sprememba Zamenjaj preskočena, ker je bil seznam sprememb tako velik, da ni ustrezal zaslonu. In ker je bila to običajna posodobitev v testnem okolju, spremembam ni bilo posvečene veliko pozornosti.
Obstajajo viri, ki jih nikoli ne želite zamenjati ali odstraniti. To so storitve s polnim stanjem, kot je primerek baze podatkov RDS ali gruča elasticsearch itd. Lepo bi bilo, če bi aws samodejno zavrnil uvedbo, če bi operacija, ki se izvaja, zahtevala brisanje takega vira. Na srečo ima cloudformation vgrajen način za to. To se imenuje politika sklada in več o tem lahko preberete v
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"
Lekcija 3: Uporabite UsePreviousValue pri posodabljanju sklada s skrivnimi parametri
Ko ustvarite entiteto RDS mysql, AWS zahteva, da navedete MasterUsername in MasterUserPassword. Ker je bolje, da v izvorni kodi ne ostanejo skrivnosti in sem želel popolnoma vse avtomatizirati, sem implementiral "pametni mehanizem", kjer bodo pred uvedbo poverilnice pridobljene iz s3, in če poverilnic ni mogoče najti, se generirajo nove poverilnice in shranjeno v s3.
Te poverilnice bodo nato kot parametri posredovane ukazu create-change-set za oblikovanje oblaka. Med eksperimentiranjem s skriptom se je zgodilo, da se je povezava s s3 izgubila in moj "pametni mehanizem" je to obravnaval kot signal za generiranje novih poverilnic.
Če bi začel uporabljati ta skript v proizvodnji in bi se težava s povezavo ponovila, bi posodobil sklad z novimi poverilnicami. V tem konkretnem primeru se ne bo zgodilo nič slabega. Vendar sem opustil ta pristop in začel uporabljati drugega, s poverilnicami samo enkrat – pri ustvarjanju sklada. In pozneje, ko je treba sklad posodobiti, bi namesto podajanja tajne vrednosti parametra preprosto uporabil 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"
Lekcija 4: Uporabite konfiguracijo povrnitve nazaj
Druga ekipa, s katero sem delal, je uporabila to funkcijo oblačnostklical konfiguracijo povrnitve nazaj. Na to še nisem naletel in hitro sem ugotovil, da bo zaradi tega razporeditev mojih skladov še bolj kul. Zdaj ga uporabljam vsakič, ko uvedem svojo kodo v lambda ali ECS z uporabo oblaka.
Kako deluje: določite sami Alarm CloudWatch v parametru --configuration-rollbackko ustvarite nabor sprememb. Pozneje, ko izvedete niz sprememb, aws spremlja alarm vsaj eno minuto. Povrne razmestitev, če alarm v tem času spremeni stanje v ALARM.
Spodaj je primer izvlečka predloge oblačnostv kateri ustvarjam alarm v oblaku, ki sledi uporabniški meritvi v oblaku kot številu napak v dnevnikih v oblaku (metrika se ustvari prek MetricFilter):
Resources:
# this metric tracks number of errors in the cloudwatch logs. In this
# particular case it's assumed logs are in json format and the error logs are
# identified by level "error". See 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 minute
EvaluationPeriods: 1
Threshold: 0
TreatMissingData: notBreaching
ActionsEnabled: yes
Zdaj Alarm se lahko uporablja kot rollback sproži ob izvajanju orodjarne:
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"
5. lekcija: poskrbite, da boste uvedli najnovejšo različico predloge
Preprosto je namestiti manj kot najnovejšo različico predloge za oblikovanje oblaka, vendar bo to povzročilo veliko škode. To se nam je enkrat zgodilo: razvijalec ni potisnil najnovejših sprememb iz Gita in je nevede uvedel prejšnjo različico sklada. To je povzročilo izpad aplikacije, ki je uporabljala ta sklad.
Nekaj tako preprostega, kot je dodajanje preverjanja, ali je veja posodobljena, preden se ji posvetite, bi bilo v redu (ob predpostavki, da je git vaše orodje za nadzor različic):
git fetch
HEADHASH=$(git rev-parse HEAD)
UPSTREAMHASH=$(git rev-parse master@{upstream})
if [[ "$HEADHASH" != "$UPSTREAMHASH" ]] ; then
echo "Branch is not up to date with origin. Aborting"
exit 1
fi
6. lekcija: Ne izumljajte kolesa znova
Morda se zdi kot uvajanje z oblačnost - to je enostavno. Potrebujete le kup skriptov bash, ki izvajajo ukaze aws cli.
Pred 4 leti sem začel s preprostimi skripti, imenovanimi ukaz aws cloudformation create-stack. Kmalu scenarij ni bil več preprost. Vsaka lekcija je naredila scenarij vedno bolj zapleten. Ni bilo samo težko, ampak tudi polno hroščev.
Trenutno delam v manjšem IT oddelku. Izkušnje so pokazale, da ima vsaka ekipa svoj način uvajanja skladov za oblikovanje oblaka. In to je slabo. Bolje bi bilo, če bi vsi imeli enak pristop. Na srečo je na voljo veliko orodij, ki vam pomagajo pri uvajanju in konfiguriranju skladov za oblikovanje oblakov.
Te lekcije vam bodo pomagale preprečiti napake.
Vir: www.habr.com