Salesforce ApexからAmazon S3バケットのファイルを操作してみた

Salesforce ApexからAmazon S3バケットのファイルを操作してみた

Clock Icon2025.02.18

はじめに

ApexからAmazon S3のファイルを操作する機能を実装したので、備忘録として残します。

AWS側の準備

S3バケットを作成する

下記の名前のS3バケットを作成します。

  • salesforce-api-s3-demo-bucket

デモ用のファイルを作成し、S3バケットにアップロードします。

s3demo.json
{
    "text": "S3 Access Demo"
}

S3バケットとファイル

IAMユーザーを作成する

APIリクエストのためにIAMユーザーを作成します。
IAMユーザーには下記のカスタマーインラインポリシーをアタッチし、作成したS3バケットのみアクセスを許可します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*"
            "Resource": [
                "arn:aws:s3:::salesforce-api-s3-demo-bucket",
                "arn:aws:s3:::salesforce-api-s3-demo-bucket/*"
            ]
        }
    ]
}

アクセスキーとシークレットを発行します。後述の外部ログイン情報プリンシパルで使用するので控えておきます。

指定ログイン情報の設定

AWSのAPIリクエストの認証処理はApexで書くこともできますが、指定ログイン情報を設定しておくことでAPIリクエストの処理を簡略化できます。

外部ログイン情報を作成する

Salesforceの設定画面のクイック検索に「指定ログイン情報」と入力し、指定ログイン情報の画面に遷移します。
外部ログイン情報のタブから新規のボタンをクリックします。
外部ログイン情報
それぞれの項目を入力、選択します。

  • 表示ラベル
    • AwsS3AccessDemo
  • 名前
    • AwsS3AccessDemo
  • 認証プロトコル
    • AWS 署名バージョン 4
  • サービス
    • s3
  • 地域
    • ap-northeast-1
      外部ログイン情報設定

プリンシパルを作成する

外部ログイン情報の画面をスクロールし、中ほどにあるプリンシパルのセクションから新規のボタンをクリックします。
プリンシパル
それぞれの項目を入力します。

  • パラメータ名
    • AwsS3AccessDemoPrincipal
  • 連番
    • 1
  • アクセスキー
    • IAMユーザーのアクセスキー
  • アクセスの秘密
    • IAMユーザーのシークレット
      プリンシパル設定

指定ログイン情報を作成する

外部ログイン情報のタブから新規のボタンをクリックします。
指定ログイン情報
それぞれの項目を入力、チェックします。

  • 表示ラベル
    • AwsS3AccessDemoCredential
  • 名前
    • AwsS3AccessDemoCredential
  • URL
    • S3バケットのURLを仮想ホスト形式で記述します。
      • https://<bucket-name>.s3-ap-northeast-1.amazonaws.com
  • コールアウトに対応
    • ON(デフォルトのまま)

その他項目はデフォルト値のままとします。
指定ログイン情報設定

権限セットを作成する

設定画面のクイック検索に「権限セット」と入力し、権限セットの画面に遷移します。
新規のボタンをクリックします。
権限セット
それぞれの項目を入力し保存します。

  • 表示ラベル
    • AwsS3AccessDemoPermissionSet
  • API 参照名
    • AwsS3AccessDemoPermissionSet
      権限セット作成

権限セットに外部ログイン情報プリンシパルアクセスを追加する

作成した権限セットのアプリケーションセクションにある外部ログイン情報プリンシパルアクセスをクリックします。
編集をクリックし、先ほど作成した外部情報プリンシパルを追加して保存します。
権限セット外部ログイン情報プリンシパルアクセス

権限セットにユーザーを割り当てる

Apexを実行するユーザーを権限セットに割り当てます。今回はシステムユーザーを割り当てました。
権限セットユーザー割り当て

備考

割り当てたユーザーにユーザーの外部ログイン情報オブジェクトへのアクセス権がない場合は、作成した権限セットもしくはプロファイルでアクセス権を付与してください。
ユーザーの外部ログイン情報の有効化

ApexからS3へのAPIリクエスト

指定ログイン情報を使用する準備ができたのでAnonyumous WindowでApexコードを実行して動作を確認します。

ファイルの取得

コールアウトの後ろにファイル名を指定してGETメソッドでリクエストします。

HttpRequest req = new HttpRequest();
req.setEndpoint('callout:AwsS3AccessDemoCredential/s3demo.json');
req.setMethod('GET');
Http http = new Http();
HttpResponse res = http.send(req);
Map<String, Object> resBody = (Map<String, Object>)Json.deserializeUntyped(res.getBody());
System.debug(resBody.get('text'));

結果

S3 Access Demo

ファイルの更新

内容を追記した同名ファイルをPUTメソッドでリクエストしアップロードします。

HttpRequest req = new HttpRequest();
req.setEndpoint('callout:AwsS3AccessDemoCredential/s3demo.json');
req.setMethod('PUT');
String json_body = '{"text": "S3 Access Demo File Upload"}';
req.setBody(json_body);
Http http = new Http();
HttpResponse res = http.send(req);
System.debug(res);

結果

System.HttpResponse[Status=OK, StatusCode=200]

アップロードしたファイルを再度取得し、更新されていることを確認します。

HttpRequest req = new HttpRequest();
req.setEndpoint('callout:AwsS3AccessDemoCredential/s3demo.json');
req.setMethod('GET');
Http http = new Http();
HttpResponse res = http.send(req);
Map<String, Object> resBody = (Map<String, Object>)Json.deserializeUntyped(res.getBody());
System.debug(resBody.get('text'));

結果

S3 Access Demo File Upload

ファイルの削除

ファイル名を指定してDELETEメソッドでリクエストします。

HttpRequest req = new HttpRequest();
req.setEndpoint('callout:AwsS3AccessDemoCredential/s3demo.json');
req.setMethod('DELETE');
Http http = new Http();
HttpResponse res = http.send(req);
System.debug(res);

結果

System.HttpResponse[Status=No Content, StatusCode=204]

S3バケットからファイルが削除されています。
S3 ファイル削除後

まとめ

指定ログイン情報を使用することでS3のファイル操作をシンプルに記述できました。
STSやIAM Rome Anywhereを使った設定についても今後検証したいと思います。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.