Ги научив овие 6 лекции за работа со cloudformation до крајот на мојот живот.

Почнав да работам со облачно формирање пред 4 години. Оттогаш искршив многу инфраструктури, дури и оние што веќе беа во производство. Но, секогаш кога ќе збркав нешто, научив нешто ново. Преку ова искуство, ќе споделам некои од најважните лекции што ги научив.

Ги научив овие 6 лекции за работа со cloudformation до крајот на мојот живот.

Лекција 1: Тестирајте ги промените пред да ги примените

Оваа лекција ја научив веднаш откако почнав да работам со облачно формирање. Не се сеќавам што точно скршив тогаш, но дефинитивно се сеќавам дека ја користев командата Ажурирање на облак формацијата aws. Оваа команда едноставно го прикажува шаблонот без никаква валидација на промените што ќе бидат распоредени. Мислам дека не е потребно никакво објаснување зошто треба да ги тестирате сите промени пред да ги примените.

По овој неуспех, веднаш се променив распоредување гасоводот, заменувајќи ја командата за ажурирање со командата креирај-промени-сет

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

Откако ќе се креира сет за промени, тоа нема ефект врз постојниот стек. За разлика од командата за ажурирање, пристапот на сет промени не го активира вистинското распоредување. Наместо тоа, создава листа на промени што можете да ги прегледате пред распоредувањето. Можете да ги видите промените во интерфејсот на конзолата aws. Но, ако сакате да автоматизирате сè што можете, тогаш проверете ги во 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

Оваа команда треба да произведе излез сличен на следново:

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

Обрнете посебно внимание на промените каде што е Action Заменете, Избришете или каде Потребна е замена - Точно. Ова се најопасните промени и обично доведуваат до губење на информации.

Откако ќе се разгледаат промените, тие можат да се применат

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: Користете политика на стек за да спречите заменување или отстранување на државните ресурси

Понекогаш едноставното гледање на промените не е доволно. Сите сме луѓе и сите грешиме. Набргу откако почнавме да користиме промени, мојот тимски колега несвесно изврши распоредување што резултираше со ажурирање на базата на податоци. Ништо лошо не се случи бидејќи тоа беше средина за тестирање.

Иако нашите скрипти прикажуваа список со промени и бараа потврда, промената Замени беше прескокната бидејќи списокот со промени беше толку голем што не се вклопуваше на екранот. И бидејќи ова беше нормално ажурирање во средина за тестирање, не беше посветено многу внимание на промените.

Постојат ресурси кои никогаш не сакате да ги замените или отстраните. Ова се државни услуги, како што е пример на база на податоци RDS или кластер за пребарување на elastics, итн. За среќа, cloudformation има вграден начин да го направи тоа. Ова се нарекува политика на стек, и можете да прочитате повеќе за тоа во документација:

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: Користете UsePreviousValue кога ажурирате стек со тајни параметри

Кога креирате RDS mysql ентитет, AWS бара од вас да наведете MasterUsername и MasterUserPassword. Бидејќи е подобро да не се чуваат тајни во изворниот код и сакав да автоматизирам апсолутно сè, имплементирав „паметен механизам“ каде пред распоредувањето ќе се добиваат ингеренциите од s3, а доколку не се најдат ингеренциите, се генерираат нови ингеренции и складирани во s3.

Овие ингеренции потоа ќе се пренесат како параметри на командата cloudformation create-change-set. Додека експериментирав со сценариото, се случи врската со s3 да се изгуби, а мојот „паметен механизам“ го третираше како сигнал за генерирање нови ингеренции.

Ако почнам да ја користам оваа скрипта во производството и проблемот со поврзувањето се случи повторно, тоа ќе го ажурира оџакот со нови ингеренции. Во овој конкретен случај, ништо лошо нема да се случи. Сепак, го напуштив овој пристап и почнав да користам друг, давајќи акредитиви само еднаш - при креирањето на стекот. И подоцна, кога стекот треба да се ажурира, наместо да ја специфицирам тајната вредност на параметарот, едноставно би користел UsePreviousValue=точно:

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: Користете ја конфигурацијата за враќање назад

Друг тим со кој работев ја искористи функцијата облачно формирање, повикан конфигурација за враќање назад. Не го сретнав претходно и брзо сфатив дека ќе го направи распоредувањето на моите купови уште поладно. Сега го користам секогаш кога го распоредувам мојот код на ламбда или ECS користејќи облак формација.

Како функционира: вие наведете CloudWatch аларм arn во параметарот --враќање-конфигурацијакога креирате сет на промени. Подоцна, кога ќе извршите збир на промени, aws го следи алармот најмалку една минута. Го враќа распоредувањето ако алармот ја промени состојбата во ALARM во ова време.

Подолу е пример за извадок од шаблон облачно формирањево која создавам аларм за часовник во облак, која ја следи метриката на корисникот облак како број на грешки во дневниците на облакот (метриката се генерира преку Метрички филтер):

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

Сега алармот може да се користи како враќање активирањето при извршување на алатникот:

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: Погрижете се да ја распоредите најновата верзија на шаблонот

Лесно е да се распореди помалку од најновата верзија на шаблонот за облакформација, но тоа ќе предизвика многу штета. Ова ни се случи еднаш: програмер не ги притисна најновите промени од Git и несвесно распореди претходна верзија на стекот. Ова резултираше со прекин на апликацијата што го користеше овој стек.

Нешто едноставно како додавање чек за да се види дали филијалата е ажурирана пред да се посветите, би било добро (да се претпостави дека git е вашата алатка за контрола на верзијата):

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: Не измислувајте го тркалото повторно

Можеби изгледа како да се распоредува со облачно формирање - тоа е лесно. Потребни ви се само еден куп баш скрипти кои ги извршуваат командите aws cli.

Пред 4 години започнав со едноставни скрипти наречени команда aws cloudformation create-stack. Наскоро сценариото веќе не беше едноставно. Секоја научена лекција го правеше сценариото сè покомплексно. Не само што беше тешко, туку и полно со бубачки.

Моментално работам во мал оддел за ИТ. Искуството покажа дека секој тим има свој начин на распоредување на стекови на облак формации. И тоа е лошо. Би било подобро сите да го прифатат истиот пристап. За среќа, има многу достапни алатки кои ќе ви помогнат да ги распоредите и конфигурирате стековите за облакформација.

Овие лекции ќе ви помогнат да избегнете грешки.

Извор: www.habr.com

Додадете коментар