|
3 | 3 | [](https://travis-ci.org/jameshy/pgdump-aws-lambda)
|
4 | 4 | [](https://coveralls.io/github/jameshy/pgdump-aws-lambda?branch=master)
|
5 | 5 |
|
6 |
| -# Overview |
7 |
| - |
8 | 6 | An AWS Lambda function that runs pg_dump and streams the output to s3.
|
9 | 7 |
|
10 | 8 | It can be configured to run periodically using CloudWatch events.
|
11 | 9 |
|
12 | 10 | ## Quick start
|
13 | 11 |
|
14 | 12 | 1. Create an AWS lambda function:
|
15 |
| - - Runtime: Node.js 6.10 |
16 |
| - - Code entry type: Upload a .ZIP file |
17 |
| - ([pgdump-aws-lambda.zip](https://github.com/jameshy/pgdump-aws-lambda/releases/download/v1.1.5/pgdump-aws-lambda.zip)) |
18 |
| - - Configuration -> Advanced Settings |
19 |
| - - Timeout = 5 minutes |
20 |
| - - Select a VPC and security group (must be suitable for connecting to the target database server) |
21 |
| -2. Create a CloudWatch rule: |
22 |
| - - Event Source: Fixed rate of 1 hour |
23 |
| - - Targets: Lambda Function (the one created in step #1) |
24 |
| - - Configure input -> Constant (JSON text) and paste your config, e.g.: |
| 13 | + - Author from scratch |
| 14 | + - Runtime: Node.js 12.x |
| 15 | +2. Configuration -> Function code: |
| 16 | + - Code Entry Type: Upload a .zip file |
| 17 | + - Upload ([pgdump-aws-lambda.zip](https://github.com/jameshy/pgdump-aws-lambda/releases/latest)) |
| 18 | + - Basic Settings -> Timeout: 15 minutes |
| 19 | + - Save |
| 20 | +3. Configuration -> Execution role |
| 21 | + - Edit the role and attach the policy "AmazonS3FullAccess" |
| 22 | +4. Test |
| 23 | + - Create new test event, e.g.: |
25 | 24 | ```json
|
26 | 25 | {
|
27 |
| - "PGDATABASE": "oxandcart", |
28 |
| - "PGUSER": "staging", |
29 |
| - "PGPASSWORD": "uBXKFecSKu7hyNu4", |
30 |
| - "PGHOST": "database.com", |
31 |
| - "S3_BUCKET" : "my-db-backups", |
| 26 | + "PGDATABASE": "dbname", |
| 27 | + "PGUSER": "postgres", |
| 28 | + "PGPASSWORD": "password", |
| 29 | + "PGHOST": "host", |
| 30 | + "S3_BUCKET" : "db-backups", |
32 | 31 | "ROOT": "hourly-backups"
|
33 | 32 | }
|
34 | 33 | ```
|
| 34 | + - *Test* and check the output |
35 | 35 |
|
36 |
| -Note: you can test the lambda function using the "Test" button and providing config like above. |
| 36 | +5. Create a CloudWatch rule: |
| 37 | + - Event Source: Schedule -> Fixed rate of 1 hour |
| 38 | + - Targets: Lambda Function (the one created in step #1) |
| 39 | + - Configure input -> Constant (JSON text) and paste your config (as per step #3) |
37 | 40 |
|
38 |
| -**AWS lambda has a 5 minute maximum execution time for lambda functions, so your backup must take less time that that.** |
39 | 41 |
|
40 |
| -## File Naming |
| 42 | +#### File Naming |
41 | 43 |
|
42 | 44 | This function will store your backup with the following s3 key:
|
43 | 45 |
|
44 | 46 | s3://${S3_BUCKET}${ROOT}/YYYY-MM-DD/[email protected]
|
45 | 47 |
|
46 |
| -## PostgreSQL version compatibility |
| 48 | +#### AWS Firewall |
47 | 49 |
|
48 |
| -This script uses the pg_dump utility from PostgreSQL 9.6.2. |
| 50 | +- If you run the Lambda function outside a VPC, you must enable public access to your database instance, a non VPC Lambda function executes on the public internet. |
| 51 | +- If you run the Lambda function inside a VPC (not tested), you must allow access from the Lambda Security Group to your database instance. Also you must add a NAT gateway to your VPC so the Lambda can connect to S3. |
49 | 52 |
|
50 |
| -It should be able to dump older versions of PostgreSQL. I will try to keep the included binaries in sync with the latest from postgresql.org, but PR or message me if there is a newer PostgreSQL binary available. |
| 53 | +#### Encryption |
51 | 54 |
|
52 |
| -## Encryption |
| 55 | +You can add an encryption key to your event, e.g. |
53 | 56 |
|
54 |
| -You can pass the config option 'ENCRYPTION_PASSWORD' and the backup will be encrypted using aes-256-ctr algorithm. |
55 |
| - |
56 |
| -Example config: |
57 | 57 | ```json
|
58 | 58 | {
|
59 | 59 | "PGDATABASE": "dbname",
|
60 | 60 | "PGUSER": "postgres",
|
61 | 61 | "PGPASSWORD": "password",
|
62 |
| - "PGHOST": "localhost", |
63 |
| - "S3_BUCKET" : "my-db-backups", |
64 |
| - "ENCRYPTION_PASSWORD": "my-secret-password" |
| 62 | + "PGHOST": "host", |
| 63 | + "S3_BUCKET" : "db-backups", |
| 64 | + "ROOT": "hourly-backups", |
| 65 | + "ENCRYPT_KEY": "c0d71d7ae094bdde1ef60db8503079ce615e71644133dc22e9686dc7216de8d0" |
65 | 66 | }
|
66 | 67 | ```
|
67 | 68 |
|
68 |
| -To decrypt these dumps, use the command: |
69 |
| -`openssl aes-256-ctr -d -in ./encrypted-db.backup -nosalt -out unencrypted.backup` |
| 69 | +The key should be exactly 64 hex characters (32 hex bytes). |
| 70 | + |
| 71 | +When this key is present the function will do streaming encryption directly from pg_dump -> S3. |
| 72 | + |
| 73 | +It uses the aes-256-cbc encryption algorithm with a random IV for each backup file. |
| 74 | +The IV is stored alongside the backup in a separate file with the .iv extension. |
| 75 | + |
| 76 | +You can decrypt such a backup with the following bash command: |
| 77 | + |
| 78 | +```bash |
| 79 | +openssl enc -aes-256-cbc -d \ |
| 80 | + |
| 81 | + |
| 82 | +-K c0d71d7ae094bdde1ef60db8503079ce615e71644133dc22e9686dc7216de8d0 \ |
| 83 | + |
| 84 | +``` |
| 85 | + |
| 86 | + |
| 87 | +## Developer |
70 | 88 |
|
71 |
| -## Loading your own `pg_dump` binary |
72 |
| -1. Spin up an Amazon AMI image on EC2 (since the lambda function will run |
73 |
| - on Amazon AMI image, based off of CentOS, using it would have the |
74 |
| -best chance of being compatible) |
75 |
| -2. Install PostgreSQL using yum. You can install the latest version from the [official repository](https://yum.postgresql.org/repopackages.php#pg96). |
76 |
| -3. Add a new directory for your pg_dump binaries: `mkdir bin/postgres-9.5.2` |
| 89 | +#### Bundling a new `pg_dump` binary |
| 90 | +1. Launch an EC2 instance with the Amazon Linux 2 AMI |
| 91 | +2. Connect via SSH and (Install PostgreSQL using yum)[https://stackoverflow.com/questions/55798856/deploy-postgres11-to-elastic-beanstalk-requires-etc-redhat-release]. |
| 92 | +3. Locally, create a new directory for your pg_dump binaries: `mkdir bin/postgres-11.6` |
77 | 93 | 3. Copy the binaries
|
78 |
| - - `scp -i YOUR-ID.pem ec2-user@AWS_IP:/usr/bin/pg_dump ./bin/postgres-9.5.2/pg_dump` |
79 |
| - - `scp -i YOUR-ID.pem ec2-user@AWS_UP:/usr/lib64/libpq.so.5.8 ./bin/postgres-9.5.2/libpq.so.5` |
80 |
| -4. When calling the handler, pass the env variable PGDUMP_PATH=postgres-9.5.2 to use the binaries in the bin/postgres-9.5.2 directory. |
| 94 | + - `scp -i <aws PEM> ec2-user@<EC2 Instance IP>:/usr/bin/pg_dump ./bin/postgres-11.6/pg_dump` |
| 95 | + - `scp -i <aws PEM> ec2-user@<EC2 Instance IP>:/usr/lib64/{libcrypt.so.1,libnss3.so,libsmime3.so,libssl3.so,libsasl2.so.3,liblber-2.4.so.2,libldap_r-2.4.so.2} ./bin/postgres-11.6/` |
| 96 | + - `scp -i <aws PEM> ec2-user@<EC2 Instance IP>:/usr/pgsql-11/lib/libpq.so.5 ./bin/postgres-11.6/libpq.so.5` |
| 97 | +4. When calling the handler, pass the environment variable `PGDUMP_PATH=postgres-11.6` to use the binaries in the bin/postgres-11.6 directory. |
| 98 | + |
| 99 | +#### Creating a new function zip |
81 | 100 |
|
82 |
| -NOTE: `libpq.so.5.8` is found out by running `ll /usr/lib64/libpq.so.5` |
83 |
| -and looking at where the symlink goes to. |
| 101 | +`npm run deploy` |
84 | 102 |
|
85 |
| -## Contributing |
| 103 | +#### Contributing |
86 | 104 |
|
87 | 105 | Please submit issues and PRs.
|
0 commit comments