Help us understand the problem. What is going on with this article?

AWS Lambdaをブラウザから実行する。

More than 3 years have passed since last update.

AWS LambdaのファンクションをAPI的に使えないか

AWS LambdaはAmazonのクラウド型アプリケーション実行のプラットフォームですが、発表されてからWebアプリのAPI的な使い方はできないのか?と思っていました。
公式のドキュメントでもモバイルアプリから実行できると書いてあるので、ブラウザからも実行できそうですが、公式サイトをみても具体的な方法を探せず、実例を検索してもなかなか出てこない。
しかし、本サービスに移行時のアップデートで、AWS SDK for JavaScript in the Browserから実行できるようになったみたいです。しかも同期的に実行できるので、APIとして使うことが期待できます。

Lambdaファンクションを登録する

Lambdaファンクションの登録については、いろいろなところで、書いてあるので省略します。AWSアカウントを作って、Lambdaのサービスへ遷移して、指示に従えばとりあえず以下の図のように関数が登録されます。テンプレートとして「HelloWorld」という関数があるのでそれをそのまま使うことにします。

関数を登録

ここで重要なのが、Function ARNの値です。あとで利用します。

IAMでlambda関数実行の権限をもつユーザーを登録する

ブラウザから実行するには、lambda関数を実行する権限を持つIAMユーザーの、「Access Key Id」と「Secret Access Key」が必要です。注意しなければいけないのは、公開APIとしてブラウザからlambdaを利用するにはこの2つのキーをJavaScript内に記述する必要があることです。この2つのキーがあれば、ユーザーが権限をもつ操作は全て出来てしまうので、JavaScript内に記述するということは、基本的には誰でもできてしまうということです。

ですので、目的のlambda関数のみの実行権限をもつIAMユーザーを作成する必要があります。

ユーザーの追加

AWSコンソールから、IAMサービスへ移動し、ユーザー > 新規作成へ進み、適当なユーザー名を指定して作成してください。
「Access Key Id」と「Secret Access Key」を表示してメモっておくか、認証情報をダウンロードしてください。

ユーザーの権限の設定

最初にユーザーを追加した段階では、全く権限のないユーザーが追加されます。ここに目的のlamda関数の実行権限を付与します。

まずはユーザー一覧から目的のユーザーを選択してください。

「アクセス許可」の項目から、「インラインポリシー」のドロワーを開くと
"表示するインラインポリシーはありません。作成するには、ここをクリックしてください。"
と表示されますので、クリックします。

「許可を設定」の画面で、Policy Generatorを選択します。

lambda_3.jpg

Policy Generatorの画面で

  • サービス:AWS Lambda
  • アクション:invokeFunction
  • ARN:lambda関数のARN値

を入力し「ステートメントを追加」をクリックします。もし、実行したい関数が複数ある場合は、同様に2個、3個と登録して下さい。

lambda_4.jpg

必要な関数への権限が付与できたら、「次のステップ」をクリックして下さい。そうすると、ポリシー適用用のJsonが表示されます。
この画面で「ポリシーを適用」ボタンをクリックすると、ユーザーに権限が付与されます。

JavaScript側の実装

lambda関数とIAMユーザーを作成したら、ブラウザから実行する準備は整いました。

AWS SDK for JavaScript in the Browser

AWS SDK for JavaScript in the Browserは、ブラウザでAWSにアクセスするための機能を集めたライブラリです。
scriptタグで読み込むだけで利用できます。

<script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.34.min.js"></script>

Base64ライブラリ

これで基本的には実装可能ですが、Lamda関数にブラウザからパラメーターを渡すためには、SDKの関数にBase64エンコードした値を指定する必要があるので、Base64エンコード用のライブラリ

js-base64

も読み込んでおきます

<script src="base64.min.js"></script>

Script本体

lambdaの関数を実行するソースは以下のとおりです。

    AWS.config.update({accessKeyId: 'akid', secretAccessKey: 'sakey' ,region:"us-west-2"});

    var context = Base64.encode(JSON.stringify( {param:"value1"} ));

    var lambda = new AWS.Lambda();    

    var params = {
      FunctionName:"HelloWorld",
      InvocationType:"RequestResponse",
      ClientContext:context
    };

    lambda.invoke( params,function(err,data) {
      if(err) console.log(err,err.stack);
      else console.log(data);
    });

権限の設定

まずはAWSサービスにアクセスするための権限設定を行います。

AWS.config.update({accessKeyId: 'akid', secretAccessKey: 'sakey' ,region:"us-west-2"});

accessKeyIdとsecretAccessKeyには先ほど作成したユーザーの認証情報をいれてください。
regionには実行するlambda関数を登録したリージョンを入力して下さい。lambda関数のARN値

arn:aws:lambda:us-east-1:xxxxxx:function:HelloWorld

の「arn:aws:lambda:」の後に続く文字列です。

関数に渡すパラメーターの設定

関数に渡すパラメータはObjectとして渡すことができます。ただし、Objectをbase64エンコードする必要があるので,ObjectをJSON.stringifyし、Base64エンコードします。

var context = Base64.encode(JSON.stringify( {param:"value1"} ));

lambdaクラスのインスタンス化

lambdaクラスのインスタンス化を行います

var lambda = new AWS.Lambda();

パラメーターの設定

SDKのlambda関数実行用のメソッドに渡すパラメータを指定します。

    var params = {
      FunctionName:"HelloWorld",
      InvocationType:"RequestResponse",
      ClientContext:context
    };
  • FunctionName:作成したlambda関数の名前を指定します。
  • InvocationType:今回は同期的に実行したいので、"RequestResponse"を指定します。
  • ClientContext:ここにはBase64エンコーディングしたObjectを渡します。

ClientContextに指定した値は、lambda関数の中で、

context.clientContext

としてアクセス可能です。

lambda関数を実行。実行後callback関数を実行

最後に、AWS.Lambda.invokeメソッドを利用して、lambda関数を実行します。

    lambda.invoke( params,function(err,data) {
      if(err) console.log(err,err.stack);
      else console.log(data);
    });

dataの中には、lambda関数の中で実行する、context.doneの第2引数が入ります。
lambda関数のなかで処理したデータをいれれば、同期的に実行し、返り値を受け取ることが可能になります。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした