はじめに
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_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
ローカル環境変数を指定
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_ENDPOINT
を host.docker.internal
に指定することです。
localhost
に指定すると、Docker コンテナからLocalに接続できないので Connection Error
になります。
なお、 host.docker.internal
というのは Docker コンテナからローカルPCのポートに接続するために用意されたエンドポイントらしいです[4]
。この方法は Docker form Mac/Windows のみ有効のようです。
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.
という認証系のエラーメッセージとなり、さらに混乱させられました。
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をローカルから実行することができるようになりました。
ただ、やはりテストの指針としては以下の記事で書いたような、ローカルでテスト可能なライブラリを増やしていって、