自己学習記録：TypeScript を Lambda で使う為には

# 背景
業務で AWS や JavaScript などが必要になった、おじいちゃんの学習記録。

Lambda では TypeScript を使えないってことで、使う方法は？って探したところ
Serverless Framework が見つかった。

で、試してたら、なんか色々あることを知らされる・・

- serverless 
- SAM
- AWS-ToolKit for VSCode
    - 結局は、SAM ？

## Serverless に対する期待
- TransCompile しながら Lambda への Deploy が出来そう
- Serverless Offline もあるので、うまくいったあとは、開発は Offline で
- Google Cloud Functions/Azure Function などへも deploy 出来るので、覚えておくと役立つかも？

## SAM & ToolKit 
AWS のサポート受けられるってことでやっぱりこっちなのかな・・と
まぁ、どっちも素人なので・・

こっちを選びたくない理由は、Docker 入れないと Offline 動作が出来ないってところかな。

# serverless を試す
https://www.serverless.com/framework/docs/getting-started

- まずはインストール
```powershell: install -g: global に
npm install -g serverless
```

公式ではここで、`serverless` で、 template 選択って話だけど、typescript にしたかったので、help を確認

```powershell: template list 確認
serverless create --help
```

で、一覧を見ると、aws 用のは一つしかない。あとは、Alexa/Azure function/Cloud functions 用かな？
> "aws-clojure-gradle", "aws-clojurescript-gradle", "aws-nodejs", "aws-nodejs-docker", **"aws-nodejs-typescript"**, **"aws-alexa-typescript"**, "aws-nodejs-ecma-script", "aws-python", "aws-python3", "aws-python-docker", "aws-groovy-gradle", "aws-java-maven", "aws-java-gradle", "aws-kotlin-jvm-maven", "aws-kotlin-jvm-gradle", "aws-kotlin-jvm-gradle-kts", "aws-kotlin-nodejs-gradle", "aws-scala-sbt", "aws-csharp", "aws-fsharp", "aws-go", "aws-go-dep", "aws-go-mod", "aws-ruby", "aws-provided", "tencent-go", "tencent-nodejs", "tencent-python", "tencent-php", "azure-csharp", "azure-nodejs", **"azure-nodejs-typescript"**, "azure-python", "cloudflare-workers", "cloudflare-workers-enterprise", "cloudflare-workers-rust", "fn-nodejs", "fn-go", "google-nodejs", **"google-nodejs-typescript"**, "google-python", "google-go", "kubeless-python", "kubeless-nodejs""knative-docker", "openwhisk-java-maven", "openwhisk-nodejs", "openwhisk-php", "openwhisk-python", "openwhisk-ruby", "openwhisk-swift", "spotinst-nodejs", "spotinst-python", "spotinst-ruby", "spotinst-java8", "twilio-nodejs", "aliyun-nodejs", "plugin", "hello-world"

```powershell: Create as "aws-nodejs-typescript"
serverless create -t aws-nodejs-typescript
```
説明は yaml ファイルだが、実際には typescript 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/e0f995d4-a8ef-d419-3ce1-4d17ad413b32.png)

で、deploy
```powershell: Deploy
serverless deploy
```

