ほりひログ

所属組織の製品 (Azure とか) に関連する内容が多めだけど、個人の見解であって、所属組織を代表する公式情報ではないです。

VS Code Remote Development で App Service on Linux 上のファイルを編集する

はじめに

「試してみた」系エントリーです。
役に立つかは微妙。

Web SSH 上での vi がめんどくさかった

App Service on Linux を使っていて、いろいろ試したくてリモートのファイルを直接操作することが多々あります。

App Service on Linux で使用されている Blessed Image は sshd が稼働しているので、Azure ポータルから (Web) SSH でログインすることができますが、 Web ブラウザーに表示される SSH セッション上で、vi などのテキスト ベースのエディターを使うことになるので、やや操作がめんどくさいです。

なので、VS Code で直接 App Service on Linux 上でのファイル操作にチャレンジしてみました。

VS Code Remote Development

VS Code には、Remote Development という拡張機能があります。

code.visualstudio.com

これを使うと、WSL や Docker コンテナー、リモート サーバー (SSH 経由) 上のファイル システムを直接開いて、操作することができます。

SSH であれば、下図のように、VS Code が裏で SSH サーバーに接続し、ファイル操作のコマンド送信しているようです(たぶん)。

-----------             --------------
| VS Code | <- (SSH) -> | SSH Server |
-----------             --------------

Azure CLI での SSH トンネリング

次に、Azure CLI には "webapp create-remote-connection" というサブ コマンドを紹介します。

これを実行すると、ローカルの SSH クライアントと App Service on Linuxsshd を橋渡しする SSH 用のローカル プロキシーが稼働します。

docs.microsoft.com

下図のように、Azure CLISSH で待ち受けし、SSH クライアントからの接続を、App Service on Linux 上の sshd へつなぎます。
内部的には、Azure CLI から Azure プラットフォームへの Web Socket 接続を経由しているようです (それっぽい debug ログが出るので)。

            -------------                       ------------------------
<- (SSH) -> | Azure CLI | <- (WS <<-->> SSH) -> | App Service on Linux |
            -------------                       ------------------------

サブコマンドのオプションなどはこちらのドキュメントに記載してあります。
# コマンド名が違うような。。。

docs.microsoft.com

2つを繋げてみる

イメージとしてはこんな感じです。

-----------             -------------                       ------------------------
| VS Code | <- (SSH) -> | Azure CLI | <- (WS <<-->> SSH) -> | App Service on Linux |
-----------             -------------                       ------------------------

Azure CLI を実行する

まずは、Azure CLISSH プロキシを構築します。

az webapp create-remote-connection --ids <resourceId>

<resourceId> は、

/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName/providers/Microsoft.web/sites/<Web Apps名>

ですね。

実行すると下記のように、ローカル側のポート番号と、SSH ログインに必要なアカウント情報が出力されます。

Opening tunnel on port: 12345
SSH is available { username: root, password: Docker! }
Ctrl + C to close

ポート番号は、既定では Azure CLI がランダムに決定しますが、下記のように Azure CLI 実行時に -p オプションを使うことで、こちらから指定することも可能です。

az webapp create-remote-connection --ids <resourceId> -p <port>

Remote Development を実行する

次に、Azure CLI で起動した SSH プロキシに、VS Code から接続してみます。

事前に下記の Remote SSH 拡張を VS Code に入れておきます。

marketplace.visualstudio.com

f:id:horihiro:20200119101919p:plain

拡張機能のインストールが完了すると、左下に「≶」みたいなアイコンが表示されるので、これをクリックして、"Remote-SSH: Connect to Host..." -> "Add New SSH Host..." と選択してください。

f:id:horihiro:20200119102130p:plain

最後に接続コマンドとして下記のコマンドを指定します。

ssh root@localhost -p <port>

<port> は Azure CLI の出力結果に書いてあったものを指定してください。

ここからは通常の Remote Development と同じ流れになります。

接続が成功すると、左下のアイコンが下記のように変わります。

f:id:horihiro:20200119104144p:plain

後は通常の VS Code でのファイル編集と一緒です。

使った感想

VS Code からリモート ファイルを編集できることは結構便利です。重宝しますね。

一方で、VS Code からの接続に失敗することもあります。というか、よく失敗します。 f:id:horihiro:20200119134909p:plain

そんな時は "More Actions..." から "Reload Window" をするとうまく開けることがあります。 f:id:horihiro:20200119134948p:plain

あと、Azure CLI のコマンドを Windows で実行した場合、接続が安定せず切断されることがよくあります。
なぜか、Azure CLI を WSL で実行した場合、もしくは、Windows でも --debug オプションをつけると接続は安定しました。
パッと見た感じ、Python のマイナー バージョンくらいしか違いが見られないんですけどね。。。

$ az --version
azure-cli                         2.0.80

command-modules-nspkg              2.0.3
core                              2.0.80
nspkg                              3.0.4
telemetry                          1.0.4

Python location 'C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\python.exe'
Extensions directory 'C:\Users\<USER_NAME>\.azure\cliextensions'

Python (Windows) 3.6.6 (v3.6.6:4cf1f54eb7, Jun 27 2018, 02:47:15) [MSC v.1900 32 bit (Intel)]
$ az --version
azure-cli                         2.0.80

command-modules-nspkg              2.0.3
core                              2.0.80
nspkg                              3.0.4
telemetry                          1.0.4

Python location '/opt/az/bin/python3'
Extensions directory '/home/<USER_NAME>/.azure/cliextensions'

Python (Linux) 3.6.5 (default, Jan 13 2020, 05:03:40)
[GCC 5.4.0 20160609]

実用に耐えるものか、いろいろ試してみようと思います。