Έμαθα αυτά τα 6 μαθήματα εργασίας με το cloudformation για το υπόλοιπο της ζωής μου.

Άρχισα να δουλεύω με σύννεφο πριν 4 χρόνια. Από τότε έχω σπάσει πολλές υποδομές, ακόμα και αυτές που ήταν ήδη σε παραγωγή. Αλλά κάθε φορά που μπέρδευα κάτι, μάθαινα κάτι νέο. Μέσα από αυτή την εμπειρία, θα μοιραστώ μερικά από τα πιο σημαντικά μαθήματα που έμαθα.

Έμαθα αυτά τα 6 μαθήματα εργασίας με το cloudformation για το υπόλοιπο της ζωής μου.

Μάθημα 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   |
+---------+--------------------+----------------------+------------+

Δώστε ιδιαίτερη προσοχή στις αλλαγές όπου βρίσκεται το Action Αντικαταστήστε, Διαγραφή ή πού Απαιτείται αντικατάσταση - Σωστό. Αυτές είναι οι πιο επικίνδυνες αλλαγές και συνήθως οδηγούν σε απώλεια πληροφοριών.

Αφού ελεγχθούν οι αλλαγές, μπορούν να αναπτυχθούν

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=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: Χρήση διαμόρφωσης επαναφοράς

Μια άλλη ομάδα με την οποία συνεργάστηκα χρησιμοποίησε τη συνάρτηση σύννεφοπου ονομάζεται διαμόρφωση επαναφοράς. Δεν το είχα ξανασυναντήσει και γρήγορα συνειδητοποίησα ότι θα έκανε την ανάπτυξη των στοίβών μου ακόμα πιο δροσερή. Τώρα το χρησιμοποιώ κάθε φορά που αναπτύσσω τον κώδικά μου σε lambda ή ECS χρησιμοποιώντας cloudformation.

Πώς λειτουργεί: προσδιορίζετε εσείς Συναγερμός CloudWatch στην παράμετρο -- επαναφορά-διαμόρφωσηόταν δημιουργείτε ένα σύνολο αλλαγών. Αργότερα, όταν εκτελείτε ένα σύνολο αλλαγών, το aws παρακολουθεί το ξυπνητήρι για τουλάχιστον ένα λεπτό. Επαναφέρει την ανάπτυξη εάν ο συναγερμός αλλάξει κατάσταση σε ALARM κατά τη διάρκεια αυτής της περιόδου.

Παρακάτω είναι ένα παράδειγμα αποσπάσματος προτύπου σύννεφοστο οποίο δημιουργώ συναγερμός cloudwatch, η οποία παρακολουθεί μια μέτρηση χρήστη cloud ως τον αριθμό των σφαλμάτων στα αρχεία καταγραφής του cloud (η μέτρηση δημιουργείται μέσω 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

Τώρα τρομάζω μπορεί να χρησιμοποιηθεί ως rollback ενεργοποίηση κατά την εκτέλεση της εργαλειοθήκης:

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: Βεβαιωθείτε ότι έχετε αναπτύξει την πιο πρόσφατη έκδοση του προτύπου

Είναι εύκολο να αναπτύξετε μια λιγότερο από την πιο πρόσφατη έκδοση του προτύπου cloudformation, αλλά κάτι τέτοιο θα προκαλέσει μεγάλη ζημιά. Αυτό συνέβη σε εμάς μία φορά: ένας προγραμματιστής δεν προώθησε τις τελευταίες αλλαγές από το 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. Σύντομα το σενάριο δεν ήταν πια απλό. Κάθε μάθημα έκανε το σενάριο όλο και πιο περίπλοκο. Δεν ήταν μόνο δύσκολο, αλλά και γεμάτο σφάλματα.

Αυτή τη στιγμή εργάζομαι σε ένα μικρό τμήμα πληροφορικής. Η εμπειρία έχει δείξει ότι κάθε ομάδα έχει τον δικό της τρόπο να αναπτύσσει στοίβες σχηματισμού cloud. Και αυτό είναι κακό. Θα ήταν καλύτερα να ακολουθούσαν όλοι την ίδια προσέγγιση. Ευτυχώς, υπάρχουν πολλά διαθέσιμα εργαλεία για να σας βοηθήσουν να αναπτύξετε και να διαμορφώσετε στοίβες cloudformation.

Αυτά τα μαθήματα θα σας βοηθήσουν να αποφύγετε λάθη.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο