Lambda

Lambda handler

まずは、Lambda handlerのコードから始めます。

  1. プロジェクトツリーの最上位のディレクトリに lambdaディレクトリを作成し、 (hello フォルダの隣).
  2. lambda/hello.py を作成して以下のコードを追加します。

    import json
    
    
    def handler(event, context):
    print('request: {}'.format(json.dumps(event)))
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'text/plain'
        },
        'body': 'Hello, CDK! You have hit {}\n'.format(event['path'])
    }

これは、 「Hello、CDK!」 というテキストを返す単純なLambda関数です。関数の出力には、HTTPステータスコードとHTTPヘッダーも含まれます。これらは、ユーザーへのHTTPレスポンスを返すために、API Gatewayを経由して送信されます。

AWS Lambdaコンストラクトライブラリをインストールする

AWS CDKには、AWS Construct Libraryと呼ばれる広範なコンストラクトライブラリが付属しています。コンストラクトライブラリは、AWSサービスごとに1つの モジュール に分割されます。たとえば、AWS Lambda関数を定義する場合、AWS Lambdaコンストラクトライブラリを使用する必要があります。

AWSコンストラクト学ぶためには、 AWS Construct Library reference を参照してください。

使用するには、 pip install コマンドを実行してAWS Lambdaモジュールをインストールし、プロジェクトに必要な依存関係をすべて解決します。

pip install aws-cdk.aws-lambda

このワークショップでのコピー、ペーストに関するいくつかの助言

このワークショップでは、コピー、ペーストをするのではなく、実際にCDKのコードを入力することを強く推奨します(通常、入力する量は多くありません)。これにより、CDKの使い方についてより理解していただけるものとなります。IDEがオートコンプリート、インラインドキュメント、およびタイプセーフに対応しているのがご理解いただけるでしょう。

AWS Lambda関数をスタックに追加

import ステートメントを hello/hello_stack.py の冒頭に挿入し、, lambda.Function をスタックに追加します。

from aws_cdk import (
    core,
    aws_lambda as _lambda,
)


class MyStack(core.Stack):

    def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # Defines an AWS Lambda resource
        my_lambda = _lambda.Function(
            self, 'HelloHandler',
            runtime=_lambda.Runtime.PYTHON_3_7,
            code=_lambda.Code.asset('lambda'),
            handler='hello.handler',
        )

注目すべきいくつかの点:

  • aws_lambdaモジュールを_lambdaとしてインポートしています。なぜなら、lambdaはPythonのビルトイン識別子として存在するからです。
  • この関数はPython3.7ランタイムを使用します
  • ハンドラーコードは、先程作った lambda ディレクトリからロードされます。パスは、プロジェクトのルートディレクトリから相対パスで cdk コマンドが実行されます。、プロジェクトのルートディレクトリである実行元からの相対パスです。
  • ハンドラー関数の名前は hello.handler (「hello」はファイル名、「handler」は関数名です)

コンストラクト(constructs) と コンストラクター(constructors) について

ご覧のとおり、両方のコンストラクタークラス MyStacklambda.Function (およびCDKの他の多くのクラス)にはシグネチャ(scope, id, **kwargs)が含まれています。 これらのすべては コンストラクト であるため、 CDKアプリの基本的な構成要素となっています。 それらは、スコープを介してより高いレベルの抽象化に一緒に構成できる抽象的な「クラウドコンポーネント」を表します。 スコープにはコンストラクトを含めることができ、そのコンストラクトには他のコンストラクトなどを含めることができます。

コンストラクトは常に別のコンストラクトのスコープ内で作成され、作成されたスコープ内で一意でなければならない識別子を常に持っている必要があります。したがって、コンストラクト初期化子(コンストラクター)には常に次のシグネチャが必要です。

  1. scope: 最初の引数には、この構成が作成されるスコープを必ず指定します。ほとんどすべての場合、現在の コンストラクトスコープ内でコンストラクトを定義することになります。つまり、通常this は最初の引数に渡すだけです 。

  2. id :2番目の引数は、構造の ローカルID です。これは、同じスコープ内のコンストラクト間で一意である必要があるIDです。CDKはこのIDを使用して、 このスコープ内で定義された各リソースのCloudFormation 論理IDを計算します。CDKのIDの詳細については、CDKユーザーマニュアルを参照してください。

  3. **kwargs : 最後の(場合によってはオプションの)引数は、初期化プロパティのセットです。これらは各構成に固有です。たとえば、 lambda.Function コンストラクトはruntimecodehandlerのようなプロパティを受け入れます。 IDEのオートコンプリートまたはオンラインドキュメントを使用して、さまざまなオプションを調べられます。

