EC2インスタンス起動時のキャパシティ不足エラーを通知してみる

EC2 インスタンスを起動時にキャパシティ不足が発生した場合の通知を試してみました。
2022.11.08

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

EC2 インスタンス起動時にキャパシティ不足が発生したときに通知したいと思い、試してみました。

通知は Amazon EventBridge で RunInstance のエラーコードServer.InsufficientInstanceCapacityを契機にすることで実現できました。マネジメントコンソール上で EC2 インスタンス起動時にキャパシティ不足が発生する場合と AutoScaling が EC2 インスタンス起動時にキャパシティ不足が発生する場合の通知を確認しました。

試してみた

Server error codes の種類は次の API リファレンスで公開されており、キャパシティ不足はInsufficientInstanceCapacityが該当します。

Error codes for the Amazon EC2 API - Amazon Elastic Compute Cloud

InsufficientInstanceCapacityの説明の抜粋です。

There is not enough capacity to fulfill your request. This error can occur if you launch a new instance, restart a stopped instance, create a new Capacity Reservation, or modify an existing Capacity Reservation. Reduce the number of instances in your request, or wait for additional capacity to become available. You can also try launching an instance by selecting different instance types (which you can resize at a later stage). The returned message might also give specific guidance about how to solve the problem.

このエラーコードを利用して、Amazon EventBridge で次のイベントパターンを設定することで、キャパシティ不足発生を通知することができます。

{
  "source": ["aws.ec2"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": ["ec2.amazonaws.com"],
    "eventName": ["RunInstances"],
    "errorCode": ["Server.InsufficientInstanceCapacity"]
  }
}

Amazon EventBridge のイベントメニューのルールから新しいルールを作成します。なお、SNS トピックは作成済みとします。

始めに、名前と説明(オプション)を入力します。

次に、イベントソースとしてその他を選択した後に、上述したイベントパターンを入力します。

次に、通知先となるターゲットを設定します。

通知先となる SNS トピックは事前に作成しておく必要があります。今回は、Slack に通知する SNS トピックを選択しています。

最後に、任意でタグを設定し、レビュー(確認)した後にルールの作成を行えば完了です。

ここからは通知内容を確認してみます。

まずはマネジメントコンソール上で EC2 インスタンスの起動する際にキャパシティ不足が発生した場合に、意図通り通知されました。

通知内容のリンクから CloudTrail イベントを見ることもできます。

メール通知の場合は次の内容でした。errorCodeServer.InsufficientInstanceCapacityであることが確認できます。

{
  "version": "0",
  "id": "4d0d2631-b20a-306e-0e8d-6540bf920330",
  "detail-type": "AWS API Call via CloudTrail",
  "source": "aws.ec2",
  "account": "111122223333",
  "time": "2022-11-07T15:07:57Z",
  "region": "ap-northeast-1",
  "resources": [],
  "detail": {
    "eventVersion": "1.08",
    "userIdentity": {
      "type": "AssumedRole",
      "principalId": "AROA5VOZMRYTILEXAMPLE:cm-test-user",
      "arn": "arn:aws:sts::111122223333:assumed-role/cm-test-user/cm-test-user",
      "accountId": "111122223333",
      "accessKeyId": "ASIA5VOZMRYTGEXAMPLE",
      "sessionContext": {
        "sessionIssuer": {
          "type": "Role",
          "principalId": "AROA5VOZMRYTILEXAMPLE",
          "arn": "arn:aws:iam::111122223333:role/cm-test-user",
          "accountId": "111122223333",
          "userName": "cm-test-user"
        },
        "webIdFederationData": {},
        "attributes": {
          "creationDate": "2022-11-07T14:41:13Z",
          "mfaAuthenticated": "true"
        }
      }
    },
    "eventTime": "2022-11-07T15:07:57Z",
    "eventSource": "ec2.amazonaws.com",
    "eventName": "RunInstances",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "AWS Internal",
    "userAgent": "AWS Internal",
    "errorCode": "Server.InsufficientInstanceCapacity",
    "errorMessage": "We currently do not have sufficient m4.16xlarge capacity in the Availability Zone you requested (ap-northeast-1a). Our system will be working on provisioning additional capacity. You can currently get m4.16xlarge capacity by not specifying an Availability Zone in your request or choosing ap-northeast-1c, ap-northeast-1d.",
    "requestParameters": {
      "instancesSet": {
        "items": [
          {
            "imageId": "ami-0de5311b2a443fb89",
            "minCount": 1,
            "maxCount": 1,
            "keyName": "test-keypair"
          }
        ]
      },
      "instanceType": "m4.16xlarge",
      "blockDeviceMapping": {
        "items": [
          {
            "deviceName": "/dev/xvda",
            "ebs": {
              "snapshotId": "snap-03f58d3d918e5bd0a",
              "volumeSize": 8,
              "deleteOnTermination": true,
              "volumeType": "gp2",
              "encrypted": true,
              "kmsKeyId": "alias/aws/ebs"
            }
          }
        ]
      },
      "monitoring": { "enabled": false },
      "disableApiTermination": false,
      "disableApiStop": false,
      "clientToken": "af54154d-1626-4322-a2c6-0e6d1a406937",
      "networkInterfaceSet": {
        "items": [
          {
            "deviceIndex": 0,
            "subnetId": "subnet-0375cdacaaa606235",
            "associatePublicIpAddress": true,
            "groupSet": { "items": [{ "groupId": "sg-03dff1269b307cedc" }] }
          }
        ]
      },
      "ebsOptimized": true,
      "tagSpecificationSet": {
        "items": [
          {
            "resourceType": "instance",
            "tags": [{ "key": "Name", "value": "test-capasity-instance" }]
          }
        ]
      },
      "privateDnsNameOptions": {
        "hostnameType": "ip-name",
        "enableResourceNameDnsARecord": true,
        "enableResourceNameDnsAAAARecord": false
      }
    },
    "responseElements": null,
    "requestID": "4e520aff-154b-48f9-981e-ed6bf75f768a",
    "eventID": "bec9abad-db15-4d2f-8420-d45a28b15866",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "111122223333",
    "eventCategory": "Management",
    "sessionCredentialFromConsole": "true"
  }
}

