hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.82k stars 9.17k forks source link

[Bug]: aws_wafv2_web_acl_logging_configuration face WAFLogDestinationPermissionIssueException at first time TF apply #36000

Open Jack-WangZhe opened 8 months ago

Jack-WangZhe commented 8 months ago

Terraform Core Version

1.5

AWS Provider Version

5.35.0

Affected Resource(s)

aws_wafv2_web_acl_logging_configuration

Expected Behavior

Terraform was applied successfully and all required resources have already been created the first time.

Actual Behavior

Terraform applied with the error exception: WAFLogDestinationPermissionIssueException, but then re-plan tf scripts and apply, and everything went well.

Relevant Error/Panic Output Snippet

putting WAFv2 WebACL Logging Configuration (arn:aws:wafv2:us-east-1:.....:global/webacl/...): WAFLogDestinationPermissionIssueException: Unable to deliver logs to the configured destination. You might need to grant log delivery permissions for the destination. If you're using S3 as your log destination, you might have exceeded your bucket limit.

Terraform Configuration Files

resource "aws_cloudwatch_log_group" "this" {
  count = var.enable_log ? 1 : 0

  name = "aws-waf-logs-customized"
}

resource "aws_wafv2_web_acl_logging_configuration" "this" {
  count = var.enable_log ? 1 : 0

  log_destination_configs = [aws_cloudwatch_log_group.this.arn]
  resource_arn            = aws_wafv2_web_acl.this.arn # The web acl here will be used for CloudFront
}

resource "aws_cloudwatch_log_resource_policy" "this" {
  count = var.enable_log ? 1 : 0

  policy_document = data.aws_iam_policy_document.cw_log_policy_doc.json
  policy_name     = "webacl-policy-customized"
}

data "aws_iam_policy_document" "cw_log_policy_doc" {
  count = var.enable_log ? 1 : 0

  version = "2012-10-17"
  statement {
    effect = "Allow"
    principals {
      identifiers = ["delivery.logs.amazonaws.com"]
      type        = "Service"
    }
    actions   = ["logs:CreateLogStream", "logs:PutLogEvents"]
    resources = ["${aws_cloudwatch_log_group.this.arn}:*"]
    condition {
      test     = "ArnLike"
      values   = ["arn:aws:logs:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:*"]
      variable = "aws:SourceArn"
    }
    condition {
      test     = "StringEquals"
      values   = [tostring(data.aws_caller_identity.current.account_id)]
      variable = "aws:SourceAccount"
    }
  }
}

data "aws_region" "current" {}

data "aws_caller_identity" "current" {}

Steps to Reproduce

Debug Output

No response

Panic Output

No response

Important Factoids

No response

References

No response

Would you like to implement a fix?

None

github-actions[bot] commented 8 months ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

Jack-WangZhe commented 8 months ago

Hi guys,

We tested several times to set up the web Acl log configurations by terraform script with aws_wafv2_web_acl_logging_configuration and found the terraform always applied failed the first time as the above comment said.

Do you face the same problem with us? Or would you mind helping us solve the question?

Thank you! šŸ™‚ Jack

AErmie commented 8 months ago

I too am encountering this error. But I am only able to deploy this resource if the terraform apply completes fully, then re-add this resource back in.

If I try to apply a terraform plan (that successfully deploys all other resources but this one), re-running the terraform apply still fails. I have to comment out/remove the aws_wafv2_web_acl_logging_configuration resource completely, run the terraform plan to successful completion, then re-add the resource back, and re-run again.

Environment Details:

Error Error: putting WAFv2 WebACL Logging Configuration (arn:aws:wafv2:us-east-1:123456789012:regional/webacl/waf-dev-apigateway/GUID): AccessDeniedException: You don't have the permissions that are required to perform this operation.

I even granted the Service Account Terraform is using, excessive permissions (ie. "wafv2:*"), with no change.

Code Example

resource "aws_cloudwatch_log_group" "waf_api_gateway_log_group" {
  name = "aws-waf-logs-${lower(var.tags.Environment)}-api-gateway"
}

resource "aws_wafv2_web_acl" "waf_api_gateway" {
  name  = "waf-${lower(var.tags.Environment)}-apigateway"
  scope = "REGIONAL"

  default_action {
    allow {}
  }

  rule {
    name     = "AWSManagedRulesAmazonIpReputationList"
    priority = 0

    override_action {
      count {}
    }

    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesAmazonIpReputationList"
        vendor_name = "AWS"
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "AWSManagedRulesAmazonIpReputationList"
      sampled_requests_enabled   = true
    }
  }

  rule {
    name     = "AWSManagedRulesCommonRuleSet"
    priority = 1

    override_action {
      count {}
    }

    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesCommonRuleSet"
        vendor_name = "AWS"
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "AWSManagedRulesCommonRuleSet"
      sampled_requests_enabled   = true
    }
  }

  rule {
    name     = "AWSManagedRulesKnownBadInputsRuleSet"
    priority = 2

    override_action {
      count {}
    }

    statement {
      managed_rule_group_statement {
        name        = "AWSManagedRulesKnownBadInputsRuleSet"
        vendor_name = "AWS"
      }
    }

    visibility_config {
      cloudwatch_metrics_enabled = true
      metric_name                = "AWSManagedRulesKnownBadInputsRuleSet"
      sampled_requests_enabled   = true
    }
  }

  visibility_config {
    cloudwatch_metrics_enabled = true
    metric_name                = "waf-apigateway"
    sampled_requests_enabled   = true
  }

  tags = merge(
    var.tags, var.tags_common
  )
}

resource "aws_wafv2_web_acl_logging_configuration" "waf_logging_configuration" {
  log_destination_configs = [
    aws_cloudwatch_log_group.waf_api_gateway_log_group.arn
  ]
  resource_arn = aws_wafv2_web_acl.waf_api_gateway.arn
}
justinretzolk commented 7 months ago

Hey @Jack-WangZhe šŸ‘‹ Thank you for taking the time to raise this! I believe this may be due to your aws_cloudwatch_log_resource_policy being created after the aws_wafv2_web_acl_logging_configuration resource. It doesn't look like there's any dependency between the two currently, so the order of creation isn't currently guaranteed.

Can you configure depends_on to ensure that the aws_wafv2_web_acl_logging_configuration is dependent on aws_cloudwatch_log_resource_policy and they're created in the correct order?

@AErmie šŸ‘‹ Your error looks a bit different -- it's throwing AccessDeniedException rather than WAFLogDestinationPermissionIssueException, the former of which is (almost?) always an issue with the permissions of the user making the request. If you continue to have issues with it after looking into your permissions, I'd recommend opening a separate issue so we can triage it as necessary.

justinretzolk commented 1 month ago

Hi all, I wanted to check in here to see if this issue is still happening, or if this is something we can close out.