AWS Lambda
開発者ガイド

Lambda コンソールでの継続的デリバリーによるアプリケーションの作成

Lambda コンソールで、統合された継続的デリバリーパイプラインを使用してアプリケーションを作成できます。継続的デリバリーでは、ソース管理リポジトリにプッシュした変更ごとに、アプリケーションを自動的にビルドおよびデプロイするパイプラインがトリガーされます。Lambda コンソールには、サンプルコード付きの一般的なアプリケーションタイプをビルドするためのテンプレートと、サポートリソースを作成するためのテンプレートが用意されています。

このチュートリアルでは、次のリソースを作成します。

  • アプリケーション – Node.js Lambda 関数、ビルド仕様、および AWS サーバーレスアプリケーションモデル (AWS SAM) テンプレート。

  • パイプライン – 他のリソースを接続して継続的デリバリーを有効にする AWS CodePipeline パイプライン。

  • リポジトリ – AWS CodeCommit の Git リポジトリ。変更をプッシュすると、パイプラインはソースコードを Amazon S3 バケットにコピーしてから、それをビルドプロジェクトに渡します。

  • トリガー – リポジトリのマスターブランチを監視し、パイプラインをトリガーする Amazon CloudWatch Events ルール。

  • ビルドプロジェクト – パイプラインからソースコードを取得してアプリケーションをパッケージ化する、AWS CodeBuild のビルド。ソースにはビルド仕様が含まれています。この仕様には、依存関係をインストールしてデプロイ用のアプリケーションテンプレートを準備するコマンドが含まれています。

  • デプロイ設定 – パイプラインのデプロイステージは、ビルド出力から処理済みの AWS SAM テンプレートを取得し、AWS CloudFormation で新しいバージョンをデプロイする一連のアクションを定義します。

  • バケット – デプロイアーティファクトストレージ用の Amazon Simple Storage Service (Amazon S3) バケット。

  • ロール – パイプラインのソース、ビルド、デプロイの各ステージには、AWS リソースを管理するための IAM ロールがあります。アプリケーションの関数には、ログをアップロードするための実行ロールがあります。このロールは、他のサービスにアクセスするように拡張できます。

アプリケーションおよびパイプラインリソースは、カスタマイズして拡張できる AWS CloudFormation テンプレートに定義されています。アプリケーションリポジトリに含まれているテンプレートは、カスタマイズして Amazon DynamoDB テーブル、Amazon API Gateway API、その他のアプリケーションリソースを追加できます。継続的デリバリーパイプラインは、ソース管理外の別のテンプレートに定義されており、独自のスタックがあります。

パイプラインは、リポジトリ内の 1 つのブランチを 1 つのアプリケーションスタックにマッピングします。さらにパイプラインを作成して、他のブランチの環境を同じリポジトリ内に追加することができます。また、試験遂行、ステージング、手動承認用にステージをパイプラインに追加することもできます。AWS CodePipeline の詳細については、「AWS CodePipeline とは」を参照してください。

前提条件

このチュートリアルでは、基本的な Lambda オペレーションと Lambda コンソールについてある程度の知識があることを前提としています。まだ作成していない場合は、AWS Lambda の使用開始 の指示に従って、まず Lambda 関数を作成します。

このガイドの手順に従うには、コマンドを実行するためのコマンドラインターミナルまたはシェルが必要になります。コマンドは、該当する場合、プロンプト記号 ($) と現在のディレクトリの名前が前に付けられて、リストに示されます。

~/lambda-project$ this is a command this is output

コマンドが長い場合は、エスケープ文字 (\) を使用して、コマンドを複数の行に分割します。

Linux および macOS では、任意のシェルとパッケージマネージャーを使用します。Windows 10 では、Linux 用の Windows サブシステムをインストールして、Windows 統合バージョンの Ubuntu および Bash を入手できます。

このチュートリアルでは、ソース管理に CodeCommit を使用します。アプリケーションコードにアクセスして更新するようにローカルマシンを設定するには、AWS CodeCommit ユーザーガイドの「設定」を参照してください。

