Application Auto Scaling のスケールアウトを EventBridge で検知するための条件
Monitor Application Auto Scaling events using Amazon EventBridge - Application Auto Scaling
Only events that are specific to scaled to max and API calls via CloudTrail are currently available for Application Auto Scaling.
スケールアウトを検知する方法は以下の 2 つです。
- 最大までスケールアウトしたことを検知する方法
- CloudTrail のイベントを検知する方法
1. 最大までスケールアウトしたことを検知する方法
「最大まで」という条件があるため、以下のような挙動となります。
- Auto Scaling の最小容量 1, 希望容量 1, 最大容量 3 の場合
- 容量が 3 にスケールアウトした場合は検知可能
- 容量が 2 にスケールアウトした場合は検知不可
試してみた
ECS サービスを作成し、以下のスケーリングポリシーを設定しました。
- ターゲット追跡スケーリング
- メトリクスタイプ: ECSServiceAverageCPUUtilization
- 実行タスク数: 1 ~ 3
EventBridge ルールは以下のように定義しました。
{
"source": [
"aws.application-autoscaling"
],
"detail-type": [
"Application Auto Scaling Scaling Activity State Change"
],
"detail": {
"direction": ["scale-out"]
}
}
EventBridge ルールのターゲットは CloudWatch Logs です。
この状態で Auto Scaling のしきい値を 0.5 % などの極端に低い値に設定し、意図的に Auto Scaling を発動させます。
数分後に CloudWatch アラームがアラーム状態になり、CloudWatch Logs に以下のログが出力されました。
{
"version": "0",
"id": "0b079227-5ae7-1708-f3c3-e884cc8af443",
"detail-type": "Application Auto Scaling Scaling Activity State Change",
"source": "aws.application-autoscaling",
"account": "012345678901",
"time": "2025-03-21T10:32:10Z",
"region": "ap-northeast-1",
"resources": [],
"detail": {
"resourceId": "service/test/test",
"scaledToMax": true,
"scalableDimension": "ecs:service:DesiredCount",
"maxCapacity": 3,
"minCapacity": 1,
"startTime": "2025-03-21T10:31:01.336Z",
"serviceNamespace": "ecs",
"newDesiredCapacity": 3,
"endTime": "2025-03-21T10:32:04.787Z",
"oldDesiredCapacity": 1,
"statusCode": "Successful",
"direction": "scale-out"
}
}
scaledToMax
が true
なので最大容量までスケールアウトされたことでイベントが発火されたことがわかります。
2. CloudTrail のイベントを検知する方法
AWS service events delivered via AWS CloudTrail - Amazon EventBridge
最大容量までスケールアウトしない場合、上記のイベントパターンでは検知できません。
そのため、最大容量以外のスケールアウトも検知する必要がある場合、CloudTrail に記録される UpdateService などの API を検知にする必要があります。
ECS サービスの場合、タスク容量の調整は UpdateService によって実施されるため、以下のようなイベントパターンで検知できます。
UpdateService - Amazon Elastic Container Service
{
"source": ["aws.ecs"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventSource": ["ecs.amazonaws.com"],
"eventName": ["UpdateService"],
"userAgent": ["ecs.application-autoscaling.amazonaws.com"],
"requestParameters": {
"cluster": ["<ECS クラスター名>"],
"service": ["<ECS サービス名>"]
}
}
}
UpdateService API はコンソールからユーザーがタスク数を変更した場合にも記録されるため、Application Auto Scaling によるスケールアウトを検知するために userAgent を指定しています。
上記イベントパターンで検知したイベントには desiredCount が含まれているため、どの容量までスケールアウトしたのかを確認することができます。
UpdateService の記録
{
"version": "0",
"id": "bf64fc86-bb0f-e2af-f720-14c62cbd2192",
"detail-type": "AWS API Call via CloudTrail",
"source": "aws.ecs",
"account": "012345678901",
"time": "2025-03-21T10:57:53Z",
"region": "ap-northeast-1",
"resources": [],
"detail": {
"eventVersion": "1.11",
"userIdentity": {
"type": "AssumedRole",
"principalId": "xxx:AutoScaling-UpdateDesiredCapacity",
"arn": "arn:aws:sts::012345678901:assumed-role/AWSServiceRoleForApplicationAutoScaling_ECSService/AutoScaling-UpdateDesiredCapacity",
"accountId": "012345678901",
"accessKeyId": "xxx",
"sessionContext": {
"sessionIssuer": {
"type": "Role",
"principalId": "xxx",
"arn": "arn:aws:iam::012345678901:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService",
"accountId": "012345678901",
"userName": "AWSServiceRoleForApplicationAutoScaling_ECSService"
},
"attributes": {
"creationDate": "2025-03-21T10:57:53Z",
"mfaAuthenticated": "false"
}
},
"invokedBy": "ecs.application-autoscaling.amazonaws.com"
},
"eventTime": "2025-03-21T10:57:53Z",
"eventSource": "ecs.amazonaws.com",
"eventName": "UpdateService",
"awsRegion": "ap-northeast-1",
"sourceIPAddress": "ecs.application-autoscaling.amazonaws.com",
"userAgent": "ecs.application-autoscaling.amazonaws.com",
"requestParameters": {
"cluster": "test",
"desiredCount": 3,
"forceNewDeployment": false,
"service": "test"
},
"responseElements": {
"service": {
"serviceArn": "arn:aws:ecs:ap-northeast-1:012345678901:service/test/test",
"serviceName": "test",
"clusterArn": "arn:aws:ecs:ap-northeast-1:012345678901:cluster/test",
"loadBalancers": [],
"serviceRegistries": [],
"status": "ACTIVE",
"desiredCount": 3,
"runningCount": 2,
"pendingCount": 0,
"launchType": "FARGATE",
"platformVersion": "LATEST",
"platformFamily": "Linux",
"taskDefinition": "arn:aws:ecs:ap-northeast-1:012345678901:task-definition/test:61",
"deploymentConfiguration": {
"deploymentCircuitBreaker": {
"enable": true,
"rollback": true
},
"maximumPercent": 200,
"minimumHealthyPercent": 100,
"alarms": {
"alarmNames": [],
"rollback": false,
"enable": false
}
},
"deployments": [
{
"id": "ecs-svc/0324308393307114801",
"status": "PRIMARY",
"taskDefinition": "arn:aws:ecs:ap-northeast-1:012345678901:task-definition/test:61",
"desiredCount": 2,
"pendingCount": 0,
"runningCount": 2,
"failedTasks": 0,
"createdAt": "Mar 21, 2025, 10:20:09 AM",
"updatedAt": "Mar 21, 2025, 10:55:36 AM",
"launchType": "FARGATE",
"platformVersion": "1.4.0",
"platformFamily": "Linux",
"networkConfiguration": {
"awsvpcConfiguration": {
"assignPublicIp": "ENABLED",
"securityGroups": ["sg-0849e791c058df084"],
"subnets": [
"subnet-06ec2ff6a93ea5ba8",
"subnet-0f2690c6ffd8fd0b5",
"subnet-0f1c943a631285f62"
]
}
},
"rolloutState": "COMPLETED",
"rolloutStateReason": "ECS deployment ecs-svc/0324308393307114801 completed.",
"failedLaunchTaskCount": 0,
"replacedTaskCount": 0,
"scale": {
"value": 100,
"unit": "PERCENT"
},
"stabilityStatus": "STABILIZING"
}
],
"roleArn": "arn:aws:iam::012345678901:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS",
"version": 0,
"events": [
{
"id": "dac88e68-f6d2-4615-9948-b4b192ba323d",
"createdAt": "Mar 21, 2025, 10:55:36 AM",
"message": "(service test) has reached a steady state."
},
{
"id": "65111595-040f-4a70-b428-622e07d553e4",
"createdAt": "Mar 21, 2025, 10:54:58 AM",
"message": "(service test) has started 1 tasks: (task 3b2c41a4c9014b4aaaf4a91e10f7360f)."
},
{
"id": "738ceb54-9cc4-43f0-a52e-463eec81d0e7",
"createdAt": "Mar 21, 2025, 10:44:50 AM",
"message": "(service test) has reached a steady state."
},
{
"id": "5a46956b-f87b-4f65-9e37-1898427dffba",
"createdAt": "Mar 21, 2025, 10:44:41 AM",
"message": "(service test) has stopped 1 running tasks: (task 2d0e9b9cdd3a4c84bc83432edc63538a)."
},
{
"id": "7ab7cd0b-6e38-4f6d-a36e-d70afd4ee08e",
"createdAt": "Mar 21, 2025, 10:42:47 AM",
"message": "(service test) has reached a steady state."
},
{
"id": "eb07a2af-947b-44be-93ce-d29a944eff44",
"createdAt": "Mar 21, 2025, 10:42:38 AM",
"message": "(service test) has stopped 1 running tasks: (task 999efbc2fb6c4f348f5805e0c03ef960)."
},
{
"id": "fc461efb-6bbc-4a36-9398-1a9a51781b3a",
"createdAt": "Mar 21, 2025, 10:41:54 AM",
"message": "(service test) has reached a steady state."
},
{
"id": "3703b8f0-4f1c-413f-b1b6-24ad58a72a30",
"createdAt": "Mar 21, 2025, 10:41:46 AM",
"message": "(service test) has stopped 7 running tasks: (task e6acf1214dff401199917319d00b5901) (task 25006224e34a4a15baa1352f527f02ce) (task 7b68fec44cdc4fff9914ce97916c9aff) (task 3c86554e52fb4c98a9bea27c50626b82) (task 59d67050d5164815951a1bd80f7307ef) (task d749a5b9ed4d49dbb3090668ce8da691) (task bdc6f45fe2ba484196428e5f5ac58c46)."
},
{
"id": "3204dca2-37a6-4e19-ab5a-6972585120de",
"createdAt": "Mar 21, 2025, 10:38:40 AM",
"message": "(service test) has reached a steady state."
},
{
"id": "fee7510a-d767-4ecf-9f4c-8708e63470ac",
"createdAt": "Mar 21, 2025, 10:38:12 AM",
"message": "(service test) has started 9 tasks: (task 25006224e34a4a15baa1352f527f02ce) (task 2d0e9b9cdd3a4c84bc83432edc63538a) (task 3c86554e52fb4c98a9bea27c50626b82) (task 59d67050d5164815951a1bd80f7307ef) (task 7b68fec44cdc4fff9914ce97916c9aff) (task 999efbc2fb6c4f348f5805e0c03ef960) (task bdc6f45fe2ba484196428e5f5ac58c46) (task d749a5b9ed4d49dbb3090668ce8da691) (task e6acf1214dff401199917319d00b5901)."
},
{
"id": "ca2a6619-4acb-4d1d-bdfc-2eebf93cbc40",
"createdAt": "Mar 21, 2025, 10:31:39 AM",
"message": "(service test) has reached a steady state."
},
{
"id": "d03f29f1-1850-4003-8157-245d3d77a7f1",
"createdAt": "Mar 21, 2025, 10:31:11 AM",
"message": "(service test) has started 2 tasks: (task 28377ac6ec0a496da8d6b610a7fa6672) (task 3d0cbd5f0cf148d681f80f0fff80284d)."
},
{
"id": "1a66f172-20dc-42f4-91af-859571f5dfde",
"createdAt": "Mar 21, 2025, 10:23:04 AM",
"message": "(service test) has reached a steady state."
},
{
"id": "f6b0cf91-db85-444c-9201-e86d9d7e8a60",
"createdAt": "Mar 21, 2025, 10:23:04 AM",
"message": "(service test) (deployment ecs-svc/0324308393307114801) deployment completed."
},
{
"id": "a32f6f47-9c06-4f2a-9a9f-921f7dbe6c73",
"createdAt": "Mar 21, 2025, 10:20:23 AM",
"message": "(service test) has started 1 tasks: (task 930417a1fea144fbbbb0c52d07ae30a2)."
}
],
"createdAt": "Mar 21, 2025, 10:20:09 AM",
"placementConstraints": [],
"placementStrategy": [],
"networkConfiguration": {
"awsvpcConfiguration": {
"assignPublicIp": "ENABLED",
"securityGroups": ["sg-0849e791c058df084"],
"subnets": [
"subnet-06ec2ff6a93ea5ba8",
"subnet-0f2690c6ffd8fd0b5",
"subnet-0f1c943a631285f62"
]
}
},
"healthCheckGracePeriodSeconds": 0,
"schedulingStrategy": "REPLICA",
"deploymentController": {
"type": "ECS"
},
"createdBy": "xxx",
"enableECSManagedTags": true,
"propagateTags": "NONE",
"enableExecuteCommand": false,
"availabilityZoneRebalancing": "ENABLED",
"runStatus": "SteadyState",
"extendDeploymentTimePeriod": 0
}
},
"requestID": "c5a7edf3-ca00-4599-b05e-e78a81a4b72d",
"eventID": "aa3eefc6-88aa-4dd2-8597-9f2d45598bce",
"readOnly": false,
"eventType": "AwsApiCall",
"managementEvent": true,
"recipientAccountId": "012345678901",
"eventCategory": "Management"
}
}
情報量が多いので、メールや Slack に通知する場合には EventBridge の入力トランスフォーマーや Lambda で整形すると可視性が向上すると思います。
まとめ
Application Auto Scaling のスケールアウトを EventBridge で検知するための条件を紹介しました。
どなたかの参考になれば幸いです。
Discussion