Привет всем, как дела? Мы прошли через AWS CloudFormation, и я уверен, что вы с нетерпением ждете последнего раздела. Не волнуйтесь; Я готовлю для вас хорошие примеры, и как только они будут готовы, я их опубликую. Но сегодня я хочу поговорить об AWS CDK?.

Что такое AWS CDK?

Это платформа для определения облачной инфраструктуры в коде и предоставления ее с помощью AWS CloudFormation.

Теперь вы понимаете, почему я начал с AWS CloudFormation, чтобы ознакомиться с основным продуктом, лежащим в основе большей части инфраструктуры AWS, в виде интерфейсов командной строки кода, таких как AWS CDK, AWS SAM, AWS CDK и т. д. Использование AWS CDK дает множество преимуществ при создании масштабируемых, экономичные приложения в облаке AWS.

AWS CDK поддерживает TypeScript, JavaScript, Python, Java, C#/.Net и (в предварительной версии для разработчиков) Go. Разработчики могут использовать один из этих поддерживаемых языков программирования для определения многократно используемых облачных компонентов, известных как конструкции. Вы объединяете их в стеки и приложения

Команда AWS создала уникальную платформу для работы при развертывании и настройке ресурсов в AWS. Этот инструмент упрощает процесс. Вам необходимо установить AWS CDK Toolkit, который является инструментом командной строки. Используйте эту команду для установки комплекта.

// install toolkit
npm install -g aws-cdk 

// once installed, run the following command:
cdk version

После установки давайте взглянем на некоторые распространенные команды:
cdk — help
cdk list — список всех стеков в приложении
cdk synthetic — печатает шаблон cloudformation
cdk bootstrap — развернуть промежуточный стек
cdk deploy — развернуть указанные стеки
cdk destroy — уничтожить указанный стек
метаданные cdk — отобразить метаданные
cdk init — создать новый проект
cdk context — управляет кэшированными значениями контекста
cdk docs — справочник cdk API
cdk doctor — проверяет наличие проблем

Теперь, когда мы ознакомились с AWS CDK, прежде чем замарать руки, давайте начнем с настройки наших учетных данных. Выполните следующую команду, чтобы настроить среду.

aws configure

Вы можете дополнительно использовать параметр —role-arn (или -r), чтобы указать ARN роли IAM, которую следует использовать для развертывания. Эта роль должна быть назначена используемой учетной записью AWS.

Давайте начнем и создадим наше первое приложение с помощью AWS CDK. Это приложение будет простым, благодаря чему у пользователя будет два доступа к двум маршрутам; маршрут GET для получения их секрета и маршрут PUT для создания их секрета. Мы можем добавить еще один маршрут, DELETE, чтобы удалить сохраненный секрет.

Для начала давайте создадим папку с именем cdk-typescript. Я буду использовать машинописный язык, но вы можете использовать любой из поддерживаемых языков.

mkdir cdk-typescript
cd cdk-typescript

После того, как мы создали папку, мы можем запустить следующую команду, чтобы создать приложение:

cdk init app --language typescript

Теперь у нас есть готовое приложение, давайте создадим папку с именем lambdaFunction и добавим файл с именем app.js.

mkdir lambdaFunction && touch app.js

Затем добавьте следующее содержимое в app.js

const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({ apiVersion: '2012-08-10' });

// Get resources from enviroment
const secretTableName = process.env.SECRET_TABLE_NAME;


/**
 *
 * Event doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format
 * @param {Object} event - API Gateway Lambda Proxy Input Format
 *
 * Context doc: https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html 
 * @param {Object} context
 *
 * Return doc: https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
 * @returns {Object} object - API Gateway Lambda Proxy Output Format
 * 
 */

exports.handler = async (event) => {

  const lambdaResponse = {
    statusCode: 200,
    headers: {
      "Access-Control-Allow-Headers": "Content-Type",
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "OPTIONS,POST,GET,DELETE"
    },
    body: '',
  };

  try {
    switch (event.httpMethod) {
      case 'PUT':
        if (event.queryStringParameters.content) {
          const results = await createSecret(event.queryStringParameters.content)
          lambdaResponse.body = `https://${event.requestContext.apiId}.execute-api.us-east-1.amazonaws.com/prod${event.path}?id=${results}`
        } else {
          lambdaResponse.body = "Please provide a secret"
        }
        break;
      case 'GET':
        if (event.queryStringParameters.id) {
          lambdaResponse.body = await getSecret(event.queryStringParameters.id)
        } else {
          lambdaResponse.body = "Please provide the id of the secret you want to retrive"
        }
        break;
      case 'DELETE':
        if (event.queryStringParameters.id) {
          await deleteSecret(event.queryStringParameters.id)
        } else {
          lambdaResponse.body = "Please provide the id of the secret you want to delete"
        }
        break;
      default:
        break
    }
  } catch (error) {
    lambdaResponse.statusCode = 400
    lambdaResponse.body = error.message
  } finally {
    lambdaResponse.body = JSON.stringify(lambdaResponse.body)
  }

  return lambdaResponse;
};

