I am attempting to swap out a NATGateway instance in my Cloudformation Yaml script with a Nat instance AMI named Fck-Nat in order to reduce the (insane) cost from $40/m to around $4/m.
My current VPC Diagram from the console
The key difference:
# NatGateway:
# Type: AWS::EC2::NatGateway
# Properties:
# AllocationId: !GetAtt ElasticIp.AllocationId
# SubnetId: !Ref PublicSubnet
VpcPrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref StaticIpVpc
PrivateRoute:
Type: AWS::EC2::Route
DependsOn: VpcAttachment
Properties:
DestinationCidrBlock: 0.0.0.0/0
RouteTableId: !Ref VpcPrivateRouteTable
# NatGatewayId: #!Ref NatGateway # - OLD Hook <===============
NetworkInterfaceId: !Ref FckNatInterface # New Hook <===============Replaced with
PrivateSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref VpcPrivateRouteTable
SubnetId: !Ref PrivateSubnet
'FckNatInterface' is the same as mentioned in the docs Fck-nat deployment (Cloudformation section)
Everything deploys without error, however the lambda function cannot access the ElasticIP or otherwise reach the outside world see image below of the axios response from inside the function:
I have checked the routes, ipv4 allocation, and as far as I can tell, the architecture is fine. I have also re-enabled the NAT-Gateway to ensure no mistakes where made elsewhere (all worked as intended). So the issue is 100% with fck-nat bridge from private to public, but I'm not enough of an expert in network to debug further.
Any advice is welcome. Hopefully this also helps others.
Other info:
A staticIP is a requirement for my lambda Function due to security requirements of LimeLM,LimeLm Forumn link
Please let me know if additional information required in the commnents, I will update as needed
See Here for a fairly close varient of what my implementation is with NATGateway instead of fck-nat.
A great general guide explaining VPC Architecture click Here
Finally worked out an answer! :
1) The Internet gateway has to be connected to the public route table:
PublicSubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId:
!Ref VpcPublicRouteTable
SubnetId:
!Ref PublicSubnet
The 'AWS::EC2::Instance' requires a network interface with a 'groupset' that allows all traffic through, rather than a direct 'network interface' connection
FckNatEC2Instance:
Type: AWS::EC2::Instance
Properties:
Tags:
- Key: Name
Value: fckNatInstance
SourceDestCheck: false
ImageId: ami-084b3eca5402436bf
InstanceType: t4g.nano
NetworkInterfaces:
# - NetworkInterfaceId: !Ref FckNatInterface OLD
# NEW:
- DeleteOnTermination: true
Description: fckNatEC2Instance network interface
SubnetId: !Ref PublicSubnet
GroupSet:
- !Ref SGAllTrafficFromVPC
AssociatePublicIpAddress: "true"
DeviceIndex: "0"
Add:
SGAllTrafficFromVPC:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupName: SGAllTrafficFromVPC
GroupDescription: VPN Traffic from VPC CIDR
VpcId: !Ref StaticIpVpc
SecurityGroupIngress:
- IpProtocol: '-1'
CidrIp: !Ref VpcCidrBlock
Description: All Traffic from VPC CIDR
Bonus: it also helps to add ssh support for debugging:
EC2SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
VpcId: !Ref StaticIpVpc
GroupDescription: Access ssh access to
SecurityGroupIngress:
- CidrIp : 10.0.0.0/24
IpProtocol: tcp
FromPort: 22
ToPort: 22
Tags:
- Key: Name
Value: EC2SecurityGroup