APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

【AWS】Azure経験者でAWS初心者の私がPythonでLambdaに触れてみる

目次

はじめに

こんにちは、株式会社エーピーコミュニケーションズ クラウド事業部の佐藤です。 私は2025年2月にAPCに中途入社いたしました。前職ではAzureをメインに触っていたのですが、今後AWSを触る機会が多くなりそうなので早速AWSに触れてみて力を身に着けていこうと思います。

AWSを触ってみたい、Lambdaを触ってみたい、PythonでLambda動かしてみたいなど、初心者の方の第一歩の一助になれば幸いです。

この記事のゴール

  • AWSのLambdaにPythonで実装したHello World相当のソースコードをデプロイし、HTTPで結果の取得ができることを確認する。
    • Lambda上でpandas(外部モジュール)をimportする
      • 外部モジュールをどのように使用可能にするのか確認するため
    • URLクエリパラメーターで操作内容が分岐できるようにする
      • ?control=helloのときにHello Worldのメッセージをjsonで返却する
      • ?control=calcのときにpandasを利用して足し算を行い結果をjsonで返却する
        • 今回の目的はpandasの動作確認のみのため、足し算に使用する数値はユーザーが入力する仕様ではなくハードコーディングをしておく。
        • 今回は10 + 123.456を処理する

作業の流れ

  1. Pythonのソースコードを実装
  2. AWS上でLambda関数の作成と設定
    1. Lambda関数の作成
    2. レイヤーの設定
    3. 関数URLの設定
  3. PythonソースコードをLambdaへデプロイ
  4. 動作確認

取り上げないこと

  • API Managementやロードバランサーの設定など
    • 今回は関数URLを使用して動作確認を行いました。
  • 関数URLの認証
    • 今回は動作確認のみのため認証は無効にして確認しました。
  • zipファイルを用いたデプロイ、Pythonのレイヤー作成など
    • 下記「ハマったこと」に記載したのですが今回は用意されているレイヤーを追加したので、zipファイルを用いたデプロイやレイヤーの作成は行いませんでした。
    • 外部モジュールを手動でインストールする際には、Lambda関数のアーキテクチャとインストールするモジュールのアーキテクチャを合わせることに気を付けたほうがよさそうです。

作業

ハマったこと

作業全体を通じてハマったポイントを先に記載します。

  • zipファイルのデプロイについて docs.aws.amazon.com

    • 閲覧日: 2025年2月18日
    • 公式ドキュメントでは依存する外部モジュールをすべてzipファイルにまとめてデプロイする方法が記載されていますが、今回利用するpandasモジュールをこの方法でインストールしてからzipファイルにしてデプロイしようとすると容量が50MBを超えてしまうので失敗します
      • 解決策1. 用意されているレイヤーをLambda関数に追加する (この記事内で採用した方法)
        • 今回利用するpandasはAWS上でレイヤーが用意されているので、それを追加するだけでLambda関数内でpandasが利用可能になります。
      • 解決策2. レイヤーを自作する
        • 今回は解決策1で解決したため使用しませんでしたが自分でレイヤーを作る方法もあるようです。 docs.aws.amazon.com
        • AWS上でレイヤーが用意されていない外部モジュールを使いたいときはこちらの方法をとるほうが良さそうに見えます。(要調査)
    • 余談: Azure Functionsだとrequirements.txtを置くだけでよかったので、AWSのほうが一手間かかりますね。。。
      50MBを超えるzipファイルをアップロードしようとした際のエラー
  • AzureのようにVisial Studio Code上で操作が完結しない

    • Azureの場合、VScodeの公式拡張機能を入れることでGUI上だけでデプロイできたりログが見れたりと色んな操作ができたのですが、AWSではできないようです(それはそうという話かもですが。。。)
    • 以前はまったく気にしてなかったのですが、Azure(Microsoft)のプロダクトの強みを今さら感じているところです。。。

Pythonのソースコードを実装

docs.aws.amazon.com - 閲覧日: 2025年2月18日

  • ゴールに到達できるように今回実装したソースコードは以下です。
import pandas as pd
from typing import TypedDict

class HelloWorldResult(TypedDict):
    """
    ?control=helloの結果表示用
    """
    message: str

class CalcResult(TypedDict):
    """
    ?control=calcの結果表示用
    """
    value1: int
    value2: float
    answer: float

def get_hello_world(event, context) -> HelloWorldResult:
    """
    control=helloのときに実行される
    Hello Worldを返す
    """
    result = HelloWorldResult(
        message='Hello World!'
    )
    return result

