Azure Storage ServiceでSFTPができるようになったのでAzure Data Factoryと連携してみた

[前回の記事](https://qiita.com/hidekko/items/d333efdd260a1c66d290)から随分間が開いてしまいましたが、その間転職したり入院したりと忙しかったです。
特に入院は前回の入院から1年もあかずに入院したので驚きました。

私は記事が書けませんでしたがその間に新しい会社でたまたま私が少しだけ教育を担当した[若いメンバーが記事](https://qiita.com/fsdg-kohei-ioroi/items/9d034a45dd4c77015961)を書いてくれました。
いや、ホントに若くて仕事ができる人って羨ましいですね。
私が同年代のときは彼ほど仕事ができませんでした。

# やってみた記事では面白くないので連携までしてみよう
新しい機能がリリースされたんでやってみました。
だけでは面白みに欠けるので、もうちょっと踏み込んで連携までやってみました。
この記事を書きだした時点ではまだ連携できていないので、実際できるかどうかわわかりません。
たぶんできますけど。

# 構成図
いつもの構成図ですね。
いつもはパワーポイントで書いて貼り付けてたんですが、今回はVisual Studio CodeのDraw.io Integrationという拡張機能で描きました。

![構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/a4665821-67d0-1637-3eb1-679b6fee8ce4.png)


オンプレミスのPCからADLSにsftpでデータを配置し、Azure Data Factory v2(以下、ADF)でそのデータが参照できるかどうか、という連携です。
本記事ではADLSと記述しますが、構成図の通り正確にはADLS Gen2です。
Gen1はほぼ使われないので、現在ADLSといえばGen2です。
<font color="red">本来的にはADFの背後に更にSQL DBなどのデータの格納先があるのですが、そこまでの連携は本記事では行いません。</font>
ADFで連携できればSQL DBまでは連携できるのは確実ですからね。

# ADLSにSFTPサーバを構築
これはもう瞬殺ですね。
敢えてポイントを挙げるとしたらStorage AccountにADLSの設定を施すのはStorage Account構築時のみ、という点くらいでしょうか。
Azure PortalにログインしてStorage Account作成を行い、サブスクリプション、リソースグループを選択し、ストレージアカウント名を入力します。
ストレージカウント名はアルファベット小文字と数字のみ、記号が使えませんので命名には注意が必要です。
地域(リージョン)も指定しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/832e08b1-408b-8373-9e8b-185eaa3726b1.png)

今回は検証なのでパフォーマンス(IO)もStandardで構いませんし、冗長性もLRSで十分です。
ここまで入力して[次へ:詳細設定>]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/015d5d82-9e9b-039c-2066-794dde740d9b.png)

<font color="red">ここが唯一の注意点ですね。</font>
[詳細設定]の項目で<font color="red">**階層型名前空間を有効にする**</font>のチェックボックスがデフォルトだと外れているのでチェックを入れます。
この**階層型名前空間**というのが**ADLSを有効にする**という設定です。
**この設定はStorage Accountデプロイ後は有効化、無効化、ともにできなくなる取り返しのつかない設定です。**
次にSFPTを有効にするため、<font color="red">**SFTPを有効にする**</font>にチェックを入れます。
この設定値は階層型名前空間を有効にするにチェックを入れる前はグレーアウトしていて設定できないのですが、階層型名前空間を有効にする＝ADLSを有効にすることによりアクティブになるオプションです。
このオプションはStorage Accountをデプロイ後も変更可能です。
ここまで設定出来たらあとの設定はデフォルトのままで大丈夫なので[レビュー]を押しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/ea8c3543-45b0-584e-4f8b-cd49c1f052a1.png)

設定した各種パラメーターを確認して、[作成]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/2db3ee6c-ed50-ba15-9aa5-de5a8be9be1f.png)

サクッとStorage Accountの作成は終わります。
**SFTPは有効にしているとその分通常のStorage Accountの従量課金と別で課金されますのでご注意ください。**
下記の画像の上段赤枠内にその注意が記載されています。
SFTPの設定は下記の画像中段左側の[SFTP]をクリックして行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/586c18c9-0fbb-4abf-3ede-b6a2772f29b3.png)

SFTP用のユーザ作成を行います。
[+ ローカルユーザーを追加する]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/3161e944-077c-bf65-e5de-887d9f488a72.png)

まずはSFTPのユーザ名と認証方法をパスワードかキーかを選択します。
無難にキーでいっちゃいましょう。
Data Factoryで連携する際もキーの方が面白いので。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/08bc8c41-6ff2-fd8b-66a6-fd21a4beb725.png)

