AppFlowでSalesforceとS3をつなぐ設定手順
S3バケットを準備し、Amazon AppFlowでSalesforceを送信元、Amazon S3を送信先に設定する流れを説明します。Apexから直接S3を呼びたいときの注意点も併せて書きます。
AppFlowを使う理由
SalesforceのデータをAmazon S3へ運ぶ方法は2つあります。1つはApexでS3のAPIを直接呼ぶ方法、もう1つはAmazon AppFlowでコードを書かずにつなぐ方法です。AppFlowは接続・認証・スケジュール実行を画面設定だけで済ませられるので、定期的なデータ連携ではまずこちらを検討します。Apexで直接呼ぶのは、AppFlowの対応範囲を超える細かい制御が要るときだけです。
S3バケットを準備する
Amazon S3のコンソールでバケットを作成する
バケット名は、ほかのAWSアカウントのバケットとも重複しない一意な名前を付けます。リージョンは「アジアパシフィック(東京)ap-northeast-1」のように、Salesforce組織や利用者に近いリージョンを選びます。
オブジェクト所有者を確認する
現在は新規バケットの既定が「ACL無効(バケット所有者の強制)」です。バケットの所有者がすべてのオブジェクトを所有する設定で、アクセス制御はバケットポリシーだけで行います。特別な事情がなければ既定のままにします。
バケットのバージョニングを選ぶ
既定は無効です。誤って上書き・削除したときに過去バージョンへ戻したいなら有効にします。
暗号化の設定を確認して作成する
サーバー側の暗号化はSSE-S3が既定で選ばれています。そのまま「バケットを作成」を押します。
Amazon AppFlowでフローを作成する
Amazon AppFlowでフローを作成する
「フローを作成」を押し、フロー名を入力します。
送信元にSalesforceを指定する
「接続する」を押し、接続名を入力します。Salesforce環境は「Production」(本番組織)と「Sandbox」から、実際に接続する組織に合わせて選びます。認証はAppFlowが自動で用意する接続用アプリケーションによるOAuth認可で、Salesforce側で事前に接続アプリを作る必要はありません。認可画面で許可を押すと接続が完了します。
連携するSalesforceオブジェクトを選ぶ
取引先など、転送したいオブジェクトを選びます。
送信先にAmazon S3を指定する
準備したバケットを選びます。バケットが別リージョンにあると選択時にエラーになるので、S3バケットと同じリージョンでフローを作成します。
フィールドのマッピングとトリガーを設定する
「フィールドを直接マッピングする」を選び、フロートリガーは「オンデマンドで実行」を選びます。
フローを作成して実行する
設定内容を確認してフローを作成し、「フローを実行」を押します。実行履歴で成功・失敗を確認します。
送信先バケットの書き込み権限
AppFlowコンソールでS3を送信先に選ぶと、必要なバケットポリシーはコンソールが自動で付与します。API・SDK経由でフローを作る場合は、次のポリシーを自分でバケットに設定する必要があります。
{
"Statement": [
{
"Effect": "Allow",
"Sid": "AllowAppFlowDestinationActions",
"Principal": { "Service": "appflow.amazonaws.com" },
"Action": [
"s3:PutObject",
"s3:AbortMultipartUpload",
"s3:ListMultipartUploadParts",
"s3:ListBucketMultipartUploads",
"s3:GetBucketAcl",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::myBucketName",
"arn:aws:s3:::myBucketName/*"
],
"Condition": {
"StringEquals": { "aws:SourceAccount": "myAccountId" },
"ArnLike": { "aws:SourceArn": "arn:aws:appflow:*:myAccountId:flow/*" }
}
}
]
}AppFlowサービスにs3:PutObjectなどを許可する例。myBucketNameとmyAccountIdは自分の値に置き換えます。
⚠️ Conditionのaws:SourceAccountとaws:SourceArnは、他のAWSアカウントのAppFlowから同じバケットを書き換えられてしまう「confused deputy」を防ぐための設定です。手動でポリシーを書くときは必ず入れます。
Apexから直接S3を呼びたいとき
AppFlowでは足りない細かい制御(1レコードずつの即時アップロードなど)をApexから行うときは、アクセスキー・シークレットキーをApexやRemote Site Settingsに直書きしません。代わりに名前付き認証情報(Named Credential)と外部認証情報(External Credential)を使います。
外部認証情報の認証プロトコルに「AWS Signature 4」を選ぶと、アクセスキー・シークレットキーの保管と、リクエストへのAWS署名の付与をSalesforceが代わりに行います。リモートサイト設定はドメインを許可リストに載せるだけで、署名やキーの保管はApex側で自分で実装する必要がありました。名前付き認証情報はここまで含めて設定画面だけで完結します。
HttpRequest req = new HttpRequest(); req.setEndpoint('callout:S3_Credential/example-bucket/upload.csv'); req.setMethod('PUT'); req.setHeader('Content-Type', 'text/csv'); req.setBody(csvBody); Http http = new Http(); HttpResponse res = http.send(req);
Named Credential経由でS3へPUTする例。エンドポイントにキーを直接書きません。
⚠️ Apexのコールアウトには上限があります。1トランザクションで送れるコールアウトは合計100回まで、コールアウトの累計タイムアウトは120秒までです。ヒープサイズは同期処理で6MB、非同期処理で12MBまでなので、大きなファイルをループで送るとどちらかに先に当たります。件数が多いときはAppFlowかBatch Apexへ処理を分けます。
Salesforce側にアップロード済みのファイルをS3へ転送したいときは、AttachmentではなくContentVersionとContentDocumentLinkからファイル本体とレコードへの関連付けを取得します。Attachmentは新しいファイル管理の仕組みではないため、新規の実装では使いません。
ここで間違えやすい
| 間違い | 何が起きるか |
|---|---|
| バケット作成時に暗号化を無効にしようとする | 選択肢自体が無く、SSE-S3が既定で有効になります |
| S3バケットとは別リージョンでフローを作る | 送信先選択時にエラーになります |
| APIでフローを作ってバケットポリシーを設定し忘れる | AppFlowがバケットへ書き込めず失敗します |
| AWSのアクセスキーをApexのコードに直書きする | 認証情報が変わるたびにコード修正とデプロイが要ります。名前付き認証情報を使います |
| ループで大量のファイルをコールアウトで送る | コールアウト回数上限やヒープ上限に当たって途中で止まります |
確認した環境
- 2026年9月/Salesforce Summer '26(APIバージョン67.0)時点のdeveloper.salesforce.com・help.salesforce.comの公式ドキュメントで、名前付き認証情報とApexコールアウトの上限を確認しています
- AWS側はdocs.aws.amazon.comのAmazon AppFlowユーザーガイドとAmazon S3ユーザーガイドで、バケット作成の既定値とバケットポリシーの要件を確認しています
まとめ
- 定期的なデータ連携はAmazon AppFlowをまず検討します。Apexで直接呼ぶのは細かい制御が必要なときだけです
- S3バケットの暗号化は2023年1月5日以降すべて既定で有効になり、無効にはできません
- AppFlowコンソールでS3を送信先にすると、必要なバケットポリシーは自動で付きます。API経由で作るときは自分で設定します
- Apexから直接S3を呼ぶときは、アクセスキーをコードに書かず名前付き認証情報とAWS Signature 4の外部認証情報を使います
- Apexのコールアウトは1トランザクション100回・累計120秒・ヒープ6MB(非同期12MB)が上限です
Salesforceの導入・運用についてご相談ください
導入前の検討から、お使いの環境の改修・運用、AIとの連携まで承ります。状況を伺ったうえで、進め方をご提案します。