🏴‍☠️

ALBターゲットグループの対象がECSサービスだとIPアドレスが表示されてて対象がわからない

2024/02/22に公開2

こういうの。

Alt text

terraformとかでALBのターゲットグループにECSのサービスを指定してこれを見ると、意識の外側から殴られたかのような感覚になりますね。

CLIで探しに行ってみよう👒

以下のコマンドを打つと対象タスクのJSONを取得できます!これで何のサービスを指定したのかわかります。
(結構時間かかるかも)

aws ecs list-tasks --cluster クラスター名 | jq -r '.taskArns[]' | xargs -L 1 aws ecs describe-tasks --cluster クラスター名 --tasks | jq 'select(.tasks[].containers[].networkInterfaces[].privateIpv4Address=="IPアドレス")' | jq -s 'unique_by(.tasks[].taskArn)'

これで終わり!ってするのは流石に短すぎるので解説を入れておきます。

解説

1. 全タスクのarnをゲット

aws ecs list-tasks --cluster クラスター名

aws cli です。
ecs list-tasks で対象のクラスター内にあるタスクをJSONで取得できます。
arnだけではどのタスクが何のIPアドレスを使ってるかわかりませんね。
arnを使ってそれぞれの詳細を出して、対象のIPがヒットしたら表示、ということをしていきます。

2. arnを1つずつ出して処理しやすくする

jq -r '.taskArns[]

jq です。JSONを整形したり、フィルタしたり、必要な情報を抜き出したりできます。
オブジェクトからtaskArnsという キーに入ってる値を配列として順次処理 して -rで1行ずつ表示 します。
例えば{taskArns: [1,2,3]}とかだったら

1
2
3

って感じで出してくれます。

3. タスクごとに詳細を取得

xargs -L 1 aws ecs describe-tasks --cluster クラスター名 --tasks

xargs とaws cliです。
xargsは標準入力を任意の箇所に入れたり、標準入力の行ごとにコマンド実行したりできます。
-L 1は1行ずつ処理する指定になります。(なくても良さそう)
さっきの例で言うと

aws ecs describe-tasks --cluster クラスター名 --tasks 1
aws ecs describe-tasks --cluster クラスター名 --tasks 2
aws ecs describe-tasks --cluster クラスター名 --tasks 3

こんな感じの実行ができます!嬉しいね。

ちなみに describe-tasks はタスクの詳細を取得できます。

4. IPアドレスでフィルタリング

jq 'select(.tasks[].containers[].networkInterfaces[].privateIpv4Address=="IPアドレス")'

またjqです。
select を使うとマッチする情報のみにフィルタリングできます。

はい、これで終わりの方は終わりです。
しかし、人によっては同じタスクが重複して表示されているかと思います。

5. 重複タスクを除去

jq -s 'unique_by(.tasks[].taskArn)'

またまたjqです。
taskのarnが被らないよう unique_by で結果を整形します。
-sオプションを指定することで行の分かれた標準入力を1つの配列として処理できます。
(jqからjqに繋げるのが冗長というかなんかjq1つで解決する方法ありそうなんですが今回わからなかったです)

終わり

これでterraformと睨めっこしないで済むようになりました!

正直CLIをあまり使ってこなかったので目的ベースで触ると楽しいですね。
これからもっとCLIを使ってエンジニアライフをさらに楽しみましょう!

ソーシャルデータバンク テックブログ

Discussion

rakiraki

興味深かったのでちょっとやってみました。

  • 1つ目の jq は明らかに冗長なので --query で消します。
  • text 出力させるとarrayがくっついてタブ区切りになるのは [@] で回避
  • xargs は -I で名前を付けてあげると -L 1 みたいな動きができるし読みやすい。
  • describe-tasks の query で絞り込みしたかったんだけど冗長になりすぎたので諦めた
  • ので IP と taskArn を1行にまとめてテキストで出力
  • IPで grep して sort -u(ユニーク抜いてソート)
export ECSCLUSTER=<クラスタ名>; \
export IPADDR=<IPアドレス>; \
aws ecs list-tasks --cluster $ECSCLUSTER --query 'taskArns[].[@]' --output text \
| xargs -ITASK aws ecs describe-tasks --cluster $ECSCLUSTER --tasks TASK --output text \
--query 'tasks[].[containers[].networkInterfaces[].privateIpv4Address, taskArn][][]' \
| grep $IPADDR \
| sort -u

むしろ長くなってるし IP と taskArn だけになってるじゃねぇかってつっこみは jq を使わない例、ということでひとつw

AsahiAsahi

コメントありがとうございます!励みになります😄

1つ目の jq は明らかに冗長なので --query で消します。

queryオプションというのがあるんですね...ありがとうございます!使ってみます

jq頼りだったのでとても参考になりました!