💡
ECS内部からCloudWatch LogsのURLを生成する
経緯
Step Functionsのフローで、FargateなECSを用いて実行しているPythonの結果によって
- pass
- lambda経由でslackにアラート
という分岐をさせているのですが、2で流すメッセージの中にアラート元のECSコンテナに紐づくCloudWatch LogsのURLを含めたいと思っていました。含まれていると嬉しい為。
例:右側$.result_status == false
の際のlambda payloadにcloudwatch URLも含めたい
現在のCloudWatch LogsのURL構成は以下になっているので......
# NOTE: {project_name}周りは実際の設定によって異なるためご自身の環境で改めてURL構成を確認してください
https://{region}.console.aws.amazon.com/cloudwatch/home?/region={region}#logsV2:log-groups/log-group/$252Faws$252Fecs$252F{project_name}/log-events/ecs$252F{task_name}$252F{TASK_ARN}
regionやtask_nameの様な固定値と合わせて、末尾のTASK_ARNの値が実行中のコンテナ内部から取得できればログに紐づくURLが自動的に生成できるようになります。
...
実行中にTASK_ARNってどこから取るの?(StepFunctionsだとoutputとかに出てるけど)boto3/ecsでdescribe_tasksとかから取るの?しんどくない?
等と思い、色々探してたら結構時間を食っていたのですぐ思い出せるように記します。
...
ECS内部からCloudWatch LogsのURLを生成する
ECSタスクでの各コンテナ内部の環境変数
- ECS_CONTAINER_METADATA_URI_V4
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-metadata-endpoint-v4-fargate.html
に設定されているメタデータ取得用のendpointからタスクのメタデータを取得して、ほぐした値でURLをフォーマットしてあげて下さい。
import json
import os
import requests
ECS_CONTAINER_METADATA_URI_V4 = os.environ["ECS_CONTAINER_METADATA_URI_V4"]
res = requests.get(f"{metadata_url}/task")
if res.status_code == 200:
metadata = json.loads(res.text)
region = metadata["Containers"][0]["LogOptions"]["awslogs-region"]
task_arn = metadata["TaskARN"].split("/")[-1]
cloudwatch_url = f"https://{region}.console.aws.amazon.com/cloudwatch/home?region={region}#logsV2:log-groups/log-group/$252Faws$252Fecs$252F{project_name}$252Fcluster/log-events/ecs$252F{task_name}$252F{task_arn}"
else:
cloudwatch_url = None
コレで生成したURLを、Pythonタスクのreturn時に
sfn.send_task_success(
taskToken = TASK_TOKEN,
output=json.dumps({
"result_status": result_status,
"cloudwatch_url": cloudwatch_url
})
)
return None
等として次のlambda stepに渡してあげて下さい。
Discussion