|
1 | | -# Aurora DSQL Ruby on Rails code examples |
| 1 | +# Ruby on Rails with Aurora DSQL |
| 2 | +This example demonstrates how to use an Aurora DSQL cluster with a Ruby On Rails |
| 3 | +application. Aurora DSQL only supports token-based authentication so we extend the |
| 4 | +[`pg-aws_rds_iam`][rds-plugin-repo] plugin to generate Aurora DSQL auth tokens |
| 5 | +when required. |
| 6 | + |
| 7 | +It also includes changes to ActiveRecord behavior to be compatible with Aurora DSQL |
| 8 | +supported features. |
| 9 | + |
| 10 | +[rds-plugin-repo]: https://github.com/haines/pg-aws_rds_iam |
| 11 | + |
| 12 | +## Running this example |
| 13 | +See [`petclinic/README.md`](./petclinic/README.md). |
| 14 | + |
| 15 | +## Using Aurora DSQL authentication tokens with Rails |
| 16 | +These are the changes to make to your Rails application to be compatible with Aurora DSQL. |
| 17 | + |
| 18 | +### Add a token generator |
| 19 | +To modify your Rails application to work with Aurora DSQL you should reproduce the |
| 20 | +`DsqlAuthTokenGenerator` in [`adapter.rb`][file-adapter]. |
| 21 | + |
| 22 | +```ruby |
| 23 | +require "aws-sdk-dsql" |
| 24 | + |
| 25 | +class DsqlAuthTokenGenerator |
| 26 | + def call(host:, port:, user:) |
| 27 | + # e.g. host == "<clusterID>.dsql.us-east-1.on.aws" |
| 28 | + region = host.split(".")[2] |
| 29 | + raise "Unable to extract AWS region from host '#{host}'" unless region =~ /[\w\d-]+/ |
| 30 | + |
| 31 | + token_generator = Aws::DSQL::AuthTokenGenerator.new( |
| 32 | + credentials: Aws::CredentialProviderChain.new.resolve, |
| 33 | + ) |
| 34 | + |
| 35 | + auth_token_params = { |
| 36 | + endpoint: host, |
| 37 | + region: region, |
| 38 | + expires_in: 15 * 60 # 15 minutes, optional |
| 39 | + } |
| 40 | + |
| 41 | + case user |
| 42 | + when "admin" |
| 43 | + token_generator.generate_db_connect_admin_auth_token(auth_token_params) |
| 44 | + else |
| 45 | + token_generator.generate_db_connect_auth_token(auth_token_params) |
| 46 | + end |
| 47 | + end |
| 48 | +end |
| 49 | +``` |
2 | 50 |
|
3 | | -## Overview |
| 51 | +`call` will be invoked when a new database connection is requested. It will: |
| 52 | +1. Retrieve credentials for the running environment. The `Aws::CredentialProviderChain` discovers credentials |
| 53 | + in the order described in [these docs][docs-cred-provider]. |
| 54 | +1. Determine which token type to generate based on the database user. |
4 | 55 |
|
5 | | -The code examples in this topic show you how to use the Ruby on Rails work with Aurora DSQL. |
| 56 | +The retrieved credentials will need permission to `dsql:DbConnectAdmin` for the `admin` user or |
| 57 | +`dsql:DbConnect` for a custom user. See Aurora DSQL documentation for [IAM role connect][docs-dsql-iam] |
| 58 | +and [authentication token generation][docs-generate-token] for more details. |
6 | 59 |
|
7 | | -## Run the examples |
8 | 60 |
|
9 | | -### Prerequisites |
| 61 | +Finally, register the adapter with the `pg-aws_rds_iam` plugin. |
| 62 | +```ruby |
| 63 | +PG::AWS_RDS_IAM.auth_token_generators.add :dsql do |
| 64 | + DsqlAuthTokenGenerator.new |
| 65 | +end |
| 66 | +``` |
10 | 67 |
|
11 | | -* ruby version == 3.3.5 is needed |
12 | | -* AWS credentials file is configured |
| 68 | +[file-adapter]: ./petclinic/config/initializers/adapter.rb |
| 69 | +[docs-cred-provider]: https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/credential-providers.html |
| 70 | +[docs-dsql-iam]: https://docs.aws.amazon.com/aurora-dsql/latest/userguide/authentication-authorization.html#authentication-authorization-iam-role-connect |
| 71 | +[docs-generate-token]: https://docs.aws.amazon.com/aurora-dsql/latest/userguide/SECTION_authentication-token.html |
13 | 72 |
|
14 | | -### Setup test running environment |
| 73 | +### Alter ActiveRecord behavior |
| 74 | +Disable features not supported by Aurora DSQL. The example includes this in [`adapter.rb`][file-adapter]. |
15 | 75 |
|
16 | | -Install ruby 3.3.5 for Cloud Desktop: |
17 | | -``` |
18 | | -sudo yum install -y libyaml-devel |
19 | | -rbenv install 3.3.5 |
20 | | -``` |
| 76 | +```ruby |
| 77 | +require "active_record/connection_adapters/postgresql/schema_statements" |
| 78 | + |
| 79 | +module ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements |
| 80 | + # DSQL does not support setting min_messages in the connection parameters |
| 81 | + def client_min_messages=(level); end |
| 82 | +end |
21 | 83 |
|
22 | | -### Run the example tests |
23 | | -Open a Ruby on Rails app console to manually test console commands: |
| 84 | +require "active_record/connection_adapters/postgresql_adapter" |
24 | 85 |
|
| 86 | +class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter |
| 87 | + def set_standard_conforming_strings; end |
| 88 | + |
| 89 | + # Avoid error running multiple DDL or DDL + DML statements in the same transaction |
| 90 | + def supports_ddl_transactions? |
| 91 | + false |
| 92 | + end |
| 93 | +end |
25 | 94 | ``` |
26 | | -# Use the account credentials dedicated for Ruby on Rails |
27 | 95 |
|
28 | | -# Download the Amazon root certificate from the official trust store |
29 | | -# This example shows one of the available certs that can be used by the client; |
30 | | -# other certs such as AmazonRootCA2.pem, AmazonRootCA3.pem, etc. can also be used. |
31 | | -wget https://www.amazontrust.com/repository/AmazonRootCA1.pem -O root.pem |
| 96 | +### Use the adapter in the database configuration |
| 97 | +Refer to [`database.yml`](./petclinic/config/database.yml). |
| 98 | +
|
| 99 | +```yml |
| 100 | +development: |
| 101 | + <<: *default |
| 102 | + |
| 103 | + # Always the database name for Aurora DSQL |
| 104 | + database: postgres |
| 105 | + |
| 106 | + # eg: admin or other postgres users |
| 107 | + username: <postgres username> |
| 108 | + |
| 109 | + # Set this value based on the access of the configured user, |
| 110 | + # or omit if running as 'admin' and using the 'public' schema. |
| 111 | + schema_search_path: myschema |
32 | 112 |
|
33 | | -export CLUSTER_ENDPOINT="<your cluster endpoint from us-east-1>" |
34 | | -cd petclinic |
35 | | -bundle install |
| 113 | + # Set to Aurora DSQL instance endpoint |
| 114 | + # Use environment variables, etc for production values! |
| 115 | + # e.g. {clusterId}.dsql.{region}.on.aws |
| 116 | + host: foo0bar1baz2quux3quuux4.dsql.us-east-1.on.aws |
36 | 117 |
|
37 | | -# Generate the schema from the model files in db/migrate. |
38 | | -bin/rails db:migrate |
| 118 | + # Use the custom token generator we created |
| 119 | + aws_rds_iam_auth_token_generator: dsql |
39 | 120 |
|
40 | | -# Start the rails console |
41 | | -bin/rails console |
| 121 | + # Provide the path to the root certificate. |
| 122 | + # Amazon's root certs can be fetched from https://www.amazontrust.com/repository/ |
| 123 | + sslrootcert: <replace with the path to root certificate> |
| 124 | + sslmode: verify-full |
42 | 125 |
|
| 126 | + # More DSQL compatibility tweaks |
| 127 | + advisory_locks: false |
| 128 | + prepared_statements: false |
43 | 129 | ``` |
44 | 130 |
|
45 | 131 | --- |
46 | 132 |
|
47 | | -Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| 133 | +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
48 | 134 |
|
49 | 135 | SPDX-License-Identifier: MIT-0 |
0 commit comments