S3にファイルがアップロードされたらLambdaからAutonomous DatabaseのPL/SQLプロシージャを実行してObject Storageにファイルをコピーする

# はじめに

自己学習を兼ねて、Amazon S3にファルがアップロードされたら、それをトリガーにしてLambdaファンクションが起動し、LambdaファンクションがAutonomous Databaseに接続してアップロードされたファイルをAmazon S3からOCI Object Storageに移動するPL/SQLプロシージャを実行するという仕組みを構築してみました。

処理の流れのイメージは以下のようになります。

1. Amazon S3のバケットにファイルをアップロード

2. Amazon S3バケットのオブジェクト作成イベントをLambdaに通知

3. LambdaからAutonomous Databaseにアクセス

4. Amazon S3にアップロードされたファイルをOCI Object Storageに移動するPL/SQLプロシージャをLambdaから実行

5. PL/SQLプロシージャによって、Amazon S3にアップロードされたファイルがOCI Object Storageに移動される

※なお、Python、Lambdaに関して初心者ですので、最低限動くといったコーディング、設定しか行っていません。実装にあたっては、エラーハンドリング等を追加し充分に検証を行ってから実装してください。こちらの内容を元に実装されたことによる問題について、当方は一切の責任を負いません。
また、こちらの内容に関するOracle Supportへのご質問等はご遠慮ください。

# 1. 事前準備

・OCI Object StorageとAmazon S3に同じ名前のバケットを作成します。
（今回はobject-move-test-bucketという名前のバケットを作成しました。）

＜OCI Object Storage＞
![スクリーンショット 2024-07-26 9.48.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/fb193cd4-36d9-e6f6-c483-3fbf18735b60.png)

＜Amazon S3＞
![スクリーンショット 2024-07-26 9.48.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/5ef3fca4-62be-d3e0-fb1c-f6f09d2bdce8.png)

・Autonomous Databasのリソース・プリンシパルを有効化し、OCI Object Storageへのアクセスを許可します。
　リソース・プリンシパルの使用方法については、こちらを参照ください。

https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/serverless/adbsb/resource-principal.html#GUID-E283804C-F266-4DFB-A9CF-B098A21E496A

・Autonomous DatabaseからAmazon S3にアクセスするためのクレデンシャルの作成します。
　今回はAWS_S3_CREDという名前のARNを使用したロールベースのクレデンシャルを作成し、使用しました。
 　ARNを使用したロール・ベースのクレデンシャルの作成については、こちらを参照ください。
  
https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/serverless/adbsb/amazon-arn.html#GUID-BDEE5519-3807-4699-9C53-546EFD2F3A17

・AWS CLI、SAM CLIが利用可能な環境を準備します。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/install-sam-cli.html

# 2. PL/SQLプロシージャの作成

バケット名とオブジェクト名を引数として渡すと、AWS S3からOCI Object Storageにオブジェクトを移動するPL/SQLプロシージャmove_awss3_to_ociosを作成します。

Autonomous Databaseには、2つのバケット間でオブジェクトを移動するPL/SQLプロシージャDBMS_CLOUD.MOVE_OBJECTが用意されていますので、このプロシージャを使用します。

```sql:move_awss3_to_ociosプロシージャ
CREATE OR REPLACE PROCEDURE move_awss3_to_ocios ( bucket_name IN VARCHAR2, object_name IN VARCHAR2)
IS
    source_uri VARCHAR2(200);
    target_uri VARCHAR2(200);

BEGIN
    source_uri := 'https://'||bucket_name||'.s3.ap-northeast-1.amazonaws.com/'||object_name;
	target_uri := 'https://objectstorage.ap-tokyo-1.oraclecloud.com/n/namespace/b/'||bucket_name||'/o/'||object_name;
    
    DBMS_CLOUD.MOVE_OBJECT (
        source_credential_name  => 'AWS_S3_CRED',
        source_object_uri       => source_uri,
        target_credential_name  => 'OCI$RESOURCE_PRINCIPAL',
        target_object_uri       => target_uri
    );
END;
/
```

adminユーザとして、SQL*PlusからAutonomous Databaseに接続します。
```
[oracle@oracle23ai ~]$ sqlplus  admin/Demo#1Demo#1@adw23ai

SQL*Plus: Release 23.0.0.0.0 - Production on Fri Jul 26 11:44:46 2024
Version 23.4.0.24.05

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

Last Successful login time: Fri Jul 26 2024 11:42:17 +09:00

Connected to:
Oracle Database 23ai Enterprise Edition Release 23.0.0.0.0 - Production
Version 23.5.0.24.06

SQL>
```
上記のDDLを実行して、PL/SQLプロシージャmove_awss3_to_ociosを作成します。
<namespace>の部分は、テナントのObject Storageのネームスペースを入力します。
```
SQL> CREATE OR REPLACE PROCEDURE move_awss3_to_ocios ( bucket_name IN VARCHAR2, object_name IN VARCHAR2)
  2  IS
  3  	 source_uri VARCHAR2(200);
  4  	 target_uri VARCHAR2(200);
  5  
  6  BEGIN
  7  	 source_uri := 'https://'||bucket_name||'.s3.ap-northeast-1.amazonaws.com/'||object_name;
  8  	     target_uri := 'https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<namespace>/b/'||bucket_name||'/o/'||object_name;
  9  
 10  	 DBMS_CLOUD.MOVE_OBJECT (
 11  	     source_credential_name  => 'AWS_S3_CRED',
 12  	     source_object_uri	     => source_uri,
 13  	     target_credential_name  => 'OCI$RESOURCE_PRINCIPAL',
 14  	     target_object_uri	     => target_uri
 15  	 );
 16  END;
 17  /

Procedure created.

SQL>
```
PL/SQLプロシージャmove_awss3_to_ociosが作成できました。

# 3. Lambdaファンクションの作成

sam initを実行して新規アプリケーションを初期化します。
今回はAWS Quick Start Templatesに用意されているHello World Exampleをテンプレートとして使用しました。
プロジェクト名はmoveobjectとしました。

```
(mypy) myuser@mymac sam % sam init

You can preselect a particular runtime or package type when using the `sam init` experience.
Call `sam init --help` to learn more.

Which template source would you like to use?
	1 - AWS Quick Start Templates
	2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
	1 - Hello World Example
	2 - Data processing
	3 - Hello World Example with Powertools for AWS Lambda
	4 - Multi-step workflow
	5 - Scheduled task
	6 - Standalone function
	7 - Serverless API
	8 - Infrastructure event management
	9 - Lambda Response Streaming
	10 - Serverless Connector Hello World Example
	11 - Multi-step workflow with Connectors
	12 - GraphQLApi Hello World Example
	13 - Full Stack
	14 - Lambda EFS example
	15 - DynamoDB Example
	16 - Machine Learning
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]: y

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: 

Would you like to enable monitoring using CloudWatch Application Insights?
For more info, please view https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/cloudwatch-application-insights.html [y/N]: 

Would you like to set Structured Logging in JSON format on your Lambda functions?  [y/N]: 

Project name [sam-app]: moveobject

    -----------------------
    Generating application:
    -----------------------
    Name: moveobject
    Runtime: python3.9
    Architectures: x86_64
    Dependency Manager: pip
    Application Template: hello-world
    Output Directory: .
    Configuration file: moveobject/samconfig.toml
    
    Next steps can be found in the README file at moveobject/README.md
        

Commands you can use next
=========================
[*] Create pipeline: cd moveobject && sam pipeline init --bootstrap
[*] Validate SAM template: cd moveobject && sam validate
[*] Test Function in the Cloud: cd moveobject && sam sync --stack-name {stack-name} --watch

(mypy) myuser@mymac sam % 

```
作成されたmoveobjectディレクトリに移動します。
```
(mypy) myuser@mymac sam % cd moveobject
(mypy) myuser@mymac moveobject % ls
README.md	events		samconfig.toml	tests
__init__.py	hello_world	template.yaml
(mypy) myuser@mymac moveobject %
```
hello_worldディレクトリに移動します。

```
(mypy) myuser@mymac moveobject % cd hello_world 
(mypy) myuser@mymac hello_world % ls
__init__.py		app.py			requirements.txt
(mypy) kmyuser@mymac hello_world % 
```

