لقد بدأت العمل مع
cloudformation قبل 4 سنوات. منذ ذلك الحين ، لقد كسرت العديد من البنى التحتية ، حتى تلك التي كانت بالفعل في الإنتاج. لكن في كل مرة أفسد فيها شيئًا ما ، تعلمت أشياء جديدة. بفضل هذه التجربة ، سأشارك بعض أهم الدروس التي تعلمتها.

الدرس 1: التحقق من صحة التغييرات قبل النشر
لقد تعلمت هذا الدرس بمجرد أن بدأت العمل مع
السحابة . لا أتذكر بالضبط ما الذي
كسرته في ذلك الوقت ، لكنني أتذكر تمامًا أنني استخدمت
أمر تحديث cloud cloud aws . يقوم هذا الأمر ببساطة بطرح القالب دون أي تحقق من التغييرات التي سيتم نشرها. لا أعتقد أن هناك حاجة إلى توضيحات ، والتي تحتاج إلى التحقق من جميع التغييرات قبل نشرها.
بعد هذا الفشل ، قمت على الفور بتغيير
خط أنابيب النشر ، واستبدال أمر التحديث بأمر
create-change-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"
عند إنشاء مجموعة تغيير ، لن يؤثر ذلك على المكدس الحالي. على عكس أمر التحديث ، لا يتم نشر نهج مجموعة التغيير بالفعل. بدلاً من ذلك ، ينشئ قائمة بالتغييرات التي يمكنك مراجعتها قبل النشر. يمكنك عرض التغييرات في واجهة وحدة التحكم 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 | +---------+--------------------+----------------------+------------+
انتبه بشكل خاص إلى التغييرات التي يكون فيها الإجراء "
استبدال" أو "
حذف" أو حيث يكون "
eedNeeded "صحيحًا . هذه هي أخطر التغييرات وعادة ما تؤدي إلى فقدان المعلومات.
عندما يتم عرض التغييرات ، يمكن توسيعها
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 أو مجموعة elastichsearch ، وما إلى ذلك. سيكون من الجيد أن يرفض aws النشر تلقائيًا ، إذا كانت العملية التي يتم تنفيذها تتطلب إزالة مثل هذا المورد. لحسن الحظ ، لدى cloudform طريقة مضمّنة للقيام بذلك. وهذا ما يسمى سياسة المكدس ، ويمكنك قراءة المزيد حول هذا في
الوثائق :
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: استخدم Use PreviousValue عند تحديث مكدس مع المعلمات السرية
عندما تقوم بإنشاء كيان RDS ، فإن mysql AWS يتطلب منك تقديم MasterUsername و MasterUserPassword. نظرًا لأنه من الأفضل عدم الاحتفاظ بالأسرار في الكود المصدري ، وأردت تشغيل كل شيء تلقائيًا ، فقد طبقت "آلية ذكية" يتم فيها الحصول على بيانات الاعتماد من s3 قبل النشر ، وإذا لم يتم العثور على بيانات الاعتماد ، يتم إنشاء بيانات اعتماد جديدة وتخزينها في s3 .
بعد ذلك سيتم تمرير بيانات الاعتماد هذه كمعلمات لأمر cloudformation create-change-set. أثناء التجارب على البرنامج النصي ، حدث ضياع الاتصال بـ s3 ، واعتبرته "آليتي الذكية" إشارة إلى توليد بيانات اعتماد جديدة.
إذا بدأت في استخدام هذا البرنامج النصي في بيئة إنتاج ونشأت مشكلة الاتصال مرة أخرى ، فسيؤدي ذلك إلى تحديث المكدس بأوراق اعتماد جديدة. في هذه الحالة بالذات ، لن يحدث شيء سيء. ومع ذلك ، فقد تخلت عن هذا النهج وبدأت في استخدام طريقة أخرى ، وتوفير بيانات الاعتماد مرة واحدة فقط - عند إنشاء مجموعة العناصر. وبعد ذلك ، عندما يتطلب الأمر مكدس التحديث ، بدلاً من تحديد القيمة السرية للمعلمة ، أود ببساطة استخدام
Use PreviousValue = 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: استخدام التكوين التراجع
كان هناك فريق آخر عملت معه باستخدام وظيفة
cloudform تسمى
تكوين التراجع . لم أقابلها من قبل وأدركت بسرعة أن هذا من شأنه أن يجعل نشر مكدساتي أفضل. الآن يمكنني استخدام كل مرة أقوم بنشر الرمز الخاص بي في lambda أو ECS باستخدام cloudform.
كيف يعمل: يمكنك تحديد
المنبه CloudWatch في
المعلمة - إعادة تكوين التكوين عند إنشاء مجموعة التغيير. في وقت لاحق ، عند إكمال مجموعة التغيير ، يتعقب aws المنبه لمدة دقيقة واحدة على الأقل. يتم استرجاع النشر إذا تغير التنبيه حالة خلال هذا الوقت إلى ALARM.
فيما يلي مثال على
مقتطفات من قالب
السحابة التي أقوم بإنشاء
منبه للساعة السحابية يتتبع مقياس سحابة المستخدم كعدد الأخطاء في سجلات السحابة (يتم إنشاء المقياس عبر
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
الآن يمكن استخدام
المنبه كمشغل للتراجع عند تنفيذ مجموعة من الأدوات:
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: تأكد من نشر أحدث نسخة من القالب
ليس من السهل نشر أحدث إصدار من قالب السحابة ، لكنه سيتسبب في الكثير من الضرر. بمجرد أن يكون معنا: لم يرسل المطور آخر التغييرات من 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: لا تعيد اختراع العجلة
قد يكون
النشر باستخدام
السحابة سهلاً. تحتاج فقط إلى مجموعة من البرامج النصية للباش التي تنفذ أوامر aws cli.
منذ 4 سنوات ، بدأت ببرامج نصية بسيطة تسمى الأمر aws cloudform create-stack. قريباً ، لم يعد النص بسيطًا. كل درس تعلّم جعل النص أكثر تعقيدًا. لم يكن الأمر صعبًا فحسب ، ولكن أيضًا مع مجموعة من الأخطاء.
الآن أنا أعمل في قسم تكنولوجيا المعلومات صغير. لقد أظهرت التجربة أن لكل فريق طريقته الخاصة في نشر أكوام السحابة. وهذا سيء. سيكون من الأفضل لو استخدم الجميع منهجًا واحدًا. لحسن الحظ ، هناك العديد من الأدوات التي تساعدك على نشر وتكوين مكدسات السحاب.
هذه الدروس سوف تساعدك على تجنب الأخطاء.