【Serveless Framework V.2対応】serverless.ymlのinclude/excludeを利用してzipにまとめるファイルを選択する方法


2020/04/21
2021/06/20

Serverless Framework(以降SLS)からAWS Lambdaへデプロイする時にはzipファイルに自動で全てのファイルがまとめられます。

ビルドからデプロイまでAWSへ自動一括処理してくれるのが便利な反面、全てをお任せで自動化させて、うっかりするとデプロイ後のS3のバケットに見せたく無いファイルまでアップロードされてしまう恐れがあります。

今回は勝手にまとめて欲しくないファイルを
serverless.ymlexcludeオプションを利用することで、zipにまとめるファイルから除外する方法を紹介します。


SLS Ver.1(旧式)でまとめる

本内容の動作確認時(2021年6月)で、最新のSLSのバージョンが2.47.0となっています。

現行のSLS V.2と、この節の内容であるSLS V.1系のyamlファイルの記述作法が異なるので、SLS V.2対応の話は次節にお進みください。

【SLS Ver.1の場合】excludeオプションなしのserverless.ymlを使用した場合

一例としてAngularプロジェクト(手元の環境ではcli@11.0.0以降で動作確認)でプロジェクトをAWSサービスにデプロイする際に、excludeを適切に処理しない場合、以下のように困った具材までzipされてアップロードされてしまいます。

            
            $ tree
.
├── Dockerfile
├── README.md
├── angular.json
├── dist
│   ├── browser
│   │   ├── 3rdpartylicenses.txt
│   │   ├── hogehoge.woff
│   │   ├── hogehoge.ttf
│   │   ├── hogehoge.woff2
│   │   ├── assets
│   │   │   └── personal_logo.svg
│   │   ├── es2015-polyfills.js
│   │   ├── favicon.ico
│   │   ├── index.html
│   │   ├── main.js
│   │   ├── polyfills.js
│   │   ├── robots.txt
│   │   ├── runtime.js
│   │   ├── sitemap.xml
│   │   └── styles.css
│   ├── prerender.js
│   ├── server
│   │   ├── main.js
│   │   └── main.js.map
│   ├── server.js
│   └── static
│       ├── 3rdpartylicenses.txt
│       └── hogehoge.woff
├── docker-compose.yml
├── lambda.js
├── local.js
├── ng-toolkit.json
├── node_modules
│   ├── aws-serverless-express
│   ├── binary-case
│   ├── media-typer
│   ├── mime-db
│   ├── mime-types
│   └── type-is
├── package.json
├── prerender.ts
├── server.ts
├── serverless.yml
├── static.js
├── static.paths.ts
├── tsconfig.json
├── tslint.json
├── webpack.server.config.js
├── yarn-error.log
└── yarn.lock
        
個人的には実質のビルド生成物であるdistフォルダが適切にアップロードされていればいいのですが、なんかプライベートな具材まで綺麗にタタミこまれちゃってます。これでは、AWSアカウント情報を記述したファイルが混入していたら、万が一、悪意ある第三者に流出した場合にセキュリティー的な問題が発生します。

【SLS Ver.1の場合】serverless.ymlでのexcludeオプションの記述例

早速流出させたくないファイルをserverless.ymlファイルのexcludeタグに追加していきます。

            
            #...中略