今回はAutonomous Databaseへのアクセスにpython-oracledbを使用するので、reqirements.txtにoracledbを追加します。
```
(mypy) myuser@mymac hello_world % vi requirements.txt
```

```text:requirements.txt
requests
```
oracledbを追加して保存します。
```text:requirements.txt
requests
oracledb
```

pip installで必要なパッケージをインストールします。
```
(mypy) myuser@mymac hello_world % pip install -r requirements.txt 
```

アプリケーション本体のapp.pyを編集します。
```
(mypy) myuser@mymac hello_world % vi app.py
```
以下のような内容に書き換えます。
```python:app.py
import json
import oracledb
import os

# 環境変数を取得
un = os.environ.get('PYTHON_USERNAME')
pw = os.environ.get('PYTHON_PASSWORD')
cs = os.environ.get('PYTHON_CONNECTSTRING')

def lambda_handler(event, context):
# イベント通知からバケット名とオブジェクト名を取得
    bucket_name = event['Records'][0]['s3']['bucket']['name']
    object_name = event['Records'][0]['s3']['object']['key']
    
# Autonomous Databaseに接続し、バケット名、オブジェクト名を引数としてmove_awss3_to_ociosプロシージャを実行
    with oracledb.connect(user=un, password=pw, dsn=cs) as connection:
        with connection.cursor() as cursor:
            cursor.callproc('move_awss3_to_ocios', [bucket_name, object_name])

    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "hello world",
            # "location": ip.text.replace("\n", "")
        }),
    }
```



moveobjectディレクトリに移動します。
```
(mypy) myuser@mymac hello_world % cd ..
(mypy) myuser@mymac moveobject % ls
README.md	events		samconfig.toml	tests
__init__.py	hello_world	template.yaml
(mypy) myuser@mymac moveobject %
```

sam buildでアプリケーションをビルドを実行します。
```
(mypy) myuser@mymac moveobject % sam build
Starting Build use cache                                                        
Manifest file is changed (new hash: 2768310a16637613860e1081461caa9f) or        
dependency folder (.aws-sam/deps/842f4bbf-8ed0-453f-8945-1a0ca9c9f08e) is       
missing for (HelloWorldFunction), downloading dependencies and copying/building 
source                                                                          
Building codeuri: /Users/kyamakaw/sam/moveobject/hello_world runtime: python3.9 
metadata: {} architecture: x86_64 functions: HelloWorldFunction                 
 Running PythonPipBuilder:CleanUp                                               
 Running PythonPipBuilder:ResolveDependencies                                   
 Running PythonPipBuilder:CopySource                                            
 Running PythonPipBuilder:CopySource                                            

Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided
(mypy) myuser@mymac moveobject % 

```

