DevOps

Как CDK упрощает создание инфраструктуры AWS

Использование Infra как НАСТОЯЩЕГО кода в соответствии с принципами AWS

Что такое AWS CDK? Как это соотносится с CloudFormation и другими сторонними решениями?

Сначала была CloudFormation

Изначально выбор был прост. Когда CloudFormation был выпущен в 2011 году, он намного опередил предложение того времени:

  • Это декларативное видение желаемой инфраструктуры, то есть описание того, что вы хотите, а не того, как это делать.
  • Он выражается в виде хорошо известного синтаксиса, такого как JSON или YAML.
  • Он готовится самими AWS, что означает своевременные (а не долгие задержки :) обновления.

Тем не менее, люди были разочарованы написанием этих шаблонов CloudFormation вручную, поскольку это часто было вопросом бездумного копирования / вставки большого количества строк YAML. Людям нужны были широко распространенные функции императивных языков и возможность легко повторно использовать некоторый код.

Вскоре появились многочисленные побочные продукты, использующие популярные языки для генерации шаблонов CloudFormation, например, такие решения, как Troposhpere с использованием Python в качестве верхнего уровня.

Затем появились облачные решения с Terraform с использованием собственного настраиваемого DSL или Pulumi с использованием известных языков. Эти решения не полагаются на CloudFormation, а напрямую используют API.

Потом пришел CDK

CDK хочет быть санкционированным AWS подходом к «Инфра как НАСТОЯЩИЙ код». Он позволяет создавать инфраструктуру в виде кода с использованием языков общего назначения, таких как TypeScript, JavaScript и Python. Подобно Troposhpere, CDK является транспилятором, то есть написанный код преобразуется в другой код (в данном случае CloudFormation).

CDK работает на CloudFormation

Как и Troposhpere, CDK полагается на CloudFormation и его базовую инфраструктуру для выполнения своей работы. Это особенно очевидно, когда CDK позволяет получить доступ к конструкциям нижнего уровня «L1», которые представляют собой простое сопоставление 1: 1 с синтаксисом CloudFormation.

const bucket = new s3.CfnBucket(this, "MyBucket", {
  bucketName: "MyBucket"
});

Более интересны и предпочтительны конструкции L2, больше похожие на реальные объекты.

new s3.Bucket(this, 'MyBucket', { versioned: true });

Использование CDK находится между написанием реального кода и CloudFormation

Даже если вы используете реальный язык, логика CDK остается декларативной, описывая желаемое состояние инфраструктуры вместо реального программирования.

Тем не менее, вы получаете выгоду от функций выбранного языка, таких как управление пакетами и их распространение, полная поддержка IDE с безопасностью типов (если вы выбираете правильный язык :) и, конечно, зацикливание и тестирование.

Но, возможно, одним из важных преимуществ является отсутствие необходимости изучать новый язык или синтаксис, например Terraform с его конкретным DSL.

Использование государственного управления

Неудивительно, что CDK делегирует управление состоянием стеку CloudFormation. Ему необходимо хранить свое состояние и активы в удаленной корзине S3. Обратите внимание, что нет команды для уничтожения ресурсов начальной загрузки, вам нужно сделать это вручную.

Что касается Terraform или Pulumi, вы можете использовать либо локальные состояния, либо удаленные общие состояния, используя внешнее хранилище, такое как S3.

Создание разрешений

CDK может автоматически генерировать некоторые политики. Например, при написании этого кода:

const queue = new sqs.Queue(this, 'CdkQueue', {
      visibilityTimeout: cdk.Duration.seconds(300)
});
const topic = new sns.Topic(this, 'CdkTopic');
topic.addSubscription(new subs.SqsSubscription(queue));

Создается AWS::SQS::QueuePolicy разрешение теме отправлять сообщения в очередь. Приятно также то, что вы можете просто написать некоторые разрешения IAM:

const grant = bucket.grantRead(lambda);

Эта строка просто добавляет права чтения в корзину для данной функции Lambda: это проще, чем писать соответствующие политики JSON IAM.

