概要
-
AWS SAMの
sam init
使ってLambdaの言語にTypeScript指定する場合にlambdaのZip形式にのみ Templdateファイルが対応しているようだったので、 Image形式に対応させた際の手順のメモ -
公式ドキュメント
準備
-
参考資料: https://dev.classmethod.jp/articles/typescript-native-support-in-the-aws-sam-cli/
-
What package type would you like to use?
の聞かれた際の選択肢1 - Zip
を選択すると、 後続のSelect your starter template
と聞かれた際に Typescript を指定できるが、2 - Image
を選択すると js でプロジェクトが作成されてしまう -
今回はTypescriptかつZip形式のプロジェクトを作成した後に、Image形式への対応を行なっていく
AWS SAM の sam init
で Typescriptを利用するプロジェクトを作成する
% sam init
You can preselect a particular runtime or package type when using the `sam init` experience.
Call `sam init --help` to learn more.
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
Choose an AWS Quick Start application template
1 - Hello World Example
2 - Data processing
3 - Hello World Example with Powertools for AWS Lambda
4 - Multi-step workflow
5 - Scheduled task
6 - Standalone function
7 - Serverless API
8 - Infrastructure event management
9 - Lambda Response Streaming
10 - Serverless Connector Hello World Example
11 - Multi-step workflow with Connectors
12 - GraphQLApi Hello World Example
13 - Full Stack
14 - Lambda EFS example
15 - Hello World Example With Powertools for AWS Lambda
16 - DynamoDB Example
17 - Machine Learning
Template: 1
Use the most popular runtime and package type? (Python and zip) [y/N]: N
Which runtime would you like to use?
1 - aot.dotnet7 (provided.al2)
2 - dotnet6
3 - go1.x
4 - go (provided.al2)
5 - graalvm.java11 (provided.al2)
6 - graalvm.java17 (provided.al2)
7 - java17
8 - java11
9 - java8.al2
10 - java8
11 - nodejs18.x
12 - nodejs16.x
13 - nodejs14.x
14 - python3.9
15 - python3.8
16 - python3.7
17 - python3.11
18 - python3.10
19 - ruby3.2
20 - ruby2.7
21 - rust (provided.al2)
Runtime: 11
What package type would you like to use?
1 - Zip
2 - Image
Package type: 1
Based on your selections, the only dependency manager available is npm.
We will proceed copying the template using npm.
Select your starter template
1 - Hello World Example
2 - Hello World Example TypeScript
Template: 2
Would you like to enable X-Ray tracing on the function(s) in your application? [y/N]: y
X-Ray will incur an additional cost. View https://aws.amazon.com/xray/pricing/ for more details
Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: y
AppInsights monitoring may incur additional cost. View https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/appinsights-what-is.html#appinsights-pricing for more details
Project name [sam-app]: sam-app-sample
Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)
-----------------------
Generating application:
-----------------------
Name: sam-app-sample
Runtime: nodejs18.x
Architectures: x86_64
Dependency Manager: npm
Application Template: hello-world-typescript
Output Directory: .
Configuration file: sam-app-sample/samconfig.toml
Next steps can be found in the README file at sam-app-sample/README.md
Commands you can use next
=========================
[*] Create pipeline: cd sam-app-sample && sam pipeline init --bootstrap
[*] Validate SAM template: cd sam-app-sample && sam validate
[*] Test Function in the Cloud: cd sam-app-sample && sam sync --stack-name {stack-name} --watch
初期化後のディレクトリ構成
-
sam init
が完了すると下記のディレクトリ構成で作成されるので、こちらを土台に、TypescriptのImageを作成していく - ディレクトリ
hello-world
存在しており関数ごとにpackage.json等の設定ファイル系を用意する構成になっている - そのままだとLambdaの関数を増やす際は関数用のディレクトリ新規に作成し、package.json等の設定ファイル系もそれぞれ用意する必要がある構成
.
├── .gitignore
├── README.md
├── events
│ └── event.json
├── hello-world
│ ├── .eslintignore
│ ├── .eslintrc.js
│ ├── .npmignore
│ ├── .prettierrc.js
│ ├── app.ts
│ ├── jest.config.ts
│ ├── package.json
│ ├── tests
│ │ └── unit
│ │ └── test-handler.test.ts
│ └── tsconfig.json
├── samconfig.toml
└── template.yaml
LambdaのImage形式への対応
ディレクトリ構成の変更
- Lambda関数の設定ファイル系を
hello-world
ディレクトリ内から プロジェクト直下に移動し、関数が増えた場合にも共通の設定ファイルを利用できる構成に変更していく
.
├── .DS_Store
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .npmignore
├── .prettierrc.js
├── Dockerfile
├── README.md
├── events
│ └── event.json
├── jest.config.ts
├── package-lock.json
├── package.json
├── samconfig.toml
├── src
│ └── hello-world
│ ├── app.ts
│ └── tests
│ └── unit
│ └── test-handler.test.ts
├── template.yaml
└── tsconfig.json
- srcの部分について、関数を増やす場合に以下のような構成で増やすことも可能
src
├── hello-world
│ └── app.ts
└── hello-world-2
└── app.ts
buildコマンドの追記
- tscを使ってbuisを行うためのスクリプトを追記
"scripts": {
"build": "tsc"
}
tsconfigファイルの修正
-
outDir
・rootDir
・baseUrl
・paths
・incluede
を追記 - moduleは
es2020
・targetはes2015
が初期化時は指定されているが、関数実行時にexport
が存在しないと怒られるので削除 - コンパイル時にjsファイルを生成するために
noEmit
をfalseに修正 -
include
にsrcを指定
{
"compilerOptions": {
"outDir": "dist",
"rootDir": ".",
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
"strict": true,
"preserveConstEnums": true,
"noEmit": false,
"sourceMap": false,
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src"],
"exclude": ["node_modules", "**/*.test.ts"]
}
Dockerファイルの作成
- AWSが用意しているLamba用のImageを利用するDockerファイルを作成
FROM public.ecr.aws/lambda/nodejs:18 as builder
WORKDIR /usr/app
COPY package.json ./
RUN npm install
COPY tsconfig.json ./
COPY src ./src
RUN npm run build
FROM public.ecr.aws/lambda/nodejs:18
WORKDIR ${LAMBDA_TASK_ROOT}
COPY --from=builder /usr/app/dist/* ./
COPY --from=builder /usr/app/node_modules ./node_modules
templdate.yamlの変更
- Lambdaの関数をImageを使うように修正
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
PackageType: Image
Architectures:
- x86_64
ImageConfig:
Command:
- /var/task/hello-world/app.lambdaHandler
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
Metadata:
DockerTag: nodejs18.x-v1
DockerContext: .
Dockerfile: Dockerfile
ビルド
$ sam build
デプロイ
$ sam deploy --guided