なになれ

IT系のことを記録していきます

AWS CDKでLambdaをいい感じにIaC化する

AWS Lambdaに対してのIaCのやり方を模索していて、AWS CDKが今のところ一番いい感じだと思ったので試してみた記録です。

各種方法との比較

AWS LambdaをIaC化するやり方は主に以下のやり方があると思います。
他にもいろいろあると思いますが、自分が経験したものの範囲になります。

  • AWS SAM
  • Serverless Framework
  • Terraform
  • AWS CDK

AWS SAMは割と以前から存在するLambdaをIaC化するためのAWS公式の方法です。AWS CDKと比較するとAWS SAMテンプレートと呼ばれるAWS CloudFormationテンプレートを拡張した長大なYAMLを利用しなければいけないところが辛いところです。

Serverless Frameworkは公式ではないところの不安やLambdaのみのIaCの仕組みなので学習コストが気になるところです。AWS CDKと比較しても優位がない感じがします。

Terraformは公式ではないものの広くAWSのIaCで使われていて安心感があります。ただLambdaを管理するには手間がかかります。Terraformの場合、基本的にAWSAPIをHCLでそのまま利用する形です。Lambda関数を作成する場合、zipファイルを用意するか、コンテナイメージを用意するかがあり面倒です。

こういったことを踏まえるとAWS CDKでのやり方は面倒なことがなく、公式で提供されている仕組みということもあり一番良いと考えました。AWS CDKではコンストラクトという要素でCloudFormationのリソースを利用可能ですが、それらを抽象化した高度なコンストラクトも用意されています。AWS Lambdaにおいては楽にリソースを作成する体験が得られます。

以下でどのようになるかを紹介します。

AWS CDKによるLambda関数の作成方法

以下のAWS CDK Workshopの通りにcdk deployができていることを前提としています。

cdkworkshop.com

aws_lambda.FunctionでLambda関数を作成できます。

lib/main.ts

import { aws_lambda, Duration, Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';

...

export class AwsLambdaCicdExampleStack extends Stack {
  constructor(scope: Construct, id: string, props: LambdaFunctionConfig) {
    super(scope, id);

    new aws_lambda.Function(this, `HelloFunction`, {
      functionName: `hello-function-${props.environmentValues.NODE_ENV}`,
      runtime: props.runtime,
      code: aws_lambda.Code.fromAsset(props.path),
      handler: props.handler,
      timeout: Duration.minutes(15),
      environment: props.environmentValues
    });
  }
}

Lambdaのコードを指定するにはcodeのパラメータにaws_lambda.Code.fromAssetメソッドでLambdaのコードが配置してあるディレクトリパスを指定するだけです。zipファイル化が不要なので楽です。

AWS CDKではTypeScriptのLambda関数も扱えます。aws_lambda_nodejs.NodejsFunctionを使います。

lib/main.ts

import { aws_lambda, aws_lambda_nodejs, Duration, Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';

...

export class AwsLambdaCicdExampleStack extends Stack {
  constructor(scope: Construct, id: string, props: LambdaFunctionConfig) {
    super(scope, id);

    new aws_lambda_nodejs.NodejsFunction(this, `HelloFunction`, {
      functionName: `hello-function-${props.environmentValues.NODE_ENV}`,
      runtime: props.runtime,
      entry: props.path,
      handler: props.handler,
      timeout: Duration.minutes(15),
      environment: props.environmentValues
    });
  }
}

TypeScriptのLambdaのコードを指定するにはentryのパラメータにTypeScriptのエントリーファイルのパスを指定するだけです。
NodejsFunctionでは内部的にTypeScriptのトランスパイルなどを実行してLambda関数を作成してくれます。

まとめ

LambdaをIaC化する場合、主要な要素がコードになるのでアプリケーション開発者がIaCできると良さそうです。
その場合、AWS CDKのように汎用プログラミング言語を利用できるのは、アプリケーション開発者にとって取り組みやすいのではないかと思います。
また、AWS CDKでは今回紹介したように簡単にLambdaをIaC化できる仕組みになっているのも良いです。

参考

JavaScriptgithub.com

TypeScript版

github.com

cdkworkshop.com