SalesforceのデータをAmazon AppFlowでSnowflakeに増分連携してみた

SalesforceのデータをAmazon AppFlowでSnowflakeに増分連携してみた

SalesforceのデータをAppFlowでSnowflakeに連携する方法を実装・検証しました。S3経由での連携手順と、設定時のポイント、実際の増分転送結果まで詳しく紹介します。
2026.07.06

データ事業本部の鈴木です。

SalesforceのデータをAppFlowでSnowflakeに連携したいことがあったので、どのように実現できるか確認しました。
SalesforceからAmazon S3の連携はよく例があるのですが、Snowflakeへは意外と情報が少なかったので、現時点でどのようにできるかをご紹介できればと思います。

もちろんS3に連携して、外部ステージから読み込むのもアリと思います。今回紹介する機能も内部的にはそのようになっていました。
S3への連携は以下が参考になります。

https://dev.classmethod.jp/articles/cdk-appflow-salesforce-to-s3-data-load/

以降にSalesforceのデータをSnowflakeに増分連携するAppFlowの設定と、データ連携した様子をご紹介します。

1. データ連携元・連携先の準備

i. Salesforce環境の準備

Salesforce Developer Edition へのサインアップを行い、Developer Editionの環境を用意しました。

https://developer.salesforce.com/docs/atlas.ja-jp.api_rest.meta/api_rest/quickstart_dev_org.htm

今回は商談オブジェクトのデータを使いました。

Salesforce標準オブジェクトは以下が参考になりました。

https://qiita.com/na0AaooQ/items/c2678f5e809923fa9fb5

ii. Snowflake環境の準備

検証向けに、AppFlow向けのユーザーを作成しました。

CREATE USER appflow_user
  PASSWORD = '<ユーザー向けのパスワードを入力する>'
  DEFAULT_ROLE = SYSADMIN
  DEFAULT_WAREHOUSE = COMPUTE_WH;

今回はあくまで検証なので、SYSADMINを付与しておきました。実際は最小権限のロールを付与することをお勧めします。

その次に、AppFlow向けのデータベース・スキーマを作成しました。また、その下にSalesforceから取得する商談向けのテーブルを作成しました。
実際にシステムを構築する際は、ここでSalesforceから取得するデータを格納するためのテーブルを作成します。
商談オブジェクトのカラム全てを取り込むと、AppFlowのフロー作成画面での設定が動作確認の目的に対して煩雑なため、ここではいくつかに絞っておきました。

CREATE DATABASE APPFLOW_DB;
CREATE SCHEMA APPFLOW_DB.APPFLOW_SCHEMA;

CREATE OR REPLACE TABLE APPFLOW_DB.APPFLOW_SCHEMA.SALESFORCE_OPPORTUNITY (
  ID                       STRING        NOT NULL,
  NAME                     STRING,
  ACCOUNT_ID               STRING,
  OWNER_ID                 STRING,
  CREATED_DATE             TIMESTAMP_NTZ,
  LAST_MODIFIED_DATE       TIMESTAMP_NTZ,
  IS_DELETED               BOOLEAN,
  LOADED_AT                TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP(),
  PRIMARY KEY (ID)
);

また、AppFlowがSalesforceから取得したデータをSnowflakeにロードする際に使用するストレージ統合と外部ステージを作成しました。
この操作はガイドに解説があるのでそちらに譲ります。

https://docs.snowflake.com/ja/user-guide/data-load-s3-config-storage-integration

S3バケットおよびIAMロールはAppFlowフローを作成するのと同じAWSアカウントで作成しておくこととします。

最終的に、以下の状態にしておきました。

Snowflake側の準備の結果

2. AppFlowの準備

i. Salesforce接続の作成

まずはSalesforceへの接続を作成しました。
これは簡単で、接続 > 接続を管理より、Salesforceのコネクタを選択して、接続を作成を押しました。

Salesforce向け接続の作成1

今回はデータソースがDeveloper Edition環境だったので、OAuth グラントタイプは認証コード、Salesforce 環境はProductionを選びました。

Salesforce向け接続の作成2

PrivateLinkを有効にすることもできますが、Salesforce側でライセンスが必要なため、今回は無効としました。

接続するを押すと、データソースとの認証向けのポップアップが出るので、接続を作成するアカウントで認証しました。

データソースとの認証向けのポップアップ

認証ができればSalesforce接続の作成は完了です。

ii. Snowflake接続の作成

次にSnowflakeへの接続を作成しました。
Salesforceと同じく、接続 > 接続を管理より、Snowflakeのコネクタを選択して、接続を作成を押しました。

Snowflake向け接続の作成1

接続するSnowflake環境の設定を入力しました。
特に以下はポイントでした。

  • ウェアハウス:ユーザーが権限のあるウェアハウスの名前を入力する
  • ステージ名:S3外部ステージの完全修飾ステージ名
  • バケットの詳細:上記のS3外部ステージを設定したS3のパス
  • アカウント名:アカウントロケーター(SELECT CURRENT_ACCOUNT()で取得できる値)
  • ユーザー名:AppFlowが利用するSnowflakeユーザー
  • パスワード:上記ユーザーのパスワード

Snowflake向け接続の作成2-1

Snowflake向け接続の作成2-2

私がハマったところで、ユーザーがウェアハウスに権限がない場合、フロー設定時にデータのCOPY先テーブルが表示されない現象が起こりました。ユーザーに権限があるはずなのに表示されない場合はウェアハウス向けの権限もあるか確認してみてください。
ステージ名とバケットの詳細も、同一のS3外部ステージを指しているので注意してください。後で記載するように、フローは実行時にバケットの詳細に設定したパス+フロー名のプレフィクスに連携データを配置します。そのため、バケットの詳細に設定したパスがS3外部ステージで指定した場所に対応していないと、Snowflake側で実行されるCOPYコマンドのCOPY元が異なる場所を向いてしまい、空振りや誤ったデータのロードに繋がる可能性がありました。

また、フロー名がバケットの詳細に設定したパスに既に含まれていると、バケットの詳細に設定したパスだけでオブジェクトのパスが決まるように見えました。バケットの詳細は一度設定すると編集で変えてもフロー実行時の出力先が変わらないようにも見えたため、もし同じ現象が起これば再度接続を作り直してフローに設定すると反映されました。

アカウント名はSELECT CURRENT_ACCOUNT()で取得できるアカウントロケーターを設定する必要がありました。

こちらは必要なパラメータを入力し、接続するを押して無事にエラーなく作成されたら作業完了です。

iii. フローの作成

フロー > フローを作成より、新規にフローを作成しました。
フロー名と説明を入力し、ほかはデフォルトとしました。

フローの詳細を指定

フローを設定で、作成した接続を指定しました。
送信元ではSalesforceオブジェクトとして商談を、送信先は作成した商談テーブルをSnowflakeオブジェクトとして選択しました。この設定から、連携オブジェクトにつき1本フローを作成する必要があることが分かります。

フローを設定1

エラー処理も設定可能です。

フローを設定2

フロートリガーも設定しました。

今回は増分転送を確認したかったので、スケジュール実行を設定しました。

フローを設定3

続いてデータ送信元/送信先でデータフィールドをマッピングしました。
今回は手動でマッピングしました。

データフィールドをマッピング1

送信元から送信先フィールドへのマッピングで対応のペアを選び、マップフィールドを押して、マッピングを追加しました。

データフィールドをマッピング2

ここでポイントとなるのが、その他の設定にある削除されたレコードのインポートです。増分転送の場合はデータ送信元で削除された場合はデータ送信先にもその情報を送りたいと思うので、その場合はここをチェックします。送信元が小さいデータで、フローで連携したデータで毎回全量洗い替えするような場合は不要と思います。

連携フローではフィルタを設定することも可能でした。今回はなしで進めました。

フィルタ設定

最後に設定を見直して作成を完了しました。

フローは最初は下書きステータスなので、フローをアクティブ化でスケジュール実行を開始しました。

フローをアクティブ化

以下のようになればスケジュール実行が開始します。

フローをアクティブ化済

3. AppFlowフローの増分転送結果を確認する

i. 結果の確認

ここまでの説明でフローは増分転送で実行されているので、後は転送を待つだけとなります。
フローの実行履歴を確認するとどのような転送がいつ行われたのか概要を把握できました。

フローの実行履歴

Snowflakeの連携先テーブルを確認すると、Salesforceのデータが連携できていました。

Snowflake連携先テーブル

いくつか私が検証用に作成・削除データが入っていますが、増分実行の場合、初回は直近30日以内のデータが連携されます。

https://docs.aws.amazon.com/ja_jp/appflow/latest/userguide/flow-triggers.html

IS_DELETEDカラムがTRUEの場合、削除済みレコードとなります。

レコードの状態はフロー実行断面のものが連携されました。
AppFlow向けテスト商談は作成後すぐに削除したため、削除後の状態のみ連携されました。
AppFlow向け商談newは作成して削除する間に一度連携を挟んでいるため、IS_DELETEDカラムがTRUEのものとFALSEのものが両方あります。
ほかのレコードもIS_DELETEDカラムがTRUEですが、これは事前に作成・削除していたレコードです。

オブジェクトはSalesforceの商談ページから、適当な名前でデータを作成しました。

商談データ作成

個別の商談ページから削除を押すと、ゴミ箱に移動し、論理削除がされます。これがIS_DELETEDカラムがTRUEの状態です。

商談の削除1

商談の削除2

ii. オブジェクトのSnowflakeへの連携方法確認

S3上のオブジェクトも確認しておきます。
以下のようにバケットの詳細に設定したパス+フロー名のプレフィクスに連携データが配置されていました。

S3上のデータ

フローに設定したユーザーでクエリ履歴を確認すると、COPYコマンドで上記のパスからデータをロードしたことが分かります。

COPYコマンド実行履歴

これらのことから、フローは一度S3にSalesforceより取得したデータを出力し、外部ステージ経由でCOPYコマンドでロードをすることが伺えました。もし認証など設定が上手くできているのにテーブルにロードできない場合は、ステージ上の取得データとCOPYコマンドの参照元が一致しているか確認してみると良いです。

最後に

SalesforceのデータをAmazon AppFlowでSnowflakeに増分連携してみたのでご紹介しました。
以前からある機能ではありますが、意外と設定方法の情報が少なかったり、細かな挙動は試してみないと分からなかったので、改めてまとめてみました。

若干設定にコツが必要なところもありましたが、価格も安いですし、必要に応じてPrivateLink経由の通信もできるため、かなり良い仕組みと思います。

https://docs.aws.amazon.com/ja_jp/appflow/latest/userguide/private-flows.html

参考になりましたら幸いです。


Snowflakeの導入支援はクラスメソッドに!

クラスメソッドでは Snowflake の導入を支援しております。
製品の詳細や支援の内容についてお気軽にお問い合わせください。

Snowflakeの詳細を見る

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事