Сьогодні Amazon Web Services (AWS) є найбільшим провайдером хмарних сервісів. За даними Amazon кількість активних користувачів AWS перевищує 1 000 000. Їх послугами користуються як величезні гіганти, такі як Netflix, Linkedin, Facebook, Adobe, Twitter, так і стартапи чи маленький бізнес. Підрахувати точну кількість сервісів, які надають AWS, важко. За деякими даними станом на січень 2020 року їх більш, ніж 280. 

Було би дивно, якщо б AWS не мали нативного механізму, який автоматично створює ресурси. На щастя, такий механізм є, і реалізовний він в такому сервісі, як CloudFormation. Описувати інфраструктуру в CloudFormation доволі просто, та цього не достатньо. У цій статті ми розповімо про найкращі практики запропоновані AWS відносно CloudFormation і роз’яснимо, як їх ефективно використовувати у роботі.

Що таке CloudFormation і навіщо він потрібен?

CloudFormation – це сервіс Amazon, який дозволяє створити інфраструктуру в Amazon, описавши її тестом у  форматі YAML, JSON. У файлі ви описуєте ресурси, які потрібно створити і залежності між ними.

Перш за все завдяки CloudFormation вам нічого не потрібно документувати, оскільки все вже задокументовано в коді. Все створюється автоматично, поки ви п’єте каву. А основне – AWS сам знає, в якій послідовності краще створювати та видаляти ресурси. Завдяки цьому у вас не буде таких ситуацій, коли ви видалили якийсь шматок інфраструктури, а про його залежності забули. CloudFormation робить це за вас. 

Ви пишете код у себе на комп’ютері, далі заливаєте його в S3 bucket або напряму кладете у CloudFormation, і він створює стек із ресурсами, які були описані в темплейті. В результаті у вашій консолі залишається CloudFormation ресурс, який ви можете менеджити. Коли вам потрібно щось оновити, ви йдете у конкретний stack і згодовуєте йому новий темплейт.

З яких секцій складається CloudFormation

  1. AWSTemplateFormatVersion
  2. Description
  3. Metadata
  4. Parameters
  5. Mappings
  6. Conditions
  7. Transform
  8. Resources
  9. Output

Лише одна секція в темплейті CloudFormation є required – це Resources, але якщо користуватись лише нею, то у вас буде величезна купа хардкоду і ваші темплейти будуть, м’яко кажучи, огидними.

Як же деякі із перечислених секцій можуть зробити життя тих, хто ними користується, набагато простішим? У своїй статті про найкращі практики в CloudFormation AWS розділили їх на три блоки: Планування та організація (Planning and organizing), створення темплейтів (Creating templates) та управління стеками (Managing stacks). У середині кожного блоку є по 6 пунктів, які ми розглянемо детальніше.

Planning and organizing 

Organize Your Stacks by Lifecycle and Ownership

Ви можете запхати все в один CloudFormation Stack – конфігурації мереж, s3 бакети, різного роду кластери і т.д. Однак такий підхід може призвести до певних проблем. Напевно всі, хто колись використовував CloudFormation, стикались із ситуацією, коли створені за допомогою CloudFormation ресурси модифікувались мануально через консоль чи aws cli якимось колегою. Після цього, коли ви намагались оновити стеки, вони зависали, тому їх доводилось видаляти і створювати знову. Так от, якщо у вас все буде в одному стеку, то ймовірність того, що вам доведеться перестворювати стек, дуже висока. Тому варто розділяти критичні ресурси із менш критичними.

Use Cross-Stack References to Export Shared Resources

Тут ми поговоримо про доступ до даних з одного стеку в іншому. Наприклад, коли ми створюємо SecurityGroup, нам потрібно вказати VPC ID, до якої буде прив’язана ця група. У нас є вибір, або хардкодити ці значення, що апріорі не правильно, або зробити Export змінної в батьківському темплейті та імпортувати її в дочірньому за допомогою функції Fn::ImportValue.

ImportValue-function

Use IAM to Control Access

IAM – це сервіс, який дозволяє зробити розмежування доступів для користувачів, ролей та користувацьких груп до ресурсів AWS. Ви можете використовувати IAM з CloudFormation для того, щоб вказати, що саме може робити користувач з CloudFormation: що він може переглядати, створювати, видаляти і т.д. Окрім того, будь-який користувач, який використовує CloudFormation, повинен мати права на створення ресурсів, описаних в його темплейті.

Reuse Templates to Replicate Stacks in Multiple Environments