アプリケーションを作成します。

Lambda コンソールでアプリケーションを作成します。

アプリケーションを作成するには

  1. Lambda コンソールアプリケーションページを開きます。

  2. [Create application] を選択します。

  3. [Author from scratch] を選択します。

  4. アプリケーション設定を構成します。

    • アプリケーション名my-app

    • アプリケーションの説明my application

    • ランタイムNode.js 12.x

    • リポジトリプロバイダCodeCommit

    • リポジトリプロバイダmy-app-repo

    • アクセス許可ロールとアクセス許可の境界を作成します

  5. [Create] を選択します。

Lambda は、パイプラインおよび関連リソースを作成し、サンプルアプリケーションコードを Git リポジトリにコミットします。リソースが作成されると、概要ページに表示されます。

関数の呼び出し

関数を呼び出して、それが動作することを確認します。

アプリケーションの関数を呼び出すには

  1. Lambda コンソールアプリケーションページを開きます。

  2. [my-app] を選択します。

  3. [リソース] で、[helloFromLambdaFunction] を選択します。

  4. [Test] を選択します。

  5. テストイベントを設定します。

    • イベント名test

    • 本文{}

  6. [作成] を選択します。

  7. [Test] を選択します。

Lambda コンソールが関数を実行し、その結果を表示します。結果の下の [詳細] セクションを展開して、出力と実行の詳細を表示します。

AWS リソースの追加

アプリケーションを作成すると、Lambda コンソールはサンプルアプリケーションが含まれた Git リポジトリを作成します。ローカルマシンでアプリケーションコードのコピーを取得するには、プロジェクトリポジトリをクローンします。

プロジェクトリポジトリをクローンするには

  1. Lambda コンソールアプリケーションページを開きます。

  2. [my-app] を選択します。

  3. [コード] を選択します。

  4. [リポジトリの詳細] で、「セットアップ」で設定した認証モードに応じて、HTTP または SSH リポジトリ URI をコピーします。

  5. リポジトリをクローンします。

    ~$ git clone ssh://git-codecommit.us-east-2.amazonaws.com/v1/repos/my-app-repo

リポジトリには、アプリケーションのテンプレート、ビルド仕様、およびコードが含まれています。アプリケーションテンプレートに DynamoDB テーブルを追加します。

DynamoDB テーブルを追加するには

  1. テキストエディタで template.yml を開きます。

  2. テーブルリソース、テーブル名を関数に渡す環境変数、およびテーブルリソースの管理を関数に許可するアクセス許可ポリシーを追加します。

    例 template.yml - リソース

    ... Resources: ddbTable: Type: AWS::Serverless::SimpleTable Properties: PrimaryKey: Name: id Type: String ProvisionedThroughput: ReadCapacityUnits: 1 WriteCapacityUnits: 1 helloFromLambdaFunction: Type: AWS::Serverless::Function Properties: Handler: src/handlers/hello-from-lambda.helloFromLambdaHandler Runtime: nodejs12.x MemorySize: 128 Timeout: 100 Description: This is a hello from Lambda example. Environment: Variables: DDB_TABLE: !Ref ddbTable Policies: - DynamoDBCrudPolicy: TableName: !Ref ddbTable - AWSLambdaBasicExecutionRole
  3. 変更をコミットしてプッシュします。

    ~/my-app-repo$ git commit -am "Add DynamoDB table" ~/my-app-repo$ git push

変更をプッシュすると、アプリケーションのパイプラインがトリガーされます。アプリケーション画面の [Deployments (デプロイ)] タブを使用して、パイプラインを通過する変更を追跡します。デプロイが完了したら、次のステップに進みます。

アクセス許可の境界の更新

サンプルアプリケーションは、その関数の実行ロールにアクセス許可の境界を適用します。アクセス許可の境界は、関数のロールに追加できるアクセス許可を制限します。境界がないと、プロジェクトリポジトリへの書き込みアクセス権を持つユーザーは、プロジェクトテンプレートを変更して、サンプルアプリケーションの範囲外のリソースやサービスにアクセスするためのアクセス許可を関数に付与できます。

