Šias 6 darbo su debesų formavimu pamokas išmokau visą likusį gyvenimą.

Pradėjau dirbti su debesų formavimas prieš 4 metus. Nuo tada sulaužiau daugybę infrastruktūrų, net ir tų, kurios jau buvo gaminamos. Bet kiekvieną kartą, kai ką nors sujaučiau, išmokdavau kažko naujo. Per šią patirtį pasidalinsiu kai kuriomis svarbiausiomis pamokomis, kurias išmokau.

Šias 6 darbo su debesų formavimu pamokas išmokau visą likusį gyvenimą.

1 pamoka: išbandykite pakeitimus prieš juos įdiegdami

Šią pamoką išmokau netrukus po to, kai pradėjau dirbti debesų formavimas. Nepamenu, ką tiksliai tada sulaužiau, bet tikrai prisimenu, kad naudojau komandą aws debesų formavimo atnaujinimas. Ši komanda paprasčiausiai išleidžia šabloną be jokių pakeitimų, kurie bus įdiegti, patvirtinimo. Nemanau, kad reikia paaiškinti, kodėl turėtumėte išbandyti visus pakeitimus prieš juos įdiegiant.

Po šios nesėkmės iškart pasikeičiau dujotiekis, pakeisdami naujinimo komandą komanda kurti-keisti-rinkti

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

Sukūrus pakeitimų rinkinį, jis neturės jokios įtakos esamam kaminui. Skirtingai nei naujinimo komanda, pakeitimų rinkinio metodas nesukelia tikrojo diegimo. Vietoj to sukuriamas pakeitimų, kuriuos galite peržiūrėti prieš įdiegiant, sąrašas. Pakeitimus galite peržiūrėti aws konsolės sąsajoje. Bet jei norite automatizuoti viską, ką galite, patikrinkite juos 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

Ši komanda turėtų pateikti išvestį, panašią į šią:

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

Ypatingą dėmesį atkreipkite į pokyčius ten, kur yra veiksmas pakeisti, panaikinti arba kur ReplacementNeeded – tiesa. Tai yra patys pavojingiausi pokyčiai, dėl kurių paprastai prarandama informacija.

Kai pakeitimai bus peržiūrėti, juos galima įdiegti

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"

2 pamoka: naudokite dėklo politiką, kad išvengtumėte būsenos išteklių pakeitimo ar pašalinimo

Kartais neužtenka vien tik stebėti pakeitimus. Mes visi esame žmonės ir visi klystame. Netrukus po to, kai pradėjome naudoti pakeitimų rinkinius, mano komandos draugas nesąmoningai atliko diegimą, dėl kurio buvo atnaujinta duomenų bazė. Nieko blogo nenutiko, nes tai buvo testavimo aplinka.

Nors mūsų scenarijuose buvo rodomas pakeitimų sąrašas ir buvo prašoma patvirtinimo, pakeitimas buvo praleistas, nes pakeitimų sąrašas buvo toks didelis, kad netilpo ekrane. Ir kadangi tai buvo įprastas atnaujinimas testavimo aplinkoje, pakeitimams nebuvo skiriama daug dėmesio.

Yra išteklių, kurių niekada nenorite pakeisti ar pašalinti. Tai visos būsenos paslaugos, pvz., RDS duomenų bazės egzempliorius arba elasticsearch klasteris ir tt Būtų gerai, jei aws automatiškai atsisakytų diegimo, jei dėl atliekamos operacijos reikėtų ištrinti tokį šaltinį. Laimei, debesų formavimas turi integruotą būdą tai padaryti. Tai vadinama krūvos politika ir daugiau apie tai galite perskaityti dokumentacija:

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"

3 pamoka: naudokite UsePreviousValue, kai atnaujinate krūvą su slaptais parametrais

Kai kuriate RDS mysql objektą, AWS reikalauja pateikti pagrindinį vartotojo vardą ir pagrindinį vartotojo slaptažodį. Kadangi šaltinio kode paslapčių geriau nelaikyti ir norėjau absoliučiai viską automatizuoti, įdiegiau „išmanųjį mechanizmą“, kai prieš diegiant kredencialai bus gauti iš s3, o jei kredencialai nerandami, generuojami nauji kredencialai ir saugomi s3.

