Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terraform API Gateway HTTP API - Getting the error Insufficient permissions to enable logging

My terraform script for deploying an HTTP API looks like the following. I am getting the following error when I run this -

error creating API Gateway v2 stage: BadRequestException: Insufficient permissions to enable logging

Do I need to add something else to make it work?

resource "aws_cloudwatch_log_group" "api_gateway_log_group" {
  name              = "/aws/apigateway/${var.location}-${var.custom_tags.Layer}-demo-publish-api"
  retention_in_days = 7
  tags = var.custom_tags
}

resource "aws_apigatewayv2_api" "demo_publish_api" {
  name = "${var.location}-${var.custom_tags.Layer}-demo-publish-api"
  description = "API to publish event payloads"
  protocol_type = "HTTP"
  tags = var.custom_tags
}

resource "aws_apigatewayv2_vpc_link" "demo_vpc_link" {
  name = "${var.location}-${var.custom_tags.Layer}-demo-vpc-link"
  security_group_ids = local.security_group_id_list
  subnet_ids = local.subnet_ids_list
  tags = var.custom_tags
}

resource "aws_apigatewayv2_integration" "demo_apigateway_integration" {
  api_id           = aws_apigatewayv2_api.demo_publish_api.id
  integration_type = "HTTP_PROXY"
  connection_type = "VPC_LINK"
  integration_uri = var.alb_listener_arn
  connection_id = aws_apigatewayv2_vpc_link.demo_vpc_link.id
  integration_method = "POST"
  timeout_milliseconds = var.api_timeout_milliseconds
}

resource "aws_apigatewayv2_route" "demo_publish_api_route" {
  api_id    = aws_apigatewayv2_api.demo_publish_api.id
  route_key = "POST /api/event"
  target = "integrations/${aws_apigatewayv2_integration.demo_apigateway_integration.id}"
}

resource "aws_apigatewayv2_stage" "demo_publish_api_default_stage" {
  depends_on = [aws_cloudwatch_log_group.api_gateway_log_group]

  api_id = aws_apigatewayv2_api.demo_publish_api.id
  name   = "$default"
  auto_deploy = true
  tags = var.custom_tags

  route_settings {
    route_key = aws_apigatewayv2_route.demo_publish_api_route.route_key
    throttling_burst_limit = var.throttling_burst_limit
    throttling_rate_limit = var.throttling_rate_limit
  }

  default_route_settings {
    detailed_metrics_enabled = true
    logging_level = "INFO"
  }

  access_log_settings {
    destination_arn = aws_cloudwatch_log_group.api_gateway_log_group.arn
    format = jsonencode({ "requestId":"$context.requestId", "ip": "$context.identity.sourceIp"})
  }
}
like image 627
bdev03 Avatar asked Dec 31 '22 21:12

bdev03


2 Answers

I was stuck on this for a couple of days before reaching out to AWS support. If you have been deploying a lot of HTTP APIs, then you might have run into the same issue where an IAM policy gets very large.

  1. Run this AWS CLI command to find the associated CloudWatch Logs resource policy: aws logs describe-resource-policies
  2. Look for AWSLogDeliveryWrite20150319. You'll notice this policy has a large number of associated LogGroup resources. You have three options:
  • Adjust this policy by removing some of the potentially unused entries.
  • Change the resource list to "*"
  • You can add another policy. Based on this policy, split the resource records between them.
  1. Apply updates via this AWS CLI command: aws logs put-resource-policy

Here's the command I ran to set resources. Use "*" for the policy:

aws logs put-resource-policy --policy-name AWSLogDeliveryWrite20150319 --policy-document "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"AWSLogDeliveryWrite\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"delivery.logs.amazonaws.com\"},\"Action\":[\"logs:CreateLogStream\",\"logs:PutLogEvents\"],\"Resource\":[\"*\"]}]}"
like image 189
Danielfy Avatar answered Jan 02 '23 12:01

Danielfy


@Marcin Your initial comment about the aws_api_gateway_account was correct. I added the following resources and now it is working fine -

resource "aws_api_gateway_account" "demo" {
  cloudwatch_role_arn = var.apigw_cloudwatch_role_arn
}
data "aws_iam_policy_document" "demo_apigw_allow_manage_resources" {
  version = "2012-10-17"
  statement {
    actions = [
      "logs:DescribeLogGroups",
      "logs:DescribeLogStreams",
      "logs:GetLogEvents",
      "logs:FilterLogEvents"
    ]

    resources = [
      "*"
    ]
  }

  statement {
    actions = [
      "logs:CreateLogDelivery",
      "logs:PutResourcePolicy",
      "logs:UpdateLogDelivery",
      "logs:DeleteLogDelivery",
      "logs:CreateLogGroup",
      "logs:DescribeResourcePolicies",
      "logs:GetLogDelivery",
      "logs:ListLogDeliveries"
    ]

    resources = [
      "*"
    ]
  }
}

data "aws_iam_policy_document" "demo_apigw_allow_assume_role" {
  version = "2012-10-17"
  statement {
    effect = "Allow"
    actions = [
      "sts:AssumeRole"]
    principals {
      type = "Service"
      identifiers = ["apigateway.amazonaws.com"]
    }
  }
}

resource "aws_iam_role_policy" "demo_apigw_allow_manage_resources" {
  policy = data.aws_iam_policy_document.demo_apigw_allow_manage_resources.json
  role = aws_iam_role.demo_apigw_cloudwatch_role.id
  name = var.demo-apigw-manage-resources_policy_name
}

resource "aws_iam_role" "demo_apigw_cloudwatch_role" {
  name = "demo_apigw_cloudwatch_role"
  tags = var.custom_tags
  assume_role_policy = data.aws_iam_policy_document.demo_apigw_allow_assume_role.json
}
like image 26
bdev03 Avatar answered Jan 02 '23 12:01

bdev03