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

Започнах работа с образуване на облак преди 4 години. Оттогава съм счупил много инфраструктури, дори такива, които вече са в производство. Но всеки път, когато обърках нещо, научавах нещо ново. Чрез този опит ще споделя някои от най-важните уроци, които научих.

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

Урок 1: Тествайте промените, преди да ги внедрите

Научих този урок скоро след като започнах да работя с образуване на облак. Не помня какво точно счупих тогава, но определено помня, че използвах командата актуализация на aws cloudformation. Тази команда просто пуска шаблона без валидиране на промените, които ще бъдат внедрени. Не мисля, че е необходимо обяснение защо трябва да тествате всички промени, преди да ги внедрите.

След този провал веднага се промених тръбопровод за внедряване, заменяйки командата за актуализиране с командата създаване-промяна-задаване

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

Обърнете специално внимание на промените, където е Действие Сменете, Изтрий или къде Необходима подмяна - вярно. Това са най-опасните промени и обикновено водят до загуба на информация.

След като промените бъдат прегледани, те могат да бъдат внедрени

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 база данни или клъстер elasticsearch и т.н. Би било хубаво, ако aws автоматично откаже внедряване, ако извършваната операция изисква изтриване на такъв ресурс. За щастие, 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. Докато експериментирах със скрипта, се случи връзката с 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: Използвайте конфигурация за връщане назад

Друг екип, с който работих, използва функцията образуване на облакНаречен конфигурация за връщане назад. Не бях попадал на него преди и бързо разбрах, че ще направи разгръщането на моите стекове още по-готино. Сега го използвам всеки път, когато внедрявам кода си в lambda или ECS, използвайки cloudformation.

Как работи: Вие определяте CloudWatch аларма в параметър --rollback-конфигурациякогато създавате набор от промени. По-късно, когато изпълните набор от промени, aws следи алармата за поне една минута. Той връща разгръщането, ако алармата промени състоянието на АЛАРМА през това време.

По-долу е даден пример за извадка от шаблон образуване на облакв който творя облачна аларма, който проследява потребителски показател в облака като брой грешки в регистрационните файлове в облака (показателят се генерира чрез 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

Сега аларма може да се използва като общо намаление на цените задействане при изпълнение на кутия с инструменти:

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: Не преоткривайте колелото

Може да изглежда като внедряване с образуване на облак - това е лесно. Просто се нуждаете от куп bash скриптове, изпълняващи aws cli команди.

Преди 4 години започнах с прости скриптове, наречени команда aws cloudformation create-stack. Скоро сценарият вече не беше прост. Всеки научен урок правеше сценария все по-сложен. Беше не само трудно, но и пълно с грешки.

В момента работя в малък IT отдел. Опитът показва, че всеки екип има свой собствен начин за внедряване на стекове за формиране на облак. И това е лошо. Би било по-добре, ако всички възприемат същия подход. За щастие има много налични инструменти, които да ви помогнат да внедрите и конфигурирате стекове за формиране на облак.

Тези уроци ще ви помогнат да избегнете грешки.

Източник: www.habr.com

Добавяне на нов коментар