Щоб ваші темплейти можна було використовувати, користуйтесь такими секціями, як Parameters, Mappings та Conditions. Це дозволить максимально кастомізувати ваші стеки під час їх створення. До прикладу, якщо ви створюєте EC2 інстанси в різних регіонах з одного і того ж образу, то ідентифікаційні номери (ID) Amazon Machine Image (AMI) будуть різні, тому хардкодом тут не обійдешся. Вийти з ситуації допоможе секція Mapping і функція AWS::Region. Також вам, напевно, цікаво мати середовище, наближене до продуктового (production), однак у розробницькому (development) середовищі часто немає великого навантаження, і там не потрібні великі потужності. Тобто в параметрах ви можете задати, AllowedValues, наприклад, prd, stg, dev, а в секції Mapping вказати, що такий-то тип відповідає такому-то значенню середовища.

Verify Quotas for All Resource Types

Це лише офіційна позиція AWS. Насправді, нонсенс ходити і перевіряти, чи достатньо у вас квот, маючи автоматизований процес розгортання. Уже існують підходи, які дозволяють відслідковувати ваші квоти і нотифікувати у разі досягнення певних порогів. З цього приводу рекомендую звернути увагу на утиліту awslimitchecker.

Use Nested Stacks to Reuse Common Template Patterns

Ви можете відокремити загальні компоненти та створити для них виділені темплейти. Таким чином, можна змішувати та співставляти різні темплейти, але використовувати вкладені стеки для створення єдиного об’єднаного стека. Nested стеки – це стеки, які створюють інші стеки. Допустимо, що у вас є конфігурація Load Balancer, яку ви використовуєте для більшості стеків. Замість того, щоб копіювати та вставляти ті самі конфігурації у темплейти, ви можете створити виділений темплейт для Load Balancer. Потім ви використовуєте ресурс AWS::CloudFormation::Stack для посилання на цей темплейт з інших темплейтів. Якщо темплейт балансера оновлений, будь-який стек, на який він посилається, буде використовувати оновлений темплейт. Давайте подивимось на приклад із SecurityGroup.

 

Creating Templates

Do Not Embed Credentials in Your Templates

Замість того, щоб вставляти в темплейти AWS CloudFormation конфіденційну інформацію, AWS рекомендує використовувати динамічні посилання у темплейтах. Завдяки їм ви можете посилатися на зовнішні значення, які зберігаються та керуються в інших службах, таких як AWS Systems Manager Parameter Store або AWS Secrets Manager. Коли ви використовуєте динамічні посилання, під час операцій зі стеком при необхідності CloudFormation витягує значення зазначеного посилання. Плюсом є те, що CloudFormation ніколи не зберігає фактичне значення. 

Примітка: Якщо вже не хочете використовувати перелічені сервіси, то використовуйте хоча б Parameters із опцією NoEcho встановленою в True.

Use AWS-Specific Parameter Types

У більшості темплейтів, які потрапляли до мене на рев’ю, я бачив лише такі типи параметрів як String, рідше Number, про решту я взагалі не згадую. Таких типів є більше 20-ти:

AWS-parameter-typesCloudFormation може швидко валідувати значення параметрів для специфічного AWS ресурсу перед тим, як ви натиснете кнопку submit. Окрім того, якщо ви використовуєте AWS консоль, то CloudFormation підтягне значення існуючих ресурсів, таких як SSH ключ, VPC чи Security Group. Детальніше дізнатись про типи параметрів можна тут

Use Parameter Constraints

За допомогою обмежень ви можете описати дозволені вхідні значення, щоб AWS CloudFormation відловлював будь-які неправильні значення перед створенням стеку. Ви можете встановити обмеження, такі як мінімальна довжина, максимальна довжина та дозволені патерни. Наприклад, якщо ви все ж задаєте пароль до бази даних через параметри (будь ласка, не робіть цього), то можете вказати його мінімальну довжину і які символи там можуть бути використані:

  • Type
  • AllowedPattern
  • AllowedValues
  • ConstraintDescription
  • Default
  • Description
  • MaxLenght
  • MaxValue
  • MinLenght
  • MinValue
  • NoEcho

Use AWS::CloudFormation::Init to Deploy Software Applications on Amazon EC2 Instances

Я часто зустрічаю CFn темплейти, в яких дуже багато операцій зі встановлення пакетів, а створення файлів розташоване в UserData. Такі темплейти виглядають дуже незграбно. Окрім того, з часом навігація по такому темплейту ускладнюється. Для таких задач AWS рекомендує використовувати AWS::CloudFormation::Init, який дозволяє все це описати в темплейті без зайвих «костилів».

Use the Latest Helper Scripts

AWS не пояснює нічого з цього приводу, але я підозрюю, що оновлювати їх потрібно не лише тому, що там з’являються нові фічі, але і тому, що вони закривають певні security дірки.

