[Oracle Cloud] Resource Principalを使用して、Autonomous DBからObject Storageにアクセスする

# はじめに

Autonomous DBは、OSレイヤにアクセスできないPaaSのサービスであるため、外部ファイルと連携するためにObject Storageが使われることがよくあります。

Object Storageへのアクセスには認証・認可が必要です。以前まで、認証方法として「認証トークン」または「APIキー」のみがサポートされており、Computeインスタンスのようにインスタンス・プリンシパルを使用した認証ができませんでした。

[参考Blog: Autonomous Database Now Supports Accessing the Object Storage with OCI Native Authentication](https://blogs.oracle.com/datawarehousing/autonomous-database-now-supports-accessing-the-object-storage-with-oci-native-authentication)

2021年4月ごろから、Autonomous DBやDBCSでもリソース・プリンシパルという機能により、インスタンス・プリンシパルと同様に動的グループによる認証が可能になりました。
(何で区別するのでしょうね。インスタンス・プリンシパルはComputeのみで、それ以外がリソース・プリンシパル？)

[参考Blog: Accessing Oracle Cloud Infrastructure Resources from Your Autonomous Database using Resource Principal](https://blogs.oracle.com/datawarehousing/accessing-oracle-cloud-infrastructure-resources-from-your-autonomous-database-using-resource-principal)


この記事では、リソース・プリンシパルを使用して、Autonomous DBの認証を試してみます。なお、リソース・プリンシパルによる動的グループの設定は、DBCSでも可能です。

Autonomous DBのリソース・プリンシパルに関するマニュアルは、[こちら](https://docs.oracle.com/en/cloud/paas/autonomous-database/adbsa/resource-principal.html#GUID-E283804C-F266-4DFB-A9CF-B098A21E496A)です

# 前提
・Autonomous DBは、Free Tierのものを使用します

# 手順
## Autonomous DBの作成
* [メニュー]⇒[Oracle Database]⇒[Autonomous Database]に遷移します
* 「Autonomous Databaseの作成」ボタンを押下します。
* Always Freeのインスタンスを作成します (詳細説明は割愛)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/c1a572b2-e7ea-bc21-cf8c-ae9671888976.png)

作成完了後、動的グループの指定に使用するため、Autonomous DBのOCIDをコピーしてメモします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/515af027-1f18-ff69-b502-e6c867c73adb.png)


## 動的グループによる認証設定

動的グループを作成して、作成したAutnomous DBを識別できるようにします。

* [メニュー]⇒[アイデンティティとセキュリティ]⇒[動的グループ]に遷移します
* 「動的グループの作成」ボタンを押下します
* 一致ルールとして、「resource.id = '<上述手順でコピーした、Autonomous DBのOCID>'」を入力します。これ以外の指定方法は[マニュアル](https://docs.oracle.com/en/cloud/paas/autonomous-database/adbsa/resource-principal-prereq.html#GUID-3CF59CED-F7DF-46AF-B3CF-E703ED0BB3EE)を参照ください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/a09feea1-0e2b-7f16-2f33-056ea6e28a52.png)

## ポリシー
ポリシーを設定して、認可の設定をします。

* [メニュー]⇒[アイデンティティとセキュリティ]⇒[ポリシー]に遷移します
* 「ポリシーの作成」ボタンを押下します
* バケットを作成したコンパートメント内のバケット・オブジェクトに対して読み取り権限を与えてあげます

```
Allow dynamic-group <作成した動的グループ名> to read buckets in compartment <バケットを作成したコンパートメント名>
Allow dynamic-group <作成した動的グループ名> to read objects in compartment <バケットを作成したコンパートメント名>
```
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/23c70b00-2304-f00c-8ec5-3927102f68c8.png)


## DB接続用Walletのダウンロード
Autonomous DB作成後、「DB接続」ボタンを押下して、インスタンス・ウォレットをダウンロードします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/f2885d1b-930f-6fbd-38bb-23a568102cd0.png)

# 

# バケットの作成
Object Storageにバケットを作成します

* [メニュー]⇒[ストレージ]⇒[バケット]のリンクを押下します
* 「バケットの作成」ボタンを押下します
* 設定値はすべてデフォルトにして、バケットを作成します
* 以下のCSVファイルを作成して、"names.csv"というオブジェクト名で作成したバケットにアップロードします

```CSV
id,last_name,first_name
1,Yamada,Taro
2,Suzuki,Jiro
3,Sato,Saburo
```

アップロードしたオブジェクト(nams.csv)の右端メニューを押下し、オブジェクト詳細の表示を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/4f1ef044-1093-a6eb-7486-f908fafe2d73.png)

オブジェクトのURLパスをメモします。後述の手順で、外部表作成時に指定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1674918/4adfe2dd-b598-9c79-b8a7-c5e2e16dfd12.png)


# Resource Principalの有効化
## ADBにアクセス

ADBにsqlplusを使用してアクセスします。接続方法の詳細は記載しませんが、以下のように、Linuxホストからsqlplusでアクセスしました

```CONSOLE
$ sqlplus admin@adb01_low

SQL*Plus: Release 19.0.0.0.0 - Production on Wed Jun 23 19:59:24 2021
Version 19.10.0.0.0

Copyright (c) 1982, 2020, Oracle.  All rights reserved.

Enter password:

Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.5.0.0.0

SQL>
```

## Resource Principalの有効化

Objectにアクセスするユーザが、ADMINユーザの場合は以下のSQLを実行します。
※検証では、ADMINユーザを使用しました。

```
SQL> EXEC DBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPAL();

PL/SQL procedure successfully completed.

SQL> SELECT owner, credential_name FROM dba_credentials 
     WHERE credential_name = 'OCI$RESOURCE_PRINCIPAL' AND owner = 'ADMIN'; 

OWNER  CREDENTIAL_NAME
-----  ----------------------
ADMIN  OCI$RESOURCE_PRINCIPAL 

⇒ OCI$RESOURCE_PRINCIPAL という名前で、資格証明が作成されていることを確認します。
```

[参考] ADMINユーザ以外のユーザからアクセスする場合は、以下のSQLを実行します。

```
SQL> EXEC DBMS_CLOUD_ADMIN.ENABLE_RESOURCE_PRINCIPAL(username => '<ADB_USER名>');
```

# 外部表の作成
Object(csvファイル)を参照する外部表を作成して、Objectにアクセスできることを確認します

```
SQL> BEGIN
   DBMS_CLOUD.CREATE_EXTERNAL_TABLE(
     table_name      => 'SAMPLE_EXTERNAL_TABLE',
     credential_name => 'OCI$RESOURCE_PRINCIPAL',
     file_uri_list   => '<上述の手順で確認した、オブジェクトのURLパス>',
     format          => '{"type": "CSV", "skipheaders": "1"}' ,
     column_list     => 'ID NUMBER, LAST_NAME VARCHAR2(50), FIRST_NAME VARCHAR2(50)'
   );
END;
/

PL/SQL procedure successfully completed.

* 今回は、CSVファイルにヘッダーがついているので、skipheadersを指定して1行目を読み飛ばしています
```

参照してみます。

```
SQL> select * from SAMPLE_EXTERNAL_TABLE;
        ID LAST_NAME  FIRST_NAME
---------- ---------- ----------
         1 Yamada     Taro
         2 Suzuki     Jiro
         3 Sato       Saburo
```


参照できました！

なお、DBCSもリソース・プリンシパルをサポートしているそうで、oci cliの実行時の認証に利用できるようになっているそうです。