Aghju amparatu queste 6 lezioni di travaglià cù a furmazione di nuvola per u restu di a mo vita.

Aghju cuminciatu à travaglià cun a furmazione di nuvola 4 anni fà. Da tandu aghju rottu assai infrastrutture, ancu quelle chì eranu digià in pruduzzione. Ma ogni volta chì aghju sbagliatu qualcosa, aghju amparatu qualcosa di novu. Per mezu di sta sperienza, sparteraghju alcune di e lezioni più impurtanti chì aghju amparatu.

Aghju amparatu queste 6 lezioni di travaglià cù a furmazione di nuvola per u restu di a mo vita.

Lezzione 1: Pruvate i cambiamenti prima di implementà

Aghju amparatu sta lezzione pocu dopu avè cuminciatu à travaglià a furmazione di nuvola. Ùn mi ricordu micca esattamente ciò chì aghju ruttu allora, ma mi ricordu di sicuru chì aghju utilizatu u cumandamentu aghjurnamentu di aws cloudformation. Stu cumandimu simpricimenti stende u mudellu senza alcuna validazione di i cambiamenti chì saranu implementati. Ùn pensu micca bisognu di spiegazione perchè duvete pruvà tutti i cambiamenti prima di implementà.

Dopu stu fallimentu, aghju cambiatu immediatamente spargeru, rimpiazzà u cumandamentu di l'aghjurnamentu cù u cumandamentu creà-cambià-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"

Una volta chì un set di cambiamenti hè creatu, ùn hà micca effettu nantu à a pila esistente. A cuntrariu di u cumandamentu di l'aghjurnamentu, l'approcciu di u cambiamentu ùn attiva micca a implementazione attuale. Invece, crea una lista di cambiamenti chì pudete esaminà prima di implementazione. Pudete vede i cambiamenti in l'interfaccia di aws console. Ma se preferite automatizà tuttu ciò chì pudete, verificateli in a 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

Stu cumandimu duveria pruduce output simili à i seguenti:

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

Prestate una attenzione speciale à i cambiamenti induve Azione hè Sustituitu, cancillari o induve Sostituzione necessaria - True. Quessi sò i cambiamenti più periculosi è generalmente portanu à a perdita di l'infurmazioni.

Una volta chì i cambiamenti sò stati riveduti, ponu esse implementati

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"

Lezzione 2: Aduprate a pulitica di stack per impedisce chì e risorse stateful sò rimpiazzate o eliminate

Calchì volta simpricimenti vede i cambiamenti ùn hè micca abbastanza. Semu tutti umani è tutti facemu sbagli. Pocu dopu avemu cuminciatu à aduprà cambiamenti, u mo cumpagnu di squadra hà realizatu senza sapè fà una implementazione chì hà risultatu in un aghjurnamentu di basa di dati. Ùn hè accadutu nunda di male perchè era un ambiente di prova.

Ancu s'è i nostri script anu mostratu una lista di cambiamenti è dumandanu a cunferma, u cambiamentu di rimpiazzà hè stata saltata perchè a lista di cambiamenti era cusì grande chì ùn si adattava micca à u screnu. E postu chì questu era un aghjurnamentu normale in un ambiente di prova, ùn hè micca stata assai attente à i cambiamenti.

Ci sò risorse chì ùn vulete mai rimpiazzà o sguassà. Quessi sò servizii statefull, cum'è una istanza di basa di dati RDS o un cluster di elasticsearch, etc. Saria bellu se aws ricusà automaticamente l'implementazione se l'operazione esse realizata necessitava di sguassà una tale risorsa. Per furtuna, cloudformation hà un modu integratu per fà questu. Questu hè chjamatu stack policy, è pudete leghje più nantu à questu in ducumentazione:

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"

Lezzione 3: Aduprate UsePreviousValue quandu aghjurnà una pila cù paràmetri secreti