Также обратите внимание, что в качестве дополнительной безопасности, когда CDK вносит изменения в ресурсы IAM, появляется запрос на подтверждение. Вы можете снять эту блокировку для использования CI с помощью флага --require-approval="Never".

Работа с существующей инфраструктурой

В настоящее время нет специального способа импортировать существующую инфраструктуру с помощью CDK, в отличие от Terraform или Pulumi с помощью команды / ресурса импорта.

Однако есть открытый RFC (открыт в декабре 2019 года) и некоторые обходные пути.

Своевременные обновления?

Эти решения имеют тенденцию отставать, когда объявляются об изменениях в инфраструктуре. Сначала публикуется официальный API, затем обновляются решения IaaC.

Таким образом, функция может быть доступна в CloudFormation, но в CDK нет конструкции для службы или, возможно, существующие конструкции не предоставляют новый набор параметров. Хуже того, в то время может не быть поддержки CloudFormation, что означает отсутствие поддержки CDK.

Чтобы справиться с неполной конструкцией в CDK, которая поддерживается в CloudFormation, вы можете использовать конструкции L1, поскольку они представляют собой простое сопоставление с кодом CloudFormation. В этих конструкциях вы можете добавлять или переопределять любые свойства:

// Get the AWS CloudFormation resource 
const cfnBucket = bucket.node.defaultChild as s3.CfnBucket;  
cfnBucket.addOverride('Properties.VersioningConfiguration.Status', 'NewStatus');

Если ресурса CloudFormation не существует, вам следует положиться непосредственно на API и написать свой собственный AWS Custom Resource или подождать :)

Получение некоторых результатов

CDK генерирует для вас идентификатор CloudFormation. Обратите внимание, что эти ID довольно некрасивые, например CdkTestStack-CdkTestTopicD368A42F-78K64F9UIAXW. Первый хеш добавляется для уникальности, второй сам CloudFormation при создании ресурса.

Вам может потребоваться получить некоторую информацию об управляемой инфраструктуре вашего стека в качестве выходных данных, например, о недавно созданной конечной точке шлюза API.

Выполнение команды развертывания напечатает это для вас в конце:

CdkTestStack: deploying...

✅  CdkTestStack (no changes)
Outputs:
CdkTestStack.Endpoint8024A810 = https://xxxxxxxxx.execute-api.eu-west-3.amazonaws.com/prod/

Однако эти выходные данные нелегко проанализировать, что затрудняет автоматизацию, например получение этого URL-адреса и внедрение его в качестве конфигурации для приложения.

В качестве обходного пути вы можете использовать cdk deploy --outputs-file=output.json для вывода в файл JSON:

{
  "CdkTestStack": {
    "Endpoint8024A810": "https://xxxxxxxxx.execute-api.eu-west-3.amazonaws.com/prod/"
  }
}

Но даже в JSON вывод не так удобен для автоматизации, поскольку сгенерированный идентификатор Endpoint8024A810 является случайным и нет указания типа или других свойств.

К счастью, вы можете использовать overrideLogicalId() в любой конструкции, чтобы установить свой собственный идентификатор, вместо того, чтобы полагаться на автоматически сгенерированные.

Последние мысли

CDK - это огромное улучшение по сравнению с CloudFormation, поскольку вы можете использовать все функции предпочитаемого вами языка для написания инфраструктуры. Если вы сосредотачиваете свои усилия на облачном предложении AWS, CDK - ваш лучший выбор.

Однако структура все еще молода, и ее будущее будет зависеть от стремления команды AWS постоянно улучшать и обновлять ее.

Подпишитесь на Темы FAUN и получайте еженедельное авторское письмо с обязательными техническими историями, новостями и учебными пособиями 🗞️

Подписывайтесь на нас в Twitter 🐦 и Facebook 👥 и Instagram 📷 и присоединяйтесь к нашим Facebook и Linkedin Группы 💬

Если этот пост был полезен, пожалуйста, нажмите несколько раз кнопку хлопка 👏 ниже, чтобы выразить поддержку автору! ⬇