Windows上のOracle DatabaseとAutonomous Database間のDatabase Linkの作成方法

##はじめに
この記事ではPrivate Endpointを設定したAutonomous Databaseから、Private Subnet内にあるWindowsインスタンスにDatabase Linkを利用して接続する手順を示します。

##構成図
![構成図.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/d0bd0bb6-a750-5676-75f5-00624aa229f1.jpeg)

構築手順は以下です。
1. Public Subnet内に踏み台インスタンスbastion01を作成
2. Private Subnet内にWindowsインスタンスWin01を作成
3. bastion01経由でWin01に接続
4. Win01にOracle Databaseをインストール
5. TCPS接続の設定
6. bastion02経由でADBに接続
7. bastion01にポートフォワーディング設定
8. Object StorageへWindowsインスタンスで作成したウォレットのアップロード
9. Database Link作成

1~5の手順については、[こちらの記事](https://qiita.com/wahagon/private/db49cec182f65a73ba43)を参考にしてください。

#6. bastion02経由でADBに接続
Private Subnet内のADBのOutbound IPアドレスを調べるため、一度ADBに接続します。
[こちら](https://oracle-japan.github.io/ocitutorials/database/adb104-connect-using-wallet/)を参考に、ADBに接続し、以下のコマンドを実行します。

```
select cloud_identity from v$pdbs;
```

Outbound IP アドレスが表示され、次のポートフォワーディング設定で使用するため、メモしておきます。

#7. bastion01にポートフォワーディング設定
ADBからWindowsインスタンスへポートフォワーディングを行うための設定をします。
bastion01で以下のコマンドを実行してルールを登録します。

```
sudo firewall-cmd --add-rich-rule='rule family=ipv4 source address="ADBのOutbound IPアドレス" forward-port to-addr="WindowsのPrivate IPアドレス" to-port="1522" protocol="tcp" port="1525"'
sudo firewall-cmd --add-masquerade
```

successと表示されれば設定成功です。
次にルールを永続化します。

```
sudo firewall-cmd --runtime-to-permanent
```

bastion01での設定は以上です。

続いてPublic SubnetのSecurity ListでADBからのイングレス・ルールを許可します。
ソース：{ADBのOutbound IPアドレス}/32
ソース・ポート範囲：ALL
宛先ポート範囲：ADBが使用するポート番号（今回は1525）
![sl.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1930162/fd726119-4378-2492-bde7-14d448e49a7c.jpeg)

#8. Object StorageへWindowsインスタンスで作成したウォレットのアップロード
[こちら](https://oracle-japan.github.io/ocitutorials/database/adb102-dataload/#2-2-oci%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B8%E3%81%B8%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89)の「2.OCIオブジェクトストレージへのデータアップロード」を参考に、ウォレットをObject Storageにアップロードします。

#9. Database Linkの作成
1. ADBへ接続し、ウォレット配置用のディレクトリ・オブジェクトを作成します。

    ```
CREATE DIRECTORY dblink_wallet_dir as 'walletdir';
    ```

2. クレデンシャル情報を登録します。

```
BEGIN
  DBMS_CLOUD.CREATE_CREDENTIAL(
  credential_name => 'WORKSHOP_CREDENTIAL',
  username => 'xxx@xxxx.com',
  password => 'xxxxxx');
END;
/
```

credential_name: データベースに保存した認証情報を識別するための名前、任意
username: Oracle Object Storageにアクセスするためのユーザー名
password: 認証トークン ユーザー名、認証トークンの生成については、[こちら](https://oracle-japan.github.io/ocitutorials/database/adb102-dataload/)の「1.OCIオブジェクトストレージへのアクセス情報を取得」を参考にしてください。
3. Object Storageにアップロードしたウォレットをディレクトリ・オブジェクトに配置します。

```
BEGIN
  DBMS_CLOUD.GET_OBJECT(
  credential_name => 'WORKSHOP_CREDENTIAL',
  object_uri => 'https://objectstorage.<region>.oraclecloud.com/n/<namespace>/b/<bucket>/o/cwallet.sso',
  directory_name => 'dblink_wallet_dir');
END;
/
```

object_uri: Object StorageにアップロードしたファイルのURL(< region >、< namespace >、< bucket >は実際の値に置き換えて下さい)
4. Windows上のデータベースへ接続するためのクレデンシャルを作成します。

```
BEGIN
 DBMS_CLOUD.CREATE_CREDENTIAL(
 credential_name => 'DB_LINK_CRED',
 username => 'HR',
 password => 'WelCome123#123#'
 );
END;
/
```

※ usernameは大文字’HR’で指定してください。
5. 新規 Database Linkを作成します。

```
BEGIN
 DBMS_CLOUD_ADMIN.CREATE_DATABASE_LINK(
 db_link_name => 'HR_LINK',
 hostname => 'xxx.xxx.xxx.xxx',
 port => '1525',
 service_name => '<pdb1>.<subnet>.<vcn>.oraclevcn.com',
 ssl_server_cert_dn => 'CN=Win',
 credential_name => 'DB_LINK_CRED',
 directory_name => 'dblink_wallet_dir');
END;
/
```

hostname: 踏み台インスタンスbastion01のPublic IPアドレス
service_name: Windowsインスタンスのtnsnames.oraに記載されているPDBのサービス名（本記事ではorclpdb）
6. Database Linkを使用して、Windowsのデータベースのテーブルを参照します。

```
SELECT * FROM COUNTRIES@HR_LINK;
```

正しく実行されると、Windows上のデータベースに接続され、25個の国名が表示されます。

##参考文献
https://oracle-japan.github.io/ocitutorials/database/adb104-connect-using-wallet/

https://oracle-japan.github.io/ocitutorials/database/adb402-database-link/