2023年12月19日火曜日

ARNを使ったクリデンシャルを作成してAPEXのワークスペースからAWS S3のバケットにアクセスする

Oracle Autonomous Database(Always Freeを使います)に、AWS IAMで作成したロールのARNs(Amazon Resource Names)を使ったクリデンシャルを作成して、AWS S3にアクセスしてみます。

S3のバケットは、以下の記事に書かれている手順で作成したmyoraclefreebucketを使います。ポリシーも同じ記事に手順があるポリシーOracleFreeS3Policyを使います。

Oracle Database 23c FreeにDBMS_CLOUDパッケージを入れてAmazon S3にアクセスする

Autonomous DatabaseにユーザーADMINでアクセスし、SQL Developer WebSQLワークシートを開きます。


APEXのワークスペースはAPEXDEV、ワークスペース・スキーマはWKSP_APEXDEVとして作成済みとします。

ワークスペース・スキーマWKSP_APEXDEVで、AWSのARNを使った認証を有効にします。
begin
    dbms_cloud_admin.enable_principal_auth(
        provider => 'AWS'
        ,username => 'WKSP_APEXDEV'
    );
end;


ビューCLOUD_INTEGRATIONSを検索し、AWSのIAMで作成するロールにアカウントIDとして設定する値を取得します。
select param_value from cloud_integrations where param_name = 'aws_user_arn'


APEXからの利用なので、AWSのIAMのロールの外部IDデータベースのOCIDを設定することにします。未確認ですが、テナントのOCIDコンパートメントのOCID外部IDとすることもできるようです。

Autonomous Databaseの情報ページを開き、OCIDコピーします。


AWSコンソールを開きIAMロールより、ロールを作成します。


信頼されたエンティティタイプとしてAWSアカウントを選択します。AWSアカウントとして別のAWSアカウントを選択し、アカウントIDにビューCLOUD_INTEGRATIONSPARAM_NAMEaws_user_arnPARAM_VALUEとして得られた値の12桁の数値の部分を設定します。

オプション外部IDを要求するチェックを入れ、外部IDとしてデータベースのOCIDを設定します。

次へ進みます。


許可ポリシーとしてOracleFreeS3Policyを検索し、チェックを入れます。

次へ進みます。


ロール名としてOracleAPEXRole説明としてRole for Oracle APEX.と入力して、ロールを作成します。


ロールOracleAPEXRoleが作成されます。ロールのARNを取得するため、作成されたロールを表示します。


作成されたロールOracleAPEXRoleARNをコピーします。


以上でAWS側の設定は完了です。

Autonomous Databaseに戻ります。

パッケージDBMS_CLOUDの実行権限を、APEXのワークスペース・スキーマWKSP_APEXDEVに与えます。デフォルトの状態では、APEXのワークスペース・スキーマはDBMS_CLOUDの実行権限を持っていません。
grant execute on dbms_cloud to wksp_apexdev;

これからは、APEXのSQLコマンドから作業を行います。

AWSのロールのARNを使ったクリデンシャルをaws_role_arnという名前で作成します。
begin
    dbms_cloud.create_credential(
        credential_name => 'aws_role_arn'
        ,params => json_object(
            'aws_role_arn' value 'ロールOracleAPEXRoleのARN'
            ,'external_id_type' value 'database_ocid'
        )
    );
end;
作成が完了するまでにかなりの時間(10秒前後)かかります。


ビューUSER_CREDENTIALSを検索し、作成されたクリデンシャルを確認します。

select * from user_credentials


S3のバケットを操作し、クリデンシャルが正しく作成されたことを確認します。

これからの手順は、以前の記事と同じでクリデンシャルだけが異なります。

内容にmy first uploadと記載したファイルtest.txtを、S3のバケットにアップロードします。
declare
    l_resp dbms_cloud_types.resp;
    l_blob blob;
    l_clob clob;
begin
    l_clob := 'my first upload';
    l_blob := apex_util.clob_to_blob(l_clob);
    l_resp := dbms_cloud.send_request(
        credential_name => 'aws_role_arn'
        ,uri => 'https://s3.us-east-1.amazonaws.com/myoraclefreebucket/test.txt'
        ,method => 'PUT'
        ,body => l_blob
    );
end;

バケットの内容をリストします。test.txtがアップロードされていることが確認できます。
select * from dbms_cloud.list_objects(
    credential_name => 'aws_role_arn'
,location_uri => 'https://s3.us-east-1.amazonaws.com/myoraclefreebucket' )

ファイルtest.txtを取得します。ファイルの内容がmy first uploadとして表示されます。
declare
    l_resp dbms_cloud_types.resp;
    l_clob clob;
begin
    l_resp := dbms_cloud.send_request(
        credential_name => 'aws_role_arn'
,uri => 'https://s3.us-east-1.amazonaws.com/myoraclefreebucket/test.txt' ,method => 'GET' ); l_clob := dbms_cloud.get_response_text( resp => l_resp ); dbms_output.put_line(l_clob); end;


ファイルtest.txtを削除します。
begin
    dbms_cloud.send_request(
        credential_name => 'aws_role_arn'
,uri => 'https://s3.us-east-1.amazonaws.com/myoraclefreebucket/test.txt' ,method => 'DELETE' ); end;

再度、バケット内のファイルをリストします。データが見つかりませんと返されます。


今回の記事は以上になります。

Oracle APEXのアプリケーション作成の参考になれば幸いです。