Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
max-line-length=88
81 changes: 76 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ This CDK Construct enables provisioning an RDS Database (and optionally a DB Ser
```python
import os
from aws_cdk import (
Duration,
aws_ec2 as ec2,
aws_rds as rds,
aws_lambda as lambda_,
)

from constructs import Construct

from cdk_bootstrapped_db.helpers import create_database_server
from cdk_bootstrapped_db.constructs import BootstrappedDb


Expand All @@ -24,7 +22,6 @@ class MyDatabase(Construct):
self,
scope: Construct,
id: str,
name: str,
secrets_prefix: str,
db_server: rds.DatabaseInstance,
vpc: ec2.IVpc,
Expand Down Expand Up @@ -66,7 +63,6 @@ This package comes with a helper function for setting up a new RDS server. The a
```python
import os
from aws_cdk import (
Duration,
aws_ec2 as ec2,
aws_rds as rds,
aws_lambda as lambda_,
Expand All @@ -83,7 +79,6 @@ class MyDatabase(Construct):
self,
scope: Construct,
id: str,
name: str,
secrets_prefix: str,
vpc: ec2.IVpc,
**kwargs,
Expand Down Expand Up @@ -126,3 +121,79 @@ class MyDatabase(Construct):

self.db_connection_secret = self.db.secret
```

### Creating an RDS Server from a Snapshot

If you have a snapshot of an RDS Server that you wish to restore in a new deployment, you can pass in the optional parameter
`db_snapshot_arn` to `create_database_server` instead of using `db_name`.

This snapshot must reside in the region you're deploying into, you can copy a snapshot across regions following these docs:
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_CopySnapshot.html

By default, the created server will use the admin username of `postgres` - If the RDS Server your snapshot is from used a
different admin username, you can provide it with the parameter `db_snapshot_admin_username`.

This whole scenario is shown below:

```python
import os
from aws_cdk import (
aws_ec2 as ec2,
aws_rds as rds,
aws_lambda as lambda_,
)

from constructs import Construct

from cdk_bootstrapped_db.helpers import create_database_server
from cdk_bootstrapped_db.constructs import BootstrappedDb


class MyDatabase(Construct):
def __init__(
self,
scope: Construct,
id: str,
secrets_prefix: str,
vpc: ec2.IVpc,
**kwargs,
):
super().__init__(scope, id, **kwargs)

self.db_server = create_database_server(
self,
"MyDBServer",
identifier="mydbserver",
vpc=vpc,
db_snapshot_arn="arn:aws:rds:us-west-2:123456789012:snapshot:mysql-instance1-snapshot-20130805",
db_snapshot_admin_username="myadminusername",
db_version=rds.PostgresEngineVersion.VER_14,
instance_type=ec2.InstanceType.of(
ec2.InstanceClass.BURSTABLE4_GRAVITON, ec2.InstanceSize.NANO
),
)

db_setup_handler = lambda_.Function(
self,
"RunMigrations",
handler="handler.handler",
runtime=lambda_.Runtime.PYTHON_3_8,
code=lambda_.Code.from_docker_build(
path=os.path.abspath("."),
file="Dockerfile",
),
vpc=vpc,
)

self.db = BootstrappedDb(
self,
"MyDB",
db=self.db_server,
new_dbname="mydb",
new_username="mydbuser",
secrets_prefix=secrets_prefix,
handler=db_setup_handler,
)

self.db_connection_secret = self.db.secret
```
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.1.0
3.0.0
17 changes: 10 additions & 7 deletions cdk_bootstrapped_db/constructs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import json
import os
from datetime import datetime
from typing import Optional, Union

from aws_cdk import (
Expand Down Expand Up @@ -56,7 +55,9 @@ def __init__(
secret_string_template=json.dumps(
{
"dbname": new_dbname,
"engine": db_engine if db_engine else db.engine.engine_type, # type: ignore
"engine": db_engine
if db_engine
else db.engine.engine_type, # type: ignore
"port": db.instance_endpoint.port,
"host": db.instance_endpoint.hostname,
"username": new_username,
Expand All @@ -83,7 +84,9 @@ def __init__(
secret_string_template=json.dumps(
{
"dbname": new_dbname,
"engine": db_engine if db_engine else db.engine.engine_type, # type: ignore
"engine": db_engine
if db_engine
else db.engine.engine_type, # type: ignore
"port": db.instance_endpoint.port,
"host": db.instance_endpoint.hostname,
"username": read_only_username,
Expand All @@ -92,7 +95,7 @@ def __init__(
generate_string_key="password",
exclude_punctuation=True,
),
description=f"Read-only user secret deployed by {Stack.of(self).stack_name}",
description=f"Read-only user secret deployed by {Stack.of(self).stack_name}", # noqa: E501
)

self.provider = custom_resources.Provider(
Expand All @@ -108,9 +111,9 @@ def __init__(

# Optionally include the read-only secret ARN
if self.read_only_secret:
resource_properties["read_only_user_secret_arn"] = (
self.read_only_secret.secret_arn
)
resource_properties[
"read_only_user_secret_arn"
] = self.read_only_secret.secret_arn

self.resource = CustomResource(
scope=scope,
Expand Down
5 changes: 4 additions & 1 deletion cdk_bootstrapped_db/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ def create_database_server(
vpc: ec2.IVpc,
subnet_selection: ec2.SubnetSelection,
deletion_protect: bool,
# Default admin username for Postgres is "postgres" for rds.DatabaseInstance
# https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_rds/DatabaseInstance.html#aws_cdk.aws_rds.DatabaseInstance
db_snapshot_admin_username: str = "postgres",
db_name: Optional[str] = None,
db_snapshot_arn: Optional[str] = None,
db_version: Optional[rds.PostgresEngineVersion] = None,
Expand Down Expand Up @@ -51,7 +54,7 @@ def create_database_server(
**params,
snapshot_identifier=db_snapshot_arn,
credentials=rds.SnapshotCredentials.from_generated_password(
username="superuser"
username=db_snapshot_admin_username
),
)

Expand Down