Запитай в рекрутера

CloudFormation – потужний сервіс, який допомагає вам створювати і управляти інфраструктурою в AWS. У попередній статті я розповів про найкращі практики в AWS CloudFormation. Однак лише найкращих практик не достатньо. У цій статті ми розповімо про те, як краще організовувати ваші темплейти і як оновлювати критичні ресурси без простоїв (downtime). Що важливо знати, щоб розширити спектр перевикористання ваших темплейтів, а також, як не втратити критично важливі ресурси, які були створені за допомогою CloudFormation під час видалення чи оновлення стеків.

Старайтесь використовувати Fn::Sub замість Fn::Join…

За можливості старайтесь використовувати Fn::Sub замість Fn::Join, оскільки Sub є більш читабельним. Допустимо, нам потрібно сформувати стрічку arn:aws:execute-api:us-east-1:123456789012:/*/* (звичайно за умови, що ви перебуваєте в регіоні us-east-1 і ID вашого акаунта 123456789012) в CloudFormation темплейті. 

За допомогою Fn::Join це можна зробити так:

 !Join: 
- ''
- - 'arn:'
- Ref: AWS::Partition
- ':execute-api:'
- Ref: AWS::Region
- ':'
- Ref: AWS::AccountId
- ':'
- Ref: ApiGatewayRestApi
- '/*/*'

 У цьому прикладі є багато символів “:”, які виступають як об’єднувачами двох стрічок, так і просто присутні в стрічках на початку і в кінці. Це можна виправити, додавши в Join в Join.

!Join: 
  - ''
  - - !Join
    - ':'
    - - 'arn'
      - Ref: AWS::Partition
      - execute-api
      - Ref: AWS::Region
      - Ref: AWS::AccountId
      - Ref: ApiGatewayRestApi
    - '/*/*' !Join:

Виглядає правильніше, аніж у попередньому прикладі, але для розуміння важче. А тепер давайте поглянемо, як те ж саме виглядатиме в Fn::Sub.

SourceArn: !Sub 
- 'arn:${AWS::Partition}:executeapi:${AWS::Region}:${AWS::AccountId}:${RestApi}/*/*'
- { RestApi: Ref: ApiGatewayRestApi } SourceArn: !Sub

Елегантніше, простіше і зрозуміліше. Звичайно, Fn::Sub не замінить вам Fn::Join у випадку, коли ви працюєте з UserData, тому використовуйте Fn::Sub з розумом.

Використовуйте YAML замість JSON

  1. YAML дозволяє залишати коментарі в коді
  2. Розмір темплейту, записаному на YAML, буде меншим за рахунок відсутності великої кількості надлишкових символів, таких як кома, лапки, фігурні та квадратні дужки. Це також важливо для тих, хто створює CFn стеки за допомогою aws cli, оминаючи s3, оскільки ваш темплейт не може бути більшим за ~52Kb.
  3. Окрім того, я вважаю YAML читабельнішим за JSON.

Використовуйте Rollback Trigger для критичних ресурсів

На одному з моїх попередніх проєктів треба було впевнитись, що ресурс правильно оновився, навіть у випадку зі staging середовищем. Тоді ми оперували ECS кластерами, і якщо розробники розпочинали оновлення певного сервісу, а код був неробочий, кластер швидко забивався мертвими контейнерами. Тут на допомогу прийшли rollback тригери і CloudWatch Events. Якщо CloudWatch event бачив, що йому починають прилітати певні повідомлення, то викликалась Rollback процедура і повертала сервіс до попередньої версії. Ось приклад такого CloudWatch Event.

 

Як бути впевненим, що темплейт можна перевикористати на інших акаунтах і в інших регіонах Ніколи не хардкодьте ідентифікатор акаунта, регіон та інші службові змінні. Використовуйте наступні псевдопараметри, щоб формувати стрічки:

  • AWS::AccountId
  • AWS::Partition
  • AWS::Region
  • AWS::UrlSuffix

Використовуйте секцію Metadata

Якщо ваші темплейти використовують консоль через AWS, то Metadata з ключем Interface – must have. Це допоможе згрупувати дані на сторінці для введення параметрів, а також присвоїти опис кожному полю. Таким чином, ви збережете час, який однозначно витратите на те, щоб пояснювати значення кожної змінної вашим колегам.

 

Якщо ви створюєте VPC і мережі за допомогою CloudFormation, то старайтесь не хардкодити значення. З цим вам допоможуть функції GetAZs і CIDR. Fn::Cidr відіграє роль, такого собі, IP калькулятора. У випадку Fn::Cidr": [ 10.0.0.0/8, "256", "8”] він поверне список з 256 мереж із маскою.

Використовуйте Create, Update, Delete Policies

Буває, що потрібно створити якийсь ресурс, але видаляти його не потрібно. Дехто через це не використовує CFn, оскільки думає, що при видаленні стеку важливий ресурс також видалиться. Такими ресурсами можуть бути RDS інстанси, S3 бакети з важливою інформацією, KMS ключі та ін. На щастя, в CFn є такі атрибути, як UpdatePolicy та DeletePolicy, які дозволять вам вказати, що саме ви можете зробити з ресурсом після його оновлення чи видалення. 

Якщо ви використовуєте CFn всередині CI/CD, використовуйте wait з вашою командою.

Одного разу мені потрібно було додати CloudFormation в мій CD Pipeline. Я додав команду aws cloudformation create-stack --stack-name my-stack --change-set-name my-change-set, але одразу ж стало зрозуміло, що вона не дає змоги слідувати за виконанням, а просто посилає команду на створення/оновлення стеку. Отже, я спробував знайти, чи дозволяє AWS CLI це робити, але відповіді не знайшов. Зрештою, я реалізував такий сценарій на Python, який допомагав слідувати за виконанням і відображати кожну подію під час створення/оновлення/видалення стеку. Потім я зрозумів, що потрібно було всього лиш додати команду wait. Я вирішив нікому про це не розповідати, але за деякий час, рев’юваючи код на іншому проєкті, я побачив таку ж ситуацію, тобто такий же скрипт, який я написав приблизно за два роки до цього. 

Отже, ваша команда повинна виглядати так: aws cloudformation wait create-stack --stack-name my-stack --change-set-name my-change-set.Тому не пишіть свої “костилі” використовуйте wait.

Висновок

Використовуйте YAML замість JSON – це збільшить читабельність темплейту та зменшить його розмір. Використовуйте RollBack Trigger – це допоможе уникнути downtime-ів. Використовуйте політики для видалення і оновлення ресурсів. Використовуйте секцію Metadata із ключем AWS::CloudFormation::Interface – це зробить сторінку з параметрами зрозумілішою для користувачів. Використовуйте Fn::GetAZs і Fn::CIRD – це допоможе вам створювати мережі без хардкоду. Використовуйте псевдофункції – це допоможе уникнути хардкоду і зробити темплейти гнучкішими до перевикористання. І наостанок, читайте документацію і не пишіть “костилів”.

Корисні посилання

  1. https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/best-practices.html#organizingstacks
  2. https://cloudonaut.io/6-unknown-cloudformation-features-you-should-know-about/
  3. https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html
  4. https://github.com/99stealth/cfn-workshop-chapter1
  5. https://github.com/99stealth/cfn-ami-to-mapping
  6. https://github.com/99stealth/simple-infrastructure
  7. https://github.com/99stealth/simple_random_app

Команда наших DevOps-інженерів чекає на тебе! Обирай роль та подавай резюме!