Step Functions Local が出た!SAMやDynamoDB Localと一緒に使ってみる

Step Functions Local が出た!SAMやDynamoDB Localと一緒に使ってみる:


はじめに

先日、Step Functions Local が利用できるようになり、

ワークフローをローカルで開発、テストすることが可能になりました。

DynamoDB Localと同じようにJAR パッケージおよび Docker イメージが提供されています。

AWS Step Functions ワークフローをローカルで開発してテストする
https://aws.amazon.com/jp/about-aws/whats-new/2019/02/develop-and-test-aws-step-functions-workflows-locally/

早速触ってみたのですが、単体では動作ができたものの、

SAM CLIやDynamoDB Localとの連携がまだ上手くいっておらず、原因を調べています。


事前準備

dockerのインストール方法や基本的な使用方法については割愛します。

またAWSCLIを使用します。インストールまたはアップグレードしておきます。

# aws --version 
aws-cli/1.16.101 Python/3.6.2 Linux/4.14.88-88.76.amzn2.x86_64 botocore/1.12.91 
Step Functions LocalのDockerイメージをダウンロードします。

# docker pull amazon/aws-stepfunctions-local:1.0.0 
1.0.0: Pulling from amazon/aws-stepfunctions-local 
6c5ec16d4336: Pull complete 
fed0ccb4012f: Pull complete 
018f3324324c: Pull complete 
Digest: sha256:f9e6ae948b814f604ec313a15e00aef850bfa2cd085e33a68b84e6fc8fee0ba7 
Status: Downloaded newer image for amazon/aws-stepfunctions-local:1.0.0 
DynamoDB LocalのDockerイメージもダウンロードします。

# docker pull amazon/dynamodb-local:1.11.477 
1.11.477: Pulling from amazon/dynamodb-local 
638b75f800bf: Pull complete 
7d727a2b79b4: Pull complete 
c83cc16257dd: Pull complete 
Digest: sha256:cbe14c530c08997a38da04efe3778242f5544e0cdb7e9002fbbc3682f2421c0c 
Status: Downloaded newer image for amazon/dynamodb-local:1.11.477 


まずは Hello World

Step Functions Localを起動します。

# docker run --name stepfunctions -p 8083:8083 -d amazon/aws-stepfunctions-local:1.0.0 
050fe420af809354937caba0bd1cfd4bf200a79ec2d5af2e10dad7e39a2db132 
# docker ps 
CONTAINER ID        IMAGE                                  COMMAND                  CREATED             STATUS              PORTS                    NAMES 
050fe420af80        amazon/aws-stepfunctions-local:1.0.0   "java -jar StepFunct…"   40 seconds ago      Up 38 seconds       0.0.0.0:8083->8083/tcp   stepfunctions 
以下のようなシンプルなステートマシンを実行してみます。


image.png


ASL定義は以下の内容です。

HelloWorld.json
{ 
  "StartAt": "HelloWorld", 
  "States": { 
    "HelloWorld": { 
      "Type": "Pass", 
      "Result":"Hello World", 
      "End": true 
    } 
  } 
} 
ローカルで実行されているStep Functionsにアクセスするには AWS CLIを実行する際に

エンドポイントとしてローカルホストを指定します。

# aws stepfunctions create-state-machine \ 
> --endpoint http://localhost:8083 --definition file://HelloWorld.json \ 
> --name "HelloWorld" --role-arn "arn:aws:iam::012345678901:role/DummyRole" 
 
{ 
    "stateMachineArn": "arn:aws:states:us-east-1:123456789012:stateMachine:HelloWorld", 
    "creationDate": 1549696926.307 
} 
作成したステートマシンのARNを指定して実行します。

# aws stepfunctions start-execution \ 
> --endpoint http://localhost:8083 \ 
> --state-machine-arn arn:aws:states:us-east-1:123456789012:stateMachine:HelloWorld \ 
> --name 01 
 
{ 
    "executionArn": "arn:aws:states:us-east-1:123456789012:execution:HelloWorld:01, 
    "startDate": 1549697048.004 
} 
executionArn を指定してステートマシンの状態を確認します。

"status": "SUCCEEDED" となっています。

# aws stepfunctions describe-execution \ 
> --endpoint http://localhost:8083 \ 
> --execution-arn arn:aws:states:us-east-1:123456789012:execution:HelloWorld:01 
 
{ 
    "executionArn": "arn:aws:states:us-east-1:123456789012:execution:HelloWorld:01", 
    "stateMachineArn": "arn:aws:states:us-east-1:123456789012:stateMachine:HelloWorld", 
    "name": "01", 
    "status": "SUCCEEDED", 
    "startDate": 1549697048.004, 
    "stopDate": 1549697048.074, 
    "input": "{}", 
    "output": "\"Hello World\"" 
} 


SAMやDynamoDB Localと組み合わせて使う

結論を先に言うと、今のところどちらも上手くいっていません。。。


コンテナの再作成

先ほどのHelloWorldで作成したコンテナを破棄します。