def get_calc_result(event, context) -> CalcResult:
    """
    control=calcのときに実行される
    value1 = 10, value2 = 123.456を定義し、
    pandasのDataFrameにしてから足し算した結果を返す
    """
    # value1 と value2 を定義
    value1: int = 10
    value2: float = 123.456

    # DataFrameを作成
    data = {'Value1': [value1], 'Value2': [value2]}
    df = pd.DataFrame(data)

    # Value1 と Value2 を足し算
    calc_result = (df['Value1'] + df['Value2']).iloc[0]

    result = CalcResult(
        value1=value1,
        value2=value2,
        answer=float(calc_result)
    )
    return result

def lambda_handler(event, context):
    """
    Lambda関数のメイン部分
    """
    # クエリパラメータのチェック、controlが存在するか
    if not 'queryStringParameters' in event:
        return 'No query string'
    if not 'control' in event['queryStringParameters']:
        return 'No query string'
    control = event['queryStringParameters']['control']

    # helloとcalc以外は何もしないで終了
    if control == 'hello':
        return get_hello_world(event, context)
    elif control == 'calc':
        return get_calc_result(event, context)
    else:
        return 'Invalid query string'
###EOF
  • 実装のポイント
    • ファイル名はlambda_function.pyとし、メインとなる関数の名前はlambda_handlerとする。

      • 公式ドキュメントに記載のとおりこちらが標準設定なのですが、Lambdaのランタイム設定より任意のファイル名や関数名に変更できるようです。
      • 公式ドキュメントより引用 (閲覧日: 2025年2月18日)

        関数ハンドラーには任意の名前を付けることができますが、Lambda コンソールのデフォルト名は lambda_function.lambda_handler です。この関数ハンドラー名には、関数名 (lambda_handler) と、ハンドラコードが保存されているファイル (lambda_function.py) が反映されます。

    • URLクエリパラメーターはevent変数内のqueryStringParametersに格納されるので、ここから取得する。 docs.aws.amazon.com

      • 今回の例ではcontrolを取得し、helloのときとcalcのときで処理を分岐させています。
    • dict型の変数を返すことで、Lambda上ではjsonで取得が可能。
      • ソースコード内ではTypedDictで定義しています。

AWS上でLambda関数の作成と設定

  • AWSのコンソールからLambda関数を作成と設定を行います。
  • Lambda関数の作成
    • ランタイムはPython 3.13にする
      • 2025年2月18日時点の最新バージョンです。
  • レイヤーの設定
    • pandasを利用するために、Lambda関数のコンソールの「コード」タブの画面下部にある「レイヤー」で「レイヤーの追加」を行う。
      • 「レイヤーを追加」の画面では「AWSレイヤー」を選択し、AWSSDKPandas-Python313を選択し追加する。
        Lambda関数へのレイヤーの追加画面
        AWSSDKPandas-Python313のレイヤーを追加した状態
  • 関数URLの設定
    • HTTPでアクセスするために「設定」タブの「関数URL」より関数URLを作成する。
      • 今回は簡単な動作確認のみのため「認証タイプ」はNONEを選択する
      • NONEにすると認証機能が無効になり、該当のLambda関数が外部に公開された状態になるようなので、セキュリティ上問題がないかちゃんと確認が必要です。
      • 作成した関数URLは動作確認で利用します。

PythonのソースコードをLambdaへデプロイ

  • Lambda関数画面のコードソース内にlambda_function.pyを作成して、上記のソースコードを貼り付ける。
  • Deployボタンを押す。
    • デプロイする手段は色々あるようですが、今回はPythonのソースコードのファイルが1個だけなので、一番お手軽なコピペで対応しました。
      ソースコードを貼り付けた状態。画面左部にDeployボタン。

動作確認

ブラウザやcurlコマンドなどで関数URLにアクセスして動作確認をします。

  • 関数URLのみの場合
    • https://[生成されたURL]/

        No query string
      
    • ?control=を指定していないので実装した通りのエラーメッセージが表示される。
  • helloの場合
    • https://[生成されたURL]/?control=hello

        {"message":"Hello World!"}
      

      ?control=helloの結果

  • calcの場合
    • https://[生成されたURL]/?control=calc

        {"value2":123.456,"answer":133.45600000000002,"value1":10}
      
    • 今回は特に対策をしていないのでpandas(numpy)の丸め誤差の影響から, 10 + 123.456の答えが133.456とはなっていないです。
      ?control=calcの結果

ゴールに到達できました🎉

感想など

  • 何もない状態で作業を始めてからゴールに到達するまで4時間程度かかりました。元々PythonやAzure (Azure Functions)を触っていたこともあり勘所がすぐに掴めたからか比較的スムーズにできたかと思っています。
    • Serverlessは思いついてから実際に何かを動かすまでの敷居が低くて本当に素晴らしいですね。
  • 今回はHello Worldをゴールとしましたが、AWS SDK for Python (boto3)を利用すると他のAWSリソースと連携してできることの幅が広がりそうなのでチェックしてみようと思います。 aws.amazon.com
  • Node.js環境のTypeScript実装版もやってみたいです。