Mi lernis ĉi tiujn 6 lecionojn pri laborado kun nuboformado por la resto de mia vivo.

Mi komencis labori kun nuboformado antaŭ 4 jaroj. Ekde tiam mi rompis multajn infrastrukturojn, eĉ tiujn, kiuj jam estis en produktado. Sed ĉiufoje kiam mi fuŝis ion, mi lernis ion novan. Per ĉi tiu sperto, mi dividos kelkajn el la plej gravaj lecionoj, kiujn mi lernis.

Mi lernis ĉi tiujn 6 lecionojn pri laborado kun nuboformado por la resto de mia vivo.

Leciono 1: Testu ŝanĝojn antaŭ deploji ilin

Mi lernis ĉi tiun lecionon baldaŭ post kiam mi komencis labori kun nuboformado. Mi ne memoras, kion precize mi rompis tiam, sed mi certe memoras, ke mi uzis la komandon aws cloudformation ĝisdatigo. Ĉi tiu komando simple ruliĝas la ŝablonon sen ajna validigo de la ŝanĝoj kiuj estos deplojitaj. Mi pensas, ke neniu klarigo necesas pri kial vi devus testi ĉiujn ŝanĝojn antaŭ ol disfaldi ilin.

Post ĉi tiu malsukceso, mi tuj ŝanĝiĝis disfaldas dukton, anstataŭigante la ĝisdatigan komandon per la komando krei-ŝanĝi-aro

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

Post kiam ŝanĝaro estas kreita, ĝi havas neniun efikon al la ekzistanta stako. Male al la ĝisdatiga komando, la ŝanĝa aliro ne ekigas la realan deplojon. Anstataŭe, ĝi kreas liston de ŝanĝoj, kiujn vi povas revizii antaŭ deplojo. Vi povas vidi la ŝanĝojn en la aws-konzola interfaco. Sed se vi preferas aŭtomatigi ĉion, kion vi povas, tiam kontrolu ilin en la 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

Ĉi tiu komando devus produkti eligon similan al la sekvanta:

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

Atentu specialan ŝanĝojn kie Ago estas Anstataŭigi, forviŝi aŭ kie AnstataŭaĵoNecesa - Vera. Ĉi tiuj estas la plej danĝeraj ŝanĝoj kaj kutime kondukas al perdo de informoj.

Post kiam la ŝanĝoj estas reviziitaj, ili povas esti deplojitaj

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"

Leciono 2: Uzu stakpolitikon por malhelpi ŝtatajn rimedojn esti anstataŭigitaj aŭ forigitaj

Kelkfoje simple vidi la ŝanĝojn ne sufiĉas. Ni ĉiuj estas homoj kaj ni ĉiuj faras erarojn. Baldaŭ post kiam ni komencis uzi ŝanĝojn, mia samteamano senscie elfaris deplojon, kiu rezultigis datumbazan ĝisdatigon. Nenio malbona okazis ĉar ĝi estis testa medio.

Kvankam niaj skriptoj montris liston de ŝanĝoj kaj petis konfirmon, la Anstataŭigi ŝanĝo estis preterlasita ĉar la listo de ŝanĝoj estis tiom granda ke ĝi ne konvenis sur la ekrano. Kaj ĉar ĉi tio estis normala ĝisdatigo en prova medio, oni ne multe atentis la ŝanĝojn.

Estas rimedoj, kiujn vi neniam volas anstataŭigi aŭ forigi. Ĉi tiuj estas ŝtatplenaj servoj, kiel ekzemple RDS-datumbaza kazo aŭ elastaserĉaro, ktp. Estus bone, se aws aŭtomate rifuzus disfaldiĝon se la operacio faranta postulus forigi tian rimedon. Feliĉe, nuboformado havas enkonstruitan manieron fari tion. Ĉi tio nomiĝas stakpolitiko, kaj vi povas legi pli pri ĝi en dokumentado:

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"

Leciono 3: Uzu UsePreviousValue kiam ĝisdatigas stakon kun sekretaj parametroj

