AWS CDKを学習していく過程を記録する。
はじめに
[備忘録] AWS CDK プロジェクトの作成にて、CDK プロフェクトの作成とデプロイまでできたので、今回はAWS CDKでAPI GatewayおよびLambdaを作成してみる。
また、API GatewayをトリガーにLambdaを実行することで、LambdaがRestAPIとして外部ネットワークから利用可能になることを確認する。
Lambdaとは
AWS Lambda は、サーバーをプロビジョニングまたは管理せずにコードを実行できるようにするコンピューティングサービスです。
つまり、「サーバレスにインターネットを通じてプログラムを実行することができるサービス(Faas:Function as a Service)」である。
API Gatewayとは
公式サイトでは
Amazon API Gateway は、あらゆる規模の REST、HTTP、および WebSocket API を作成、公開、維持、モニタリング、およびセキュア化するための AWS のサービスです。
と説明されている。
要するに「APIを作成、管理するための AWS のサービス」である。
実施したこと
- Lambdaの作成
- API Gatewayの作成
1. Lambdaの作成
Lambda の処理内容の作成
lambdaフォルダと、実際に Lambda の処理内容を書いていく app-lambda.ts ファイルを作成した。
├── lambda
└── app-lambda.ts
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
export const handler = async (
event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
const RESPONSE_HEADERS = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "Content-Type,Authorization,access-token",
};
return {
statusCode: 200,
headers: RESPONSE_HEADERS,
body: "成功",
};
};
今回は単に "成功" のメッセージを返す Lambda とした。
また、Lambda の型定義のために下記コマンドより @types/aws-lambda をインストールした。
% npm i --save-dev @types/aws-lambda
Lambda の作成
app-stack.ts に、Lambda 用の IAM Role と Lambda を作成するためのコードを追加。
import { Stack, StackProps, Duration } from 'aws-cdk-lib';
import { Role, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
import { Runtime } from 'aws-cdk-lib/aws-lambda';
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
import { Construct } from 'constructs';
export class AppStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// iam role for lambda
const iamRoleForAppLambda = new Role(this, 'IamRoleForAppLambda', {
roleName: 'app-lambda-role',
assumedBy: new ServicePrincipal('lambda.amazonaws.com'),
});
// lambda
const lambda = new NodejsFunction(this, 'AppLambda', {
functionName: 'app-lambda',
entry: 'lambda/app-lambda.ts',
runtime: Runtime.NODEJS_16_X,
timeout: Duration.seconds(30),
role: iamRoleForAppLambda,
memorySize: 128
});
}
}
確認
デプロイ後コンソールから Lambda が作成されていることを確認できた。
※デプロイ時エラーが発生したが、解決方法については[備忘録] Error: spawnSync docker ENOENTの解消にまとめた。
また、テストを実行したところ、期待通り"成功"のメッセージも返ってきた。
2. API Gatewayの作成
API Gatewayの作成
app-stack.ts に、API Gatewayおよび API Key を作成するコードを追記し、それらを使用量プランで紐づける。
import { LambdaIntegration, RestApi } from 'aws-cdk-lib/aws-apigateway';
// api gateway
const api = new RestApi(this, 'AppApigateway', {
restApiName: 'app-apigateway'
});
// api key
const apiKey = api.addApiKey('AppApikey', {
apiKeyName: 'app-apikey'
});
// usage plan
const usagePlan = api.addUsagePlan('AppUsageplan');
usagePlan.addApiKey(apiKey);
usagePlan.addApiStage({ stage: api.deploymentStage });
さらに、作成した API Gateway にリソースを追加、lambda をアタッチした。
const get = api.root.addResource('get');
const lambdaIntegration = new LambdaIntegration(lambda);
get.addMethod('GET',lambdaIntegration,{
apiKeyRequired: true,
});
確認
デプロイ後コンソールから API Gateway が作成されていることを確認できた。
postmanを用いてAPIにリクエストを送信したところ、期待通り"成功"のメッセージも返ってきた。
また、今回 API Key を必須としたため、Authorization のタブから API Key を設定している。この設定がないときは、Forbidden が返ってくることも確認できた。
{
"message": "Forbidden"
}
最後に
AWS CDKでAPI GatewayおよびLambdaを作成し、API を叩くと期待通りの結果が返ってくることを確認できた。
次は、RDS、RDS Proxy を構築し、Lambda から mysql に接続できることを確認したい。
参考にした文献を記す。
- https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/welcome.html
- https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html
- https://www.wafcharm.com/jp/blog/aws-lambda-for-beginners/
- https://zenn.dev/t_morooka/articles/2951743c240063
- https://dev.classmethod.jp/articles/apig-and-lambda-best-stack-configuration-with-aws-cdk/
- https://www.npmjs.com/package/@types/aws-lambda