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.
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
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