
Salesforce ApexからAmazon S3バケットのファイルを操作してみた
はじめに
ApexからAmazon S3のファイルを操作する機能を実装したので、備忘録として残します。
AWS側の準備
S3バケットを作成する
下記の名前のS3バケットを作成します。
- salesforce-api-s3-demo-bucket
デモ用のファイルを作成し、S3バケットにアップロードします。
{
"text": "S3 Access Demo"
}
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
- ap-northeast-1
プリンシパルを作成する
外部ログイン情報の画面をスクロールし、中ほどにあるプリンシパルのセクションから新規のボタンをクリックします。
それぞれの項目を入力します。
- パラメータ名
- AwsS3AccessDemoPrincipal
- 連番
- 1
- アクセスキー
- IAMユーザーのアクセスキー
- アクセスの秘密
- IAMユーザーのシークレット
- IAMユーザーのシークレット
指定ログイン情報を作成する
外部ログイン情報のタブから新規のボタンをクリックします。
それぞれの項目を入力、チェックします。
- 表示ラベル
- AwsS3AccessDemoCredential
- 名前
- AwsS3AccessDemoCredential
- URL
- S3バケットのURLを仮想ホスト形式で記述します。
- https://<bucket-name>.s3-ap-northeast-1.amazonaws.com
- S3バケットのURLを仮想ホスト形式で記述します。
- コールアウトに対応
- ON(デフォルトのまま)
その他項目はデフォルト値のままとします。
権限セットを作成する
設定画面のクイック検索に「権限セット」と入力し、権限セットの画面に遷移します。
新規のボタンをクリックします。
それぞれの項目を入力し保存します。
- 表示ラベル
- AwsS3AccessDemoPermissionSet
- API 参照名
- AwsS3AccessDemoPermissionSet
- 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のファイル操作をシンプルに記述できました。
STSやIAM Rome Anywhereを使った設定についても今後検証したいと思います。