AWS Summit Berlin 2022 прошел 11-12 мая, и там я посетил замечательный доклад Грегора Хохпе и Луиса Моралеса из AWS под названием Infrastructure as actual code
. В нем они представили AWS CDK. Я решил попробовать, и эта заметка посвящена моим первым впечатлениям о AWS CDK.
Прежде чем перейти к тому, что делает AWS CDK, давайте рассмотрим, почему инфраструктура как код важна. В современной архитектуре облачных приложений способность развертывать инфраструктуру автоматизированным, повторяемым и последовательным способом является обязательным условием. Многие инструменты предоставляют возможность достичь этого, например CloudFormation от AWS, terraform от Hashicorp и другие.
Однако в основном эти инструменты имеют свой собственный DSL для достижения этой цели. Cloudformation использует YAML/Json файлы, а terraform использует HCL (HashiCorp Configuration Language).
Что если разработчики смогут использовать свой любимый язык программирования, на котором они пишут свои приложения и в котором у них есть опыт? Вот где AWS CDK сияет.
AWS CDK позволяет нам использовать такие известные языки программирования, как Typescript, JavaScript, Java, Python, Java, C#/.Net и Go.
Ниже показано, как может выглядеть простая функция Lambda с интеграцией Api Gateway.
public class MovieLambdaInfraStack extends Stack{
public MovieLambdaInfraStack(final Construct scope, final String id){
this(scope, id, null);
}
public MovieLambdaInfraStack(final Construct scope, final String id, final StackProps props){
super(scope, id, props);
// Parameters
CfnParameter version = CfnParameter.Builder
.create(this, "lambda-version")
.description("Version of lambda app jar")
.type("String")
.build();
// Bucket storing lambda code
IBucket lambdaCodeBucket = createBucket();
// Lambda Definition
String lambdaSource = "movie-lambda-app-" + version.getValueAsString() + ".jar";
IFunction lambda = Function.Builder.create(this, "sab-lambda-artifact")
.code(Code.fromBucket(lambdaCodeBucket, lambdaSource))
.runtime(Runtime.JAVA_11)
.functionName("sab-lambda-artifact")
.handler("com.sab.LambdaHandler")
.tracing(Tracing.ACTIVE)
.timeout(Duration.minutes(5))
.memorySize(512)
.build();
// Api Gateway
LambdaIntegration lambdaIntegration = LambdaIntegration.Builder
.create(lambda)
.proxy(true)
.build();
RestApi api = RestApi.Builder.create(this, "movies")
.defaultIntegration(lambdaIntegration)
.apiKeySourceType(ApiKeySourceType.HEADER)
.build();
Resource movies = api.getRoot().addResource("movies");
movies.addMethod("POST");
}
@NotNull
private IBucket createBucket(){
return Bucket.fromBucketName(this, "lambda-code-bucket", "sab-lambda-artifact");
}
}
и простой главный метод, который будет запущен AWS CDK для развертывания этого стека
public static void main(final String[] args) {
App app = new App();
new MovieLambdaInfraStack(app, "MovieLambdaInfraStack", StackProps.builder()
.env(Environment.builder()
.account("xxxxxx")
.region("xxxx")
.build())
.build());
app.synth();
}
AWS CDK поставляется с cmd line cli, который развернет это приложение на AWS. Под ним генерируется шаблон cloudformation.
Основные компоненты AWS CDK
App — App
— это компонент, который будет развернут cdk и будет содержать один или более Stacks
.
Stack — Stack
— это то, что определяет нашу инфру. Он будет содержать один или несколько Constructs
.
Конструкты — это настоящие сервисы AWS. Мы также можем создавать свои собственные конструкции.
Смотрите больше компонентов на https://docs.aws.amazon.com/cdk/v2/guide/core_concepts.html.
Вещи, которые мне нравятся
Я использовал cloudformation, который лично я не предпочитаю, в основном потому, что для сложной инфры он может стать очень запутанным и трудночитаемым.
В последнее время я использовал в основном terraform, и он мне понравился. Он поддерживает множество облаков. Мы можем создавать собственные модули и компоненты в terraform. Язык HCL довольно выразителен. В нем есть свои способы определения функций, типов, циклов переменных, которые иногда становятся немного неинтуитивными для нас, разработчиков.
Мое первое впечатление от AWS CDK заключается в том, что я вижу следующие преимущества —
-
Как разработчик я чувствую себя намного спокойнее, поскольку могу использовать свои любимые и известные конструкции программирования для infra.
-
Мы даже можем писать модульные тесты, используя старый добрый Junit. Ниже приведен пример
@Test
void itShouldGenerateLambda(){
App app = new App();
Stack lambda = new MovieLambdaInfraStack(app, "MovieLambdaInfraStack");
Template template = Template.fromStack(lambda);
template.resourceCountIs("AWS::Lambda::Function",1);
template.hasResourceProperties("AWS::Lambda::Function", Map.of(
"Handler", "com.sab.LambdaHandler"
));
}
-
Мы можем в полной мере использовать абстракцию в случае использования объектно-ориентированных языков программирования.
-
Эта способность создавать абстракцию поможет нам привить то же доменно-ориентированное мышление проектирования, которое мы можем применить на уровне кода приложения.
-
Более того, я вижу, что если мы используем хороший уровень абстракции при написании нашего инфра-кода, он будет служить в качестве синей печати того, как различные компоненты взаимодействуют друг с другом. Другими словами, мы можем обнаружить инфраструктурную архитектуру приложения. У нас будет как архитектура на уровне программного обеспечения, так и архитектура на уровне инфраструктуры, расположенные бок о бок в одном месте. Я полагаю, что это даст нам большое понимание.
-
Разработчики получат более широкую картину того, как инфракомпоненты работают вместе для достижения того, что пытается выразить код их приложения.
С другой стороны
Однако с другой стороны —
-
Сильная связь с cloudformation означает, что это специфично для облака AWS. Хотя есть такие библиотеки, как cdk-tf (https://github.com/hashicorp/terraform-cdk) для terraform и cdk8s для Kubernetes.
-
Они относительно новые, поэтому мне еще предстоит оценить их эффективность в большой производственной инфраструктуре.
Но в целом мне понравился подход CDK, и я надеюсь, что его внедрение приблизит инфракод к коду приложений и разрушит силос в плане инструментов и языков между инфракодом и кодом приложений.