前のステップで実行ロールに追加した DynamoDB アクセス許可を関数で使用するには、アクセス許可の境界を拡張して追加のアクセス許可を付与する必要があります。Lambda コンソールは、アクセス許可の境界から外れたリソースを検出すると、更新されたポリシーを提供して境界を更新できるようにします。

アプリケーションのアクセス許可の境界を更新するには

  1. Lambda コンソールアプリケーションページを開きます。

  2. アプリケーションを選択します。

  3. [リソース] で、[Edit permisssions boundary (アクセス許可の境界の編集)] を選択します。

  4. 表示される手順に従って境界を更新し、新しいテーブルへのアクセスを許可します。

アクセス許可の境界の詳細については、「AWS Lambda アプリケーションに対するアクセス許可の境界の使用」を参照してください。

関数コードの更新

次に、テーブルを使用するように関数コードを更新します。次のコードでは、テーブルを使用して、関数の各インスタンスで処理された呼び出しの数を追跡します。ログストリーム ID を一意の識別子として使用します。新しいインスタンスは、関数を更新するときと、複数の同時呼び出しを処理するときに作成されます。

関数コードを更新するには

  1. index.js という名前の新しいハンドラーを、次の内容で src/handlers フォルダに追加します。

    例 src/handlers/index.js

    const dynamodb = require('aws-sdk/clients/dynamodb'); const docClient = new dynamodb.DocumentClient(); exports.handler = async (event, context) => { const message = 'Hello from Lambda!'; const tableName = process.env.DDB_TABLE; const logStreamName = context.logStreamName; var params = { TableName : tableName, Key: { id : logStreamName }, UpdateExpression: 'set invocations = if_not_exists(invocations, :start) + :inc', ExpressionAttributeValues: { ':start': 0, ':inc': 1 }, ReturnValues: 'ALL_NEW' }; await docClient.update(params).promise(); const response = { body: JSON.stringify(message) }; console.log(`body: ${response.body}`); return response; }
  2. アプリケーションのテンプレートを開き、ハンドラー値を src/handlers/index.handler に変更します。

    例 template.yml

    ... helloFromLambdaFunction: Type: AWS::Serverless::Function Properties: Handler: src/handlers/index.handler Runtime: nodejs10.x
  3. 変更をコミットしてプッシュします。

    ~/my-app-repo$ git add . && git commit -m "Use DynamoDB table" ~/my-app-repo$ git push

コードの変更がデプロイされたら、関数を数回呼び出して DynamoDB テーブルを更新します。

DynamoDB テーブルを表示するには

  1. DynamoDB コンソールのテーブルページを開きます。

  2. my-appで始まるテーブルを選択します。

  3. [Items (項目)] を選択します。

  4. [Start search (検索の開始)] を選択します。

次のステップ

アプリケーションリソースを定義する AWS CloudFormation テンプレートでは、AWS サーバーレスアプリケーションモデル トランスフォームを使用して、リソース定義の構文を簡素化し、デプロイパッケージやその他のアーティファクトのアップロードを自動化します。AWS SAM は、コマンドラインインターフェイス (AWS SAM CLI) も提供しています。CLI には、AWS CLI と同じパッケージングおよびデプロイ機能があり、さらに Lambda アプリケーションに固有の機能が追加されています。AWS SAM CLIを使用して、Lambda 実行環境をエミュレートする Dockerコンテナでローカルにアプリケーションをテストします。

AWS Cloud9 は、Node.js、AWS SAM CLI、および Docker を含むオンライン開発環境を提供します。AWS Cloud9 を使用すると、開発をすばやく開始し、どのコンピュータからでも開発環境にアクセスできます。手順については、AWS Cloud9 ユーザーガイドの「開始方法」を参照してください。

ローカル開発の場合、統合開発環境 (IDE) 用の AWS ツールキットを使用すると、関数をリポジトリにプッシュする前にテストおよびデバッグできます。