/**
 * Creates a new secret
 * @param id
*/
const createSecret = async (content) => {
  const secretId = uuid(16)

  const params = {
    TableName: secretTableName,
    Item: {
      "id": secretId,
      "content": content,
    },
  }

  await docClient.put(params).promise()
  return secretId
}


/**
 * Get user secret
 * @param id 
 * @returns {object}
*/
const getSecret = async (id) => {
  const result = await docClient.get({
    TableName: secretTableName,
    Key: {
      "id": id
    }
  }).promise()
  if (!result) {
    return null
  }

  return result.Item
}

/**
 * Delete user secret 
 * @param id 
*/
const deleteSecret = async (id) => {
  var params = {
    TableName: secretTableName,
    Key: {
      "id": id,
    },
  };
  await docClient.delete(params).promise()
}

/**
 * Generate random uuid
 * @returns uuid
*/
const uuid = () => {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    var r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}

Когда наша функция готова, нам нужно обновить cdk-typescript-stack.ts.. Мы сделаем это шаг за шагом, чтобы понять, насколько просто работать с AWS CDK. Это руководство будет интересным, потому что вы заметите, как AWS CDK упростил создание серверной инфраструктуры в облаке. Для начала создадим нашу базу данных. У AWS CDK есть справочник по API, с помощью которого вы можете получить всю документацию по ресурсам AWS о том, как развертывать и настраивать с помощью AWS CDK.

Добавьте следующее содержимое в следующий файл ./lib/cdk-typescript-stack.ts.

import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';

export class CdkTypescriptStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // create a dynamodb secret table
    const table = new dynamodb.Table(this, 'SecretTable', {
      partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
    });

  }
}

Поскольку мы используем машинописный текст, нам нужно собрать наше приложение с помощью следующей команды и развернуть приложение.

// build the application
npm run build

// Optional
cdk synth

// Deploy
cdk deploy

По завершении вы должны увидеть что-то подобное в своем терминале.

Далее мы хотим добавить созданную нами лямбду. Эта лямбда-функция будет взаимодействовать с таблицей, которую мы создали выше, и, как вы знаете, разрешения AWS IAM для функции необходимо обновить, чтобы функция могла взаимодействовать с таблицей. Обновите cdk-typscript-stack.ts следующим образом, затем соберите и разверните. О, еще одна вещь, которую вы всегда можете запустить с помощью следующей команды cdk diff, чтобы проверить изменения, которые произойдут в бэкэнде.

import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import * as lambda from 'aws-cdk-lib/aws-lambda';

export class CdkTypescriptStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // create a dynamodb table
    const table = new dynamodb.Table(this, 'SecretTable', {
      partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
    });

    // create lambda function
    const secretFunction = new lambda.Function(this, 'SecretFunction', {
      runtime: lambda.Runtime.NODEJS_14_X,
      handler: 'app.handler',
      code: lambda.Code.fromAsset('./lambdaFunction')
    });

    // update function IAM polify grant full access to dynamodb
    table.grantFullAccess(secretFunction)

    // update the function enviroment
    secretFunction.addEnvironment("SECRET_TABLE_NAME", table.tableName)

  }
}

Нам осталось создать последний ресурс — API Gateway. Как правило, вы видите, насколько проста работа с AWS CDK. И это уменьшает количество необходимых нам строк кода по сравнению с работой с vanilla CloudFormation. Обновите cdk-typscript-stack.ts следующим образом, затем соберите и разверните.

import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';

export class CdkTypescriptStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // create a dynamodb table
    const table = new dynamodb.Table(this, 'SecretTable', {
      partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING },
    });

    // create lambda function
    const secretFunction = new lambda.Function(this, 'SecretFunction', {
      runtime: lambda.Runtime.NODEJS_14_X,
      handler: 'app.handler',
      code: lambda.Code.fromAsset('./lambdaFunction'),
    });

    // update function IAM polify grant full access to dynamodb
    table.grantFullAccess(secretFunction)

    // update the function enviroment
    secretFunction.addEnvironment("SECRET_TABLE_NAME", table.tableName)

    // create rest api
    const api = new apigateway.LambdaRestApi(this, 'secret-api', {
      handler: secretFunction,
      proxy: false
    });

    // add resource and methods
    const secret = api.root.addResource('secret');

    secret.addMethod('GET');
    secret.addMethod('PUT');
    secret.addMethod('DELETE');

  }
}

Теперь войдите в консоль AWS и проверьте список лямбда-выражений в регионе, который вы выбрали при настройке учетных данных с помощью следующей команды: aws configure.Теперь мы развернули наше первое приложение с помощью AWS CDK.

По завершении вы должны увидеть что-то подобное в своем терминале.

✨  Deployment time: 91.55s

Outputs:
CdkTypescriptStack.secretapiEndpointC5C4044F = https://[apiId].execute-api.us-east-1.amazonaws.com/prod/       
Stack ARN:
arn:aws:cloudformation:us-east-1:440343172651:stack/CdkTypescriptStack/d191a320-7e0d-11ec-a2aa-1249d52492bf       

✨  Total time: 103.7s

