はじめに
TypeScriptをよく使うので、TypeScriptでLambdaを書きたいなというのと、Terraformを使ってみたいなということで書きました。
VSCodeのDev Containersを用いてコンテナで開発する前提で書いています。
ECRは料金がかかるため、zipファイルでデプロイする方法をとっています。
Githubリポジトリ
下記にサンプルコードを置いています。
フォルダ構成
最終的なフォルダ構成は以下になります。
.
├── Dockerfile
├── README.md
├── docker-compose.yml
├── package-lock.json
├── package.json
├── src
│ └── index.ts
├── terraform
│ ├── iam.tf
│ ├── lambda.tf
│ ├── main.tf
│ ├── terraform.tfvars
│ └── variables.tf
└── tsconfig.json
Docker関連ファイル作成
Dockerを使用するためのファイルを追加します。
{
"service": "typescript-lambda-sample",
"dockerComposeFile": "../docker-compose.yml",
"workspaceFolder": "/typescript-lambda-sample",
}
# Lambdaが対応しているバージョンを使用する
FROM node:20-slim
ARG TERRAFORM_VERSION=1.8.0
# AWS CLIインストールに必要なものをインストール
RUN apt-get update && apt-get install -y curl unzip bash jq groff less
# AWS CLIバージョン2のインストール
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
unzip awscliv2.zip && \
./aws/install && \
rm -rf awscliv2.zip ./aws
# Terraformのインストール
RUN curl -O https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip && \
unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip -d /usr/bin && \
rm terraform_${TERRAFORM_VERSION}_linux_amd64.zip
services:
typescript-lambda-sample:
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/typescript-lambda-sample
tty: true
TypeScriptプロジェクト作成
コマンドを実行して、tsconfig.jsonやpackage.jsonなどを生成します。
npm init -y
npm i typescript @types/node ts-node
npx tsc --init --rootDir src --outDir dist \
--esModuleInterop --resolveJsonModule --lib es6,dom --module commonjs
ビルドコマンドをpackage.jsonに追加します。
{
...
"scripts": {
"build": "tsc -p .",
},
...
}
適宜Lambdaの開発がしやすくなるライブラリをインストールします。
ライブラリは他にもあるようなので、必要に応じて追加してください。
npm i @types/aws-lambda
ソースコード作成
サンプルコードを作成します。
import { APIGatewayProxyResult } from 'aws-lambda';
export const handler = async (): Promise<APIGatewayProxyResult> => {
return {
statusCode: 200,
body: JSON.stringify({
message: 'success',
}),
};
};
Terraformファイル作成
下記を参考にファイルを作成します。一部違いがある箇所を記載します。
lambda.tf
記事と異なるのはruntimeやhandlerの記載になります。
data "archive_file" "typescript_lambda_sample" {
type = "zip"
source_dir = "../dist"
output_path = "../typescript_lambda_sample.zip"
}
resource "aws_lambda_function" "typescript_lambda_sample" {
function_name = "typescript_lambda_sample"
filename = data.archive_file.typescript_lambda_sample.output_path
source_code_hash = data.archive_file.typescript_lambda_sample.output_base64sha256
runtime = "nodejs20.x"
role = aws_iam_role.lambda_iam_role.arn
handler = "index.handler"
}
variable.tf
記事ではデフォルト値を設定していましたが、terraform.tfvarsで設定した値が入ってくるので、特に設定していません。
variable "region" {
type = string
}
variable "access_key" {
type = string
}
variable "secret_key" {
type = string
}
terraform.tfvars
このファイルで記載した値がvariable.tfで定義した変数に設定されます。
region = "ap-xxxxxxxx-1"
access_key = "XXXXXX"
secret_key = "XXXXXX"
実際はAWSから取得したアクセスキーなどを記載するため、terraform.tfvarsはgithubなどにあげないようにしてください。
デプロイ
プロジェクトルートで以下のコマンドを実行し、ビルドします。
npm run build
terraformフォルダ配下で以下のコマンドを実行します。
初回以降は必要なくなるはずです。
terraform init
以下のコマンドを実行し、何が作成されるかを確認します。
terraform plan
上記で特に問題なければ以下を実行します。
terraform apply
実行するかを聞かれるため、yesと入力して実行します。
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
これでAWS上にLambdaが生成されます!
デプロイしたLambdaを使う予定がないなら以下で削除も簡単にできます。
terraform destroy
終わりに
TerraformはCloudFormationと比べて、情報が探しやすかったように思いました。
AWSに限らず使えると思うので、これから積極的に使っていこうと思います。
参考記事