差分

コードを保存し、デプロイする前に差分を見てみましょう。

cdk diff hello-cdk-1

出力は次のようになります。

The hello-cdk-1 stack uses assets, which are currently not accounted for in the diff output! See https://github.com/awslabs/aws-cdk/issues/395
IAM Statement Changes
┌───┬────────────────────────┬────────┬────────────────────────┬────────────────────────┬───────────┐
│   │ Resource               │ Effect │ Action                 │ Principal              │ Condition │
├───┼────────────────────────┼────────┼────────────────────────┼────────────────────────┼───────────┤
│ + │ ${HelloHandler/Service │ Allow  │ sts:AssumeRole         │ Service:lambda.amazona │           │
│   │ Role.Arn}              │        │                        │ ws.com                 │           │
└───┴────────────────────────┴────────┴────────────────────────┴────────────────────────┴───────────┘
IAM Policy Changes
┌───┬─────────────────────────────┬─────────────────────────────────────────────────────────────────┐
│   │ Resource                    │ Managed Policy ARN                                              │
├───┼─────────────────────────────┼─────────────────────────────────────────────────────────────────┤
│ + │ ${HelloHandler/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBas │
│   │                             │ icExecutionRole                                                 │
└───┴─────────────────────────────┴─────────────────────────────────────────────────────────────────┘
(NOTE: There may be security-related changes not in this list. See http://bit.ly/cdk-2EhF7Np)

Parameters
[+] Parameter HelloHandler/Code/S3Bucket HelloHandlerCodeS3Bucket4359A483: {"Type":"String","Description":"S3 bucket for asset \"hello-cdk-1/HelloHandler/Code\""}
[+] Parameter HelloHandler/Code/S3VersionKey HelloHandlerCodeS3VersionKey07D12610: {"Type":"String","Description":"S3 key for asset version \"hello-cdk-1/HelloHandler/Code\""}
[+] Parameter HelloHandler/Code/ArtifactHash HelloHandlerCodeArtifactHash5DF4E4B6: {"Type":"String","Description":"Artifact hash for asset \"hello-cdk-1/HelloHandler/Code\""}

Resources
[+] AWS::IAM::Role HelloHandler/ServiceRole HelloHandlerServiceRole11EF7C63 
[+] AWS::Lambda::Function HelloHandler HelloHandler2E4FBA4D 

上記のとおり、このコードから AWS::Lambda::Function リソース用のCloudFormationテンプレートを生成しました。また、ツールキットがハンドラーコードの場所を伝達するためにいくつかのCloudFormationパラメーターを利用しています。

デプロイ

次にデプロイをします。

cdk deploy hello-cdk-1

cdk deploy を実行すると、CloudFormationスタックをデプロイするだけでなく、初期構築したS3バケットに対して、ローカルの lambda ディレクトリを圧縮後、アップロードしていることがが分かるでしょう。

Lambda関数のテスト

AWS Lambdaコンソールに移動して、Lambda関数をテストしましょう。

  1. AWS Lambdaコンソールを開きます(正しいリージョンにいることを確認してください)。

    Lambda関数が表示されます。

  2. 関数名をクリックして、コンソールを移動します。

  3. テスト ボタンをクリックして、 テストイベントの設定 ダイアログを開きます。

  4. イベントテンプレート リストから Amazon API Gateway AWS Proxy を選択します。

  5. イベント名test を入力します.

  6. 作成 をクリックします.

  7. テスト をもう一度クリックし、実行が完了するまで待ちます。

  8. 実行結果 ペインで 詳細 を展開すると、出力が表示されます。

👏