ERROR

AWS IAM: Fix AccessDenied for VPC Flow Logs Triggering CloudWatch Alerts

Quick Fix Summary

TL;DR

Verify and attach the `CloudWatchLogsFullAccess` policy to the IAM role used by VPC Flow Logs.

VPC Flow Logs fail to publish to CloudWatch Logs due to insufficient IAM permissions on the delivery IAM role, causing CloudWatch alarms for missing logs to trigger.

Diagnosis & Causes

  • Missing or incorrect IAM permissions on the Flow Logs IAM role.
  • IAM role trust relationship does not allow `vpc-flow-logs.amazonaws.com` to assume it.
  • Recovery Steps

    1

    Step 1: Identify the IAM Role and Check CloudTrail

    First, identify the IAM role used by your VPC Flow Logs and check CloudTrail logs for the specific AccessDenied error.

    bash
    # List VPC Flow Logs and their IAM Role ARN
    aws ec2 describe-flow-logs --query 'FlowLogs[*].[FlowLogId, DeliverLogsPermissionArn]' --output table
    
    # Query CloudTrail for recent AccessDenied events (adjust time range)
    aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=CreateLogStream --start-time $(date -u -v-1H +%Y-%m-%dT%H:%M:%SZ) --query 'Events[*].CloudTrailEvent' --output text | jq -r '.errorCode, .userIdentity.arn, .requestParameters.roleArn'
    2

    Step 2: Verify IAM Role Trust Policy

    Ensure the IAM role's trust policy allows the VPC Flow Logs service to assume it.

    bash
    # Get the IAM role name from the ARN (e.g., arn:aws:iam::123456789012:role/FlowLogsRole)
    ROLE_ARN="arn:aws:iam::123456789012:role/FlowLogsRole"
    ROLE_NAME=$(echo $ROLE_ARN | cut -d'/' -f2)
    aws iam get-role --role-name $ROLE_NAME --query 'Role.AssumeRolePolicyDocument'
    3

    Step 3: Attach Required IAM Permissions

    Attach the necessary permissions policy to the IAM role. The minimum is `CloudWatchLogsFullAccess`, but a custom policy is recommended for production.

    bash
    # Attach the managed policy (Quick Fix)
    aws iam attach-role-policy --role-name $ROLE_NAME --policy-arn arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
    
    # For a custom, least-privilege policy, create and attach a policy document like:
    cat > flow-logs-policy.json << EOF
    {
        "Version": "2012-10-17",
        "Statement": [{
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:DescribeLogStreams"
            ],
            "Resource": "*"
        }]
    }
    EOF
    aws iam put-role-policy --role-name $ROLE_NAME --policy-name VPCFlowLogsToCloudWatch --policy-document file://flow-logs-policy.json
    4

    Step 4: Test the Configuration

    Simulate the permission check by having the role attempt a core action, or update a Flow Log to force a re-evaluation.

    bash
    # Use AWS STS to assume the role and test permissions (requires appropriate caller permissions)
    aws sts assume-role --role-arn $ROLE_ARN --role-session-name TestFlowLogsRole --query 'Credentials'
    # Export temporary credentials and test
    # Alternatively, update a Flow Log (e.g., change max aggregation interval) to trigger the service to retry
    aws ec2 modify-flow-log-attributes --flow-log-id <your-flow-log-id> --max-aggregation-interval 60

    Architect's Pro Tip

    "This often happens after the IAM role is recreated or its policies are modified. The VPC Flow Logs service caches credentials. If you fix the IAM policy but logs still fail, wait 5-15 minutes or modify the Flow Log configuration to force an immediate refresh of the service's permissions."

    Frequently Asked Questions

    Can I use a service-linked role for VPC Flow Logs instead?

    No. VPC Flow Logs to CloudWatch Logs requires you to specify a custom IAM role. There is no service-linked role for this integration.

    The role has `CloudWatchLogsFullAccess` but I still get AccessDenied. Why?

    1. Check the Trust Policy (Step 2). The principal must be `vpc-flow-logs.amazonaws.com`. 2. Check for an explicit Deny in other attached IAM policies, SCPs, or Permission Boundaries that override the Allow.

    Related AWS Guides