🐡

Lambdaレイヤー用のAWS CLIライブラリーZip作成

2024/11/14に公開

概要

LambdaからAWS CLIコマンドを利用できるようにLambdaのレイヤーにAWS CLI.v1(v2はPythonの依存関係のため使用が難しかった)を追加するためのZip作成のログを残します。

Lambda Layerの作成

Amazon Linux 環境(Lambda と同じ環境)で AWS CLI バージョン 1 をインストールし、それを Layer としてパッケージ化します。

# Amazon Linux コンテナで作業開始
docker run -it amazonlinux:2 /bin/bash
 
# 必要なパッケージをインストール
yum install -y python3 pip zip
 
# 仮想環境用ディレクトリの作成
mkdir awscli-virtualenv
 
# 仮想環境を作成
python3 -m venv awscli-virtualenv
 
# 仮想環境を開始
cd awscli-virtualenv/bin/
source activate
 
# AWS CLI バージョン 1 のインストール
pip3 install awscli

Python実行パスの変更

cat aws で見ればわかると思うが実行パスがLambda用にはなっていない。それを解消していく。

# vimでawsの中身を変更していく。
vi aws
---
#!/var/lang/bin/python <-ここをこれに変更してほしい
# Copyright 2012 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
 
#     http://aws.amazon.com/apache2.0/
 
# or in the "license" file accompanying this file. This file is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
import sys
import os
 
if os.environ.get('LC_CTYPE', '') == 'UTF-8':
    os.environ['LC_CTYPE'] = 'en_US.UTF-8'
import awscli.clidriver
 
 
def main():
    return awscli.clidriver.main()
 
 
if __name__ == '__main__':
    sys.exit(main())

AWS CLI関連パッケージをZIPにまとめる

Lambda Layerにアップロードするためにデプロイパッケージ化する!

#仮想環境終了
deactivate
 
#Lambda Layer用のデプロイ用のディレクトリを作成
cd ../..
mkdir awscli-lambda-layer
cd awscli-lambda-layer
 
#AWS CLI関連パッケージををコピー
cp ../awscli-virtualenv/bin/aws .
cp -r ../awscli-virtualenv/lib/python3.7/site-packages/* .
 
#ZIP化
zip -r ../awscli-lambda-layer.zip *

awscli_layer.zipをローカルマシンにコピーする

以下のコマンドを実行します。

docker cp <コンテナIDまたはコンテナ名>:/awscli_layer.zip .

Lambda Layer のアップロード

作成した awscli_layer.zip を AWS コンソールから Lambda Layer としてアップロードします。

これで完成!!

おまけ

Lambda関数でAWS CLIを実行してみる。

今回は、以下のPythonコードを実行します。

import subprocess
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def run_command(command):
    command_list = command.split(' ')

    try:
        logger.info("Running shell command: \"{}\"".format(command))
        result = subprocess.run(command_list, stdout=subprocess.PIPE);
        logger.info("Command output:\n---\n{}\n---".format(result.stdout.decode('UTF-8')))
    except Exception as e:
        logger.error("Exception: {}".format(e))
        return False

    return True

def lambda_handler(event, context):
    run_command('/opt/aws --version')

※コードはこちらを参考にしています。

そのまま実行するとタイムアウトしちゃうのでタイムアウト時間は適当に伸ばしてください。(*私は20sにしました)

CLI実行には、Pythonのsubprocess.run()を使用しています。

AWS CLIコマンドは、awsの代わりに/opt/awsに続く形で指定して実行します。 Lambda LayerとしてアタッチしたAWS CLIの実行ファイルawsが、/opt/awsに格納されているためです。

上記のコードを実行した結果、以下のようにAWS CLIのバージョンが表示されれば成功です。

---
aws-cli/1.18.176 Python/3.8.5 Linux/4.14.193-110.317.amzn2.x86_64 exec-env/AWS_Lambda_python3.8 botocore/1.19.16

---

同様に、他のAWS CLIコマンドも実行することが出来ます。

著者について

takumi0706です。エンジニアになりたい人でして、現在はバックエンド開発(フロントもちょっと)に注力しています。技術的な挑戦を続ける中で学んだことをアウトプットすることをなるたけ努力してます。

これからも技術的な知見を深め、共有していくことを目指していますので、ぜひフォローやフィードバックをお寄せください。



takumi0706

Discussion