Create a simple VPC Peer between Kubernetes and RDS(postgres)
Tags: vpc, kubernetes, rds, postgres
Published: 2020-03-19 15:46:00

# 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:
```shell
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
```
and for RDS:
```shell
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"
```
Now that all variables are set, **the following steps should be run as simply copy-paste** 
### Get VPC ID of acceptor i.e. RDS
```shell
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)
```

### Get VPC ID of requestor i.e. EKS 
```shell
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)
```
### get Public Route table ID of requestor and acceptor
```shell
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)
```
### Create Peering Connection 
```shell
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'
```
### Adding the private VPC CIDR block to our public VPC route table as destination
```shell
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"
```

### Add a rule that allows inbound RDS (from our Public Instance source)
```shell
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"
```
## 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>=
    ```