I'm trying to connect AS Aurora Serverless v2 with pgadmin or another postgreSQL client. I have deployed the resources using CloudFormation and serverless framework. This is my current yml configuration:
resources:
Conditions:
CreateProdResources: !Equals ["${self:provider.stage}", "prod"]
CreateDevResources: !Not [!Equals ["${self:provider.stage}", "prod"]]
Resources:
VPC:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: "10.0.0.0/16"
EnableDnsHostnames: !If [CreateDevResources, true, false]
EnableDnsSupport: !If [CreateDevResources, true, false]
Tags:
- Key: "Name"
Value: ${self:custom.resources.vpcTag}
InternetGateway:
Type: "AWS::EC2::InternetGateway"
VPCGatewayAttachment:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
VpcId: !Ref "VPC"
InternetGatewayId: !Ref "InternetGateway"
EIP:
Type: "AWS::EC2::EIP"
Properties:
Domain: "vpc"
Nat:
Type: "AWS::EC2::NatGateway"
Properties:
AllocationId: !GetAtt "EIP.AllocationId"
SubnetId: !Ref PublicSubnet
PublicSubnet:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: !Select
- 0
- !GetAZs ${self:provider.region}
VpcId: !Ref "VPC"
CidrBlock: "10.0.0.0/24"
SubnetA:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: !Select
- 1
- !GetAZs ${self:provider.region}
VpcId: !Ref "VPC"
CidrBlock: "10.0.1.0/24"
SubnetB:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: !Select
- 2
- !GetAZs ${self:provider.region}
VpcId: !Ref "VPC"
CidrBlock: "10.0.2.0/24"
PublicSubnetA:
Type: "AWS::EC2::Subnet"
Condition: CreateDevResources
Properties:
AvailabilityZone: !Select
- 1
- !GetAZs ${self:provider.region}
VpcId: !Ref "VPC"
CidrBlock: "10.0.3.0/24"
PublicSubnetB:
Type: "AWS::EC2::Subnet"
Condition: CreateDevResources
Properties:
AvailabilityZone: !Select
- 2
- !GetAZs ${self:provider.region}
VpcId: !Ref "VPC"
CidrBlock: "10.0.4.0/24"
RouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref "VPC"
InternetRoute:
Type: "AWS::EC2::Route"
Properties:
DestinationCidrBlock: "0.0.0.0/0"
GatewayId: !Ref InternetGateway
RouteTableId: !Ref RouteTable
PublicSubnetRouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref RouteTable
SubnetId: !Ref PublicSubnet
PublicSubnetARouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Condition: CreateDevResources
Properties:
RouteTableId: !Ref RouteTable
SubnetId: !Ref PublicSubnetA
PublicSubnetBRouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Condition: CreateDevResources
Properties:
RouteTableId: !Ref RouteTable
SubnetId: !Ref PublicSubnetB
NatRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref "VPC"
NatRoute:
Type: "AWS::EC2::Route"
Properties:
DestinationCidrBlock: "0.0.0.0/0"
NatGatewayId: !Ref "Nat"
RouteTableId: !Ref "NatRouteTable"
SubnetARouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref NatRouteTable
SubnetId: !Ref SubnetA
SubnetBRouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref NatRouteTable
SubnetId: !Ref SubnetB
InstanceSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupName: "SecurityGroup"
GroupDescription: "SecurityGroup"
VpcId: !Ref "VPC"
SecurityGroupEgress:
- IpProtocol: "-1"
CidrIp: "0.0.0.0/0"
InstanceSecurityGroupIngress:
Type: "AWS::EC2::SecurityGroupIngress"
DependsOn: "InstanceSecurityGroup"
Properties:
GroupId: !Ref "InstanceSecurityGroup"
IpProtocol: "tcp"
FromPort: "0"
ToPort: "65535"
SourceSecurityGroupId: !Ref "InstanceSecurityGroup"
DBSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Properties:
DBSubnetGroupName: ${self:service}-${self:provider.stage}-dbsubnetgroup
DBSubnetGroupDescription: "${self:service}-dbsubnetgroup"
SubnetIds:
- !Ref "SubnetA"
- !Ref "SubnetB"
PublicDBSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Condition: CreateDevResources
Properties:
DBSubnetGroupName: ${self:service}-${self:provider.stage}-publicdbsubnetgroup
DBSubnetGroupDescription: "${self:service}-publicdbsubnetgroup"
SubnetIds:
- !Ref "PublicSubnetA"
- !Ref "PublicSubnetB"
RDSCluster:
Type: "AWS::RDS::DBCluster"
Properties:
MasterUsername: ${self:custom.resources.databaseUser}
MasterUserPassword: ${self:custom.resources.databasePassword}
DatabaseName: ${self:custom.resources.databaseName}
Engine: "aurora-postgresql"
EngineVersion: "14.3"
ServerlessV2ScalingConfiguration:
MinCapacity: 0.5
MaxCapacity: 2
VpcSecurityGroupIds:
- !Ref "InstanceSecurityGroup"
DBSubnetGroupName: !If [CreateDevResources, !Ref "PublicDBSubnetGroup", !Ref "DBSubnetGroup"]
DBInstance1:
Type: AWS::RDS::DBInstance
Properties:
DBClusterIdentifier: !Ref "RDSCluster"
DBInstanceClass: db.serverless
Engine: aurora-postgresql
DBInstance2:
Type: AWS::RDS::DBInstance
Properties:
DBClusterIdentifier: !Ref "RDSCluster"
DBInstanceClass: db.serverless
Engine: aurora-postgresql
Reading AWS docs, as it says, I'm adding VPC DNS hostnames and support, 2 public subnets and a public dbsubnetgroup if environment is for development, but still can't connect database with pgadmin, any suggestions?
Thanks to Mark's answer I made this work with some tweaks.
First of all added MapPublicIpOnLaunch to public subnets, added securitygroupingress rule to allow all traffic and finally added PubliclyAccessible property not to the cluster, which for some reason doesnt work, but to all the db instances.
So the the resources ended like this:
resources:
Conditions:
CreateProdResources: !Equals ["${self:provider.stage}", "prod"]
CreateDevResources: !Not [!Equals ["${self:provider.stage}", "prod"]]
Resources:
VPC:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: "10.0.0.0/16"
EnableDnsHostnames: !If [CreateDevResources, true, false]
EnableDnsSupport: !If [CreateDevResources, true, false]
Tags:
- Key: "Name"
Value: ${self:custom.resources.vpcTag}
InternetGateway:
Type: "AWS::EC2::InternetGateway"
VPCGatewayAttachment:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
VpcId: !Ref "VPC"
InternetGatewayId: !Ref "InternetGateway"
EIP:
Type: "AWS::EC2::EIP"
Properties:
Domain: "vpc"
Nat:
Type: "AWS::EC2::NatGateway"
Properties:
AllocationId: !GetAtt "EIP.AllocationId"
SubnetId: !Ref PublicSubnet
PublicSubnet:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: !Select
- 0
- !GetAZs ${self:provider.region}
VpcId: !Ref "VPC"
CidrBlock: "10.0.0.0/24"
SubnetA:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: !Select
- 1
- !GetAZs ${self:provider.region}
VpcId: !Ref "VPC"
CidrBlock: "10.0.1.0/24"
SubnetB:
Type: "AWS::EC2::Subnet"
Properties:
AvailabilityZone: !Select
- 2
- !GetAZs ${self:provider.region}
VpcId: !Ref "VPC"
CidrBlock: "10.0.2.0/24"
PublicSubnetA:
Type: "AWS::EC2::Subnet"
Condition: CreateDevResources
Properties:
MapPublicIpOnLaunch: true
AvailabilityZone: !Select
- 1
- !GetAZs ${self:provider.region}
VpcId: !Ref "VPC"
CidrBlock: "10.0.3.0/24"
PublicSubnetB:
Type: "AWS::EC2::Subnet"
Condition: CreateDevResources
Properties:
MapPublicIpOnLaunch: true
AvailabilityZone: !Select
- 2
- !GetAZs ${self:provider.region}
VpcId: !Ref "VPC"
CidrBlock: "10.0.4.0/24"
RouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref "VPC"
InternetRoute:
Type: "AWS::EC2::Route"
Properties:
DestinationCidrBlock: "0.0.0.0/0"
GatewayId: !Ref InternetGateway
RouteTableId: !Ref RouteTable
PublicSubnetRouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref RouteTable
SubnetId: !Ref PublicSubnet
PublicSubnetARouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Condition: CreateDevResources
Properties:
RouteTableId: !Ref RouteTable
SubnetId: !Ref PublicSubnetA
PublicSubnetBRouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Condition: CreateDevResources
Properties:
RouteTableId: !Ref RouteTable
SubnetId: !Ref PublicSubnetB
NatRouteTable:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref "VPC"
NatRoute:
Type: "AWS::EC2::Route"
Properties:
DestinationCidrBlock: "0.0.0.0/0"
NatGatewayId: !Ref "Nat"
RouteTableId: !Ref "NatRouteTable"
SubnetARouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref NatRouteTable
SubnetId: !Ref SubnetA
SubnetBRouteTableAssociation:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref NatRouteTable
SubnetId: !Ref SubnetB
InstanceSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupName: "SecurityGroup"
GroupDescription: "SecurityGroup"
VpcId: !Ref "VPC"
SecurityGroupEgress:
- IpProtocol: "-1"
CidrIp: "0.0.0.0/0"
InstanceSecurityGroupIngress:
Type: "AWS::EC2::SecurityGroupIngress"
DependsOn: "InstanceSecurityGroup"
Properties:
GroupId: !Ref "InstanceSecurityGroup"
IpProtocol: "tcp"
FromPort: "0"
ToPort: "65535"
SourceSecurityGroupId: !Ref "InstanceSecurityGroup"
PublicInstanceSecurityGroupIngress:
Type: "AWS::EC2::SecurityGroupIngress"
DependsOn: "InstanceSecurityGroup"
Condition: CreateDevResources
Properties:
GroupId: !Ref "InstanceSecurityGroup"
IpProtocol: "-1"
CidrIp: "0.0.0.0/0"
DBSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Properties:
DBSubnetGroupName: ${self:service}-${self:provider.stage}-dbsubnetgroup
DBSubnetGroupDescription: "${self:service}-dbsubnetgroup"
SubnetIds:
- !Ref "SubnetA"
- !Ref "SubnetB"
PublicDBSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
Condition: CreateDevResources
Properties:
DBSubnetGroupName: ${self:service}-${self:provider.stage}-publicdbsubnetgroup
DBSubnetGroupDescription: "${self:service}-publicdbsubnetgroup"
SubnetIds:
- !Ref "PublicSubnetA"
- !Ref "PublicSubnetB"
RDSCluster:
Type: "AWS::RDS::DBCluster"
Properties:
MasterUsername: ${self:custom.resources.databaseUser}
MasterUserPassword: ${self:custom.resources.databasePassword}
DatabaseName: ${self:custom.resources.databaseName}
Engine: "aurora-postgresql"
EngineVersion: "14.3"
ServerlessV2ScalingConfiguration:
MinCapacity: 0.5
MaxCapacity: 2
VpcSecurityGroupIds:
- !Ref "InstanceSecurityGroup"
DBSubnetGroupName: !If [CreateDevResources, !Ref "PublicDBSubnetGroup", !Ref "DBSubnetGroup"]
DBInstance1:
Type: AWS::RDS::DBInstance
Properties:
DBClusterIdentifier: !Ref "RDSCluster"
DBInstanceClass: db.serverless
PubliclyAccessible: !If [CreateDevResources, true, false]
Engine: aurora-postgresql
DBInstance2:
Type: AWS::RDS::DBInstance
Properties:
DBClusterIdentifier: !Ref "RDSCluster"
DBInstanceClass: db.serverless
PubliclyAccessible: !If [CreateDevResources, true, false]
Engine: aurora-postgresql