API GatewayのWAF IPsetをTerraformで設定してみる

2023.02.24

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

はじめに

データアナリティクス事業本部のkobayashiです。

Amazon API Gatewayに対してセキュリティを強化したい場合はAWS WAFを使うことで実現が可能でAWS WAFなのでIP setsを設定することでリクエスト元のIPを絞り込むことが可能になります。今回この設定をTerraformを使って設定したのでその内容をまとめます。

TerraformでWAFをAPI Gatewayに設定する

AWS WAFを使用してAPI Gatewayを保護する方法は公式ドキュメントはじめ豊富な情報がありますので省略します。

AWS WAF を使用して API を保護する - Amazon API Gateway

今回行うのはWAFのIP setsを使ってIP制限をAPI Gatewayに対して行いますので作成するリソースは以下になります。

  • WAFのIP sets
  • WAFのWeb ACLs
  • Web ACLsをAPI Gatewayへの関連付け

では早速上記のリソースを作るTerraformのコードを記述します。

main.tf

variable "project_name" {
  default = "projectname"
}
variable "region" {
  default = "ap-northeast-1"
}
variable "from_ips" {
  default = [
    "xxx.xxx.xxx.xxx/32",
    "yyy.yyy.yyy.yyy/32"
  ]
}
variable "apigw_id" {
  default = "abcd1234"
}

resource "aws_wafv2_ip_set" "apigw-ip_set" {
  name               = "${var.project_name}-apigw-ipset"
  description        = "${var.project_name}-apigw-ipset"
  scope              = "REGIONAL"
  ip_address_version = "IPV4"
  addresses          = var.from_ips
}


resource "aws_wafv2_web_acl" "apigw-web_acl" {
  name        = "${var.project_name}-apigw-webacl"
  description = "${var.project_name}-apigw-webacl"
  scope       = "REGIONAL"

  default_action {
    block {}
  }

  rule {
    name     = "WAFIPsetRuleForAPIGW"
    priority = 1

    action {
      allow {}
    }

    statement {
      ip_set_reference_statement {
        arn = aws_wafv2_ip_set.apigw-ip_set.arn
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = false
      metric_name                = "waf-ipset-rule-for-apigw"
      sampled_requests_enabled   = false
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = false
    metric_name                = "${var.project_name}-apigw-web_acl-metric"
    sampled_requests_enabled   = true
  }
}

resource "aws_wafv2_web_acl_association" "apigw-web_acl-associtation" {
  resource_arn = "arn:aws:apigateway:${var.region}::/restapis/${var.apigw_id}/stages/live"
  web_acl_arn  = aws_wafv2_web_acl.apigw-web_acl.arn
}
  • 1行目から15行目まではリソース名のprefix、リージョン、IP setsに設定するリクエスト元のIPアドレス、API GatewayのIDを設定します。
  • 17行目からのaws_wafv2_ip_setではアクセスを許可するIPを設定しています。
  • 26行目からのaws_wafv2_web_aclではaws_wafv2_ip_setを許可ルールとして設定し、それ以外はblockするようにしています。
  • 63行目からのaws_wafv2_web_acl_associationではaws_wafv2_web_aclで作成したWeb ACLsをAPI Gatewayへの関連付けています。

variableを設定したらあとはterraformコマンドでリソースを作成するだけで、API GatewayにIP制限を設定することができます。

$ terraform init
$ terraform apply
aws_wafv2_ip_set.apigw-ip_set: Creating...
aws_wafv2_ip_set.apigw-ip_set: Creation complete after 0s [id=4ae034daeac6-401a-4e6b-b496-80277e83cb9c]
aws_wafv2_web_acl.apigw-web_acl: Creating...
aws_wafv2_web_acl.apigw-web_acl: Creation complete after 1s [id=80277e83cb9c-2af9-467a-9cee-4ae034daeac6]
aws_wafv2_web_acl_association.apigw-web_acl-associtation: Creating...
aws_wafv2_web_acl_association.apigw-web_acl-associtation: Still creating... [10s elapsed]
aws_wafv2_web_acl_association.apigw-web_acl-associtation: Still creating... [20s elapsed]
aws_wafv2_web_acl_association.apigw-web_acl-associtation: Still creating... [30s elapsed]
aws_wafv2_web_acl_association.apigw-web_acl-associtation: Creation complete after 33s [id=arn:aws:wafv2:ap-northeast-1:11111111111:regional/webacl/projectname-apigw-webacl/80277e83cb9c-2af9-467a-9cee-4ae034daeac6,arn:aws:apigateway:ap-northeast-1::/restapis/abcd1234/stages/live]

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

問題なくterraformでリソースが作成できました。

まとめ

Amazon API GatewayにAWS WAFでリクエスト元のIPを絞り込む設定をTerraformを使って行いました。Terraformでリソースを作成すると手元から作成・破棄を簡単に行えるので大変便利です。

最後まで読んで頂いてありがとうございました。