sam deployでアプリケーションをLambdaにファンクションとしてデプロイします。
```
(mypy) myuser@mymac moveobject % sam deploy --stack-name moveobject --guided

Configuring SAM deploy
======================

	Looking for config file [samconfig.toml] :  Found
	Reading default arguments  :  Success

	Setting default arguments for 'sam deploy'
	=========================================
	Stack Name [moveobject]: 
	AWS Region [ap-northeast-1]: 
	#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
	Confirm changes before deploy [Y/n]: 
	#SAM needs permission to be able to create roles to connect to the resources in your template
	Allow SAM CLI IAM role creation [Y/n]: 
	#Preserves the state of previously provisioned resources when an operation fails
	Disable rollback [y/N]: 
	HelloWorldFunction has no authentication. Is this okay? [y/N]: y
	Save arguments to configuration file [Y/n]: 
	SAM configuration file [samconfig.toml]: 
	SAM configuration environment [default]: 

	Looking for resources needed for deployment:

	Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-e7cuyvsbwyhw
	A different default S3 bucket can be set in samconfig.toml and auto resolution of buckets turned off by setting resolve_s3=False
                                                                                
        Parameter "stack_name=moveobject" in [default.deploy.parameters] is     
defined as a global parameter [default.global.parameters].                      
        This parameter will be only saved under [default.global.parameters] in  
/Users/kyamakaw/sam/moveobject/samconfig.toml.                                  

	Saved arguments to config file
	Running 'sam deploy' for future deployments will use the parameters saved above.
	The above parameters can be changed by modifying samconfig.toml
	Learn more about samconfig.toml syntax at 
	https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html

	Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  262144 / 7426200  (3.5Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  524288 / 7426200  (7.0Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  786432 / 7426200  (10.Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  1048576 / 7426200  (14Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  1310720 / 7426200  (17Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  1572864 / 7426200  (21Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  1835008 / 7426200  (24Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  2097152 / 7426200  (28Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  2359296 / 7426200  (31Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  2621440 / 7426200  (35Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  2883584 / 7426200  (38Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  3145728 / 7426200  (42Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  3407872 / 7426200  (45Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  3670016 / 7426200  (49Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  3932160 / 7426200  (52Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  4194304 / 7426200  (56Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  4456448 / 7426200  (60Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  4718592 / 7426200  (63Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  4980736 / 7426200  (67Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  5242880 / 7426200  (70Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  5505024 / 7426200  (74Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  5767168 / 7426200  (77Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  6029312 / 7426200  (81Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  6291456 / 7426200  (84Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  6553600 / 7426200  (88Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  6815744 / 7426200  (91Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  7077888 / 7426200  (95Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  7340032 / 7426200  (98Uploading to moveobject/c52a52a03cc30a46b36c64693968e2ce  7426200 / 7426200  (100.00%)

	Deploying with following values
	===============================
	Stack name                   : moveobject
	Region                       : ap-northeast-1
	Confirm changeset            : True
	Disable rollback             : False
	Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-e7cuyvsbwyhw
	Capabilities                 : ["CAPABILITY_IAM"]
	Parameter overrides          : {}
	Signing Profiles             : {}

Initiating deployment
=====================

	Uploading to moveobject/03f3a4731daa7d55e4fe6bb863b9ba65.template  1208 / 1208  (100.00%)


Waiting for changeset to be created..

CloudFormation stack changeset
-------------------------------------------------------------------------------------------------
Operation                LogicalResourceId        ResourceType             Replacement            
-------------------------------------------------------------------------------------------------
+ Add                    HelloWorldFunctionHell   AWS::Lambda::Permissio   N/A                    
                         oWorldPermissionProd     n                                               
+ Add                    HelloWorldFunctionRole   AWS::IAM::Role           N/A                    
+ Add                    HelloWorldFunction       AWS::Lambda::Function    N/A                    
+ Add                    ServerlessRestApiDeplo   AWS::ApiGateway::Deplo   N/A                    
                         yment47fc2d5f9d          yment                                           
+ Add                    ServerlessRestApiProdS   AWS::ApiGateway::Stage   N/A                    
                         tage                                                                     
+ Add                    ServerlessRestApi        AWS::ApiGateway::RestA   N/A                    
                                                  pi                                              
-------------------------------------------------------------------------------------------------


Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:************:changeSet/samcli-deploy1721954219/14beaea2-0e05-4400-9136-3d975a321b85


Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y

2024-07-26 09:37:14 - Waiting for stack create/update to complete

CloudFormation events from stack operations (refresh every 5.0 seconds)
-------------------------------------------------------------------------------------------------
ResourceStatus           ResourceType             LogicalResourceId        ResourceStatusReason   
-------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS       AWS::CloudFormation::S   moveobject               User Initiated         
                         tack                                                                     
CREATE_IN_PROGRESS       AWS::IAM::Role           HelloWorldFunctionRole   -                      
CREATE_IN_PROGRESS       AWS::IAM::Role           HelloWorldFunctionRole   Resource creation      
                                                                           Initiated              
CREATE_COMPLETE          AWS::IAM::Role           HelloWorldFunctionRole   -                      
CREATE_IN_PROGRESS       AWS::Lambda::Function    HelloWorldFunction       -                      
CREATE_IN_PROGRESS       AWS::Lambda::Function    HelloWorldFunction       Resource creation      
                                                                           Initiated              
CREATE_IN_PROGRESS       AWS::Lambda::Function    HelloWorldFunction       Eventual consistency   
                                                                           check initiated        
CREATE_IN_PROGRESS       AWS::ApiGateway::RestA   ServerlessRestApi        -                      
                         pi                                                                       
CREATE_IN_PROGRESS       AWS::ApiGateway::RestA   ServerlessRestApi        Resource creation      
                         pi                                                Initiated              
CREATE_COMPLETE          AWS::ApiGateway::RestA   ServerlessRestApi        -                      
                         pi                                                                       
CREATE_IN_PROGRESS       AWS::ApiGateway::Deplo   ServerlessRestApiDeplo   -                      
                         yment                    yment47fc2d5f9d                                 
CREATE_IN_PROGRESS       AWS::Lambda::Permissio   HelloWorldFunctionHell   -                      
                         n                        oWorldPermissionProd                            
CREATE_IN_PROGRESS       AWS::Lambda::Permissio   HelloWorldFunctionHell   Resource creation      
                         n                        oWorldPermissionProd     Initiated              
CREATE_IN_PROGRESS       AWS::ApiGateway::Deplo   ServerlessRestApiDeplo   Resource creation      
                         yment                    yment47fc2d5f9d          Initiated              
CREATE_COMPLETE          AWS::Lambda::Function    HelloWorldFunction       -                      
CREATE_COMPLETE          AWS::Lambda::Permissio   HelloWorldFunctionHell   -                      
                         n                        oWorldPermissionProd                            
CREATE_COMPLETE          AWS::ApiGateway::Deplo   ServerlessRestApiDeplo   -                      
                         yment                    yment47fc2d5f9d                                 
CREATE_IN_PROGRESS       AWS::ApiGateway::Stage   ServerlessRestApiProdS   -                      
                                                  tage                                            
CREATE_IN_PROGRESS       AWS::ApiGateway::Stage   ServerlessRestApiProdS   Resource creation      
                                                  tage                     Initiated              
CREATE_COMPLETE          AWS::ApiGateway::Stage   ServerlessRestApiProdS   -                      
                                                  tage                                            
CREATE_COMPLETE          AWS::CloudFormation::S   moveobject               -                      
                         tack                                                                     
-------------------------------------------------------------------------------------------------

CloudFormation outputs from deployed stack
-------------------------------------------------------------------------------------------------
Outputs                                                                                         
-------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole                                                   
Description         Implicit IAM Role created for Hello World function                          
Value               arn:aws:iam::************:role/moveobject-                                  
HelloWorldFunctionRole-2vpYoNBI2ZkL                                                             

Key                 HelloWorldApi                                                               
Description         API Gateway endpoint URL for Prod stage for Hello World function            
Value               https://v1o97s67gf.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/     

Key                 HelloWorldFunction                                                          
Description         Hello World Lambda Function ARN                                             
Value               arn:aws:lambda:ap-northeast-1:************:function:moveobject-             
HelloWorldFunction-Fh6UhaLBn4LT                                                                 
-------------------------------------------------------------------------------------------------


Successfully created/updated stack - moveobject in ap-northeast-1

(mypy) myuser@mymac moveobject % 

```