package:
  exclude:
   - README.md
   - .DS_Store
   - .dockerignore
   - .editorconfig
   - .npmrc
   - .vscode/**
   - Dockerfile
   - docker-compose.yml
   - yarn-error.log
   - yarn.lock
   - angular.json
   - compress.js
   - local.js
   - ng-toolkit.json
   - prerender.ts
   - server.ts
   - static.js
   - static.paths.ts
   - tsconfig.json
   - tslint.json
   - webpack.server.config.js
#...以下略
        
ビルドに使用する設定ファイルや、ローカルテストに使ったソースコードも要らないので、ジャンジャンexcludeします。

これを利用してプロジェクトをビルドすると、以下のようにスッキリとしたzipパッケージになりました。

            
            $ tree
.
├── dist
│   ├── browser
│   │   ├── 3rdpartylicenses.txt
│   │   ├── hogehoge.ttf
│   │   ├── hogehoge.woff
│   │   ├── hogehoge.woff2
│   │   ├── assets
│   │   │   └── personal_logo.svg
│   │   ├── es2015-polyfills.js
│   │   ├── favicon.ico
│   │   ├── index.html
│   │   ├── main.js
│   │   ├── polyfills.js
│   │   ├── robots.txt
│   │   ├── runtime.js
│   │   ├── sitemap.xml
│   │   └── styles.css
│   ├── prerender.js
│   ├── server
│   │   ├── main.js
│   │   └── main.js.map
│   └── server.js
├── lambda.js
├── node_modules
│   ├── aws-serverless-express
│   ├── binary-case
│   ├── media-typer
│   ├── mime-db
│   ├── mime-types
│   └── type-is
└── package.json
        
以上が、serverless.ymlexcludeオプションの簡単な使い方になりますが、不要なリソースも除外することでzipサイズ自体の容量も抑制出来ることが期待できます。

デプロイするパッケージに関する詳細は
公式の説明 | AWS - Packagingをご覧ください。


SLS Ver.2(現行)でまとめる

前節のSLS V.1のpackageフィールドの記述形式ではSLS V.2からは非推奨となりました。

おそらくそのままV.2に引き上げると、

            
            $ sls deploy
#...中略
Error: No file matches include / exclude patterns
    at globby.then.allFilePaths (/usr/local/lib/node_modules/serverless/lib/plugins/package/lib/packageService.js:234:13)
#....
        
と言ったように、No file matches include / exclude patternsというエラーが発生するようになりました。

どうやらSLS V.2での仕様変更で、
excludeフィールドはすべてのファイルを除外するための利用に限定されてしまうため、一旦すべてを除外してからZipパッケージに含むファイルを指定するinclude-exclude patternsで呼び出すことになったようです。

つまりはSLS V.1では
パッケージから除外したいものを主体として記述する形式でしたが、SLS V.2からはパッケージへ同梱したいものという視点でpackageフィールドを作り直さないといけません。

            
            #...中略
package:
  exclude:
    - '**'
  include:
    - 'dist/**'
    - 'lambda.js'
    - 'node_modules/@vendia/**'
    - 'node_modules/aws-serverless-express/**'
    - 'node_modules/binary-case/**'
    - 'node_modules/type-is/**'
    - 'node_modules/media-typer/**'
    - 'node_modules/mime-types/**'
    - 'node_modules/mime-db/**'
#...以下略
        
以上のように、V1とV2ではZipするパッケージの記述方法がガラッと変わりましたので気を遣う必要があります。

なお、awsへSLS V.2でSAMアプリをデプロイする場合に、
node_modules/@vendia/**を含める必要がある場合があります。

AWS Lambda側でライブラリが足りていない場合のエラーはクライアント環境では検知することができないので、AWS CloudWatchのダッシュボードから該当のLambdaのロググループの中身でエラーの内容を対処しましょう。

合同会社タコスキングダム|蛸壺の技術ブログ


まとめ

このブログ執筆次点で、もう間もなくSLS V.3がローンチされる予定ですが、V.3ではpackageタグの記述作法が変更になる予定ですので、現状でまだSLS V.1のプロジェクトで扱っている方は早めにSLS V.2への移行を検討したほうが賢明かも知れません。


参考サイト

Layer Service: No file matches include / exclude patterns

AWS Lambda + Angular web app throwing “Error: Cannot find module '@vendia/serverless-express'”


Angularの学び方

Serverless FrameworkはJSフレームワークと併せて使うことが一般的かと思いますが、著者的にはAngularとSLSの組み合わせで使うことが多いです。

主要なJavascriptのフレームワークの一角であるAngularは、現在Google主導で開発が進められている玄人フロントエンジニア向けのフレームワークです。

Angularを使えばかなり高度なWebアプリも自由に作成できるのですが、やはり初心者が独学で勉強しようとおもうとかなりの知識が必要でAngularは挫折しやすいと言われています。

特にAngularを使う上で注意が必要なのは半年に一回のペースでプログラムのメジャーバージョンが繰り上がるので、他のフレームワークと比べても格段に技術を追っかけるスピードが早いことも躓く人が多い一因になっているとも思います。

Udemyの動画講座では、基礎からじっくり学べるためより実践的なスキルを身につけることが可能です。以下の講座ではAngular初心者向けに簡単なプロジェクトの作成まで学ぶことができます。

より実践的にフロントエンジニアとして重宝されるためにはSPA(シングルページアプリケーション)をある程度作成できるスキルが必要になりますので、さらに学びたい方は以下のような講座も用意されています。

他にもAngularプログラミングの習得度に応じた講座も多数用意されているので、必要に応じて試されてはいかがでしょうか。
記事を書いた人

記事の担当:taconocat

ナンデモ系エンジニア

主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。