Introduction
Amazon Virtual Private Cloud (VPC) is the foundation of AWS networking, providing isolated virtual networks within the AWS cloud. This guide explores VPC types, enterprise network design patterns, VPC peering strategies, and practical Java implementations for production environments.
AWS VPC Fundamentals
What is AWS VPC?
AWS VPC lets you provision a logically isolated section of the AWS Cloud where you can launch AWS resources in a virtual network that you define. You have complete control over your virtual networking environment, including selection of your own IP address range, creation of subnets, and configuration of route tables and network gateways.
Types of AWS VPC
1. Default VPC
Every AWS account comes with a default VPC in each AWS Region:
- CIDR Block:
172.31.0.0/16
- Pre-configured: Internet Gateway, Route Table, Security Group
- Public Subnets: One in each Availability Zone
- Use Cases: Quick testing, simple applications
graph TB
subgraph "Default VPC (172.31.0.0/16)"
IGW[Internet Gateway]
subgraph "AZ-1a"
PUB1[Public Subnet<br/>172.31.0.0/20]
end
subgraph "AZ-1b"
PUB2[Public Subnet<br/>172.31.16.0/20]
end
subgraph "AZ-1c"
PUB3[Public Subnet<br/>172.31.32.0/20]
end
end
Internet --> IGW
IGW --> PUB1
IGW --> PUB2
IGW --> PUB3
2. Custom VPC
User-defined VPC with custom configuration:
- Custom CIDR: Any RFC 1918 address range
- Flexible Design: Public/Private subnet combinations
- Enhanced Security: Custom security groups and NACLs
- Use Cases: Production applications, complex architectures
3. VPC Types by Connectivity
VPC Type | Internet Access | Use Cases | Security Level |
---|---|---|---|
Public VPC | Direct via IGW | Web applications, API endpoints | Medium |
Private VPC | Via NAT Gateway/Instance | Databases, internal services | High |
Hybrid VPC | Mixed public/private | Multi-tier applications | Variable |
Isolated VPC | No internet access | Highly sensitive workloads | Maximum |
Enterprise Network Design Patterns
1. Three-Tier Architecture
Classic enterprise pattern with presentation, application, and data tiers:
graph TB
subgraph "Production VPC (10.0.0.0/16)"
IGW[Internet Gateway]
NGW[NAT Gateway]
subgraph "Public Tier (DMZ)"
ALB[Application Load Balancer]
WAF[Web Application Firewall]
end
subgraph "Private Application Tier"
APP1[App Server 1]
APP2[App Server 2]
APP3[App Server 3]
end
subgraph "Private Data Tier"
RDS[(RDS Database)]
REDIS[(ElastiCache)]
end
end
Internet --> IGW
IGW --> ALB
ALB --> APP1
ALB --> APP2
ALB --> APP3
APP1 --> RDS
APP2 --> RDS
APP3 --> RDS
APP1 --> NGW
APP2 --> NGW
APP3 --> NGW
NGW --> IGW
2. Hub and Spoke Architecture
Centralized connectivity model for multiple VPCs:
graph TB
subgraph "Hub VPC (Shared Services)"
HUB[Hub VPC<br/>10.0.0.0/16]
FW[Network Firewall]
DNS[Route 53 Resolver]
MGMT[Management Tools]
end
subgraph "Spoke VPCs"
PROD[Production VPC<br/>10.1.0.0/16]
DEV[Development VPC<br/>10.2.0.0/16]
TEST[Test VPC<br/>10.3.0.0/16]
end
HUB -.->|VPC Peering| PROD
HUB -.->|VPC Peering| DEV
HUB -.->|VPC Peering| TEST
OnPrem[On-Premises] -->|VPN/Direct Connect| HUB
3. Multi-Account Network Architecture
Enterprise-scale architecture across multiple AWS accounts:
graph TB
subgraph "Network Account"
TGW[Transit Gateway]
DX[Direct Connect]
end
subgraph "Production Account"
PROD_VPC[Production VPC]
end
subgraph "Development Account"
DEV_VPC[Development VPC]
end
subgraph "Security Account"
SEC_VPC[Security VPC]
FW[Centralized Firewall]
end
subgraph "Shared Services Account"
SHARED_VPC[Shared Services VPC]
DNS[DNS Services]
LOGGING[Centralized Logging]
end
TGW --> PROD_VPC
TGW --> DEV_VPC
TGW --> SEC_VPC
TGW --> SHARED_VPC
OnPrem[On-Premises] --> DX
DX --> TGW
Common Enterprise Network Components
1. Internal Network Segments
1@Component
2public class NetworkSegmentManager {
3
4 @Value("${aws.vpc.production.cidr}")
5 private String productionCidr;
6
7 @Value("${aws.vpc.development.cidr}")
8 private String developmentCidr;
9
10 public enum NetworkTier {
11 PUBLIC("Public", "0.0.0.0/0"),
12 PRIVATE_APP("Private-App", "10.0.0.0/8"),
13 PRIVATE_DATA("Private-Data", "172.16.0.0/12"),
14 MANAGEMENT("Management", "192.168.0.0/16");
15
16 private final String name;
17 private final String defaultCidr;
18
19 NetworkTier(String name, String defaultCidr) {
20 this.name = name;
21 this.defaultCidr = defaultCidr;
22 }
23
24 public String getName() { return name; }
25 public String getDefaultCidr() { return defaultCidr; }
26 }
27
28 public Subnet createSubnet(NetworkTier tier, String availabilityZone) {
29 return Subnet.builder()
30 .vpcId(getVpcId())
31 .cidrBlock(calculateSubnetCidr(tier))
32 .availabilityZone(availabilityZone)
33 .mapPublicIpOnLaunch(tier == NetworkTier.PUBLIC)
34 .tags(Map.of(
35 "Name", tier.getName() + "-" + availabilityZone,
36 "Tier", tier.getName(),
37 "Environment", getCurrentEnvironment()
38 ))
39 .build();
40 }
41}
2. Firewall Integration
1@Service
2public class NetworkFirewallService {
3
4 private final Ec2Client ec2Client;
5 private final NetworkFirewallClient firewallClient;
6
7 public NetworkFirewallService(Ec2Client ec2Client,
8 NetworkFirewallClient firewallClient) {
9 this.ec2Client = ec2Client;
10 this.firewallClient = firewallClient;
11 }
12
13 public FirewallPolicy createEnterpriseFirewallPolicy() {
14
15 List<StatelessRule> statelessRules = Arrays.asList(
16 createDenyRule("DENY_ALL_FROM_INTERNET", 1, "0.0.0.0/0"),
17 createAllowRule("ALLOW_HTTPS", 2, "443"),
18 createAllowRule("ALLOW_HTTP", 3, "80")
19 );
20
21 List<StatefulRuleGroup> statefulRules = Arrays.asList(
22 createThreatIntelligenceRules(),
23 createDomainBlockingRules(),
24 createApplicationRules()
25 );
26
27 return FirewallPolicy.builder()
28 .statelessDefaultActions("aws:forward_to_sfe")
29 .statelessFragmentDefaultActions("aws:forward_to_sfe")
30 .statelessRuleGroupReferences(
31 statelessRules.stream()
32 .map(this::createRuleGroupReference)
33 .collect(Collectors.toList())
34 )
35 .statefulRuleGroupReferences(
36 statefulRules.stream()
37 .map(this::createStatefulRuleGroupReference)
38 .collect(Collectors.toList())
39 )
40 .build();
41 }
42
43 public void deployFirewallToVPC(String vpcId, String firewallPolicyArn) {
44 try {
45 List<SubnetMapping> firewallSubnets = getFirewallSubnets(vpcId);
46
47 CreateFirewallRequest request = CreateFirewallRequest.builder()
48 .firewallName("enterprise-firewall-" + vpcId)
49 .firewallPolicyArn(firewallPolicyArn)
50 .vpcId(vpcId)
51 .subnetMappings(firewallSubnets)
52 .tags(Map.of(
53 "Environment", "production",
54 "Purpose", "enterprise-security",
55 "ManagedBy", "infrastructure-team"
56 ))
57 .build();
58
59 CreateFirewallResponse response = firewallClient.createFirewall(request);
60
61 log.info("Firewall deployed successfully: {}", response.firewall().firewallArn());
62
63 updateRouteTablesForFirewall(vpcId, response.firewall().firewallArn());
64
65 } catch (Exception e) {
66 log.error("Failed to deploy firewall to VPC {}: {}", vpcId, e.getMessage());
67 throw new NetworkFirewallDeploymentException("Firewall deployment failed", e);
68 }
69 }
70}
VPC Peering
What is VPC Peering?
VPC peering connection is a networking connection between two VPCs that enables you to route traffic between them using private IPv4 addresses or IPv6 addresses.
VPC Peering Use Cases
Use Case | Description | Benefits |
---|---|---|
Cross-Region Connectivity | Connect VPCs in different regions | Global application architecture |
Multi-Account Architecture | Connect VPCs across AWS accounts | Organizational isolation |
Hybrid Cloud Integration | Connect cloud and on-premises | Gradual cloud migration |
Microservices Communication | Service-to-service communication | Secure inter-service networking |
Data Sharing | Share databases or data lakes | Controlled data access |
VPC Peering Configuration
1@Service
2public class VPCPeeringService {
3
4 private final Ec2Client ec2Client;
5 private final CloudWatchClient cloudWatchClient;
6
7 public VPCPeeringService(Ec2Client ec2Client, CloudWatchClient cloudWatchClient) {
8 this.ec2Client = ec2Client;
9 this.cloudWatchClient = cloudWatchClient;
10 }
11
12 public VPCPeeringConnection createVPCPeering(VPCPeeringRequest peeringRequest) {
13
14 validatePeeringRequest(peeringRequest);
15
16 CreateVpcPeeringConnectionRequest request = CreateVpcPeeringConnectionRequest.builder()
17 .vpcId(peeringRequest.getSourceVpcId())
18 .peerVpcId(peeringRequest.getTargetVpcId())
19 .peerRegion(peeringRequest.getTargetRegion())
20 .peerOwnerId(peeringRequest.getTargetAccountId())
21 .tagSpecifications(
22 TagSpecification.builder()
23 .resourceType(ResourceType.VPC_PEERING_CONNECTION)
24 .tags(
25 Tag.builder().key("Name")
26 .value(peeringRequest.getConnectionName()).build(),
27 Tag.builder().key("Purpose")
28 .value(peeringRequest.getPurpose()).build(),
29 Tag.builder().key("Environment")
30 .value(peeringRequest.getEnvironment()).build()
31 )
32 .build()
33 )
34 .build();
35
36 try {
37 CreateVpcPeeringConnectionResponse response =
38 ec2Client.createVpcPeeringConnection(request);
39
40 VPCPeeringConnection connection = VPCPeeringConnection.builder()
41 .peeringConnectionId(response.vpcPeeringConnection().vpcPeeringConnectionId())
42 .sourceVpcId(peeringRequest.getSourceVpcId())
43 .targetVpcId(peeringRequest.getTargetVpcId())
44 .status(response.vpcPeeringConnection().status().code().toString())
45 .build();
46
47 if (peeringRequest.isAutoAccept()) {
48 acceptVPCPeering(connection.getPeeringConnectionId());
49 }
50
51 setupPeeringMonitoring(connection);
52
53 log.info("VPC Peering connection created: {}",
54 connection.getPeeringConnectionId());
55
56 return connection;
57
58 } catch (Exception e) {
59 log.error("Failed to create VPC peering connection: {}", e.getMessage());
60 throw new VPCPeeringException("VPC Peering creation failed", e);
61 }
62 }
63
64 public void acceptVPCPeering(String peeringConnectionId) {
65 try {
66 AcceptVpcPeeringConnectionRequest request =
67 AcceptVpcPeeringConnectionRequest.builder()
68 .vpcPeeringConnectionId(peeringConnectionId)
69 .build();
70
71 AcceptVpcPeeringConnectionResponse response =
72 ec2Client.acceptVpcPeeringConnection(request);
73
74 log.info("VPC Peering connection accepted: {}", peeringConnectionId);
75
76 waitForPeeringActive(peeringConnectionId);
77
78 } catch (Exception e) {
79 log.error("Failed to accept VPC peering connection {}: {}",
80 peeringConnectionId, e.getMessage());
81 throw new VPCPeeringException("VPC Peering acceptance failed", e);
82 }
83 }
84
85 public void configureRoutesForPeering(VPCPeeringConfiguration config) {
86 try {
87 // Configure routes in source VPC
88 for (String routeTableId : config.getSourceRouteTableIds()) {
89 CreateRouteRequest sourceRoute = CreateRouteRequest.builder()
90 .routeTableId(routeTableId)
91 .destinationCidrBlock(config.getTargetVpcCidr())
92 .vpcPeeringConnectionId(config.getPeeringConnectionId())
93 .build();
94
95 ec2Client.createRoute(sourceRoute);
96 }
97
98 // Configure routes in target VPC
99 for (String routeTableId : config.getTargetRouteTableIds()) {
100 CreateRouteRequest targetRoute = CreateRouteRequest.builder()
101 .routeTableId(routeTableId)
102 .destinationCidrBlock(config.getSourceVpcCidr())
103 .vpcPeeringConnectionId(config.getPeeringConnectionId())
104 .build();
105
106 ec2Client.createRoute(targetRoute);
107 }
108
109 log.info("Routes configured for VPC peering connection: {}",
110 config.getPeeringConnectionId());
111
112 } catch (Exception e) {
113 log.error("Failed to configure routes for peering connection {}: {}",
114 config.getPeeringConnectionId(), e.getMessage());
115 throw new VPCPeeringException("Route configuration failed", e);
116 }
117 }
118
119 private void setupPeeringMonitoring(VPCPeeringConnection connection) {
120 try {
121 // Create CloudWatch alarms for peering connection health
122 PutMetricAlarmRequest alarmRequest = PutMetricAlarmRequest.builder()
123 .alarmName("vpc-peering-" + connection.getPeeringConnectionId() + "-state")
124 .alarmDescription("Monitor VPC Peering Connection State")
125 .metricName("VPCPeeringConnectionState")
126 .namespace("AWS/VPC")
127 .statistic(Statistic.MAXIMUM)
128 .dimensions(
129 Dimension.builder()
130 .name("VPCPeeringConnectionId")
131 .value(connection.getPeeringConnectionId())
132 .build()
133 )
134 .period(300)
135 .evaluationPeriods(2)
136 .threshold(1.0)
137 .comparisonOperator(ComparisonOperator.LESS_THAN_THRESHOLD)
138 .treatMissingData("breaching")
139 .build();
140
141 cloudWatchClient.putMetricAlarm(alarmRequest);
142
143 } catch (Exception e) {
144 log.warn("Failed to setup monitoring for peering connection {}: {}",
145 connection.getPeeringConnectionId(), e.getMessage());
146 }
147 }
148}
VPC Peering Limitations and Considerations
Limitation | Description | Workaround |
---|---|---|
Transitive Routing | No transitive routing between peered VPCs | Use Transit Gateway |
Overlapping CIDRs | Cannot peer VPCs with overlapping IP ranges | Plan CIDR blocks carefully |
Single Point of Failure | One-to-one relationship | Multiple peering connections |
Regional Limitations | Cross-region peering has bandwidth limits | Consider data transfer costs |
Enterprise VPC Management
1. VPC Lifecycle Management
1@Service
2public class VPCLifecycleManager {
3
4 private final Ec2Client ec2Client;
5 private final CloudFormationClient cfnClient;
6
7 public VPCCreationResult createEnterpriseVPC(EnterpriseVPCRequest request) {
8
9 VPCConfiguration config = VPCConfiguration.builder()
10 .vpcCidr(request.getCidrBlock())
11 .environment(request.getEnvironment())
12 .availabilityZones(request.getAvailabilityZones())
13 .enableDnsSupport(true)
14 .enableDnsHostnames(true)
15 .instanceTenancy("default")
16 .build();
17
18 try {
19 // Create VPC
20 String vpcId = createVPC(config);
21
22 // Create subnets
23 List<String> publicSubnetIds = createPublicSubnets(vpcId, config);
24 List<String> privateSubnetIds = createPrivateSubnets(vpcId, config);
25
26 // Create Internet Gateway
27 String igwId = createInternetGateway(vpcId);
28
29 // Create NAT Gateway
30 String natGatewayId = createNATGateway(publicSubnetIds.get(0));
31
32 // Configure route tables
33 configureRouteTables(vpcId, igwId, natGatewayId,
34 publicSubnetIds, privateSubnetIds);
35
36 // Setup security groups
37 List<String> securityGroupIds = createDefaultSecurityGroups(vpcId);
38
39 // Enable flow logs
40 enableVPCFlowLogs(vpcId);
41
42 return VPCCreationResult.builder()
43 .vpcId(vpcId)
44 .publicSubnetIds(publicSubnetIds)
45 .privateSubnetIds(privateSubnetIds)
46 .internetGatewayId(igwId)
47 .natGatewayId(natGatewayId)
48 .securityGroupIds(securityGroupIds)
49 .status("CREATED")
50 .build();
51
52 } catch (Exception e) {
53 log.error("Failed to create enterprise VPC: {}", e.getMessage());
54 throw new VPCCreationException("VPC creation failed", e);
55 }
56 }
57
58 public void enableVPCFlowLogs(String vpcId) {
59 try {
60 CreateFlowLogsRequest request = CreateFlowLogsRequest.builder()
61 .resourceType(FlowLogsResourceType.VPC)
62 .resourceIds(vpcId)
63 .trafficType(TrafficType.ALL)
64 .logDestination("arn:aws:logs:" + getCurrentRegion() + ":" +
65 getCurrentAccountId() + ":log-group:/aws/vpc/flowlogs")
66 .logDestinationType(LogDestinationType.CLOUD_WATCH_LOGS)
67 .logFormat("${version} ${account-id} ${interface-id} ${srcaddr} ${dstaddr} " +
68 "${srcport} ${dstport} ${protocol} ${packets} ${bytes} " +
69 "${windowstart} ${windowend} ${action} ${flowlogstatus}")
70 .tags(Map.of(
71 "Name", "vpc-flowlogs-" + vpcId,
72 "Purpose", "security-monitoring"
73 ))
74 .build();
75
76 CreateFlowLogsResponse response = ec2Client.createFlowLogs(request);
77
78 log.info("VPC Flow Logs enabled for VPC {}: {}",
79 vpcId, response.flowLogIds());
80
81 } catch (Exception e) {
82 log.error("Failed to enable VPC Flow Logs for VPC {}: {}",
83 vpcId, e.getMessage());
84 throw new VPCConfigurationException("Flow logs configuration failed", e);
85 }
86 }
87}
2. Network Security Best Practices
1@Component
2public class NetworkSecurityManager {
3
4 public SecurityGroup createTieredSecurityGroups(String vpcId, NetworkTier tier) {
5
6 Map<NetworkTier, List<SecurityGroupRule>> tierRules = Map.of(
7 NetworkTier.PUBLIC, Arrays.asList(
8 SecurityGroupRule.inbound("443", "0.0.0.0/0", "HTTPS Traffic"),
9 SecurityGroupRule.inbound("80", "0.0.0.0/0", "HTTP Traffic")
10 ),
11 NetworkTier.PRIVATE_APP, Arrays.asList(
12 SecurityGroupRule.inbound("8080", "10.0.0.0/16", "App Traffic"),
13 SecurityGroupRule.inbound("443", "10.0.0.0/16", "Internal HTTPS")
14 ),
15 NetworkTier.PRIVATE_DATA, Arrays.asList(
16 SecurityGroupRule.inbound("3306", "10.0.1.0/24", "MySQL Traffic"),
17 SecurityGroupRule.inbound("6379", "10.0.1.0/24", "Redis Traffic")
18 )
19 );
20
21 CreateSecurityGroupRequest request = CreateSecurityGroupRequest.builder()
22 .groupName(tier.getName() + "-sg")
23 .description("Security Group for " + tier.getName() + " tier")
24 .vpcId(vpcId)
25 .tags(
26 Tag.builder().key("Name").value(tier.getName() + "-sg").build(),
27 Tag.builder().key("Tier").value(tier.getName()).build()
28 )
29 .build();
30
31 CreateSecurityGroupResponse response = ec2Client.createSecurityGroup(request);
32 String securityGroupId = response.groupId();
33
34 // Add rules for the tier
35 for (SecurityGroupRule rule : tierRules.get(tier)) {
36 addSecurityGroupRule(securityGroupId, rule);
37 }
38
39 return SecurityGroup.builder()
40 .groupId(securityGroupId)
41 .groupName(tier.getName() + "-sg")
42 .tier(tier)
43 .rules(tierRules.get(tier))
44 .build();
45 }
46}
Monitoring and Troubleshooting
VPC Monitoring Dashboard
1@Service
2public class VPCMonitoringService {
3
4 public void createVPCDashboard(String vpcId) {
5
6 String dashboardBody = createDashboardDefinition(vpcId);
7
8 PutDashboardRequest request = PutDashboardRequest.builder()
9 .dashboardName("VPC-Dashboard-" + vpcId)
10 .dashboardBody(dashboardBody)
11 .build();
12
13 cloudWatchClient.putDashboard(request);
14 }
15
16 private String createDashboardDefinition(String vpcId) {
17 return """
18 {
19 "widgets": [
20 {
21 "type": "metric",
22 "properties": {
23 "metrics": [
24 ["AWS/VPC", "NetworkPacketsIn", "VpcId", "%s"],
25 [".", "NetworkPacketsOut", ".", "."],
26 [".", "NetworkBytesIn", ".", "."],
27 [".", "NetworkBytesOut", ".", "."]
28 ],
29 "period": 300,
30 "stat": "Sum",
31 "region": "%s",
32 "title": "VPC Network Traffic"
33 }
34 }
35 ]
36 }
37 """.formatted(vpcId, getCurrentRegion());
38 }
39}
Conclusion
AWS VPC provides the foundation for secure, scalable cloud networking. Key takeaways:
Best Practices
- Plan CIDR blocks carefully to avoid overlapping ranges
- Implement defense in depth with multiple security layers
- Use VPC Flow Logs for security monitoring and troubleshooting
- Design for high availability across multiple Availability Zones
- Implement proper tagging for resource management
When to Use VPC Peering
- Cross-region connectivity requirements
- Multi-account architectures
- Secure service-to-service communication
- Hybrid cloud integration scenarios
Enterprise Considerations
- Use Transit Gateway for complex multi-VPC architectures
- Implement centralized DNS and logging
- Apply consistent security policies across VPCs
- Monitor network performance and costs
This comprehensive approach to VPC design and management ensures robust, secure, and scalable cloud networking infrastructure for enterprise applications.