I am using terraform
to create a web-acl
in aws
and want to associate that web-acl
with CloudFront distribution.
So, here's how my code looks like:
provider "aws" {
alias = "east1"
region = "us-east-1"
}
# -------------------------------------------
# -------------------------------------------
# Cloud Front
module "front_end_cloudfront" {
source = "./modules/front-end/CF"
# CF_ALIASES = ["terraformer-frontend.dev.effi.com.au"]
CF_LAMBDA_ARN = module.frontend_lambda.cf_lambda_qualified_arn
CF_BUCKET_DOMAIN_NAME = module.front_end_bucket.website_endpoint
CF_BUCKET_ORIGIN_ID = module.front_end_bucket.website_domain
CF_TAGS_LIST = { "Name" : "terraformer-front-end-cloudfrontv2" }
CF_CERTFICATE_ARN = var.CLOUDFRONT_US_EAST_1_ACM_ARN
# WEB_ACL = module.waf.web_acl_id
WEB_ACL = module.waf_cf.web_acl_id
depends_on = [module.waf_cf]
}
# -------------------------------------------
# -------------------------------------------
# WAF for CF
module "waf_cf" {
source = "./modules/waf"
providers = {
aws = aws.east1
}
WAF_NAME = "terraform-web-acl-cf"
WAF_DESCRIPTION = "terraform web acl-cf"
WAF_SCOPE = "CLOUDFRONT"
WAF_RULE_NAME_1 = "AWSManagedRulesCommonRuleSet"
WAF_RULE_NAME_2 = "AWSManagedRulesAmazonIpReputationList"
WAF_RULE_NAME_3 = "AWSManagedRulesLinuxRuleSet"
WAF_RULE_NAME_4 = "AWSManagedRulesKnownBadInputsRuleSet"
WAF_VENDOR = "AWS"
WAF_METRIC_1 = "aws-waf-logs-terraformer-metric"
WAF_METRIC_2 = "aws-waf-logs-terraformer-metric"
WAF_METRIC_3 = "aws-waf-logs-terraformer-metric"
WAF_METRIC_4 = "aws-waf-logs-terraformer-metric"
WAF_TAG_LIST = {
"Tag1" : "Name"
"Tag2" : "terraformer-rule-cf"
}
WAF_METRIC = "aws-waf-logs-friendly-metric-name"
CLOUDWATCH_METRICS_ENABLED = false
SAMPLE_REQUESTS_ENABLED = false
}
These are terraform
modules I have wrote, the specific resource
files for above modules are below respectively.
# CF
resource "aws_cloudfront_distribution" "aws_cloudfront_distribution" {
# aliases = var.CF_ALIASES
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
compress = "true"
default_ttl = "0"
forwarded_values {
cookies {
forward = "none"
}
query_string = "false"
}
lambda_function_association {
event_type = "origin-response"
include_body = "false"
lambda_arn = var.CF_LAMBDA_ARN
}
max_ttl = "0"
min_ttl = "0"
smooth_streaming = "false"
target_origin_id = var.CF_BUCKET_ORIGIN_ID
viewer_protocol_policy = "redirect-to-https"
}
enabled = "true"
http_version = "http2"
is_ipv6_enabled = "true"
origin {
custom_origin_config {
http_port = "80"
https_port = "443"
origin_keepalive_timeout = "5"
origin_protocol_policy = "http-only"
origin_read_timeout = "30"
origin_ssl_protocols = ["TLSv1", "TLSv1.1", "TLSv1.2"]
}
domain_name = var.CF_BUCKET_DOMAIN_NAME
origin_id = var.CF_BUCKET_ORIGIN_ID
}
price_class = "PriceClass_All"
restrictions {
geo_restriction {
restriction_type = "none"
}
}
retain_on_delete = "false"
tags = var.CF_TAGS_LIST
viewer_certificate {
acm_certificate_arn = var.CF_CERTFICATE_ARN
cloudfront_default_certificate = "false"
minimum_protocol_version = "TLSv1.2_2018"
ssl_support_method = "sni-only"
}
web_acl_id = var.WEB_ACL
}
# WAF
resource "aws_wafv2_web_acl" "aws_wafv2_web_acl" {
name = var.WAF_NAME
description = var.WAF_DESCRIPTION
scope = var.WAF_SCOPE
default_action {
allow {}
}
rule {
name = var.WAF_RULE_NAME_1
priority = 1
override_action {
count {}
}
statement {
managed_rule_group_statement {
name = var.WAF_RULE_NAME_1
vendor_name = var.WAF_VENDOR
# excluded_rule {
# name = "SizeRestrictions_QUERYSTRING"
# }
# excluded_rule {
# name = "NoUserAgent_HEADER"
# }
}
}
visibility_config {
cloudwatch_metrics_enabled = var.CLOUDWATCH_METRICS_ENABLED
metric_name = var.WAF_METRIC_1
sampled_requests_enabled = var.SAMPLE_REQUESTS_ENABLED
}
}
rule {
name = var.WAF_RULE_NAME_2
priority = 2
override_action {
count {}
}
statement {
managed_rule_group_statement {
name = var.WAF_RULE_NAME_2
vendor_name = var.WAF_VENDOR
}
}
visibility_config {
cloudwatch_metrics_enabled = var.CLOUDWATCH_METRICS_ENABLED
metric_name = var.WAF_METRIC_2
sampled_requests_enabled = var.SAMPLE_REQUESTS_ENABLED
}
}
rule {
name = var.WAF_RULE_NAME_3
priority = 3
override_action {
count {}
}
statement {
managed_rule_group_statement {
name = var.WAF_RULE_NAME_3
vendor_name = var.WAF_VENDOR
}
}
visibility_config {
cloudwatch_metrics_enabled = var.CLOUDWATCH_METRICS_ENABLED
metric_name = var.WAF_METRIC_3
sampled_requests_enabled = var.SAMPLE_REQUESTS_ENABLED
}
}
rule {
name = var.WAF_RULE_NAME_4
priority = 4
override_action {
count {}
}
statement {
managed_rule_group_statement {
name = var.WAF_RULE_NAME_4
vendor_name = var.WAF_VENDOR
}
}
visibility_config {
cloudwatch_metrics_enabled = var.CLOUDWATCH_METRICS_ENABLED
metric_name = var.WAF_METRIC_4
sampled_requests_enabled = var.SAMPLE_REQUESTS_ENABLED
}
}
tags = var.WAF_TAG_LIST
visibility_config {
cloudwatch_metrics_enabled = var.CLOUDWATCH_METRICS_ENABLED
metric_name = var.WAF_METRIC
sampled_requests_enabled = var.SAMPLE_REQUESTS_ENABLED
}
}
But I am getting the below error
error updating CloudFront Distribution (E32RNPFGEUHQ6J): InvalidWebACLId: Web ACL is not accessible by the requester.
Here the cloudfront
is created in ap-southeast-2
region and the waf
is created in us-east-1
region.
Can someone please help me on this?
When using WAFv2, you need to specify the the ARN not the ID to web_acl_id
in aws_cloudfront_distribution
.
See the note here https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution#web_acl_id
or this GitHub issue https://github.com/hashicorp/terraform-provider-aws/issues/13902