ファイル連携・EDI

ファイルが届いていなかった。気づいたのは月曜だった。

ファイル転送は社内で最も古い仕事で、たいてい最も見られていません。cron 上のシェルスクリプト、リトライなし、通知なし、何が動いたかの記録なし。Dagu は転送コマンドをそのまま残し、その周りに到着待ち、検証、リトライ、履歴を足します。

ファイルの到着待ちは、自分で保守するポーリングループではなくステップ
どの転送にもリトライと失敗通知が付く
社内ネットワークの中で動くので、ファイルがクラウドを経由しない
セルフホストは無料。接続単位のライセンスなし
01

誰も刷新しない連携

受注ファイル、請求データ、給与の抽出、銀行データ、在庫連携は、いまもファイルとして定時に動いています。転送そのものは解決済みの問題です。足りていないのは、たいていその周辺すべてです。

  • スクリプトはファイルの送り方を知っています。相手先が落ちているときにどうするかは知りません
  • 失敗は下流の人間が、しばしば数日後に見つけます。ファイルが来ていない状態と、単に静かな日の区別が付かないからです
  • どのファイルがいつ動いて、完全だったのかを誰も答えられません。記録している場所がないからです
02

ファイルの到着待ちはステップになる

多くのスケジューラでは、sleep とカウンタでポーリングループを書き、その後ずっと保守することになります。Dagu には待機アクションがあるので、到着の待ち時間はコードではなく宣言になり、来なかったファイルは実行をハングさせずに失敗させます。

  • wait.file が、指定したパスの出現、または消滅を、指定した間隔で待ちます
  • タイムアウトを付けることで、届かなかった配信が「誰かが見るまで止まったジョブ」ではなく「通知付きの失敗」になります
  • 検証は独立したステップなので、途中で切れたファイルや壊れたファイルは取り込みに流れず、そこで止まります
受信: 待つ、検証する、取り込む、保管する
# edi-inbound.yaml
schedule: "0 * * * *"
max_active_runs: 1

s3:
  bucket: corp-edi-archive
  region: ap-northeast-1

steps:
  - id: wait_for_delivery
    action: wait.file
    with:
      path: /var/spool/edi/orders.csv
      poll_interval: 30s
    timeout_sec: 1800

  - id: verify
    run: |
      cd /var/spool/edi
      sha256sum -c orders.csv.sha256
    depends: wait_for_delivery

  - id: import
    run: /opt/core/import-orders.sh /var/spool/edi/orders.csv
    depends: verify
    retry_policy:
      limit: 2
      interval_sec: 300

  - id: archive
    action: s3.upload
    with:
      key: edi/inbound/orders.csv
      source: /var/spool/edi/orders.csv
    depends: import

  - id: mark_done
    action: file.move
    with:
      source: /var/spool/edi/orders.csv
      destination: /var/spool/edi/done/orders.csv
      create_dirs: true
    depends: archive

handler_on:
  failure:
    run: /opt/edi/notify-failure.sh

mail_on:
  failure: true
03

静かに失敗することが問題

大きな音を立てて失敗する転送は小さな問題です。静かに失敗する転送は、後から突き合わせをやり直すプロジェクトになります。足す価値があるのは運用の層です。

  • retry_policy が、相手先が一時的に到達できない状況を吸収します。転送の失敗はほとんどこれです
  • mail_on.failure と handler_on.failure で、届かなかった配信が同じ時間内に担当者へ届きます
  • max_active_runs: 1 が、遅れた転送と次の定時実行の重なりを止め、同じファイルを二重に送ることを防ぎます
04

両端とも自社の境界の内側に置く

ファイルを社外に出せないのは、金融、医療、公共では普通の前提です。自社のホスト上で動く単一バイナリなら、SFTP で相手先に届き、基幹システムにはローカルで届きます。経路に第三者のサービスが入りません。

  • sftp.upload と sftp.download が鍵認証でファイルを転送します。踏み台ホストも指定できます
  • 同じワークフローから、SSH でオンプレのシステムに、オブジェクトストレージに保管用のコピーに、それぞれ到達できます
  • ベンダーのクラウドを中継しないため、データの所在と監査の説明が単純なままです
送信: 抽出、チェックサム、送信
# edi-outbound.yaml
schedule: "30 18 * * 1-5"
max_active_runs: 1

ssh:
  user: edi
  host: sftp.partner.example.com
  key: ~/.ssh/edi_key

steps:
  - id: extract
    run: /opt/core/export-invoices.sh ./outgoing/invoices.csv
    retry_policy:
      limit: 2
      interval_sec: 120

  - id: checksum
    run: |
      cd ./outgoing
      sha256sum invoices.csv > invoices.csv.sha256
    depends: extract

  - id: send_file
    action: sftp.upload
    with:
      source: ./outgoing/invoices.csv
      destination: /inbound/invoices.csv
    depends: checksum
    retry_policy:
      limit: 3
      interval_sec: 60

  - id: send_checksum
    action: sftp.upload
    with:
      source: ./outgoing/invoices.csv.sha256
      destination: /inbound/invoices.csv.sha256
    depends: send_file

handler_on:
  failure:
    run: /opt/edi/notify-failure.sh

mail_on:
  failure: true
05

ファイルではなく、証跡を残す

障害の後で問われるのは、たいていファイルの中身ではありません。いつ届いたか、完全だったか、誰が再実行したかです。

  • 実行ごとにステップ単位のログ、状態、所要時間、リトライ回数が残ります
  • オブジェクトストレージへの保管をワークフローのステップにすることで、保存期間が習慣ではなくスケジュールになります
  • 再実行も同じ記録経路を通るため、手作業での復旧が自動実行と同じだけ見えます
06

接続単位ではなくサーバー単位の課金

マネージドファイル転送製品は、たいてい接続数、取引先数、または転送サーバー数で課金されます。取引先が増えるたびに請求が増えるのはそのためです。

  • コミュニティ版のセルフホストは無料で、サーバー数もワーカー数も無制限です
  • ライセンス版は Dagu サーバー単位の課金で、SSO、権限分離、監査ログが付きます
  • 取引先を増やす作業はワークフローファイルを 1 つ増やすことであり、ライセンス数は変わりません
07

マネージドファイル転送製品のほうが適している場合

Dagu は転送をスケジュールし、監視します。MFT プラットフォームそのものではありませんし、本当に製品が必要な要件もあります。

  • プロトコルの幅。AS2、OFTP2、認定 EDI VAN 接続が必要なら、そのために作られた製品を使ってください
  • 取引先向けのセルフサービス画面、取引先ごとの認証情報のローテーション、否認防止の受領証は、MFT の機能でありスケジューラの機能ではありません
  • 認定された転送製品を要求するコンプライアンス要件は、技術的に何ができるかに関わらず、汎用のオーケストレータを受け入れません

FAQ

導入前によくある質問

マネージドファイル転送製品を置き換えられますか?

定時の SFTP とファイルベースの連携についてはたいてい置き換えられます。転送を実行し、到着を待ち、検証し、リトライし、通知し、履歴を残します。AS2、OFTP2、認定 EDI VAN 接続、取引先向けポータル、否認防止の受領証については置き換えられません。それらは MFT プラットフォームの機能で、スケジューラがそう装うべきではありません。

定時ではなく、ファイルの到着で起動するには?

短い間隔のスケジュールで実行し、先頭に wait.file ステップを置いてください。パスを監視し、現れた時点で後続に進みます。ステップにタイムアウトを付けておけば、来なかった配信は永久に待たずに失敗して通知されます。送信側から呼べる場合は、webhook で外部から実行を起動することもできます。

対応しているプロトコルは?

SSH 上の SFTP が sftp.upload と sftp.download として組み込まれており、S3 互換のオブジェクトストレージも組み込みです。それ以外は通常のコマンドステップとして実行するため、FTPS、rsync、ベンダー製クライアントなど既存のツールが、スケジュールと監視に包まれた状態でそのまま動きます。

認証情報はどう扱いますか?

SSH の鍵認証が既定で、相手先が踏み台の内側にある場合は踏み台も指定できます。シークレットはワークフロー側で宣言し、環境変数、ファイル、Vault、クラウドのシークレット管理などのプロバイダから解決します。値は実行ログで伏字になります。

インターネットに接続できない環境でも動きますか?

はい。Dagu は外部データベースやブローカーを必須としない自己完結のバイナリなので、オンプレミスや閉域ネットワークで動作します。分散実行も自社ネットワーク内のコーディネーターとワーカーの間の gRPC で完結します。

次のステップ

まず 1 本から始める。

Dagu を入れて、いま cron で動いているスクリプトを 1 本だけ YAML に移し、実際の実行履歴で判断してください。