Kiam vi kreas RDS-mysql-entaĵon, AWS postulas, ke vi disponigu MasterUsername kaj MasterUserPassword. Ĉar estas pli bone ne konservi sekretojn en la fontkodo kaj mi volis aŭtomatigi absolute ĉion, mi efektivigis "inteligentan mekanismon" kie antaŭ deplojo la akreditaĵoj estos akiritaj de s3, kaj se la akreditaĵoj ne estas trovitaj, novaj akreditaĵoj estas generitaj kaj stokita en s3.

Ĉi tiuj akreditaĵoj tiam estos transdonitaj kiel parametroj al la komando cloudformation create-change-set. Eksperimentante kun la skripto, okazis, ke la konekto al s3 estis perdita, kaj mia "inteligenta mekanismo" traktis ĝin kiel signalon por generi novajn akreditaĵojn.

Se mi komencus uzi ĉi tiun skripton en produktado kaj la koneksa problemo denove okazis, ĝi ĝisdatigus la stakon kun novaj akreditaĵoj. En ĉi tiu aparta kazo, nenio malbona okazos. Tamen, mi forlasis ĉi tiun aliron kaj komencis uzi alian, provizante akreditaĵojn nur unufoje - dum kreado de la stako. Kaj poste, kiam la stako bezonas ĝisdatigon, anstataŭ specifi la sekretan valoron de la parametro, mi simple uzus UsePreviousValue=vera:

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"

Leciono 4: Uzu revalidan agordon

Alia teamo kun kiu mi laboris uzis la funkcion nuboformado, vokis restariga agordo. Mi ne renkontis ĝin antaŭe kaj rapide rimarkis, ke ĝi eĉ pli malvarmigus deploji miajn stakojn. Nun mi uzas ĝin ĉiufoje kiam mi deplojas mian kodon al lambda aŭ ECS per nuboformado.

Kiel ĝi funkcias: vi specifu CloudWatch alarmo en la parametro --rollback-agordokiam vi kreas ŝanĝaron. Poste, kiam vi efektivigas aron da ŝanĝoj, aws kontrolas la alarmon dum almenaŭ unu minuto. Ĝi retroiras la deplojon se alarmo ŝanĝas staton al ALARM dum ĉi tiu tempo.

Malsupre estas ekzemplo de ŝablono eltiraĵo nuboformadoen kiu mi kreas cloudwatch alarmo, kiu spuras nuban uzantan metrikon kiel la nombro da eraroj en la nubaj protokoloj (la metriko estas generita per 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

Nun alarmo povas esti uzata kiel rollback ellasilon dum plenumado de ilarkesto:

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"

Leciono 5: Certigu, ke vi disfaldas la lastan version de la ŝablono

Estas facile deploji malpli-ol-lastan version de la ŝablono pri nuboformado, sed fari tion kaŭzos multe da damaĝo. Ĉi tio okazis al ni unufoje: programisto ne puŝis la lastajn ŝanĝojn de Git kaj senkonscie deplojis antaŭan version de la stako. Ĉi tio rezultigis malfunkcion por la aplikaĵo, kiu uzis ĉi tiun stakon.

Io tiel simpla kiel aldoni kontrolon por vidi ĉu la branĉo estas ĝisdatigita antaŭ ol fari ĝin estus bone (supoze ke git estas via versio-kontrolilo):

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

Leciono 6: Ne reinventu la radon

Ĝi povas ŝajni kiel deploji kun nuboformado - ĝi estas facila. Vi nur bezonas amason da bash-skriptoj ekzekutantaj aws cli komandojn.

Antaŭ 4 jaroj mi komencis per simplaj skriptoj nomataj la komando aws cloudformation create-stack. Baldaŭ la skripto ne plu estis simpla. Ĉiu lernita leciono igis la skripton pli kaj pli kompleksa. Ĝi estis ne nur malfacila, sed ankaŭ plena de cimoj.

Nuntempe mi laboras en malgranda IT-sekcio. Sperto montris, ke ĉiu teamo havas sian propran manieron deploji nubformajn stakojn. Kaj tio estas malbona. Estus pli bone, se ĉiuj farus la saman aliron. Feliĉe, ekzistas multaj iloj disponeblaj por helpi vin disfaldi kaj agordi nubformajn stakojn.

Ĉi tiuj lecionoj helpos vin eviti erarojn.

fonto: www.habr.com

Aldoni komenton