Saya mempelajari 6 pelajaran dalam bekerja dengan cloudformation selama sisa hidup saya.

Saya mulai bekerja dengan formasi awan 4 tahun yang lalu. Sejak itu saya telah merusak banyak infrastruktur, bahkan infrastruktur yang sudah berproduksi. Tapi setiap kali saya mengacaukan sesuatu, saya belajar sesuatu yang baru. Melalui pengalaman ini, saya akan membagikan beberapa pelajaran terpenting yang saya pelajari.

Saya mempelajari 6 pelajaran dalam bekerja dengan cloudformation selama sisa hidup saya.

Pelajaran 1: Uji perubahan sebelum menerapkannya

Saya mempelajari pelajaran ini segera setelah saya mulai bekerja dengannya formasi awan. Saya tidak ingat persis apa yang saya langgar saat itu, tetapi saya ingat pasti bahwa saya menggunakan perintah tersebut pembaruan cloudformation aws. Perintah ini hanya meluncurkan templat tanpa validasi apa pun terhadap perubahan yang akan diterapkan. Saya rasa tidak diperlukan penjelasan apa pun mengapa Anda harus menguji semua perubahan sebelum menerapkannya.

Setelah kegagalan ini, saya langsung berubah pipa penyebaran, mengganti perintah update dengan perintah buat-ubah-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"

Setelah set perubahan dibuat, perubahan tersebut tidak berpengaruh pada tumpukan yang ada. Berbeda dengan perintah update, pendekatan changeset tidak memicu penerapan sebenarnya. Sebaliknya, ini membuat daftar perubahan yang dapat Anda tinjau sebelum penerapan. Anda dapat melihat perubahan di antarmuka konsol aws. Namun jika Anda lebih suka mengotomatiskan semua yang Anda bisa, periksa di 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

Perintah ini akan menghasilkan keluaran seperti berikut:

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

Berikan perhatian khusus pada perubahan di mana Action berada menggantikan, Delete atau dimana Diperlukan Penggantian - Benar. Ini adalah perubahan yang paling berbahaya dan biasanya mengakibatkan hilangnya informasi.

Setelah perubahan ditinjau, perubahan dapat diterapkan

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"

Pelajaran 2: Gunakan kebijakan tumpukan untuk mencegah penggantian atau penghapusan sumber daya stateful

Terkadang sekadar melihat perubahan saja tidak cukup. Kita semua adalah manusia dan kita semua melakukan kesalahan. Tak lama setelah kami mulai menggunakan perubahan, rekan satu tim saya tanpa sadar melakukan penerapan yang menghasilkan pembaruan basis data. Tidak ada hal buruk yang terjadi karena ini adalah lingkungan pengujian.

Meskipun skrip kami menampilkan daftar perubahan dan meminta konfirmasi, perubahan Ganti dilewati karena daftar perubahan terlalu banyak sehingga tidak muat di layar. Dan karena ini adalah pembaruan normal dalam lingkungan pengujian, tidak banyak perhatian diberikan pada perubahan tersebut.

Ada sumber daya yang tidak ingin Anda ganti atau hapus. Ini adalah layanan statefull, seperti instance database RDS atau cluster elasticsearch, dll. Alangkah baiknya jika aws secara otomatis menolak penerapan jika operasi yang dilakukan memerlukan penghapusan sumber daya tersebut. Untungnya, cloudformation memiliki cara bawaan untuk melakukan hal ini. Ini disebut kebijakan tumpukan, dan Anda dapat membacanya lebih lanjut di dokumentasi:

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"

Pelajaran 3: Gunakan UsePreviousValue saat memperbarui tumpukan dengan parameter rahasia

Saat Anda membuat entitas mysql RDS, AWS mengharuskan Anda memberikan MasterUsername dan MasterUserPassword. Karena lebih baik tidak menyimpan rahasia dalam kode sumber dan saya ingin mengotomatiskan semuanya, saya menerapkan "mekanisme cerdas" di mana sebelum penerapan kredensial akan diperoleh dari s3, dan jika kredensial tidak ditemukan, kredensial baru akan dibuat dan disimpan di s3.

