من این 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 در آن قرار دارد توجه ویژه ای داشته باشید جایگزین کردن, حذف یا کجا Replacement Needed - درست است. اینها خطرناک ترین تغییرات هستند و معمولاً منجر به از دست رفتن اطلاعات می شوند.

پس از بررسی تغییرات، می توان آنها را مستقر کرد

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: از خط مشی پشته برای جلوگیری از جایگزینی یا حذف منابع حالت دار استفاده کنید

گاهی اوقات مشاهده تغییرات کافی نیست. همه ما انسان هستیم و همه اشتباه می کنیم. مدت کوتاهی پس از اینکه ما شروع به استفاده از تغییرات ست کردیم، هم تیمی من ناآگاهانه یک استقرار را انجام داد که منجر به به روز رسانی پایگاه داده شد. هیچ اتفاق بدی نیفتاد زیرا یک محیط آزمایشی بود.

حتی با وجود اینکه اسکریپت های ما لیستی از تغییرات را نمایش می دادند و درخواست تایید می کردند، تغییر Replace نادیده گرفته شد زیرا لیست تغییرات به قدری بزرگ بود که روی صفحه قرار نمی گرفت. و از آنجایی که این یک به روز رسانی معمولی در یک محیط آزمایشی بود، توجه زیادی به تغییرات صورت نگرفت.

منابعی هستند که هرگز نمی خواهید جایگزین یا حذف کنید. اینها سرویس‌های دولتی هستند، مانند یک نمونه پایگاه داده 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 create-change-set ارسال می شود. در حین آزمایش با اسکریپت، این اتفاق افتاد که اتصال به 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: از تنظیمات برگشتی استفاده کنید

تیم دیگری که با آن کار کردم از این تابع استفاده کرد شکل گیری ابر، تماس گرفت پیکربندی برگشت. من قبلاً با آن برخورد نکرده بودم و به سرعت متوجه شدم که استقرار پشته های من را حتی سردتر می کند. اکنون هر بار که کدم را با استفاده از cloudformation روی لامبدا یا ECS قرار می دهم از آن استفاده می کنم.

چگونه کار می کند: شما مشخص می کنید زنگ ساعت CloudWatch در پارامتر -پیکربندی برگشتیهنگامی که یک تغییرات ایجاد می کنید. بعداً، وقتی مجموعه‌ای از تغییرات را اجرا می‌کنید، aws زنگ هشدار را حداقل برای یک دقیقه نظارت می‌کند. اگر در این مدت زنگ حالت به ALARM تغییر کند، استقرار را به عقب برمی گرداند.

در زیر نمونه ای از گزیده الگو آورده شده است شکل گیری ابرکه در آن ایجاد می کنم زنگ ساعت ابری، که یک متریک کاربر ابری را به عنوان تعداد خطاها در گزارش های ابری ردیابی می کند (متریک از طریق ایجاد می شود فیلتر متریک):

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: چرخ را دوباره اختراع نکنید

ممکن است شبیه به استقرار با شکل گیری ابر - آسان است. شما فقط به یک سری اسکریپت bash نیاز دارید که دستورات aws cli را اجرا کنند.

4 سال پیش من با اسکریپت های ساده ای به نام دستور aws cloudformation create-stack شروع کردم. به زودی فیلمنامه دیگر ساده نبود. هر درس آموخته شده، فیلمنامه را پیچیده تر و بیشتر می کرد. نه تنها سخت بود، بلکه پر از اشکال بود.

من در حال حاضر در یک بخش کوچک فناوری اطلاعات کار می کنم. تجربه نشان داده است که هر تیم روش خاص خود را برای استقرار پشته‌های ابرفرمینگ دارد. و این بد است. اگر همه همین رویکرد را داشته باشند بهتر است. خوشبختانه، ابزارهای زیادی برای کمک به استقرار و پیکربندی پشته های cloudformation در دسترس هستند.

این درس ها به شما کمک می کند تا از اشتباهات جلوگیری کنید.

منبع: www.habr.com

اضافه کردن نظر