[Terraform] Cloudwatch Alarmを特定リージョンに作成しようとして失敗した件


# この記事について

以下のようなTerraformコードを作成して、CloudWatch Alarmをバージニアリージョンに作成しようとした。

```
resource "aws_cloudwatch_metric_alarm" "for_topic" {
  provider            = aws.virginia
  
  alarm_name          = local.alert.name
  comparison_operator = "LessThanThreshold"
  evaluation_periods  = "1"
  metric_name         = "HealthCheckStatus"
  namespace           = "AWS/Route53"
  period              = "60"
  statistic           = "Minimum"
  threshold           = "1"
  alarm_actions       = [aws_sns_topic.topic_route53.arn]

  dimensions = {
    HealthCheckId     = aws_route53_health_check.hoge.id
  }

  depends_on          = [aws_route53_health_check.hoge]
}

resource "aws_sns_topic" "topic_route53" {

  name = local.sns.topic_name
  tags = {
    Name = local.sns.topic_name
  }
}

resource "aws_sns_topic_subscription" "subscription_firehose" {
  topic_arn             = aws_sns_topic.topic_route53.arn
  protocol              = "firehose"
  endpoint              = aws_kinesis_firehose_delivery_stream.firehose_newrelic.arn
  subscription_role_arn = aws_iam_role.subscription-firehose.arn
}
```

terraform applyを実施したところ、以下のエラーが出力された。

```
│ Error: failed creating CloudWatch Metric Alarm (test-route53-healthcheck-alert): ValidationError: Invalid region ap-northeast-1 specified. Only us-east-1 is supported.
│       status code: 400, request id: 3ec4a15a-550b-4efe-9d37-4ccbe430c28b
│ 
│   with aws_cloudwatch_metric_alarm.for_topic,
│   on event-newrelic.tf line 29, in resource "aws_cloudwatch_metric_alarm" "for_topic":
│   29: resource "aws_cloudwatch_metric_alarm" "for_topic" {
│ 
```

`provier = aws.virginia`でリージョンを指定しているはずが、東京リージョンにCloudwatch Alarmが作られようとしてエラーになっている模様

この事象を解決した際の記録をこの記事に残す。

# 原因

エラーの文言だとaws_cloudwatch_metric_alarmをバージニアリージョンに作成することができていないように見受けられるが、実際はCloudwatch Alarmの通知先となっているSNSトピック/サブスクリプションがバージニアリージョンにないことが原因だった。

今回は`Cloudwatch Alarm -> SNSトピック -> サブスクリプション -> Kinesis Data Firehouse -> 外部API`という流れで、AWSと外部サービスを連携させていた。Cloudwatch Alarmだけでなく、SNSトピック/サブスクリプション/Firehose全て同一リージョンにて作成する必要があった。

SNSトピックとサブスクリプションとFirehoseをバージニアリージョンで作成するようにすればterraform applyは成功した。

```
provider "aws" {
  region = "us-east-1"
  alias  = "virginia"
}

resource "aws_cloudwatch_metric_alarm" "for_topic" {
  provider            = aws.virginia
  
  alarm_name          = local.alert.name
  comparison_operator = "LessThanThreshold"
  evaluation_periods  = "1"
  metric_name         = "HealthCheckStatus"
  namespace           = "AWS/Route53"
  period              = "60"
  statistic           = "Minimum"
  threshold           = "1"
  alarm_actions       = [aws_sns_topic.topic_route53.arn]

  dimensions = {
    HealthCheckId     = aws_route53_health_check.hoge.id
  }

  depends_on          = [aws_route53_health_check.hoge]
}

resource "aws_sns_topic" "topic_route53" {
  provider            = aws.virginia

  name = local.sns.topic_name
  tags = {
    Name = local.sns.topic_name
  }
}

resource "aws_sns_topic_subscription" "subscription_firehose" {
  provider            = aws.virginia

  topic_arn             = aws_sns_topic.topic_route53.arn
  protocol              = "firehose"
  endpoint              = aws_kinesis_firehose_delivery_stream.firehose_newrelic.arn
  subscription_role_arn = aws_iam_role.subscription-firehose.arn
}
```

# 参考

https://github.com/hashicorp/terraform/issues/7371