もりはやメモφ(・ω・ )

インフラなエンジニアからSREへ

digdagのループ for_each 利用時の _parallel 指定について

digdagのループ for_each 利用時の _parallel 指定について仕様を調べたのでメモ。

公式ドキュメントの Parallel execution にある通り「子タスクには効果があるが、孫タスクには効果が無い」ことを確認します。

If _parallel: true parameter is set to a group, child tasks in the group run in parallel (grandchildren are not affected):

ケース1: _parallel指定無し

_parallelを指定しなかった場合、デフォルトがシーケンシャルのため、全てがシーケンシャルに実行されます。

+testing:
  _export:
    sweet: &SWEETS
      - apple
      - banana
      - candy

  for_each>:
    sweet: *SWEETS

  _do:
    +task1:
      sh>: echo "$(date) - ${sweet} - 1" ; sleep 3

    +task2:
      sh>: echo "$(date) - ${sweet} - 2"

実行ログは以下のとおり。appleの1, 2が行われ、続いてbanana, candyという順に実行されます。

2020-04-15 22:26:29 +0900: Digdag v0.9.41
2020-04-15 22:26:41 +0900 [WARN] (main): Reusing the last session time 2020-04-14T00:00:00+00:00.
2020-04-15 22:26:41 +0900 [INFO] (main): Using session /Users/morihaya/work/testdig/.digdag/status/20200414T000000+0000.
2020-04-15 22:26:41 +0900 [INFO] (main): Starting a new session project id=1 workflow name=child session_time=2020-04-14T00:00:00+00:00
2020-04-15 22:26:42 +0900 [INFO] (0017@[0:default]+child+testing): for_each>: {sweet=[apple, banana, candy]}
2020-04-15 22:26:43 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=0=apple+task1): sh>: echo "$(date) - apple - 1" ; sleep 3
Wed Apr 15 22:26:43 JST 2020 - apple - 1
2020-04-15 22:26:46 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=0=apple+task2): sh>: echo "$(date) - apple - 2"
Wed Apr 15 22:26:46 JST 2020 - apple - 2
2020-04-15 22:26:46 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=1=banana+task1): sh>: echo "$(date) - banana - 1" ; sleep 3
Wed Apr 15 22:26:46 JST 2020 - banana - 1
2020-04-15 22:26:50 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=1=banana+task2): sh>: echo "$(date) - banana - 2"
Wed Apr 15 22:26:50 JST 2020 - banana - 2
2020-04-15 22:26:50 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=2=candy+task1): sh>: echo "$(date) - candy - 1" ; sleep 3
Wed Apr 15 22:26:50 JST 2020 - candy - 1
2020-04-15 22:26:53 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=2=candy+task2): sh>: echo "$(date) - candy - 2"
Wed Apr 15 22:26:53 JST 2020 - candy - 2
Success. Task state is saved at /Users/morihaya/work/testdig/.digdag/status/20200414T000000+0000 directory.
  * Use --session <daily | hourly | "yyyy-MM-dd[ HH:mm:ss]"> to not reuse the last session time.
  * Use --rerun, --start +NAME, or --goal +NAME argument to rerun skipped tasks.

ケース2: タスクの外で _parallel 指定は意味がない

以下のように、タスクの外で _parallel: true を指定しても効果がないことがわかりました。

_parallel: true

+testing:
  _export:
    sweet: &SWEETS
      - apple
      - banana
      - candy

  for_each>:
    sweet: *SWEETS

  _do:
    +task1:
      sh>: echo "$(date) - ${sweet} - 1" ; sleep 3

    +task2:
      sh>: echo "$(date) - ${sweet} - 2"

ログは以下の通り

