0
1

AWS SAMを使ってTypeScriptでImage形式のLambdaを起動する

Last updated at Posted at 2023-09-30

概要

準備

  • 参考資料: 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ファイルの修正

  • outDirrootDirbaseUrlpathsincluedeを追記
  • 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ファイルの作成

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
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1