って普通にやると、Default の us-east-1 にされてしまうので、provider に region 追加してからだった・・
```typescript: region 追加
    region: "ap-northeast-1",
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/1e3d26d1-8d77-cbc9-d9dc-805d30a5e5ad.png)

非常に簡単に、あげられるのね、と感動

ただ・・以下が素人には課題
- sourcemap されてる
    - serverless.ts の設定で変えればOK
- middy されてる
    - 素人には、以下の点で困るところ
        - Lambda 上で簡単に修正することは出来ない。
        - middy や json-schema-to-ts を使わないコードに戻すか、別の Sample を探さないといけない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/b853cd91-98d0-25a0-049f-bc1fcaf8e1c4.png)

で、どうせ素人なので、SAM も試してみることに。

## エラーと対処
###　ts-node 不足
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/3838bed7-abd2-42d3-725a-8d05e148e8ad.png)

なんかエラーが出ると思って調べたら、typescript 用の場合、ts-node インストールしろって書いてある・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/97a32588-5ce0-6653-85f7-998eac608763.png)

https://www.serverless.com/framework/docs/providers/aws/guide/intro#alternative-configuration-format
```powershell: ts-node をinstall して終わり
npm install ts-node
```
### 権限不足
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/e3b74239-af31-d762-8e79-37bb8c31167c.png)

とりあえず、適当にアクセス権を追加して対処。
[ここ](https://gist.github.com/ServerlessBot/7618156b8671840a539f405dea2704c8) みたいな感じでちゃんと絞ってね、との記載有り。
最終的には、IAM Access Analyzer でアクセスに応じたポリシーしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/c57bfc4b-975b-8ab7-42d7-5ca384a464af.png)

https://www.serverless.com/framework/docs/providers/aws/guide/credentials/

https://us-east-1.console.aws.amazon.com/access-analyzer/home?region=us-east-1#/

### unable to verify the first certificate
Proxyなので、設定変更して確認

```powershell: プロキシ設定と確認
$env:http_proxy="http://*.*.*.*:****"
$env:https_proxy="http://*.*.*.*:****"
Get-ChildItem env:h*
```

### sls (serverless の alias) が効かない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/1a8d17fd-c383-b959-0636-34284e61a44a.png)
そのままだと、別物に定義されてるので、sls deploy とか効かないので注意

## Deployが遅いと感じた場合
[ここ](https://www.serverless.com/blog/quick-tips-for-faster-serverless-development/) を見て、"-f" オプション試してみたら・・・速い！！

```powershell: コードのみの Deploy
serverless deploy function -f {functionName}
```
functionName: module.exports.hello = の、"hello" の部分？
Zipのみの更新するので、超速い

## Offline 化
https://github.com/dherault/serverless-offline

Docker 入れずに動かせるのは便利、だけど、そこまで現時点では優先度高くない・・かな

### エラー対処
- npm ERR! code ERR_INVALID_URL
プロキシの設定でプロトコルを消してた・・
以下な感じになってたので、"http://" を追加
> 10.10.10.10:8080

nvm 入れてる場合の、プロキシは以下に　version 単位で設定
%appdata%\nvm{version}\etc\npmrc

# SAM を試してみる
https://aws.amazon.com/jp/serverless/sam/

## SAM のインストールから
https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/install-sam-cli.html

ダウンロード後、インストール。

Terminal を事前起動してたら、環境変数の反映の為に、Terminal を再起動

```powershell: version 確認
sam --version
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/5f9a2546-08cf-7c1f-99f5-cdb2e6a83ee4.png)

## [AWS 認証情報のセットアップ](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-getting-started-set-up-credentials.html)
既にやってあるはずなので Skip

## [チュートリアル: Hello World アプリケーションのデプロイ](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-getting-started-hello-world.html)

