Skip to content

فصل ۲۱ — تغییر امن زیرساخت

موضوع دادن تغییرات مکرر و سریع در سراسر این کتاب جریان دارد. همان‌طور که در همان ابتدا ذکر شد («اعتراض: «باید بین سرعت و کیفیت انتخاب کنیم»» در صفحه ۷)، دور از اینکه سیستم‌ها را unstable کند، سرعت enabler پایداری است و بالعکس. شعار «move fast and break things» نیست، بلکه «move fast and improve things» است.

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

همه آنچه این کتاب توصیه می‌کند — از استفاده از کد برای ساخت زیرساخت به‌طور سازگار، تا تست به‌عنوان بخش مداوم کار، تا شکستن سیستم‌ها به قطعات کوچک‌تر — تغییرات سریع، مکرر و امن را enable می‌کند.

اما دادن تغییرات مکرر به زیرساخت چالش‌هایی برای تحویل سرویس‌های بدون وقفه ایجاد می‌کند. این فصل این چالش‌ها و تکنیک‌های برخورد با آن‌ها را بررسی می‌کند. ذهنیتی که این تکنیک‌ها را underpin می‌کند این نیست که تغییرات را تهدیدی برای پایداری و تداوم ببینیم، بلکه ماهیت پویا زیرساخت مدرن را exploit کنیم. اصول، practiceها و تکنیک‌های توصیف‌شده در سراسر این کتاب را exploit کنید تا اختلال از تغییرات را به حداقل برسانید.

کاهش دامنه تغییر

رویکردهای Agile، XP، Lean و مشابه سرعت و قابلیت اطمینان تحویل را با دادن تغییرات در افزایش‌های کوچک بهینه می‌کنند. برنامه‌ریزی، پیاده‌سازی، تست و debug تغییر کوچک آسان‌تر از تغییر بزرگ است، پس batch size را کاهش می‌دهیم.¹ البته اغلب نیاز به تغییرات قابل توجه در سیستم‌هایمان داریم، اما می‌توانیم این کار را با شکستن به مجموعه کوچکی از تغییرات که یکی‌یکی تحویل می‌دهیم انجام دهیم.

به‌عنوان مثال، تیم ShopSpinner در ابتدا زیرساختش را با یک stack زیرساخت واحد ساخت. stack شامل cluster وب‌سرور و application server بود. با گذشت زمان، اعضا application serverهای بیشتری اضافه کردند و بعضی را به cluster تبدیل کردند. فهمیدند اجرای cluster وب‌سرور و همه application serverها در یک VLAN طراحی ضعیفی است، پس طراحی شبکه را بهبود دادند و این عناصر را به VLANهای مختلف منتقل کردند. همچنین تصمیم گرفتند از توصیه این کتاب پیروی کنند و زیرساخت را به چند stack تقسیم کنند تا تغییر جداگانه آسان‌تر شود.

پیاده‌سازی اولیه ShopSpinner یک stack واحد با یک VLAN بود (شکل ۲۱-۱ را ببینید).

شکل ۲۱-۱. نمونه پیاده‌سازی شروع، stack واحد، VLAN واحد

تیم برنامه دارد stack را به چند stack تقسیم کند. این‌ها شامل shared-networking-stack و application-infrastructure-stack از مثال‌های فصل‌های قبل است. برنامه همچنین web-cluster-stack برای مدیریت cluster کانتینر frontend وب‌سرورها و application-database-stack برای مدیریت نمونه پایگاه داده هر برنامه را شامل می‌شود (شکل ۲۱-۲).

¹ Donald G. Reinertsen مفهوم کاهش batch size را در کتاب The Principles of Product Development Flow (Celeritas Publishing) توصیف می‌کند.

شکل ۲۱-۲. برنامه تقسیم به چند stack

تیم همچنین VLAN واحد را به چند VLAN تقسیم می‌کند. application serverها در این VLANها برای redundancy پخش می‌شوند (شکل ۲۱-۳ را ببینید).

شکل ۲۱-۳. برنامه ایجاد چند VLAN

فصل ۱۷ انتخاب‌های طراحی و بعضی الگوهای پیاده‌سازی برای تقسیم این stackهای نمونه را توصیف کرد. حالا می‌توانیم راه‌های انتقال از یک پیاده‌سازی به دیگری در سیستم production را بررسی کنیم.

تغییرات کوچک

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

خوشبختانه دنیای توسعه نرم‌افزار مسیر را نشان داده. بسیاری از تکنیک‌هایی که ساخت سیستم‌ها را تکه‌تکه پشتیبانی می‌کنند در سراسر این کتاب گنجانده شده، از جمله TDD، CI و CD. تست و تحویل تدریجی تغییرات کد با pipeline، همان‌طور که در فصل ۸ توضیح داده و در سراسر کتاب ارجاع شده، enabler است. باید بتوانید تغییر کوچکی در کد بدهید، push کنید، بازخورد بگیرید که کار می‌کند یا نه، و آن را به production ببرید.

تیم‌هایی که این تکنیک‌ها را مؤثر استفاده می‌کنند تغییرات را بسیار مکرر push می‌کنند. یک مهندس ممکن است هر ساعت یا حدود آن تغییر push کند و هر تغییر در codebase اصلی یکپارچه و برای آمادگی production در سیستم کاملاً یکپارچه تست می‌شود.

افراد اصطلاحات و تکنیک‌های مختلفی برای دادن تغییر قابل توجه به‌عنوان مجموعه‌ای از تغییرات کوچک مطرح می‌کنند:

Incremental (افزایشی) تغییر افزایشی یکی از قطعات پیاده‌سازی برنامه‌شده را اضافه می‌کند. می‌توانید سیستم ShopSpinner نمونه را به‌صورت افزایشی با پیاده‌سازی یک stack در هر زمان بسازید. اول stack شبکه مشترک را ایجاد کنید. سپس stack cluster وب را اضافه کنید. در نهایت stack زیرساخت برنامه را بسازید.

Iterative (تکراری) تغییر تکراری بهبود تدریجی در سیستم می‌دهد. ساخت سیستم ShopSpinner را با ایجاد نسخه پایه همه سه stack شروع کنید. سپس مجموعه‌ای از تغییرات بدهید که هر کدام قابلیت stackها را گسترش می‌دهد.

Walking skeleton walking skeleton پیاده‌سازی پایه بخش‌های اصلی سیستم جدید است که برای کمک به validate طراحی و ساختار کلی پیاده‌سازی می‌کنید.² اغلب walking skeleton برای پروژه زیرساخت همراه با پیاده‌سازی‌های اولیه مشابه برنامه‌هایی که روی آن اجرا می‌شوند ایجاد می‌شود تا تیم‌ها ببینند تحویل، deployment و عملیات چگونه ممکن است کار کند. پیاده‌سازی اولیه و انتخاب ابزارها و سرویس‌ها برای skeleton اغلب همان‌هایی نیست که برای بلندمدت برنامه‌ریزی شده. مثلاً ممکن است راه‌حل مانیتورینگ full-featured برنامه‌ریزی کنید، اما walking skeleton را با سرویس‌های پایه‌تر out of the box ارائه‌شده توسط cloud provider بسازید.

² Growing Object-Oriented Software, Guided by Tests اثر Steve Freeman و Nat Pryce (Addison-Wesley) فصلی به walking skeleton اختصاص دارد.

Refactoring (بازآرایی) refactoring شامل تغییر طراحی سیستم یا جزئی از سیستم بدون تغییر رفتار آن است. refactoring اغلب برای هموار کردن راه تغییراتی که رفتار را تغییر می‌دهند انجام می‌شود.³ refactoring ممکن است وضوح کد را بهبود دهد تا تغییر آسان‌تر شود، یا کد را reorganize کند تا با تغییرات برنامه‌ریزی‌شده هم‌راستا شود.

³ Kent Beck workflowهایی برای «تغییرات بزرگ در گام‌های کوچک و امن» در مقاله «SB Changes» توصیف می‌کند. این شامل مجموعه‌ای از تغییرات است، بعضی کد را برای آماده‌سازی تغییر رفتاری مرتب می‌کنند، دیگران تغییرات رفتاری می‌دهند. نکته کلیدی این است که هر تغییر یکی از این دو کار را انجام می‌دهد، هرگز هر دو.

نمونه Refactoring

تیم ShopSpinner تصمیم می‌گیرد stack فعلی را به چند stack و نمونه stack decompose کند. پیاده‌سازی برنامه‌شده شامل یک نمونه stack برای cluster کانتینری که وب‌سرورها را host می‌کند و دیگری برای ساختارهای شبکه مشترک است. تیم همچنین جفت stack برای هر سرویس خواهد داشت، یکی برای application server و شبکه مرتبط و یکی برای نمونه پایگاه داده آن سرویس (شکل ۲۱-۴ را ببینید).

شکل ۲۱-۴. برنامه decompose کردن stack

اعضای تیم همچنین می‌خواهند محصول cluster کانتینر را جایگزین کنند و از cluster Kubernetes که خودشان روی ماشین‌های مجازی deploy می‌کنند به Containers as a Service ارائه‌شده توسط cloud vendor بروند (به «راه‌حل‌های Application Cluster» در صفحه ۲۳۰ مراجعه کنید).

تیم تصمیم می‌گیرد معماری decompose‌شده را به‌صورت افزایشی پیاده‌سازی کند. اولین گام استخراج cluster کانتینر به stack خودش و سپس جایگزینی محصول کانتینر درون stack است (شکل ۲۱-۵).

شکل ۲۱-۵. برنامه استخراج و جایگزینی cluster کانتینر

این برنامه نمونه استفاده از refactoring برای enable کردن تغییر است. تغییر راه‌حل cluster کانتینر وقتی در stack خودش isolated باشد آسان‌تر از وقتی بخشی از stack بزرگ‌تر با زیرساخت دیگر است. وقتی اعضا cluster را به stack خودش استخراج می‌کنند، می‌توانند نقاط یکپارچه‌سازی با بقیه سیستم را تعریف کنند. تست‌ها و validationهای دیگری می‌نویسند که جداسازی و یکپارچه‌سازی را تمیز نگه می‌دارند. این به تیم اطمینان می‌دهد می‌تواند محتوای stack کانتینر را با امنیت تغییر دهد.

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

Push کردن تغییرات ناقص به Production

چگونه می‌توانید تغییر قابل توجهی به سیستم production را به‌عنوان مجموعه‌ای از تغییرات کوچک افزایشی تحویل دهید در حالی که سرویس کار می‌کند؟ بعضی از آن تغییرات کوچک ممکن است به‌تنهایی مفید نباشند. ممکن است عملی نباشد قابلیت موجود را حذف کنید تا کل مجموعه تغییرات کامل شود.

«نمونه Refactoring» در صفحه ۳۵۹ دو گام افزایشی نشان داد: استخراج cluster کانتینر از یک stack به stack خودش و سپس جایگزینی راه‌حل cluster در stack جدید. هر کدام از این گام‌ها بزرگ است، پس احتمالاً به‌عنوان مجموعه‌ای از pushهای کد کوچک‌تر پیاده‌سازی می‌شوند.

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

نمونه‌های موازی (Parallel Instances)

گام دوم مثال جایگزینی cluster با راه‌حل کانتینر اصلی در stack خودش شروع می‌شود و با راه‌حل کانتینر جدید تمام می‌شود (شکل ۲۱-۶ را ببینید).

شکل ۲۱-۶. جایگزینی راه‌حل cluster

راه‌حل موجود توزیع Kubernetes بسته‌بندی‌شده به نام KubeCan است.⁴ تیم به FKS، سرویس cluster مدیریت‌شده ارائه‌شده توسط پلتفرم ابری، سوئیچ می‌کند.⁵ برای اطلاعات بیشتر درباره cluster as a service و توزیع cluster بسته‌بندی‌شده به «راه‌حل‌های Application Cluster» در صفحه ۲۳۰ مراجعه کنید.

⁴ KubeCan یکی دیگر از محصولات خیالی است که تیم خیالی ShopSpinner ترجیح می‌دهد.

⁵ FKS مخفف Fictional Kubernetes Service است.

عملی نیست cluster KubeCan را در گام‌های کوچک به cluster FKS تبدیل کنید. اما تیم می‌تواند دو cluster را به‌صورت موازی اجرا کند. چند روش مختلف برای اجرای دو stack کانتینر متفاوت به‌صورت موازی با یک نمونه stack اصلی وجود دارد.

یک گزینه پارامتری برای stack اصلی است که انتخاب کند با کدام stack کانتینر یکپارچه شود (شکل ۲۱-۷ را ببینید).

شکل ۲۱-۷. یک stack فعال است و یکی غیرفعال

با این گزینه، یکی از stackها فعال است و workload زنده را handle می‌کند. stack دوم غیرفعال است اما همچنان موجود است. تیم می‌تواند stack دوم را در محیط کاملاً عملیاتی تست کند، pipeline تحویل و test suite آن را exercise و توسعه دهد و آن را با بخش‌های دیگر زیرساخت در هر محیط یکپارچه کند.

چرا اصلاً راه‌حل کانتینر قدیمی را استخراج کنیم؟ با توجه به اینکه در نهایت stack مستقل با راه‌حل کانتینر جدید ساخته‌ایم، شاید بتوان گفت می‌توانستیم گام استخراج راه‌حل قدیمی به stack خودش را رد کنیم. می‌توانستیم stack جدید را با راه‌حل جدید از صفر بسازیم. با استخراج راه‌حل قدیمی، اطمینان از تطابق رفتار راه‌حل جدید با راه‌حل قدیمی آسان‌تر است. stack استخراج‌شده به‌وضوح نحوه یکپارچه‌سازی cluster با زیرساخت دیگر را تعریف می‌کند. با استفاده از stack استخراج‌شده در production، تضمین می‌کنیم نقاط یکپارچه‌سازی درست هستند. افزودن تست‌های خودکار و pipeline جدید برای stack استخراج‌شده تضمین می‌کند فوراً وقتی یکی از تغییراتمان چیزی را می‌شکند می‌فهمیم. اگر راه‌حل cluster قدیمی را در stack اصلی بگذاریم و جدید را جداگانه بسازیم، جایگزینی آن disruptive خواهد بود. تا انتها نمی‌دانیم تصمیم طراحی یا پیاده‌سازی ناسازگار داده‌ایم یا نه. زمان زیادی برای یکپارچه‌سازی stack جدید با بخش‌های دیگر زیرساخت و تست، debug و رفع مشکلات لازم است.

گزینه دیگر یکپارچه‌سازی هر دو stack با stack اصلی است (شکل ۲۱-۸ را ببینید).

شکل ۲۱-۸. هر پیاده‌سازی cluster در نمونه stack خودش اجرا می‌شود

با این ترتیب، می‌توانید بخشی از workload را به هر stack کانتینر هدایت کنید. می‌توانید workload را به روش‌های مختلف تقسیم کنید:

Workload percentage (درصد workload) بخشی از workload را به هر stack هدایت کنید. معمولاً stack قدیمی در ابتدا بیشتر بار را handle می‌کند و stack جدید درصد کوچکی برای ارزیابی عملکرد می‌گیرد. وقتی stack جدید جا افتاد، می‌توانید بار را با گذشت زمان بالا ببرید. بعد از اینکه stack جدید با موفقیت ۱۰۰٪ بار را مدیریت کرد و همه آماده‌اند، stack قدیمی را decommission کنید. این گزینه فرض می‌کند stack جدید همه قابلیت‌های stack قدیمی را دارد و مشکلی با داده یا messaging تقسیم‌شده بین stackها نیست.

Service migration (مهاجرت سرویس) سرویس‌ها را یکی‌یکی به cluster جدید migrate کنید. workloadها در stack اصلی، مانند اتصالات شبکه یا پیام‌ها، به هر نمونه stack که سرویس مربوط روی آن اجرا می‌شود هدایت می‌شوند. این گزینه به‌ویژه وقتی مفید است که باید برنامه‌های سرویس را برای انتقال به stack جدید تغییر دهید. اغلب یکپارچه‌سازی پیچیده‌تری می‌خواهد، شاید حتی بین stackهای cluster قدیم و جدید. این پیچیدگی برای migrate کردن portfolio سرویس پیچیده ممکن است توجیه شود.⁶