# 4. Lambdaファンクションの設定

S3バケットにオブジェクトが作成された時にLambdaファンクションが起動するように、ファンクションにトリガーを追加します。

AWSコンソールから、作成したLambdaファンクションの詳細画面にアクセスし、設定タブにアクセスします。
![スクリーンショット 2024-07-26 9.38.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/513b46bb-4d8d-8678-11d4-ef65b2726cf9.png)

「トリガーを追加」をクリックします。
![スクリーンショット 2024-07-26 9.39.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/330fb423-4771-95aa-31b0-9a1c452170c2.png)

バケット名に1.で作成したバケットを選択します。
イベントタイプはデフォルトで「全てのオブジェクト作成イベント」が設定されているので、そのままにします。
![スクリーンショット 2024-07-26 9.43.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/545f1a58-d42e-1d11-457f-eb44c99e03ea.png)

入力が完了したら、「追加」をクリックして、トリガを追加します。
![スクリーンショット 2024-07-26 10.05.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/cdcfc613-d081-e737-869c-7943b4967209.png)
トリガーが追加されました。


![スクリーンショット 2024-07-26 9.43.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/53176efa-490f-decb-7416-ee2c88132af7.png)

![スクリーンショット 2024-07-26 9.44.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/a7ea1836-7d03-d356-ed69-af31025e4549.png)

