Naučio sam ovih 6 lekcija o radu sa cloudformacijom do kraja života.

Počeo sam da radim sa formiranje oblaka prije 4 godine. Od tada sam razbio dosta infrastrukture, čak i one koje su već bile u proizvodnji. Ali svaki put kada sam nešto zabrljao, naučio sam nešto novo. Kroz ovo iskustvo podijelit ću neke od najvažnijih lekcija koje sam naučio.

Naučio sam ovih 6 lekcija o radu sa cloudformacijom do kraja života.

Lekcija 1: Testirajte promjene prije njihove implementacije

Naučio sam ovu lekciju ubrzo nakon što sam počeo da radim sa formiranje oblaka. Ne sjećam se šta sam tačno tada slomio, ali se sigurno sjećam da sam koristio komandu aws cloudformation update. Ova naredba jednostavno pokreće predložak bez ikakve validacije promjena koje će biti implementirane. Mislim da nije potrebno nikakvo objašnjenje zašto biste trebali testirati sve promjene prije nego što ih implementirate.

Nakon ovog neuspjeha, odmah sam se promijenio uvodni gasovod, zamjenjujući naredbu ažuriranja naredbom kreiraj-promeni-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"

Jednom kada se kreira skup promjena, on nema utjecaja na postojeći stek. Za razliku od naredbe ažuriranja, pristup skupa promjena ne pokreće stvarnu implementaciju. Umjesto toga, kreira listu promjena koje možete pregledati prije implementacije. Možete vidjeti promjene u interfejsu aws konzole. Ali ako više volite automatizirati sve što možete, provjerite ih u 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

Ova naredba bi trebala proizvesti izlaz sličan sljedećem:

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

Obratite posebnu pažnju na promjene gdje je Akcija zamijeniti, izbrisati ili gde Potrebna zamjena - Tačno. To su najopasnije promjene i obično dovode do gubitka informacija.

Nakon što se izmjene pregledaju, mogu se primijeniti

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"

Lekcija 2: Koristite politiku steka da spriječite zamjenu ili uklanjanje resursa s podacima o stanju

Ponekad jednostavno pregledavanje promjena nije dovoljno. Svi smo mi ljudi i svi griješimo. Ubrzo nakon što smo počeli koristiti skupove izmjena, moj kolega iz tima je nesvjesno izvršio implementaciju koja je rezultirala ažuriranjem baze podataka. Ništa loše se nije dogodilo jer je to bilo okruženje za testiranje.

Iako su naše skripte prikazale listu promjena i tražile potvrdu, promjena Zamijeni je preskočena jer je lista izmjena bila toliko velika da nije stala na ekran. A pošto je ovo bilo normalno ažuriranje u okruženju za testiranje, promjenama se nije obraćala mnogo pažnje.

Postoje resursi koje nikada ne želite zamijeniti ili ukloniti. To su usluge pune stanja, kao što je instanca baze podataka RDS ili klaster elastičnog pretraživanja, itd. Bilo bi lijepo kada bi aws automatski odbio implementaciju ako bi operacija koja se izvodi zahtijevala brisanje takvog resursa. Srećom, cloudformation ima ugrađen način za to. Ovo se zove politika steka, a više o tome možete pročitati u dokumentaciju:

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"

Lekcija 3: Koristite UsePreviousValue kada ažurirate stog sa tajnim parametrima

Kada kreirate RDS mysql entitet, AWS zahtijeva da unesete MasterUsername i MasterUserPassword. Pošto je bolje ne čuvati tajne u izvornom kodu i želeo sam da automatizujem apsolutno sve, implementirao sam "pametan mehanizam" gde će se pre implementacije akreditivi dobiti od s3, a ako se akreditivi ne pronađu, generišu se novi akreditivi i pohranjeno u s3 .

Ove vjerodajnice će zatim biti proslijeđene kao parametri naredbi cloudformation create-change-set. Dok sam eksperimentisao sa skriptom, desilo se da se veza sa s3 izgubi, a moj "pametni mehanizam" je to tretirao kao signal za generisanje novih akreditiva.

Ako bih počeo da koristim ovu skriptu u produkciji i ponovo se desio problem sa vezom, ažurirala bi stek novim akreditivima. U ovom konkretnom slučaju neće se dogoditi ništa loše. Međutim, napustio sam ovaj pristup i počeo koristiti drugi, dajući vjerodajnice samo jednom - prilikom kreiranja steka. I kasnije, kada je stog potrebno ažuriranje, umjesto specificiranja tajne vrijednosti parametra, jednostavno bih koristio 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"

Lekcija 4: Koristite konfiguraciju za vraćanje nazad

Drugi tim s kojim sam radio koristio je tu funkciju formiranje oblaka, zvao konfiguracija vraćanja nazad. Nisam ranije naišao na nju i brzo sam shvatio da će to učiniti raspoređivanje mojih stekova još hladnijim. Sada ga koristim svaki put kada implementiram svoj kod na lambda ili ECS koristeći cloudformation.

Kako to radi: Vi odredite CloudWatch alarm v parametar --rollback-configurationkada kreirate skup promjena. Kasnije, kada izvršite niz promjena, aws prati alarm najmanje jedan minut. Poništava primenu ako alarm promeni stanje u ALARM tokom ovog vremena.

Ispod je primjer izvoda šablona formiranje oblakau kojoj stvaram alarm za čuvanje oblaka, koji prati korisničku metriku u oblaku kao broj grešaka u dnevnicima oblaka (metrika se generira putem 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

Sada alarm može se koristiti kao povratak okidač prilikom izvršavanja toolboxa:

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"

Lekcija 5: Obavezno implementirajte najnoviju verziju predloška

Lako je implementirati manje od najnovije verzije predloška za formiranje oblaka, ali to će uzrokovati veliku štetu. Ovo nam se jednom dogodilo: programer nije ubacio najnovije izmjene iz Gita i nesvjesno je postavio prethodnu verziju steka. To je rezultiralo prekidom rada aplikacije koja je koristila ovaj stog.

Nešto tako jednostavno kao što je dodavanje provjere da se vidi da li je grana ažurirana prije nego što se preda na nju, bilo bi u redu (pod pretpostavkom da je git vaš alat za kontrolu verzija):

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

Lekcija 6: Ne izmišljajte točak

Može izgledati kao da se postavlja sa formiranje oblaka - to je lako. Treba vam samo hrpa bash skripti koje izvršavaju aws cli komande.

Prije 4 godine počeo sam s jednostavnim skriptama zvanim aws cloudformation create-stack komanda. Ubrzo scenario više nije bio jednostavan. Svaka naučena lekcija činila je scenario sve složenijim. Bilo je ne samo teško, već i puno grešaka.

Trenutno radim u malom IT odjelu. Iskustvo je pokazalo da svaki tim ima svoj način postavljanja oblaka za formiranje stokova. I to je loše. Bilo bi bolje da svi imaju isti pristup. Srećom, postoji mnogo dostupnih alata koji će vam pomoći da implementirate i konfigurirate oblake za formiranje oblaka.

Ove lekcije će vam pomoći da izbjegnete greške.

izvor: www.habr.com

Dodajte komentar