RedshiftのIAM認証を試してみる

2022.03.22

はじめに

データアナリティクス事業本部のkobayashiです。

RedshiftではIAM認証を使用したデータベース接続を行えることは知っていたのですがなかなか試す機会がありませんでした。この度IAM認証でRedshiftに接続する方法を調査する機会がありましたのでまとめます。

IAM認証を使用したRedshiftデータベースへの接続

Redshiftへの接続にはデータベースユーザーを作成しユーザー名・パスワードでデータベースにログインするのが一般的かと思います。一方、AWS IAMのアクセス許可ポリシーで制御されるアクセス許可に基づきRedshiftのデータベースへアクセス管理を行うのが「IAM認証を使用したRedshiftデータベースへの接続」になります。

具体的にはIAMでIAMユーザーやロールを作成しその情報でRedshiftリソースへJDBCやODBCでアクセスを行います。またSAML2.0 に準拠した ID プロバイダーを使用してRedshiftリソースへのアクセスを管理することもできます。

今回は一番単純なIAMユーザーを利用したRedshiftリソースへのアクセスを行います。これはIAMユーザーを新規に作成しRedshiftのデータベースユーザーと紐付けることでRedshiftリソースへのアクセスを行う方法になります。

流れとしてはすでにPublicなRedshiftが起動している状態で 公式ドキュメント にしたがって以下の様に進めます。

  1. GetClusterCredentials を呼び出すアクセス許可を持つIAMユーザーを作成する
  2. データベースユーザーを作成する
  3. IAM 認証情報を使用するようにJDBC接続を設定する
    1. DBeaverで接続を試す

では早速設定を行っていきます。

環境

  • macOS 10.15.7
  • DBeaver バージョン21.2.4.202111011351

Redshift接続用のIAMユーザーを作成する

はじめにIAMユーザーを作成します。GetClusterCredentials を呼び出す必要があるのでインラインポリシーを作成します。

手順1)AWSマネージメントコンソールでIAM >ユーザーと進みユーザーを追加を選択する

手順2)ユーザー名に適当な名前を入力し、AWS認証タイプアクセスキー-プログラムによるアクセスをチェックし、次のステップへ進む

手順3)ポリシーは後で設定するのでこの段階では設定せずに次のステップへ進む

手順4)「このユーザーにはアクセス権限がありません」と表示されるがそのままユーザーを作成する

手順5)後の工程で使うのでアクセスキーIDとシークレットアクセスキーキーをメモしておく

次に作成したIAMユーザーへGetClusterCredentialsアクセス許可を行うポリシーを付与します。

手順6)作成したユーザー名を選択し、アクセス権限のタブにて以下のインラインポリシーの追加を行う

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "redshift:GetClusterCredentials",
            "Resource": [
                "arn:aws:redshift:{リージョン}:{アカウントID}:dbuser:{クラスター識別子}/user1",
                "arn:aws:redshift:{リージョン}:{アカウントID}:dbname:{クラスター識別子}/dev"
            ]
        }
    ]
}

このポリシーでRedshiftデータベースユーザーuser1でデータベース名devへ接続することができるようになります。

他にもポリシーではredshift:JGetClusterCredentialsアクションにリソースとしてdbgroupを含めてログインするユーザーにRedshiftのグループを割り当てることもできます。その際にはredshift:JoinGroupアクションを追加する必要があります。

また最小限のポリシーにしてあるのでこのポリシーの場合はJDBC URLに記述するホスト名をエンドポイント名にしなくてはいけませんが、redshift:DescribeClustersアクションを許可することでクラスター識別子に省略することができます。

他にも設定できる項目があるので公式ドキュメントをご確認ください。

データベースユーザーを作成する

次にデータベースユーザーを作成します。ポリシーで指定したRedshiftのユーザーuser1を作成します。

手順1)Redshiftへログインしてuser1を作成する。その際にIAM認証でログインするためパスワードは必要ないのでパスワードの使用を無効にする。

create user user1 password disable;

手順2)Grantを使って必要な権限を作成したユーザーに付与する。

これでRedshiftのユーザーが作成できたのであとは実際に接続してみます。

IAM認証情報を使用するようにJDBC接続を設定する

JDBC URLにはアクセスキーIDとシークレットアクセスキーをパラメータにして接続しますが、セキュリティ上気になるのでプロファイルをパラメータにすることにします。そのため先にAWS認証情報ファイル.aws/credentialsへアクセスキーIDとシークレットアクセスキーを追記します。

手順1).aws/credentialsを開き、作成したIAMユーザーのアクセスキーIDとシークレットアクセスキーを追記する。

[cm_rs_iam]
aws_access_key_id=AKIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

手順2) 以下を考慮してJDBC URLを作成する。

  • redshift:DescribeClustersアクションをポリシーで許可していないのでエンドポイント名とポートの指定が必要
  • 認証情報はプロファイルを使用するのでProfileパラメータで指定する
  • Redshiftにログインするユーザー名をDbUserパラメータで指定する

redshift:DescribeClustersアクションをポリシーで許可している場合はクラスター識別子とリージョンを指定で良いので以下の様になります。

jdbc:redshift:iam://{クラスター識別子}:{リージョン}/dev?Profile=cm_rs_iam&DbUser=user1

今回はredshift:DescribeClustersアクションをポリシーで許可していないので以下がJDBC URLとなります。

jdbc:redshift:iam://{redshiftエンドポイント}:5439/dev?Profile=cm_rs_iam&DbUser=user1

準備は整ったので実際にDBeaverでRedshiftに接続してみます。

DBeaverでRedshiftに接続してみる。

ここまでの設定でIAM認証を使用したRedshiftデータベースへの接続ができるようになっているのでDBクライアントツールのDBeaverにてRedshiftへ接続してみます。他のクライアントツールでもRedshiftのドライバが入っていれば接続可能です。

DBeaverでの接続は接続先用の専用ドライバを作り、そのドライバーを使った接続先を作る必要があります。この専用ドライバはIAM認証を使用したRedshiftデータベースへの接続ごとに作成する必要があるので接続方法を増やしたり変更するごとに作成する必要があります。

手順1)メニューバーからデータベース > ドライバーマネージャーを選択する

手順2)ドライバマネージャーからRedshiftを選択してコピーする

手順3)URLテンプレートに先程作成したJDBC URL(jdbc:redshift:iam://{redshiftエンドポイント}:5439/dev?Profile=cm_rs_iam&DbUser=user1)を入力して専用のドライバを作成する

手順4)データベースから新規 > 接続で手順3で作成したドライバを新しい接続を作成する

手順5)はじめにRedshiftのJDBCドライバのダウンロードを促されるのでダウンロードをする

手順6)IAM認証を使用したRedshiftデータベースへの接続ではSSL接続が必須なのでSSLを使用するにチェックを入れる

手順7)テスト接続を押下して接続が問題ないことを確認する

これでDBeaverでの接続設定は完了なので実際にクエリを実行してみるとIAM認証を使用したRedshiftデータベースへの接続でデータが取得できることがわかります。

まとめ

IAM認証を使用したRedshiftデータベースへの接続をJDBCドライバで試してみました。特に難しいところもなかったので次は SAML2.0 に準拠した ID プロバイダーを使用してRedshiftリソースへのアクセスも試してみたいと思います。

最後まで読んで頂いてありがとうございました。