# docker stop stepfunctions && docker rm -v stepfunctions 
stepfunctions 
stepfunctions 
他のサービスのローカルエンドポイントを使用するにはコンテナ起動時に環境変数を指定します。

# docker run --name stepfunctions -p 8083:8083 -d \ 
> -e LAMBDA_ENDPOINT=http://<host_ip>:3001 \ 
> -e DYNAMODB_ENDPOINT=http://<host_ip>:8000 \ 
> amazon/aws-stepfunctions-local:1.0.0 
83c9f085bbb329ad83751344a2d583a17afd2023d900545e3bd2a2020d18db98 
# docker ps 
CONTAINER ID        IMAGE                                  COMMAND                  CREATED             STATUS              PORTS                    NAMES 
83c9f085bbb3        amazon/aws-stepfunctions-local:1.0.0   "java -jar StepFunct…"   4 seconds ago       Up 4 seconds        0.0.0.0:8083->8083/tcp   stepfunctions 


SAMとの連携

AWS SAM CLI を使用してHelloWorldFunctionを作成し、Local lambdaを起動します。

# sam init --runtime python 
# cd sam-app 
# sam local start-lambda 
2019-02-09 08:20:01 Starting the Local Lambda Service. You can now invoke your Lambda Functions defined in your template through the endpoint. 
2019-02-09 08:20:01  * Running on http://127.0.0.1:3001/ (Press CTRL+C to quit) 
ローカルでLambda関数がinvokeできることを確認しておきます。

# aws lambda invoke \ 
> --endpoint http://localhost:3001 \ 
> --function-name HelloWorldFunction outputfile.txt 
{ 
    "StatusCode": 200 
} 
 
# python -m json.tool < outputfile.txt 
{ 
    "body": "{\"message\": \"hello world\"}", 
    "statusCode": 200 
} 
以下のようなASL定義を用意します。

HelloWorldFunction.json
{ 
  "StartAt": "HelloWorld", 
  "States": { 
    "HelloWorld": { 
      "Type": "Task", 
      "Resource": "arn:aws:lambda:us-east-1:123456789012:function:HelloWorldFunction", 
      "End": true 
    } 
  } 
} 
HelloWorldFunction.jsonをもとにステートマシンを作成します。

# aws stepfunctions create-state-machine \ 
> --endpoint http://localhost:8083 --definition file://HelloWorldFunction.json \ 
> --name "HelloWorldFunction" --role-arn "arn:aws:iam::012345678901:role/DummyRole" 
 
{ 
    "stateMachineArn": "arn:aws:states:us-east-1:123456789012:stateMachine:HelloWorldFunction", 
    "creationDate": 1549722746.87 
} 
起動しますが、失敗します。。。

# aws stepfunctions start-execution \ 
> --endpoint http://localhost:8083 \ 
> --state-machine-arn arn:aws:states:us-east-1:123456789012:stateMachine:HelloWorldFunction \ 
> --name 01 
 
{ 
    "executionArn": "arn:aws:states:us-east-1:123456789012:execution:HelloWorldFunction:01", 
    "startDate": 1549722930.414 
} 
 
# aws stepfunctions describe-execution \ 
> --endpoint http://localhost:8083 \ 
> --execution-arn arn:aws:states:us-east-1:123456789012:execution:HelloWorldFunction:01 
 
{ 
    "executionArn": "arn:aws:states:us-east-1:123456789012:execution:HelloWorldFunction:01", 
    "stateMachineArn": "arn:aws:states:us-east-1:123456789012:stateMachine:HelloWorldFunction", 
    "name": "01", 
    "status": "FAILED", 
    "startDate": 1549722930.414, 
    "stopDate": 1549722931.197, 
    "input": "{}" 
} 
ログを確認すると、SAMで起動してるLocal Lambdaにアクセスしようとしてますが、

どうしてもConnection refusedになってしまいます。