通知内容は入力トランスフォーマーを利用して編集することも可能です。

次に、AutoScaling が EC2 インスタンスを起動しようとしてキャパシティ不足が発生した場合は、次のような通知内容になりました。

User identity や User agent が AutoScaling の情報になっています。

通知内容のリンクから CloudTrail イベントを確認した画面です。ユーザー名がAutoScalingです。

メール通知した場合の例は次の通りです。

{
  "version": "0",
  "id": "a80b1968-a607-51af-451e-9f122ca28901",
  "detail-type": "AWS API Call via CloudTrail",
  "source": "aws.ec2",
  "account": "111122223333",
  "time": "2022-11-07T15:26:28Z",
  "region": "ap-northeast-1",
  "resources": [],
  "detail": {
    "eventVersion": "1.08",
    "userIdentity": {
      "type": "AssumedRole",
      "principalId": "AROA5VOZMRYTOUEXAMPLE:AutoScaling",
      "arn": "arn:aws:sts::111122223333:assumed-role/AWSServiceRoleForAutoScaling/AutoScaling",
      "accountId": "111122223333",
      "sessionContext": {
        "sessionIssuer": {
          "type": "Role",
          "principalId": "AROA5VOZMRYTOUEXAMPLE",
          "arn": "arn:aws:iam::111122223333:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling",
          "accountId": "111122223333",
          "userName": "AWSServiceRoleForAutoScaling"
        },
        "webIdFederationData": {},
        "attributes": {
          "creationDate": "2022-11-07T15:26:25Z",
          "mfaAuthenticated": "false"
        }
      },
      "invokedBy": "autoscaling.amazonaws.com"
    },
    "eventTime": "2022-11-07T15:26:28Z",
    "eventSource": "ec2.amazonaws.com",
    "eventName": "RunInstances",
    "awsRegion": "ap-northeast-1",
    "sourceIPAddress": "autoscaling.amazonaws.com",
    "userAgent": "autoscaling.amazonaws.com",
    "errorCode": "Server.InsufficientInstanceCapacity",
    "errorMessage": "We currently do not have sufficient m4.16xlarge capacity in the Availability Zone you requested (ap-northeast-1a). Our system will be working on provisioning additional capacity. You can currently get m4.16xlarge capacity by not specifying an Availability Zone in your request or choosing ap-northeast-1c, ap-northeast-1d.",
    "requestParameters": {
      "instancesSet": { "items": [{ "minCount": 1, "maxCount": 1 }] },
      "blockDeviceMapping": {},
      "availabilityZone": "ap-northeast-1a",
      "monitoring": { "enabled": false },
      "disableApiTermination": false,
      "disableApiStop": false,
      "clientToken": "6ae6114a-ccbb-ec9d-362b-4c6c9a36d70d",
      "networkInterfaceSet": {
        "items": [{ "deviceIndex": 0, "subnetId": "subnet-0375cdacaaa606235" }]
      },
      "tagSpecificationSet": {
        "items": [
          {
            "resourceType": "instance",
            "tags": [
              {
                "key": "aws:autoscaling:groupName",
                "value": "test-capacity-autoscaling^group"
              }
            ]
          }
        ]
      },
      "launchTemplate": {
        "launchTemplateId": "lt-0034448149002d1d1",
        "version": "1"
      }
    },
    "responseElements": null,
    "requestID": "7e52bd02-5fd2-4f32-917b-6317c971d8fa",
    "eventID": "b6008335-520a-40ec-b0a8-071c0dee31b8",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "111122223333",
    "eventCategory": "Management"
  }
}

以上で、キャパシティ不足の通知の説明は終わりです。

最後に参考情報ですが、マネジメントコンソール上でキャパシティ不足が発生した場合は、次の画像のようにエラーが出力されました。

さいごに

EC2 インスタンスの起動時にキャパシティ不足が発生したときの通知を試してみました。試してみたものの、利用シーンは限定的な気がしています。今回は起動(RunInstance)を対象としましたが、開始(StartInstance)を対象にすることもできそうです。

もしキャパシティ不足が発生した場合の解決方法は次の AWS ナレッジセンターが参考になります。

EC2 インスタンスの開始または起動時に発生する、InsufficientInstanceCapacity エラーのトラブルシューティング

以上、このブログがどなたかのご参考になれば幸いです。