Skip to content

Commit

Permalink
more documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Nemo64 committed Mar 1, 2020
1 parent d633f96 commit 5a5f0a0
Showing 1 changed file with 75 additions and 4 deletions.
79 changes: 75 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
This is a driver to use the aws [rds-data] api on projects
that are using dbal for their database access.

It emulates a MySQL connection including transactions.
However: the driver does never establish a persistent connection.

This is experimental. I implemented it in a symfony project
with the doctrine orm and with this driver it worked fine.
I tested the schema tools, migrations and transactions.
Expand All @@ -17,24 +20,40 @@ I tested the schema tools, migrations and transactions.
- The data api makes it possible to use a database in an aws hosting environment
without the need for VPC's which are not that easy to set up,
might cost money if you need internet access
and slow down lambda function starts (which is possible using [bref]).
and slow down lambda function starts
(which you can run php on using custom runtimes like [bref]).
- Your application does not need the database password in plain text.
You just need access to the aws api which can be managed a lot better.
(there are other ways to achieve the same but still, it is really easy with the data api)
- There might be a performance benefit due to not needing to establish
a direct database connection and automatic pool management
(which is unheard of in the php world)
(which is unheard of in the php world).

## Why wouldn't you use it?

- This implementation isn't well tested. Be prepared for problems.
- The [rds-data] api has size restrictions in the [ExecuteStatement] call
which might become a problem when your application grows.
I have ideas how to work around that but there is nothing implemented yet.
- The [rds-data] api is currently only available in [a few regions].
- The [rds-data] api is currently only available in [a few regions]. This limitation can be lifted any day though.
However, at the moment of writing this, there is only 1 region in europe available.
- The [rds-data] api is only available with [Aurora Serverless] and this library also limits you to MySQL mode.
If you plan on using other databases then you can't use the rds-data api and this library (yet).
Here are alternatives you might want to consider:
- Aurora Serverless in Postgres mode (although this can probably very easily be added here, I'm open to pull requests)
- Aurora Classic to get an [SLA] or to benefit from reserved instance pricing on predictable workloads
- Aurora Global for better availability and all the benefits of Aurora Classic
- or even normal RDS to save money or use engines that are not emulated by Aurora

All those disadvantages are not inherit to the new technology and can be removed
either by progress from AWS or by progress on this library.

## How to use it

First you must store your database credentials as [a secret] including the username.
Then make sure to correctly configure [access to your database] to use the secret and the database.
If you create a iam user then there is a "AmazonRDSDataFullAccess" policy that can be used directly.

If you use dbal directly than this is the way:

```php
Expand Down Expand Up @@ -66,7 +85,7 @@ doctrine:

# you must not include a driver in the database url
# in this case I also didn't include the aws tokens in the url
DATABASE_URL=//eu-west-1/mydb
DATABASE_URL=//eu-west-1/mydb?driverOptions[resourceArn]=arn&&driverOptions[secretArn]=arn

# the aws-sdk will pick those up
# they are automatically configured in lambda and ec2 environments
Expand All @@ -77,8 +96,60 @@ DATABASE_URL=//eu-west-1/mydb

Other than the configuration it should work exactly like any other dbal connection.

### CloudFormation

Sure, here is a CloudFormation template to configure [Aurora Serverless] and a [Secret],
putting both together and setting an environment variable with the needed information.

```yaml

# [...]
environment:
DATABASE_URL: !Join
- ''
- - '//' # rds-data is set to default because custom drivers can't be named in a way that they can be used here
- !Ref AWS::Region # the hostname is the region
- '/database'
- '?driverOptions[resourceArn]='
- !Join [':', ['arn:aws:rds', !Ref AWS::Region, !Ref AWS::AccountId, 'cluster', !Ref Database]]
- '&driverOptions[secretArn]='
- !Ref DatabasePassword

# [...]

# Make sure that there is a default VPC in your account.
# https://console.aws.amazon.com/vpc/home#vpcs:isDefault=true
# If not, click "Actions" > "Create Default VPC"
# While your applications doesn't need it, the database must still be provisioned into a VPC so use the default.
Database:
Type: AWS::RDS::DBCluster # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-rds-dbcluster.html
Properties:
Engine: aurora
EngineMode: serverless
EnableHttpEndpoint: true # https://stackoverflow.com/a/58759313 (not fully documented in every language yet)
DatabaseName: 'database'
MasterUsername: !Join ['', ['{{resolve:secretsmanager:', !Ref DatabasePassword, ':SecretString:username}}']]
MasterUserPassword: !Join ['', ['{{resolve:secretsmanager:', !Ref DatabasePassword, ':SecretString:password}}']]
BackupRetentionPeriod: 1 # day
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-rds-dbcluster-scalingconfiguration.html
ScalingConfiguration: {MinCapacity: 1, MaxCapactiy: 2, AutoPause: true}
DatabasePassword:
Type: AWS::SecretsManager::Secret # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-secretsmanager-secret.html
Properties:
GenerateSecretString:
SecretStringTemplate: '{"username": "admin"}'
GenerateStringKey: "password"
PasswordLength: 41 # max length of a mysql password
ExcludeCharacters: '"@/\'
```
[rds-data]: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html
[bref]: https://bref.sh/
[ExecuteStatement]: https://docs.aws.amazon.com/rdsdataservice/latest/APIReference/API_ExecuteStatement.html
[a few regions]: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html#data-api.regions
[Aurora Serverless]: https://aws.amazon.com/de/rds/aurora/serverless/
[SLA]: https://aws.amazon.com/de/rds/aurora/sla/
[access to your database]: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html#data-api.access
[a secret]: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html#data-api.secrets
[Secret]: https://aws.amazon.com/de/secrets-manager/

0 comments on commit 5a5f0a0

Please sign in to comment.