2021年12月28日火曜日

AWS Step FunctionsのMapでループをイテレートする

Step functionsでループを回すとき、Lambdaを使っていたのですが、Mapを使う方が簡単なのではないかということでメモ。


WorkFlow Studioで描く

2021年に出た機能です。絵を書くのは簡単ですが、途中で保存できないのが少し困ります。そのうち改良されるでしょうが・・・。



コード全体

WorkFlow Studioで絵を書いてからコードに変換できます(逆はできない。。)

"MaxConcurrency": 1 としないとループしないで同時に実行してしまうので注意が必要です(デフォルト無設定)。エラー処理の部分はデフォルトです。

{
  "Comment": "A description of my state machine",
  "StartAt": "Map",
  "States": {
    "Map": {
      "Type": "Map",
      "Iterator": {
        "StartAt": "Lambda Invoke",
        "States": {
          "Lambda Invoke": {
            "Type": "Task",
            "Resource": "arn:aws:states:::lambda:<lambda-name>",
            "OutputPath": "$.Payload",
            "Parameters": {
              "FunctionName": "map_step_function:$LATEST"
            },
            "Retry": [
              {
                "ErrorEquals": [
                  "Lambda.ServiceException",
                  "Lambda.AWSLambdaException",
                  "Lambda.SdkClientException"
                ],
                "IntervalSeconds": 2,
                "MaxAttempts": 6,
                "BackoffRate": 2
              }
            ],
            "End": true
          }
        }
      },
      "End": true,
      "MaxConcurrency": 1
    }
  }
}

Lambda関数はこちらのを使っています。 
arn:aws:states:::lambda:<lambda-name> という名前になるようにしてnode.js  で作成します。

exports.handler = (event, context, callback) => {
    callback(null, "Hello, " + event.who + "!");
};

StepFunctionsに入力するデータ
[
  {
    "who": "bob"
  },
  {
    "who": "meg"
  },
  {
    "who": "joe"
  }
]
実行すると、イテレートしていることが分かります。


もう少し入力を変えたいときはこちらを参考に。

2021年12月23日木曜日

udemyの動画を一時停止したときのボタンが邪魔→解決

 Udemyの動画を見ているときに、一時停止すると中央にアイコンが出ます。

こんな感じで、講義中のコードが読めなくて邪魔。


どうにかならないかと思っていたのですが、AfterShokz OPENCOMMのボタンで停止すると、このアイコンが表示されないで済むことがわかりました。一時停止の解除も同じボタンでやる必要があります。他のBluetooth機器でもできるんじゃないでしょうか。ちょっと手間ですが、とりあえず解決しました。


2022/01/14 一時停止中の表示が消えるように変更されたようです。



2021年12月10日金曜日

CLIの出力のJSONをgrepで抜き出したい

JSON出力から一部を取り出したいとき、いつも困っているのでメモ

練習のために、CloudFormationのCLIコマンド出力をtmp.json に保存して使います。

{
    "Stacks":  [
        {
            "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/myteststack/466df9e0-0dff-08e3-8e2f-5088487c4896",
            "Description": "AWS CloudFormation Sample Template S3_Bucket: Sample template showing how to create a publicly accessible S3 bucket. **WARNING** This template creates an S3 bucket. You will be billed for the AWS resources used if you create a stack from this template.",
            "Tags": [],
            "Outputs": [
                {
                    "Description": "Name of S3 bucket to hold website content",
                    "OutputKey": "BucketName",
                    "OutputValue": "myteststack-s3bucket-jssofi1zie2w"
                }
            ],
            "StackStatusReason": null,
            "CreationTime": "2013-08-23T01:02:15.422Z",
            "Capabilities": [],
            "StackName": "myteststack",
            "StackStatus": "CREATE_COMPLETE",
            "DisableRollback": false
        }
    ]
}


一行だけを抜き出したい

OutputValue がある行を抜き出します。

grep -o '"OutputValue": "[^"]*' tmp.json | grep -o '[^"]*$'

'"OutputValue": "[^"]*' の部分で "OutputValue... の部分にマッチして(最後の"の手前まで)、
grep -o '[^"]*$' の部分で最初の " を削除しています。


一ブロックを抜き出したい

"Outputs" のブロックを抜き出します。中身を見ながらコマンドを作る必要があります。

a="$(cat tmp.json)" として、jsonの中身を変数aに入れておきます。 echo $a で確認できます。ここからネストした部分を切り出していきます。

echo $a | jq -r '.Stacks[0]'

で Stacks の1番目が見れます。

さらにOutputsを抜き出すには、こうなります。

echo $a | jq -r '.Stacks[0].Outputs[0]'

最終的に、cliコマンドの結果から繋げて直接見たいときは

aws cloudformation describe-stacks --stack-name aaaabbbbcccc | jq -r '.Stacks[0].Outputs[0]'

などとなります。


参考

https://stackoverflow.com/questions/36073695/how-to-retrieve-single-value-with-grep-from-json

https://unix.stackexchange.com/questions/597368/grep-print-value-of-a-key-in-json-that-is-stored-in-a-variable