🍣

【AWS】CLIベースでのlambdaの操作方法

に公開

lambdaをCLIベースで操作していきます。
言語はpython3です。

前提

  • Mac OSで、シェルはbash
  • brewとaws cliセットアップ済み

セットアップ

brew install python@3.12
python3.12 -V

mkdir lambda-practice && cd lambda-practice

# 仮想環境作成
python3.12 -m venv .venv

# 現在のシェルで仮想環境有効化
source .venv/bin/activate
python -V # 3.12になっているはず

lambdaアップロード用ファイル用意

まずは入れたいパッケージを入れます。

echo 'requests>=2.0,<3.0' > requirements.txt
pip install -r requirements.txt
pip list

次はコード(lambda_function.py)を書きます。
今回、ローカルでlambdaを試すSAM等のツールは使わないので、徐々にlambdaの書き方に寄せる方法を採用します。
まずはデバッグっぽく…

import requests

r = requests.get("https://httpbin.org/uuid", timeout=5)
data = r.json()
print(data)
# 実行
# 以下のようなレスポンスが返ることを期待します。
# {'uuid': '3ff681f9-c7cb-4822-9137-e45acfba0b37'}
python lambda_function.py

lambda向けにスクリプトを書き換えます。

import json
import requests

def lambda_handler(event, context):
    r = requests.get("https://httpbin.org/uuid", timeout=5)
    data = r.json()
    print(data) # CloudWatchのログに吐き出されます。便利です
    return {
        "statusCode": 200,
        "headers": {"Content-Type": "application/json"},
        "body": json.dumps({
            "uuid": data.get("uuid"),
            "event": event
        })
    }

lambdaアップロード用のファイル群一式を作成し、zip化します

# 対象ディレクトリをupload_packageとする
# 依存を入れる
pip install -r requirements.txt -t upload_package
# ファイル本体を入れる
cp lambda_function.py ./upload_package

# zip化
cd upload_package
zip -r ../function.zip .
cd ../

ロール調整

roleに対し、assume roleとpolicyを紐づけます。
このroleを当該lambdaに付与することにより、当該lambdaがAWSリソースに対する権限を得ることができます。
これは、特にCloudWatchのログに効いてきます。

まずはassume role用のjson(truct-policy.json)の作成からです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": { "Service": "lambda.amazonaws.com" },
            "Action": "sts:AssumeRole"
        }
    ]
}

roleの作成と、policyの付与を行います。

# role作成、assume roleの付与
aws iam create-role --role-name lambda-basic-exec --assume-role-policy-document file://trust-policy.json

# policyの付与
aws iam attach-role-policy --role-name lambda-basic-exec --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

# 確認
aws iam get-role --role-name lambda-basic-exec
aws iam get-role --role-name lambda-basic-exec --query "Role.Arn" --output text # よく見るテクニック

lambdaアップロード

コマンドでアップロードができます。

aws lambda create-function \
  --function-name {function_name} \
  --runtime python3.12 \
  --role {role_arn} \
  --handler lambda_function.lambda_handler \
  --zip-file fileb://function.zip \ # バイナリをアップするのでfileではなくfileb
  --architectures arm64

動作確認

# 実行。payloadをbase64エンコードするのが手間の場合、--cli-binary-format raw-in-base64-out
aws lambda invoke --function-name {function_name} --cli-binary-format raw-in-base64-out --payload '{"query": "ping"}' test_out.json

# 別タブでログをtail。print()の内容も下記で見れる
aws logs tail "/aws/lambda/{function_name}" --follow

再デプロイ

zipを作り直して、update-XXXでOKです。

aws lambda update-function-code \
  --function-name {function_name} \
  --zip-file fileb://function.zip

削除

aws lambda delete-function --function-name {function_name}
aws iam detach-role-policy --role-name lambda-basic-exec --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
aws iam delete-role --role-name lambda-basic-exec

結び

以上が簡単なlambdaの操作方法でした。

個人的な感想なのですが…、
別クラウドのサーバーレス・Functionサービスを使っていた際、すごくしんどいなと思うことがありました。
具体的には、とにかくデプロイ・E2Eで動作確認!としていたので、開発スピードが遅い自覚がありました。
それはきっと、GUIベースで操作していたことと、コードの実行までに関係しているサービスを理解していなかったことにあると思います。
各種サービス間の依存を把握しつつ、ドキュメントを読みながら試していくと、開発もデバッグもスムーズに進行できそうです。
すごく当たり前なことを書いてしまっていますが、動けばOK!としない態度を心がけようと思います。

参考

Discussion