2017年頃からサーバレスに浸っている、小西啓介です。
SAM CLIでは、Lambdaに近い環境でビルドできる
SAM(Serverless Application Model) CLI のビルドコマンド(sam build
)には、
Lambda用の npm
や pip
などで、アーキテクチャ(WindowsかLinux等)に依存するモジュールが有る場合に対応する
オプション (--use-container
)がある。
このオプションを使用すると、通常、実行環境(windows等)で行うビルド処理を、Lambda(Amazon Linux) に近い
Docker環境内で行うようなるため、コンパイルを伴うような場合でも問題なく(※文末参照 2020/07/10追記)、Lambda用のリソースを作成することが可能となる。
Proxyの憂鬱
ここにも、毎度おなじみのProxyの憂鬱がある。
PS C:\Users\komikoni\workspace\sam app> sam build --use-container
Building function 'NodeFunc'
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
Fetching lambci/lambda:build-nodejs12.x Docker container image......
Mounting C:\Users\komikoni\workspace\sam app\node-function as /tmp/samcli/source:ro,delegated inside runtime container
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
Build Failed
Error: NodejsNpmBuilder:NpmInstall - NPM Failed: npm ERR! code ENOTFOUND
npm ERR! errno ENOTFOUND
npm ERR! network request to https://registry.npmjs.org/jsonwebtoken failed, reason: getaddrinfo ENOTFOUND registry.npmjs.org
npm ERR! network This is a problem related to network connectivity.
npm ERR! network In most cases you are behind a proxy or have bad network settings.
npm ERR! network
npm ERR! network If you are behind a proxy, please make sure that the
npm ERR! network 'proxy' config is set properly. See: 'npm help config'
npm ERR! A complete log of this run can be found in:
実行環境が、Proxy経由でインターネットに繋がっている場合、
当然、Docker内からもProxy経由でしかインターネットに繋ぐことが出来ない為、
Docker インスタンスに対して、環境変数等でProxy設定を与えてあげる必要がある。
しかし、SAM のビルドコマンド(sam build
)で、実行する場合、動的にDockerインスタンスを作成し
ビルドが終了すると自動的に削除される為、Proxyを与えることが難しかった。
※Docker Desktopのproxy設定は、Docker Imageをダウンロードする際に使用するProxy設定で、Docker Image内には適用されない。
この課題は、以下のIssueに上がっている。
そこで、SAM では、 Docker SDK >= 3.7.0 でサポートされた、global docker configuration file. 機能を使って、
外部からProxy設定を可能となるよう対応が行われた。
既に、上記のPull Request は、マージされてReleaseされているですが、
特にドキュメント上には、記載がなさそうなので、ここに書き残したいと思います。
global docker configuration file の設定
設定方法は、以下の記事 @2fbCvmiYKX さんの記事や Dockerのドキュメントが詳しいが、
- Docker Desktop for Windows の proxy 設定 - Qiita
- Configure Docker to use a proxy server | Docker Documentation
%USERPROFILE%\.docker\config.json
の編集し
{
"auths": {
"https://index.docker.io/v1/": {}
},
"credsStore": "desktop",
"experimental": "enabled",
"stackOrchestrator": "kubernetes"
}
を以下のように修正する
{
"auths": {
"https://index.docker.io/v1/": {}
},
"credsStore": "desktop",
"experimental": "enabled",
"stackOrchestrator": "kubernetes",
"proxies": {
"default": {
"httpProxy": "http://proxy.example.com:8080",
"httpsProxy": "http://proxy.example.com:8080",
"noProxy": "no_proxy.example.com"
}
}
}
これで、以下の通り、Proxy環境下であっても、SAM CLI の Docker内(--use-container) ビルドを実施することが、可能となる。
PS C:\Users\komikoni\workspace\sam app> sam build --use-container
Starting Build inside a container
Building function 'AuthFunc'
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
Fetching lambci/lambda:build-nodejs12.x Docker container image......
Mounting C:\Users\komikoni\workspace\sam app\node-function as /tmp/samcli/source:ro,delegated inside runtime container
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrc
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUpNpmrc
Building function 'NodeFunc'
Fetching lambci/lambda:build-nodejs12.x Docker container
image..............................................................................................................................................................................................................
Mounting C:\Users\komikoni\workspace\sam app\node-function as /tmp/samcli/source:ro,delegated inside runtime container
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrc
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUpNpmrc
Building function 'PythonFunc'
//./pipe/docker_engine
//./pipe/docker_engine
Fetching lambci/lambda:build-python3.6 Docker container image..............................................................................................................................................................................................................
Mounting C:\Users\komikoni\workspace\sam app\python-function as /tmp/samcli/source:ro,delegated inside runtime container
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
//./pipe/docker_engine
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
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource
PS C:\Users\komikoni\workspace\sam app>
実行ファイルのパーミッションについて (2020/07/10追記) → (2020/10/30解消)
一点書き忘れました、 --use-container
を利用した場合、コンパイルを伴うビルドも可能ですが、実行ファイルに関しては、問題があります。
基本的に、Windowsでは、パーミッション設定が行えずZip化する場合もパーミッションが付与されない為、Lambda内で実行する際にパーミッションエラーとなります。
上記の通り、Issueが上がっていますが、2020/07/10現在まだマージされておらず、
以下のいずれかの方法を取る必要があります。
- Windowsから、
--use-container
を使うのではなく、LinuxにSAM を入れでビルドを行う。 - sam build 、 sam deploy やcfn deploy を使わず、自分でZip化し、パーミッションを設定する。
- Lambda上で、パーミッションを変更する。
※ 3.
について、Zipで上げたファイルの自体は、領域としてパーミッション変更できない為、
一度 /tmp
にコピーしてからパーミッションを変更して、実行する必要があります。
早くIssueが取り込まれることを期待したいですね。
ついに取り込まれて解消しました。
SAM CLI Release 1.7.0 で
2020/10/30に解消しました。
7d5101a - Fix: Missing Unix Permission Bits for Artifact ZIP Created in Windows (#2193)
と記載がある通り、上記Issueが解消しました。(実際は別Issue のGo周りの対応で解消された)