はじめに
ECSタスクをAWS Fargateで実行する際、Datadogを活用した監視やCloudWatch Logsを使ったログ管理が重要になります。
本記事では、Terraformを用いてECSタスク定義を構築する手順を解説します。
書こうと思ったきっかけ
ECSタスクを運用する中で、コンテナの監視やログ管理を適切に設定しないと、トラブル時の原因特定が困難になると実感しました。
DatadogやCloudWatch Logsを組み合わせることで、リアルタイムの監視や効率的なデバッグが可能になるため、その方法を整理してみました。
実際に解説してみた
このTerraformの設定は、AWS Fargate上で動作するECSタスク を定義しています。
タスクには、Datadog監視用のエージェントとアプリケーションコンテナが含まれており、CloudWatch Logsでログを管理 する構成になっています。
それぞれのパートについて詳しく解説します。
1. ECSタスクの基本設定
resource "aws_ecs_task_definition" "main" {
family = "Datadog"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = "256"
memory = "512"
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
-
何をしているか?
- タスク名 (
family
) を"Datadog"
に設定 -
ネットワークモード (
network_mode
) を"awsvpc"
に指定(各コンテナに独自の ENI が付与される) - Fargate を使用 (
requires_compatibilities
) -
CPU とメモリを指定 (
cpu
,memory
)-
cpu = 256
(0.25 vCPU)、memory = 512 MB
(リソースが少なめの軽量コンテナ向け)
-
- 実行ロール (
execution_role_arn
) を指定し、タスクが AWS のサービスへアクセスできるようにする
- タスク名 (
2. ボリュームの設定
volume {
name = "cws-instrumentation-volume"
}
-
何をしているか?
cws-instrumentation-volume
という名前のボリュームを作成- コンテナ間で共有するデータの保存用
3. Datadog用の初期設定コンテナ (cws-instrumentation-init
)
{
name = "cws-instrumentation-init"
image = "datadog/cws-instrumentation:latest"
essential = false
user = "0"
command = [
"/cws-instrumentation",
"setup",
"--cws-volume-mount",
"/cws-instrumentation-volume"
]
mountPoints = [
{
sourceVolume = "cws-instrumentation-volume"
containerPath = "/cws-instrumentation-volume"
readOnly = false
}
]
-
何をしているか?
- Datadog のセキュリティ監視用の初期設定コンテナ
command
により/cws-instrumentation setup
を実行し、ボリュームに設定情報を書き込む- ボリュームを
/cws-instrumentation-volume
にマウント
4. Datadogエージェント (datadog-agent
)
{
name = "datadog-agent"
image = "datadog/agent:latest"
essential = true
environment = [
{
name = "DD_API_KEY"
value = "xxx"
},
{
name = "DD_SITE"
value = "ap1.datadoghq.com"
},
{
name = "ECS_FARGATE"
value = "true"
},
# メトリクス収集(CPU・メモリ)を有効化
{
name = "DD_CONTAINER_METRICS_ENABLED"
value = "true"
},
-
何をしているか?
- Datadog の監視エージェントを起動
- 環境変数で Datadog の API キー (
DD_API_KEY
) や監視サイト (DD_SITE
) を指定 - CPU/メモリメトリクス (
DD_CONTAINER_METRICS_ENABLED=true
) を有効化 -
不要な機能(APM, Process Monitoring, Security Agent など)を無効化
DD_PROCESS_AGENT_ENABLED=false
DD_APM_ENABLED=false
DD_SECURITY_AGENT_ENABLED=false
DD_LOGS_ENABLED=false
5. アプリケーションコンテナ (my-app-repo
)
{
name = "my-app-repo"
image = "881490128743.dkr.ecr.ap-northeast-1.amazonaws.com/my-app-repo"
entryPoint = ["/usr/src/app/app"] # 実行ファイルの絶対パスを指定
-
何をしているか?
- アプリケーションコンテナ
- ECR (Amazon Elastic Container Registry) に格納された
my-app-repo
の Docker イメージを使用 - エントリーポイント (
entryPoint
) を/usr/src/app/app
に指定
依存関係の設定
dependsOn = [
{
containerName = "datadog-agent"
condition = "HEALTHY"
},
{
containerName = "cws-instrumentation-init"
condition = "SUCCESS"
}
]
- Datadog エージェント (
datadog-agent
) がヘルスチェック (HEALTHY
) を通過し、 cws-instrumentation-init
のセットアップが成功 (SUCCESS
) してから起動。
ポート設定
portMappings = [
{
containerPort = 1323
hostPort = 1323
protocol = "tcp"
}
]
- アプリケーションの通信を
1323
ポートで受け付ける
6. CloudWatch Logs の設定
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = "/ecs/datadog"
awslogs-region = "ap-northeast-1"
awslogs-stream-prefix = "my-app-repo"
}
}
-
何をしているか?
- CloudWatch Logs (
awslogs
) にアプリケーションのログを送信 - ロググループ
/ecs/datadog
を使用 - AWS リージョン
ap-northeast-1
に設定 - ログストリームのプレフィックスを
"my-app-repo"
にする
- CloudWatch Logs (
ここまでの設定周りを表にしてみた
設定項目 | 説明 |
---|---|
ECS タスク定義 | Fargate で動作する ECS タスクを定義 |
ネットワークモード (awsvpc ) |
各コンテナに独立した ENI を割り当てる |
CPU / メモリ設定 | 256 vCPU / 512MB |
Datadog 初期設定 (cws-instrumentation-init ) |
Datadog のセキュリティ設定を準備 |
Datadog エージェント (datadog-agent ) |
モニタリング用コンテナを起動 |
アプリケーション (my-app-repo ) |
ECR から取得したアプリケーションコンテナ |
依存関係 (dependsOn ) |
Datadog エージェントが正常に起動してからアプリを起動 |
ポート設定 (portMappings ) |
1323 ポートで通信 |
CloudWatch Logs 設定 (logConfiguration ) |
ログを /ecs/datadog に送信 |
実際の完成したコードについて
# ECS タスク定義(Fargate で動作するコンテナの定義)
resource "aws_ecs_task_definition" "main" {
family = "Datadog"
network_mode = "awsvpc"
requires_compatibilities = ["FARGATE"]
cpu = "256"
memory = "512"
execution_role_arn = aws_iam_role.ecs_task_execution_role.arn
volume {
name = "cws-instrumentation-volume"
}
container_definitions = jsonencode([
{
name = "cws-instrumentation-init"
image = "datadog/cws-instrumentation:latest"
essential = false
user = "0"
command = [
"/cws-instrumentation",
"setup",
"--cws-volume-mount",
"/cws-instrumentation-volume"
]
mountPoints = [
{
sourceVolume = "cws-instrumentation-volume"
containerPath = "/cws-instrumentation-volume"
readOnly = false
}
]
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = "/ecs/datadog"
awslogs-region = "ap-northeast-1"
awslogs-stream-prefix = "cws-instrumentation-init"
}
}
},
{
name = "datadog-agent"
image = "datadog/agent:latest"
essential = true
environment = [
{
name = "DD_API_KEY"
value = "xxx"
},
{
name = "DD_SITE"
value = "ap1.datadoghq.com"
},
{
name = "ECS_FARGATE"
value = "true"
},
# メトリクス収集(CPU・メモリ)を有効化
{
name = "DD_CONTAINER_METRICS_ENABLED"
value = "true"
},
# Process Monitoring を完全に無効化
{
name = "DD_PROCESS_AGENT_ENABLED"
value = "false"
},
{
name = "DD_PROCESS_CONFIG_ENABLED"
value = "false"
},
{
name = "DD_ORCHESTRATOR_EXPLORER_ENABLED"
value = "false"
},
{
name = "DD_SYSTEM_PROBE_ENABLED"
value = "false"
},
# APM, ログ, セキュリティ機能も無効化
{
name = "DD_LOGS_ENABLED"
value = "false"
},
{
name = "DD_APM_ENABLED"
value = "false"
},
{
name = "DD_TRACE_ENABLED"
value = "false"
},
{
name = "DD_SECURITY_AGENT_ENABLED"
value = "false"
},
{
name = "DD_RUNTIME_SECURITY_CONFIG_ENABLED"
value = "false"
},
{
name = "DD_RUNTIME_SECURITY_CONFIG_EBPFLESS_ENABLED"
value = "false"
}
]
healthCheck = {
command = ["CMD-SHELL", "/probe.sh"]
interval = 30
timeout = 5
retries = 2
startPeriod = 60
}
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = "/ecs/datadog"
awslogs-region = "ap-northeast-1"
awslogs-stream-prefix = "datadog-agent"
}
}
},
{
name = "my-app-repo"
image = "881490128743.dkr.ecr.ap-northeast-1.amazonaws.com/my-app-repo"
entryPoint = ["/usr/src/app/app"] # 実行ファイルの絶対パスを指定
mountPoints = [
{
sourceVolume = "cws-instrumentation-volume"
containerPath = "/cws-instrumentation-volume"
readOnly = true
}
]
linuxParameters = {
capabilities = {
add = ["SYS_PTRACE"]
}
}
dependsOn = [
{
containerName = "datadog-agent"
condition = "HEALTHY"
},
{
containerName = "cws-instrumentation-init"
condition = "SUCCESS"
}
]
portMappings = [
{
containerPort = 1323
hostPort = 1323
protocol = "tcp"
}
]
logConfiguration = {
logDriver = "awslogs"
options = {
awslogs-group = "/ecs/datadog"
awslogs-region = "ap-northeast-1"
awslogs-stream-prefix = "my-app-repo"
}
}
}
])
}
まとめ
この記事は、自分用の備忘録としてまとめたものです。その点をご理解いただけると幸いです。
もし、この記事の内容が少しでも参考になれば嬉しく思います。
今後も同様の内容を継続して投稿していきますので、温かく見守っていただけるとありがたいです。