User partitioning (تقسیم‌بندی کاربر) در بعضی موارد، مجموعه‌های مختلف کاربران به پیاده‌سازی‌های مختلف stack هدایت می‌شوند. testerها و کاربران داخلی اغلب گروه اول هستند. می‌توانند تست‌های اکتشافی انجام دهند و سیستم جدید را قبل از ریسک دادن به مشتریان «واقعی» exercise کنند. در بعضی موارد ممکن است بعد از آن به مشتریانی که opt-in به alpha testing یا preview service کرده‌اند دسترسی بدهید. این موارد وقتی بیشتر معنا دارند که سرویس روی stack جدید تغییراتی دارد که کاربران متوجه می‌شوند.

اجرای شرطی یا موازی بخش‌های جدید و قدیمی سیستم نوعی branch by abstraction است. انتقال تدریجی بخش‌هایی از workload به بخش‌های جدید سیستم canary release است. dark launching توصیف می‌کند قابلیت جدید سیستم را به production بیاورید اما به workloadهای production expose نکنید تا تیم بتواند تست کند.

⁶ این نوع سناریوی migrate پیچیده با برنامه‌های یکپارچه در دو cluster hosting هنگام migrate کردن estate بزرگ برنامه‌های مبتنی بر سرور host‌شده در data center به پلتفرم hosting ابری رایج است.

تبدیل‌های Backward Compatible

در حالی که بعضی تغییرات ممکن است نیاز به ساخت و اجرای جزء جدید به‌صورت موازی با قدیمی تا کامل شدن داشته باشند، می‌توانید بسیاری تغییرات را درون جزء بدون تأثیر روی کاربران یا consumerها بدهید.

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

مثلاً تیم ShopSpinner برنامه دارد shared-networking-stack را از یک VLAN به سه VLAN تغییر دهد (شکل ۲۱-۹).

شکل ۲۱-۹. تغییر از VLAN واحد به سه VLAN

stackهای consumer، از جمله application-infrastructure-stack، با VLAN واحد مدیریت‌شده توسط stack شبکه با یکی از روش‌های discovery توصیف‌شده در «کشف وابستگی‌ها بین Stackها» در صفحه ۲۸۷ یکپارچه می‌شوند. کد shared-networking-stack شناسه VLAN را برای stackهای consumer برای discovery export می‌کند:

yaml
vlans:
  - main_vlan
    address_range: 10.2.0.0/8

export:
  - main_vlan: main_vlan.id

نسخه جدید shared-networking-stack سه VLAN ایجاد و شناسه‌هایشان را با نام‌های جدید export می‌کند. همچنین یکی از شناسه‌های VLAN را با شناسه قدیمی export می‌کند:

yaml
vlans:
  - appserver_vlan_A
       address_range: 10.1.0.0/16
  - appserver_vlan_B
       address_range: 10.2.0.0/16
  - appserver_vlan_C
       address_range: 10.3.0.0/16

export:
  - appserver_vlan_A: appserver_vlan_A.id
  - appserver_vlan_B: appserver_vlan_B.id
  - appserver_vlan_C: appserver_vlan_C.id
  # Deprecated
  - main_vlan: appserver_vlan_A.id

با نگه داشتن شناسه قدیمی، stack شبکه اصلاح‌شده همچنان برای کد زیرساخت consumer کار می‌کند. کد consumer باید برای استفاده از شناسه‌های جدید اصلاح شود و وقتی همه وابستگی‌ها به شناسه قدیمی رفت، می‌توان آن را از کد stack شبکه حذف کرد.

Feature Toggleها

وقتی تغییری در جزء می‌دهید، اغلب باید تا پایان تغییر از پیاده‌سازی موجود استفاده کنید. بعضی افراد کد را در source control branch می‌کنند و روی تغییر جدید در یک branch کار می‌کنند و branch قدیمی را در production استفاده می‌کنند. مشکلات این رویکرد شامل موارد زیر است:

  • کار اضافی برای اطمینان از merge تغییرات در حوزه‌های دیگر جزء، مانند bugfixها، به هر دو branch لازم است.
  • تلاش و منابع برای اطمینان از تست و deploy مداوم هر دو branch لازم است. در غیر این صورت، کار در یک branch با تست کم‌سخت‌گیرانه‌تر پیش می‌رود و احتمال خطا و rework بعدی بیشتر می‌شود.
  • وقتی تغییر آماده است، جابه‌جایی نمونه‌های production عملیات بیشتر «big bang» با ریسک شکست بالاتر است.

مؤثرتر است روی تغییرات در codebase اصلی بدون branching کار کنید. می‌توانید از feature toggle برای سوئیچ پیاده‌سازی کد برای محیط‌های مختلف استفاده کنید. در بعضی محیط‌ها به کد جدید سوئیچ کنید تا کار را تست کنید و برای محیط‌های production-line به کد موجود سوئیچ کنید. از پارامتر پیکربندی stack (همان‌طور که در فصل ۷ توضیح داده شد) برای مشخص کردن کدام بخش کد روی نمونه مشخص اعمال شود استفاده کنید.

وقتی تیم ShopSpinner VLANها را به shared-networking-stack اضافه کرد، همان‌طور که قبلاً توضیح داده شد، باید application-infrastructure-stack را برای استفاده از VLANهای جدید تغییر دهد. اعضا کشف می‌کنند این تغییر به‌اندازه اول فکر نمی‌کردند ساده نیست.

stack برنامه مسیرهای شبکه مختص برنامه، VIPهای load balancer و قوانین firewall را تعریف می‌کند. وقتی application serverها در چند VLAN به‌جای یک VLAN host می‌شوند پیچیده‌تر است.

چند روز طول می‌کشد تا اعضا کد و تست‌ها را برای این تغییر پیاده‌سازی کنند. به‌اندازه کافی طولانی نیست که احساس کنند stack جداگانه setup کنند، همان‌طور که در «نمونه‌های موازی» در صفحه ۳۶۱ توضیح داده شد. اما مشتاق‌اند تغییرات افزایشی را هنگام کار به repository push کنند تا بازخورد مداوم از تست‌ها، از جمله تست‌های یکپارچه‌سازی سیستم، بگیرند.

تیم تصمیم می‌گیرد پارامتر پیکربندی به application-infrastructure-stack اضافه کند که بسته به اینکه باید از VLAN واحد یا چند VLAN استفاده کند، بخش‌های مختلف کد stack را انتخاب می‌کند.

این قطعه از کد منبع stack از سه متغیر — appserver_A_vlan، appserver_B_vlan و appserver_C_vlan — برای مشخص کردن VLAN اختصاص‌یافته به هر application server استفاده می‌کند. مقدار هر کدام بسته به مقدار پارامتر feature toggle، toggle_use_multiple_vlans، متفاوت تنظیم می‌شود:

yaml
input_parameters:
  name: toggle_use_multiple_vlans
  default: false

variables:
  - name: appserver_A_vlan
    value:
      $IF(${toggle_use_multiple_vlans} appserver_vlan_A ELSE main_vlan)
  - name: appserver_B_vlan
    value:
      $IF(${toggle_use_multiple_vlans} appserver_vlan_B ELSE main_vlan)
  - name: appserver_C_vlan
    value:
      $IF(${toggle_use_multiple_vlans} appserver_vlan_C ELSE main_vlan)

virtual_machine:
  name: appserver-${SERVICE}-A
  memory: 4GB
  address_block: ${appserver_A_vlan}

virtual_machine:
  name: appserver-${SERVICE}-B
  memory: 4GB
  address_block: ${appserver_B_vlan}

virtual_machine:
  name: appserver-${SERVICE}-C
  memory: 4GB
  address_block: ${appserver_C_vlan}

اگر toggle toggle_use_multiple_vlans روی false تنظیم شود، پارامترهای appserver_X_vlan همه برای استفاده از شناسه VLAN قدیمی main_vlan تنظیم می‌شوند. اگر toggle true باشد، هر متغیر به یکی از شناسه‌های VLAN جدید تنظیم می‌شود.

همان پارامتر toggle در بخش‌های دیگر کد stack استفاده می‌شود، جایی که تیم روی پیکربندی routing و عناصر tricky دیگر کار می‌کند.

توصیه درباره Feature Toggleها «Feature Toggles (aka Feature Flags)» اثر Pete Hodgson را برای توصیه درباره استفاده از feature toggle و نمونه‌ها از کد نرم‌افزار ببینید. چند توصیه اضافه دارم. اولاً، تعداد feature toggleهایی که استفاده می‌کنید را به حداقل برسانید. feature toggleها و شرط‌ها کد را شلوغ می‌کنند و فهمیدن، نگهداری و debug را سخت می‌کنند. آن‌ها را کوتاه‌عمر نگه دارید. وابستگی‌ها به پیاده‌سازی قدیمی را هرچه زودتر حذف کنید و toggleها و کد شرطی را بردارید. هر feature toggle که بیش از چند هفته بماند احتمالاً پارامتر پیکربندی است. feature toggleها را بر اساس کاری که انجام می‌دهند نام‌گذاری کنید. از نام‌های مبهم مانند new_networking_code خودداری کنید. toggle نمونه قبلی، toggle_use_multiple_vlans، به خواننده می‌گوید feature toggle است تا از پارامتر پیکربندی متمایز شود. می‌گوید VLANهای چندگانه را enable می‌کند، پس خواننده می‌داند چه می‌کند. و نام روشن می‌کند toggle چگونه کار می‌کند. خواندن نامی مانند toggle_multiple_vlans، یا بدتر toggle_vlans، شما را در مورد enable یا disable کردن کد VLAN چندگانه نامطمئن می‌گذارد. این به خطا منجر می‌شود، جایی که کسی شرط را برعکس در کدش استفاده می‌کند.

تغییر زیرساخت زنده

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

مثلاً وقتی تیم ShopSpinner تغییر کد shared-networking-stack را که VLAN واحد را با سه VLAN جایگزین می‌کند اعمال می‌کند، همان‌طور که در «تبدیل‌های Backward Compatible» در صفحه ۳۶۴ توضیح داده شد، چه اتفاقی برای منابع stackهای دیگر که به VLAN اول اختصاص یافته‌اند می‌افتد (شکل ۲۱-۱۰ را ببینید)؟

شکل ۲۱-۱۰. تغییر ساختارهای شبکه‌ای که در حال استفاده‌اند

اعمال کد شبکه main_vlan را که سه نمونه سرور دارد destroy می‌کند. در محیط زنده، destroy کردن آن سرورها یا detach کردن از شبکه سرویس‌هایی که ارائه می‌دهند را مختل می‌کند.

بیشتر پلتفرم‌های زیرساخت از destroy کردن ساختار شبکه‌ای که نمونه سرور به آن attach است خودداری می‌کنند، پس عملیات fail می‌شود. اگر تغییر کدی که اعمال می‌کنید منابع دیگر را حذف یا تغییر دهد، عملیات ممکن است آن تغییرات را روی نمونه پیاده‌سازی کند و محیط را در حالت نیمه‌راه بین نسخه قدیم و جدید کد stack بگذارد. این تقریباً همیشه بد است.

چند راه برای handle کردن این نوع تغییر زیرساخت زنده وجود دارد. یکی نگه داشتن VLAN قدیمی main_vlan و افزودن دو VLAN جدید appserver_vlan_B و appserver_vlan_C است.

این کار سه VLAN را همان‌طور که قصد داشتید می‌گذارد، اما یکی نام متفاوتی از بقیه دارد. نگه داشتن VLAN موجود احتمالاً از تغییر جنبه‌های دیگر آن، مانند محدوده IP address، جلوگیری می‌کند. باز هم ممکن است تصمیم بگیرید با نگه داشتن VLAN اصلی کوچک‌تر از جدیدها سازش کنید.

این نوع سازش‌ها عادت بد است و به سیستم‌های ناسازگار و کدی که نگهداری و debug آن گیج‌کننده است منجر می‌شود.

می‌توانید از تکنیک‌های دیگر برای تغییر سیستم‌های زنده و گذاشتن آن‌ها در حالت تمیز و سازگار استفاده کنید. یکی ویرایش منابع زیرساخت با infrastructure surgery است. دیگری expand و contract کردن منابع زیرساخت است.

Infrastructure Surgery

بعضی ابزارهای مدیریت stack، مانند Terraform، به ساختارهای داده‌ای که منابع زیرساخت را به کد map می‌کنند دسترسی می‌دهند. این همان ساختارهای داده‌ای است که در الگوی stack data lookup برای کشف وابستگی استفاده می‌شود (به «الگو: Stack Data Lookup» در صفحه ۲۹۱ مراجعه کنید).

بعضی (نه همه) ابزارهای stack گزینه‌ای برای ویرایش ساختارهای داده‌ای دارند. می‌توانید از این قابلیت برای تغییر زیرساخت زنده استفاده کنید.

تیم ShopSpinner می‌تواند از ابزار stack خیالی برای ویرایش ساختارهای داده stack استفاده کند. اعضا از این برای تغییر محیط production به استفاده از سه VLAN جدید استفاده می‌کنند. اول نمونه دومی از shared-networking-stack با نسخه جدید کد ایجاد می‌کنند (شکل ۲۱-۱۱ را ببینید).

شکل ۲۱-۱۱. نمونه‌های موازی stack شبکه production

هر یک از این سه نمونه stack — نمونه application-infrastructure-stack و نمونه‌های قدیم و جدید shared-networking-stack — ساختار داده‌ای دارد که نشان می‌دهد کدام منابع در پلتفرم زیرساخت به آن stack تعلق دارند (شکل ۲۱-۱۲ را ببینید).

شکل ۲۱-۱۲. هر نمونه stack ساختار داده stack خود را دارد

تیم ShopSpinner main_vlan را از ساختارهای داده نمونه stack قدیمی به ساختار داده نمونه stack جدید منتقل می‌کند. سپس از آن برای جایگزینی appserver_vlan_A استفاده می‌کند.

VLAN در پلتفرم زیرساخت به هیچ وجه تغییر نمی‌کند و نمونه‌های سرور کاملاً دست‌نخورده می‌مانند. این تغییرات کاملاً تمرین bookkeeping در ساختارهای داده ابزار stack است.

تیم دستور ابزار stack را برای انتقال main_vlan از stack قدیمی به نمونه stack جدید اجرا می‌کند:

bash
$ stack datafile move-resource \
    source-instance=shared-networking-stack-production-old \
    source-resource=main_vlan \
    destination-instance=shared-networking-stack-production-new
Success: Resource moved

گام بعدی حذف appserver_vlan_A است. نحوه انجام بسته به ابزار واقعی مدیریت stack متفاوت است. دستور stack خیالی این عملیات را فوق‌العاده ساده می‌کند. اجرای دستور زیر VLAN را در پلتفرم زیرساخت destroy و از فایل ساختار داده حذف می‌کند:

bash
$ stack datafile destroy-resource \
    instance=shared-networking-stack-production-new \
    resource=appserver_vlan_A
Success: Resource destroyed and removed from the datafile

توجه کنید اعضا appserver_vlan_A را از کد منبع stack حذف نکرده‌اند، پس اگر الان کد را روی نمونه اعمال کنند دوباره ایجاد می‌شود. اما این کار را نمی‌کنند. در عوض دستوری برای rename کردن resource main_vlan که از نمونه stack قدیمی منتقل کردند اجرا می‌کنند:

bash
$ stack datafile rename-resource \
    instance=shared-networking-stack-production-new \
    from=main_vlan \
    to=appserver_vlan_A
Success: Resource renamed in the datafile

وقتی تیم کد shared-networking-stack را روی نمونه جدید اعمال می‌کند، نباید چیزی تغییر کند. از نظر ابزار، همه چیز در کد در نمونه وجود دارد.

توجه کنید توانایی ویرایش و انتقال منابع بین stackها کاملاً به ابزار مدیریت stack بستگی دارد. بیشتر ابزارهای ارائه‌شده توسط cloud vendor، حداقل تا زمان نگارش این کتاب، امکان ویرایش ساختارهای داده stack را expose نمی‌کنند.⁷

⁷ دستور terraform mv و دستور pulumi state را برای دو نمونه ابزارهایی که از ویرایش ساختارهای داده stack پشتیبانی می‌کنند ببینید.

ویرایش دستی ساختارهای داده stack آسان است اشتباه کنید، پس ریسک ایجاد outage بالاست. می‌توانید اسکریپتی برای پیاده‌سازی دستورات بنویسید و در محیط‌های upstream تست کنید. اما این ویرایش‌ها idempotent نیستند. فرض state شروع مشخصی دارند و اجرای اسکریپت اگر چیزی متفاوت باشد غیرقابل پیش‌بینی است.

