紹介する内容
- localstackでlambdaを作ります
- localstackのdocker-entrypoint-initaws.dを使う。主にshell scriptを使います
- ユーザーが指定したディレクトリにpackageをインストールします
- インストールしたpackageをzipに固めます
結論
-
lambdaのpackageのインストールを別のdockerコンテナにしたら、いろんな言語のpackageインストールに対応できます
- localstackのコンテナにpythonのvenvなどのバージョン管理ツールをインストールして使う手もあります。ですが、言語ごとにツールの使い方を思えるより、dockerの使い方を覚えて全言語をカバーする方が効率的だと思いました
-
localstackのdocker-entrypoint-initaws.dでshell scriptでプロビジョニングは限界がある
- 二つ以上のリソースが連携する形では戻り値のAWSのARNなどの扱いが大変です
紹介始めます
localstack紹介
実のAWSを使わずにいろいろ試せるものです。
バージョン0.11.0から大きな変化がありました。本記事は0.11.0バージョンのlocalstackを使います
https://github.com/localstack/localstack
ディレクトリ構成
全体ソースコードは https://github.com/cheekykorkind/qiita-example/tree/master/localstack/0.11.0/init-by-shell で確認できます
localstack構築
docker composeを使います。
version: '3'
services:
pip_installer:
container_name: 'pip_installer'
image: python:3.7-alpine3.10
tty: true
working_dir: /workspace/sam-lambda
environment:
LAMBDA_ZIP_PATH: /workspace/sam-lambda/hello_world/lambda.zip
volumes:
- ./sam-lambda:/workspace/sam-lambda
localstack:
container_name: 'localstack-dev'
image: localstack/localstack:0.11.0
ports:
- '4566:4566'
environment:
SERVICES: lambda,logs,dynamodb
DEBUG: 1
HOSTNAME_EXTERNAL: localstack
EDGE_PORT: 4566
PORT_WEB_UI: 8080
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
AWS_DEFAULT_REGION: us-east-1
LAMBDA_ZIP_PATH: /workspace/sam-lambda/hello_world/lambda.zip
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./initaws:/docker-entrypoint-initaws.d
- ./tmp/localstack:/tmp/localstack
- ./sam-lambda:/workspace/sam-lambda
depends_on:
- pip_installer
docker-composeのvolumes(マウント)設定
-
localstackコンテナ
- packageインストールやzipファイル共有するために、AWS SAMプロジェクトをマウントしておきます。
-
./sam-lambdaは絶対パスqitta-example/localstack/0.11.0/init-by-shell/sam-lambdaと同じです
-
- localstackの
docker-entrypoint-initaws.d機能を使うためにマウントして置きます-
./initawsは絶対パスqitta-example/localstack/0.11.0/init-by-shell/initawsと同じです
-
- packageインストールやzipファイル共有するために、AWS SAMプロジェクトをマウントしておきます。
-
pip_installerコンテナ
- packageインストールやzipファイル共有するために、AWS SAMプロジェクトをマウントしておきます。
-
./sam-lambdaは絶対パスqitta-example/localstack/0.11.0/init-by-shell/sam-lambdaと同じです
-
- packageインストールやzipファイル共有するために、AWS SAMプロジェクトをマウントしておきます。
docker-composeの環境変数設定
-
localstackコンテナ
-
SERVICES、DEBUG、HOSTNAME_EXTERNAL、EDGE_PORT、PORT_WEB_UIはlocalstack固有の環境変数です。localstackを調べると理解できると思います -
AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、AWS_DEFAULT_REGIONはaws cliを便利に使うために設定しました -
LAMBDA_ZIP_PATHはlambda生成に使うzipファイルの位置を書きました。コンテナ2つが連携して作業するから管理しやすくするために設定しました
-
-
pip_installerコンテナ
-
LAMBDA_ZIP_PATHはlambda生成に使うzipファイルの位置を書きました。コンテナ2つが連携して作業するから管理しやすくするために設定しました
-
docker-compose upによる作業の流れ
- pip_installerコンテナが作れる
- localstackコンテナが
depends_onしているから、localstackコンテナより先に作られます -
tty: trueオプションによって、作れた後もup状態を維持します
- localstackコンテナが作れる
- コンテナが作れた後、localstack固有の
もろもろ初期化作業が行われます
- docker-entrypoint-initaws.dディレクトリにあるshファイルを名前順で実行します
- localstackの固有機能です。
-
もろもろ初期化作業が終わったら、マウントしているqitta-example/localstack/0.11.0/init-by-shell/initawsの00_create_lambda_zip.sh、01_lambda.sh順で実行してくれます
- 00_create_lambda_zip.sh
- 待機していたpip_installerコンテナにdockerコマンドで入ります
- pythonのpackageをディレクトリ
qitta-example/localstack/0.11.0/init-by-shell/sam-lambda/hello_world/packagesに指定し、インストールします - pythonコード及びインストールしたpackageたちをzipで固めて
$LAMBDA_ZIP_PATHに置きます - pip_installerコンテナを終了し、削除します
- 01_lambda.sh
- aws cliを使って、lambdaを作ります。zipの位置は
00_create_lambda_zip.shの作業で指定した$LAMBDA_ZIP_PATHにします - lambdaが作られます
localstackで作ったlambdaを試します
docker-compose up -d && docker attach localstack-dev します
cd qitta-example/localstack/0.11.0/init-by-shell
docker-compose up -d && docker attach localstack-dev
docker attach localstack-devしているあからlocalstackコンテナの作業が見れます

pythonのpackageがpipによってインストールされてます
インストール終了後、zipで固めてます
lambdaが生成されました
コンソールをもう一個開いて、localstackのlambdaにinvokeします
左側が docker attach localstack-dev している方、右側が docker exec -it localstack-dev /bin/bash してlambdaをinvokeする方です。
200返すことからちゃんと動いた確認が取れました。

lambdaのコードはrequestsパッケージを使ってGET一回投げることをしています。
qitta-example/localstack/0.11.0/init-by-shell/sam-lambda/hello_world/app.py





