Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 904a9d1

Browse files
committedApr 7, 2022
Merge branch '324-cloudformation-fixes' into 'master'
feat(cf): enable secure connections with TLS certificates (#324) Closes #324 See merge request postgres-ai/database-lab!509
2 parents bbef35d + 455f513 commit 904a9d1

File tree

3 files changed

+207
-75
lines changed

3 files changed

+207
-75
lines changed
 

‎cloudformation/dle_cf_template.yaml

Lines changed: 195 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Description: >-
66
Metadata:
77
AWS::CloudFormation::Interface:
88
ParameterGroups:
9-
-
9+
-
1010
Label:
1111
default: "Amazon EC2 configuration"
1212
Parameters:
@@ -15,16 +15,22 @@ Metadata:
1515
- SSHLocation
1616
- VPC
1717
- Subnet
18-
- KeyName
19-
-
18+
- KeyName
19+
- Label:
20+
default: "TLS certificate configuration"
21+
Parameters:
22+
- CertificateSubdomain
23+
- CertificateHostedZone
24+
- CertificateEmail
25+
-
2026
Label:
2127
default: "Database Lab Engine (DLE) configuration"
2228
Parameters:
2329
- DLERetrievalRefreshTimetable
2430
- PostgresDumpParallelJobs
2531
- DLEVerificationToken
2632
- DLEDebugMode
27-
-
33+
-
2834
Label:
2935
default: "Source PostgreSQL parameters"
3036
Parameters:
@@ -35,30 +41,36 @@ Metadata:
3541
- SourcePostgresDBName
3642
- SourcePostgresVersion
3743
- PostgresConfigSharedPreloadLibraries
38-
- SourcePostgresDBList
44+
- SourcePostgresDBList
3945
ParameterLabels:
4046
KeyName:
4147
default: "Key pair"
42-
VPC:
43-
default: "VPC security group"
44-
Subnet:
45-
default: "Subnet"
4648
InstanceType:
47-
default: "EC2 instance type"
49+
default: "Instance type"
4850
SSHLocation:
49-
default: "IP range for SSH connections"
51+
default: "Connection source IP range"
5052
ZFSVolumeSize:
51-
default: "Size of EBS volume for PGDATA and temporary dump, GiB"
53+
default: "EBS volume size in GB for ZFS"
54+
CertificateSubdomain:
55+
default: "Certificate subdomain"
56+
CertificateHostedZone:
57+
default: "Hosted zone"
58+
CertificateEmail:
59+
default: "Certificate email"
5260
DLEDebugMode:
53-
default: "Enable debug mode"
61+
default: "DLE debug mode"
5462
DLEVerificationToken:
5563
default: "DLE verification token"
5664
DLERetrievalRefreshTimetable:
57-
default: "Data retrieval refresh timetable"
65+
default: "DLE retrieval refresh timetable"
5866
PostgresDumpParallelJobs:
5967
default: "Number of pg_dump jobs"
6068
SourcePostgresDBName:
61-
default: "Source DB name"
69+
default: "Database name"
70+
VPC:
71+
default: "VPC security group"
72+
Subnet:
73+
default: "Subnet"
6274
SourcePostgresVersion:
6375
default: "Postgres version"
6476
SourcePostgresHost:
@@ -72,7 +84,7 @@ Metadata:
7284
PostgresConfigSharedPreloadLibraries:
7385
default: "shared_preload_libraries parameter"
7486
SourcePostgresDBList:
75-
default: "Comma separated list of databases to copy"
87+
default: "Comma separated list of databases to copy"
7688

7789
Parameters:
7890
Subnet:
@@ -157,6 +169,18 @@ Parameters:
157169
Description: The size of the EBS volumes used for DLE ZFS pool
158170
Type: Number
159171
Default: 40
172+
CertificateSubdomain:
173+
Description: Subdomain to obtain a TLS certificate for (for example, dle)
174+
Type: String
175+
CertificateHostedZone:
176+
Description: Hosted zone to obtain a TLS certificate for (for example, example.com)
177+
Type: String
178+
CertificateEmail:
179+
Description: Email address for important account notifications about the issued TLS certificate
180+
Type: String
181+
AllowedPattern: '^$|[^\s@]+@[^\s@]+\.[^\s@]+'
182+
Default: ''
183+
ConstraintDescription: Must be a valid email of the form \'user@example.com\'
160184
DLEDebugMode:
161185
Description: Enables DLE debug mode
162186
Type: String
@@ -167,15 +191,15 @@ Parameters:
167191
DLEVerificationToken:
168192
Description: DLE verification token
169193
Type: String
170-
Default: "example-verification-token"
194+
Default: "example-verification-token"
171195
MinLength: '9'
172196
MaxLength: '32'
173197
DLERetrievalRefreshTimetable:
174198
Description: DLE refresh schedule on cron format
175199
Type: String
176200
Default: '0 0 * * *'
177201
SourcePostgresDBName:
178-
Description: Source database name
202+
Description: Source database name. This parameter is used to connect to the database
179203
Type: String
180204
Default: 'postgres'
181205
SourcePostgresVersion:
@@ -213,13 +237,13 @@ Parameters:
213237
Type: String
214238
Default: ''
215239
PostgresDumpParallelJobs:
216-
Description: Number of jobs to run pg_dump against the source database
240+
Description: Number of jobs to run pg_dump against the source database
217241
Type: String
218242
Default: '1'
219243
SourcePostgresDBList:
220244
Description: List of database names on source for copy to DLE. Leave it empty to copy all accessible databases
221245
Type: String
222-
Default: ''
246+
Default: ''
223247
Mappings:
224248
AWSInstanceType2Arch:
225249
t1.micro:
@@ -326,39 +350,44 @@ Mappings:
326350
Arch: HVM64
327351
AWSRegionArch2AMI:
328352
eu-north-1:
329-
HVM64: ami-081887cbd4ae7185f
353+
HVM64: ami-034e4aed1f3ca0c3c
330354
ap-south-1:
331-
HVM64: ami-0bddbd3ec5d558943
355+
HVM64: ami-0e659eacedfb041d7
332356
eu-west-3:
333-
HVM64: ami-052460c22a01cd753
357+
HVM64: ami-08e35ca54e9190c97
334358
eu-west-2:
335-
HVM64: ami-04f292b00b02878fb
359+
HVM64: ami-0ecae7aba70abc116
336360
eu-west-1:
337-
HVM64: ami-051b242c0685a2a0a
361+
HVM64: ami-042f1da51ef5fd484
338362
ap-northeast-3:
339-
HVM64: ami-01d4b3bdb07544d3b
363+
HVM64: ami-01e9e9d567c32dd8f
340364
ap-northeast-2:
341-
HVM64: ami-0b74271f84354121e
365+
HVM64: ami-090fe41b7122583e1
342366
ap-northeast-1:
343-
HVM64: ami-06e9318c86a7bd3cb
367+
HVM64: ami-071b0fe046bc270b3
344368
sa-east-1:
345-
HVM64: ami-07e1a750e8779f490
369+
HVM64: ami-07a47547657f8dc18
346370
ca-central-1:
347-
HVM64: ami-0fbb25015660a32fe
371+
HVM64: ami-0578cffaf594ab219
348372
ap-southeast-1:
349-
HVM64: ami-04933b42f349e54c6
373+
HVM64: ami-0f151d9dcf524c7c2
350374
ap-southeast-2:
351-
HVM64: ami-06357c78fa8690ba7
375+
HVM64: ami-005263d8988e47a47
352376
eu-central-1:
353-
HVM64: ami-086d7d4e6d34451ad
377+
HVM64: ami-0b32ee6d741554a21
354378
us-east-1:
355-
HVM64: ami-074808abc8d765331
379+
HVM64: ami-088b2214cd2a232dc
356380
us-east-2:
357-
HVM64: ami-0d62c866f9add835d
381+
HVM64: ami-033774769e0f3cfc7
358382
us-west-1:
359-
HVM64: ami-0df8bef65801e5602
383+
HVM64: ami-07215a5d464906c4c
360384
us-west-2:
361-
HVM64: ami-0ab2c332753acfe0c
385+
HVM64: ami-05b2a489e553d9f0c
386+
387+
Conditions:
388+
CreateSubDomain:
389+
!Not [!Equals [!Ref CertificateHostedZone, '']]
390+
362391
Resources:
363392
ZFSVolume:
364393
Type: AWS::EC2::Volume
@@ -372,19 +401,23 @@ Resources:
372401
Key: Name
373402
Value: dle-zfs-volume
374403
VolumeType: gp2
404+
375405
DLEInstance:
376406
Type: 'AWS::EC2::Instance'
377407
Properties:
378-
ImageId: !FindInMap
408+
ImageId: !FindInMap
379409
- AWSRegionArch2AMI
380410
- !Ref 'AWS::Region'
381-
- !FindInMap
411+
- !FindInMap
382412
- AWSInstanceType2Arch
383413
- !Ref InstanceType
384414
- Arch
385415
InstanceType: !Ref InstanceType
386-
SecurityGroupIds:
387-
- !GetAtt DLESecurityGroup.GroupId
416+
SecurityGroupIds: !If
417+
- CreateSubDomain
418+
- - !GetAtt DLESecurityGroup.GroupId
419+
- !GetAtt DLEUISecurityGroup.GroupId
420+
- - !GetAtt DLESecurityGroup.GroupId
388421
KeyName: !Ref KeyName
389422
SubnetId: !Ref Subnet
390423
Tags:
@@ -413,20 +446,23 @@ Resources:
413446

414447
yq e -i '
415448
.global.debug=${DLEDebugMode} |
449+
.embeddedUI.host="" |
416450
.server.verificationToken="${DLEVerificationToken}" |
417451
.retrieval.refresh.timetable="${DLERetrievalRefreshTimetable}" |
418-
.retrieval.spec.logicalDump.options.source.connection.dbname="${SourcePostgresDBName}" |
419452
.retrieval.spec.logicalRestore.options.forceInit=true |
420-
.embeddedUI.host="" |
421-
.databaseContainer.dockerImage="postgresai/extended-postgres:${SourcePostgresVersion}"
453+
.databaseContainer.dockerImage="postgresai/extended-postgres:${SourcePostgresVersion}" |
454+
.databaseConfigs.configs.shared_preload_libraries="${PostgresConfigSharedPreloadLibraries}" |
455+
.databaseContainer.dockerImage="postgresai/extended-postgres:${SourcePostgresVersion}"
422456
' $dle_config_path/server.yml
423457
424458
yq e -i '
425459
.retrieval.spec.logicalDump.options.source.connection.host = "${SourcePostgresHost}" |
426460
.retrieval.spec.logicalDump.options.source.connection.port = ${SourcePostgresPort} |
461+
.retrieval.spec.logicalDump.options.source.connection.dbname="${SourcePostgresDBName}" |
427462
.retrieval.spec.logicalDump.options.source.connection.username = "${SourcePostgresUsername}" |
428463
.retrieval.spec.logicalDump.options.source.connection.password = "${SourcePostgresPassword}" |
429-
.retrieval.spec.logicalDump.options.parallelJobs = ${PostgresDumpParallelJobs}
464+
.retrieval.spec.logicalDump.options.parallelJobs = ${PostgresDumpParallelJobs} |
465+
.retrieval.spec.logicalRestore.options.configs.shared_preload_libraries = "${PostgresConfigSharedPreloadLibraries}"
430466
' $dle_config_path/server.yml
431467
432468
for i in $(echo ${SourcePostgresDBList} | sed "s/,/ /g")
@@ -450,15 +486,60 @@ Resources:
450486
--volume $dle_meta_path:/home/dblab/meta \
451487
--volume $postgres_conf_path:/home/dblab/standard/postgres/control \
452488
--env DOCKER_API_VERSION=1.39 \
453-
--restart on-failure \
454-
registry.gitlab.com/postgres-ai/database-lab/dblab-server:3.0.1
489+
--restart always \
490+
registry.gitlab.com/postgres-ai/database-lab/dblab-server:3.0.3
491+
492+
if [ ! -z "${CertificateHostedZone}" ]; then
493+
export DOMAIN=${CertificateSubdomain}.${CertificateHostedZone}
494+
export USER_EMAIL=${CertificateEmail}
495+
export CERTIFICATE_EMAIL=${!USER_EMAIL:-'noreply@'$DOMAIN}
496+
497+
sudo certbot certonly --standalone -d $DOMAIN -m $CERTIFICATE_EMAIL --agree-tos -n
498+
sudo cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/envoy/certs/fullchain1.pem
499+
sudo cp /etc/letsencrypt/live/$DOMAIN/privkey.pem /etc/envoy/certs/privkey1.pem
500+
501+
cat <<EOF > /etc/letsencrypt/renewal-hooks/deploy/envoy.deploy
502+
#!/bin/bash
503+
umask 0177
504+
export DOMAIN=${CertificateSubdomain}.${CertificateHostedZone}
505+
export DATA_DIR=/etc/envoy/certs/
506+
cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem $DATA_DIR/fullchain1.pem
507+
cp /etc/letsencrypt/live/$DOMAIN/privkey.pem $DATA_DIR/privkey1.pem
508+
EOF
509+
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/envoy.deploy
510+
511+
sudo systemctl enable envoy
512+
sudo systemctl start envoy
513+
fi
455514

456515
MountPoint:
457516
Type: AWS::EC2::VolumeAttachment
458517
Properties:
459518
InstanceId: !Ref DLEInstance
460519
VolumeId: !Ref ZFSVolume
461520
Device: /dev/xvdh
521+
522+
DLEElasticIP:
523+
Type: AWS::EC2::EIP
524+
Properties:
525+
Domain: vpc
526+
InstanceId: !Ref DLEInstance
527+
528+
SubDomain:
529+
Type: AWS::Route53::RecordSet
530+
Condition: CreateSubDomain
531+
Properties:
532+
HostedZoneName: !Sub '${CertificateHostedZone}.'
533+
Comment: DNS name for DLE instance.
534+
Name: !Sub '${CertificateSubdomain}.${CertificateHostedZone}'
535+
Type: CNAME
536+
TTL: 60
537+
ResourceRecords:
538+
- !GetAtt DLEInstance.PublicDnsName
539+
DependsOn:
540+
- DLEInstance
541+
- DLEElasticIP
542+
462543
DLESecurityGroup:
463544
Type: 'AWS::EC2::SecurityGroup'
464545
Properties:
@@ -472,24 +553,72 @@ Resources:
472553
- IpProtocol: -1
473554
CidrIp: '0.0.0.0/0'
474555
VpcId: !Ref VPC
556+
557+
DLEUISecurityGroup:
558+
Type: 'AWS::EC2::SecurityGroup'
559+
Condition: CreateSubDomain
560+
Properties:
561+
GroupDescription: Enable ports to access DLE UI
562+
SecurityGroupIngress:
563+
- IpProtocol: tcp
564+
FromPort: 80
565+
ToPort: 80
566+
CidrIp: !Ref SSHLocation
567+
568+
- IpProtocol: tcp
569+
FromPort: 443
570+
ToPort: 443
571+
CidrIp: !Ref SSHLocation
572+
573+
- IpProtocol: tcp
574+
FromPort: 446
575+
ToPort: 446
576+
CidrIp: !Ref SSHLocation
577+
SecurityGroupEgress:
578+
- IpProtocol: -1
579+
CidrIp: '0.0.0.0/0'
580+
VpcId: !Ref VPC
581+
582+
475583
Outputs:
476-
DLEURL:
584+
VerificationToken:
585+
Description: 'DLE verification token'
586+
Value: !Ref DLEVerificationToken
587+
588+
DLE:
477589
Description: URL for newly created DLE instance
478-
Value: !Join
479-
- ''
480-
- - 'http://'
481-
- !GetAtt
482-
- DLEInstance
483-
- PublicDnsName
484-
DLETunneling:
485-
Description: To connect to DLE istance you may use tunnel
486-
Value: !Join
487-
- ''
488-
- - 'ssh -N -L 2345:'
489-
- !GetAtt
490-
- DLEInstance
491-
- PublicDnsName
492-
- ':2345 -i YOUR_PRIVATE_KEY ubuntu@'
493-
- !GetAtt
494-
- DLEInstance
495-
- PublicDnsName
590+
Value: !Sub 'https://${CertificateSubdomain}.${CertificateHostedZone}'
591+
Condition: CreateSubDomain
592+
593+
UI:
594+
Description: UI URL with a domain for newly created DLE instance
595+
Value: !Sub 'https://${CertificateSubdomain}.${CertificateHostedZone}:446'
596+
Condition: CreateSubDomain
597+
598+
DNSName:
599+
Description: Public DNS name
600+
Value: !GetAtt DLEInstance.PublicDnsName
601+
602+
EC2SSH:
603+
Description: SSH connection to the EC2 instance with Database Lab Engine
604+
Value: !Sub
605+
- 'ssh -i YOUR_PRIVATE_KEY ubuntu@${DNSName}'
606+
- DNSName: !GetAtt DLEInstance.PublicDnsName
607+
608+
DLETunnel:
609+
Description: Create an SSH-tunnel to Database Lab Engine
610+
Value: !Sub
611+
- 'ssh -N -L 2345:${DNSName}:2345 -i YOUR_PRIVATE_KEY ubuntu@${DNSName}'
612+
- DNSName: !GetAtt DLEInstance.PublicDnsName
613+
614+
UITunnel:
615+
Description: Create an SSH-tunnel to Database Lab UI
616+
Value: !Sub
617+
- 'ssh -N -L 2346:${DNSName}:2346 -i YOUR_PRIVATE_KEY ubuntu@${DNSName}'
618+
- DNSName: !GetAtt DLEInstance.PublicDnsName
619+
620+
CloneTunnel:
621+
Description: Create an SSH-tunnel to Database Lab clones
622+
Value: !Sub
623+
- 'ssh -N -L CLONE_PORT:${DNSName}:CLONE_PORT -i YOUR_PRIVATE_KEY ubuntu@${DNSName}'
624+
- DNSName: !GetAtt DLEInstance.PublicDnsName

‎packer/install-dblabcli.sh

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
set -x
44
sudo su - ubuntu
55
mkdir ~/.dblab
6-
curl https://gitlab.com/postgres-ai/database-lab/-/raw/$dle_version/scripts/cli_install.sh | bash
6+
curl https://gitlab.com/postgres-ai/database-lab/-/raw/$dle_version/engine/scripts/cli_install.sh | bash
77
sudo mv ~/.dblab/dblab /usr/local/bin/dblab
88
echo $dle_version > ~/.dblab/dle_version
99

1010
# Copy base templates
11-
curl https://gitlab.com/postgres-ai/database-lab/-/raw/$dle_version/configs/config.example.logical_generic.yml --output ~/.dblab/config.example.logical_generic.yml
12-
curl https://gitlab.com/postgres-ai/database-lab/-/raw/$dle_version/configs/config.example.logical_rds_iam.yml --output ~/.dblab/config.example.logical_rds_iam.yml
13-
curl https://gitlab.com/postgres-ai/database-lab/-/raw/$dle_version/configs/config.example.physical_generic.yml --output ~/.dblab/config.example.physical_generic.yml
14-
curl https://gitlab.com/postgres-ai/database-lab/-/raw/$dle_version/configs/config.example.physical_walg.yml --output ~/.dblab/config.example.physical_walg.yml
11+
curl https://gitlab.com/postgres-ai/database-lab/-/raw/$dle_version/engine/configs/config.example.logical_generic.yml --output ~/.dblab/config.example.logical_generic.yml
12+
curl https://gitlab.com/postgres-ai/database-lab/-/raw/$dle_version/engine/configs/config.example.logical_rds_iam.yml --output ~/.dblab/config.example.logical_rds_iam.yml
13+
curl https://gitlab.com/postgres-ai/database-lab/-/raw/$dle_version/engine/configs/config.example.physical_generic.yml --output ~/.dblab/config.example.physical_generic.yml
14+
curl https://gitlab.com/postgres-ai/database-lab/-/raw/$dle_version/engine/configs/config.example.physical_walg.yml --output ~/.dblab/config.example.physical_walg.yml
1515

1616
# Adjust DLE config
1717
dle_config_path="/home/ubuntu/.dblab/engine/configs"
@@ -22,7 +22,7 @@ mkdir -p $dle_config_path
2222
mkdir -p $dle_meta_path
2323
mkdir -p $postgres_conf_path
2424

25-
curl https://gitlab.com/postgres-ai/database-lab/-/raw/${dle_version}/configs/config.example.logical_generic.yml --output $dle_config_path/server.yml
26-
curl https://gitlab.com/postgres-ai/database-lab/-/raw/${dle_version}/configs/standard/postgres/control/pg_hba.conf \
25+
curl https://gitlab.com/postgres-ai/database-lab/-/raw/${dle_version}/engine/configs/config.example.logical_generic.yml --output $dle_config_path/server.yml
26+
curl https://gitlab.com/postgres-ai/database-lab/-/raw/${dle_version}/engine/configs/standard/postgres/control/pg_hba.conf \
2727
--output $postgres_conf_path/pg_hba.conf
28-
curl https://gitlab.com/postgres-ai/database-lab/-/raw/${dle_version}/configs/standard/postgres/control/postgresql.conf --output $postgres_conf_path/postgresql.conf
28+
curl https://gitlab.com/postgres-ai/database-lab/-/raw/${dle_version}/engine/configs/standard/postgres/control/postgresql.conf --output $postgres_conf_path/postgresql.conf

‎packer/template.json.pkr.hcl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ data "amazon-ami" "base" {
2121
}
2222

2323
source "amazon-ebs" "base" {
24-
ami_description = "Ubuntu 20.04 with ZFS, Docker, Envoy proxy and Database Lab Engine 3.0 with client CLI."
24+
ami_description = "Ubuntu 20.04 with ZFS, Docker, Envoy proxy and Database Lab Engine 3.1 with client CLI."
2525
ami_name = "${var.ami_name_prefix}-${var.dle_version}-${formatdate("YYYY-MM-DD", timestamp())}-${uuidv4()}"
2626
instance_type = "t2.large"
2727
source_ami = "${data.amazon-ami.base.id}"
@@ -53,4 +53,7 @@ build {
5353
scripts = ["${path.root}/install-prereqs.sh", "${path.root}/install-envoy.sh","${path.root}/install-dblabcli.sh"]
5454
}
5555

56+
provisioner "shell" {
57+
inline = ["echo 'remove authorized keys'", "sudo rm /home/ubuntu/.ssh/authorized_keys", "sudo rm /root/.ssh/authorized_keys"]
58+
}
5659
}

0 commit comments

Comments
 (0)
Please sign in to comment.