2020-04-15 22:30:42 +0900: Digdag v0.9.41
2020-04-15 22:30:54 +0900 [WARN] (main): Reusing the last session time 2020-04-14T00:00:00+00:00.
2020-04-15 22:30:54 +0900 [INFO] (main): Using session /Users/morihaya/work/testdig/.digdag/status/20200414T000000+0000.
2020-04-15 22:30:54 +0900 [INFO] (main): Starting a new session project id=1 workflow name=child session_time=2020-04-14T00:00:00+00:00
2020-04-15 22:30:55 +0900 [INFO] (0017@[0:default]+child+testing): for_each>: {sweet=[apple, banana, candy]}
2020-04-15 22:30:56 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=0=apple+task1): sh>: echo "$(date) - apple - 1" ; sleep 3
Wed Apr 15 22:30:56 JST 2020 - apple - 1
2020-04-15 22:30:59 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=0=apple+task2): sh>: echo "$(date) - apple - 2"
Wed Apr 15 22:30:59 JST 2020 - apple - 2
2020-04-15 22:30:59 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=1=banana+task1): sh>: echo "$(date) - banana - 1" ; sleep 3
Wed Apr 15 22:31:00 JST 2020 - banana - 1
2020-04-15 22:31:03 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=1=banana+task2): sh>: echo "$(date) - banana - 2"
Wed Apr 15 22:31:03 JST 2020 - banana - 2
2020-04-15 22:31:03 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=2=candy+task1): sh>: echo "$(date) - candy - 1" ; sleep 3
Wed Apr 15 22:31:03 JST 2020 - candy - 1
2020-04-15 22:31:06 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=2=candy+task2): sh>: echo "$(date) - candy - 2"
Wed Apr 15 22:31:06 JST 2020 - candy - 2
Success. Task state is saved at /Users/morihaya/work/testdig/.digdag/status/20200414T000000+0000 directory.
  * Use --session <daily | hourly | "yyyy-MM-dd[ HH:mm:ss]"> to not reuse the last session time.
  * Use --rerun, --start +NAME, or --goal +NAME argument to rerun skipped tasks.

ケース3: タスク内で _parallel 指定はループの要素に効果はあるが、doの中には効果がない

タスクの中で _parallel: true を指定すると apple, banana, candy という各要素についてはパラレルで実行されるが、 _do: で指定したタスクはシーケンシャルで実行されました。子タスク=要素のループで、孫タスク=_doの中のタスクと分かりました。

+testing:
  _parallel: true
  _export:
    sweet: &SWEETS
      - apple
      - banana
      - candy

  for_each>:
    sweet: *SWEETS

  _do:
    +task1:
      sh>: echo "$(date) - ${sweet} - 1" ; sleep 3

    +task2:
      sh>: echo "$(date) - ${sweet} - 2"

以下はログ。apple, banana, candy はパラレルで実行されるため、順番も入れ替わって見えますが、task2 が task1 より先に実行されることはありません。

2020-04-15 22:35:13 +0900: Digdag v0.9.41
2020-04-15 22:35:26 +0900 [WARN] (main): Reusing the last session time 2020-04-14T00:00:00+00:00.
2020-04-15 22:35:26 +0900 [INFO] (main): Using session /Users/morihaya/work/testdig/.digdag/status/20200414T000000+0000.
2020-04-15 22:35:26 +0900 [INFO] (main): Starting a new session project id=1 workflow name=child session_time=2020-04-14T00:00:00+00:00
2020-04-15 22:35:27 +0900 [INFO] (0017@[0:default]+child+testing): for_each>: {sweet=[apple, banana, candy]}
2020-04-15 22:35:29 +0900 [INFO] (0018@[0:default]+child+testing^sub+for-0=sweet=1=banana+task1): sh>: echo "$(date) - banana - 1" ; sleep 3
2020-04-15 22:35:29 +0900 [INFO] (0019@[0:default]+child+testing^sub+for-0=sweet=2=candy+task1): sh>: echo "$(date) - candy - 1" ; sleep 3
Wed Apr 15 22:35:29 JST 2020 - candy - 1
Wed Apr 15 22:35:29 JST 2020 - banana - 1
2020-04-15 22:35:29 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=0=apple+task1): sh>: echo "$(date) - apple - 1" ; sleep 3
Wed Apr 15 22:35:29 JST 2020 - apple - 1
2020-04-15 22:35:32 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=0=apple+task2): sh>: echo "$(date) - apple - 2"
2020-04-15 22:35:32 +0900 [INFO] (0019@[0:default]+child+testing^sub+for-0=sweet=1=banana+task2): sh>: echo "$(date) - banana - 2"
Wed Apr 15 22:35:32 JST 2020 - apple - 2
Wed Apr 15 22:35:32 JST 2020 - banana - 2
2020-04-15 22:35:32 +0900 [INFO] (0018@[0:default]+child+testing^sub+for-0=sweet=2=candy+task2): sh>: echo "$(date) - candy - 2"
Wed Apr 15 22:35:32 JST 2020 - candy - 2
Success. Task state is saved at /Users/morihaya/work/testdig/.digdag/status/20200414T000000+0000 directory.
  * Use --session <daily | hourly | "yyyy-MM-dd[ HH:mm:ss]"> to not reuse the last session time.
  * Use --rerun, --start +NAME, or --goal +NAME argument to rerun skipped tasks.

ケース4: タスク内でも、do内でも parallel 指定をすると全てがパラレルで実行される