Lambdaファンクションの環境変数を設定します。
今回は、Autonomous Databaseに接続する際のユーザ名、パスワード、接続文字列を環境変数に設定し、Lambdaファンクションから参照します。
PYTHON_USERNAME：ユーザ名
PYTHON_PASSWORD：パスワード
PYTHON_CONNECTSTRING：接続文字列

左側のメニューから「環境変数」をクリックし、「編集」をクリックします。
![スクリーンショット 2024-07-26 9.44.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/94ca0ea0-12bc-2531-1a98-c608d2ff6567.png)

「環境変数の追加」をクリックして入力欄を追加し、PYTHON_USERNAME、PYTHON_PASSWORD、PYTHON_CONNECTSTRINGの値をそれぞれ設定して「保存」をクリックします。
![スクリーンショット 2024-07-26 9.46.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/ff07365d-c8dd-424c-2b7b-9e09e003deca.png)

環境変数が設定できました。
![スクリーンショット 2024-07-26 9.46.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/b5f5ce95-447a-fa1d-0c22-370cd24031d8.png)

![スクリーンショット 2024-07-26 9.46.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/979cca27-d3b3-ce94-661a-acdf8c62ce2b.png)



# 5. 動作確認
この時点では、OCI Object Storageバケット、Amazon S3バケットにファイル（オブジェクト）はありません。

＜OCI Object Storage＞
![スクリーンショット 2024-07-26 9.48.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/71e92fcc-f135-e868-c8db-9f95bca3e769.png)

＜Amazon S3＞
![スクリーンショット 2024-07-26 9.48.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/fa3a0067-0f6d-610b-207d-42940a143230.png)

S3バケットにファイルempdata1.csvをアップロードします。
![スクリーンショット 2024-07-26 9.49.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/f293e6e4-a9eb-9fb9-48fc-6c6dee88e133.png)

アップロードが完了したら、「閉じる」をクリックします。
![スクリーンショット 2024-07-26 9.49.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/18dddb89-075c-1683-91c6-2684625bccc4.png)

S3バケットにアップロードしたはずファイルがありません。
![スクリーンショット 2024-07-26 9.49.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/eb343cc2-1492-69c1-dcf9-0f127bbd60df.png)

Object Storageのオブジェクトの表示をリフレッシュします。
![スクリーンショット 2024-07-26 9.49.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/f0ff446e-8500-a0e1-2844-328c1561675e.png)

S3バケットにアップロードしたファイルが同じ名前のObject Storageバケットに移動されていることが確認できました。
![スクリーンショット 2024-07-26 9.50.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/67ab1fee-2c2c-7b07-32ac-9f51854a8908.png)

![スクリーンショット 2024-07-26 9.50.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784824/4ab86239-e016-728d-f416-8065e9491460.png)


# まとめ
Amazon S3へのファイルのアップロードをトリガーとしてAutonomous Database内のPL/SQLプロシージャを実行し、ファイルの移動処理を行うことができることを確認できました。

# 参考文献
・[リソース・プリンシパルを使用したOracle Cloud Infrastructureリソースへのアクセス](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/serverless/adbsb/resource-principal.html#GUID-E283804C-F266-4DFB-A9CF-B098A21E496A)
・[Amazonリソース名(ARN)を使用したAWSリソースへのアクセス](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/serverless/adbsb/amazon-arn.html#GUID-BDEE5519-3807-4699-9C53-546EFD2F3A17)
・[AWS CLIの最新バージョンのインストールまたは更新](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html)
・[AWS SAM CLI のインストール](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/install-sam-cli.html)
・[sam init コマンドを使用してアプリケーションを作成する](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/using-sam-cli-init.html)
・[sam build](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-build.html)
・[sam deploy](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-deploy.html)
・[The python-oracledb driver for Oracle Database](https://oracle.github.io/python-oracledb/)
・[DBMS_CLOUD.MOVE_OBJECTプロシージャ](https://docs.oracle.com/cd/E83857_01/paas/autonomous-database/serverless/adbsb/dbms-cloud-subprograms.html#GUID-A3E59F80-EDF9-4314-9664-F10F4BACA3FC)