Quandu crea una entità RDS mysql, AWS richiede di furnisce un MasterUsername è MasterUserPassword. Siccomu hè megliu micca di guardà sicreti in u codice fonte è vulia automatizà assolutamente tuttu, aghju implementatu un "mecanismu intelligente" induve prima di implementazione i credenziali seranu ottenuti da s3, è se i credenziali ùn sò micca truvati, novi credenziali sò generati è almacenatu in s3.

Queste credenziali saranu poi passate cum'è paràmetri à u cumandamentu di creazione-cambio-set di cloudformation. Mentre spirimintò cù u script, hè accadutu chì a cunnessione à s3 hè stata persa, è u mo "mecanismu intelligente" trattatu cum'è un signalu per generà novi credenziali.

Se aghju cuminciatu à utilizà stu script in a produzzione è u prublema di cunnessione hè accadutu di novu, aghjurnà a pila cù novi credenziali. In questu casu particulari, nunda di male ùn succede. Tuttavia, aghju abbandunatu stu approcciu è cuminciatu à aduprà un altru, furnisce credenziali una sola volta - quandu creanu a pila. È più tardi, quandu a pila hà bisognu di aghjurnà, invece di specificà u valore secretu di u paràmetru, solu aduprà 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"

Lezzione 4: Utilizà a cunfigurazione di rollback

Un altru squadra cù quale aghju travagliatu hà utilizatu a funzione a furmazione di nuvola, chjamatu cunfigurazione di rollback. Ùn l'avia micca scontru prima è aghju capitu rapidamente chì renderebbe a distribuzione di e mo pile ancu più fresche. Avà l'aghju utilizatu ogni volta chì implementu u mo codice à lambda o ECS usendu cloudformation.

Cumu funziona: specificate Alarma CloudWatch arn v paràmetru --rollback-configurazionequandu crea un set di cambiamenti. Più tardi, quandu eseguite un set di cambiamenti, aws monitoreghja l'alarma per almenu un minutu. Ritorna l'implementazione se l'alarma cambia u statu in ALARM durante stu tempu.

Quì sottu hè un esempiu di un extracte di mudellu a furmazione di nuvolain quale aghju creatu alarme cloudwatch, chì traccia una metrica di l'utilizatori di nuvola cum'è u numeru di errori in i logs di nuvola (a metrica hè generata via 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

Avà alarme pò esse usatu cum'è rollback trigger quandu eseguisce toolbox:

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"

Lezzione 5: Assicuratevi di implementà l'ultima versione di u mudellu

Hè facilitu implementà una versione menu di l'ultima versione di u mudellu di furmazione di nuvola, ma fà cusì causarà assai danni. Questu hè accadutu à noi una volta: un sviluppatore ùn hà micca spintu l'ultimi cambiamenti da Git è, senza sapè, hà implementatu una versione precedente di a pila. Questu hà risultatu in downtime per l'applicazione chì usava sta pila.

Qualcosa di simplice cum'è aghjunghje un cuntrollu per vede s'ellu a filiera hè aghjurnata prima di impegnà in questu seria bè (assumendu chì git hè u vostru strumentu di cuntrollu di versione):

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

Lezzione 6: Ùn reinventate micca a rota

Pò sembrà cum'è implementà cun a furmazione di nuvola - hè faciule. Avete solu bisognu di una mansa di scripts bash chì eseguenu cumandamenti aws cli.

4 anni fà aghju cuminciatu cù script simplici chjamati aws cloudformation create-stack command. Prestu u script ùn era più simplice. Ogni lezzione amparata facia u script sempre più cumplessu. Ùn era micca solu difficiule, ma ancu pienu di bugs.

Attualmente travagliu in un picculu dipartimentu IT. L'esperienza hà dimustratu chì ogni squadra hà u so propiu modu di implementà stacks di nuvola. È hè male. Saria megliu se tutti piglianu u listessu approcciu. Per furtuna, ci sò parechje strumenti dispunibuli per aiutà à implementà è cunfigurà pile di nuvola.

Queste lezioni vi aiutanu à evità i sbagli.

Source: www.habr.com

Add a comment