Мы создали серверную часть нашего приложения, мы можем проверить URL-адрес с помощью почтальона, чтобы убедиться, что все работает правильно.

ПОЛОЖИТЬ МЕТОД

curl --location --request PUT 'https://[apiId].execute-api.us-east-1.amazonaws.com/prod/secret?content=kevinodongo'

Замените apiId и выполните следующую команду:

"https://[apiId].execute-api.us-east-1.amazonaws.com/prod/secret?id=54a7a7b9-972e-4b2e-9422-715c0ea8733d"

Эта команда создаст новую запись в DynaModb и вернет URL-адрес, который вы можете использовать для получения секрета.

ПОЛУЧИТЬ МЕТОД

Замените apiId и выполните следующую команду:

curl -i --location --request PUT 'https://[apiId].execute-api.us-east-1.amazonaws.com/prod/secret?id=54a7a7b9-972e-4b2e-9422-715c0ea8733d

Ваш ответ должен выглядеть примерно так.

{"content":"kevinodongo","id":"54a7a7b9-972e-4b2e-9422-715c0ea8733d"}

УДАЛИТЬ СПОСОБ

Замените apiId и выполните следующую команду:

curl --location --request DELETE 'https://[apiId].execute-api.us-east-1.amazonaws.com/prod/secret?id=54a7a7b9-972e-4b2e-9422-715c0ea8733d'

Теперь, когда мы завершили наше приложение, давайте рассмотрим некоторые термины, которые вам необходимо изучить с помощью AWS CDK. Я пройдусь по ним кратко, но подробнее о них можно прочитать здесь

Конструкты

Это стандартные блоки, содержащие все, что требуется AWS CloudFormation для создания среды.

Состав

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

Инициализация

Конструкции реализованы в классах, расширяющих базовый класс Construct. Вы определяете конструкцию, создавая экземпляр класса. При инициализации все конструкции принимают три параметра: Scope, id и Props.

Приложения и стеки

Стеки в приложениях AWS CDK расширяют базовый класс Stack, как показано в предыдущем примере. Этот подход является типичным шаблоном при создании стека в приложении AWS CDK:

  • Расширьте класс стека.
  • Определите конструктор, который принимает область действия, идентификатор и реквизиты.
  • Вызовите конструктор базового класса через super с полученной областью действия, идентификатором и свойствами, как показано в следующем примере.

Единица развертывания в AWS CDK называется стеком. Все ресурсы AWS, определенные в рамках стека, прямо или косвенно предоставляются как единое целое.

Каждый экземпляр стека в вашем приложении AWS CDK явно или неявно связан со средой (env). Среда — это целевая учетная запись AWS и регион, в котором развернут стек.

const regionEU = { account: '2383838383', region: 'eu-west-1' }; 
const regionUSA = { account: '8373873873', region: 'us-east-1' }; 

new USAStack(app, 'stack-us', { env: regionUSA }); 
new EUStack(app, 'stack-eu', { env: regionEU });

Привет! не торопитесь и хорошо разберитесь со следующими понятиями:

Лучшие практики

Одна вещь, которую вы должны принять во внимание, — это иметь конвейер непрерывной доставки для развертывания. Вы должны организовать приложение в виде отдельных строительных блоков, например, API, базы данных, мониторинга и т. д.

  1. Организации следует определить стандарты и политики, которыми будут руководствоваться ее облачные инфраструктуры. Целевая зона — это предварительно настроенная, безопасная, масштабируемая среда AWS с несколькими учетными записями, основанная на передовых методах. Вы можете связать вместе сервисы, составляющие вашу зону приземления, с помощью AWS Control Tower. Этот высокоуровневый сервис настраивает и управляет всей вашей системой с несколькими учетными записями из единого пользовательского интерфейса.
  2. Начните с простого и усложняйте только при необходимости.
  3. Согласование с платформой AWS Well-Architected
  4. Инфраструктура и код среды выполнения находятся в одном пакете.
  5. Каждое приложение начинается с одного пакета в одном репозитории.
  6. Перемещайте код в репозитории в зависимости от жизненного цикла кода или владения командой.
  7. Моделируйте с помощью конструкций, развертывайте с помощью стеков.
  8. Настройка со свойствами и методами, а не с переменными среды
  9. Модульное тестирование вашей инфраструктуры
  10. Не изменяйте логический идентификатор ресурсов с отслеживанием состояния.
  11. Принимайте решения во время синтеза.
  12. Используйте сгенерированные имена ресурсов, а не физические имена.
  13. Определение политик удаления и хранения журналов
  14. Разделите приложение на несколько стеков в соответствии с требованиями развертывания.
  15. Разрешите AWS CDK управлять ролями и группами безопасности.
  16. Смоделируйте все этапы производства в коде
  17. Измерьте все

Это все, чем я могу поделиться, чтобы начать работу с AWS CDK. Эта статья должна помочь вам начать работу и убедиться, что вы можете работать с AWS CDK. Не останавливайтесь на этой статье, исследуйте больше. Я буду продолжать делиться информацией об AWS CDK. Спасибо и увидимся в следующий раз.

Первоначально опубликовано на https://dev.to 26 января 2022 г.