まずはやってみる
```powershell: initialize
sam init
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/b074cfc8-af5d-0895-b79c-b955509c4c08.png)
- Template の利用を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/13f9ee85-0fb9-cf6f-2d91-23dd9178a636.png)
- 一番簡単な Hello World で

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/7fcd83b0-d3d6-08d4-fb00-2be3f4e6d0c0.png)
- Node.js を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/02696eef-966b-e28a-c5df-1a538b653c45.png)
- Zip で

deploy 出来るものは、コンテナか コードzip か

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/gettingstarted-package.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/d8d88455-efab-f277-c1ab-68bfdf84b74d.png)
- TypeScript が選択出来た！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/18f42c98-366a-160e-21b9-9278190283e4.png)
- X-Ray は、本番の時にしか使わなくてよさげ

> AWS X-Ray は、リクエストのトレース、例外の収集、およびプロファイリングの機能を使用して、開発者の分散型アプリケーションの動作分析を容易にします。 

https://docs.aws.amazon.com/ja_jp/xray/index.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/0a538a3a-b63a-6472-c98f-3d0155b25775.png)

初期化が終わったので、ビルドへ

```powershell: build
cd sam-app
sam build
```

npm も、serverless も Current Directory にて init していくのに、sam は init するとフォルダ作ってくれるのね・・
先にフォルダ作っちゃったよ・・

build 成功するとこんな感じで、次のアクションを教えてくれる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/6ccd7269-410d-27ac-2678-e37e691f2e14.png)

で、いよいよ deploy

```powershell: deploy
sam deploy --guided
```

ガイド付きでデプロイなので、以下のように色々聞かれて、config が作成されるっぽい
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/7b87b407-4161-3f78-a182-99a1f4bfbd64.png)

無事成功
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/978802ae-cac1-b512-d715-c47be7056678.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/b6adba56-a6ee-0dfe-7b5e-5e563930a2ce.png)

Default だと minify & sourcemap: true なので false にしてみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/385e63b3-35cb-940e-0610-f3b5bdca16dc.png)

まぁ、Lambda 上で修正可能かな？という状況に。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/7d596d64-f279-75db-561e-37edbe98be18.png)

### エラーと対処
- MAX_PATH エラーが出たら、LongPathsEnabled を設定へ
    - regedit で `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem` を開いて、`LongPathsEnabled` を `0` to `1` へ<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/4402092b-6536-bd8b-c0a0-91ad1558d574.png)

- Git が入れてないと、最後の選択肢でエラー発生
    - Git Install して解消

https://git-scm.com/download/win


- sam build 時にエラー: Error: NodejsNpmEsbuildBuilder:EsbuildBundle
    - esbuild を install で対処
        - npm install esbuild
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/4c461476-e554-58d3-b7d9-2dc560b71369.png)

# AWS ToolKit
https://docs.aws.amazon.com/ja_jp/toolkit-for-vscode/latest/userguide/setup-toolkit.html

VS そのものでも良かったけど、VS2022 は業務でまだ使えないのと、2019 のライセンスコード探すの面倒ってのもあって、VS Code で

Tookkit 
## 前提条件(Prerequisite)
- node.js は nvm で対応済み。[npm download](https://nodejs.org/en/download/)
- AWS SAM CLI もSAM で対処済み
- Docker は とりあえず放置

## AWS Toolkit インストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/69c857b8-6128-e337-bbc3-0e89aee3fc57.png)

## AWS Explorer の設定
- region 追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/598c5fdb-f319-a820-ee05-082c35aaa08a.png)
対象 Region をチェックして、OK へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/ba1709b5-0347-1f84-b804-f18ee5b0f633.png)
こんな感じに
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/c9811e70-df6e-f031-0626-9e6cea3c4154.png)

これ、サービス毎に全部見えるのが素敵。
ただ、何もないサービスは見えないように出来ないものか・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/b48c5c98-f9c4-5dc0-7672-497feb56576a.png)

せっかくなので、Feedback として以下機能を送信しておいた
- 「No Custers found] の非表示☑
- custers 数をサービス名の横に表示
- フィルター機能 in Explorer

## 実際に活用？
https://docs.aws.amazon.com/ja_jp/toolkit-for-vscode/latest/userguide/serverless-apps.html#serverless-apps-debug

既に、SAM で sam-app を作ってたので、そこを利用していく

### デバッグ設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/a4b78028-d926-1b2b-e3f0-2b6a7139db60.png)

ただ、これするとしたら、Docker インストールが必要だったので、後で・・かな

## Deploy 方法
AWS Deploy Application ? 化と思ったら、Update Lambda?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/51f6b422-95af-5d43-a99b-f4b8230aa844.png)
Region 選択：Config 等で省略可能？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/0f691c6b-c3e0-efdf-ceb4-9023d12f5d79.png)
Zip or Directory
Directory なら、Local のプロジェクトフォルダを選択すればOK
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/dc2133ba-ba54-dfd5-679f-49da6c1619d4.png)
確認に対して、Yes するだけ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/99b612f3-9f9f-8ae7-cd65-e51d8a509062.png)
Upload 待ち
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/5b1d3101-ff16-a80f-646d-517e6a123014.png)
完了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/ab9f080e-5f8e-e35e-6f1a-5b7693f74503.png)

これなら、以下の方が楽なので、なんか設定がある筈・・
1. CTRL + @
1. sam deploy

## 今わかってる ToolKit の利点
- 利点
    - Explorer で Service が見られる
    - Lambda の場合の GUI 操作<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/3e07b269-3869-a665-8ab7-f42d7a061c39.png)
        - Invvoke はこんな感じ<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/c04ea8f6-1637-57ac-40c8-a20878863534.png)
        - Upload は、VSCode からのコマンドが動く程度で楽になる感じは無い


多分、sam コマンドを打つより楽な方法があるとは思うんだけど・・現状不明
まぁ、sam コマンドと併用していく感じで、少しずつ便利な機能を探していく・・かな。


# あとがき
とりあえず、 TypeScript のコードで、Lambda をあげられることは分かった。

課題がいっぱいあり過ぎて参るけど、少しずつ・・頑張るしかないね

今の課題としてはこの辺？
- SAM でのトリガー変更方法（デフォルトは API Gateway なので）
- ToolKit の便利な使い方
- AWS config の理解
- TypeScript の基礎（そもそも JavaScript すら知らん人なんですけどね :laughing: