Visual Studio CodeとAzure VMでローカル環境でのコード開発を止めたらめちゃくちゃ快適だった

#はじめに 
2019/4/30 にVisual Studio Code の新機能としてリモート開発を行うための新機能 Remote Developmentが発表されました。 
そこから一カ月間、developer版のVS Code Insiderでのみ機能提供されていましたが、2019/6/6の [VS code 1.35 (Stable ver)](https://code.visualstudio.com/updates/v1_35)でも Remote Developmentが使用できるようになりました。 一カ月ほどVS Code Insiderで試用してきましたが、かなり便利だったためstable版での利用開始にあわせて使用方法等をまとめます。 

#Remote Deploymentとは？ 
Visual Studio CodeのRemote Deploymentはローカル（クライアント）とリモート（サーバー）を分離し、ローカルではUI部分の機能を提供し、リモート側でソースコードの配置、コードの実行環境、デバッガーなどを稼働させる機能です。 コードの実行環境となるリモート側は、SSH経由で接続するリモートマシン、コンテナー、Windows Subsytem for Linuxが現在利用できます。 

※アーキテクチャ![GetImage.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192113/c6cd5b2b-5132-beca-8352-08a9338757e7.jpeg)

私はVS Code InsiderでRemote Deploymentの機能が提供されてから、リモート側（Remote OS）としてAzure環境に構築した Ubuntu VMを利用していました。 これのメリットは、ソースコードと実行環境がリモート側のクラウド上のサーバー１つに集約できます。自分の場合、コードを書く端末がMacだったりWindowsだったりしてOSが混在しており、自宅(Macbook)、会社(Windows Desktop)、持ち運び用(Surface Go)といった利用シーンで複数端末を切り替えてコード見たり書いたりすることが多いので、ソースコードはGitリポジトリに集約しているのでまだよかったのですが、実行環境をそれぞれの端末でセットアップするのは非常に手間でした。 
その点、Remote Deploymentで、クラウド側のサーバに開発環境を集約すると、ローカル端末側はVS CodeのインストールとサーバへのSSH接続設定のみをしていれば、いつでもどこでもインターネット接続さえあれば同一環境で作業できます。 
gitリポジトリにpushするまでもいかない微妙なコード変更も一旦クラウド側のサーバに保存しておけますし、Windows端末でストレスフリーにLinux環境でコードを実行して動作確認もできます。 

#環境セットアップ 
大きな流れは以下の通りです。
1,2,3 は, Azure 仮想マシンをRemote OSにする場合の手順なので、既存のリモート環境を使用する場合や既にVS Code入れている場合は不要な手順です。 また、仮想マシンの構築は当然ながら一度のみとなるので、違う端末でコードを書く必要ができた場合は、2, 3以外の手順を実施することになります。 

 1. ローカル端末にVS Codeをインストールする 
 2. Azure CLI をインストールする 
 3. リモート開発環境となるAzure 仮想マシンを作成する 
 4. ローカル端末で VS codeのExtentionsからRemoteDevelopmentをインストールする 
 5. ローカル端末でssh configを設定する 
 6. VS Codeからリモート環境に接続する

## 1. ローカル端末にVS Codeをインストールする 
まずは以下から VS Codeのインストーラーをダウンロードしローカル端末にインストールします。 

　Visual Studio Code Installer 
　https://code.visualstudio.com/Download 

## 2. Azure CLI をインストールする 
今回は Azure CLIでAzure サーバ環境を構築したいと思います。（サーバ構築は、Azure ポータルやPowershellでも方法でもOKです） 
Azure CLIは、Cross-Platform（Linux, Mac. Windows）で動作する[Azureのリソース管理のコマンドツール](https://qiita.com/yy1106/items/28c603791d995103093d)です。 Windowsならmsi, Macならbrew, Linuxならapt, yumなどのパッケージ管理ソフト経由でインストールできます。 

　Install the Azure CLI 
　https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest 

インストールするとローカル端末のshellやpowershellなどからazコマンドが使えるようになります。 

```
PS C:\Users\xxxx> az 
     /\ 
    /  \    _____   _ _  ___ _ 
   / /\ \  |_  / | | | \'__/ _\ 
  / ____ \  / /| |_| | | |  __/ 
 /_/    \_\/___|\__,_|_|  \___| 

Welcome to the cool new Azure CLI! 
Use `az --version` to display the current version. 
Here are the base commands: 
    account           : Manage Azure subscription information. 
    acr               : Manage private registries with Azure Container Registries. 
<省略> 
``` 

補足として、VS Code上でAzure CLIのスクリプトをがっつり書きたい場合は、Azure CLI ToolsというExtentionがインテリセンスが効いて便利です。 
<img width="894" alt="GetImage.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192113/59427f21-718c-44c6-fcbf-16e9f66193ed.png">

## 3. リモート開発環境となるAzure 仮想マシンを作成する 
まずは、Azureにログインし、仮想マシンを作成するサブスクリプションを指定します。 ローカル端末のPowershell、あるいはTerminal、もしくはVisual Studio Codeの上部メニューから Terminal > New Terminalをひらいてコマンドを実行します。 

``` 
az login # Azureサブスクリプションへログイン 
az account set -s <SubscriptionName or SubscriptionID>　#操作対象のサブスクリプションを指定
``` 

次は仮想マシンを作成します。特にこだわりがなければ以下のコマンドでAzureのマーケットプレイス上にあるUbuntuの最新イメージからVMが東日本リージョンに作成されます。 

```sh 
az group create --name DevTools --location japaneast 
az vm create --resource-group DevTools --name ubuntu-dev-server --image UbuntuLTS  --generate-ssh-keys --public-ip-address-dns-name my-ubuntu-server
``` 

この時--public-ip-address-dns-nameオプションで指定する値が、VMに接続するためのパブリックDNS名になるので任意に変えてください。既に使用されているDNS名は指定できません。 上の例でmy-ubuntu-serverと指定し東日本に仮想マシンを作るとmy-ubuntu-server.japaneast.cloudapp.azure.comがDNS名となり、このDNSのポート22でssh接続が可能になります。 
また、sshするための初期ユーザは、コマンドを実行したローカルユーザと同一になり、C:\Users\<UserName>\.ssh\（あるいは ~/.ssh）にsshの公開鍵と秘密鍵が保存されます。この秘密鍵(id_rsa)を使ってRemote Deploymentでリモート環境に接続します。 

## 5. ローカル端末で VS codeのExtentionsからRemoteDevelopmentをインストールする
Extentionの項目から、RemoteDevelopmentを検索してインストールします。 
<img width="899" alt="GetImage (1).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192113/dc08047b-fa40-e1f4-f097-ddb524f109a8.png">
 
## 6. ローカル端末でssh configを設定する
必須ではありませんが、ssh configを設定しておくと便利です。 
View > Command Palette > Remote-SSH: Open Configuration Filesを選択し、~/.ssh配下にconfigファイルを作成します。 
<img width="900" alt="GetImage (2).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192113/8d5f60a9-c2b4-7371-d6f4-7f55449b7e58.png">

Hostは設定の名称ですので任意でOKです。HostNameでリモートサーバのDNS名を指定し、Userでsshのユーザアカウント名を指定します。 デフォルトで~/.ssh配下の秘密鍵を指定してssh接続をおこなうようになります。 

```
# Read more about SSH config files: https://linux.die.net/man/5/ssh_config 
Host my-ubuntu-server 
    HostName my-ubuntu-server.japaneast.cloudapp.azure.com 
    User <sshuser> 
``` 

## 7. VS Codeからリモート環境に接続する  
Ssh configを設定すると次のようにConntenctionsに設定したサーバが表示されるようになります。
<img width="278" alt="GetImage (3).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192113/e0ef5f5c-a99a-b6d0-e506-7135b9132f38.png">

これを選択すると別ウィンドウが開いてリモートサーバに接続します。
あとは File > Add Folder to WorkSpaceなどを設定し、いつも通りVS Codeを使っていきます。
VS Code上のターミナル操作も当然リモートサーバ側の操作となりますので、開発環境をセットアップしたり、gitリポジトリから既存のコードを落としてきて、クライアントに依存せずコードを書いていけます。
![GetImage (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192113/871602bd-068e-fa3a-c2bf-d03dfca77965.png)

##補足1
クライアントがWindowsの場合、OpenSSHがインストールされている必要があります。その場合、[「Windows Server 2019 および Windows 10 の OpenSSH のインストール」](https://docs.microsoft.com/ja-jp/windows-server/administration/openssh/openssh_install_firstuse#installing-openssh-with-powershell)に沿ってインストールします。 

PowerShellを管理者権限で起動

```
Get-WindowsCapability -Online | ? Name -like 'OpenSSH*' 
# This should return the following output: 
Name  : OpenSSH.Client~~~~0.0.1.0 
State : NotPresent 
Name  : OpenSSH.Server~~~~0.0.1.0 
State : NotPresent 
```

ssh clientをインストール

```
# Install the OpenSSH Client 
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
```

##補足2
間違ってRemote開発用の仮想マシンを削除すると悲惨なことになるので、[「Azure リソースを誤って削除してしまわないためのベストプラクティス」](https://qiita.com/yy1106/items/d5557982f389a0f1bc23)に書いた対策をしておくことを勧めします。特にLockは追加コストもないのでオススメです。