# docker logs stepfunctions 
2019-02-09 16:36:34.325: arn:aws:states:us-east-1:123456789012:execution:HelloWorldFunction:01  
: {"Type":"LambdaFunctionFailed","PreviousEventId":4,"LambdaFunctionFailedEventDetails": 
{"Error":"Lambda.SdkClientException","Cause":"Unable to execute HTTP request: Connect to  
172.31.2.102:3001 [/172.31.2.102] failed: Connection refused (Connection refused)"}} 


DynamoDB Localとの連携

続いてDynamoDB Localを起動します。

# docker run --name dynamodb -p 8000:8000 -d amazon/dynamodb-local:1.11.477 
ec860af91a8ab918949e54ff599db479853f610e8b91547d3bb260fbc6f2f052 
# docker ps 
CONTAINER ID        IMAGE                                  COMMAND                  CREATED             STATUS              PORTS                    NAMES 
ec860af91a8a        amazon/dynamodb-local:1.11.477         "java -jar DynamoDBL…"   3 seconds ago       Up 2 seconds        0.0.0.0:8000->8000/tcp   dynamodb 
83c9f085bbb3        amazon/aws-stepfunctions-local:1.0.0   "java -jar StepFunct…"   44 minutes ago      Up 44 minutes       0.0.0.0:8083->8083/tcp   stepfunctions 
ここではlocaltable というテーブルを作成しておきます。

# aws dynamodb create-table \ 
> --endpoint-url http://localhost:8000 --table-name localtable \ 
> --attribute-definitions AttributeName=id,AttributeType=S \ 
> --key-schema AttributeName=id,KeyType=HASH \ 
> --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 
{ 
    "TableDescription": { 
        "AttributeDefinitions": [ 
            { 
                "AttributeName": "id", 
                "AttributeType": "S" 
            } 
        ], 
        "TableName": "localtable", 
        "KeySchema": [ 
            { 
                "AttributeName": "id", 
                "KeyType": "HASH" 
            } 
        ], 
        "TableStatus": "ACTIVE", 
        "CreationDateTime": 1549702430.218, 
        "ProvisionedThroughput": { 
            "LastIncreaseDateTime": 0.0, 
            "LastDecreaseDateTime": 0.0, 
            "NumberOfDecreasesToday": 0, 
            "ReadCapacityUnits": 5, 
            "WriteCapacityUnits": 5 
        }, 
        "TableSizeBytes": 0, 
        "ItemCount": 0, 
        "TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/localtable", 
        "BillingModeSummary": { 
            "BillingMode": "PROVISIONED", 
            "LastUpdateToPayPerRequestDateTime": 0.0 
        } 
    } 
} 
 
# aws dynamodb --endpoint-url http://localhost:8000 list-tables 
{ 
    "TableNames": [ 
        "localtable" 
    ] 
} 
inputで指定した内容をDynamoDBに格納するだけのステートマシンを作ってみたいと思います。

以下のようなシンプルな内容です。



image.png


ASL定義は以下のようなものです。

PutDynamoDB.json
{ 
  "StartAt": "PutDynamoDB", 
  "States": { 
    "PutDynamoDB": { 
      "Type": "Task", 
      "Resource": "arn:aws:states:::dynamodb:putItem", 
      "Parameters": { 
        "TableName": "localtable", 
        "Item": { 
          "id": {"S.$": "$.id"}, 
          "message": {"S.$": "$.message"} 
        } 
      }, 
      "End": true  
    } 
  } 
} 
ステートマシンを作成します。

# aws stepfunctions create-state-machine \ 
> --endpoint http://localhost:8083 --definition file://PutDynamoDB.json \ 
> --name "PutDynamoDB" --role-arn "arn:aws:iam::012345678901:role/DummyRole" 
 
{ 
    "stateMachineArn": "arn:aws:states:us-east-1:123456789012:stateMachine:PutDynamoDB", 
    "creationDate": 1549720535.77 
} 
input で以下を指定します。

input.json
{ 
    "id": "1", 
    "message": "Hello World" 
} 
実行しますが、またしても失敗してしまいました。

# aws stepfunctions --endpoint http://localhost:8083 start-execution \ 
> --state-machine-arn arn:aws:states:us-east-1:123456789012:stateMachine:PutDynamoDB \ 
> --name 01 --input file://input.json 
 
{ 
    "executionArn": "arn:aws:states:us-east-1:123456789012:execution:PutDynamoDB:01", 
    "startDate": 1549720800.303 
} 
 
# aws stepfunctions describe-execution \ 
> --endpoint http://localhost:8083 \ 
> --execution-arn arn:aws:states:us-east-1:123456789012:execution:PutDynamoDB:01 
 
{ 
    "executionArn": "arn:aws:states:us-east-1:123456789012:execution:PutDynamoDB:01", 
    "stateMachineArn": "arn:aws:states:us-east-1:123456789012:stateMachine:PutDynamoDB", 
    "name": "01", 
    "status": "FAILED", 
    "startDate": 1549720800.303, 
    "stopDate": 1549720801.464, 
    "input": "{\n    \"id\": \"1\",\n    \"message\": \"HelloWorld\"\n}\n" 
} 
ログを確認すると、DynamoDB Localの方ではなく、実アカウントの方を見てしまっています。

# docker logs stepfunctions 
2019-02-09 14:00:01.463: arn:aws:states:us-east-1:123456789012:execution:PutDynamoDB:01 : 
{"Type":"ExecutionFailed","PreviousEventId":0,"ExecutionFailedEventDetails": 
{"Error":"States.Runtime","Cause":"User: arn:aws:sts::<account_id>:assumed-role/<role_name>/ 
i-0fxxxxxxxxxxxx is not authorized to perform: dynamodb:PutItem on resource:  
arn:aws:dynamodb:us-east-1:<account_id>:table/localtable (Service: AmazonDynamoDBv2; Status  
Code: 400; Error Code: AccessDeniedException; Request ID:  
OSIPIKBRVHMQ5R9A8OCKUD7TIFVV4KQNSO5AEMVJF66Q9ASUAAJG)"}} 
SAM CLIやDynamoDB Localとの連携方法については引き続き調べたいと思いますが

一部でも参考になれば幸いです。

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

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

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)