WSLへのServerlessFrameworkの導入

# 自己紹介

乙井です……。（ヒロシです風）
Gakken LEAPという EdTech の会社で丁稚エンジニアをやっております。
本稿では WSL への ServerlessFramework の導入についてご説明します。
なお前回は[remi で入る PHP アップグレード](https://qiita.com/GleapPost/private/b25bb1f3309e548d976e)という記事を書いたりしています。

# 目次

- [自己紹介](#自己紹介)
- [目次](#目次)
  - [前書き](#前書き)
  - [前提条件](#前提条件)
  - [コマンド](#コマンド)
    - [下準備1](#下準備1)
    - [Serverless Framework 導入](#serverless-framework-導入)
    - [ローカル実行](#ローカル実行)
    - [下準備2](#下準備2)
    - [デプロイ・リモート実行](#デプロイリモート実行)
  - [余談](#余談)
  - [★エンジニア募集！★](#エンジニア募集)

## 前書き

今回は淡々とコマンドを書いていきます。

## 前提条件

- WSL（Ubuntu）自体の導入は完了しているものとする。

## コマンド

### 下準備1

- apt アップデート

~~~bash
sudo apt update
sudo apt upgrade
~~~

- curl インストール

~~~bash
sudo apt-get install curl
~~~

- node.js インストール
  - [nvm](https://github.com/nvm-sh/nvm) インストール
    - 執筆時[最新版](https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating)

    ~~~bash
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
    ~~~

    - ※参考

    ~~~bash
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v{バージョン}/install.sh | bash
    ~~~

  - node.js インストール（安定版（LTS）のインストール）

  ~~~bash
  nvm install --lts
  ~~~

  - 確認

  ~~~bash
  node -v
  ~~~

### Serverless Framework 導入

- 導入
  - インストール

    ~~~bash
    npm install -g serverless
    ~~~

  - 確認

    ~~~bash
    serverless --version
    ~~~

  - 参考
    - 下記二つは同じコマンド（短縮形）

    ~~~bash
    serverless
    sls
    ~~~

    - デバッグオプション

    ~~~bash
    --verbose --debug="*"
    -v --debug="*"
    ~~~

- リポジトリ作成
  - 既存のGitリポジトリから落としてくる場合

  ~~~bash
  sls install -u [URI]
  ~~~

  - 新規作成の場合
    - 基本コマンド

    ~~~bash
    sls create --template <言語> --name <作成リポジトリ名> --path <作成リポジトリ名>
    ~~~

    - python3 での実行例

    ~~~bash
    sls create --template aws-python3 --name my-api --path my-api
    ~~~

    - ※使用可能な言語一覧（執筆時点）

    ~~~txt
    aws-nodejs
    aws-nodejs-typescript
    aws-nodejs-ecma-script
    aws-python
    aws-python3
    aws-kotlin-jvm-maven
    aws-kotlin-jvm-gradle
    aws-kotlin-nodejs-gradle
    aws-groovy-gradle
    aws-java-maven
    aws-java-gradle
    aws-scala-sbt
    aws-csharp
    aws-fsharp
    ~~~

- リポジトリ導入
  - コマンド例（リポジトリ新規作成）

    ~~~bash
    sls create -t aws-python3 --verbose --debug="*"
    ~~~

### ローカル実行

- 実行（引数なし）

  ~~~bash
  sls invoke local --function {関数名}
  ~~~

- 実行（引数あり）

  ~~~bash
  sls invoke local --function {関数名} --data {"key":"value"}
  ~~~

  - コマンド例（引数あり）

    ~~~bash
    sls invoke local --function hello --data {"id":"0"}
    ~~~

### 下準備2

- AWS連携
  - IAM の作成
    - まず AWS 側で Serverless Framework に対する IAM を作成する（手順は省略）
    - 権限は Administrator 権限が推奨されているが、どこまで絞った権限で使えるかの試行錯誤も各所でなされている。
    - 筆者の経験上では、S3 や DynamoDB や Lambda 等各必要サービスへのフルアクセス, IAM を作成操作する権限, Cloudwatch Logs の権限あたりを与えれば割と動く。このあたりは時間と気力が許すなら都度エラーと対話しながら絞った権限を付与していくのもあり。
      - 参考記事
        - [IAM権限を絞ったuserでserverlessを使う](https://blog.n-t.jp/post/tech/awscli-create-user-and-policy/)
        - [Serverless Framworkを使ってdeployするときの必要最低限の権限](https://qiita.com/adachi_you/items/ef06a1127b8bcddeafa3)
        - [【AWS x S3 x IAM】アプリから S3 にデータをアップロードするときの IAM 権限設定](https://qiita.com/tanakaworld/items/196300d556feada5737b)
  - AWS CLI の設定
    - 導入
      - 作業用一時ディレクトリ作成

        ~~~bash
        mkdir ~/tmp
        cd ~/tmp
        ~~~

      - AWS CLI ダウンロード, 解凍, インストール

        ~~~bash
        sudo curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
        unzip awscliv2.zip
        sudo ./aws/install
        ~~~

      - 確認

        ~~~bash
        aws --version
        ~~~

    - 設定
      - 使用する AWS の IAM の情報（アクセスキー, シークレットアクセスキー）, デフォルトで使用するリージョン, 出力フォーマットを設定する
      - 設定

        ~~~bash
        aws configure
        ~~~

      - 確認

        ~~~bash
        aws configure list
        ~~~

        - 確認結果例

        ~~~txt
        $ aws configure
        AWS Access Key ID [None]: YOUR1AMACCESSKEY4API
        AWS Secret Access Key [None]: ****************************************
        Default region name [None]: ap-northeast-1
        Default output format [None]: json
        $ aws configure list
            Name                    Value             Type    Location
            ----                    -----             ----    --------
        profile                <not set>             None    None
        access_key     ****************ABCD shared-credentials-file
        secret_key     ****************1234 shared-credentials-file
            region           ap-northeast-1      config-file    ~/.aws/config
        $
        ~~~

### デプロイ・リモート実行

- デプロイ

  ~~~bash
  sls deploy
  ~~~

  - serverless.yml の設定次第では都度オプションでデプロイ先を変える事も可能。
  - 参考例：serverless.yml

      ~~~yml
      custom:
        defaultStage: dev
        region:
          dev: us-west-2
          stg: ap-northeast-3
          prod: ap-northeast-1
      ~~~

  - 参考例：デプロイコマンド

      ~~~bash
      sls deploy --stage dev
      ~~~

  - 参考例：実行結果

      ~~~txt
      $ sls deploy -v --stage dev
      Framework Core: 3.27.0
      Plugin: 6.2.3
      SDK: 4.3.2

      $ sls deploy

      Deploying my-api to stage dev (us-west-2)

      ✔ Service deployed to stack my-api-dev (113s)

      endpoint: GET - https://example123.execute-api.us-west-2.amazonaws.com/users/create
      functions:
      hello: my-api-dev-hello (389 B)

      Monitor all your API routes with Serverless Console: run "serverless --console"
      $
      ~~~

    - ここで `endpoint` に表示されている URI がデプロイした各関数のエンドポイントとリクエストメソッド

- リモート関数実行

  ~~~bash
  curl <エンドポイント名>
  ~~~

  - POST で json データを送る場合

    ~~~bash
    curl <エンドポイント名> --data '{"key":"value"}'
    ~~~

  - 参考例

    ~~~bash
    curl https://example123.execute-api.us-west-2.amazonaws.com/users/create --data '{"username":"王定六"}'
    ~~~

## 余談

- WSL のディレクトリは直パスでだいたい下記にある（Windows 10）

~~~txt
C:\Users\[ユーザー名]\AppData\Local\Packages\CanonicalGroupLimited.[WSLパッケージ名]\LocalState\rootfs\home

C:
├─ \Users
│  ├─ \[ユーザー名]
│  │  ├─ \AppData
│  │  │  ├─ \Local
│  │  │  │  ├─ \Packages
│  │  │  │  │  ├─ \CanonicalGroupLimited.[WSLパッケージ名]
│  │  │  │  │  │  ├─ \LocalState
│  │  │  │  │  │  │  ├─ \rootfs
│  │  │  │  │  │  │  │  ├─ \home
│  │  │  │  │  │  │  │  │  ├─ \[WSLユーザー名]
~~~

- あまりショートカットは作らない方がいいらしいが、個人的には行き来に楽なのでローカルのGitHubディレクトリ（リポジトリ置き場）と相互にショートカットを作って置いている。

## ★エンジニア募集！★

Gakken LEAP では教育をアップデートしていきたいエンジニアを絶賛大募集しています！！
ぜひお気軽にカジュアル面談へお越しください！！
<https://gakken-leap.co.jp/recruit/>