مشاهده ساختارهای داده stack برای debug مفید است، اما باید از ویرایش آن‌ها خودداری کنید. شاید بتوان گفت برای رفع outage ویرایش ساختارها لازم است. اما فشار این موقعیت‌ها اغلب احتمال اشتباه را بیشتر می‌کند. نباید ساختارها را به‌صورت routine ویرایش کنید. هر بار که به ویرایش ساختارها متوسل شدید، تیم باید blameless postmortem انجام دهد تا بفهمد چگونه از تکرار اجتناب کند.

راه امن‌تر برای تغییر زیرساخت زنده expand و contract است.

Expand و Contract

تیم‌های زیرساخت از الگوی expand and contract (که Parallel Change هم نامیده می‌شود) برای تغییر رابط بدون شکستن consumerها استفاده می‌کنند. ایده این است که تغییر رابط provider دو گام دارد: تغییر provider، سپس تغییر consumerها. الگوی expand and contract این گام‌ها را decouple می‌کند.

جوهر الگو این است که اول resource جدید را اضافه کنید در حالی که موجود را نگه می‌دارید، سپس consumerها را به resource جدید منتقل کنید و در نهایت resource قدیمی استفاده‌نشده را حذف کنید. هر یک از این تغییرات با pipeline تحویل می‌شود («Pipelineهای تحویل زیرساخت» در صفحه ۱۱۹ را ببینید) پس به‌طور کامل تست می‌شود.

تغییر با expand و contract شبیه تبدیل backward compatible است («تبدیل‌های Backward Compatible» در صفحه ۳۶۴ را ببینید). آن تکنیک resource قدیمی را جایگزین و رابط قدیمی را به یکی از resourceهای جدید re-point می‌کرد. با این حال، اعمال کد جدید روی نمونه در حال اجرا سعی می‌کرد resource قدیمی را destroy کند که یا consumerهای attach‌شده را مختل می‌کرد یا تکمیل را fail می‌کرد. پس چند گام اضافی لازم است.

اولین گام تیم ShopSpinner برای استفاده از expand and contract برای تغییر VLAN افزودن VLANهای جدید به shared-networking-stack است در حالی که main_vlan قدیمی سر جایش می‌ماند:

yaml
vlans:
  - main_vlan
    address_range: 10.2.0.0/8
  - appserver_vlan_A
       address_range: 10.1.0.0/16
  - appserver_vlan_B
       address_range: 10.2.0.0/16
  - appserver_vlan_C
       address_range: 10.3.0.0/16

export:
  - main_vlan: main_vlan.id
  - appserver_vlan_A: appserver_vlan_A.id
  - appserver_vlan_B: appserver_vlan_B.id
  - appserver_vlan_C: appserver_vlan_C.id

برخلاف تکنیک نمونه‌های موازی («نمونه‌های موازی» در صفحه ۳۶۱) و infrastructure surgery («Infrastructure Surgery» در صفحه ۳۷۰)، تیم ShopSpinner نمونه دوم stack اضافه نمی‌کند، فقط نمونه موجود را تغییر می‌دهد.

بعد از اعمال این کد، نمونه‌های consumer موجود تحت تأثیر قرار نمی‌گیرند — همچنان به main_vlan attach هستند. تیم می‌تواند resourceهای جدید به VLANهای جدید اضافه کند و تغییراتی در consumerها برای سوئیچ آن‌ها هم بدهد.

نحوه سوئیچ resourceهای consumer برای استفاده از resourceهای جدید به زیرساخت و پلتفرم مشخص بستگی دارد. در بعضی موارد می‌توانید تعریف resource را به‌روز کنید تا به رابط provider جدید attach شود. در موارد دیگر ممکن است نیاز به destroy و rebuild resource باشد.

تیم ShopSpinner نمی‌تواند نمونه‌های سرور مجازی موجود را به VLANهای جدید reassign کند. با این حال، تیم می‌تواند از الگوی expand and contract برای جایگزینی سرورها استفاده کند. کد application-infrastructure-stack هر سرور را با IP address ثابتی که ترافیک را به سرور route می‌کند تعریف می‌کند:

yaml
virtual_machine:
  name: appserver-${SERVICE}-A
  memory: 4GB
  vlan: external_stack.shared_network_stack.main_vlan

static_ip:
  name: address-${SERVICE}-A
  attach: virtual_machine.appserver-${SERVICE}-A

اولین گام تیم افزودن نمونه سرور جدید attach‌شده به VLAN جدید است:

yaml
virtual_machine:
  name: appserver-${SERVICE}-A2
  memory: 4GB
  vlan: external_stack.shared_network_stack.appserver_vlan_A

virtual_machine:
  name: appserver-${SERVICE}-A
  memory: 4GB
  vlan: external_stack.shared_network_stack.main_vlan

static_ip:
  name: address-${SERVICE}-A
  attach: virtual_machine.appserver-${SERVICE}-A

دستور virtual_machine اول در این کد نمونه سرور جدیدی به نام appserver-${SERVICE}-A2 ایجاد می‌کند. pipeline تیم این تغییر را به هر محیط تحویل می‌دهد. نمونه سرور جدید در این نقطه استفاده نمی‌شود، اگرچه تیم می‌تواند تست‌های خودکار اضافه کند که ثابت کند درست اجرا می‌شود.

گام بعدی تیم سوئیچ ترافیک کاربر به نمونه سرور جدید است. تیم تغییر دیگری در کد می‌دهد و دستور static_ip را اصلاح می‌کند:

yaml
virtual_machine:
  name: appserver-${SERVICE}-A2
  memory: 4GB
  vlan: external_stack.shared_network_stack.appserver_vlan_A

virtual_machine:
  name: appserver-${SERVICE}-A
  memory: 4GB
  vlan: external_stack.shared_network_stack.main_vlan

static_ip:
  name: address-${SERVICE}-A
  attach: virtual_machine.appserver-${SERVICE}-A2

Push کردن این تغییر از pipeline سرور جدید را فعال و ترافیک به سرور قدیمی را متوقف می‌کند. تیم می‌تواند مطمئن شود همه چیز کار می‌کند و در صورت مشکل به‌راحتی تغییر را rollback کند تا سرور قدیمی را بازگرداند.

وقتی تیم سرور جدید را OK دارد، می‌تواند سرور قدیمی را از کد stack حذف کند:

yaml
virtual_machine:
  name: appserver-${SERVICE}-A2
  memory: 4GB
  vlan: external_stack.shared_network_stack.appserver_vlan_A

static_ip:
  name: address-${SERVICE}-A
  attach: virtual_machine.appserver-${SERVICE}-A2

وقتی این تغییر از pipeline عبور کرد و روی همه محیط‌ها اعمال شد، application-infrastructure-stack دیگر به main_vlan در shared-networking-stack وابسته نیست. بعد از اینکه همه زیرساخت consumer سوئیچ کرد، تیم ShopSpinner می‌تواند main_vlan را از کد stack provider حذف کند:

yaml
vlans:
  - appserver_vlan_A
       address_range: 10.1.0.0/16
  - appserver_vlan_B
       address_range: 10.2.0.0/16
  - appserver_vlan_C
       address_range: 10.3.0.0/16

export:
  - appserver_vlan_A: appserver_vlan_A.id
  - appserver_vlan_B: appserver_vlan_B.id
  - appserver_vlan_C: appserver_vlan_C.id

تغییر VLAN کامل است و آخرین باقی‌مانده‌های main_vlan جمع‌آوری شده‌اند.⁸

⁸ نگران نباشید، ترس سیستم‌های محلی را در خط نگه می‌دارد.

تغییرات Zero Downtime

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

چند تکنیک رایج برای handle کردن این موقعیت‌ها وجود دارد.

تغییرات Blue-Green

تغییر blue-green شامل ایجاد نمونه جدید، سوئیچ استفاده به نمونه جدید و سپس حذف نمونه قدیمی است. این از نظر مفهومی شبیه expand and contract («Expand و Contract» در صفحه ۳۷۲) است که resourceها را درون نمونه جزئی مانند stack اضافه و حذف می‌کند. تکنیک کلیدی برای پیاده‌سازی زیرساخت immutable است («زیرساخت Immutable» در صفحه ۳۵۱ را ببینید).

تغییرات blue-green به مکانیزمی برای handle کردن switchover workload از یک نمونه به دیگری نیاز دارد، مانند load balancer برای ترافیک شبکه. پیاده‌سازی‌های پیچیده اجازه می‌دهند workload «drain» شود — کار جدید به نمونه جدید تخصیص یابد و منتظر بماند تا همه کار روی نمونه قدیمی تمام شود قبل از destroy. بعضی راه‌حل‌های خودکار clustering سرور و clustering برنامه این را به‌عنوان قابلیت ارائه می‌دهند، مثلاً enable کردن «rolling upgrade» روی نمونه‌ها در cluster.

blue-green با زیرساخت static با نگه داشتن دو محیط پیاده‌سازی می‌شود. یک محیط در هر لحظه live است و دیگری آماده گرفتن نسخه بعدی. نام‌های blue و green تأکید می‌کنند این محیط‌های برابرند که نوبتی live می‌شوند، نه محیط primary و secondary.

با سازمانی کار کردم که data centerهای blue-green پیاده‌سازی کرده بود. release شامل switch workload کل سیستم از یک data center به دیگری بود. این مقیاس unwieldy شد، پس به سازمان کمک کردیم deployment در مقیاس کوچک‌تر پیاده‌سازی کند تا فقط برای سرویس مشخصی که upgrade می‌شد blue-green deployment انجام دهد.

تداوم (Continuity)

فصل ۱ تضاد بین رویکردهای سنتی «عصر آهن» برای مدیریت زیرساخت و رویکردهای مدرن «عصر ابری» را بحث کرد (به «از عصر آهن به عصر ابری» در صفحه ۲ مراجعه کنید). وقتی بیشتر با دستگاه‌های فیزیکی کار می‌کردیم و آن‌ها را دستی مدیریت می‌کردیم، هزینه دادن تغییرات بالا بود.

هزینه اشتباه کردن هم بالا بود. وقتی سرور جدیدی بدون RAM کافی provision کردم، بیش از یک هفته طول کشید تا RAM بیشتر سفارش دهم، به data center ببرم، سرور را خاموش و از rack بیرون بکشم، باز کنم و RAM اضافه کنم، دوباره در rack بگذارم و boot کنم.

هزینه دادن تغییر با practiceهای عصر ابری بسیار کمتر است، همان‌طور که هزینه و زمان لازم برای اصلاح اشتباه. اگر سرور بدون RAM کافی provision کنم، فقط چند دقیقه طول می‌کشد با ویرایش فایل و اعمال روی سرور مجازی اصلاح کنم.

رویکردهای عصر آهن به تداوم بر پیشگیری تأکید می‌کنند. برای MTBF، Mean Time Between Failure، به قیمت قربانی کردن سرعت و فرکانس تغییر بهینه می‌کنند. رویکردهای عصر ابری برای MTTR، Mean Time to Recover، بهینه می‌کنند. اگرچه حتی بعضی علاقه‌مندان روش‌های مدرن در دام فکر می‌افتند که تمرکز روی MTTR به معنای قربانی کردن MTBF است، این درست نیست، همان‌طور که در «اعتراض: «باید بین سرعت و کیفیت انتخاب کنیم»» در صفحه ۷ توضیح داده شد. تیم‌هایی که روی چهار معیار کلیدی (سرعت و فرکانس تغییرات، MTTR و نرخ شکست تغییر، همان‌طور که در «چهار معیار کلیدی» در صفحه ۹ توصیف شده) تمرکز می‌کنند MTBF قوی را به‌عنوان اثر جانبی به دست می‌آورند. نکته «move fast and break things» نیست، بلکه «move fast and fix things» است.

چند عنصر برای دستیابی به تداوم با زیرساخت مدرن وجود دارد. پیشگیری، تمرکز practiceهای مدیریت تغییر عصر ابری، ضروری است، اما زیرساخت ابری و اتوماسیون استفاده از practiceهای مهندسی Agile مؤثرتر برای کاهش خطا را enable می‌کند. علاوه بر این، می‌توانیم فناوری‌ها و practiceهای جدید را exploit کنیم تا سیستم‌ها را recover و rebuild کنیم و به سطوح تداوم بالاتر از آنچه قبلاً تصور می‌شد برسیم. و با exercise مداوم مکانیزم‌هایی که تغییرات را تحویل و سیستم‌ها را recover می‌کنند، می‌توانیم قابلیت اطمینان و آمادگی برای انواع گسترده فاجعه را تضمین کنیم.

تداوم با پیشگیری از خطا

همان‌طور که ذکر شد، رویکردهای عصر آهن به حاکمیت تغییرات عمدتاً پیشگیرانه بودند. چون هزینه رفع اشتباه بالا بود، سازمان‌ها سنگین در پیشگیری از اشتباه سرمایه‌گذاری می‌کردند. چون تغییرات عمدتاً دستی بود، پیشگیری شامل محدود کردن کسانی بود که می‌توانستند تغییر دهند. افراد باید تغییرات را با جزئیات برنامه‌ریزی و طراحی می‌کردند و دیگران هر تغییر را به‌طور exhaustive بررسی و بحث می‌کردند. ایده این بود که داشتن افراد بیشتر با زمان بیشتر برای در نظر گرفتن تغییر از قبل اشتباهات را می‌گرفت.

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

نتیجه این است که عملیات تغییر batch بزرگ با فرکانس پایین و برنامه‌ریزی سنگین سنتی نرخ شکست بالا و اغلب زمان بازیابی طولانی دارد.

practiceها و الگوهای توصیف‌شده در سراسر این کتاب هدف دارند خطا را بدون قربانی کردن فرکانس و سرعت تغییر پیشگیری کنند. تغییرات تعریف‌شده به‌عنوان کد پیاده‌سازی را بهتر از هر نمودار یا سند طراحی نشان می‌دهند. یکپارچه‌سازی، اعمال و تست مداوم تغییرات هنگام کار آمادگی production را ثابت می‌کند. استفاده از pipeline برای تست و تحویل تغییرات تضمین می‌کند گام‌ها رد نشوند و سازگاری در محیط‌ها را enforce می‌کند. این احتمال شکست در production را کاهش می‌دهد.

بینش اصلی توسعه نرم‌افزار Agile و Infrastructure as Code چرخش نگرش به تغییر است. به‌جای ترس از تغییر و انجام کم آن، می‌توانید با دادن مکرر تغییرات خطا را پیشگیری کنید. تنها راه بهتر شدن در دادن تغییرات، دادن مکرر تغییرات و بهبود مداوم سیستم‌ها و فرایندهاست.

بینش کلیدی دیگر این است که با پیچیده‌تر شدن سیستم‌ها، توانایی ما برای replicate و تست دقیق رفتار کد در production کوچک می‌شود. باید آگاه باشیم چه چیزهایی را می‌توانیم و نمی‌توانیم قبل از production تست کنیم و چگونه ریسک‌ها را با بهبود visibility سیستم‌های production کاهش دهیم (به «تست در Production» در صفحه ۱۲۵ مراجعه کنید).

تداوم با بازیابی سریع

practiceهای توصیف‌شده تا اینجا در این فصل می‌توانند downtime را کاهش دهند. محدود کردن اندازه تغییرات، دادن افزایشی آن‌ها و تست قبل از production می‌تواند نرخ شکست تغییر را پایین بیاورد. اما عاقلانه نیست فرض کنیم خطاها کاملاً قابل پیشگیری‌اند، پس باید بتوانیم سریع و آسان recover کنیم.

practiceهای ترویج‌شده در سراسر این کتاب rebuild هر بخش سیستم را آسان می‌کند. سیستم شما از اجزای loosely coupled تشکیل شده که هر کدام به‌عنوان کد idempotent تعریف شده. می‌توانید به‌راحتی هر نمونه جزء را repair کنید یا destroy و rebuild کنید با اعمال مجدد کدش. باید تداوم داده host‌شده روی جزء را هنگام rebuild تضمین کنید که در «تداوم داده در سیستم در حال تغییر» در صفحه ۳۸۲ بحث شده.

در بعضی موارد، پلتفرم یا سرویس‌های شما می‌توانند زیرساخت شکست‌خورده را به‌طور خودکار rebuild کنند. پلتفرم زیرساخت یا runtime برنامه اجزای جداگانه را وقتی health check را fail می‌کنند destroy و rebuild می‌کند. اعمال مداوم کد روی نمونه‌ها («اعمال مداوم کد» در صفحه ۳۵۰) هر انحراف از کد را به‌طور خودکار revert می‌کند. می‌توانید دستی trigger کنید مرحله pipeline («Pipelineهای تحویل زیرساخت» در صفحه ۱۱۹) کد را روی جزء شکسته دوباره اعمال کند.

در سناریوهای شکست دیگر، این سیستم‌ها ممکن است به‌طور خودکار مشکل را fix نکنند. نمونه compute ممکن است به‌گونه‌ای malfunction کند که همچنان health check را پاس کند. عنصر زیرساخت ممکن است درست کار نکند در حالی که همچنان با تعریف کد match می‌کند، پس اعمال مجدد کد کمکی نمی‌کند.

این سناریوها به نوعی اقدام اضافی برای جایگزینی اجزای شکسته نیاز دارند. ممکن است جزئی را flag کنید تا سیستم خودکار آن را failed بداند و destroy و جایگزین کند. یا اگر recovery از سیستمی استفاده می‌کند که کد را دوباره اعمال می‌کند، شاید خودتان جزء را destroy کنید و به سیستم اجازه دهید نمونه جدید بسازد.

برای هر سناریوی شکستی که نیاز به اقدام فرد دارد، باید مطمئن شوید ابزار، اسکریپت یا مکانیزم‌های دیگری دارید که اجرایشان ساده است. افراد نباید دنباله‌ای از گام‌ها را دنبال کنند؛ مثلاً backup داده قبل از destroy نمونه. در عوض باید اقدامی را invoke کنند که همه گام‌های لازم را انجام دهد. هدف این است که در اضطرار نیازی به فکر کردن درباره نحوه recover صحیح سیستم نباشد.

Disaster Recovery مداوم

رویکردهای مدیریت زیرساخت عصر آهن disaster recovery را رویداد غیرمعمول می‌بینند. بازیابی از شکست سخت‌افزار static اغلب نیاز به shift workload به مجموعه جداگانه‌ای از سخت‌افزار standby دارد.

بسیاری از سازمان‌ها عملیات recovery را به‌ندرت تست می‌کنند — در بهترین حالت هر چند ماه، در بعضی موارد یک‌بار در سال. سازمان‌های زیادی را دیده‌ام که به‌ندرت فرایند failover را تست می‌کنند. فرض این است که تیم اگر لازم شد چند روز طول می‌کشد تا سیستم backup را راه بیندازد.

disaster recovery مداوم همان فرایندها و ابزارهایی را leverage می‌کند که برای provision و تغییر زیرساخت استفاده می‌شود. همان‌طور که قبلاً توضیح داده شد، می‌توانید کد زیرساخت را برای rebuild زیرساخت شکسته اعمال کنید، شاید با اتوماسیون اضافه برای اجتناب از از دست دادن داده.

یکی از اصول زیرساخت عصر ابری فرض کردن ناپایداری سیستم‌هاست («اصل: فرض کنید سیستم‌ها ناپایدارند» در صفحه ۱۴). نمی‌توانید نرم‌افزار را روی ماشین مجازی نصب کنید و انتظار داشته باشید تا هرچه بخواهید آنجا اجرا شود. cloud vendor ممکن است ماشین یا host system را برای نگهداری، patch امنیتی یا upgrade جابه‌جا، destroy یا جایگزین کند. پس باید آماده جایگزینی سرور باشید.⁹

Treat کردن disaster recovery به‌عنوان توسعه عملیات عادی آن را بسیار قابل اعتمادتر از treat کردن به‌عنوان استثنا می‌کند. تیم شما فرایند و ابزار recovery را بارها در روز هنگام کار روی تغییرات کد زیرساخت و به‌روزرسانی سیستم exercise می‌کند. اگر کسی تغییری در اسکریپت یا کد دیگر بدهد که provisioning را می‌شکند یا در به‌روزرسانی داده از دست می‌دهد، معمولاً در مرحله تست pipeline fail می‌شود و سریع fix می‌کنید.

⁹ نمونه‌های compute از روزهای اول cloud computing قابل اعتمادتر شده‌اند. در ابتدا نمی‌توانستید instance AWS EC2 را shutdown و بعداً boot کنید — وقتی instance متوقف می‌شد برای همیشه رفته بود. ماهیت ephemeral compute مجبور کرد کاربران cloud practiceهای جدید برای اجرای سرویس‌های قابل اعتماد روی زیرساخت ناپایدار adopt کنند. این منشأ Infrastructure as Code، chaos engineering و practiceهای دیگر زیرساخت عصر ابری بود.

Chaos Engineering

Netflix پیشگام disaster recovery مداوم و مدیریت زیرساخت عصر ابری بود.¹⁰ Chaos Monkey و Simian Army مفهوم disaster recovery مداوم را یک گام جلوتر بردند و اثربخشی مکانیزم‌های تداوم سیستم را با injection خطا به سیستم‌های production ثابت کردند. این به حوزه Chaos Engineering تکامل یافت: «رشته آزمایش روی سیستم برای ساخت اطمینان در قابلیت سیستم.»¹¹

روشن است chaos engineering درباره ایجاد مسئولانه outage سرویس production نیست. practitioners با سناریوهای شکست مشخصی experiment می‌کنند که انتظار می‌رود سیستم handle کند. این تست‌های ضروری production هستند که ثابت می‌کنند مکانیزم‌های detection و recovery درست کار می‌کنند. قصد بازخورد سریع است وقتی تغییری در سیستم اثر جانبی دارد که با این مکانیزم‌ها تداخل می‌کند.

¹⁰ «5 Lessons We've Learned Using AWS» نوشته ۲۰۱۰ را برای بینش درس‌های اولیه ساخت سرویس‌های بسیار قابل اعتماد روی public cloud در مقیاس ببینید.

¹¹ این تعریف از وب‌سایت اصول chaos engineering است.

برنامه‌ریزی برای شکست

شکست‌ها اجتناب‌ناپذیرند. در حالی که می‌توانید و باید گام‌هایی برای کم‌محتمل‌تر کردن آن‌ها بردارید، همچنین باید اقداماتی برای کم‌مضر و آسان‌تر handle کردن آن‌ها قرار دهید.

تیم workshop نقشه‌برداری سناریوی شکست برگزار می‌کند تا انواع شکست‌های ممکن را brainstorm کند و سپس mitigation برنامه‌ریزی کند.¹² می‌توانید نقشه احتمال و impact هر سناریو بسازید، فهرست اقدامات برای برخورد با سناریوها ایجاد کنید و سپس آن‌ها را در backlog کار تیم به‌درستی اولویت‌بندی کنید.

برای هر سناریوی شکست مشخص، چند شرط برای بررسی وجود دارد:

Causes and prevention (علل و پیشگیری) چه موقعیت‌هایی می‌تواند به این شکست منجر شود و چه کاری می‌توانید برای کم‌محتمل‌تر کردن آن‌ها انجام دهید؟ مثلاً سرور ممکن است وقتی usage spike می‌کند از فضای دیسک تمام شود. می‌توانید با تحلیل الگوهای استفاده دیسک و گسترش اندازه دیسک برای سطوح usage بالاتر برخورد کنید. شاید مکانیزم‌های خودکار برای تحلیل مداوم سطوح usage و پیش‌بینی پیاده‌سازی کنید تا فضای دیسک preemptively اضافه شود. گام بعدی تنظیم خودکار ظرفیت دیسک با افزایش usage است.

Failure mode (حالت شکست) وقتی شکست رخ می‌دهد چه اتفاقی می‌افتد؟ چه کاری می‌توانید برای کاهش پیامد بدون مداخله انسان انجام دهید؟ مثلاً اگر سرور مشخص از فضای دیسک تمام شود، برنامه روی آن ممکن است transaction بپذیرد اما fail کند در ثبت. این می‌تواند بسیار مضر باشد، پس شاید برنامه را تغییر دهید تا اگر نتواند روی دیسک ثبت کند transaction نپذیرد. در بسیاری موارد تیم‌ها واقعاً نمی‌دانند وقتی خطای مشخص رخ می‌دهد چه خواهد شد. ایده‌آل failure mode سیستم را کاملاً عملیاتی نگه می‌دارد. مثلاً وقتی برنامه پاسخ نمی‌دهد، load balancer ممکن است ترافیک به آن را متوقف کند.

Detection (کشف) چگونه وقتی شکست رخ می‌دهد کشف می‌کنید؟ چه کاری برای کشف سریع‌تر، شاید حتی از قبل، می‌توانید انجام دهید؟ ممکن است وقتی دیسک پر شد کشف کنید وقتی برنامه crash کرد و مشتری به CEO شما زنگ زد. بهتر است وقتی برنامه crash کرد notification بگیرید. بهتر از همه وقتی فضای دیسک کم شد، قبل از پر شدن واقعی.

Correction (اصلاح) چه گام‌هایی برای recover از شکست لازم است؟ در بعضی سناریوها، همان‌طور که قبلاً توضیح داده شد، سیستم‌ها ممکن است به‌طور خودکار وضعیت را اصلاح کنند، شاید با destroy و rebuild نمونه برنامه غیرپاسخگو. دیگران چند گام برای repair و restart سرویس می‌خواهند.

اگر سیستم شما سناریوی شکست را به‌طور خودکار handle می‌کند، مانند restart نمونه compute غیرپاسخگو، باید سناریوی شکست عمیق‌تر را در نظر بگیرید. چرا instance در اول جا غیرپاسخگو شد؟ چگونه مشکل زیربنایی را کشف و اصلاح می‌کنید؟ نباید چند روز طول بکشد تا بفهمید نمونه‌های برنامه هر چند دقیقه recycle می‌شوند.

برنامه‌ریزی شکست فرایند مداوم است. هر وقت incident با سیستم دارید، از جمله در محیط توسعه یا تست، تیم باید در نظر بگیرد آیا سناریوی شکست جدیدی برای تعریف و برنامه‌ریزی وجود دارد.

باید checkهایی پیاده‌سازی کنید که سناریوهای شکست را ثابت کنند. مثلاً اگر باور دارید وقتی سرور از فضای دیسک تمام می‌شود برنامه transaction نمی‌پذیرد، به‌طور خودکار نمونه سرور جدید اضافه می‌کند و تیم را alert می‌کند، باید تست خودکاری داشته باشید که این سناریو را exercise کند. می‌توانید در مرحله pipeline (availability testing همان‌طور که در «چه چیزهایی را با زیرساخت تست کنیم؟» در صفحه ۱۰۸ توصیف شده) یا با chaos experiment تست کنید.

¹² همچنین «Failure mode and effects analysis» را ببینید.

بهبود تدریجی تداوم آسان است اقدامات بازیابی بلندپروازانه تعریف کنید که سیستم شما به‌طور graceful هر شکست قابل تصور را بدون قطع سرویس handle کند. هرگز تیمی ندیدم که زمان و منابع داشته باشد حتی نیمی از آنچه می‌خواهد بسازد. هنگام نقشه‌برداری سناریوهای شکست و mitigationها، می‌توانید مجموعه افزایشی اقداماتی که می‌توانید پیاده‌سازی کنید تعریف کنید. آن‌ها را به storyهای پیاده‌سازی جداگانه بشکنید و بر اساس احتمال سناریو، آسیب بالقوه و هزینه پیاده‌سازی در backlog اولویت‌بندی کنید. مثلاً اگرچه nice است فضای دیسک برنامه را وقتی کم می‌شود به‌طور خودکار گسترش دهید، گرفتن alert قبل از تمام شدن گام اول ارزشمند است.

تداوم داده در سیستم در حال تغییر

بسیاری از practiceها و تکنیک‌های عصر ابری برای deploy نرم‌افزار و مدیریت زیرساخت با خوش‌رویی destroy و گسترش casual منابع را توصیه می‌کنند، با فقط اشاره‌ای به مشکل داده. بخشیده می‌شوید فکر کنید hipsterهای DevOps کل ایده داده را بازگشتی به عصر آهن می‌بینند — برنامه twelve-factor مناسب stateless است. بیشتر سیستم‌های دنیای واقعی داده دارند و افراد به آن وابسته‌اند.

داده می‌تواند چالشی هنگام تغییر افزایشی سیستم باشد، همان‌طور که در «Push کردن تغییرات ناقص به Production» در صفحه ۳۶۱ توضیح داده شد. اجرای نمونه‌های موازی زیرساخت storage ممکن است ناسازگاری یا حتی corrupt کردن داده ایجاد کند. بسیاری از رویکردهای deploy افزایشی به توانایی rollback کردن آن‌ها وابسته‌اند که با تغییرات schema داده ممکن است ممکن نباشد.

افزودن، حذف و rebuild پویای resourceهای زیرساختی که داده host می‌کنند به‌ویژه چالش‌برانگیز است. با این حال، بسته به موقعیت راه‌هایی برای مدیریت وجود دارد. بعضی رویکردها شامل lock، segregate، replicate و reload است.

Lock

بعضی پلتفرم‌های زیرساخت و ابزارهای مدیریت stack اجازه می‌دهند resourceهای مشخص را lock کنید تا با دستوراتی که در غیر این صورت آن‌ها را destroy می‌کنند حذف نشوند. اگر این تنظیم را برای عنصر storage مشخص کنید، ابزار از اعمال تغییر به این عنصر خودداری می‌کند و به اعضای تیم اجازه می‌دهد تغییر را دستی بدهند.

با این حال، چند مسئله وجود دارد. در بعضی موارد، اگر تغییری به resource محافظت‌شده اعمال کنید، ابزار ممکن است stack را در حالت نیمه‌تغییریافته بگذارد که می‌تواند downtime برای سرویس‌ها ایجاد کند.

اما مسئله اساسی این است که محافظت بعضی resourceها از تغییرات خودکار، درگیر شدن دستی در تغییرات را تشویق می‌کند. کار دستی اشتباهات دستی را دعوت می‌کند. بسیار بهتر است راهی برای automate کردن فرایندی که زیرساخت را با امنیت تغییر می‌دهد پیدا کنید.

Segregate

می‌توانید داده را با جدا کردن resourceهایی که آن را host می‌کنند از بخش‌های دیگر سیستم segregate کنید؛ مثلاً با ساخت stack جداگانه (نمونه‌ای در «الگو: Micro Stack» در صفحه ۶۲ داده شده). می‌توانید نمونه compute را بی‌مجازات destroy و rebuild کنید با detach و reattach volume دیسکش.

نگه داشتن داده در پایگاه داده انعطاف بیشتری می‌دهد و بالقوه اجازه افزودن چند نمونه compute می‌دهد. همچنان به استراتژی تداوم داده برای stackی که داده را host می‌کند نیاز دارید، اما دامنه مسئله را محدود می‌کند. شاید بتوانید تداوم داده را کاملاً با سرویس DBaaS میزبانی‌شده offload کنید.

Replicate

بسته به داده و نحوه مدیریت آن، شاید بتوانید آن را در چند نمونه زیرساخت replicate کنید. نمونه کلاسیک cluster پایگاه داده توزیع‌شده است که داده را در nodeها replicate می‌کند.

با استراتژی replication درست، داده به node تازه rebuild‌شده از nodeهای دیگر cluster reload می‌شود. این استراتژی اگر nodeهای زیادی از دست بروند fail می‌شود که با outage hosting بزرگ می‌تواند اتفاق بیفتد. پس این رویکرد به‌عنوان خط دفاع اول کار می‌کند و مکانیزم دیگری برای سناریوهای شکست سخت‌تر لازم است.

Reload

شناخته‌شده‌ترین راه‌حل تداوم داده backup و restore داده از زیرساخت storage قابل اعتمادتر است. وقتی زیرساختی که داده host می‌کند rebuild می‌کنید، اول داده را backup می‌کنید. داده را بعد از ایجاد نمونه جدید reload می‌کنید.

شاید backupهای دوره‌ای هم بگیرید که در سناریوهای recovery reload می‌کنید، اگرچه هر تغییر داده بین backup و recovery را از دست می‌دهید. این را می‌توان با stream کردن تغییرات داده به backup، مانند نوشتن transaction log پایگاه داده، به حداقل رساند و شاید حذف کرد.

پلتفرم‌های ابری سرویس‌های storage مختلف ارائه می‌دهند، همان‌طور که در «منابع Storage» در صفحه ۲۹ توصیف شده، با سطوح مختلف قابلیت اطمینان. مثلاً سرویس‌های object storage مانند AWS S3 معمولاً تضمین‌های قوی‌تری برای durability داده نسبت به سرویس‌های block storage مانند AWS EBS دارند. پس می‌توانید backupها را با کپی یا stream داده به volume object storage پیاده‌سازی کنید.

باید فرایند را نه فقط برای backup داده بلکه برای recover آن automate کنید. پلتفرم زیرساخت شما ممکن است راه‌های آسان برای این کار فراهم کند. مثلاً می‌توانید قبل از اعمال تغییر به volume storage دیسک به‌طور خودکار snapshot بگیرید.

شاید بتوانید از snapshotهای volume دیسک برای بهینه‌سازی فرایند افزودن node به سیستمی مانند cluster پایگاه داده استفاده کنید. به‌جای ایجاد node پایگاه داده جدید با volume storage خالی، attach کردن clone دیسک node دیگر ممکن است synchronize و online آوردن node را سریع‌تر کند.

«Backupهای تست‌نشده همانند نبود backup است» ضرب‌المثل رایجی در صنعت ماست. از آنکه practiceهای Infrastructure as Code را دنبال می‌کنید، از تست خودکار برای جنبه‌های مختلف سیستم استفاده می‌کنید. پس می‌توانید همین کار را با backupها انجام دهید. فرایند backup restore را در pipeline یا به‌عنوان chaos experiment exercise کنید، چه در production چه نه.

ترکیب رویکردهای تداوم داده

بهترین راه‌حل اغلب ترکیبی از segregate، replicate و reload است. segregate کردن داده فضا برای مدیریت انعطاف‌پذیرتر بخش‌های دیگر سیستم ایجاد می‌کند. replication داده را بیشتر وقت در دسترس نگه می‌دارند. و reload داده backstop برای موقعیت‌های extreme‌تر است.

جمع‌بندی

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

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

نمایه

نمایه واژه‌ها و مفاهیم کتاب با شماره صفحات. اصطلاحات فنی و نام ابزارها به زبان اصلی نگه داشته شده‌اند.

A

  • spaghetti module، ۲۸۰-۲۸۳
  • abstraction layers، ۲۸۴
  • unshared module، ۲۷۷
  • Accelerate State of DevOps Report، xv، ۴، ۱۰۷
  • Apache Mesos (website)، ۱۶۱، ۲۳۲
  • actionability, of code، ۳۸
  • Apache OpenWhisk (website)، ۲۴۷
  • activity, as a pipeline stage، ۱۲۰
  • API gateways، ۳۲، ۱۶۷
  • ad hoc apply، ۳۵۰
  • APIs
  • ADRs (architecture decision records)، ۴۷
  • static code analysis with، ۱۳۳
  • AKS (Azure Kubernetes Service)، ۲۹، ۲۳۰، ۲۳۴
  • testing with mock، ۱۳۳
  • Amazon، ۲۰۴
  • application clusters، ۲۲۹-۲۴۸
  • Amazon DynamoDB، ۲۹
  • about، ۲۲۹
  • Amazon Elastic Container Service for Kuberdeploying applications to، ۱۶۱
  • netes (EKS)، ۲۹، ۲۳۰، ۲۳۴ for governance، ۲۴۳
  • Amazon Elastic Container Services (ECS)، ۲۹,
  • for teams، ۲۴۴
  • 230، ۲۳۴ separating for delivery stages، ۲۴۲
  • Amazon's S3، ۳۰
  • solutions for، ۲۳۰-۲۳۲
  • Ambler, Scott
  • stack topologies for، ۲۳۲-۲۴۱
  • Refactoring Databases، ۱۶۵ strategies for، ۲۴۱-۲۴۶
  • Aminator (website)، ۲۰۹
  • application data، ۱۶۴-۱۶۵
  • Andrew File System، ۳۰
  • application group stack pattern، ۵۶، ۵۹
  • Ansible، ۳۸، ۴۵، ۱۷۲
  • application hosting clusters، ۲۹
  • Ansible Cloud Modules (website)، ۵۲
  • application package، ۳۶
  • Ansible for OpenShift (website)، ۲۳۵
  • application runtimes
  • Ansible Tower، ۱۰۰، ۱۷۳
  • about، ۱۵۵
  • antipatterns
  • application connectivity، ۱۶۵-۱۶۸
  • apply on change، ۱۹۲ application data، ۱۶۴-۱۶۵
  • copy-paste environments، ۷۰ application-driven infrastructure، ۱۵۶
  • defined, xx as components of infrastructure systems، ۲۴
  • dual persistent and ephemeral stack stages, cloud native infrastructure، ۱۵۶
  • 145 deploying applications to servers، ۱۵۹
  • for infrastructure stacks، ۵۶-63 deployment packages، ۱۵۸
  • manual stack parameters، ۸۰-82 injecting secrets at، ۱۰۳
  • monolithic stack، ۵۶-59 targets for، ۱۵۷
  • multiple-environment stack، ۶۸ application server، ۱۲۹
  • obfuscation module، ۲۷۶ application-driven infrastructure، ۱۵۶
  • applications
  • Azure Devops، ۲۶
  • as components of infrastructure systems، ۲۳ Azure Functions، ۲۹، ۲۴۷
  • connectivity with، ۱۶۵-168 Azure Image Builder (website)، ۲۱۰
  • delivering، ۳۱۴ Azure Kubernetes Service (AKS)، ۲۹، ۲۳۰، ۲۳۴
  • deployable parts of، ۱۵۷ Azure ML Services، ۲۹
  • deploying FaaS serverless، ۱۶۳ Azure Page Blobs، ۳۰
  • deploying to application clusters، ۱۶۱ Azure Pipelines (website)، ۱۲۴
  • deploying to server clusters، ۱۶۰ Azure Resource Manager (wesbite)، ۵۲
  • deploying to servers، ۱۵۹ Azurite (website)، ۱۳۳
  • deploying using infrastructure code، ۳۱۷
  • packages for deploying to clusters، ۱۶۲-۱۶۳
  • packaging in containers، ۱۵۹

B

  • BaaS (Backend as a Service)، ۲۴۷
  • testing with infrastructure، ۳۱۵ backward compatible transformation، ۳۶۴
  • apply on change antipattern، ۱۹۲
  • bake servers، ۱۹۷
  • apply-time project integration pattern، ۳۳۳-335 baking server images، ۱۸۷، ۲۱۶
  • approval, as a pipeline stage، ۱۲۰
  • Bamboo (website)، ۱۲۳
  • AppVeyor (website)، ۱۲۴
  • bare metal، ۲۸
  • Architectural Quantum، ۲۵۷
  • base operating system, as a source for servers,
  • architecture decision records (ADRs)، ۴۷
  • 171
  • Artifactory (website)، ۳۲۴
  • batect (website)، ۳۴۷
  • artifacts، ۳۲۳
  • Bazel (website)، ۳۲۹
  • ASG (Auto Scaling Group)، ۲۸
  • Beck, Kent، ۲۵۳، ۳۵۹
  • Assume Systems Are Unreliable principle، ۱۴
  • Behr, Kevin
  • asynchronous messaging، ۳۲
  • The Visible Ops Handbook، ۴
  • Atlantis، ۱۲۴، ۳۴۶
  • best practice، xx
  • authentication, as service mesh service، ۲۴۵
  • blameless postmortem، ۳۵۴، ۳۷۲
  • authorization, secretless، ۱۰۳
  • blast radius، ۵۸
  • auto-recovery، ۱۸۲
  • block storage (virtual disk volumes)، ۳۰
  • automated testing, in pipeline-based workflow,
  • blue-green deployment pattern، ۳۷۵
  • 352 Borg، ۱۶۱
  • automation fear spiral، ۱۹
  • Bosh (website)، ۵۲
  • automation lag، ۳۴۹
  • boundaries
  • autoscaling، ۱۸۲
  • aligning to security and governance conavailability
  • cerns، ۲۶۹
  • application clusters and، ۲۴۲ aligning with component life cycles,
  • as service mesh service، ۲۴۵ ۲۶۳-۲۶۴
  • of testing، ۱۰۹ aligning with natural change patterns، ۲۶۲
  • AWS CodeBuild (website)، ۱۲۴
  • aligning with organizational structures، ۲۶۵
  • AWS CodePipeline (website)، ۱۲۴
  • creating that support resilience، ۲۶۵
  • AWS ECS Services (website)، ۱۶۲
  • creating that support scaling، ۲۶۶
  • AWS Elastic BeanStalk، ۲۶، ۳۰
  • drawing between components، ۲۶۲-۲۷۰
  • AWS Image Builder (website)، ۲۱۰
  • hard، ۱۶۸
  • AWS Lambda، ۲۹، ۲۴۷
  • network، ۲۷۰
  • AWS SageMaker، ۲۹
  • BoxFuse (website)، ۱۲۴
  • AWS subnets، ۳۲
  • branch by abstraction، ۳۶۴
  • Awspec (website)، ۱۳۵
  • "break glass" process، ۱۹۶
  • Azure App Service Plans (website)، ۱۶۲
  • "A Brief and Incomplete History of Build Pipe‐
  • Azure Block Blobs، ۳۰
  • lines" blog post، ۱۱۹
  • Azure Cosmos DB، ۲۹
  • Buck (website)، ۳۲۹
  • build server، ۱۲۳
  • Chef, xix، ۳۸، ۴۵، ۴۶، ۱۷۲، ۱۷۴
  • build stage، ۱۳۱
  • Chef Community Cookbooks (website)، ۳۲۵
  • build-time project integration pattern، ۳۲۷-۳۳۰
  • Chef Infra Server (website)، ۱۰۰
  • builder instances، ۲۱۱
  • Chef Provisioning (website)، ۵۲
  • builders Chef Server، ۱۷۳، ۳۲۴، ۳۲۵
  • as code writers، ۳۴۲
  • chroot command، ۲۱۴
  • in team workflow، ۳۴۱
  • CI، ۵۹
  • BuildKite (website)، ۱۲۴
  • CI servers، ۹۵
  • bundle module pattern، ۲۷۶، ۲۷۸، ۲۸۳
  • CircleCI (website)، ۱۲۴
  • Butler-Cole, Ben، ۱۹۵
  • circular logic risk، ۱۱۱
  • Clarity (website)، ۱۳۵

C

  • Clay-Shafer, Andrew, xix
  • Cloud Age
  • CaaS (Containers as a Service)، ۲۸، ۳۶۰
  • cache، ۳۳ about، ۱۳
  • Campbell, Laine
  • Assume Systems Are Unreliable principle,
  • Database Reliability Engineering، ۱۶۵
  • 14
  • canary development pattern، ۳۶۴
  • Create Disposable Things principle، ۱۶
  • can_connect method، ۱۴۰
  • defined، ۲
  • Capistrano (website)، ۱۶۰
  • Ensure That You Can Repeat Any Process
  • causes and prevention، ۳۸۰
  • principle، ۲۰
  • CD (Continuous Delivery)
  • Make Everything Reproducible principle، ۱۴
  • about، ۱۰۵
  • Minimize Variation principle، ۱۷-۱۹
  • challenges with، ۱۱۰-۱۱۵
  • principles of، ۱۳-۲۱
  • infrastructure delivery pipelines، ۱۱۹-۱۲۵
  • cloud agnostic، ۲۷
  • progressive testing، ۱۱۵-۱۱۹
  • cloud computing، ۲۵
  • reasons for، ۱۰۶-۱۱۰
  • Cloud Development Kit (CDK) (see CDK
  • testing in production، ۱۲۵
  • (Cloud Development Kit))
  • CD software، ۱۲۴
  • Cloud Foundry Application Runtime (CFAR),
  • CDC (consumer-driven contract testing)، ۳۳۵
  • 232
  • CDK (Cloud Development Kit)، ۳۹، ۴۳، ۲۹۰,
  • Cloud Native Computing Foundation، ۱۵۶
  • 292 cloud native infrastructure، ۱۵۶، ۱۶۵
  • CDN (Content Distribute Network)، ۳۳
  • cloud platform services، ۱۲۴
  • Centos، ۲۲۱
  • cloud-first strategy، xv
  • centralized service, applying code from a، ۳۴۵
  • cloud-init (website)، ۲۰۰
  • CFAR (Cloud Foundry Application Runtime),
  • CloudFormation، ۳۸، ۴۵، ۵۲، ۵۳، ۷۳، ۱۶۳، ۲۷۲,
  • 232 292
  • CFEngine، ۳۸، ۱۷۲
  • CloudFormation Linter (website)، ۱۳۲
  • cfn_nag (website)، ۱۳۲
  • CloudFoundry app manifests، ۴۵
  • CFRs (Cross-Functional Requirements)، ۱۰۸
  • cluster، ۲۳۰، ۲۳۰
  • change fail percentage, as a key metric for soft(see also application clusters)
  • ware delivery and operational performance,
  • (see also server clusters)
  • 9 cluster as a service، ۲۳۰، ۲۳۳
  • change management
  • CMDB (Configuration Management Dataapplication clusters and، ۲۴۱
  • base)، ۹۷
  • patterns for، ۱۹۲-۱۹۷
  • CNAB (Cloud Native Application Bundle)
  • changelog، ۳۰۸
  • (website)، ۱۶۲
  • chaos engineering، ۱۴، ۱۲۷، ۲۰۴، ۳۷۹
  • Cobbler (website)، ۱۸۳
  • Chaos Monkey، ۳۷۹
  • code
  • checkov (website)، ۱۳۲
  • applying continuously، ۳۵۰
  • in pipeline-based workflow، ۳۵۲
  • containers
  • managing in version control system (VCS),
  • about، ۲۸
  • 37 as code، ۲۳۰
  • quality of، ۱۰۸
  • extracting solutions، ۳۶۳
  • codebase، ۳۹، ۴۶، ۵۳، ۷۳، ۹۲، ۱۰۷، ۱۱۷، ۱۵۸، ۱۷۳,
  • packaging applications in، ۱۵۹
  • 321، ۳۴۸، ۳۵۳
  • Containers as a Service (CaaS)، ۲۸، ۳۶۰
  • coding languages
  • Content Distribute Network (CDN)، ۳۳
  • about، ۳۸
  • continuity
  • declarative infrastructure languages، ۴۱
  • about، ۳۷۶
  • domain-specific infrastructure languages
  • by fast recovery، ۳۷۸
  • (DSL)، ۴۴ by preventing errors، ۳۷۷
  • for stack components، ۲۷۲-۲۷۴
  • chaos engineering، ۳۷۹
  • general-purpose languages، ۴۶
  • continuous disaster recovery، ۳۷۹
  • high-level infrastructure languages، ۵۵
  • in changing systems، ۳۸۲-۳۸۴
  • imperative infrastructure languages، ۴۳-۴۴
  • incrementally improving، ۳۸۱
  • low-level infrastructure languages، ۵۴
  • planning for failure، ۳۸۰
  • procedural languages، ۳۹، ۴۶، ۱۱۲
  • continuous configuration synchronizatio patprogrammable (see imperative infrastruc‐
  • tern، ۱۹۳، ۱۹۷
  • ture languages) Continuous Delivery (CD) (see CD (Continu‐
  • cohesion، ۲۵۲
  • ous Delivery))
  • compliance, of testing، ۱۰۹
  • Continuous Delivery (Humble and Farley),
  • components 105، ۱۱۹
  • refactoring، ۱۴۱
  • continuous stack reset pattern، ۱۴۷
  • scope tested in stages، ۱۲۱
  • Conway's Law، ۲۶۵، ۳۰۳
  • composition, as reason for modularizing stacks,
  • copy-paste environments antipattern، ۷۰
  • 271 CoreOS rkt (website)، ۱۵۹
  • compute instances، ۳۷۹
  • correction، ۳۸۱
  • compute resources، ۲۸
  • correlation, of code، ۳۸
  • ConcourseCI، ۹۴، ۱۲۴
  • coupling، ۲۵۲
  • concurrency, testing and، ۱۲۶
  • cowboy IT، ۲
  • configuration
  • Create Disposable Things principle، ۱۶
  • application clusters and، ۲۴۱
  • Cron، ۱۷۳
  • as a script task، ۳۳۶
  • Cross-Functional Requirements (CFRs)، ۱۰۸
  • choosing tools for externalized، ۳۶
  • cross-project tests، ۳۱۰
  • configuration drift، ۱۷، ۳۴۹-۳۵۱
  • Crowbar (website)، ۱۸۳
  • configuration files، ۸۸
  • Configuration Management Database
  • (CMDB)، ۹۷

