ラジオ体操の時間にファイル転送したいんだよねぇ 〜AWS Transfer for SFTP〜

AWS運用自動化サービス「Cloud Automator」

あ〜た〜らし〜い、朝が〜きた〜

おはようございます。技術1課の木次です。いっちに〜
皆さんラジオ体操してますか?さんし〜

今週1週間はリモートワーク勤務が推奨されています。(2019年もテレワーク・デイズに参加いたします)
ずーっと自宅だと体に悪いので、期間中はなるべくラジオ体操をやっています。いっちに〜 さんし〜

SFTP で AWS 側にファイル転送

古いシステムやパッケージ連携などで、ファイル転送に SFTP を利用するケースがあります。
SFTP とは SSH File Transfer Protocol の略で、文字通り SSH 経由でファイル転送をするため、従来の FTP に比べてセキュアな通信が可能です。

この SFTP で AWS 側にファイル転送する場合、EC2 インスタンスをたてて、というやり方もありますが、可用性を考えるとやりたくないですよね。
そのような場合、AWS Transfer for SFTP を利用すると幸せになれます。

AWS Transfer for SFTP

昨年の re:Invent 2018 で発表されたマネージドな SFTP サービスです。
転送したファイルは S3 に保存してくれるので、やろうと思えばサーバーレスな環境を構築できます。

気になる金額ですが、1時間ごとの料金になります。(それ以外にデータアップロードとダウンロードの転送料金も発生)
東京リージョンだと、1 時間あたり 0.3USD。常時稼働した場合、1日で 7.2 USD。1月だと約 216 USD です。

特定の時間だけ利用したい

いやー、ファイル転送するのは朝方だけなんだよねぇ。1時間だけでいいんだよ。

オンプレなら難しいですが、AWS なら 1時間だけ 大丈夫です。スケジュール実行した Lambda から AWS Transfer for SFTP を作成・削除してみましょう。
せっかくなので、ラジオ体操中にファイル転送を試してみます。いっちに〜 さんし〜

おおまかな流れは以下になります。

  1. 【CloudWatch】AM 6:00 スケジュール実行
  2. 【Step Functions】Transfer Server を作成
  3. 【Step Functions】50分待機
  4. 【クライアント】AM 06:35 ファイル転送
  5. 【Step Functions】Transfer Server を削除

ポイントは Step Functions。
2 で作成した Transfer Server のサーバーID をステートとして保持し、4 で削除のために利用します。

AWS Step Functions

AWS Step Functions は、視覚的なワークフローを使用して、分散アプリケーションとマイクロサービスのコンポーネントを調整できるマネージドなサービスです。ASL (Amazon States Language) と呼ばれる JSON 形式の言語でワークフローを定義できます。

このワークフロー内で、タスクを定義して Lambda を呼び出します。
Lambda 自身はステートレスなので状態(ステート) を保持できせん。ですが、Step Functions を利用すると、ワークフロー内で値を引き渡すことができます。

ワークフローを下記のように定義します。状態遷移はシンプルに上から下へ流れるだけです。

StartAt 項目では、最初に起動するステートを設定し、Next 項目で次に実行するステートを設定します。最後のステートには End 項目に true を設定します。

処理詳細

細かく見ていきましょう。

1. AM 6:00 スケジュール実行

CloudWatch Events で 日本時間 AM 6:00 (0 21 * * ? *) に起動するルールを作成します。UTCなので、そこは注意です。
起動するターゲットとして作成した Step Functions ステートマシン を選択し、入力値として 定数(JSON) を渡します。

この入力値は Lambda 内で利用します。

2. Transfer Server を作成

CreateServer ステートでは、ステートタイプに Task を指定して Transfer Server を作成する Lambda を呼び出します。

Transfer は比較的新しいサービスのため、boto3 モジュールと一緒にデプロイしてください。
対応していない場合は [ERROR] UnknownServiceError: Unknown service: 'transfer' と表示されます。

  • create_server
    • SFTP サーバーを作成します。戻り値のサーバーID は削除時にも利用します。
    • CloudWatch Logs にログ保存するためのロールを指定します。
  • upsert_cname_record
    •  クライアント側からのエンドポイントを固定するため、CNAME レコードセットを作成します。
    • 事前に Route 53 にホストゾーンを作成しておきます。
  • create_user
    •  クライアントから接続するために、SFTP にユーザーを作成します。
    • サンプルのため SSH 公開鍵は環境変数から取得しています。実際には SSM パラメータストア や Secrets Manager を検討した方がいいでしょう。

3. 50分待機

ステートタイプに Wait を指定して、待機する秒数を設定しています。

4. AM 06:35 ファイル転送

他サーバーに sftp を 実行するシェルを用意して、AM 6:35 (35 21 * * *) に実行されるように cron を仕掛けます。

バッチファイルの中身では PUT コマンドを記述します。

5. Transfer Server を削除

  • delete_server
    • SFTP サーバーを削除します。作成したユーザーも一緒に削除されます。
  • delete_cname_record
    • 作成した CNAME のレコードセットを削除します。

実際にラジオ体操やってきた

ということで、ラジオ体操をやっている公園にやってきました。自宅から徒歩30分くらい。程よい距離で散歩にも適しています。

ラジオ体操は 6:30 スタート。
最初は第一体操から始まり、第二体操へ。そして40分頃に終了となります。

1日目

恥ずかしくて端っこから参加。
おいおい結構しんどいぞ、汗だらだら。そしてラジオ体操第二をすっかり忘れてる。。。

2日目

勇気を出して輪の中へ。いつか、あの真ん中のステージに立ちたい。いっちに〜 さんし〜

3日目

より前進。
3日目には恥ずかしさはなくなり、第二体操も8割くらい出来るように。気持ちいい〜。いっちに〜 さんし〜

結果は

さて、ファイルは届いているでしょうか。まずは Step Functions ワークフローの結果を確認します。

実行ステータスは成功 。開始と終了時間も想定通りです。

指定した S3 バケットにファイルが届いていました。更新日時も想定通りです。
やったね。

最後に

ラジオ体操はテレワーク・デイズ期間だけと思っていましたが、体と脳が刺激されて、その後の仕事がはかどるような気がしました。
せっかくなので、リモートワークの日は積極的に行こうと思います。

今日はこのへんで失礼します。いっちに〜 さんし〜

AWS運用自動化サービス「Cloud Automator」