Tada šie kredencialai bus perduoti kaip parametrai debesų formavimo komandai kurti-keisti-nustatyti. Eksperimentuojant su scenarijumi atsitiko taip, kad nutrūko ryšys su s3, o mano „protingas mechanizmas“ traktavo tai kaip signalą generuoti naujus kredencialus.

Jei pradėčiau naudoti šį scenarijų gamyboje ir vėl pasikartotų ryšio problema, ji atnaujintų krūvą naujais kredencialais. Šiuo konkrečiu atveju nieko blogo nenutiks. Tačiau šio požiūrio atsisakiau ir pradėjau naudoti kitą, kredencialus pateikdamas tik vieną kartą – kurdamas krūvą. O vėliau, kai reikės atnaujinti steką, vietoj to, kad nurodyčiau slaptą parametro reikšmę, aš tiesiog naudočiau 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"

4 pamoka: naudokite atšaukimo konfigūraciją

Kita komanda, su kuria dirbau, naudojo šią funkciją debesų formavimas, paskambino atšaukimo konfigūracija. Anksčiau su tuo nebuvau susidūręs ir greitai supratau, kad tai dar labiau paverstų mano stekų panaudojimą. Dabar naudoju jį kiekvieną kartą, kai diegiu savo kodą į lambda arba ECS, naudodamas debesų formavimą.

Kaip tai veikia: jūs nurodote CloudWatch žadintuvas arn parametre --atšaukimo konfigūracijakai kuriate pakeitimų rinkinį. Vėliau, kai atliekate pakeitimų rinkinį, aws stebi žadintuvą bent vieną minutę. Jis atšaukia diegimą, jei per tą laiką pavojaus signalo būsena pakeičiama į ALARM.

Žemiau pateikiamas šablono ištraukos pavyzdys debesų formavimaskuriame aš kuriu debesų laikrodžio signalas, kuri seka debesies naudotojo metriką kaip klaidų skaičių debesies žurnaluose (metrika sugeneruojama naudojant 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

Dabar žadintuvas gali būti naudojamas kaip Atmesti paleidiklis vykdant įrankių rinkinį:

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 pamoka: Įsitikinkite, kad įdiegėte naujausią šablono versiją

Nesunku įdiegti ne naujausią debesų formavimo šablono versiją, tačiau tai padarysite daug žalos. Taip nutiko mums kartą: kūrėjas neperkėlė naujausių Git pakeitimų ir nesąmoningai įdiegė ankstesnę dėklo versiją. Dėl šios priežasties programa, kuri naudojo šį dėklą, prastovos.

Toks paprastas dalykas, kaip patikrinti, ar filialas yra atnaujintas prieš įsipareigojant, būtų gerai (darant prielaidą, kad git yra jūsų versijos valdymo įrankis):

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 pamoka: Neišradinėk dviračio iš naujo

Tai gali atrodyti kaip diegimas su debesų formavimas - tai lengva. Jums tereikia daugybės bash scenarijų, vykdančių aws cli komandas.

Prieš 4 metus pradėjau nuo paprastų scenarijų, vadinamų aws cloudformation create-stack komanda. Netrukus scenarijus nebebuvo paprastas. Kiekviena išmokta pamoka scenarijų darė vis sudėtingesnį. Buvo ne tik sunku, bet ir pilna klaidų.

Šiuo metu dirbu mažame IT skyriuje. Patirtis parodė, kad kiekviena komanda turi savo būdą, kaip įdiegti debesų formavimo krūvas. Ir tai yra blogai. Būtų geriau, jei visi laikytųsi vienodo požiūrio. Laimei, yra daug įrankių, padedančių diegti ir konfigūruoti debesų formavimo krūvas.

Šios pamokos padės išvengti klaidų.

Šaltinis: www.habr.com

Добавить комментарий