terraformで Cloudfront に WAF2 を使って特定のパスやAPIにIP制限をする
terraformでWAF2を使ってやるやり方が割と最近対応したので備忘録的なあれ
/admin/*
と /api/admin/*
にIP制限をするサンプル
IP sets と Regex pattern setsを作成
resource "aws_wafv2_regex_pattern_set" "admin-path" {
name = "admin-path-set"
scope = "CLOUDFRONT"
provider = aws.east
regular_expression {
regex_string = "^\\/?admin.*$"
}
}
resource "aws_wafv2_regex_pattern_set" "admin-api-path" {
name = "admin-api-path-set"
scope = "CLOUDFRONT"
provider = aws.east
regular_expression {
regex_string = "^\\/?api\\/admin.*$"
}
}
resource "aws_wafv2_ip_set" "admin-ips" {
name = "admin-ip-set"
scope = "CLOUDFRONT"
provider = aws.east
ip_address_version = "IPV4"
addresses = ["192.168.1.1/32", "192.168.1.2/32"] // 指定したいIPをサブネット付きで書く
}
##### ACL作成
resource "aws_wafv2_web_acl" "cloudfront-waf" {
name = "cloudfront-waf"
scope = "CLOUDFRONT"
provider = aws.east
default_action {
allow {}
}
// /admin/* /api/admin は指定IPのみ許可する
rule {
name = "admin-path-only-allow-ips"
priority = 5
action {
block {}
}
// URLが ("/admin/*" or "/api/admin/*") && !指定IP だったらBlockみたいなこと書いてある
statement {
and_statement {
statement {
or_statement {
statement {
regex_pattern_set_reference_statement {
arn = aws_wafv2_regex_pattern_set.admin-path.arn
field_to_match {
uri_path {
}
}
text_transformation {
priority = 1
type = "NONE"
}
}
}
statement {
regex_pattern_set_reference_statement {
arn = aws_wafv2_regex_pattern_set.admin-api-path.arn
field_to_match {
uri_path {
}
}
text_transformation {
priority = 1
type = "NONE"
}
}
}
}
}
statement {
not_statement {
statement {
ip_set_reference_statement {
arn = aws_wafv2_ip_set.admin-ips.arn
}
}
}
}
}
}
visibility_config {
cloudwatch_metrics_enabled = false
metric_name = "admin-path-only-allow-ips"
sampled_requests_enabled = false
}
}
visibility_config {
cloudwatch_metrics_enabled = false
metric_name = "cloudfront-waf"
sampled_requests_enabled = false
}
}
Cloudfrontに反映
resource "aws_cloudfront_distribution" "cloudfront" {
// ...省略
web_acl_id = aws_wafv2_web_acl.cloudfront-waf.arn
注意点
CloudFrontはリージョンがGlobalでしか作れないので、下記のように us-east-1
のProviderでACL等のリソースを作成しないとCloudfrontに設定できない
provider "aws" {
region = "us-east-1"
version = "= 2.68.0"
access_key = "hoge"
secret_key = "fuga"
alias = "east"
}
resource "aws_wafv2_regex_pattern_set" "admin-path" {
name = "admin-path-set"
scope = "CLOUDFRONT"
// ここ!!
provider = aws.east
regular_expression {
regex_string = "^\\/?admin.*$"
}
}