Научио сам ових 6 лекција рада са цлоудформатионом до краја живота.

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

Научио сам ових 6 лекција рада са цлоудформатионом до краја живота.

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

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

После овог неуспеха, одмах сам се променио цевовод за примену, замењујући наредбу ажурирања командом креирај-промени-сет

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

Једном када се направи скуп промена, он нема утицаја на постојећи стек. За разлику од команде за ажурирање, приступ скупа измена не покреће стварну примену. Уместо тога, креира листу промена које можете да прегледате пре примене. Можете видети промене у интерфејсу авс конзоле. Али ако више волите да аутоматизујете све што можете, онда их проверите у ЦЛИ:

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

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

Када се промене прегледају, могу се применити

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

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

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

Постоје ресурси које никада не желите да замените или уклоните. То су услуге пуне стања, као што је инстанца базе података РДС или кластер еластичне претраге, итд. Било би лепо када би авс аутоматски одбио примену ако би операција која се изводи захтевала брисање таквог ресурса. Срећом, цлоудформатион има уграђен начин да то уради. Ово се зове политика стека, а више о томе можете прочитати у документација:

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: Користите УсеПревиоусВалуе када ажурирате стек са тајним параметрима

Када креирате РДС мискл ентитет, АВС захтева да наведете МастерУсернаме и МастерУсерПассворд. Пошто је боље не чувати тајне у изворном коду и желео сам да аутоматизујем апсолутно све, имплементирао сам „паметан механизам“ где ће се пре имплементације акредитиви добити од с3, а ако се акредитиви не пронађу, генеришу се нови акредитиви и похрањено у с3 .

Ови акредитиви ће затим бити прослеђени као параметри команди цлоудформатион цреате-цханге-сет. Током експериментисања са скриптом, десило се да се веза са с3 изгуби, а мој „паметни механизам“ је то третирао као сигнал за генерисање нових акредитива.

Ако бих почео да користим ову скрипту у продукцији и поново се десио проблем са везом, ажурирала би стек новим акредитивима. У овом конкретном случају неће се догодити ништа лоше. Међутим, напустио сам овај приступ и почео да користим други, дајући акредитиве само једном - приликом креирања стека. И касније, када је стеку потребно ажурирање, уместо навођења тајне вредности параметра, једноставно бих користио УсеПревиоусВалуе=труе:

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

Други тим са којим сам радио користио је ову функцију формирање облака, позван конфигурацију повратка. Раније нисам наишао на то и брзо сам схватио да ће то учинити распоређивање мојих стекова још хладнијим. Сада га користим сваки пут када поставим свој код на ламбда или ЕЦС користећи цлоудформатион.

Како то функционише: Ви одредите ЦлоудВатцх аларм арн у параметру --роллбацк-цонфигуратионкада креирате скуп промена. Касније, када извршите скуп промена, авс прати аларм најмање један минут. Поништава примену ако аларм промени стање у АЛАРМ током овог времена.

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

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 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: Не измишљајте точак

Може изгледати као да се примењује са формирање облака - то је лако. Треба вам само гомила басх скрипти које извршавају авс цли команде.

Пре 4 године сам почео са једноставним скриптама под називом авс цлоудформатион цреате-стацк команда. Убрзо сценарио више није био једноставан. Свака научена лекција чинила је сценарио све сложенијим. Било је не само тешко, већ и пуно буба.

Тренутно радим у малом ИТ одељењу. Искуство је показало да сваки тим има свој начин постављања стекова за формирање облака. И то је лоше. Било би боље да сви имају исти приступ. Срећом, постоји много доступних алата који ће вам помоћи да примените и конфигуришете стекове за формирање облака.

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

Извор: ввв.хабр.цом

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