トラブルシューティング

アプリケーションを開発する際、以下のタイプのエラーが発生する可能性があります。

  • ビルドエラー – コンパイル、テスト、パッケージングのエラーなど、ビルドフェーズ中に発生する問題。

  • デプロイエラー – AWS CloudFormation がアプリケーションスタックを更新できない場合に発生する問題。これには、アクセス許可のエラー、アカウントの制限、サービスの問題、またはテンプレートのエラーが含まれます。

  • 呼び出しエラー – 関数のコードまたはランタイムから返されるエラー。

ビルドエラーおよびデプロイエラーの場合は、Lambda コンソールでエラーの原因を特定できます。

アプリケーションエラーのトラブルシューティングを行うには

  1. Lambda コンソールアプリケーションページを開きます。

  2. アプリケーションを選択します。

  3. [デプロイ] を選択します。

  4. アプリケーションのパイプラインを表示するには、[Deployment pipeline (デプロイパイプライン)] を選択します。

  5. エラーが発生したアクションを特定します。

  6. コンテキストでエラーを表示するには、[詳細] を選択します。

ExecuteChangeSet アクション中に発生したデプロイエラーの場合、パイプラインは AWS CloudFormation コンソールのスタックイベントのリストにリンクされます。ステータスが UPDATE_FAILED のイベントを検索します。エラーの発生後に AWS CloudFormation はロールバックするため、関連するイベントは、リスト内の他のいくつかのイベントの下にあります。AWS CloudFormation が変更セットを作成できなかった場合、エラーは [イベント] の下ではなく [変更セット] の下に表示されます。

デプロイエラーや呼び出しエラーの一般的な原因は、1 つ以上のロールにアクセス許可が不足していることです。パイプラインには、AWS CloudFormation スタックを直接更新するために使用する ユーザーアクセス許可と同等のデプロイ用のロール (CloudFormationRole) があります。アプリケーションにリソースを追加する場合や、ユーザーアクセス許可を必要とする Lambda 機能を有効にする場合に、デプロイロールが使用されます。デプロイロールへのリンクは、アプリケーションの概要の [Infrastructure (インフラストラクチャ)] の下にあります。

関数が AWS の他のサービスやリソースにアクセスする場合、または追加のアクセス許可が関数に必要となる機能を有効にすると、関数の実行ロールが使用されます。アプリケーションテンプレートで作成されるすべての実行ロールには、アプリケーションのアクセス許可の境界も適用されます。この境界により、テンプレートの実行ロールにアクセス許可を追加した後で、追加のサービスやリソースへのアクセス権を IAM で明示的に付与する必要があります。

たとえば、関数を Virtual Private Cloud (VPC) に接続するには、VPC リソースを記述するためのユーザーアクセス許可が必要です。実行ロールには、ネットワークインターフェイスを管理するためのアクセス許可が必要です。この場合、以下のステップに従います。

  1. IAM でデプロイロールに必要なユーザーアクセス許可を追加します。

  2. IAM でアクセス許可の境界に実行ロールアクセス許可を追加します。

  3. アプリケーションテンプレートで実行ロールに実行ロールアクセス許可を追加します。

  4. コミットしてプッシュし、更新された実行ロールをデプロイします。

アクセス許可のエラーに対処したら、パイプラインの概要で [変更のリリース] を選択して、ビルドとデプロイを再実行します。

クリーンアップ

サンプルを引き続き変更して使用し、独自のアプリケーションを開発できます。サンプルを使い終わったら、アプリケーションを削除して、パイプライン、リポジトリ、およびストレージに課金されないようにします。

アプリケーションを削除するには

  1. AWS CloudFormation コンソールを開きます。

  2. アプリケーションスタック – my-app を削除します。

  3. Amazon S3 コンソールを開きます。

  4. アーティファクトバケット – aws-us-east-2-123456789012-my-app-pipe を削除します。

  5. AWS CloudFormation コンソールに戻り、インフラストラクチャスタック – serverlessrepo-my-app-toolchain を削除します。