📝

CloudFormation で AWS コスト異常検出を東京リージョンからデプロイしてみた

に公開

コスト異常検出で CloudFormation リージョンのサポートが拡張されます

以前は、コスト異常検出での CloudFormation のサポートは、米国東部 (バージニア北部) と中国 (寧夏) リージョンでのみ利用可能でした。この制限のため、一部のお客様は、リソースとインフラストラクチャを設定した場所とは別にコスト異常検出を設定する必要がありました。利用可能なリージョンが拡張されたことで、お客様はリージョン全体のリソースとインフラストラクチャに近い CloudFormation を介してコスト異常検出を設定できるようになり、この不一致が解消されます。お客様は希望するリージョンに CloudFormation スタックを作成し、必要な場所にコスト異常検出をデプロイできます。

上述の通り、CloudFormation でのサポート開始当初は東京リージョンからのデプロイはできませんでしたが、現在は東京リージョンからのデプロイも可能なため試してみました。

使用したテンプレート

CloudFormationでCost Anomaly Detectionを設定する - サーバーワークスエンジニアブログ
上記ブログで紹介されているテンプレートをそのままお借りしました。

なお、当該ブログ執筆時点では東京リージョンからのデプロイができなかったため、以下の文言が記載されています。

Cost Anomaly Detectionはグローバルなサービスであるため、バージニアリージョンでテンプレートを流す必要があります。

東京リージョンからデプロイしてみた

東京リージョンからのデプロイが成功することを確認できました。

コスト異常検出のコンソールでもアラートなどが設定されています。

サブスクライバーである SNS トピックも東京リージョンに作成されています。

CloudTrail の記録を確認したところ、コスト異常検出の API についてはバージニア北部リージョンに記録されていました。

CreateAnomalyMonitor
{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "xxx",
        "arn": "xxx",
        "accountId": "012345678901",
        "accessKeyId": "xxx",
        "sessionContext": {
            "sessionIssuer": {
                "type": "Role",
                "principalId": "xxx",
                "arn": "xxx",
                "accountId": "012345678901",
                "userName": "xxx"
            },
            "webIdFederationData": {},
            "attributes": {
                "creationDate": "2025-01-08T10:40:34Z",
                "mfaAuthenticated": "true"
            }
        },
        "invokedBy": "cloudformation.amazonaws.com"
    },
    "eventTime": "2025-01-08T10:42:29Z",
    "eventSource": "ce.amazonaws.com",
    "eventName": "CreateAnomalyMonitor",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "cloudformation.amazonaws.com",
    "userAgent": "cloudformation.amazonaws.com",
    "requestParameters": {
        "AnomalyMonitor": {
            "MonitorName": "MonitorTest",
            "MonitorType": "DIMENSIONAL",
            "MonitorDimension": "SERVICE"
        },
        "ResourceTags": [
            {
                "Key": "aws:cloudformation:stack-name",
                "Value": "test2"
            },
            {
                "Key": "aws:cloudformation:logical-id",
                "Value": "AnomalyServiceMonitor"
            },
            {
                "Key": "aws:cloudformation:stack-id",
                "Value": "arn:aws:cloudformation:ap-northeast-1:012345678901:stack/test2/3febf7c0-cdad-11ef-afd6-0e54854a627b"
            }
        ]
    },
    "responseElements": {
        "MonitorArn": "arn:aws:ce::012345678901:anomalymonitor/e8a254ea-dab2-417c-ab5d-7f023070c1f2"
    },
    "requestID": "adbcb01a-4ec0-4177-a45a-c1f80d354bf2",
    "eventID": "b135a6ca-4d34-4ced-a51b-9f0a612c6caa",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "012345678901",
    "eventCategory": "Management"
}
CreateAnomalySubscription
{
    "eventVersion": "1.08",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "xxx",
        "arn": "xxx",
        "accountId": "012345678901",
        "accessKeyId": "xxx",
        "sessionContext": {
            "sessionIssuer": {
                "type": "Role",
                "principalId": "xxx",
                "arn": "xxx",
                "accountId": "012345678901",
                "userName": "xxx"
            },
            "webIdFederationData": {},
            "attributes": {
                "creationDate": "2025-01-08T10:40:34Z",
                "mfaAuthenticated": "true"
            }
        },
        "invokedBy": "cloudformation.amazonaws.com"
    },
    "eventTime": "2025-01-08T10:42:31Z",
    "eventSource": "ce.amazonaws.com",
    "eventName": "CreateAnomalySubscription",
    "awsRegion": "us-east-1",
    "sourceIPAddress": "cloudformation.amazonaws.com",
    "userAgent": "cloudformation.amazonaws.com",
    "requestParameters": {
        "AnomalySubscription": {
            "MonitorArnList": [
                "arn:aws:ce::012345678901:anomalymonitor/e8a254ea-dab2-417c-ab5d-7f023070c1f2"
            ],
            "Subscribers": [
                {
                    "Address": "arn:aws:sns:ap-northeast-1:012345678901:cost-anomaly-detection-sns-topic",
                    "Type": "SNS"
                }
            ],
            "Threshold": 1,
            "Frequency": "IMMEDIATE",
            "SubscriptionName": "AlertSubscriptionTest"
        },
        "ResourceTags": [
            {
                "Key": "aws:cloudformation:stack-name",
                "Value": "test2"
            },
            {
                "Key": "aws:cloudformation:logical-id",
                "Value": "AnomalySubscription"
            },
            {
                "Key": "aws:cloudformation:stack-id",
                "Value": "arn:aws:cloudformation:ap-northeast-1:012345678901:stack/test2/3febf7c0-cdad-11ef-afd6-0e54854a627b"
            }
        ]
    },
    "responseElements": {
        "SubscriptionArn": "arn:aws:ce::012345678901:anomalysubscription/2c749977-6df3-4c63-8b58-6c13a85e4456"
    },
    "requestID": "04c76379-e67b-474d-be74-4e352c82d3a7",
    "eventID": "5ea59db3-44e1-498a-99a8-2503326196d2",
    "readOnly": false,
    "eventType": "AwsApiCall",
    "managementEvent": true,
    "recipientAccountId": "012345678901",
    "eventCategory": "Management"
}

以上より、CloudFormation 側で適切なリージョンにリソースを作成していると思われました。

おまけ

手動で作成したコストモニターが存在する状態で CloudFormation テンプレートをデプロイしたところ、以下のエラーが発生しました。

Resource handler returned message: "Limit exceeded on dimensional spend monitor creation

コストモニターは 1 アカウントあたり 1 つという制限があり、この制限に抵触したことが原因でした
Quotas and restrictions - AWS Cost Management

Maximum number of anomaly monitors you can create for an AWS services monitor type
1 monitor per account

手動で作成したコストモニターを削除後にデプロイすることでエラーは解消しました。
なお、コストモニターのクォータがハードリミットであるどうかや、上限緩和の可否についてはドキュメントに明記されていなかったため、詳細については AWS サポートへの問い合わせが必要であると思われました。

まとめ

今回は CloudFormation で AWS コスト異常検出を東京リージョンからデプロイしてみました。
どなたかの参考になれば幸いです。

参考資料

Discussion