ablog

不器用で落着きのない技術者のメモ

Redshift で WLM のワークロードキューとアクセス権限を別のグルーピングで設定する

やりたいこと

  • Redshift のユーザーについて、WLM とアクセス権限を別々のグルーピングを行いたい。
  • WLM のワークロードキューで管理したいユーザー群とアクセス権限が同じユーザー群が異なるグルーピングになるため。

実装方法

  • WLM(Workload Mangagement)のワークロードキューはユーザーグループで設定し、アクセス権限制御はロールで設定する。
  • RBAC(Role Based Access Control)のアクセス権限機能(階層構造と継承など)を利用できるため、アクセス権限制御はロールを用いる。
  • WLM 以下の理由でグループを使用する
    • ロールはアクセス権限制御を行うための機能のため。例えば、
      GRANT ROLE ロール名 TO ユーザー名
      で設定するが、グループは
      create user ユーザー名 ... in group グループ名
      で設定する。
    • アクセス権限とWLMの管理を人間が見てわかりやすいようグループを使用する。いずれもロールで設定すると、ユーザーが GRANT されているロールのどれがアクセス権限制御用ロールでどれがWLMのワークロードキュー用ロールか判断できない(ロール名の命名規則やロールの定義を見ればわかるが)。

検証ポイント

  • ロールで設定通りのアクセス制御が行われること
  • グループでWLM制御が行われること
構成要素(グループ・ユーザー・ロール・スキーマ・テーブル)
  • ユーザーグループ
    • batch_group
      • batch_user_01
      • batch_user_02
    • adhoc_user_group
      • individual_user_01
      • individual_user_02
  • ロール
    • system_role
      • batch_user_01
      • batch_user_02
    • individual_role
      • individual_user_01
      • individual_user_02
  • スキーマ
    • system_schema
    • individual_schema
  • テーブル
    • system_role がアクセスできるテーブル
      • system_schema.stg_tbl_01
      • system_schema.dwh_tbl_01
    • individual_role がアクセスできるテーブル
      • individual_schema.wrk_tbl_01
      • individual_schema.wrk_tbl_02

DDL

  • グループ
CREATE GROUP batch_group;
CREATE GROUP adhoc_user_group;
  • ユーザー
# バッチユーザー
CREATE USER batch_user_01 PASSWORD 'Password123!' IN GROUP batch_group;
CREATE USER batch_user_02 PASSWORD 'Password123!' IN GROUP batch_group;
# 個人ユーザー
CREATE USER individual_user_01 PASSWORD 'Password123!' IN GROUP adhoc_user_group;
CREATE USER individual_user_02 PASSWORD 'Password123!' IN GROUP adhoc_user_group;
create schema system_schema;
create schema individual_schema;
  • テーブル
CREATE TABLE system_schema.stg_tbl_01 (col1 VARCHAR(20)); # stg_tbl_01
CREATE TABLE system_schema.dwh_tbl_01 (col1 VARCHAR(20)); # dwh_tbl_01
CREATE TABLE individual_schema.wrk_tbl_01 (col1 VARCHAR(20)); # wrk_tbl_01
CREATE TABLE individual_schema.wrk_tbl_02 (col1 VARCHAR(20)); # wrk_tbl_02
  • ロール
# ロールを作成
CREATE ROLE system_role;
CREATE ROLE individual_role;
  • 権限付与
# ロールからスキーマへの権限を付与
GRANT USAGE ON SCHEMA system_schema TO ROLE system_role;
GRANT USAGE ON SCHEMA individual_schema TO ROLE individual_role;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA system_schema TO ROLE system_role;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA individual_schema TO ROLE individual_role;
# ユーザーにロール単位でアクセス権限を付与
GRANT ROLE system_role TO batch_user_01, batch_user_02;
GRANT ROLE individual_role TO individual_user_01, individual_user_02;
  • システムビューで設定を確認する
dev=# SELECT * FROM svv_user_grants;
 user_id |                     user_name                      | role_id |    role_name    | admin_option 
---------+----------------------------------------------------+---------+-----------------+--------------
     181 | dm_admin_user                                      |  372701 | dm_admin_role   | f
     189 | ds:central_db_nsp_b77f35248f9446f9bc61b7d8a3026df5 |  871650 | ds:central_db   | f
     190 | batch_user_01                                      | 1157704 | system_role     | f
     191 | batch_user_02                                      | 1157704 | system_role     | f
     190 | batch_user_01                                      | 1157705 | individual_role | f
     192 | individual_user_01                                 | 1157705 | individual_role | f
     193 | individual_user_02                                 | 1157705 | individual_role | f
(7 rows)

WLM設定

検証結果
  • サービスの機能検証をするわけではないので、網羅的なテストは実施していない。
[ec2-user@ip-172-31-0-101 ~]$ psql "host=redshift-cluster-poc-central.********.ap-northeast-1.redshift.amazonaws.com user=individual_user_01 dbname=dev port=5439" 
Password for user individual_user_01: 
psql (13.7, server 8.0.2)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

dev=> select * from system_schema.stg_tbl_01;
ERROR:  permission denied for schema system_schema
dev=> select * from individual_schema.wrk_tbl_01;
 col1 
------
(0 rows)

dev=> 

参考

ロール・グループ・ユーザーの属性
CREATE ROLE role_name
[ EXTERNALID external_id ]
CREATE GROUP group_name
[ [ WITH ] [ USER username ] [, ...] ]
CREATE USER name [ WITH ]
PASSWORD { 'password' | 'md5hash' | 'sha256hash' | DISABLE }
[ option [ ... ] ]

where option can be:

CREATEDB | NOCREATEDB
| CREATEUSER | NOCREATEUSER
| SYSLOG ACCESS { RESTRICTED | UNRESTRICTED }
| IN GROUP groupname [, ... ]
| VALID UNTIL 'abstime'
| CONNECTION LIMIT { limit | UNLIMITED }
| SESSION TIMEOUT limit
| EXTERNALID external_id
システムビュー
GRANT ROLE role1 TO reguser;
GRANT ROLE role2 TO reguser;
GRANT ROLE role1 TO superuser;
GRANT ROLE role2 TO superuser;

SELECT user_name,role_name,admin_option FROM svv_user_grants;

 user_name | role_name | admin_option
-----------+-----------+--------------
 superuser |  role1    | False
 reguser   |  role1    | False
 superuser |  role2    | False
  reguser  |  role2    | False

インターフェース型VPCエンドポイント(PrivateLink)のスループット

デフォルトでは、各 VPC エンドポイントは、アベイラビリティーゾーンあたり最大 10 Gbps の帯域幅をサポートし、最大 100 Gbps まで自動的にスケールアップします。すべてのアベイラビリティーゾーンに負荷を分散する場合の VPC エンドポイントの最大帯域幅は、アベイラビリティーゾーンの数に 100 Gbps を掛けたものです。アプリケーションでより高いスループットが必要な場合は、 AWS サポートにお問い合わせください。

AWS PrivateLink クォータ - Amazon Virtual Private Cloud

Redshift にRedshift-managed VPCE 経由で接続した場合の stl_connection_log.remotehost に接続元ホストの IP アドレスが入るか

結論としてはリモートホストの IP アドレスが入ることを確認した。

通常のエンドポイントと VPCE 経由の両方で接続する

  • 通常のクラスターエンドポイントから接続して、クエリを発行、切断する。
[ec2-user@ip-172-31-0-101 ~]$ curl http://169.254.169.254/latest/meta-data/hostname
ip-172-31-0-101.ap-northeast-1.compute.internal
[ec2-user@ip-172-31-0-101 ~]$ psql "host=redshift-cluster-poc-central.********.ap-northeast-1.redshift.amazonaws.com user=awsuser dbname=dev port=5439"
psql (13.7, server 8.0.2)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

dev=# select now();
              now
-------------------------------
 2024-06-20 02:32:06.687504+00
(1 row)

dev=# \q
  • Redshift-managed VPC endpoint から接続して、クエリを発行、切断する。
[ec2-user@ip-172-17-3-212 ~]$ curl http://169.254.169.254/latest/meta-data/hostname
ip-172-17-3-212.ap-northeast-1.compute.internal
[ec2-user@ip-172-17-3-212 ~]$ psql "host=rs-vpce-poc-central-public-endpoint-kzi2t4cottw7qieudolz.********.ap-northeast-1.redshift.amazonaws.com user=awsuser dbname=dev port=5439"
psql (13.7, server 8.0.2)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

dev=# select now();
              now
-------------------------------
 2024-06-20 02:33:08.027258+00
(1 row)

dev=# \q

STL_CONNECTION_LOG の remotehost 列を確認する。

ev=# select top 10 event,recordtime,remotehost,remoteport,dbname,username,authmethod from STL_CONNECTION_LOG where remotehost not in ('127.0.0.1', '[local]') orderby recordtime desc;
-[ RECORD 1 ]--------------------------------------------------
event      | disconnecting session
recordtime | 2024-06-20 02:33:09.818793
remotehost | ::ffff:172.17.3.212
remoteport | 33218
dbname     | dev
username   | awsuser
authmethod | password
-[ RECORD 2 ]--------------------------------------------------
event      | set application_name
recordtime | 2024-06-20 02:32:50.64765
remotehost | ::ffff:172.17.3.212
remoteport | 33218
dbname     | dev
username   | awsuser
authmethod | password
-[ RECORD 3 ]--------------------------------------------------
event      | initiating session
recordtime | 2024-06-20 02:32:50.647539
remotehost | ::ffff:172.17.3.212
remoteport | 33218
dbname     | dev
username   | awsuser
authmethod | password
-[ RECORD 4 ]--------------------------------------------------
event      | authenticated
recordtime | 2024-06-20 02:32:50.647434
remotehost | ::ffff:172.17.3.212 ★別VPCのEC2から Redshift-managed VPCE 経由接続した場合、接続元 EC2 のプライベートIPが記録されている
remoteport | 33218
dbname     | dev
username   | awsuser
authmethod | password
-[ RECORD 5 ]--------------------------------------------------
event      | disconnecting session
recordtime | 2024-06-20 02:32:12.746419
remotehost | ::ffff:172.31.0.101 ★同一VPC内のEC2から接続した場合、接続元EC2のプライベートIPが記録されている
remoteport | 52836
dbname     | dev
username   | awsuser
authmethod | password
-[ RECORD 6 ]--------------------------------------------------
event      | set application_name
recordtime | 2024-06-20 02:32:02.845983
remotehost | ::ffff:172.31.0.101
remoteport | 52836
dbname     | dev
username   | awsuser
authmethod | password
-[ RECORD 7 ]--------------------------------------------------
event      | initiating session
recordtime | 2024-06-20 02:32:02.84587
remotehost | ::ffff:172.31.0.101
remoteport | 52836
dbname     | dev
username   | awsuser
authmethod | password
-[ RECORD 8 ]--------------------------------------------------
event      | authenticated
recordtime | 2024-06-20 02:32:02.845774
remotehost | ::ffff:172.31.0.101
remoteport | 52836
dbname     | dev
username   | awsuser
authmethod | password
-[ RECORD 9 ]--------------------------------------------------
event      | disconnecting session
recordtime | 2024-06-20 02:31:36.468434
remotehost | ::ffff:172.31.0.101
remoteport | 42932
dbname     | dev
username   | awsuser
authmethod | password
-[ RECORD 10 ]-------------------------------------------------
event      | set application_name
recordtime | 2024-06-20 02:31:31.169609
remotehost | ::ffff:172.31.0.101
remoteport | 42932
dbname     | dev
username   | awsuser
authmethod | password

Redshift で監査ログを有効化する

マネジメントコンソールで Redshift クラスターを選択し、[プロパティ]-[データベース設定]-[編集]-[監査ログを編集] を選択して設定する。

Amazon Redshift で監査ログ記録をオンにする | AWS re:Post

Redshift でテーブルにカラムを追加できる位置

Redshift でテーブルの末尾にしかカラムを追加できない。ドキュメントを見る限りカラム位置を指定するような構文はない。

  • 接続する
$ psql -a "host=redshift-cluster-poc-central.********.ap-northeast-1.redshift.amazonaws.com user=awsuser dbname=dev port=5439"
  • テーブルを作成
dev=# create table test(
dev(#   name varchar(10),
dev(#   updated timestamp
dev(# );
CREATE TABLE
  • カラム追加
dev=# alter table test add column added_column int;
ALTER TABLE
  • 追加したカラムを確認
dev=# show table test;
               Show Table DDL statement
------------------------------------------------------
 CREATE TABLE public.test (                          +
     name character varying(10) ENCODE lzo,          +
     updated timestamp without time zone ENCODE az64,+
     added_column integer ENCODE az64                +
 )                                                   +
 DISTSTYLE AUTO;
(1 row)

dev=#
dev=# SHOW COLUMNS FROM TABLE dev.public.test;
 database_name | schema_name | table_name | column_name  | ordinal_position | column_default | is_nullable |          data_type          | character_maximum_length | numeric_precision | remarks
---------------+-------------+------------+--------------+------------------+----------------+-------------+-----------------------------+--------------------------+-------------------+---------
 dev           | public      | test       | added_column |                3 |                | YES         | integer                     |                          |                32 |
 dev           | public      | test       | name         |                1 |                | YES         | character varying           |                       10 |                   |
 dev           | public      | test       | updated      |                2 |                | YES         | timestamp without time zone |                          |                   |
(3 rows)