RDS(PostgreSQL)におけるデータベース所有者設定でのエラー回避方法

はじめに

RDSにてPostgreSQLを使っているとき、マスターユーザーとは別のユーザーを作ってそのユーザがオーナーのデータベースを作ろうとするとERROR: must be member of role "xxxxx"というメッセージが出ることがあります。例を以下に記します。

postgres=> CREATE ROLE testuser001 WITH PASSWORD 'hogehogehoge' LOGIN;
CREATE ROLE
postgres=> CREATE DATABASE mytestdb001 WITH OWNER testuser001;
ERROR:  must be member of role "testuser001"
postgres=> 

この状態の原因と対策を以下に記します。

原因

RDSのマスターユーザー(ここではpostgres)にSuperuserが付与されていないのが原因です。\duにて権限を見てみます。

postgres=> \du
                                                                                        List of roles
    Role name    |                         Attributes                         |                                                  Member of

-----------------+------------------------------------------------------------+--------------------------------------------------------------------------------------------------------
------
 postgres        | Create role, Create DB                                    +| {rds_superuser}
                 | Password valid until infinity                              |
 rds_ad          | Cannot login                                               | {}
 rds_iam         | Cannot login                                               | {}
 rds_password    | Cannot login                                               | {}
 rds_replication | Cannot login                                               | {}
 rds_superuser   | Cannot login                                               | {pg_read_all_data,pg_write_all_data,pg_monitor,pg_signal_backend,pg_checkpoint,rds_replication,rds_pass
word}
 rdsadmin        | Superuser, Create role, Create DB, Replication, Bypass RLS+| {}
                 | Password valid until infinity                              |
 rdsrepladmin    | No inheritance, Cannot login, Replication                  | {}
 rdstopmgr       |                                                            | {pg_monitor,pg_checkpoint}

postgres=>

このようにマスターユーザー(postgres)にはSuperuserが付与されておらず、RDS固有のロールであるrdsadminにSuperuserが付与されています。

対策

マスターユーザー(postgres)が新たに作成したユーザー(testuser001)のメンバにしてあげればOKです。

postgres=> GRANT testuser001 TO postgres;
GRANT ROLE
postgres=>

これで、当初の目的であるマスターユーザーとは別のユーザーを作ってそのユーザがオーナーのデータベースを作ることができます。

postgres=> CREATE DATABASE mytestdb001 WITH OWNER testuser001;
CREATE DATABASE
postgres=>

\lにて確認してみます。

postgres=> \l
                                                    List of databases
    Name     |    Owner    | Encoding |   Collate   |    Ctype    | ICU Locale | Locale Provider |   Access privileges
-------------+-------------+----------+-------------+-------------+------------+-----------------+-----------------------
 mytestdb001 | testuser001 | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            |
 postgres    | postgres    | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            |
 rdsadmin    | rdsadmin    | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | rdsadmin=CTc/rdsadmin+
             |             |          |             |             |            |                 | rdstopmgr=Tc/rdsadmin
 template0   | rdsadmin    | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | =c/rdsadmin          +
             |             |          |             |             |            |                 | rdsadmin=CTc/rdsadmin
 template1   | postgres    | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | =c/postgres          +
             |             |          |             |             |            |                 | postgres=CTc/postgres
(6 rows)

postgres=>

オンプレミスのPostgreSQLですとこのようなことはなかった気がしますので、念の為記録しておきます。

考察

上記ではrdsadminの詳細についてスルーしましたが、詳細はAWSの以下のドキュメントに記されています。

docs.aws.amazon.com

オンプレミスのPostgreSQLと同じノリで操作するとこういうところでつまづくので、上記のようなドキュメントには目を通しておいた方が良いかなと考えています。

参考

この記事を書くためにAWS re:Postを検索すると以下の記事がヒットしました。

repost.aws

むやみに権限を付与しなくてもよいかなと思いますが、対策の一つとしてよいかなと考えています。