Validate Templates Before Using Them

Перед тим, як створювати стек, перевірте темплейт, щоб у разі помилки вам не довелось видаляти стек, а потім знову його створювати. Перевірити темплейт допоможуть такі утиліти як: cfn-lint, yaml-validate та json-validate. Ну і звісно, у цьому списку також має бути aws cloudformation validate-template. Окрім того, все вище перелічене можна і навіть варто використовувати у випадку, якщо у вас є процес CI/CD для самого CloudFormation. Наприклад, заборонити злиття гілки, в якій розроблявся новий функціонал, в головну гілку, якщо тести в cfn-lint не пройдуть.

Managing Stacks

Manage All Stack Resources Through AWS CloudFormation

Якщо ви створили ресурси за допомогою CloudFormation, то управляйте ними лише за допомогою цього сервісу. Однак на всіх ви вплинути не можете. Трапляється, що на проєкті є колега, якого не цікавить, як було створено ресурс. Автоматичне і мануальне редагування може зашкодити збудованим процесам, однак, якщо йому потрібно, цей колега він все одно змінить конфігурацію мануально.

Допомогти виявити незадекларовані зміни в ресурсах, створених за допомогою CloudFormation, може така функція, як  DriftDetection. DriftDetection допоможе ідентифікувати, чи консистентні ваші ресурси з поточним стеком/темплейтом.

Create Change Sets Before Updating Your Stacks

Використовуйте change set-и, щоб перевірити, як ваші зміни можуть впливати на запущені ресурси, особливо, на критичні ресурси. Наприклад, якщо ви зміните ім'я екземпляра бази даних Amazon RDS, AWS CloudFormation створить нову базу даних і видалить стару. У результаті, якщо ви не забекапили дані у старій вазі, ви їх втратите.
Якщо використаєте change set, то побачите, що ваша зміна вплине на базу даних. Це може допомогти спланувати оновлення стеку.

Use Stack Policies

Stack Policy допомагає захистити критичні ресурси стеку від ненавмисних оновлень, які можуть призвести до видалення або заміни ресурсів. Stack Policy – це документ у форматі JSON. Він описує, які дії з оновлення можна виконувати на визначених ресурсах. Вказуйте політику стеку щоразу, коли створюєте стек, який має критичні ресурси.Під час оновлення стека потрібно чітко вказати захищені ресурси, які ви хочете оновити, в іншому випадку вони не будуть захищені. Ось як виглядає така політика:

 

Use AWS CloudTrail to Log AWS CloudFormation Calls

AWS каже, що треба логувати усі API Calls до CloudFormation. На мою думку, треба логувати усі calls до AWS. Так легше буде знайти, хто і де зробив помилку.

Use Code Reviews and Revision Controls to Manage Your Templates

На одному з моїх попередніх проєктів у нас було 200 стеків, 180 з них – це мікросервіси для різних середовищ, як то production, staging та development. Спершу ми хотіли перевірити зміни на dev, stg, а лише тоді – на prd. Але з часом ми почали плутатись, який стек ми вже оновлювали, а який – ні. Нам допомогла, здавалось б, така не потрібна секція як Description. У ній ми прописували версію, наприклад v0.0.1. Основна зручність полягала в тому, що в консолі AWS було видно, яку версію темплейту використовують конкретні стеки. Ось приклад того, як велась розробка в нашому репозиторії.

 

 Update Your Amazon EC2 Linux Instances Regularly

На одному із проектів, де я працював, час від часу треба було оновлювати секцію Mapping із ідентифікаторами образів по регіонах. Ця робота мені не подобалась більш за все. Уже після того, як я пішов з цього проєкту, я написав, «приблуду», якій ти згодовуєш ID в певному регіоні або її ім’я, а вона натомість автоматично будує карту. Ви можете її встановити за допомогою python-pip. У випадку, якщо вам цікаво, що там під капотом, можете зібрати її власноруч. Знайти її можна у моєму github репозиторії.

Висновок

Більшість практик, описаних в документі AWS, є дуже доречними. Завдяки їм ваші темплейти будуть читабельними, а інфраструктура – в порядку. Однак цих практик лишt 18 і, як на мене, у них все ще є прогалини. Керуватись лише кращими практиками AWS не достатньо. Тому у наступному матеріалі я розповім про лайфхаки, які ми можемо застосовувати при роботі з CloudFormation. 

Стань колегою Романа!
Долучайся до нашої команди DevOps!

 

 ПЕРЕГЛЯНЬ ВІДКРИТІ
ВАКАНСІЇ ДЛЯ…
DevOps спеціалістів