Jag lärde mig dessa 6 lektioner av att arbeta med molnbildning för resten av mitt liv.

Jag började jobba med molnbildning 4 år sedan. Sedan dess har jag brutit sönder många infrastrukturer, även sådana som redan var i produktion. Men varje gång jag förstörde något lärde jag mig något nytt. Genom denna erfarenhet kommer jag att dela med mig av några av de viktigaste lärdomarna jag lärt mig.

Jag lärde mig dessa 6 lektioner av att arbeta med molnbildning för resten av mitt liv.

Lektion 1: Testa ändringar innan du distribuerar dem

Jag lärde mig den här läxan strax efter att jag började arbeta med molnbildning. Jag minns inte exakt vad jag bröt då, men jag kommer definitivt ihåg att jag använde kommandot aws cloudformation uppdatering. Detta kommando rullar helt enkelt ut mallen utan någon validering av ändringarna som kommer att distribueras. Jag tror inte det behövs någon förklaring till varför du bör testa alla ändringar innan du implementerar dem.

Efter detta misslyckande ändrade jag mig omedelbart distribution pipeline, ersätter uppdateringskommandot med kommandot skapa-förändring-uppsättning

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

När en ändringsuppsättning väl har skapats har den ingen effekt på den befintliga stacken. Till skillnad från uppdateringskommandot utlöser inte changeset-metoden den faktiska distributionen. Istället skapar den en lista med ändringar som du kan granska innan implementering. Du kan se ändringarna i aws-konsolens gränssnitt. Men om du föredrar att automatisera allt du kan, kontrollera dem i 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

Detta kommando bör producera utdata som liknar följande:

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

Var särskilt uppmärksam på förändringar där Action är ersätta, Radera eller var Behövs byte - sant. Dessa är de farligaste förändringarna och leder vanligtvis till förlust av information.

När ändringarna har granskats kan de implementeras

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"

Lektion 2: Använd stackpolicy för att förhindra att statistiska resurser ersätts eller tas bort

Ibland räcker det inte att bara titta på ändringarna. Vi är alla människor och vi gör alla misstag. Kort efter att vi började använda ändringsuppsättningar, utförde min lagkamrat omedvetet en distribution som resulterade i en databasuppdatering. Inget dåligt hände eftersom det var en testmiljö.

Även om våra skript visade en lista med ändringar och bad om bekräftelse, hoppades ändringen Ersätt över eftersom listan med ändringar var så stor att den inte fick plats på skärmen. Och eftersom detta var en normal uppdatering i en testmiljö ägnades inte mycket uppmärksamhet åt ändringarna.

Det finns resurser som du aldrig vill ersätta eller ta bort. Dessa är tillståndsfulla tjänster, såsom en RDS-databasinstans eller ett elastiskt sökkluster, etc. Det skulle vara trevligt om aws automatiskt skulle vägra driftsättning om operationen som utförs skulle kräva att en sådan resurs tas bort. Lyckligtvis har molnbildning ett inbyggt sätt att göra detta. Detta kallas stackpolicy, och du kan läsa mer om det i dokumentation:

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"

Lektion 3: Använd UsePreviousValue när du uppdaterar en stack med hemliga parametrar

När du skapar en RDS mysql-entitet kräver AWS att du tillhandahåller ett MasterUsername och MasterUserPassword. Eftersom det är bättre att inte hålla hemligheter i källkoden och jag ville automatisera absolut allt, implementerade jag en "smart mekanism" där inloggningsuppgifterna kommer att hämtas från s3 innan implementeringen, och om referenserna inte hittas genereras nya inloggningsuppgifter och lagras i s3.

Dessa referenser kommer sedan att skickas som parametrar till kommandot cloudformation create-change-set. När jag experimenterade med skriptet hände det att anslutningen till s3 förlorades, och min "smarta mekanism" behandlade det som en signal för att generera nya referenser.

Om jag började använda det här skriptet i produktionen och anslutningsproblemet inträffade igen, skulle det uppdatera stacken med nya referenser. I det här speciella fallet kommer inget dåligt att hända. Men jag övergav det här tillvägagångssättet och började använda en annan, och lämnade inloggningsuppgifter bara en gång - när jag skapade stacken. Och senare, när stacken behöver uppdateras, istället för att ange parameterns hemliga värde, skulle jag helt enkelt använda 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"

Lektion 4: Använd återställningskonfiguration

Ett annat team jag arbetade med använde funktionen molnbildningkallad återställningskonfiguration. Jag hade inte stött på det tidigare och insåg snabbt att det skulle göra utplaceringen av mina stackar ännu coolare. Nu använder jag det varje gång jag distribuerar min kod till lambda eller ECS med hjälp av molnformation.

Hur det fungerar: du anger CloudWatch-larm i parametern --rollback-konfigurationnär du skapar en ändringsuppsättning. Senare, när du utför en uppsättning ändringar, övervakar aws larmet i minst en minut. Det rullar tillbaka driftsättningen om larmet ändrar tillstånd till ALARM under denna tid.

Nedan finns ett exempel på ett mallutdrag molnbildningdär jag skapar molnurslarm, som spårar ett molnanvändarmått som antalet fel i molnloggarna (måttet genereras 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

Nu larm kan användas som rollback trigger när verktygslådan körs:

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"

Lektion 5: Se till att du distribuerar den senaste versionen av mallen

Det är lätt att distribuera en mindre än den senaste versionen av molnformationsmallen, men att göra det kommer att orsaka mycket skada. Detta hände oss en gång: en utvecklare drev inte de senaste ändringarna från Git och distribuerade omedvetet en tidigare version av stacken. Detta resulterade i driftstopp för applikationen som använde denna stack.

Något så enkelt som att lägga till en kontroll för att se om grenen är uppdaterad innan du bestämmer dig för det skulle vara bra (förutsatt att git är ditt versionskontrollverktyg):

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

Lektion 6: Uppfinn inte hjulet på nytt

Det kan verka som att distribuera med molnbildning - det är lätt. Du behöver bara ett gäng bash-skript som kör aws cli-kommandon.

För 4 år sedan började jag med enkla skript som kallas aws cloudformation create-stack kommandot. Snart var manuset inte längre enkelt. Varje lärdom gjorde manuset mer och mer komplext. Det var inte bara svårt, utan också fullt av buggar.

Jag arbetar för närvarande på en liten IT-avdelning. Erfarenhet har visat att varje team har sitt eget sätt att distribuera molnformationsstackar. Och det är dåligt. Det vore bättre om alla tog samma inställning. Lyckligtvis finns det många tillgängliga verktyg som hjälper dig att distribuera och konfigurera molnformationsstackar.

Dessa lektioner hjälper dig att undvika misstag.

Källa: will.com

Lägg en kommentar