次にSFTPユーザのホームディレクトリ設定です。
まずはADLSなのでコンテナを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/aec43587-29e3-cab1-6d55-6e09c79077aa.png)

次にSFTPユーザのアクセス権設定です。
今回どこまで検証するかわからなのでフルアクセス権を振っておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/0642cb8e-3348-f3be-5e68-f0cdc7a1afbc.png)

次にSFTPユーザのホームディレクトリ設定の続きです。
実際にSFTPユーザがログインした後に配置されるディレクトリのパス指定です。
コンテナ名/のあとに恐らくユーザ名ごとにディレクトリを切ると管理しやすいのではないでしょうか？
今回は1ユーザでの検証なのでそこまでは行いません。
ここまで設定して[追加]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/72f22c5c-baae-8e36-877a-d82a4f94c441.png)

SFPTユーザとホームディレクトリの設定やアクセス権の付与も無事終わりました。
これも瞬殺です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/8782ef1e-5b80-a52c-95f0-1124b6824e4e.png)

<font color="red">**SSHキーを新規で作成した場合はダウンロード画面が1回だけ出てきますので忘れずにダウンロードして保存しておきましょう。**</font>

# アクセス確認
では実際にアクセス確認を行います。
先ほどのADLSのSFTP設定画面の赤枠内をクリックして接続情報をコピーします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/5f26c76d-45bd-2d07-bac1-a61f4a3ca30b.png)

先ほどダウンロードしたキーを指定して、はい、見事にアクセスできましたね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/7447bef5-dc50-92e5-32a5-c50cdb6f6342.png)

まぁなんてことはない、ただのSFTPサーバです。

試しに何かファイルを置いてみましょう。
まぁこんな簡単なファイルを作成してみて、putしてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/8f51de68-159f-dd3a-b5a9-830b30f3be2e.png)

はい。
普通にputできますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/13fc52d6-c512-b715-c1d7-253370c7b427.png)

ではオリジナルのファイルを削除してみてこのADLS内のファイルをダウンロードしてみます。

はい。
普通にダウンロードできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/c09c9627-aee0-01fc-907a-72a82a951c2b.png)

続いてAzure Portal上からもファイルがあるか確認してみましょう。
Azure Portalから該当のStorage Accountを開き[コンテナー]をクリックして先ほど作成したコンテナ名をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/0d1ead3b-ef80-5011-f573-3aac7bb1bae1.png)

はい、<font color="red">**バッチリ**</font>ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/dfb525a3-b7cc-c4e4-ff78-b93f95067d86.png)

# ADFとADLSを連携
はい。
もう最後の項目です。
今回はあっけなく終わりそうですね。

Azure PotalからADFの画面を開き、[スタジオの起動]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/52b4452d-4fa1-74d5-be4a-21eb7f2319c7.png)

画面左ペインの[管理]をクリックし[リンクサービス]をクリック、[新規]をクリックし、[データストア]の項目で[Azure]をクリックし、[Azure Data Lake Storage Gen2]をクリックし[続行]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/2f3a1d1d-cea9-b2ca-765c-1e535a731726.png)

[名前]の項目でこの接続の名前を付けます。
[統合ランタイム経由で接続]は[AutoResolvedIntegrationRuntime]とします。
[認証の種類]は[システム割り当てマネージドID]とします。
デフォルトだと[アカウントキー]ですが、これを選択するとADFがStorage Accountのキーを持ってしまうことになるのでセキュリティ的に良くありませんので、Azureのリソース間同士の認証を有効にする[システム割り当てマネージド]を選択するのは正しいです。
[アカウントの選択方法]は[From Azure subscriotion]を選択し、[Azureサブスクリプション]は自身のサブスクリプションを選択し、[ストレージアカウント名]は接続対象のストレージアカウントを選択します。
ここまで入力すると必要項目が満たされますので[テスト接続]を行えるようになるのですが、画像のように失敗します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/b73bf9ea-a380-786a-4b85-c31d694d3f19.png)

## 被疑箇所特定
まぁ簡単ですね。
<font color="red">**賢明な読者の皆様なら既にお気づきだと思いますが、[認証の種類]を[システム割り当てマネージドID]にしたため、ADFがADLS側で認証されずにアクセスされていない、ということです。**</font>

## 解消方法
ADLSのアクセス制御にて接続元であるADFに権限を付与します。
対象のADLS、Storage AccountにAzure Portalからアクセスし、[アクセス制御]をクリックし、[ロールの割り当て]を確認すると、当然ADFは含まれていません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/f0030f2c-bad4-9941-0025-03ea3a337121.png)

同じ画面の[追加]をクリックし、[ロールの割り当ての追加]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/0bb9a761-507a-f1e0-bbbf-f33f3e558163.png)

やいのやいのロールが存在しますが、今回は最小権限付与の原則にのっとって[ストレージ BLOB データ閲覧者]の権限をクリックし、[次へ]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/61ba262a-777b-95d8-04fe-80134b00d347.png)

[マネージドID]を選択し[メンバーを選択する]をクリックします。
[サブスクリプション]はご自身のサブスクリプションを選択し、[マネージドID]の項目には、そのものズバリ[Data Factory (V2)]が存在しますので、これをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/c6db089b-079c-60a1-ab37-e37063f5b1c7.png)

先ほど作業していたADFが出てきますので、クリックして[選択]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/f58c4a16-f0a7-d8ea-8084-e36c6ddbbd8b.png)

権限付与対象を確認して[レビューと割り当て]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/fb93b6cc-dfbc-0fe2-4bea-2b8112b471ff.png)

最後にもう一度権限付与対象と付与する権限を確認して[レビューと割り当て]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/db4d4f81-6997-82be-2249-2e95fc42ee79.png)

権限が正しく付与されたことを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/cb093d58-909b-dd92-c0e8-a7633b5457c1.png)

## エラー解消の確認
ADFスタジオ画面に戻り、再度[テスト接続]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/2de2bdce-25e4-9fab-ecda-c2a6689d378c.png)

[接続成功]になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/f32c4d3c-8ef5-312d-96e6-cb5662bfdfe2.png)

これでエラーは解消されました。

# 気を取り直して再度ADLSとADFを連携する
接続成功になっていることを確認し、[作成]をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/8be9c9ad-7444-ea53-1803-f94b22315d81.png)

画面上段にある[すべて発行]をクリックします。
恐らくPublish行為なんだと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/9a986247-94b4-a2b4-1799-a902a68ecffb.png)

やっぱり[発行]なんですね。
クリックしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/6ec70d74-3d69-fcc5-07dc-82b58ffc2752.png)

# 実際にADFからADLSにデータを見に行く
リンクサービスが無事Publishされたことを確認してから、ADFスタジオの左ペインの[作成]をクリックし、[データセット]をクリックし、[新しいデータセット]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/523db05d-4f08-b0c6-fbc3-1ad8c82c9c7c.png)

ここでもリンクサービスと同じく[Azure]を選択し、[ADLS]をクリックし[続行]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/dbfc9167-caff-1bc7-c46d-022756be721f.png)

ここからはリンクサービスとは違い、ADLSから連携されるファイル形式を聞いてきます。
今回はCSVを選択して続行をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/e8ddc50f-2407-595f-dcc5-98e859d78dde.png)

検証用にADLSにsftpで適当なcsvファイルを配置しておきます。
今回は国勢調査の男女別人口－全国,都道府県(大正9年～平成27年)にしました。
実際のリンクは[こちら](https://www.e-stat.go.jp/stat-search/file-download?statInfId=000031524010&fileKind=1)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/3af506a1-ef00-52d3-a092-8d7f647bb365.png)
実際のデータはこんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/f8685dcc-d537-db7a-8e95-e06df29abd5b.png)

データセット作成を行うとデータセット名を[名前]に、リンクサービスの選択を求められるので先ほど作成したリンクサービスを選択しフォルダボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/1ed18479-4a47-dea6-e1af-da28ff903847.png)

ADLS内に構築したコンテナ名をクリックし、先ほどの国勢調査のサンプルファイル名をクリックし、[OK]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/afae2248-483d-7f18-6c17-0103837952d8.png)

[スキーマのインポート]は[接続またはストアから]を選択し、[OK]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/a0990874-9c1a-268e-ac1d-7e8653893a2a.png)

[エンコード]を[SHIFT-JIS]を選択し、[データのプレビュー]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/518d1fb2-dce7-14e7-28b5-46fb5aa6147d.png)

<font color="red">**完璧ですね！**</font>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/643392/480d2c7d-c673-67b3-4d9a-5c0fa3ef04a2.png)

国勢調査のサンプルファイルが無事取得できました。

後はこれをパブリッシュすればデータセットは完成です。
この後はパイプラインを作成して後続のSQL DBに流し込んであげればOKです。
その際にデータフローでETLを実施することも可能です。
この辺りはまた別の記事で書こうと思います。

本日はここまで。