VPC Flow Logs in AWS CDK EC2 provide detailed information about network traffic flowing to and from network interfaces in your VPC, enabling monitoring, troubleshooting, and security analysis.
The FlowLog class creates and manages VPC Flow Logs:
class FlowLog extends Resource implements IFlowLog {
constructor(scope: Construct, id: string, props: FlowLogProps);
readonly flowLogId: string;
static fromFlowLogId(scope: Construct, id: string, flowLogId: string): IFlowLog;
}
interface IFlowLog extends IResource {
readonly flowLogId: string;
}
interface FlowLogProps {
readonly resourceType: FlowLogResourceType;
readonly trafficType?: FlowLogTrafficType;
readonly destination?: FlowLogDestination;
readonly logFormat?: string[];
readonly maxAggregationInterval?: FlowLogMaxAggregationInterval;
}Enums and interfaces for flow log configuration:
enum FlowLogTrafficType {
ACCEPT = 'ACCEPT',
ALL = 'ALL',
REJECT = 'REJECT'
}
enum FlowLogResourceType {
VPC = 'VPC',
SUBNET = 'Subnet',
NETWORK_INTERFACE = 'NetworkInterface'
}
enum FlowLogMaxAggregationInterval {
ONE_MINUTE = 60,
TEN_MINUTES = 600
}
abstract class FlowLogDestination {
static toCloudWatchLogs(logGroup: logs.ILogGroup, iamRole?: iam.IRole): FlowLogDestination;
static toS3(bucket: s3.IBucket, keyPrefix?: string): FlowLogDestination;
}VPC methods for adding flow logs:
// These methods are part of the IVpc interface
interface IVpc {
addFlowLog(id: string, options?: FlowLogOptions): FlowLog;
}
interface FlowLogOptions {
readonly trafficType?: FlowLogTrafficType;
readonly destination?: FlowLogDestination;
readonly logFormat?: string[];
readonly maxAggregationInterval?: FlowLogMaxAggregationInterval;
}import * as ec2 from "@aws-cdk/aws-ec2";
import * as logs from "@aws-cdk/aws-logs";
const vpc = new ec2.Vpc(this, "MyVpc");
// Create log group for flow logs
const logGroup = new logs.LogGroup(this, "VpcFlowLogGroup", {
retention: logs.RetentionDays.ONE_WEEK
});
// Add flow log to VPC
const flowLog = vpc.addFlowLog("VpcFlowLog", {
trafficType: ec2.FlowLogTrafficType.ALL,
destination: ec2.FlowLogDestination.toCloudWatchLogs(logGroup)
});import * as s3 from "@aws-cdk/aws-s3";
const bucket = new s3.Bucket(this, "FlowLogBucket");
const s3FlowLog = vpc.addFlowLog("S3FlowLog", {
trafficType: ec2.FlowLogTrafficType.ALL,
destination: ec2.FlowLogDestination.toS3(bucket, "flow-logs/"),
maxAggregationInterval: ec2.FlowLogMaxAggregationInterval.ONE_MINUTE
});const customFormatFlowLog = vpc.addFlowLog("CustomFormatFlowLog", {
trafficType: ec2.FlowLogTrafficType.ALL,
destination: ec2.FlowLogDestination.toCloudWatchLogs(logGroup),
logFormat: [
'${srcaddr}',
'${dstaddr}',
'${srcport}',
'${dstport}',
'${protocol}',
'${packets}',
'${bytes}',
'${windowstart}',
'${windowend}',
'${action}'
]
});const subnet = vpc.publicSubnets[0];
const subnetFlowLog = new ec2.FlowLog(this, "SubnetFlowLog", {
resourceType: ec2.FlowLogResourceType.SUBNET,
trafficType: ec2.FlowLogTrafficType.ALL,
destination: ec2.FlowLogDestination.toCloudWatchLogs(logGroup)
});const networkInterfaceFlowLog = new ec2.FlowLog(this, "NetworkInterfaceFlowLog", {
resourceType: ec2.FlowLogResourceType.NETWORK_INTERFACE,
trafficType: ec2.FlowLogTrafficType.REJECT,
destination: ec2.FlowLogDestination.toCloudWatchLogs(logGroup),
maxAggregationInterval: ec2.FlowLogMaxAggregationInterval.TEN_MINUTES
});import * as iam from "@aws-cdk/aws-iam";
const flowLogRole = new iam.Role(this, "FlowLogRole", {
assumedBy: new iam.ServicePrincipal("vpc-flow-logs.amazonaws.com"),
managedPolicies: [
iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/VPCFlowLogsDeliveryRolePolicy")
]
});
const roleBasedFlowLog = vpc.addFlowLog("RoleBasedFlowLog", {
trafficType: ec2.FlowLogTrafficType.ALL,
destination: ec2.FlowLogDestination.toCloudWatchLogs(logGroup, flowLogRole)
});const vpc = new ec2.Vpc(this, "LoggedVpc");
const logGroup = new logs.LogGroup(this, "FlowLogs");
// VPC-level flow log
vpc.addFlowLog("VpcLevel", {
trafficType: ec2.FlowLogTrafficType.ALL,
destination: ec2.FlowLogDestination.toCloudWatchLogs(logGroup)
});
// Individual subnet flow logs
vpc.publicSubnets.forEach((subnet, index) => {
new ec2.FlowLog(this, `PublicSubnetFlowLog${index}`, {
resourceType: ec2.FlowLogResourceType.SUBNET,
trafficType: ec2.FlowLogTrafficType.ALL,
destination: ec2.FlowLogDestination.toCloudWatchLogs(logGroup)
});
});
vpc.privateSubnets.forEach((subnet, index) => {
new ec2.FlowLog(this, `PrivateSubnetFlowLog${index}`, {
resourceType: ec2.FlowLogResourceType.SUBNET,
trafficType: ec2.FlowLogTrafficType.ALL,
destination: ec2.FlowLogDestination.toCloudWatchLogs(logGroup)
});
});import * as cloudwatch from "@aws-cdk/aws-cloudwatch";
const vpc = new ec2.Vpc(this, "AnalyzedVpc");
const logGroup = new logs.LogGroup(this, "FlowLogGroup");
const flowLog = vpc.addFlowLog("AnalyzedFlowLog", {
trafficType: ec2.FlowLogTrafficType.ALL,
destination: ec2.FlowLogDestination.toCloudWatchLogs(logGroup)
});
// Create CloudWatch dashboard for flow log analysis
const dashboard = new cloudwatch.Dashboard(this, "FlowLogDashboard", {
dashboardName: "VPC-Flow-Logs"
});
// Add widgets for monitoring
const trafficWidget = new cloudwatch.GraphWidget({
title: "Network Traffic",
left: [
new cloudwatch.Metric({
namespace: "AWS/VPC",
metricName: "PacketsDropped",
dimensionsMap: {
VpcId: vpc.vpcId
}
})
]
});
dashboard.addWidgets(trafficWidget);