DEV Community

Imran Hayder
Imran Hayder

Posted on • Updated on

Create a simple VPC Peer between Kubernetes and RDS(postgres)

Create a VPC Peering connection between EKS Kubernetes and RDS Postgres

Note: this script assumes your resources names are prefixed with name of EKS cluster so if EKS cluster name is "myEKS" then the EKS VPC name is myEKS/VPC.

please fix this script variables in Step#1 according to your naming convention or actual names of resources.
all rest of steps are same.

Set some basic information like EKS names / VPC Names

Setting variables for EKS cluster:

EKS_CLUSTER="name_of_EKS_cluster_goes_here"
# set name of VPC in which EKS exists, for me i use eksctl to create eks
# so vpc name is automatically set to name_of_eks_cluster/VPC
# you can change here to whatever your VPC name is
EKS_VPC="$EKS_CLUSTER"/VPC 
# same goes for the VPC public routing table name of EKS
EKS_PUBLIC_ROUTING_TABLE="$EKS_CLUSTER"/PublicRouteTable
Enter fullscreen mode Exit fullscreen mode

and for RDS:

RDS_NAME="name_of_RDS_goes_here"
# set this variable to the name of VPC in which RDS exists 
RDS_VPC="$RDS_NAME"/VPC
# same goes for private routing table of RDS
RDS_PRIVATE_ROUTING_TABLE="$RDS_NAME"/RDSPrivateRoutingTable

RDS_DB_NAME="Name_of_RDS_instance"
Enter fullscreen mode Exit fullscreen mode

Now that all variables are set, the following steps should be run as simply copy-paste

Get VPC ID of acceptor i.e. RDS

echo "getting the VPC ID and CIDR of acceptor(RDS instance)"
ACCEPT_VPC_ID=$(aws ec2 describe-vpcs --filters Name=tag:Name,Values=$RDS_VPC --query=Vpcs[0].VpcId --output text)
ACCEPT_CIDR=$(aws ec2 describe-vpcs --filters Name=tag:Name,Values=$RDS_VPC --query=Vpcs[0].CidrBlockAssociationSet[0].CidrBlock --output text)
Enter fullscreen mode Exit fullscreen mode

Get VPC ID of requestor i.e. EKS

REQUEST_VPC_ID=$(aws ec2 describe-vpcs --filters Name=tag:Name,Values=$EKS_VPC --query=Vpcs[0].VpcId --output text)
REQUEST_CIDR=$(aws ec2 describe-vpcs --filters Name=tag:Name,Values=$EKS_VPC --query=Vpcs[0].CidrBlockAssociationSet[0].CidrBlock --output text)
Enter fullscreen mode Exit fullscreen mode

get Public Route table ID of requestor and acceptor

REQ_ROUTE_ID=$(aws ec2 describe-route-tables --filters Name=tag:Name,Values=$EKS_PUBLIC_ROUTING_TABLE --query=RouteTables[0].RouteTableId --output text)
ACCEPT_ROUTE_ID=$(aws ec2 describe-route-tables --filters Name=tag:Name,Values=$RDS_PRIVATE_ROUTING_TABLE --query=RouteTables[0].RouteTableId --output text)
Enter fullscreen mode Exit fullscreen mode

Create Peering Connection

peerVPCID=$(aws $DRY_RUN ec2 create-vpc-peering-connection --vpc-id $REQUEST_VPC_ID --peer-vpc-id $ACCEPT_VPC_ID --query VpcPeeringConnection.VpcPeeringConnectionId --output text)
aws $DRY_RUN ec2 accept-vpc-peering-connection --vpc-peering-connection-id "$peerVPCID"
aws $DRY_RUN ec2 create-tags --resources "$peerVPCID" --tags 'Key=Name,Value=eks-peer-rds'
Enter fullscreen mode Exit fullscreen mode

Adding the private VPC CIDR block to our public VPC route table as destination

aws $DRY_RUN ec2 create-route --route-table-id "$REQ_ROUTE_ID" --destination-cidr-block "$ACCEPT_CIDR" --vpc-peering-connection-id "$peerVPCID"
aws $DRY_RUN ec2 create-route --route-table-id "$ACCEPT_ROUTE_ID" --destination-cidr-block "$REQUEST_CIDR" --vpc-peering-connection-id "$peerVPCID"
Enter fullscreen mode Exit fullscreen mode

Add a rule that allows inbound RDS (from our Public Instance source)

RDS_VPC_SECURITY_GROUP_ID=$(aws rds describe-db-instances --db-instance-identifier $RDS_DB_NAME --query=DBInstances[0].VpcSecurityGroups[0].VpcSecurityGroupId --output text)
aws ec2 authorize-security-group-ingress --group-id ${RDS_VPC_SECURITY_GROUP_ID} --protocol tcp --port 5432 --cidr "$REQUEST_CIDR"
Enter fullscreen mode Exit fullscreen mode

TESTING CONNECTIONS

  1. Run postgresql container :

    kubectl run -i --tty --rm postgresdebug --image=alpine:3.5 -- 
     restart=Never -- sh
    
  2. install postgresql:

    apk update
    apk add postgresql
    
  3. Run PSQL:

    psql -h <HOST> -U <USER>
    Password for user <USER>:
    psql (9.6.10, server 9.6.15)
    SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM- 
    SHA384, bits: 256, compression: off)
    Type "help" for help.
    <DB_NAME>=
    

Discussion (2)

Collapse
marktwallace profile image
Mark Wallace

Thanks for the helpful example! I used this to create a script to automate creating peering for my EKS and Aurora VPC's. I found that one step was left out: we also need to allow DNS resolution between the VPC's. The extra command needed, following the pattern above, is:

aws $DRY_RUN ec2 modify-vpc-peering-connection-options \
--vpc-peering-connection-id "$peerVPCID" \
--requester-peering-connection-options '{"AllowDnsResolutionFromRemoteVpc":true}' \
--accepter-peering-connection-options '{"AllowDnsResolutionFromRemoteVpc":true}'

Collapse
elepolt profile image
Evan

Thank you this was extremely useful. I have a quick question on how this might work if I need a second EKS VPC to peer to my RDS. Following the same commands gives me an error that there's a duplicate route and rule for 192.168.0.0/16, therefore my second EKS is timing out.