This post is the first in a series to share my learnings as I get to grips with AWS Network Firewall.
See the second part here
There are many use cases; however, in this series, I'll focus on the following.
Inspection VPC
This pattern will place the firewall between two VPCs and inspect any traffic that passes between the two.
As Network Firewall doesn't support VPC Peering, Transit Gateway needs to be implemented, which isn't bad as it's like a router on steroids! See an overlay use case with TGW here.
If you deal with multiple accounts and many VPCs, you will never regret implementing it.
Inspection VPC with Internet Egress
This pattern will enable a central egress point to the internet via NAT gateway, allowing us to allow or block traffic to the internet from instances in private subnets across one or many VPCs.
Inspection VPC for North-South traffic across cloud providers.
What the hell does North-South mean, I hear you say. Wikipedia defines it as
"Network traffic flowing into and out of a data center"
I feel that description is a little dated; however, it makes sense if we treat AWS as one data center and "other" cloud provider as another.
This pattern will establish a Site-to-Site VPN with the "other" cloud provider and ensure all traffic that passes between providers, North-South, will go via the firewall.
Asymmetric Routing
The above diagrams are a simple representation; however, in an Enterprise environment, instances are spread across multiple availability zones so enabling traffic to pass across AZs is necessary.
As detailed in the AWS docs here, by default, Transit Gateway maintains Availability Zone affinity, which means that it uses the same Availability Zone to forward the traffic from where it entered the transit gateway.
The above is perfect if we don't have an inspection VPC in place; however, as soon as we place an inline firewall, traffic must flow through the same interfaces on the firewall, or it gets silently dropped.
Thankfully the product teams at AWS have made life easy and enabled a flag we can set called Transit Gateway Appliance Mode.
In Part 2, we will go through the setup of the above patterns. However, as a parting gift, here is a CloudFormation template to deploy the Inspection VPC.
I hope this helps someone else!
Cheers
For more articles on AWS Firewall click here!
Inspection VPC CloudFormation
---
AWSTemplateFormatVersion: 2010-09-09
Description: AWS Firewall & NAT Gateway Inspection VPC
Parameters:
Name:
Type: String
Description: 'VPC Name used throughout tag names'
Default: 'Inspection'
Region:
Type: String
Description: 'Region'
Default: 'ap-southeast-2'
TransitGatewayId:
Type: String
Description: 'Transit Gateway Id'
VPCCIDR:
Type: String
Description: 'VPC IP address space, RFC 1918 address space only.'
Default: '10.147.0.0/18'
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref 'VPCCIDR'
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'VPC']]
VPCIGW:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: !Join ['-', [' !Ref 'Name', 'IGW']]
VPCIGWAttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref 'VPCIGW'
VpcId: !Ref 'VPC'
# Transit Gateway Endpoint Subnets, ACLs, Route Tables, Associations
TGWEndpointACL:
Type: AWS::EC2::NetworkAcl
Properties:
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'TGW']]
VpcId: !Ref 'VPC'
TGWEndpointACLEgressEntry:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId:
Ref: TGWEndpointACL
RuleNumber: 100
Protocol: -1
RuleAction: allow
Egress: true
CidrBlock: 0.0.0.0/0
TGWEndpointACLIngressEntry:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId:
Ref: TGWEndpointACL
RuleNumber: 100
Protocol: -1
RuleAction: allow
Egress: false
CidrBlock: 0.0.0.0/0
# Transit Gateway Endpoints Availability Zone 1
TGWEndpointRouteTableAZ1:
Type: AWS::EC2::RouteTable
Properties:
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'TGW', '2a']]
VpcId: !Ref 'VPC'
TWGNFWRouteAZ1:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: '0.0.0.0/0'
VpcEndpointId: !Select [ 0, !Split [ ',', !Select [ 1 , !Split [ 'a:', !Join [ ',', !GetAtt Firewall.EndpointIds ] ] ] ] ]
RouteTableId: !Ref TGWEndpointRouteTableAZ1
TGWEndpointSubnetAZ1:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: !Join ['', [!Ref 'Region', 'a']]
CidrBlock:
!Select [0, !Cidr [!GetAtt VPC.CidrBlock, 9, 6]]
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'TGW-2a']]
VpcId: !Ref 'VPC'
TGWEndpointSubnetAZ1Assoc:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref 'TGWEndpointSubnetAZ1'
RouteTableId: !Ref 'TGWEndpointRouteTableAZ1'
TGWEndpointNACLAZ1Assoc:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref 'TGWEndpointSubnetAZ1'
NetworkAclId: !Ref 'TGWEndpointACL'
# Transit Gateway Endpoints Availability Zone 2
TGWEndpointRouteTableAZ2:
Type: AWS::EC2::RouteTable
Properties:
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'TGW', '2b']]
VpcId: !Ref 'VPC'
TWGNFWRouteAZ2:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: '0.0.0.0/0'
VpcEndpointId: !Select [ 0, !Split [ ',', !Select [ 1 , !Split [ 'b:', !Join [ ',', !GetAtt Firewall.EndpointIds ] ] ] ] ]
RouteTableId: !Ref TGWEndpointRouteTableAZ2
TGWEndpointSubnetAZ2:
Type: AWS::EC2::Subnet
Metadata:
cfn-lint:
config:
ignore_checks:
- W3010
Properties:
AvailabilityZone: !Join ['', [!Ref 'Region', 'b']]
CidrBlock:
!Select [1, !Cidr [!GetAtt VPC.CidrBlock, 9, 6]]
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'TGW-2b']]
VpcId: !Ref 'VPC'
TGWEndpointSubnetAZ2Assoc:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref 'TGWEndpointSubnetAZ2'
RouteTableId: !Ref 'TGWEndpointRouteTableAZ2'
TGWEndpointNACLAZ2Assoc:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref 'TGWEndpointSubnetAZ2'
NetworkAclId: !Ref 'TGWEndpointACL'
# Transit Gateway Endpoints Availability Zone 3
TGWEndpointRouteTableAZ3:
Type: AWS::EC2::RouteTable
Properties:
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'TGW', '2c']]
VpcId: !Ref 'VPC'
TWGNFWRouteAZ3:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: '0.0.0.0/0'
VpcEndpointId: !Select [ 0, !Split [ ',', !Select [ 1 , !Split [ 'c:', !Join [ ',', !GetAtt Firewall.EndpointIds ] ] ] ] ]
RouteTableId: !Ref TGWEndpointRouteTableAZ3
TGWEndpointSubnetAZ3:
Type: AWS::EC2::Subnet
Metadata:
cfn-lint:
config:
ignore_checks:
- W3010
Properties:
AvailabilityZone: !Join ['', [!Ref 'Region', 'c']]
CidrBlock:
!Select [2, !Cidr [!GetAtt VPC.CidrBlock, 9, 6]]
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'TGW-2c']]
VpcId: !Ref 'VPC'
TGWEndpointSubnetAZ3Assoc:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref 'TGWEndpointSubnetAZ3'
RouteTableId: !Ref 'TGWEndpointRouteTableAZ3'
TGWEndpointNACLAZ3Assoc:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref 'TGWEndpointSubnetAZ3'
NetworkAclId: !Ref 'TGWEndpointACL'
# Firewall Endpoint Subnets, ACLs, Route Tables, Associations
NFWEndpointACL:
Type: AWS::EC2::NetworkAcl
Properties:
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NFW']]
VpcId: !Ref 'VPC'
NFWEndpointACLEgressEntry:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId:
Ref: NFWEndpointACL
RuleNumber: 100
Protocol: -1
RuleAction: allow
Egress: true
CidrBlock: 0.0.0.0/0
NFWEndpointACLIngressEntry:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId:
Ref: NFWEndpointACL
RuleNumber: 100
Protocol: -1
RuleAction: allow
Egress: false
CidrBlock: 0.0.0.0/0
# Firewall Endpoints Availability Zone 1
NFWEndpointRouteTableAZ1:
Type: AWS::EC2::RouteTable
Properties:
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NFW', '2a']]
VpcId: !Ref 'VPC'
NFWNATRouteAZ1:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: '0.0.0.0/0'
NatGatewayId: !Ref NatGwAZ1
RouteTableId: !Ref NFWEndpointRouteTableAZ1
NFWTGWRouteAZ1:
Type: AWS::EC2::Route
DependsOn: TransitGatewayAttachment
Properties:
DestinationCidrBlock: '10.0.0.0/8'
TransitGatewayId: !Ref TransitGatewayId
RouteTableId: !Ref NFWEndpointRouteTableAZ1
NFWEndpointSubnetAZ1:
Type: AWS::EC2::Subnet
Metadata:
cfn-lint:
config:
ignore_checks:
- W3010
Properties:
AvailabilityZone: !Join ['', [!Ref 'Region', 'a']]
CidrBlock:
!Select [3, !Cidr [!GetAtt VPC.CidrBlock, 9, 6]]
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NFW-2a']]
VpcId: !Ref 'VPC'
NFWEndpointSubnetAZ1Assoc:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref 'NFWEndpointSubnetAZ1'
RouteTableId: !Ref 'NFWEndpointRouteTableAZ1'
NFWEndpointNACLAZ1Assoc:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref 'NFWEndpointSubnetAZ1'
NetworkAclId: !Ref 'NFWEndpointACL'
# Firewall Endpoints Availability Zone 2
NFWEndpointRouteTableAZ2:
Type: AWS::EC2::RouteTable
Properties:
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NFW', '2b']]
VpcId: !Ref 'VPC'
NFWNATRouteAZ2:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: '0.0.0.0/0'
NatGatewayId: !Ref NatGwAZ2
RouteTableId: !Ref NFWEndpointRouteTableAZ2
NFWTGWRouteAZ2:
Type: AWS::EC2::Route
DependsOn: TransitGatewayAttachment
Properties:
DestinationCidrBlock: '10.0.0.0/8'
TransitGatewayId: !Ref TransitGatewayId
RouteTableId: !Ref NFWEndpointRouteTableAZ2
NFWEndpointSubnetAZ2:
Type: AWS::EC2::Subnet
Metadata:
cfn-lint:
config:
ignore_checks:
- W3010
Properties:
AvailabilityZone: !Join ['', [!Ref 'Region', 'b']]
CidrBlock:
!Select [4, !Cidr [!GetAtt VPC.CidrBlock, 9, 6]]
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NFW-2b']]
VpcId: !Ref 'VPC'
NFWEndpointSubnetAZ2Assoc:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref 'NFWEndpointSubnetAZ2'
RouteTableId: !Ref 'NFWEndpointRouteTableAZ2'
NFWEndpointNACLAZ2Assoc:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref 'NFWEndpointSubnetAZ2'
NetworkAclId: !Ref 'NFWEndpointACL'
# Firewall Endpoints Availability Zone 3
NFWEndpointRouteTableAZ3:
Type: AWS::EC2::RouteTable
Properties:
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NFW', '2c']]
VpcId: !Ref 'VPC'
NFWNATRouteAZ3:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: '0.0.0.0/0'
NatGatewayId: !Ref NatGwAZ3
RouteTableId: !Ref NFWEndpointRouteTableAZ3
NFWTGWRouteAZ3:
Type: AWS::EC2::Route
DependsOn: TransitGatewayAttachment
Properties:
DestinationCidrBlock: '10.0.0.0/8'
TransitGatewayId: !Ref TransitGatewayId
RouteTableId: !Ref NFWEndpointRouteTableAZ3
NFWEndpointSubnetAZ3:
Type: AWS::EC2::Subnet
Metadata:
cfn-lint:
config:
ignore_checks:
- W3010
Properties:
AvailabilityZone: !Join ['', [!Ref 'Region', 'c']]
CidrBlock:
!Select [5, !Cidr [!GetAtt VPC.CidrBlock, 9, 6]]
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NFW-2c']]
VpcId: !Ref 'VPC'
NFWEndpointSubnetAZ3Assoc:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref 'NFWEndpointSubnetAZ3'
RouteTableId: !Ref 'NFWEndpointRouteTableAZ3'
NFWEndpointNACLAZ3Assoc:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref 'NFWEndpointSubnetAZ3'
NetworkAclId: !Ref 'NFWEndpointACL'
# NAT Endpoint Subnets, ACLs, Route Tables, Associations
NATEndpointACL:
Type: AWS::EC2::NetworkAcl
Properties:
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NAT']]
VpcId: !Ref 'VPC'
NATEndpointACLEgressEntry:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId:
Ref: NATEndpointACL
RuleNumber: 100
Protocol: -1
RuleAction: allow
Egress: true
CidrBlock: 0.0.0.0/0
NATEndpointACLIngressEntry:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId:
Ref: NATEndpointACL
RuleNumber: 100
Protocol: -1
RuleAction: allow
Egress: false
CidrBlock: 0.0.0.0/0
# NAT Endpoints Availability Zone 1
NATEndpointRouteTableAZ1:
Type: AWS::EC2::RouteTable
Properties:
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NAT', '2a']]
VpcId: !Ref 'VPC'
NATInternetRouteAZ1:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref VPCIGW
RouteTableId: !Ref NATEndpointRouteTableAZ1
NATNFWRouteAZ1:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: '10.0.0.0/8'
VpcEndpointId: !Select [ 0, !Split [ ',', !Select [ 1 , !Split [ 'a:', !Join [ ',', !GetAtt Firewall.EndpointIds ] ] ] ] ]
RouteTableId: !Ref NATEndpointRouteTableAZ1
NATEndpointSubnetAZ1:
Type: AWS::EC2::Subnet
Metadata:
cfn-lint:
config:
ignore_checks:
- W3010
Properties:
AvailabilityZone: !Join ['', [!Ref 'Region', 'a']]
CidrBlock:
!Select [6, !Cidr [!GetAtt VPC.CidrBlock, 9, 6]]
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NAT-2a']]
VpcId: !Ref 'VPC'
NATEndpointSubnetAZ1Assoc:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref 'NATEndpointSubnetAZ1'
RouteTableId: !Ref 'NATEndpointRouteTableAZ1'
NATEndpointNACLAZ1Assoc:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref 'NATEndpointSubnetAZ1'
NetworkAclId: !Ref 'NATEndpointACL'
NATGwEipAZ1:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
NatGwAZ1:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt
- NATGwEipAZ1
- AllocationId
SubnetId: !Ref NATEndpointSubnetAZ1
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NAT-2a']]
# NAT Endpoints Availability Zone 2
NATEndpointRouteTableAZ2:
Type: AWS::EC2::RouteTable
Properties:
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NAT', '2b']]
VpcId: !Ref 'VPC'
NATInternetRouteAZ2:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref VPCIGW
RouteTableId: !Ref NATEndpointRouteTableAZ2
NATNFWRouteAZ2:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: '10.0.0.0/8'
VpcEndpointId: !Select [ 0, !Split [ ',', !Select [ 1 , !Split [ 'b:', !Join [ ',', !GetAtt Firewall.EndpointIds ] ] ] ] ]
RouteTableId: !Ref NATEndpointRouteTableAZ2
NATEndpointSubnetAZ2:
Type: AWS::EC2::Subnet
Metadata:
cfn-lint:
config:
ignore_checks:
- W3010
Properties:
AvailabilityZone: !Join ['', [!Ref 'Region', 'b']]
CidrBlock:
!Select [7, !Cidr [!GetAtt VPC.CidrBlock, 9, 6]]
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NAT-2b']]
VpcId: !Ref 'VPC'
NATEndpointSubnetAZ2Assoc:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref 'NATEndpointSubnetAZ2'
RouteTableId: !Ref 'NATEndpointRouteTableAZ2'
NATEndpointNACLAZ2Assoc:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref 'NATEndpointSubnetAZ2'
NetworkAclId: !Ref 'NATEndpointACL'
NATGwEipAZ2:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
NatGwAZ2:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt
- NATGwEipAZ2
- AllocationId
SubnetId: !Ref NATEndpointSubnetAZ2
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NAT-2b']]
# NAT Endpoints Availability Zone 3
NATEndpointRouteTableAZ3:
Type: AWS::EC2::RouteTable
Properties:
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NAT', '2c']]
VpcId: !Ref 'VPC'
NATInternetRouteAZ3:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref VPCIGW
RouteTableId: !Ref NATEndpointRouteTableAZ3
NATNFWRouteAZ3:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: '10.0.0.0/8'
VpcEndpointId: !Select [ 0, !Split [ ',', !Select [ 1 , !Split [ 'c:', !Join [ ',', !GetAtt Firewall.EndpointIds ] ] ] ] ]
RouteTableId: !Ref NATEndpointRouteTableAZ3
NATEndpointSubnetAZ3:
Type: AWS::EC2::Subnet
Metadata:
cfn-lint:
config:
ignore_checks:
- W3010
Properties:
AvailabilityZone: !Join ['', [!Ref 'Region', 'c']]
CidrBlock:
!Select [8, !Cidr [!GetAtt VPC.CidrBlock, 9, 6]]
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NAT-2c']]
VpcId: !Ref 'VPC'
NATEndpointSubnetAZ3Assoc:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref 'NATEndpointSubnetAZ3'
RouteTableId: !Ref 'NATEndpointRouteTableAZ3'
NATEndpointNACLAZ3Assoc:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref 'NATEndpointSubnetAZ3'
NetworkAclId: !Ref 'NATEndpointACL'
NATGwEipAZ3:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
NatGwAZ3:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt
- NATGwEipAZ3
- AllocationId
SubnetId: !Ref NATEndpointSubnetAZ3
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NAT-2c']]
BaseDefaultSecurityGroupEgress:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: !GetAtt VPC.DefaultSecurityGroup
IpProtocol: '-1'
CidrIp: !Ref VPCCIDR
Firewall:
Type: AWS::NetworkFirewall::Firewall
Properties:
FirewallName: !Join ['-', [!Ref 'Name', 'NFW']]
FirewallPolicyArn: !Ref FirewallPolicy
VpcId: !Ref 'VPC'
SubnetMappings:
- SubnetId: !Ref NFWEndpointSubnetAZ1
- SubnetId: !Ref NFWEndpointSubnetAZ2
- SubnetId: !Ref NFWEndpointSubnetAZ3
Tags:
- Key: Name
Value: !Join ['-', [!Ref 'Name', 'NFW']]
FirewallPolicy:
Type: AWS::NetworkFirewall::FirewallPolicy
Properties:
FirewallPolicyName: 'Provider-Main'
FirewallPolicy:
StatelessDefaultActions:
- 'aws:forward_to_sfe'
StatelessFragmentDefaultActions:
- 'aws:forward_to_sfe'
TransitGatewayAttachment:
Type: AWS::EC2::TransitGatewayAttachment
Properties:
SubnetIds:
- !Ref TGWEndpointSubnetAZ1
- !Ref TGWEndpointSubnetAZ2
- !Ref TGWEndpointSubnetAZ3
Tags:
- Key: Name
Value: Provider-Inspection-VPC
TransitGatewayId: !Ref TransitGatewayId
VpcId: !Ref 'VPC'