この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
AWS上の複数サービスを連携させた処理を行いたい時やとりあえず一回手軽く動かしてみたいなーと思った場合、boto3を準備する手間に目を瞑るとAWS Lambdaがとても便利です。今ではMWAAという選択肢もありそうですが、これはこれでDAGの実装に一手間かかります。
boto3がLambda Layerへ勝手に仕込まれるようにしておけば、管理コンソール上からでもLambda関数化する際にLayerを使うように指定するだけで色々実験は可能だろうという目論見で、GitHub Actions上からboto3用のLambda Layer定期更新のWorkflowを組んでみることにしました。
ローカルの事前設定
homebrewで以下ライブラリをインストールしておきます。
brew install pyenv
brew install pipenv
brew install direnv
必要なバージョンのPythonのインストールも行っておきます。今回はGitHub ActionsのホストランナーUbuntu-20.04のPythonバージョンに合わせて3.8.10にしています。
専用リポジトリのセットアップ
GitHub上に以下のような設定でリポジトリを作成してcloneします。
git clone git@github.com:xxxxxxxx/boto3_layer.git
次にPipfile.lock作成のため、pipenv用設定の追加と仮想環境のセットアップを行います。
cd boto3_layer/
echo "3.8.10" >> .python-version
echo "export PIPENV_VENV_IN_PROJECT=true" >> .envrc
echo "layout pipenv" >> .envrc
pipenv install boto3
direnv allow .
これで必要なPipfile.lockが作成されました。
Lambda Layerの作成
次にLambda Layerの作成です。上記でセットアップしたvenvが存在するとlayerの作成がし辛いため仮想環境を一度削除します。
pipenv --rm
layer用のzipファイルを作成してアップします。
mkdir layer/
PIP_TARGET=./layer pipenv sync
zip -r boto3.zip ./layer
export AWS_PROFILE=XXXXX
aws lambda publish-layer-version --layer-name boto3 --zip-file fileb://boto3.zip --compatible-runtimes python3.8
以下実行ログ。
% mkdir layer/
% PIP_TARGET=./layer pipenv sync
% zip -r boto3.zip ./layer
adding: layer/ (stored 0%)
adding: layer/boto3-1.18.37.dist-info/ (stored 0%)
adding: layer/boto3-1.18.37.dist-info/RECORD (deflated 60%)
adding: layer/boto3-1.18.37.dist-info/LICENSE (deflated 65%)
adding: layer/boto3-1.18.37.dist-info/WHEEL (stored 0%)
...
% export AWS_PROFILE=XXXXX
% aws lambda publish-layer-version --layer-name boto3 --zip-file fileb://boto3.zip --compatible-runtimes python3.8
{
"Content": {
"Location": "https://awslambda-ap-ne-1-layers.s3.ap-northeast-1.amazonaws.com/snapshots/....",
"CodeSha256": "......",
"CodeSize": 9523215
},
"LayerArn": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXX:layer:boto3",
"LayerVersionArn": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXX:layer:boto3:1",
"Description": "",
"CreatedDate": "2021-09-08T07:28:12.932+0000",
"Version": 1,
"CompatibleRuntimes": [
"python3.8"
]
}
これでローカルからの作成は完了しました。
定期更新させる
次に定期的にLayerを更新させるようにします。まずはpipenv関係のコミット。
echo "layer/" >> .gitignore
git add -f Pipfile Pipfile.lock .envrc .python-version .gitignore
git commit -m'add pipfile settings'
git push origin HEAD
次にGitHub Actions用Workflowの作成を行います。
mkdir .github/workflows/
vim .github/workflows/layer_update.yml
git add .github/workflows/layer_update.yml
git push origin HEAD
layer_update.yml
の内容は以下の通り。
name: UpdateBoto3Layer
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * *'
jobs:
update:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- name: Install pipenv
shell: bash
run: |
python -m pip install --upgrade pip
python -m pip install pipenv
- name: Upload Lambda Layer
run: |
mkdir layer/
PIP_TARGET=./layer pipenv sync
zip -r boto3.zip ./layer
aws lambda publish-layer-version --layer-name boto3 --zip-file fileb://boto3.zip --compatible-runtimes python3.8
実行するとLayerとしてboto3が追加可能になり、追加後は関数内でimport可能になります。
import boto3
def lambda_hundler(event, context):
return {
'status': 'ok'
}
あとがき
boto3のimport用にcdkでスタックを作成するのも過剰かと思い、一番手軽に且つ定期的にアップできる手段を考えて見た結果今回の方法に至りました。
特にboto3に限ったものではないため、必要な共有ライブラリの更新手段として活用するのも一つの手です。