D

  • dark launching، ۳۶۴
  • configuration parameters، ۱۵۸
  • data
  • configuration patterns, chaining، ۹۹
  • management of, as a risk of testing in proconfiguration registries، ۹۶, ۹۹-۱۰۲, ۱۶۷
  • duction، ۱۲۷
  • configuration values، ۳۱۲، ۳۳۶
  • testing and، ۱۲۵
  • connectivity، ۱۵۸
  • data center، ۳۲، ۴۳، ۳۷۶
  • consistency
  • data schemas، ۱۶۴
  • in pipeline-based workflow، ۳۵۲
  • data set، ۱۲۶، ۲۴۳
  • of code، ۱۰
  • data structures، ۱۵۷، ۱۶۴
  • Consul (website)، ۱۰۰، ۱۶۷، ۲۴۶
  • database، ۱۳۰
  • consumer-driven contract testing (CDC)، ۳۳۵
  • Database Reliability Engineering (Campbell
  • consumers، ۱۳۸، ۲۵۵
  • and Majors)، ۱۶۵
  • DBaaS (Database as a Service)، ۳۰
  • dependency injection (DI) (see DI (dependency
  • DBDeploy (website)، ۱۶۴
  • injection))
  • dbmigrate (website)، ۱۶۴
  • deployment frequency, as a key metric for softDDD (Domain Driven Design)، ۲۸۴
  • ware delivery and operational performance,
  • DDNS (Dynamic DNS)، ۱۶۷
  • 9
  • .deb files، ۳۱۷، ۳۲۳
  • deployment manifest، ۱۶۲
  • DebianPreseed (website)، ۱۸۰، ۲۱۵
  • deployment packages، ۱۵۸
  • Debois, Patrick, xix
  • design smell، ۴۶
  • decentralized configuration، ۲۰۱
  • designers, in team workflow، ۳۴۱
  • declarative code
  • detection، ۳۸۱
  • about، ۳۹، ۴۴، ۴۶ DevOps, xix، ۲، ۳۱۳
  • reusing with modules، ۲۷۲ DI (dependency injection)، ۲۹۶-۲۹۹
  • testing combinations of، ۱۱۲ direct connection، ۳۲
  • testing variable، ۱۱۱ disaster recovery، ۳۷۹
  • declarative infrastructure languages، ۴۱
  • disposable secrets، ۱۰۴
  • declarative tests، ۱۱۱
  • DIY configuration registries، ۱۰۱
  • decoupling dependencies، ۲۹۷
  • DNS (Domain Name System)، ۱۶۷
  • dedicated integration test projects، ۳۱۱
  • Do Better As Code (website)، ۱۱۵
  • delivering، ۳۲۱-۳۳۸
  • Docker (website)، ۱۵۹
  • about، ۳۲۱ documentation, code as، ۴۷
  • building infrastructure projects، ۳۲۲ Dojo (website)، ۳۴۷
  • configuration and scripts for services، ۳۶ domain concepts، ۲۵۵، ۳۱۲
  • environments for، ۶۶ Domain Driven Design (DDD)، ۲۸۴
  • integrating projects، ۳۲۶-335 Domain Name System (DNS)، ۱۶۷
  • lead time, as a key metric for software deliv‐ doozerd (website)، ۱۰۰
  • ery and operational performance، ۹ DORA، ۹
  • packaging infrastructure code as artifacts, downstream dependencies، ۱۳۸، ۱۳۹
  • 323 Drone (website)، ۱۲۴
  • pipeline software and services، ۱۲۳-125 Dropwizard (website)، ۳۱۷
  • using repositories to deliver infrastructure DRY (Don't Repeat Tourself) principle، ۲۵۳
  • code، ۳۲۳-326 DSL (domain-specific language)، ۴۴
  • delivery-time project integration pattern,
  • dual persistent and ephemeral stack stages anti‐
  • 330-333 pattern، ۱۴۵
  • democratic quality, in pipeline-based workflow,
  • duplication, avoiding، ۲۵۳
  • 353 Dynamic DNS (DDNS)، ۱۶۷
  • dependencies
  • across component stacks، ۲۸۷-۲۹۹
  • as a script task، ۳۳۶

E

  • ECS (Amazon Elastic Container Services)، ۲۹,
  • circular، ۲۵۶ ۲۳۰، ۲۳۴
  • clarifying، ۱۱۳ EDGE model، ۱۷
  • decoupling، ۲۹۷ EDGE: Value-Driven Digital Transformation
  • isolating، ۱۱۳ (Highscmith, Luu and Robinson)، ۱۷
  • minimizing، ۱۱۳ efficiency, servers and، ۱۸۷
  • minimizing with definition code، ۲۹۷ EKS (Amazon Elastic Container Service for
  • scope used for stages، ۱۲۱ Kubernetes)، ۲۹، ۲۳۰، ۲۳۴
  • servers and، ۱۸۷ emergency fix process، ۳۵۴
  • using text fixtures to handle، ۱۳۷-141 encrypting secrets، ۱۰۲
  • Dependencies Complicate Testing InfrastrucEnsure That You Can Repeat Any Process prin‐
  • ture challenge، ۱۱۴ ciple، ۲۰
  • entr utility، ۱۰۷
  • 5 Lessons We've Learned Using AWS (website),
  • environment branches، ۷۱
  • 379
  • environments، ۶۵-۷۵
  • FKS (Fictional Kubernetes Service)، xx، ۳۶۲
  • about، ۶۵
  • Flyway (website)، ۱۶۴
  • building with multiple stacks، ۷۴
  • Foreman (website)، ۱۸۳
  • configuring، ۶۷
  • Fowler, Martin، ۴۴، ۱۱۶، ۱۴۱
  • consistency of، ۶۷
  • "Patterns for Managing Source Code
  • delivery، ۶۶
  • Branches"، ۳۴۸
  • multiple production، ۶۶
  • framework repository, as a source for servers,
  • patterns for building، ۶۸-۷۴
  • 171
  • Envoy (website)، ۲۴۶
  • Freeman, Steve
  • ephemeral instances، ۱۱۴
  • Growing Object-Oriented Software, Guided
  • ephemeral test stack pattern، ۱۴۳
  • by Tests، ۳۵۸
  • etcd (website)، ۱۰۰
  • frying server instances، ۱۸۶
  • eventual testing، ۱۰۷
  • FSI (Fictional Server Image)، xx، ۲۱۱
  • "Evolutionary Database Design" (Sadalage)، ۱۶۵ Function as a Service (FaaS) (see FaaS (Func‐
  • execitables، ۱۵۷
  • tion as a Service))
  • execution, as a script task، ۳۳۶
  • functionality, of testing، ۱۰۸
  • expand and contract pattern، ۳۷۲-۳۷۵
  • Extreme Programming (XP)، ۱۰۵

G

  • gateways، ۳۲

F

  • GCE Persistent Disk، ۳۰
  • FaaS (Function as a Service)
  • GDPR (website)، ۲۴۳
  • about، ۱۸۳ general file storage repository، ۳۲۵
  • deploying serverless applications, 163 general-purpose configuration registry prodinfrastructure for serverless, 246-248 ucts، ۱۰۰
  • serverless code runtimes، ۲۹ general-purpose languages، ۴۶
  • Fabric (website)، ۱۶۰
  • get_fixture() method، ۱۴۰
  • facade module pattern، ۲۷۴-۲۷۶، ۲۷۷، ۲۸۰، ۲۸۳
  • get_networking_subrange function، ۱۱۲
  • Facebook، ۳۰۵
  • get_vpc function، ۱۱۲
  • Facts and Fallacies of Software Engineering
  • Gillard-Moss, Peter، ۱۹۵
  • (Glass)، ۲۷۸ git-crypt (website)، ۱۰۲
  • failure mode، ۳۸۰
  • GitHub، ۱۲۳، ۱۲۴
  • failure, planning for، ۳۸۰
  • GitLab، ۱۲۴
  • "fan-in" pipeline design، ۳۳۲
  • GitOps (website)، ۱۲۵
  • Farley, David
  • GitOps methodology، ۳۵۱
  • Continuous Delivery، ۱۰۵، ۱۱۹ Given, When, Then format، ۱۱۱
  • fault tolerance, for multiple production envi‐ GKE (Google Kubernetes Engine)، ۲۹، ۲۳۰، ۲۳۴
  • ronments، ۶۶ Glass, Robert
  • FCS (Fictional Cloud Service)، xx، ۲۱۱
  • Facts and Fallacies of Software Engineering,
  • Feathers, Michael
  • 278
  • Working Effectively with Legacy Code، ۲۶۲ GoCD، ۹۴، ۱۲۴
  • feature branching، ۵۹
  • golden images، ۱۸۵
  • Feature Flags (see Feature Toggles)
  • "The Goldilocks Zone of Lightweight Architec‐
  • Feature Toggles، ۳۶۶
  • tural Governance"، ۱۷
  • files Google، ۹، ۳۰۵
  • configuration value، ۳۱۲ Google Cloud Deployment Manager (website),
  • project support، ۳۰۹ ۵۲
  • Fission (website)، ۲۴۷
  • Google Cloud Functions، ۲۹، ۲۴۷
  • Google Cloud Storage، ۳۰
  • infrastructure
  • Google Kubernetes Engine (GKE)، ۲۹، ۲۳۰، ۲۳۴
  • application-driven، ۱۵۶
  • Google ML Engine، ۲۹
  • automation tool registries، ۱۰۰
  • governance building projects، ۳۲۲
  • application clusters for، ۲۴۳
  • changing live، ۳۶۸-۳۸۴
  • channels, in pipeline-based workflow، ۳۵۳
  • cloud native، ۱۵۶، ۱۶۵
  • in pipeline-based workflow، ۳۵۲-۳۵۴
  • coding languages (see coding languages)
  • server images and، ۲۲۷
  • delivering، ۳۱۴
  • governance specialists
  • delivery pipelines، ۱۱۹-۱۲۵
  • as code writers، ۳۴۳
  • dividing into tractable pieces، ۱۱۳-۱۱۴
  • in team workflow، ۳۴۱
  • for builder instances، ۲۱۱
  • GPG (website)، ۸۲
  • for FaaS serverless، ۲۴۶-۲۴۸
  • Growing Object-Oriented Software, Guided by
  • immutable، ۳۵۱
  • Tests (Freeman and Pryce)، ۳۵۸
  • modularizing، ۲۵۶-۲۶۱
  • platforms (see platforms)

H

  • resources for، ۲۷-۳۳
  • safely changing، ۳۵۵-۳۸۴
  • hardcoded IP addresses، ۱۶۶
  • hardware architectures, server images for difsystem components of، ۲۳
  • ferent، ۲۲۶
  • testing before integration، ۳۱۶
  • HashiCorp، ۱۰۱
  • using scripts to wrap tools، ۳۳۵-۳۳۸
  • HCL configuration language، ۴۳
  • Infrastructure as Code
  • Helm (website)، ۱۶۲، ۳۱۸
  • about، ۱
  • Helm charts، ۴۵
  • benefits of، ۴
  • Heroku، ۲۶ core practices for، ۹
  • high-level infrastructure languages، ۵۵
  • defining، ۳۵
  • Highsmith, Jim
  • history of, xix
  • EDGE: Value-Driven Digital Transformaimplementation principles for defining، ۴۶
  • tion، ۱۷ using to optimize for change، ۴
  • Hirschfield, Rob، ۲۴۱
  • infrastructure domain entity pattern، ۲۸۰، ۲۸۳
  • Hodgson, Pete، ۳۶۸
  • infrastructure scripting، ۳۹
  • Honeycomb، ۱۲۷
  • infrastructure stacks، ۷۷-۱۰۴، ۱۲۹-۱۵۱
  • horizontal groupings، ۲۶۷
  • about، ۳۶، ۵۱
  • hostfile entries، ۱۶۷
  • building environments with multiple، ۷۴
  • hot-cloning servers، ۱۸۴
  • configuring servers in، ۵۴
  • HPE Container Platform (website)، ۲۳۱
  • example، ۱۲۹
  • Humble, Jez
  • high-level infrastructure languages، ۵۵
  • Continuous Delivery، ۱۰۵، ۱۱۹
  • life cycle patterns for test instances of,
  • Hunt, Craig
  • 142-149
  • TCP/IP Network Administration، ۳۳
  • low-level infrastructure languages، ۵۴
  • hybrid cloud، ۲۷
  • offline testing for، ۱۳۱
  • online testing for، ۱۳۴-۱۳۷
  • patterns and antipatterns for، ۵۶-۶۳

I

  • previewing changes، ۱۳۴
  • IaaS (Infrastructure as a Service)، ۲۴، ۲۵
  • sourc code for، ۵۳
  • idempotency، ۴۲
  • stack instances، ۵۳
  • immediate testing، ۱۰۷
  • infrastructure surgery، ۲۶۵، ۳۷۰-۳۷۲
  • immutable infrastructure، ۳۵۱
  • inotifywait utility، ۱۰۷
  • immutable server pattern، ۱۹۳، ۱۹۵-۱۹۷، ۳۲۹
  • Inspec (website)، ۱۳۵، ۱۷۸
  • imperative code، ۳۹، ۴۴، ۴۶
  • integration frequency، ۳۴۸
  • incremental changes، ۳۵۸
  • integration patterns، ۳۴۸
  • Lightweight Resource Provider (LWRP)، ۱۷۴
  • integration registry lookup pattern، ۲۹۴-۲۹۶
  • Linkerd (website)، ۲۴۶
  • integration tests، ۳۱۱
  • linking، ۳۲۷
  • "Introduction to Observability"، ۱۲۷
  • linting، ۱۳۲
  • "Inverse Conway Maneuver"، ۲۶۵
  • Liquibase (website)، ۱۶۴
  • IP addresses, hardcoded، ۱۶۶
  • load balancing rules، ۳۲
  • Iron Age، ۲
  • local testing، ۱۴۹
  • Istio (website)، ۲۴۶
  • local workstation, applying code from، ۳۴۴
  • iterative changes، ۳۵۸
  • Localstack (website)، ۱۱۵، ۱۳۳
  • locking data، ۳۸۲

J

  • LOM (lights-out management)، ۱۸۳
  • low-level infrastructure languages، ۵۴
  • Jacob, Adam, xix
  • JavaScript، ۴۶
  • LSP (Language Server Protocol)، ۱۰۷
  • Jenkins، ۹۴، ۱۲۳
  • Luu, Linda
  • JEOS (Just Enough Operating System)، ۲۱۵
  • EDGE: Value-Driven Digital Transforma‐
  • JSON، ۴۵ tion، ۱۷
  • LWRP (Lightweight Resource Provider)، ۱۷۴

K

  • Kanies, Luke, xix

M

  • Keep Parameters Simple design principle، ۷۸
  • MAAS (website)، ۱۸۳
  • KeePass (website)، ۸۲
  • Majors, Charity، ۶۹، ۱۲۵
  • Keeper (website)، ۸۲
  • Database Reliability Engineering، ۱۶۵
  • key-value pair، ۹۸
  • Make Everything Reproducible principle، ۱۴
  • key-value store، ۳۰، ۷۷، ۱۰۰
  • manual stack parameters antipattern، ۸۰-۸۲
  • Kim, Gene Martin, Karen
  • The Visible Ops Handbook، ۴
  • Value Stream Mapping، ۳۴۳
  • Kitchen-Terraform (website)، ۱۵۰
  • McCance, Gavin، ۱۶
  • kops (website)، ۲۳۱
  • Mean Time Between Failure (MTBF)، ۳۷۶
  • Kubeadm (website)، ۲۳۱
  • Mean Time to Recover (MTTR)، ۳۷۶
  • KubeCan، ۳۶۲
  • Mean Time to Restore (MTTR)، ۹
  • Kubeless (website)، ۲۴۷
  • Meszaros, Gerard
  • Kubernetes، ۲۳۱، ۲۳۷
  • xUnit Test Patterns، ۱۱۵
  • Kubernetes borg (website)، ۲۳۲
  • metrics, for software delivery and operational
  • Kubernetes Clusters، ۲۳۱
  • performance، ۹
  • kubespray (website)، ۲۳۱
  • MGs (Google Managed Instance Groups)، ۲۸
  • micro stack pattern، ۵۶، ۶۲
  • microrepo، ۳۰۷

L

  • Microsoft، ۳۰۵
  • language repository, as a source for servers، ۱۷۱ Minimize Variation principle، ۱۷-۱۹
  • Language Server Protocol (LSP)، ۱۰۷
  • modularity
  • languages (see coding languages)
  • designing for، ۲۵۲-۲۵۶
  • LastPass (website)، ۸۲
  • infrastructure and، ۲۵۶-۲۶۱
  • Law of Demeter، ۲۵۵
  • Molecule (website)، ۱۵۰
  • layering server images، ۲۲۶
  • monitoring
  • legacy silos، ۲۶۵
  • as a risk of testing in production، ۱۲۶
  • LeRoy, Jonny، ۱۷
  • as service mesh service، ۲۴۵
  • Lewis, James، ۲۵۴
  • Monolithic Stack
  • libraries, creating stack elements with، ۲۷۳
  • for packaged cluster solutions، ۲۳۴
  • Lightweight Governance، ۱۷
  • pipelines for، ۲۳۵-۲۳۸
  • using cluster as a service، ۲۳۳
  • one-time passwords، ۱۰۴
  • monolithic stack antipattern، ۵۶-۵۹
  • online image building، ۲۰۹، ۲۱۰-۲۱۲
  • monorepo، ۳۰۵، ۳۲۹، ۳۳۰
  • online testing، ۱۱۴، ۱۳۴-۱۳۷
  • moto (website)، ۱۱۵
  • Open Application Model (website)، ۲۸۵
  • Mountain Goat Software (website)، ۱۰۷
  • OpenFaaS (website)، ۲۴۷
  • .msi files، ۳۱۷، ۳۲۳
  • OpenShift (website)، ۲۳۱
  • MTBF (Mean Time Between Failure)، ۳۷۶
  • OpenStack Cinder، ۳۰
  • MTTR (Mean Time to Recover)، ۳۷۶
  • OpenStack Heat (website)، ۵۲
  • MTTR (Mean Time to Restore)، ۹
  • OpenStack Swift، ۳۰
  • multicloud، ۲۷
  • operability, of testing، ۱۱۰
  • multiple configuration registries، ۱۰۲
  • operating systems, server images for different,
  • multiple production environments، ۶۶
  • 225
  • multiple-environment stack antipattern، ۶۸
  • operations services، ۳۶
  • ORAS (OCI Registry As Storage)، ۳۲۴

N

  • orchestration, as a script task، ۳۳۶
  • organization
  • National Institute of Standards and Technology
  • (NIST)، ۲۵
  • about، ۳۰۳
  • nested stacks، ۲۷۲
  • configuration value files، ۳۱۲
  • Netflix، ۲۰۹، ۳۷۹
  • different code types، ۳۰۹-۳۱۳
  • network access rules (firewall rules)، ۳۲
  • managing infrastructure and application
  • network address blocks، ۲۶، ۳۲
  • code، ۳۱۳-۳۱۹
  • network boundaries، ۲۷۰
  • of code by domain concept، ۳۱۲
  • Network File System، ۳۰
  • of projects، ۳۰۳-۳۰۹
  • network resources، ۳۱
  • of repositories، ۳۰۳-۳۰۹
  • networked filesystems (shared network volorganizational governance, compliance with,
  • umes)، ۳۰
  • 208
  • Newman, Sam، ۱۱۹
  • OS package repositories, as a source for servers,
  • Nexus (website)، ۳۲۴
  • 171
  • NFRs (Non-Functional Requirements)، ۱۰۸
  • Osterling, Mike
  • NIST (National Institute of Standards and
  • Value Stream Mapping، ۳۴۳
  • Technology)، ۲۵
  • outcomes, testing، ۱۳۷
  • Nomad (website)، ۲۳۲
  • output, as a pipeline stage، ۱۲۱
  • nonstandard package, as a source for servers,
  • over-investing، ۱۲۵
  • 172
  • Normalization of Deviance، ۸

P

  • NuGet، ۳۲۳ PaaS (Platform as a Service)، ۲۶، ۲۹
  • packaged cluster distribution، ۲۳۱

O

  • packages
  • as a script task، ۳۳۶
  • O'Reilly (website)، ۳۵۲
  • obfuscation module antipattern، ۲۷۶
  • installing common، ۲۰۸
  • object storage، ۳۰
  • Packer (website)، ۲۰۹
  • observability
  • pair programming، ۱۰۷
  • as a risk of testing in production، ۱۲۷ Pants (website)، ۳۲۹
  • as service mesh service، ۲۴۵ parallel instances، ۳۶۱
  • OCI Registry As Storage (ORAS)، ۳۲۴
  • parameter files، ۸۸
  • Octopus Deploy (website)، ۳۱۸
  • parameters, handling secrets as، ۱۰۲-۱۰۴
  • offline image building، ۲۰۹، ۲۱۳
  • Parsons, Rebecca، ۴۴
  • offline testing، ۱۱۴، ۱۳۱
  • patching servers، ۱۹۷
  • 1Password (website)، ۸۲
  • path to production، ۶۶
  • path to production branching patterns، ۳۴۸
  • persistent instances، ۱۱۴
  • patterns persistent test stack pattern، ۱۴۲
  • application group stack، ۵۶، ۵۹
  • personal infrastructure instances، ۳۴۷
  • apply-time project integration، ۳۳۳-۳۳۵
  • phoenix server، ۳۵۱
  • blue-green deployment، ۳۷۵
  • physical servers، ۲۸
  • build-time project integration، ۳۲۷-۳۳۰
  • pipeline stack parameters pattern، ۸۰، ۸۲، ۹۳-۹۶
  • bundle module، ۲۷۶، ۲۷۸، ۲۸۳
  • pipelines
  • canary development، ۳۶۴
  • about، ۹۵
  • continuous configuration synchronization,
  • for Monolithic application cluster stacks,
  • 193، ۱۹۷ ۲۳۵-۲۳۸
  • continuous stack reset، ۱۴۷
  • governance in pipeline-based workflow,
  • defined، xx
  • 352-354
  • delivery-time project integration، ۳۳۰-۳۳۳
  • server images and، ۲۲۱
  • ephemeral test stack، ۱۴۳
  • stages of، ۱۲۰
  • expand and contract، ۳۷۲-۳۷۵
  • tools for، ۱۵۰
  • facade module، ۲۷۴-۲۷۶، ۲۷۷، ۲۸۰، ۲۸۳
  • PKS (Pivotal Container Services) (website)، ۲۳۱
  • for building environments، ۶۸-۷۴
  • platform elements، ۱۲۲
  • for configuring stacks، ۸۰-۹۹
  • platform registry services، ۱۰۱
  • for infrastructure stacks، ۵۶-۶۳
  • platform repository, as a source for servers، ۱۷۱
  • for stack components، ۲۷۴-۲۸۴
  • platforms، ۲۳-۳۳
  • immutable server، ۱۹۳، ۱۹۵-۱۹۷، ۳۲۹
  • about، ۲۳
  • infrastructure domain entity، ۲۸۰، ۲۸۳
  • as components of infrastructure systems، ۲۴
  • integration، ۳۴۸
  • dynamic، ۲۵
  • integration registry lookup، ۲۹۴-۲۹۶
  • infrastructure system components، ۲۳
  • micro stack، ۵۶، ۶۲
  • server images for different، ۲۲۵
  • path to production branching، ۳۴۸
  • Please (website)، ۳۲۹
  • periodic stack rebuild، ۱۴۶
  • Plumi for Teams (website)، ۳۴۶
  • persistent test stack، ۱۴۲
  • polycloud، ۲۷
  • pipeline stack parameters، ۸۰، ۸۲، ۹۳-۹۶
  • practice، xx
  • pull server configuration، ۱۷۳، ۱۹۵، ۲۰۰
  • primitives، ۲۷
  • push server configuration، ۱۷۳، ۱۹۳، ۱۹۸
  • principle، xx
  • resource matching، ۲۸۸-۲۹۱
  • principle of least knowledge (see Law of Deme‐
  • reusable stack، ۷۲-۷۴
  • ter)
  • scripted parameters، ۸۰، ۸۲، ۸۴-۸۷
  • principle of least privilege، ۳۱
  • service stack، ۵۶، ۶۰-۶۲
  • The Principles of Product Development Flow
  • stack configuration files، ۸۰، ۸۷-۹۰
  • (Reinerstein)، ۳۵۶
  • stack data lookup، ۲۹۱-۲۹۳، ۲۹۶
  • production, pushing incomplete changes to,
  • stack environment variables، ۸۲-۸۴
  • 361-368
  • stack parameter registry، ۹۰، ۹۶-۹۹، ۲۹۶
  • programmable, imperative infrastructure lan‐
  • wrapper stack، ۷۱، ۷۴، ۸۰، ۹۰-۹۳
  • guages، ۴۳
  • "Patterns for Managing Source Code Branches"
  • progressive deployment, as a risk of testing in
  • (Fowler)، ۳۴۸
  • production، ۱۲۷
  • PCI standard، ۱۳۹، ۲۴۳، ۲۶۹
  • progressive testing، ۱۱۴، ۱۱۵-۱۱۹، ۳۱۵
  • performance
  • project support files، ۳۰۹
  • application clusters and، ۲۴۱
  • projects
  • of testing، ۱۰۹
  • integrating، ۳۲۶-۳۳۵
  • optimizing، ۲۰۸
  • multiple، ۳۰۸
  • perimeterless security، ۳۱
  • organization of، ۳۰۳-۳۰۹
  • periodic stack rebuild pattern، ۱۴۶
  • promotion, as a script task، ۳۳۶
  • providers، ۱۳۸، ۲۵۵
  • using repositories to deliver infrastructure
  • provisioning scripts، ۸۵
  • code، ۳۲۳-۳۲۶
  • proxies، ۳۲
  • resource matching pattern، ۲۸۸-۲۹۱
  • Pryce, Nat resource tags، ۱۶۷
  • Growing Object-Oriented Software, Guided
  • resources
  • by Tests، ۳۵۸ about، ۲۷
  • pull server configuration pattern، ۱۷۳، ۱۹۵، ۲۰۰
  • compute، ۲۸
  • Pulumi، ۳۹، ۴۳، ۵۲، ۲۹۲، ۳۷۲
  • network، ۳۱
  • Puppet, xix، ۳۸، ۴۵، ۱۷۲
  • storage، ۲۹
  • Puppet Cloud Management (website)، ۵۲
  • reusability
  • PuppetDB (website)، ۱۰۰
  • as reason for modularizing stacks، ۲۷۱
  • Puppetmaster، ۱۷۳
  • in pipeline-based workflow، ۳۵۲
  • push server configuration pattern، ۱۷۳، ۱۹۳,
  • of code، ۱۰
  • 195، ۱۹۸
  • reusable stack pattern، ۷۲-۷۴
  • Python، ۴۶ risks, managing for testing in production، ۱۲۶
  • Robert, Mike

Q

  • "Serverless Architecture"، ۲۴۷
  • Robinson, David
  • quality
  • of code، ۱۰۸
  • EDGE: Value-Driven Digital Transformaprioritizing over speed، ۸
  • tion، ۱۷
  • roles
  • server images for different، ۲۲۶

R

  • servers، ۱۷۵
  • Rancher RKS (website)، ۲۳۱
  • rollback, of code، ۳۸
  • Rebar (website)، ۱۸۳
  • routes، ۳۲
  • Red Hat Kickstart (website)، ۱۸۰، ۲۱۵
  • routing, as service mesh service، ۲۴۵
  • refactoring، ۱۴۱، ۳۵۹
  • .rpm files، ۳۱۷، ۳۲۳
  • Refactoring Databases (Ambler and Sadalage),
  • Ruby، ۴۶
  • 165 rule of composition، ۲۵۴
  • reference data، ۱۵۷
  • rule of three، ۲۷۸
  • registries
  • configuration، ۹۶، ۹۹-۱۰۲
  • infrastructure automation tool، ۱۰۰ S
  • multiple configuration، ۱۰۲ SaaS services، ۱۲۴
  • single configuration، ۱۰۲ Sadalage, Pramod
  • stack parameter، ۹۶ "Evolutionary Database Design"، ۱۶۵
  • reheating server images، ۲۱۶
  • Refactoring Databases، ۱۶۵
  • Reinerstein, Donald G.
  • Salt Cloud (website)، ۵۲
  • The Principles of Product Development Salt Mine (website)، ۱۰۰
  • Flow، ۳۵۶ Saltstack، ۳۸، ۱۷۲، ۲۰۱
  • reloading data، ۳۸۳
  • scalability
  • replicating data، ۳۸۳
  • application clusters and، ۲۴۱
  • repositories
  • for multiple production environments، ۶۶
  • general file storage repository، ۳۲۵ of testing، ۱۰۹
  • multiple، ۳۰۸ scope
  • organization of، ۳۰۳-309 of change, reducing، ۳۵۵-۳۶۰
  • source code repository، ۳۲۵ of components tested in stages، ۱۲۱
  • specialized artifact repository، ۳۲۴ of dependencies used for stages، ۱۲۱
  • tool-specific repository، ۳۲۵ scripted parameters pattern، ۸۰، ۸۲، ۸۴-۸۷
  • scripts
  • for building server images، ۲۱۲
  • delivery stage for، ۲۲۴
  • infrastructure، ۳۹
  • for different hardware architectures، ۲۲۶
  • using to create servers، ۱۸۱
  • for different infrastructure platforms، ۲۲۵
  • using to wrap infrastructure tools، ۳۳۵-۳۳۸
  • for different operating systems، ۲۲۵
  • wrapper، ۳۳۷
  • for different roles، ۲۲۶
  • SDK (Software Development Kit)، ۳۹
  • governance and، ۲۲۷
  • SDN (Software Defined Networking)، ۳۱
  • handling major changes with، ۲۲۰
  • seam، ۲۶۲ layering، ۲۲۶
  • secretless authorization، ۱۰۳
  • origin content for، ۲۱۴-۲۱۶
  • secrets provenance of، ۲۱۵
  • about، ۹۵
  • reheating، ۲۱۶
  • disposable، ۱۰۴
  • sharing code across، ۲۲۸
  • encrypting، ۱۰۲
  • stock، ۲۱۵
  • handling as parameters، ۱۰۲-۱۰۴
  • test stage for، ۲۲۳
  • injecting at runtime، ۱۰۳
  • testing، ۲۲۱
  • management of، ۹۹
  • tools for building، ۲۰۹
  • management service، ۳۰
  • using multiple، ۲۲۵-۲۲۸
  • security using scripts to build، ۲۱۲
  • as service mesh service، ۲۴۵
  • versioning، ۲۱۷
  • of testing، ۱۰۹
  • server instances
  • security hardening، ۲۰۸
  • configuring new، ۱۸۵-۱۸۹
  • segregation
  • creating new، ۱۷۹-۱۸۳
  • application clusters and، ۲۴۱
  • frying، ۱۸۶
  • for multiple production environments، ۶۷
  • hand-building new، ۱۸۰
  • of data، ۳۸۲
  • replacing، ۲۰۳
  • semantic versioning، ۲۱۸
  • stopping and starting، ۲۰۲
  • Sentinel (website)، ۱۲۴
  • updating، ۲۱۸
  • separate material, as a source for servers، ۱۷۲ Server Message Block، ۳۰
  • separation of concerns، ۱۷۴
  • "Serverless Architecture" (Robert)، ۲۴۷
  • sero-downtime changes، ۳۷۵
  • serverless concept، ۲۹، ۲۴۷
  • server clusters، ۲۸، ۱۶۰
  • Servermaker, xxi، ۱۸، ۳۹، ۵۴، ۱۷۴، ۱۸۹، ۲۱۲، ۲۳۵
  • server code
  • servers، ۱۶۹-۱۹۰، ۱۹۱-۲۰۵
  • about، ۱۵۷، ۱۷۳
  • about، ۱۶۹، ۱۹۱
  • applying، ۱۹۸-۲۰۲
  • applying server configuration when creat‐
  • designing، ۱۷۴
  • ing، ۱۸۹
  • promoting، ۱۷۵
  • change management patterns، ۱۹۲-۱۹۷
  • testing، ۱۷۶-۱۷۹
  • configuration code for، ۱۷۲
  • versioning، ۱۷۵
  • configuration elements، ۳۶
  • server images
  • configuring in stacks، ۵۴
  • about، ۲۰۷
  • configuring platforms to automatically cre‐
  • across teams، ۲۲۰
  • ate، ۱۸۲
  • baking، ۱۸۷، ۲۱۶
  • deploying applications to، ۱۵۹
  • build stage for، ۲۲۲-۲۲۳
  • hot-cloning، ۱۸۴
  • building، ۲۰۸-۲۱۶
  • life cycle events، ۲۰۲-۲۰۵
  • building from scratch، ۲۱۵
  • patching، ۱۹۷
  • changing، ۲۱۶-۲۲۱
  • prebuilding، ۱۸۳
  • configuring، ۱۸۶
  • recovering failed، ۲۰۴
  • creating clean، ۱۸۵
  • roles، ۳۶، ۱۷۵، ۲۰۹
  • defined، ۳۶
  • snapshots، ۱۸۴
  • source for، ۱۷۱ SRP (single responsibility principle)، ۲۵۴
  • using in stacks، ۲۵۹-260 stack components، ۲۷۱-۲۸۵
  • using networked provisioning tools to build, about، ۲۷۱، ۲۸۷
  • 182 dependencies across، ۲۸۷-۲۹۹
  • using scripts to create، ۱۸۱ infrastructure languages for، ۲۷۲-۲۷۴
  • using stack management tools to create، ۱۸۱ patterns for، ۲۷۴-۲۸۴
  • what's on، ۱۷۰ using servers in، ۲۵۹-۲۶۰
  • Serverspec (website)، ۱۷۸
  • versus stacks as components، ۲۵۷-۲۵۸
  • service discovery، ۱۶۶
  • stack configuration files pattern، ۸۰، ۸۷
  • Service Level Agreements (SLAs)، ۳۴۰
  • stack data lookup pattern، ۲۹۱-۲۹۳، ۲۹۶
  • Service Level Indicators (SLIs)، ۳۴۰
  • stack environment variables pattern، ۸۲-۸۴
  • Service Level Objectives (SLOs)، ۳۴۰
  • stack instances
  • service mesh، ۳۳، ۲۴۴-۲۴۶
  • about، ۵۳، ۷۷
  • service migration، ۳۶۴
  • example of stack parameters، ۷۹
  • service stack pattern، ۵۶، ۶۰-۶۲
  • handling secrets as parameters، ۱۰۲-۱۰۴
  • shared-nothing architecture، ۲۶۱
  • patterns for configuring stacks، ۸۰-۹۹
  • sharing, as reason for modularizing stacks، ۲۷۱
  • using stack parameters to create unique
  • shellcheck (website)، ۳۳۷
  • identifiers، ۷۹
  • shift left، ۳۵۳
  • stack management tools, using to create
  • ShopSpinner، ۲۵۳-۲۶۲، ۲۶۶، ۲۷۳، ۲۸۷، ۲۹۶، ۳۱۲,
  • servers، ۱۸۱
  • 326، ۳۳۰-335، ۳۵۳، ۳۵۶، ۳۵۸، ۳۶۴-368 stack orchestration script، ۸۴
  • sidecar، ۱۶۷
  • stack parameter registries، ۹۶
  • Simian Army، ۳۷۹
  • stack parameter registry pattern، ۹۰، ۹۶-۹۹، ۲۹۶
  • single configuration registries، ۱۰۲
  • stack paremeters, creating unique identifiers
  • single responsibility principle (SRP)، ۲۵۴
  • using، ۷۹
  • Site Reliability Engineers (SREs)، ۳۵۳
  • stack tool، ۹۶
  • SLAs (Service Level Agreements)، ۳۴۰
  • Stackmaker، xx
  • SLIs (Service Level Indicators)، ۳۴۰
  • StackReference (website)، ۲۹۲
  • SLOs (Service Level Objectives)، ۳۴۰
  • State of DevOps Report (see Accelerate State of
  • smell، ۴۶ DevOps Report)
  • Smith, Derek A.، ۱۹۶
  • static code analysis
  • snowflake systems، ۱۵
  • offline، ۱۳۲
  • Software Defined Networking (SDN)، ۳۱
  • with APIs، ۱۳۳
  • software delivery pipeline، ۱۲۳-۱۲۵
  • storage resources، ۲۹
  • Software Development Kit (SDK)، ۳۹
  • Strangler Application (website)، ۱۴۱
  • Solaris JumpStart (website)، ۱۸۰، ۲۱۵
  • structured data storage، ۳۰
  • some-tool command، ۸۷
  • Subnet، ۲۶
  • sops (website)، ۱۰۲
  • support, in team workflow، ۳۴۱
  • source code branches, in workflows، ۳۴۸
  • Swiss Cheese Testing Model، ۱۱۸
  • source code repository، ۱۲۴، ۳۲۵
  • syntax checking، ۱۳۲
  • Soylent Green، ۳۴۰
  • Spafford, George
  • The Visible Ops Handbook، ۴

T

  • Taraporewalls, Sarah، ۱۰۸
  • spaghetti module antipattern، ۲۸۰-۲۸۳
  • Taskcat (website)، ۱۳۵
  • specialized artifact repository، ۳۲۴
  • TCP/IP Network Administration (Hunt)، ۳۳
  • speed TDD (Test Driven Development)، ۱۰۵
  • prioritizing over quality، ۸ Team City (website)، ۱۲۳
  • servers and، ۱۸۷ team workflows، ۳۳۹-۳۵۴
  • SREs (Site Reliability Engineers)، ۳۵۳
  • about، ۳۳۹
  • applying code to infrastructure، ۳۴۴ Testing Infrastructure Code Is Slow challenge,
  • governance in pipeline-based workflow، ۱۱۳-۱۱۴
  • 352-354 Tests for Declarative Code Often Have Low
  • measuring effectiveness of، ۳۴۰ Value challenge، ۱۱۰-۱۱۳
  • people، ۳۴۰-343 tflint (website)، ۱۳۲
  • preventing configuration drift، ۳۴۹ ThoughtWorks، ۱۲۴
  • source code branches in، ۳۴۸ tight coupling، ۱۵۰
  • technical debt، ۳
  • timeboxed methodologies، ۱۰۶
  • Terra، ۲۷۲، ۲۹۲
  • Tinkerbell (website)، ۱۸۳
  • Terraform، ۳۸، ۴۳، ۴۵، ۵۲، ۵۳، ۷۳، ۱۰۱، ۲۹۰، ۳۷۰ tire fire، ۱
  • Terraform Cloud، ۱۲۴، ۳۴۶
  • Tomcat، ۱۷۴، ۱۹۲
  • terraform fmt command، ۱۳۲
  • tool-specific repository، ۳۲۵
  • terraform mv command، ۳۷۲
  • toolmakers
  • Terraform Registry (website)، ۳۲۵
  • as code writers، ۳۴۳
  • Terraform state locking، ۳۴۵
  • in team workflow، ۳۴۱
  • Terragrunt (website)، ۹۳
  • tools
  • Terratest (website)، ۱۳۵، ۱۷۸
  • choosing for externalized configuration، ۳۶
  • test doubles، ۱۱۳، ۱۳۹
  • for building server images، ۲۰۹
  • Test Driven Development (TDD)، ۱۰۵
  • for test orchestration، ۱۵۰
  • Test Kitchen (website)، ۱۵۰
  • traceability, of code، ۳۷
  • test pyramid، ۱۱۶-۱۱۸
  • traffic, testing and، ۱۲۶
  • testability, as reason for modularizing stacks,
  • transcrypt (website)، ۱۰۲
  • 271 transparency, of code، ۱۰
  • testers TravisCI (website)، ۱۲۴
  • as code writers، ۳۴۳ trigger, as a pipeline stage، ۱۲۰
  • in team workflow، ۳۴۱ troubleshooting, as service mesh service، ۲۴۵
  • testing Turing-complete languages، ۴۲
  • applications with infrastructure، ۳۱۵ twelve-factor methodology (website)، ۱۵۶، ۳۸۲
  • as a script task، ۳۳۶ TypeScript، ۴۶
  • combinations of declarative code، ۱۱۲
  • cross-project، ۳۱۰
  • designing and، ۲۵۶

U

  • under-investing، ۱۲۵
  • eventual، ۱۰۷ unit tests، ۱۱۶
  • for downstream dependencies، ۱۳۹ unknown unknowns، ۱۲۶
  • immediate، ۱۰۷ unshared module antipattern، ۲۷۷
  • infrastructure before integrating، ۳۱۶ upstream dependencies، ۱۳۸
  • integration، ۳۱۱ user partitioning، ۳۶۴
  • local، ۱۴۹ users
  • offline، ۱۱۴ as code writers، ۳۴۲
  • online، ۱۱۴ in team workflow، ۳۴۱
  • orchestrating، ۱۴۹-151 testing and، ۱۲۵
  • outcomes، ۱۳۷
  • progressive، ۱۱۴، ۱۱۵-۱۱۹، ۳۱۵
  • server code، ۱۷۶-179 V
  • server images، ۲۲۱ Vagrant (website)، ۱۵۰
  • using fixtures to handle dependencies, validation rules، ۳۶
  • 137-141 value stream mapping، ۳۴۳
  • variable declarative code، ۱۱۱ Value Stream Mapping (Martin and Osterling),
  • with mock APIs، ۱۳۳ ۳۴۳
  • Vaughan, Diane، ۸
  • VCS (version control system)، ۳۷
  • Willis, John, xix
  • versioning Windows Containers (website)، ۱۵۹
  • server code، ۱۷۵ Windows installation answer file (website)، ۱۸۰,
  • server images، ۲۱۷ ۲۱۵
  • vertical groupings، ۲۶۷
  • Working Effectively with Legacy Code (FeathVirtual Private Cloud (VPC)، ۲۶, ۳۲
  • ers)، ۲۶۲
  • virtual private networks (VPNs)، ۳۲
  • workload percentage، ۳۶۴
  • virtualization technology، ۲۶
  • wrapper scripts, simplifying، ۳۳۷
  • visibility, of code، ۳۸
  • wrapper stack pattern، ۷۱، ۷۴، ۸۰، ۹۰-۹۳
  • The Visible Ops Handbook (Kim, Spafford and
  • Behr)، ۴
  • Visual Basic for Applications، ۳۷

X

  • XP (Extreme Programming)، ۱۰۵، ۱۱۶
  • VLANs، ۲۶، ۴۳، ۲۸۷
  • xUnit Test Patterns (Meszaros)، ۱۱۵
  • VMs (virtual machines)، ۱۶، ۲۸
  • VMware، ۱۶، ۲۳، ۱۶۹، ۲۰۸
  • Vocke, Ham، ۱۱۶

Y

  • VPC (Virtual Private Cloud)، ۲۶، ۳۲
  • YAGNI ("You Aren't Gonna Need It")، ۲۷۸
  • VPNs (virtual private networks)، ۳۲
  • YAML، ۴۳، ۴۵

W

  • Z
  • Walking skeleton، ۳۵۸
  • zero-downtime deployment, as a risk of testing
  • Weave Cloud (website)، ۱۶۲، ۳۴۶
  • in production، ۱۲۷
  • WeaveWorks (website)، ۱۲۵، ۳۴۶
  • zero-trust security، ۳۱، ۲۷۰
  • web server container cluster، ۱۲۹
  • Zookeeper (website)، ۱۰۰
  • wedged stacks، ۱۴۳

درباره نویسنده

Kief Morris (he/him) مدیر کلود مهندسی جهانی در ThoughtWorks است. او گفت‌وگوها را در نقش‌ها، مناطق و صنایع در شرکت‌هایی از enterpriseهای جهانی تا startupهای مرحله اولیه هدایت می‌کند. از کار و گفتگو با افراد برای کاوش practiceهای مهندسی بهتر، اصول طراحی معماری و practiceهای تحویل برای ساخت سیستم‌ها روی cloud لذت می‌برد.

Kief اولین سیستم آنلاین خود، یک bulletin board system (BBS) در فلوریدا در اوایل دهه ۱۹۹۰، را اجرا کرد. بعد در برنامه MSc علوم کامپیوتر دانشگاه تنسی ثبت‌نام کرد چون آسان‌ترین راه برای گرفتن اتصال اینترنت واقعی به نظر می‌رسید. پیوستن به تیم مدیریت سیستم بخش CS او را در معرض مدیریت صدها ماشین با انواع مختلف Unix قرار داد.

وقتی حباب dot-com شروع به inflate کردن، Kief به لندن رفت، جذب‌شده به ترکیب چندفرهنگی صنایع و افراد. هنوز آنجاست، با همسر، پسر و گربه‌اش زندگی می‌کند.

بیشتر شرکت‌هایی که Kief قبل از ThoughtWorks برایشان کار کرد post-startup بودند و به دنبال ساخت و scale بودند. عناوینی که به او داده شده یا خودش گذاشته شامل Software Developer، Systems Administrator، Deputy Technical Director، R&D Manager، Hosting Manager، Technical Lead، Technical Architect، Consultant و Director of Cloud Engineering است.

کولوفون

حیوان روی جلد Infrastructure as Code کرکس Rüppell (Gyps rueppellii) است، بومی منطقه ساحل آفریقا (منطقه جغرافیایی که به‌عنوان گذار بین صحرای بزرگ آفریقا و ساوانا عمل می‌کند). به افتخار کاوشگر و جانورشناس آلمانی قرن نوزدهم Eduard Rüppell نام‌گذاری شده.

پرنده بزرگی است (با wingspan ۷–۸ فوت و وزن ۱۴–۲۰ پوند) با پرهای قهوه‌ای رگه‌دار و گردن و سر مایل به زرد-سفید. مانند همه کرکس‌ها، این گونه گوشت‌خوار است و تقریباً منحصراً از لاشه تغذیه می‌کند. از talon و منقار تیز برای پاره کردن گوشت از لاشه استفاده می‌کنند و روی زبانشان خارهای رو به عقب دارند تا استخوان‌ها را کاملاً تمیز کنند. معمولاً ساکت‌اند، اما پرندگان بسیار اجتماعی‌اند که در محل لانه‌گذاری colony یا هنگام جنگیدن روی غذا فریاد squealing بلند می‌دهند.

کرکس Rüppell یک‌همسری است و برای زندگی جفت می‌گیرد که می‌تواند ۴۰–۵۰ سال طول بکشد. جفت‌های تولیدمثل لانه‌شان را نزدیک صخره‌ها می‌سازند، از چوب با پوشش علف و برگ (و اغلب چند سال استفاده می‌کنند). هر سال فقط یک تخم گذاشته می‌شود — وقتی فصل تولیدمثل بعدی شروع می‌شود، جوجه تازه مستقل می‌شود. این کرکس خیلی سریع پرواز نمی‌کند (حدود ۲۲ mph)، اما تا ۹۰ مایل از لانه برای غذا جستجو می‌کند.

کرکس‌های Rüppell بالاترین پرندگان پروازکننده ثبت‌شده‌اند؛ شواهدی از پرواز ۳۷,۰۰۰ فوت بالای سطح دریا وجود دارد، به‌اندازه ارتفاع هواپیماهای تجاری. هموگلوبین خاصی در خونشان دارند که جذب اکسیژن را در ارتفاعات بالا کارآمدتر می‌کند.

این گونه در معرض خطر (endangered) تلقی می‌شود و جمعیت‌ها در حال کاهش است. اگرچه از دست دادن habitat یک عامل است، جدی‌ترین تهدید مسمومیت است. کرکس حتی هدف مورد نظر نیست: کشاورزان اغلب لاشه دام را مسموم می‌کنند تا با شکارچیانی مانند شیر و کفتار تلافی کنند. چون کرکس‌ها وعده را با دید شناسایی و در دسته جمع می‌شوند، هر بار صدها پرنده کشته می‌شوند. بسیاری از حیوانات روی جلدهای O'Reilly در معرض خطرند؛ همه آن‌ها برای جهان مهم‌اند.

تصویر رنگی اثر Karen Montgomery، بر اساس حکاکی سیاه‌وسفید از Cassell's Natural History. فونت‌های جلد Gilroy Semibold و Guardian Sans هستند. فونت متن Adobe Minion Pro؛ فونت سرخط‌ها Adobe Myriad Condensed؛ و فونت کد Dalton Maag's Ubuntu Mono است.


محتوای بیشتری از اینجا وجود دارد.

تجربه کتاب‌ها، ویدیوها، دوره‌های آموزش آنلاین زنده و بیشتر از O'Reilly و ۲۰۰+ شریک ما — همه در یک مکان.

بیشتر بدانید در oreilly.com/online-learning

©۲۰۱۹ O'Reilly Media, Inc. O'Reilly علامت تجاری ثبت‌شده O'Reilly Media, Inc. است. | ۱۷۵