Ez a 6 cloudformation órára szóló leckét az egész életemre megtanultam.

Elkezdem dolgozni a cloudformation-nel 4 évvel ezelőtt. Azóta sok infrastruktúrát tönkretettem, még azokat is, amelyek már élesben voltak. De minden egyes alkalommal, amikor valamit elrontottam, új dolgot tanultam. E tapasztalat révén megosztom a legfontosabb leckéket, amelyeket megtanultam.

Ez a 6 cloudformation órára szóló leckét az egész életemre megtanultam.

1. lecke: ellenőrizze a változásokat a telepítés előtt

Ezt a leckét nem sokkal azután tanultam meg, hogy elkezdtem dolgozni a cloudformation-nel-nél. Nem emlékszem pontosan, mit rontottam el, de biztosan emlékszem, hogy használtam a parancsot aws cloudformation update. Ez a parancs egyszerűen telepíti a sablont mindenféle változásellenőrzés nélkül. Gondolom, nem szükséges elmagyarázni, miért kell az összes változást ellenőrizni a telepítés előtt.

Ez a kudarc után azonnal megváltoztattam a telepítési folyamatot, az update parancsot a create-change-set parancsra cserélve.

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

Amikor a változáskiírás elkészült, az semmilyen hatással nincs a meglévő veremre. A frissítési parancshoz képest a változáskiírásra alapozó megközelítés nem okoz tényleges telepítést. Ehelyett létrehoz egy változási listát, amelyet megtekinthet a telepítés előtt. Megtekintheti a változásokat az AWS konzolban. De ha preferálja az automatizálást, akkor ellenőrizheti őket a CLI-n:

# 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

Ez a parancs egy olyan kimenetet kell adjon, amely hasonló a következőhöz:

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

Figyeljen különösen a változásokra, ahol az Action a Replace, Törlés vagy ahol a ReplacementNeeded — True. Ezek a legveszélyesebb változások, és általában adatvesztéshez vezetnek.

Miután megvizsgálták a változásokat, azok telepíthetők:

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. lecke: használjon verempolitikát az erőforrások helyettesítésének vagy eltávolításának megakadályozására az állapot megőrzésével.

Néha a változások egyszerű megtekintése nem elegendő. Mindannyian emberek vagyunk, és mindannyian követünk el hibákat. Nem sokkal azután, hogy elkezdtük használni a változáscsomagokat, a csapattársam tudtán kívül végrehajtotta a telepítést, ami az adatbázis frissítéséhez vezetett. Semmi komoly nem történt, mert ez egy tesztkörnyezet volt.

Bár a szkripteink listázni tudták a változásokat és megerősítést kértek, a Replace változás kimaradt, mert a változási lista olyan hosszú volt, hogy nem fért el a képernyőn. Mivel ez egy megszokott frissítés volt a tesztkörnyezetben, a változásokra nem figyeltek fel túlzottan.

Vannak erőforrások, amelyeket soha nem szeretnél lecserélni vagy eltávolítani. Ezek például stateful szolgáltatások, mint az RDS adatbázis példány vagy az Elasticsearch klaszter stb. Jó lenne, ha az AWS automatikusan megtagadná a telepítést, ha a végrehajtott művelet eltávolítást igényelne egy ilyen erőforrástól. Szerencsére a CloudFormation rendelkezik egy beépített módszerrel erre. Ezt stack policy-nak hívják, és erről többet megtudhatsz a dokumentáció:

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. lecke: használd a UsePreviousValue-t, amikor titkos paraméterekkel frissíted a stacket

Amikor RDS MySQL entitást hozol létre, az AWS megköveteli, hogy add meg a MasterUsername és MasterUserPassword értékeket. Mivel a titkokat nem célszerű a forráskódban tárolni, és mindent automatikusan szerettem volna megoldani, megvalósítottam egy „okos mechanizmust”, amely előre a telepítés előtt az adatokat az S3-ból szerzi be, ha pedig az adatok nem találhatóak, új adatokat generál és tárol az S3-ban.

Ezeket az adatokat ezután paraméterként adják át a cloudformation create-change-set parancsnak. A szkripttel való kísérletezés során előfordult, hogy a kapcsolat az S3-mal megszakadt, és az én „okos mechanizmusom” ezt jelzésnek tekintette az új adatképek generálására.

