[OCI]GCPのサービスアカウントを使用してAutonomous DatabaseからGoogle Cloud Storageにアクセスしてデータ連携してみた

# はじめに

Autonomous Databaseの機能アップデートで、Google Cloud Platform（GCP）のサービスアカウントを用いたGCPリソースへのアクセスがサポートされたので試してみました。

今回は、GCPのサービスアカウントを利用してAutonomous DatabaseからGoogle Cloud Storageにアクセスし、バケットの内のオブジェクトの表示と、バケット内のオブジェクト（ファイル）をもとにした外部表の作成を試してみました。

# 1. Autonomous DatabaseでGCPのサービスアカウントを有効化

adminユーザとして、Autonomous Databaseに接続します。
```
[opc@swingbench ~]$ sqlplus admin/Demo#1Demo#1@atp1_medium

SQL*Plus: Release 21.0.0.0.0 - Production on 木 10月 13 10:26:57 2022
Version 21.7.0.0.0

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

最終正常ログイン時間: 水 10月 12 2022 14:38:22 +09:00


Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.17.0.1.0
に接続されました。
SQL> 
```
Autonomous DatabaseでGCPのサービスアカウントを有効化するには、providerに'GCP'を指定して、DBMS_CLOUD_ADMIN.ENABLE_PRINCIPAL_AUTHプロシージャを実行します。
```
SQL> BEGIN
  2      DBMS_CLOUD_ADMIN.ENABLE_PRINCIPAL_AUTH(
  3          provider => 'GCP' );
  4  END;
  5  /

PL/SQLプロシージャが正常に完了しました。

SQL>
```
cloud_integrationsビューを検索してGCPのサービスアカウント名を確認し、メモしておきます。
```
SQL> SELECT * FROM cloud_integrations WHERE param_name = 'gcp_service_account';

PARAM_NAME
--------------------------------------------------------------------------------
PARAM_VALUE
--------------------------------------------------------------------------------
gcp_service_account
GCP-SA-16231-46794@gcp-pa-project1.iam.gserviceaccount.com


SQL> 
```

# 2. Google Cloudのロールの作成

Autonomous Databaseのサービスアカウントに付与する、Google Cloud Storageへのアクセスを許可するロールを作成します。

Goole Cloudコンソールにサインインします。
![スクリーンショット 2022-10-13 10.48.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/30bcfff7-d16d-640c-0f6e-97c5e09271a9.png)
左側のメニューの「IAMと管理」を選択し、「ロール」をクリックします。
![スクリーンショット 2022-10-13 10.51.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/12b53176-9d21-ab98-3633-7656cb420339.png)
ロールの画面に移動します。
![スクリーンショット 2022-10-13 10.52.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/d33bd6be-34af-ce87-d240-43e0cb5716b3.png)
「ロールの作成」をクリックします。
![スクリーンショット 2022-10-13 10.52.25のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/30b8fba6-090f-a0f4-dac8-0e2caa9054b0.png)
タイトルとIDに任意の文字列を入力し、「権限の追加」をクリックします。
ここでは、
タイトル：Object Store Read and Write for ADB
ID：ObjectStoreReadandWriteforADB
としました。
![スクリーンショット 2022-10-13 10.54.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/6cd9257a-969d-bf7b-5a71-0163ed3abf4b.png)
「フィルタ」の横をクリックすると、プロパティのリストが表示されるので、「権限」を選択します。
![スクリーンショット 2022-10-13 10.58.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/e5e799e1-7300-90d1-e013-7cf4d248d593.png)
検索条件として「storage.objects」を入力してEnterキーを押します。
表示された権限の中から、
・storage.objects.create 
・storage.objects.get 
・storage.objects.list
・storage.objects.update
にチェックを入れ、「追加」をクリックします。
![スクリーンショット 2022-10-13 11.02.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/e2ee61bc-ccd8-1c8d-0a9c-718332729419.png)
権限が正しく追加されているか確認し、「作成」をクリックします。
![スクリーンショット 2022-10-13 11.03.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/a1107a5b-1796-342c-71e3-38d1ab545fcd.png)
Google Cloud Storageへのアクセスを許可するロール（ここでは「Object Store Read and Write for ADB」）が作成されました。
![スクリーンショット 2022-10-13 11.04.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/45ea6fa9-1fe1-ef88-a1f7-d6407ad65ed8.png)


