Обзор кода AWS CDK

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



Как и было обещано, вторая часть (эта) будет охватывать аспекты инфраструктуры (конкретно IaaC), которая состоит из трех (CDK) стеков (в контексте одного CDK App).

Я покажу вам код CDK, написанный на Go, благодаря поддержке CDK Go (на момент написания статьи это Developer Preview).

Прохождение кода CDK

Давайте возьмем это по одному стеку за раз

Обратите внимание, что часть кода была отредактирована/опущена для краткости — вы всегда можете обратиться к полному коду в репозитории GitHub

Начните со стека инфраструктуры

stack := awscdk.NewStack(scope, &id, &sprops)
vpc = awsec2.NewVpc(stack, jsii.String("demo-vpc"), nil)
authInfo := map[string]interface{}{"Type": "password", "Passwords": []string{memorydbPassword}}
user = awsmemorydb.NewCfnUser(stack, jsii.String("demo-memorydb-user"), &awsmemorydb.CfnUserProps{UserName: jsii.String("demo-user"), AccessString: jsii.String(accessString), AuthenticationMode: authInfo})
acl := awsmemorydb.NewCfnACL(stack, jsii.String("demo-memorydb-acl"), &awsmemorydb.CfnACLProps{AclName: jsii.String("demo-memorydb-acl"), UserNames: &[]*string{user.UserName()}})
//snip .....
subnetGroup := awsmemorydb.NewCfnSubnetGroup(stack, jsii.String("demo-memorydb-subnetgroup"), &awsmemorydb.CfnSubnetGroupProps{SubnetGroupName: jsii.String("demo-memorydb-subnetgroup"), SubnetIds: &subnetIDsForSubnetGroup})
memorydbSecurityGroup = awsec2.NewSecurityGroup(stack, jsii.String("memorydb-demo-sg"), &awsec2.SecurityGroupProps{Vpc: vpc, SecurityGroupName: jsii.String("memorydb-demo-sg"), AllowAllOutbound: jsii.Bool(true)})
memorydbCluster = awsmemorydb.NewCfnCluster(//... details omitted)
//...snip
twitterIngestFunctionSecurityGroup = awsec2.NewSecurityGroup(//... details omitted)
twitterLeaderboardFunctionSecurityGroup = awsec2.NewSecurityGroup(//... details omitted)
memorydbSecurityGroup.AddIngressRule(//... details omitted)
memorydbSecurityGroup.AddIngressRule(//... details omitted)

Обобщить:

  • Одна строка кода для создания VPC и сопутствующих компонентов!
  • Мы создаем группу ACL, User, Subnet для кластера MemoryDB и обращаемся к ним при создании кластера с помощью awsmemorydb.NewCfnCluster
  • Мы также создаем необходимые группы безопасности — их основная роль — разрешить функциям Lambda доступ к MemoryDB (мы указываем явные правила входящего трафика, чтобы сделать это возможным).
  • Один для кластера MemoryDB
  • По одному для обеих лямбда-функций

Следующий стек развертывает лямбда-функцию приема твитов.

//....
memoryDBEndpointURL := fmt.Sprintf("%s:%s", *memorydbCluster.AttrClusterEndpointAddress(), strconv.Itoa(int(*memorydbCluster.Port())))
lambdaEnvVars := &map[string]*string{"MEMORYDB_ENDPOINT": jsii.String(memoryDBEndpointURL), "MEMORYDB_USER": user.UserName(), "MEMORYDB_PASSWORD": jsii.String(getMemorydbPassword()), "TWITTER_API_KEY": jsii.String(getTwitterAPIKey()), "TWITTER_API_SECRET": jsii.String(getTwitterAPISecret()), "TWITTER_ACCESS_TOKEN": jsii.String(getTwitterAccessToken()), "TWITTER_ACCESS_TOKEN_SECRET": jsii.String(getTwitterAccessTokenSecret())}
awslambda.NewDockerImageFunction(stack, jsii.String("lambda-memorydb-func"), &awslambda.DockerImageFunctionProps{FunctionName: jsii.String(tweetIngestionFunctionName), Environment: lambdaEnvVars, Timeout: awscdk.Duration_Seconds(jsii.Number(20)), Code: awslambda.DockerImageCode_FromImageAsset(jsii.String(tweetIngestionFunctionPath), nil), Vpc: vpc, VpcSubnets: &awsec2.SubnetSelection{Subnets: vpc.PrivateSubnets()}, SecurityGroups: &[]awsec2.ISecurityGroup{twitterIngestFunctionSecurityGroup}})
//....

Это довольно просто по сравнению с предыдущим стеком. Мы определяем переменные среды, необходимые нашей функции Lambda (включая учетные данные Twitter API), и развертываем ее как образ Docker.

Для упаковки функции в образ Docker я использовал базовый образ Go:1.x. Но вы можете изучить и другие варианты. Во время развертывания образ Docker создается локально, помещается в частный реестр ECR и, наконец, создается функция Lambda — и все это с помощью нескольких строк кода!

Обратите внимание, что кластер MemoryDB и группа безопасности автоматически запрашиваются из предыдущего стека (не создаются повторно!).

Наконец, третий стек отвечает за лямбда-функцию таблицы лидеров.

Он очень похож на предыдущий, за исключением добавления URL-адреса лямбда-функции (awslambda.NewFunctionUrl), который мы используем для стека:

//....
memoryDBEndpointURL := fmt.Sprintf("%s:%s", *memorydbCluster.AttrClusterEndpointAddress(), strconv.Itoa(int(*memorydbCluster.Port())))
lambdaEnvVars := &map[string]*string{"MEMORYDB_ENDPOINT": jsii.String(memoryDBEndpointURL), "MEMORYDB_USERNAME": user.UserName(), "MEMORYDB_PASSWORD": jsii.String(getMemorydbPassword())}
function := awslambda.NewDockerImageFunction(stack, jsii.String("twitter-hashtag-leaderboard"), &awslambda.DockerImageFunctionProps{FunctionName: jsii.String(hashtagLeaderboardFunctionName), Environment: lambdaEnvVars, Code: awslambda.DockerImageCode_FromImageAsset(jsii.String(hashtagLeaderboardFunctionPath), nil), Timeout: awscdk.Duration_Seconds(jsii.Number(5)), Vpc: vpc, VpcSubnets: &awsec2.SubnetSelection{Subnets: vpc.PrivateSubnets()}, SecurityGroups: &[]awsec2.ISecurityGroup{twitterLeaderboardFunctionSecurityGroup}})
funcURL := awslambda.NewFunctionUrl(stack, jsii.String("func-url"), &awslambda.FunctionUrlProps{AuthType: awslambda.FunctionUrlAuthType_NONE, Function: function})
awscdk.NewCfnOutput(stack, jsii.String("Function URL"), &awscdk.CfnOutputProps{Value: funcURL.Url()})

Это все для этого сообщения в блоге. Закрытие со ссылками на ссылки на AWS Go CDK v2:

На этом серия из двух частей заканчивается. Оставайтесь с нами, чтобы узнать больше и, как всегда, удачного кодирования!