LoginSignup
1
3

More than 1 year has passed since last update.

指定ログイン情報を使用してSalesforce ApexからAWS Lambdaを実行する

Last updated at Posted at 2022-03-31

概要

Salesforce.com(以下 SFDC)からAWS LambdaをInvokeします。
具体的には、SFDCの指定ログイン情報(Named Credential)へAWSのIAMユーザークレデンシャルを保存し、Apexからコールアウト、Lambdaを実行します。
自前で実装するとなると面倒であろうAWS署名バージョン4にSFDCが対応しているため、シンプルな記述で実行可能になっています。

前提

  • Salesforceについては無償で誰でも利用可能な Salesforce Developer Edition で確認します。
  • AWS Lambdaは東京リージョン(ap-northeast-1) を利用します

手順

AWS Lambda関数を作成

実行するLambda関数 MyFunction を作成します。
今回は Pythonで記述しました。

def lambda_handler(event, context):
    name = event.get('name')
    return {
        'statusCode': 200,
        'body': f'Hello {name} !'
    }

IAMポリシーを作成

MyFunctionInvokePolicy を作成します。
東京リージョンのLambda関数 MyFunction を実行できるように指定しました。

MyFunctionInvokePolicy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction",
                "lambda:InvokeAsync"
            ],
            "Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:MyFunction"
        }
    ]
}

IAMユーザーを作成

MyFunctionInvokeUser という名前のIAMユーザーを作成しました。
AWS認証情報タイプは アクセスキー・プログラムによるアクセス を選択、ポリシーへ上記手順で作成したポリシーを指定します。
作成完了時にアクセスキーID、シークレットアクセスキーを控えておきます。

image.png

指定ログイン情報(Named Credentials)1 を作成

次のように指定しました。

項目
表示ラベル InvokeLambda
名前 InvokeLambda
URL https://lambda.ap-northeast-1.amazonaws.com/2015-03-31/functions
ID種別 指定ユーザ
認証プロトコル AWS 署名バージョン 4
AWSアクセスキーID 上記手順で作成したIAMユーザーのアクセスキーID
AWSシークレットアクセスキー 上記手順で作成したIAMユーザーのシークレットアクセスキー
AWSリージョン ap-northeast-1
AWSサービス lambda

image.png

動作確認

デベロッパーコンソールの Anonymous WindowからApexコードを実行して確認します。

HttpRequest req = new HttpRequest();
req.setEndpoint('callout:InvokeLambda/MyFunction/invocations');
req.setMethod('POST');
req.setBody('{"name": "Justin"}');

Http http = new Http();
HttpResponse res = http.send(req);
System.debug(res.getBody());

実行ログ

コード2行目の callout:InvokeLambda が 指定ログイン情報で設定したURL https://lambda.ap-northeast-1.amazonaws.com/2015-03-31/functions に置き換わり、https://lambda.ap-northeast-1.amazonaws.com/2015-03-31/functions/MyFunction/invocations というURLが生成されているのがわかりますね。
HttpResponse::getBody() でLambdaの実行結果が取得できています。

CALLOUT_REQUEST|[7]|System.HttpRequest[Endpoint=callout:InvokeLambda/MyFunction/invocations, Method=POST]
NAMED_CREDENTIAL_REQUEST|NamedCallout[Named Credential Id=0XA5h0000004DDd, Named Credential Name=InvokeLambda, Endpoint=https://lambda.ap-northeast-1.amazonaws.com/2015-03-31/functions/MyFunction/invocations, Method=POST, External Credential Type=EXTERNAL, HTTP Header Authorization=Not Set, Content-Type=null, Request Size bytes=18, Retry on 401=True]
NAMED_CREDENTIAL_RESPONSE|NamedCallout[Named Credential Id=0XA5h0000004DDd, Named Credential Name=InvokeLambda, Status Code=200, Content-Type=application/json, Response Size bytes=45, Overall Callout Time ms=647, Connect Time ms=3
CALLOUT_RESPONSE|[7]|System.HttpResponse[Status=OK, StatusCode=200]
USER_DEBUG|[8]|DEBUG|{"statusCode": 200, "body": "Hello Justin !"}

その他

Lambdaを非同期実行したい

リクエストヘッダ X-Amz-Invocation-Type: Event を指定します。

req.setHeader('X-Amz-Invocation-Type', 'Event');

実行ログを取得したい

リクエストヘッダ X-Amz-Log-Type: Tail を指定します。

req.setHeader('X-Amz-Log-Type', 'Tail');

レスポンスヘッダ X-Amz-Log-Result に最後の4KBがBASE64エンコードされてセットされます。
利用する場合はデコードが必要です。

System.debug(
    EncodingUtil.base64Decode(
        res.getHeader('X-Amz-Log-Result')
    ).toString());

最後に

SFDCからAWS Lambdaをコールするシーンとしては、企業の業務システム連携で検討する場面が多いだろうと推察します。

この方法はAWS CLIでLambda実行するのと同等ということになると思います。
API Gatewayで公開エンドポイントにしても同じことは実現できますが、IAMユーザーを固定することは、権限ポリシーを厳密に設定できたり、実行監査もしやすいのではないでしょうか。

参考リンク

  1. 英語だと Named Credentials なのですが、日本語訳の 指定ログイン情報 と関連付けて記憶しにくいなと感じています。SFDCの設定ページでいつも 「名前・・・」なんだっけ?みたいになり、named credentials でググって、あー、、となっています。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3