要素についても、タスクについてもパラレルで実行する場合のケースです。

+testing:
  _parallel: true
  _export:
    sweet: &SWEETS
      - apple
      - banana
      - candy

  for_each>:
    sweet: *SWEETS

  _do:
    _parallel: true
    +task1:
      sh>: echo "$(date) - ${sweet} - 1" ; sleep 3

    +task2:
      sh>: echo "$(date) - ${sweet} - 2"

全てが同じ時間に実行されています。

2020-04-15 22:40:14 +0900: Digdag v0.9.41
2020-04-15 22:40:26 +0900 [WARN] (main): Reusing the last session time 2020-04-14T00:00:00+00:00.
2020-04-15 22:40:26 +0900 [INFO] (main): Using session /Users/morihaya/work/testdig/.digdag/status/20200414T000000+0000.
2020-04-15 22:40:26 +0900 [INFO] (main): Starting a new session project id=1 workflow name=child session_time=2020-04-14T00:00:00+00:00
2020-04-15 22:40:27 +0900 [INFO] (0017@[0:default]+child+testing): for_each>: {sweet=[apple, banana, candy]}
2020-04-15 22:40:28 +0900 [INFO] (0018@[0:default]+child+testing^sub+for-0=sweet=0=apple+task2): sh>: echo "$(date) - apple - 2"
2020-04-15 22:40:28 +0900 [INFO] (0019@[0:default]+child+testing^sub+for-0=sweet=1=banana+task1): sh>: echo "$(date) - banana - 1" ; sleep 3
Wed Apr 15 22:40:28 JST 2020 - banana - 1
Wed Apr 15 22:40:28 JST 2020 - apple - 2
2020-04-15 22:40:28 +0900 [INFO] (0020@[0:default]+child+testing^sub+for-0=sweet=1=banana+task2): sh>: echo "$(date) - banana - 2"
2020-04-15 22:40:28 +0900 [INFO] (0022@[0:default]+child+testing^sub+for-0=sweet=2=candy+task2): sh>: echo "$(date) - candy - 2"
Wed Apr 15 22:40:28 JST 2020 - banana - 2
Wed Apr 15 22:40:28 JST 2020 - candy - 2
2020-04-15 22:40:28 +0900 [INFO] (0021@[0:default]+child+testing^sub+for-0=sweet=2=candy+task1): sh>: echo "$(date) - candy - 1" ; sleep 3
Wed Apr 15 22:40:28 JST 2020 - candy - 1
2020-04-15 22:40:28 +0900 [INFO] (0017@[0:default]+child+testing^sub+for-0=sweet=0=apple+task1): sh>: echo "$(date) - apple - 1" ; sleep 3
Wed Apr 15 22:40:28 JST 2020 - apple - 1
Success. Task state is saved at /Users/morihaya/work/testdig/.digdag/status/20200414T000000+0000 directory.
  * Use --session <daily | hourly | "yyyy-MM-dd[ HH:mm:ss]"> to not reuse the last session time.
  * Use --rerun, --start +NAME, or --goal +NAME argument to rerun skipped tasks.

まとめ

当たり前ですが、以下のドキュメントの通りの動きを確認できたので満足しました。 ループと _parallel の組み合わせは強力ですが乱用するとキューが詰まって他のWorkflowに影響が出ることもありますので要注意ですね。

If _parallel: true parameter is set to a group, child tasks in the group run in parallel (grandchildren are not affected):

AWS WorkspacesのDirectryを削除しようとしたら "Cannot delete the directory because it still has authorized applications" が出る対策

検証で利用していたAWS Workspacesのお掃除をしていたところ、以下のエラーが発生して消せなくて焦りました。

An Error Has Occurred Cannot delete the directory because it still has authorized applications. Additional directory details can be viewed at the Directory Service console.

f:id:morihaya:20200403171821p:plain
エラー画面

対策: 利用中のアプリを先に削除する

原因は全てのアプリを削除していないためでした。エラーメッセージのリンク先に飛ぶと、ディレクトリの詳細ページが表示され、以下のように利用中のアプリケーションの一覧んを確認できます。

この図では Amazon WorkDocsEnabled になっているため、ディレクトリを削除できなかったのです。

f:id:morihaya:20200403172317p:plain
利用中のアプリ一覧

リンク先へ飛びWork Docsも削除します。WorkDocsの削除画面には親切なことに I also want to delete the user directory オプションが表示されましたので、チェックを入れて削除を行います。

f:id:morihaya:20200403172624p:plain
WorkDocs削除画面

念のため Workspacesのディレクトリ一覧に戻ると、 deleting ステータスを確認できました。こちらでお掃除が完了です。

f:id:morihaya:20200403172949p:plain
削除されつつあるディレクトリの図

まとめ。

GUIでサクサクと起動できるのはいいですが、裏で複数サービスが連携して作成されることで、一箇所で削除ができないのはよくある話ですが、直面すると少し焦りますね。

awsコマンドでEC2のGlobal IPとPrivate IPを取得する1行コマンド

開発者から「IPアドレスの一覧が欲しい」と言われて必要になったので作りました。メモとして残しておきます。

aws ec2 describe-instances | jq -c '.Reservations[].Instances[] | [ (.Tags[]? | select(.Key == "Name")).Value, .PrivateIpAddress, .PublicIpAddress]' | sed -E 's/\[|\]//g' | sed -E 's/,/\|/g' | tr -d '"' | sed -E 's/^/\|/g'| sed -E 's/$/\|/g' | sort

すると以下のような結果が取れます。(IPはサンプル)

|morihaya-test-01|192.168.1.13|203.0.113.1|
|morihaya-test-02|192.168.2.11|203.0.113.2|

ヘッダーをつけて、esaなどのMarkdown対応なドキュメントに載せます。

| Hostname | Private IP | Public IP |
| --- | --- | --- | 
|morihaya-test-01 |192.168.1.13|203.0.113.1 |
|morihaya-test-02|192.168.2.11|203.0.113.2 |

すると以下のように一覧になって良さ、という話でした。

Hostname Private IP Public IP
morihaya-test-01 192.168.1.13 203.0.113.1
morihaya-test-02 192.168.2.11 203.0.113.2

もちろんサーバは日々変動することがあり、現実とのデグレが発生する未来が見えるので必要なメンバにAWSコンソールを渡してしまうのも手なのですが、ささっと閲覧可能なドキュメントとして作る分には良し。

Prometheus Meetup Tokyo #3 に参加してきました

1/15に 行われた Prometheus Meetup Tokyo #3 にブログ枠で参加してきました。

prometheus.connpass.com

  • Prometheusと私
    • 昔ちょっとだけ触った
    • 今は全然触ってない...
    • 参加のモチベーション
  • Prometheus Meetup Tokyo #3の感想
    • 会場
    • 1 - Remote Write API と Thanos を活用したメトリクス永続化 (仮)
    • 2 - Victoria Metricsで作りあげる大規模・超負荷システムモニタリング基盤
    • 3 - 次世代のログ基盤 Grafana Lokiを始めよう!
    • LT
      • イベントネットワークのlog監視をlokiでやってみた - gen16k
      • レガシー環境でも Prometheus はイケるんです - Kazuhito_Omachi
      • Prometheus でデータの水平分割を試みる - watawuwu
      • Lokiでjurnal logを可視化する方法 - yosshi_
      • Grafana/Lokiの開発元にfluent-bitのプラグインを作成してフィードバックした話- Hiroshi Hatake
  • まとめ
続きを読む

ALBとTargetGroup一式をTerraformにimportしてみる

年の瀬に何やってんだという感じではありますが、ちょっとしたタスク整理でALB一式をTerraformに落としたくなる場面があったので作業メモを残します。*1 試行錯誤した結果をそのままメモとして残していきますので、上級者が良いやり方をまとめた記事ではないことにご注意ください。

  • importするリソース
  • 前提
  • 作業開始
    • Terraforming準備
    • Terraformingでimportしようとしたが...
      • ALB
      • TargetGroup....はTerraformingにはないっぽい
    • 仕切り直しでTerraformerを準備
    • TerraformerでALBをimport
    • TerraformerでRoute53を追加でimport
    • Terrafomerが生成したファイルを確認して、利用したいものだけ拾っていく
      • lb.tf
      • lb_listenere.tf
      • lb_listener_rule.tf
      • lb_target_group.tf
      • lb_target_group_attachment.tf
      • リファクタリング
      • 手動でterraform import
      • target_group_attachmentはimportできないので諦める
    • VPC周りをdataで用意
    • SecurityGroupも追加
    • cognitoのimport
    • 仕上げ
    • 今後やること
  • まとめ

importするリソース

Importしてコード管理したいのは、以下のリソースです

  • ALB
  • TargetGroup
  • Cognito --> 残念ながらCognitoのimportは対応してませんでした、現状は手書きしてimportしかなさそうです *2

*1:早速昨日の振り返りが生きてる

*2:本来はRoute53も管理したいところなんですが、諸事情で別アカウント管理になっているため割愛しています

続きを読む