Kredensial ini kemudian akan diteruskan sebagai parameter ke perintah cloudformation create-change-set. Saat bereksperimen dengan skrip, kebetulan koneksi ke s3 terputus, dan β€œmekanisme pintar” saya memperlakukannya sebagai sinyal untuk menghasilkan kredensial baru.

Jika saya mulai menggunakan skrip ini dalam produksi dan masalah koneksi terjadi lagi, tumpukan akan diperbarui dengan kredensial baru. Dalam kasus khusus ini, tidak ada hal buruk yang akan terjadi. Namun, saya mengabaikan pendekatan ini dan mulai menggunakan pendekatan lain, memberikan kredensial hanya sekali - saat membuat tumpukan. Dan nanti, ketika tumpukan perlu diperbarui, alih-alih menentukan nilai rahasia parameter, saya cukup menggunakan UsePviousValue=benar:

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"

Pelajaran 4: Gunakan konfigurasi rollback

Tim lain tempat saya bekerja menggunakan fungsi tersebut formasi awanditelepon konfigurasi kembalikan. Saya belum pernah menemukannya sebelumnya dan segera menyadari bahwa ini akan membuat penerapan tumpukan saya menjadi lebih keren. Sekarang saya menggunakannya setiap kali saya menerapkan kode saya ke lambda atau ECS menggunakan cloudformation.

Cara kerjanya: Anda tentukan Alarm CloudWatch dalam parameter --konfigurasi kembalikansaat Anda membuat set perubahan. Nanti, ketika Anda menjalankan serangkaian perubahan, aws memonitor alarm setidaknya selama satu menit. Ini mengembalikan penerapan jika alarm berubah status menjadi ALARM selama waktu ini.

Di bawah ini adalah contoh kutipan template formasi awandi mana saya membuat alarm jam awan, yang melacak metrik pengguna cloud sebagai jumlah kesalahan dalam log cloud (metrik dihasilkan melalui Filter Metrik):

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

Sekarang alarm dapat digunakan sebagai rollback pemicu saat menjalankan kotak alat:

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"

Pelajaran 5: Pastikan Anda menerapkan templat versi terbaru

Sangat mudah untuk menerapkan versi templat cloudformation yang kurang terbaru, namun hal ini akan menyebabkan banyak kerusakan. Hal ini pernah terjadi pada kami: pengembang tidak menerapkan perubahan terbaru dari Git dan tanpa sadar menerapkan versi tumpukan sebelumnya. Hal ini mengakibatkan downtime pada aplikasi yang menggunakan tumpukan ini.

Sesuatu yang sederhana seperti menambahkan tanda centang untuk melihat apakah cabang tersebut mutakhir sebelum melakukan komitmen akan baik-baik saja (dengan asumsi git adalah alat kontrol versi Anda):

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

Pelajaran 6: Jangan menemukan kembali roda

Ini mungkin tampak seperti penerapan dengan formasi awan - mudah. Anda hanya perlu sekumpulan skrip bash yang menjalankan perintah aws cli.

4 tahun yang lalu saya memulai dengan skrip sederhana yang disebut perintah aws cloudformation create-stack. Segera naskahnya tidak lagi sederhana. Setiap pelajaran yang didapat membuat naskah menjadi semakin kompleks. Tidak hanya sulit, tetapi juga penuh dengan bug.

Saat ini saya bekerja di departemen TI kecil. Pengalaman menunjukkan bahwa setiap tim memiliki caranya sendiri dalam menerapkan tumpukan cloudformation. Dan itu buruk. Akan lebih baik jika semua orang mengambil pendekatan yang sama. Untungnya, ada banyak alat yang tersedia untuk membantu Anda menyebarkan dan mengonfigurasi tumpukan cloudformation.

Pelajaran ini akan membantu Anda menghindari kesalahan.

Sumber: www.habr.com

Tambah komentar