# 3. Google Cloud Storageの準備
Google Cloudコンソールで「Cloud Storage」の「バケット」に移動します。
![スクリーンショット 2022-10-13 11.07.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/db96f2db-71a3-ec4f-bf3a-ea158d4d5c74.png)
「作成」をクリックします。
![スクリーンショット 2022-10-13 11.07.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/addfabb8-a611-b780-20e1-93e1a7275072.png)
任意のバケット名（ここでは「gcp-cloud-storage-bucket-for-adb」）を入力し、「続行」をクリックします。
**[こちら](https://docs.oracle.com/en/cloud/paas/autonomous-database/adbsa/google-service-account-notes.html#GUID-DDF2887D-EA8E-43E5-BE2A-65BA3DB12109)のマニュアルに記載があるように、バケット名に_（アンダースコア）が含まれていると、Autonomous Databaseから参照できませんのでご注意ください。**
![スクリーンショット 2022-10-13 11.29.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/7820a691-a5a3-e8a6-9c65-362a4e98e45f.png)
任意のロケーションタイプを選択し、「続行」をクリックします。
![スクリーンショット 2022-10-13 11.29.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/111b5a0a-43d0-4532-d3ba-4e6fca562d3b.png)
ストレージクラスはデフォルトの「Standard」のままで「続行」をクリックします。
![スクリーンショット 2022-10-13 11.30.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/8c42132d-243d-7530-efe4-5f385a9723f9.png)
オブジェクトへのアクセスを制御する方法もデフォルトのままで「続行」をクリックします。
![スクリーンショット 2022-10-13 11.30.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/07830880-1b53-8e3e-6da2-26e5b95df339.png)
オブジェクトを保護する方法を選択し、「作成」をクリックします。
![スクリーンショット 2022-10-13 11.30.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/128bd0ed-c118-150f-6d28-007ac7d07aeb.png)
バケット「gcp-cloud-storage-bucket-for-adb」が作成されました。
![スクリーンショット 2022-10-13 11.31.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/5890e0cb-cba8-9119-233b-1e620f93ae16.png)
「権限」をクリックします。
![スクリーンショット 2022-10-13 11.31.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/da399fa9-5387-a5ac-b8c0-4af3e809e143.png)
「アクセス権を付与」をクリックします。
![スクリーンショット 2022-10-13 11.31.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/5fd4aef1-470e-c8de-3424-b6525f8e04f4.png)
アクセス権付与のウインドウが表示されます。
![スクリーンショット 2022-10-13 11.31.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/c6c55e31-104b-1a31-13d1-41ddf5d031bc.png)
「プリンシパルの追加」セクションの「新しいプリンシパル」に、1.でコピーしたAutonomous Databaseのサービスアカウントを入力し、Enterキーを押します。
![スクリーンショット 2022-10-13 11.32.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/00284da0-e17a-24f3-6e60-ff26498e330e.png)
「ロールを割り当てる」セクションの「ロールの選択」をクリックします。
![スクリーンショット 2022-10-13 12.51.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/029b2bc3-68ce-c143-ee28-aa1ba0cbfdda.png)
クイックアクセスの「カスタム」を選択し、2.で作成したロール（ここでは「Object Store Read and Write for ADB」）をクリックします。
![スクリーンショット 2022-10-13 11.32.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/362ca6ac-2a83-6df6-518a-93c4b5e93ea1.png)
入力が完了したら、「作成」をクリックします。
![スクリーンショット 2022-10-13 12.55.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/1ee27b59-5022-3bf7-c22a-74666b3ae80c.png)
Autonomous Databaseのサービスアカウントに対して、ロール「Object Store Read and Write for ADB」に基づくバケット「gcp-cloud-storage-bucket-for-adb」へのアクセス権が付与されました。
![スクリーンショット 2022-10-13 11.33.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/2884fa34-c482-95ad-42ad-840956096409.png)

# 4. サービスアカウントを使用したAutonomous DatabaseからGoogle Cloud Storageへのアクセス

以下のようなファイル「testdata.txt」を作成します。
```text:testdata.txt
1,Paul
2,John
3,George
4,Ringo
```
testdata.txtを3.で作成したバケット「gcp-cloud-storage-bucket-for-adb」にアップロードします。
![スクリーンショット 2022-10-13 11.35.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/208ff2de-32c6-dc4a-61a5-5155d34b5dbb.png)

DBMS_CLOUD.LIST_OBJECTSファンクションで、Autonomous Databaseからバケット「gcp-cloud-storage-bucket-for-adb」内のオブジェクトのリストを取得してみます。

**Google Cloud StorageにアクセスするためのクレデンシャルとしてGCPのサービスアカウントを使用する場合は、credential_nameに'GCP$PA'を指定します。
また、location_uriには、以下のような仮想ホスト形式でバケットを指定します。**
`https://バケット名.storage.googleapis.com/`
```
SELECT * FROM 
DBMS_CLOUD.LIST_OBJECTS(
credential_name => 'GCP$PA',
location_uri => 'https://バケット名.storage.googleapis.com/' );

```
では、実行してみます。
```
SQL> SELECT object_name, bytes FROM DBMS_CLOUD.LIST_OBJECTS( 
  2  credential_name => 'GCP$PA', 
  3  location_uri => 'https://gcp-cloud-storage-bucket-for-adb.storage.googleapis.com/' 
  4  );

OBJECT_NAME			    BYTES
------------------------------ ----------
testdata.txt			       30

SQL>
```
サービスアカウントを使用して、Autonomous DatabaseからGoogle Cloud Storageにアクセスできました。

DBMS_CLOUD.CREATE_EXTERNAL_TABLEプロシージャでGoogle Cloud Storageのバケット「gcp-cloud-storage-bucket-for-adb」内にあるオブジェクト（ファイル）「testdata.txt」をもとにした外部表を作成し、testdata.txt内のデータをAutonomous Databaseから参照してみます。

**Google Cloud StorageにアクセスするためのクレデンシャルとしてGCPのサービスアカウントを使用する場合は、credential_nameに'GCP$PA'を指定します。
また、file_uri_listには、以下のような仮想ホスト形式でバケット内のオブジェクト（ファイル）を指定します。**
`https://バケット名.storage.googleapis.com/オブジェクト名`
では、実行してみます。
```
SQL> BEGIN
  2  	DBMS_CLOUD.CREATE_EXTERNAL_TABLE(
  3  		table_name =>'member',
  4  		credential_name =>'GCP$PA',
  5  		file_uri_list =>'https://gcp-cloud-storage-bucket-for-adb.storage.googleapis.com/testdata.txt',
  6  		format => json_object('delimiter' value ','),
  7  		column_list => 'ID NUMBER, name VARCHAR2(20)' );
  8  END;
  9  /

PL/SQLプロシージャが正常に完了しました。

SQL>
```
Google Cloud Storageのバケット「gcp-cloud-storage-bucket-for-adb」内にあるオブジェクト（ファイル）「testdata.txt」をもとにした外部表「member」が作成できました。

外部表「member」の内容を確認してみます。
```
SQL> SELECT * FROM member;

        ID NAME
---------- --------------------
	     1 Paul
	     2 John
	     3 George
	     4 Ringo

SQL>
```
サービスアカウントを使用して作成した外部表「member」経由で、Google Cloud Storageのバケット「gcp-cloud-storage-bucket-for-adb」内にあるオブジェクト（ファイル）「testdata.txt」の内容を参照できることが確認できました。

# 5. Autonomous DatabaseでGCPのサービスアカウントを無効化

Autonomous DatabaseでGCPのサービスアカウントを無効にするには、providerに'GCP'を指定してDBMS_CLOUD_ADMIN.DISABLE_PRINCIPAL_AUTHプロシージャを実行します。
```
BEGIN
    DBMS_CLOUD_ADMIN.DISABLE_PRINCIPAL_AUTH(
        provider => 'GCP' );
END;
/
```

# 参考資料
・[Use Google Service Account to Access Google Cloud Platform Resources](https://docs.oracle.com/en/cloud/paas/autonomous-database/adbsa/google-service-account.html#GUID-DB8D0B97-7BC5-42C0-B556-3579D834D34B)