Ha elkezdtem volna használni ezt a szkriptet munkakörnyezetben, és a csatlakozási probléma újra jelentkezett volna, akkor frissítette volna a veremet új hitelesítő adatokkal. Ebben az esetben semmi rossz nem történik. Azonban elvetettem ezt a megközelítést, és elkezdtem használni egy másikat, amelyben a hitelesítő adatokat csak egyszer, a verem létrehozásakor adom meg. És később, amikor a verem frissítést igényel, ahelyett, hogy megadnám a titkos paraméterértéket, egyszerűen használnám 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"

4. lecke: használja a rollback konfigurációt

Egy másik parancs, amellyel dolgoztam, használt egy funkciót cloudformation-nel, amelyet rollback configuration-nak nevezték. Eddig nem találkoztam vele, és gyorsan megérthettem, hogy ez még jobbá fogja tenni a veremeseményeim telepítését. Most minden alkalommal használom, amikor a kódot telepítem lambda vagy ECS segítségével cloudformation.

Hogyan működik: megadja CloudWatch alarm arn a paraméterben -rollback-configuration, amikor létrehozza a változtatási készletet. Később, amikor végrehajtja a változtatási készletet, az AWS legalább egy percig figyeli az alarmot. Ha ez idő alatt az alarm állapota ALARM-ra változik, akkor visszaállítja a telepítést.

Az alábbiakban bemutatok egy sablonrészletet cloudformation-nel, amiben létrehozom a cloudwatch alarmot, amely a cloud logokban lévő hibák számát nyomon követő felhasználói metrikát figyeli (a metrika a MetricFilter):

által jön létre.
  Resources:
  # ez a metrika a cloudwatch naplókban lévő hibák számát követi. Ebben a
  # konkrét esetben feltételezhető, hogy a naplók json formátumban vannak, és a hiba naplók
  # az "error" szinten azonosíthatók. Lásd 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 perc
      EvaluationPeriods: 1
      Threshold: 0
      TreatMissingData: notBreaching
      ActionsEnabled: yes

Jelenleg alarm használható mint rollback trigger végrehajtásakor a készlet:

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. lecke: győződjön meg róla, hogy a legfrissebb sablont telepíti

Könnyű telepíteni nem a legfrissebb cloudformation sablont, de ez nagy kárt okozhat. Egyszer ilyen történt velünk: a fejlesztő nem küldte el a legutolsó változtatásokat a Gitből, és tudtán kívül egy korábbi verziót telepített. Ez az alkalmazás leállásához vezetett, amely ezt a verem használta.

Valami egyszerű, például a vizsgálat, hogy a ág aktuális-e, mielőtt a telepítés végrehajtására kerülne sor (ha feltételezzük, hogy a git az Ön verziókezelő eszköze):

git fetch
HEADHASH=$(git rev-parse HEAD)
UPSTREAMHASH=$(git rev-parse master@{upstream})

if [[ "$HEADHASH" != "$UPSTREAMHASH" ]] ; then
   echo "Az ág nincs szinkronban az eredetivel. Megszakítás"
   exit 1
fi

6. lecke: ne találja fel újra a kereket

Úgy tűnhet, hogy a telepítés cloudformation-nel — ez könnyű. Csak sok bash szkriptre van szüksége, amelyek aws cli parancsokat hajtanak végre.

Négy évvel ezelőtt egyszerű szkriptekkel kezdtem, amelyeket aws cloudformation create-stack parancsnak hívtak. Hamarosan a szkript már nem volt egyszerű. Minden egyes tanult lecke bonyolultabbá tette a szkriptet. Nemcsak bonyolult volt, hanem tele volt hibákkal is.

Most egy kis IT részlegen dolgozom. A tapasztalat azt mutatja, hogy minden csapatnak megvan a saját módja a cloudformation verem telepítésének. Ez rossz. Jobb lenne, ha mindenki egy egységes megközelítést használna. Szerencsére sok eszköz áll rendelkezésre, amelyek segítenek a cloudformation veremek telepítésében és konfigurálásában.

Ezek a leckék segítenek elkerülni a hibákat.

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster