Týchto 6 lekcií práce s cloudformation som sa naučil na celý život.

Začal som pracovať s tvorba oblačnosti pred 4 rokmi. Odvtedy som rozbil množstvo infraštruktúr, dokonca aj také, ktoré už boli vo výrobe. Ale vždy, keď som niečo pokazil, naučil som sa niečo nové. Prostredníctvom tejto skúsenosti sa podelím o niektoré z najdôležitejších ponaučení, ktoré som sa naučil.

Týchto 6 lekcií práce s cloudformation som sa naučil na celý život.

Lekcia 1: Otestujte zmeny pred ich nasadením

Túto lekciu som sa naučil hneď po tom, ako som s ním začal pracovať tvorba oblačnosti. Nepamätám si, čo presne som vtedy zlomil, ale určite si pamätám, že som použil príkaz aktualizácia aws cloudformation. Tento príkaz jednoducho spustí šablónu bez akéhokoľvek overenia zmien, ktoré budú nasadené. Nemyslím si, že je potrebné žiadne vysvetlenie, prečo by ste mali všetky zmeny otestovať pred ich nasadením.

Po tomto neúspechu som sa okamžite zmenil nasadenie potrubia, nahradenie príkazu update príkazom vytvoriť-zmeniť-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"

Akonáhle je sada zmien vytvorená, nemá žiadny vplyv na existujúci zásobník. Na rozdiel od príkazu update, prístup changeset nespúšťa skutočné nasadenie. Namiesto toho vytvorí zoznam zmien, ktoré môžete skontrolovať pred nasadením. Zmeny si môžete pozrieť v rozhraní konzoly aws. Ak však chcete automatizovať všetko, čo môžete, skontrolujte ich 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

Tento príkaz by mal vytvoriť výstup podobný nasledujúcemu:

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

Venujte zvláštnu pozornosť zmenám tam, kde je Action vymeniť, vymazať alebo kde Je potrebná výmena – pravda. Toto sú najnebezpečnejšie zmeny a zvyčajne vedú k strate informácií.

Po skontrolovaní zmien je možné ich nasadiť

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"

Lekcia 2: Použite politiku zásobníka, aby ste zabránili nahradeniu alebo odstráneniu stavových zdrojov

Niekedy len zobrazenie zmien nestačí. Všetci sme ľudia a všetci robíme chyby. Krátko po tom, ako sme začali používať sady zmien, môj spoluhráč nevedomky vykonal nasadenie, ktoré viedlo k aktualizácii databázy. Nič zlé sa nestalo, pretože išlo o testovacie prostredie.

Aj keď naše skripty zobrazovali zoznam zmien a žiadali potvrdenie, zmena Nahradiť bola preskočená, pretože zoznam zmien bol taký veľký, že sa nezmestil na obrazovku. A keďže išlo o bežnú aktualizáciu v testovacom prostredí, zmenám sa nevenovala veľká pozornosť.

Existujú zdroje, ktoré nikdy nechcete nahradiť alebo odstrániť. Sú to stavové služby, ako napríklad inštancia databázy RDS alebo klaster elasticsearch atď. Bolo by pekné, keby aws automaticky odmietol nasadenie, ak by si vykonávaná operácia vyžadovala vymazanie takéhoto zdroja. Našťastie, cloudformation má na to zabudovaný spôsob. Toto sa nazýva politika zásobníka a viac si o tom môžete prečítať v dokumentáciu:

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"

Lekcia 3: Použite UsePreviousValue pri aktualizácii zásobníka s tajnými parametrami

Keď vytvoríte entitu RDS mysql, AWS vyžaduje, aby ste zadali MasterUsername a MasterUserPassword. Keďže je lepšie nerobiť tajnosti v zdrojovom kóde a chcel som zautomatizovať úplne všetko, implementoval som „inteligentný mechanizmus“, kde sa pred nasadením získajú poverenia z s3 a ak sa nenájdu, vygenerujú sa nové a uložené v s3.

Tieto poverenia sa potom odovzdajú ako parametre príkazu cloudformation create-change-set. Pri experimentovaní so skriptom sa stalo, že sa stratilo spojenie so s3 a môj „inteligentný mechanizmus“ to považoval za signál na generovanie nových poverení.

Ak by som tento skript začal používať v produkcii a problém s pripojením by sa opakoval, aktualizovalo by sa zásobník o nové poverenia. V tomto konkrétnom prípade sa nič zlé nestane. Tento prístup som však opustil a začal som používať iný, pričom prihlasovacie údaje som poskytol iba raz – pri vytváraní zásobníka. A neskôr, keď je potrebné aktualizovať zásobník, namiesto špecifikovania tajnej hodnoty parametra by som jednoducho použil 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"

Lekcia 4: Použite konfiguráciu návratu

Ďalší tím, s ktorým som pracoval, túto funkciu používal tvorba oblačnostivolal konfigurácia návratu. Predtým som sa s tým nestretol a rýchlo som si uvedomil, že nasadenie mojich zásobníkov bude ešte chladnejšie. Teraz ho používam zakaždým, keď nasadím svoj kód do lambda alebo ECS pomocou cloudformácie.

Ako to funguje: špecifikujete Alarm CloudWatch v parametri --rollback-configurationkeď vytvoríte sadu zmien. Neskôr, keď vykonáte súbor zmien, aws monitoruje alarm aspoň jednu minútu. Ak sa počas tejto doby alarm zmení na stav ALARM, vráti nasadenie späť.

Nižšie je uvedený príklad úryvku zo šablóny tvorba oblačnostiv ktorom tvorím alarm cloudových hodiniek, ktorá sleduje používateľskú metriku cloudu ako počet chýb v protokoloch cloudu (metrika sa generuje prostredníctvom 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

Teraz poplach možno použiť ako rollback spúšťač pri spustení toolboxu:

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"

Lekcia 5: Uistite sa, že ste nasadili najnovšiu verziu šablóny

Je ľahké nasadiť menej ako najnovšiu verziu šablóny cloudformation, ale spôsobí to veľké škody. Toto sa nám raz stalo: vývojár nepresadil najnovšie zmeny z Gitu a nevedomky nasadil predchádzajúcu verziu zásobníka. To malo za následok výpadok aplikácie, ktorá používala tento zásobník.

Niečo také jednoduché ako pridanie kontroly, aby ste zistili, či je pobočka aktuálna predtým, ako sa jej zaviažete, by bolo v poriadku (za predpokladu, že git je váš nástroj na kontrolu verzií):

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

Lekcia 6: Neobjavujte znovu koleso

Môže sa to zdať ako nasadenie s tvorba oblačnosti - je to ľahké. Potrebujete len veľa bash skriptov, ktoré vykonávajú príkazy aws cli.

Pred 4 rokmi som začal s jednoduchými skriptami nazývanými príkaz aws cloudformation create-stack. Čoskoro scenár už nebol jednoduchý. Každá lekcia robila scenár čoraz zložitejším. Bolo to nielen náročné, ale aj plné bugov.

Momentálne pracujem v malom IT oddelení. Skúsenosti ukázali, že každý tím má svoj vlastný spôsob nasadenia cloudformačných zásobníkov. A to je zle. Bolo by lepšie, keby všetci zaujali rovnaký prístup. Našťastie je k dispozícii veľa nástrojov, ktoré vám pomôžu nasadiť a nakonfigurovať cloudové zostavy.

Tieto lekcie vám pomôžu vyhnúť sa chybám.

Zdroj: hab.com

Pridať komentár