398 lines
13 KiB
YAML
398 lines
13 KiB
YAML
service: esdp-infra
|
|
app: esdp-api-app
|
|
frameworkVersion: '4'
|
|
|
|
stages:
|
|
shared:
|
|
observability: false
|
|
params:
|
|
# Single shared database name for all app stages (dev/alpha/beta/prod)
|
|
db_name: esdp
|
|
# Your public IP in CIDR form for direct DB access (lock this down).
|
|
admin_cidr: 70.36.57.88/32
|
|
|
|
provider:
|
|
name: aws
|
|
runtime: nodejs22.x
|
|
region: ca-central-1
|
|
|
|
resources:
|
|
Resources:
|
|
EsdpVpc:
|
|
Type: AWS::EC2::VPC
|
|
Properties:
|
|
CidrBlock: 10.0.0.0/16
|
|
EnableDnsSupport: true
|
|
EnableDnsHostnames: true
|
|
Tags:
|
|
- Key: Name
|
|
Value: ${self:service}-${sls:stage}-vpc
|
|
|
|
InternetGateway:
|
|
Type: AWS::EC2::InternetGateway
|
|
Properties:
|
|
Tags:
|
|
- Key: Name
|
|
Value: ${self:service}-${sls:stage}-igw
|
|
|
|
VpcGatewayAttachment:
|
|
Type: AWS::EC2::VPCGatewayAttachment
|
|
Properties:
|
|
VpcId:
|
|
Ref: EsdpVpc
|
|
InternetGatewayId:
|
|
Ref: InternetGateway
|
|
|
|
PublicSubnetA:
|
|
Type: AWS::EC2::Subnet
|
|
Properties:
|
|
VpcId:
|
|
Ref: EsdpVpc
|
|
AvailabilityZone:
|
|
Fn::Select:
|
|
- 0
|
|
- Fn::GetAZs: ''
|
|
CidrBlock: 10.0.0.0/24
|
|
MapPublicIpOnLaunch: true
|
|
Tags:
|
|
- Key: Name
|
|
Value: ${self:service}-${sls:stage}-public-a
|
|
|
|
PublicSubnetB:
|
|
Type: AWS::EC2::Subnet
|
|
Properties:
|
|
VpcId:
|
|
Ref: EsdpVpc
|
|
AvailabilityZone:
|
|
Fn::Select:
|
|
- 1
|
|
- Fn::GetAZs: ''
|
|
CidrBlock: 10.0.1.0/24
|
|
MapPublicIpOnLaunch: true
|
|
Tags:
|
|
- Key: Name
|
|
Value: ${self:service}-${sls:stage}-public-b
|
|
|
|
PrivateSubnetA:
|
|
Type: AWS::EC2::Subnet
|
|
Properties:
|
|
VpcId:
|
|
Ref: EsdpVpc
|
|
AvailabilityZone:
|
|
Fn::Select:
|
|
- 0
|
|
- Fn::GetAZs: ''
|
|
CidrBlock: 10.0.10.0/24
|
|
MapPublicIpOnLaunch: false
|
|
Tags:
|
|
- Key: Name
|
|
Value: ${self:service}-${sls:stage}-private-a
|
|
|
|
PrivateSubnetB:
|
|
Type: AWS::EC2::Subnet
|
|
Properties:
|
|
VpcId:
|
|
Ref: EsdpVpc
|
|
AvailabilityZone:
|
|
Fn::Select:
|
|
- 1
|
|
- Fn::GetAZs: ''
|
|
CidrBlock: 10.0.11.0/24
|
|
MapPublicIpOnLaunch: false
|
|
Tags:
|
|
- Key: Name
|
|
Value: ${self:service}-${sls:stage}-private-b
|
|
|
|
PublicRouteTable:
|
|
Type: AWS::EC2::RouteTable
|
|
Properties:
|
|
VpcId:
|
|
Ref: EsdpVpc
|
|
Tags:
|
|
- Key: Name
|
|
Value: ${self:service}-${sls:stage}-public-rt
|
|
|
|
PublicRoute:
|
|
Type: AWS::EC2::Route
|
|
DependsOn: VpcGatewayAttachment
|
|
Properties:
|
|
RouteTableId:
|
|
Ref: PublicRouteTable
|
|
DestinationCidrBlock: 0.0.0.0/0
|
|
GatewayId:
|
|
Ref: InternetGateway
|
|
|
|
PublicSubnetARouteTableAssociation:
|
|
Type: AWS::EC2::SubnetRouteTableAssociation
|
|
Properties:
|
|
SubnetId:
|
|
Ref: PublicSubnetA
|
|
RouteTableId:
|
|
Ref: PublicRouteTable
|
|
|
|
PublicSubnetBRouteTableAssociation:
|
|
Type: AWS::EC2::SubnetRouteTableAssociation
|
|
Properties:
|
|
SubnetId:
|
|
Ref: PublicSubnetB
|
|
RouteTableId:
|
|
Ref: PublicRouteTable
|
|
|
|
NatEip:
|
|
Type: AWS::EC2::EIP
|
|
Properties:
|
|
Domain: vpc
|
|
|
|
NatGateway:
|
|
Type: AWS::EC2::NatGateway
|
|
Properties:
|
|
AllocationId:
|
|
Fn::GetAtt:
|
|
- NatEip
|
|
- AllocationId
|
|
SubnetId:
|
|
Ref: PublicSubnetA
|
|
Tags:
|
|
- Key: Name
|
|
Value: ${self:service}-${sls:stage}-nat
|
|
|
|
PrivateRouteTable:
|
|
Type: AWS::EC2::RouteTable
|
|
Properties:
|
|
VpcId:
|
|
Ref: EsdpVpc
|
|
Tags:
|
|
- Key: Name
|
|
Value: ${self:service}-${sls:stage}-private-rt
|
|
|
|
PrivateRoute:
|
|
Type: AWS::EC2::Route
|
|
Properties:
|
|
RouteTableId:
|
|
Ref: PrivateRouteTable
|
|
DestinationCidrBlock: 0.0.0.0/0
|
|
NatGatewayId:
|
|
Ref: NatGateway
|
|
|
|
PrivateSubnetARouteTableAssociation:
|
|
Type: AWS::EC2::SubnetRouteTableAssociation
|
|
Properties:
|
|
SubnetId:
|
|
Ref: PrivateSubnetA
|
|
RouteTableId:
|
|
Ref: PrivateRouteTable
|
|
|
|
PrivateSubnetBRouteTableAssociation:
|
|
Type: AWS::EC2::SubnetRouteTableAssociation
|
|
Properties:
|
|
SubnetId:
|
|
Ref: PrivateSubnetB
|
|
RouteTableId:
|
|
Ref: PrivateRouteTable
|
|
|
|
LambdaSecurityGroup:
|
|
Type: AWS::EC2::SecurityGroup
|
|
Properties:
|
|
GroupDescription: ${self:service}-${sls:stage} Lambda security group
|
|
VpcId:
|
|
Ref: EsdpVpc
|
|
SecurityGroupEgress:
|
|
- IpProtocol: -1
|
|
CidrIp: 0.0.0.0/0
|
|
Tags:
|
|
- Key: Name
|
|
Value: ${self:service}-${sls:stage}-lambda-sg
|
|
|
|
ProxySecurityGroup:
|
|
Type: AWS::EC2::SecurityGroup
|
|
Properties:
|
|
GroupDescription: ${self:service}-${sls:stage} RDS proxy security group
|
|
VpcId:
|
|
Ref: EsdpVpc
|
|
SecurityGroupIngress:
|
|
- IpProtocol: tcp
|
|
FromPort: 5432
|
|
ToPort: 5432
|
|
SourceSecurityGroupId:
|
|
Ref: LambdaSecurityGroup
|
|
- IpProtocol: tcp
|
|
FromPort: 5432
|
|
ToPort: 5432
|
|
CidrIp: ${param:admin_cidr}
|
|
SecurityGroupEgress:
|
|
- IpProtocol: -1
|
|
CidrIp: 0.0.0.0/0
|
|
Tags:
|
|
- Key: Name
|
|
Value: ${self:service}-${sls:stage}-proxy-sg
|
|
|
|
RdsSecurityGroup:
|
|
Type: AWS::EC2::SecurityGroup
|
|
Properties:
|
|
GroupDescription: ${self:service}-${sls:stage} RDS security group
|
|
VpcId:
|
|
Ref: EsdpVpc
|
|
SecurityGroupIngress:
|
|
- IpProtocol: tcp
|
|
FromPort: 5432
|
|
ToPort: 5432
|
|
SourceSecurityGroupId:
|
|
Ref: ProxySecurityGroup
|
|
- IpProtocol: tcp
|
|
FromPort: 5432
|
|
ToPort: 5432
|
|
CidrIp: ${param:admin_cidr}
|
|
Tags:
|
|
- Key: Name
|
|
Value: ${self:service}-${sls:stage}-rds-sg
|
|
|
|
DbSubnetGroup:
|
|
Type: AWS::RDS::DBSubnetGroup
|
|
Properties:
|
|
DBSubnetGroupDescription: ${self:service}-${sls:stage} DB subnet group
|
|
SubnetIds:
|
|
- Ref: PublicSubnetA
|
|
- Ref: PublicSubnetB
|
|
|
|
DbSecret:
|
|
Type: AWS::SecretsManager::Secret
|
|
Properties:
|
|
Description: ${self:service}-${sls:stage} RDS master credentials
|
|
GenerateSecretString:
|
|
SecretStringTemplate: '{"username":"esdp_admin"}'
|
|
GenerateStringKey: password
|
|
PasswordLength: 32
|
|
ExcludeCharacters: '"@/\\'
|
|
|
|
DbProxyRole:
|
|
Type: AWS::IAM::Role
|
|
Properties:
|
|
AssumeRolePolicyDocument:
|
|
Version: '2012-10-17'
|
|
Statement:
|
|
- Effect: Allow
|
|
Principal:
|
|
Service:
|
|
- rds.amazonaws.com
|
|
Action:
|
|
- sts:AssumeRole
|
|
Policies:
|
|
- PolicyName: ${self:service}-${sls:stage}-db-proxy-secrets
|
|
PolicyDocument:
|
|
Version: '2012-10-17'
|
|
Statement:
|
|
- Effect: Allow
|
|
Action:
|
|
- secretsmanager:GetSecretValue
|
|
Resource:
|
|
- Ref: DbSecret
|
|
|
|
DbProxy:
|
|
Type: AWS::RDS::DBProxy
|
|
Properties:
|
|
DBProxyName: ${self:service}-${sls:stage}-proxy
|
|
EngineFamily: POSTGRESQL
|
|
IdleClientTimeout: 1800
|
|
RequireTLS: true
|
|
RoleArn:
|
|
Fn::GetAtt:
|
|
- DbProxyRole
|
|
- Arn
|
|
VpcSubnetIds:
|
|
- Ref: PrivateSubnetA
|
|
- Ref: PrivateSubnetB
|
|
VpcSecurityGroupIds:
|
|
- Ref: ProxySecurityGroup
|
|
Auth:
|
|
- AuthScheme: SECRETS
|
|
SecretArn:
|
|
Ref: DbSecret
|
|
IAMAuth: DISABLED
|
|
|
|
DbProxyTargetGroup:
|
|
Type: AWS::RDS::DBProxyTargetGroup
|
|
Properties:
|
|
DBProxyName:
|
|
Ref: DbProxy
|
|
TargetGroupName: default
|
|
DBInstanceIdentifiers:
|
|
- Ref: PostgresDb
|
|
ConnectionPoolConfigurationInfo:
|
|
MaxConnectionsPercent: 75
|
|
MaxIdleConnectionsPercent: 50
|
|
ConnectionBorrowTimeout: 120
|
|
|
|
PostgresDb:
|
|
Type: AWS::RDS::DBInstance
|
|
DeletionPolicy: Snapshot
|
|
UpdateReplacePolicy: Snapshot
|
|
Properties:
|
|
DBInstanceIdentifier: ${self:service}-${sls:stage}-postgres
|
|
Engine: postgres
|
|
# EngineVersion intentionally omitted so AWS uses the current default/latest for RDS Postgres.
|
|
AutoMinorVersionUpgrade: true
|
|
DBInstanceClass: db.t4g.micro
|
|
AllocatedStorage: 20
|
|
StorageType: gp3
|
|
StorageEncrypted: true
|
|
PubliclyAccessible: true
|
|
MultiAZ: false
|
|
DBName: ${param:db_name}
|
|
BackupRetentionPeriod: 7
|
|
CopyTagsToSnapshot: true
|
|
DeletionProtection: true
|
|
VPCSecurityGroups:
|
|
- Ref: RdsSecurityGroup
|
|
DBSubnetGroupName:
|
|
Ref: DbSubnetGroup
|
|
MasterUsername:
|
|
Fn::Sub: '{{resolve:secretsmanager:${DbSecret}::username}}'
|
|
MasterUserPassword:
|
|
Fn::Sub: '{{resolve:secretsmanager:${DbSecret}::password}}'
|
|
|
|
Outputs:
|
|
VpcId:
|
|
Value:
|
|
Ref: EsdpVpc
|
|
PrivateSubnetAId:
|
|
Value:
|
|
Ref: PrivateSubnetA
|
|
PrivateSubnetBId:
|
|
Value:
|
|
Ref: PrivateSubnetB
|
|
|
|
LambdaSecurityGroupId:
|
|
Value:
|
|
Ref: LambdaSecurityGroup
|
|
ProxySecurityGroupId:
|
|
Value:
|
|
Ref: ProxySecurityGroup
|
|
RdsSecurityGroupId:
|
|
Value:
|
|
Ref: RdsSecurityGroup
|
|
|
|
DbName:
|
|
Value: ${param:db_name}
|
|
DbPort:
|
|
Value: 5432
|
|
|
|
DbEndpointAddress:
|
|
Value:
|
|
Fn::GetAtt:
|
|
- PostgresDb
|
|
- Endpoint.Address
|
|
DbEndpointPort:
|
|
Value:
|
|
Fn::GetAtt:
|
|
- PostgresDb
|
|
- Endpoint.Port
|
|
DbSecretArn:
|
|
Value:
|
|
Ref: DbSecret
|
|
|
|
DbProxyEndpoint:
|
|
Value:
|
|
Fn::GetAtt:
|
|
- DbProxy
|
|
- Endpoint
|