---
title: VPC Flow Logs disabled
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Datadog Security > Code Security > Infrastructure as Code (IaC)
  Security > IaC Security Rules > VPC Flow Logs disabled
---

# VPC Flow Logs disabled

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com, us2.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site.md). ({% placeholder "user-datadog-site-name" /%}).
{% /alert %}

{% /callout %}

## Metadata{% #metadata %}

**Id:** `cloudformation-aws-vpc-flowlogs-disabled` 

**Provider:** AWS

**Platform:** CloudFormation

**Severity:** Medium

**Category:** Observability

#### Learn More{% #learn-more %}

- [Provider Reference](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-flowlog.html)

### Description{% #description %}

VPCs must have VPC Flow Logs enabled so network traffic metadata is recorded for detecting suspicious activity and supporting incident investigation and compliance audits.

For each `AWS::EC2::VPC` resource, ensure there is an `AWS::EC2::FlowLog` resource whose `Properties.ResourceId` references that VPC (for example, `Ref: MyVPC`) so traffic for that VPC is captured. Resources missing a flow log, or where the flow log's `ResourceId` does not reference the VPC, will be flagged. The flow log should also specify a valid destination (CloudWatch Logs or S3) via `LogDestination`/`LogDestinationType`.

Secure example (CloudFormation YAML):

```yaml
MyVPC:
  Type: AWS::EC2::VPC
  Properties:
    CidrBlock: 10.0.0.0/16

FlowLogGroup:
  Type: AWS::Logs::LogGroup

VPCFlowLog:
  Type: AWS::EC2::FlowLog
  Properties:
    ResourceType: VPC
    ResourceId: !Ref MyVPC
    TrafficType: ALL
    LogDestinationType: cloud-watch-logs
    LogDestination: !GetAtt FlowLogGroup.Arn
```

## Compliant Code Examples{% #compliant-code-examples %}

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC: public and private subnets in two availability zones, a cloudonaut.io template'
Parameters:
  ClassB:
    Description: 'Class B of VPC (10.XXX.0.0/16)'
    Type: Number
    Default: 0
    ConstraintDescription: 'Must be in the range [0-255]'
    MinValue: 0
    MaxValue: 255
Resources:
  Role:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service: 'vpc-flow-logs.amazonaws.com'
          Action: 'sts:AssumeRole'
      Policies:
      - PolicyName: 'flowlogs-policy'
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - 'logs:CreateLogStream'
            - 'logs:PutLogEvents'
            - 'logs:DescribeLogGroups'
            - 'logs:DescribeLogStreams'
            Resource: !GetAtt 'LogGroup.Arn'
  MyVPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: !Sub '10.${ClassB}.0.0/16'
      EnableDnsSupport: true
      EnableDnsHostnames: true
      InstanceTenancy: default
      Tags:
      - Key: Name
        Value: !Sub '10.${ClassB}.0.0/16'
  LogGroup:
    Type: 'AWS::Logs::LogGroup'
    Properties:
      RetentionInDays: 14
  FlowLog:
    Type: 'AWS::EC2::FlowLog'
    Properties:
      DeliverLogsPermissionArn: !GetAtt 'Role.Arn'
      LogGroupName: !Ref LogGroup
      ResourceId: !Ref MyVPC
      ResourceType: 'VPC'
      TrafficType: ACCEPT
```

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: VPC whose flow log references the VPC through a short-form Ref intrinsic
Resources:
  IsolatedVPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: 10.0.0.0/16
  IsolatedLogGroup:
    Type: 'AWS::Logs::LogGroup'
    Properties:
      RetentionInDays: 14
  IsolatedFlowLog:
    Type: 'AWS::EC2::FlowLog'
    Properties:
      LogGroupName: !Ref IsolatedLogGroup
      ResourceId: !Ref IsolatedVPC
      ResourceType: 'VPC'
      TrafficType: ALL
```

## Non-Compliant Code Examples{% #non-compliant-code-examples %}

```yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC: public and private subnets in two availability zones, a cloudonaut.io template'
Parameters:
  ClassB:
    Description: 'Class B of VPC (10.XXX.0.0/16)'
    Type: Number
    Default: 0
    ConstraintDescription: 'Must be in the range [0-255]'
    MinValue: 0
    MaxValue: 255
Resources:
  Role:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service: 'vpc-flow-logs.amazonaws.com'
          Action: 'sts:AssumeRole'
      Policies:
      - PolicyName: 'flowlogs-policy'
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - 'logs:CreateLogStream'
            - 'logs:PutLogEvents'
            - 'logs:DescribeLogGroups'
            - 'logs:DescribeLogStreams'
            Resource: !GetAtt 'LogGroup.Arn'
  MyVPC:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: !Sub '10.${ClassB}.0.0/16'
      EnableDnsSupport: true
      EnableDnsHostnames: true
      InstanceTenancy: default
      Tags:
      - Key: Name
        Value: !Sub '10.${ClassB}.0.0/16'
  LogGroup:
    Type: 'AWS::Logs::LogGroup'
    Properties:
      RetentionInDays: 14
  FlowLog:
    Type: 'AWS::EC2::FlowLog'
    Properties:
      DeliverLogsPermissionArn: !GetAtt 'Role.Arn'
      LogGroupName: !Ref LogGroup
      ResourceId: !Ref MyVPC1
      ResourceType: 'VPC'
      TrafficType: ACCEPT
```
