Step Functions と Lambda をローカルで実行するときのハマりどころ

Step Functions と Lambda をローカルで実行するときのハマりどころ:


はじめに

StepFunctions を local で実行するための Docker Image amazon/aws-stepfunctions-local が公開されました。

公式チュートリアルにしたがって StepFunctions と Lambda Function をローカルで実行してみたときの手順メモ。

Docker Container を起動するときの環境変数周りでハマりました。。


手順


SAM アプリケーションの作成

公式チュートリアルにしたがって、HellorWorldFunction のSAMアプリケーションを作成します。


API のエンドポイントの確認

$ sam local start-api 
エンドポイントにアクセスする

$ curl http://127.0.0.1:3000/hello 
{"message":"hello world"} 


Lambda Function をローカルで起動する

$ sam local start-lambda 
2019-02-11 00:19:31 Found credentials in environment variables. 
2019-02-11 00:19:31 Starting the Local Lambda Service. You can now invoke your Lambda Functions defined in your template through the endpoint. 
2019-02-11 00:19:31  * Running on http://127.0.0.1:3001/ (Press CTRL+C to quit) 


Docker コンテナの環境変数を指定する

資料にあるとおり、Dockerイメージに環境変数を与える必要があります。

aws-credentials.txt
AWS_ACCOUNT_ID=123456789012 
AWS_DEFAULT_REGION=us-east-1 
AWS_ACCESS_KEY_ID=dummy 
AWS_SECRET_ACCESS_KEY=dummy 
LAMBDA_ENDPOINT=http://host.docker.internal:3001 


ローカル環境変数を指定

.envrc
export AWS_DEFAULT_REGION=us-east-1 
export AWS_REGION=us-east-1 
export AWS_ACCOUNT_ID=123456789012 
export AWS_ACCESS_KEY_ID=dummy1 
export AWS_SECRET_ACCESS_KEY=dummy 


StepFunctions をローカルで起動

$ docker run -p 8083:8083 --env-file aws-credentials.txt amazon/aws-stepfunctions-local 


ローカルの StepFunctions に state machine を作成する

$ aws stepfunctions --endpoint http://localhost:8083 create-state-machine --definition "{\ 
    \"Comment\": \"A Hello World example of the Amazon States Language using an AWS Lambda Local function\",\ 
    \"StartAt\": \"HelloWorld\",\ 
    \"States\": {\ 
      \"HelloWorld\": {\ 
        \"Type\": \"Task\",\ 
        \"Resource\": \"arn:aws:lambda:us-east-1:123456789012:function:HelloWorldFunction\",\ 
        \"End\": true\ 
      }\ 
    }\ 
  }\ 
  }}" --name "HelloWorld" --role-arn "arn:aws:iam::012345678901:role/DummyRole" 


StepFunction の実行

$ aws stepfunctions --endpoint http://localhost:8083 start-execution --state-machine arn:aws:states:us-east-1:123456789012:stateMachine:HelloWorld --name test 
{ 
    "executionArn": "arn:aws:states:us-east-1:123456789012:execution:HelloWorld:test", 
    "startDate": 1549812335.58 
} 


StepFunctin の実行状態の確認

$ aws stepfunctions --endpoint http://localhost:8083 describe-execution --execution-arn arn:aws:states:us-east-1:123456789012:execution:HelloWorld:test 
{ 
    "executionArn": "arn:aws:states:us-east-1:123456789012:execution:HelloWorld:test", 
    "stateMachineArn": "arn:aws:states:us-east-1:123456789012:stateMachine:HelloWorld", 
    "name": "test", 
    "status": "SUCCEEDED", 
    "startDate": 1549812335.58, 
    "stopDate": 1549812339.711, 
    "input": "{}", 
    "output": "{\"statusCode\":200,\"body\":\"{\\\"message\\\":\\\"hello world\\\"}\"}" 
} 


この手順のハマりどころ

ポイントは、Dockerコンテナの起動時の環境変数 LAMBDA_ENDPOINThost.docker.internal に指定することです。
localhost に指定すると、Docker コンテナからLocalに接続できないので Connection Error になります。

なお、 host.docker.internal というのは Docker コンテナからローカルPCのポートに接続するために用意されたエンドポイントらしいです[4]

。この方法は Docker form Mac/Windows のみ有効のようです。

LAMBDA_ENDPOINTをlocalhostにした場合のエラー
2019-02-10 14:27:56.514: arn:aws:states:us-east-1:123456789012:execution:HelloWorld:test : {"Type":"LambdaFunctionFailed","PreviousEventId":4,"LambdaFunctionFailedEventDetails":{"Error":"Lambda.SdkClientException","Cause":"Unable to execute HTTP request: Connect to localhost:3001 [localhost/127.0.0.1] failed: Connection refused (Connection refused)"}} 
2019-02-10 14:27:56.520: arn:aws:states:us-east-1:123456789012:execution:HelloWorld:test : {"Type":"ExecutionFailed","PreviousEventId":5,"ExecutionFailedEventDetails":{"Error":"Lambda.SdkClientException","Cause":"Unable to execute HTTP request: Connect to localhost:3001 [localhost/127.0.0.1] failed: Connection refused (Connection refused)"}} 
なお、 LAMBDA_ENDPOINT の設定をせずに起動した場合は The security token included in the request is invalid. という認証系のエラーメッセージとなり、さらに混乱させられました。

LAMBDA_ENDPOINT設定されていない場合のエラー
2019-02-10 14:25:36.380: arn:aws:states:us-east-1:123456789012:execution:HelloWorld:test1 : {"Type":"LambdaFunctionFailed","PreviousEventId":4,"LambdaFunctionFailedEventDetails":{"Error":"Lambda.AWSLambdaException","Cause":"The security token included in the request is invalid. (Service: AWSLambda; Status Code: 403; Error Code: UnrecognizedClientException; Request ID: bb917ab7-8309-447a-a830-28cbedef8aa1)"}} 
2019-02-10 14:25:36.381: arn:aws:states:us-east-1:123456789012:execution:HelloWorld:test1 : {"Type":"ExecutionFailed","PreviousEventId":5,"ExecutionFailedEventDetails":{"Error":"Lambda.AWSLambdaException","Cause":"The security token included in the request is invalid. (Service: AWSLambda; Status Code: 403; Error Code: UnrecognizedClientException; Request ID: bb917ab7-8309-447a-a830-28cbedef8aa1)"}} 


終わりに

環境変数の設定について、公式チュートリアルには明確な設定内容が書かれてなかったのでけっこうハマりました。。

とにかくこれで、StepFunctionsをローカルから実行することができるようになりました。


参考

  1. Step Functions and Lambda Local
  2. Step Functions Local Configuration Options
  3. DockerHub - amazon/aws-stepfunctions-local
  4. Networking features in Docker Desktop for Mac

コメント

このブログの人気の投稿

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-04-30 23:37:32 RSSフィード2021-04-30 23:00 分まとめ(42件)

投稿時間:2023-02-05 02:09:04 RSSフィード2023-02-05 02:00 分まとめ(9件)