AWS SAM CLI で Lambda Layers が ビルドできるようになったよ


**Building Layers**
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/building-layers.html

```shell-session
$ sam build layer-logical-id
```

SAM CLI のバージョンが 0.50.0 以上である必要があります。

```shell-session
$ sam --version
SAM CLI, version 0.50.0
```

SAM CLI の基本的な使い方については、以前 Qiita にあげたのでこちらも参照いただければと思います。

**AWS SAM CLI 再入門 2019.12**
https://qiita.com/hayao_k/items/7827c3778a23c514e196

## 簡単な例
sam init で作成できる Python 3.8 の Hello World Example を例に考えます。

```shell-session
$ sam init --runtime python3.8

$ cd sam-app
$ tree
.
├── events
│   └── event.json
├── hello_world
│   ├── app.py
│   ├── __init__.py
│   └── requirements.txt
├── README.md
├── template.yaml
└── tests
    └── unit
        ├── __init__.py
        └── test_handler.py
```

requirement.txt を確認すると requests モジュールを使用していることがわかります。
(実際は app.py ではコメントアウトされているのですが。。)

```hello_world/requirements.txt
requests
```

これをレイヤー化するする場合、template.yaml の Resources を以下のように書き換えます。

```template.yaml
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Layers:
        - !Ref MyLayer
      Events:
        HelloWorld:
          Type: Api 
          Properties:
            Path: /hello
            Method: get

  MyLayer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      Description: Layer description
      ContentUri: 'my_layer/'
      CompatibleRuntimes:
        - python3.8
    Metadata:
      BuildMethod: python3.8
```

SAM CLI で Lambda Layers をビルドするには レイヤーリソース (例では MyLayer)の
メタデータ属性として BuildMethod を記述する必要があります。

```yaml
 Metdata:
      BuildMethod: python3.8
```

ContentUri に 記載したディレクトリを作成し、requirements.txt を移動します。

```shell-session
mkdir ./my_layer
mv ./hello_world/requirements.txt ./my_layer/
```

sam build MyLayer でレイヤーをビルドできます。

```shell-session
$ sam build MyLayer
Building layer 'MyLayer'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Deploy: sam deploy --guided
```

前述のとおり template.yaml に BuildMethod を指定していないとエラーになります。

```shell-session
$ sam build MyLayer
Layer <samcli.lib.providers.sam_function_provider.SamFunctionProvider object at 0x7f3147f93f90> is missing BuildMethod Metadata.
Error: Build method missing in layer MyLayer.
```
.aws-sam/build/MyLayer 配下に requests モジュールがダウンロードされていることがわかります。

```shell-session
$ tree -a -L 5
.
├── .aws-sam
│   └── build
│       ├── MyLayer
│       │   └── python
│       │       ├── certifi
│       │       ├── certifi-2020.4.5.1.dist-info
│       │       ├── chardet
│       │       ├── chardet-3.0.4.dist-info
│       │       ├── idna
│       │       ├── idna-2.9.dist-info
│       │       ├── requests
│       │       ├── requests-2.23.0.dist-info
│       │       ├── requirements.txt
│       │       ├── urllib3
│       │       └── urllib3-1.25.9.dist-info
│       └── template.yaml
├── events
│   └── event.json
├── .gitignore
├── hello_world
│   ├── app.py
│   └── __init__.py
├── my_layer
│   └── requirements.txt
├── README.md
├── template.yaml
└── tests
    └── unit
        ├── __init__.py
        └── test_handler.py
```

単に sam build とした場合はアプリケーション全体がビルドされますが、
今回の例の場合、hello_world/ 配下の requirements.txt が存在しないためエラーとなります。

```shell-session
$ sam build
Building function 'HelloWorldFunction'
Running PythonPipBuilder:ResolveDependencies

Build Failed
Error: PythonPipBuilder:ResolveDependencies - Requirements file not found: /tmp/sam-app/hello_world/requirements.txt
```

アプリケーションのディレクトリ配下の requirements.txt  にはデプロイパッケージに
含めるモジュールを記載し、Layer ディレクトリの requirements.txt には Lambda Layers に
含めるモジュールを記載していれば、sam build コマンドで全体をビルドできます。

あとはいつもどおり sam deploy すれば OK です。

```shell-session
$ sam deploy
or
$ sam deploy --guided
```

非常にシンプルかつ、簡単に実行できました。
ただ複数のランタイムバージョンやネイティブバイナリを扱う場合などは
これだけだと物足りない場合もあるかもしれません。
このあたりは 以前 docker-lambda を使用して Lambda Layers を作成する記事を書いたので
興味のある方は参照いただければと思います。

**Lambda Layersを作成する時はdocker-lambdaやyumdaが便利**
https://qiita.com/hayao_k/items/a6fd8ecfb1f937246314

簡単ですが、以上です。
参考になれば幸いです。