We are using AWS SecretsManager (SM) to store a rotating database password for our rails app. However, when SM rotates the password, we get "FATAL: password authentication failed for user".
The password is read in database.yml
password: '<%= AwsSecretService.new.get_db_pwd(ENV['DATABASE_USERNAME']) if Rails.env.production? %>'
The problem appears to be that ActiveRecord is caching the database credentials from database.yml upon initialization and does not reparse database.yml.
My thought is to somehow trap the authentication failed error and reinitialize ActiveRecord. With the following command:
ActiveRecord::Base.establish_connection(::Rails.application.config.database_configuration[::Rails.env])
I'm not sure how to trap the error. Would I need to put an error handler in application_record.rb since all activerecord models inherit from it?
Or would it be better to use an Observer of some sort?
Ideas?
I'm working on this too and am encountering the same issue. It seems that Rails only reads in the password once at application startup. If the password is then rotated, some connections will succeed if they were already established, but new connections in the pool will fail because they'll try to use the now-outdated password.
If it were possible for Rails to be forced to create all the connections in the pool at startup, this would work. Alternatively, if it were possible for Rails to dynamically pull the password each time a new connection were established, that would also work.
However, I've not found the ability to do either thing.