AWS Systems Manager と VS Code Remote SSH を組み合わせて快適なリモート開発環境を作る方法

2023.01.09

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

しばたです。

前回の記事で.NET on AWSの開発環境には「EC2でVS Code Remote Developmentを使う」のがベストと言いました。

本記事ではその具体的な手順を解説します。

VS Code Remote概要

Visual Studio Code(VS Code)はそれ自身がサーバーとして動作し、クライアントからリモート上にあるVS Codeを使ったリモート開発が可能です。

VS Codeのリモート接続は大別して以下の三種の方式があります。

  • Dev Containers : ホストからコンテナ環境へ接続
  • Remote SSH : クライアントからリモート環境へSSH接続
  • Remote Tunnels : セキュアトンネルをつかった接続

Dev Containersはコンテナの話なので除外してRemote SSHとRemote TunnelsをEC2で使おうとすると下図のイメージになります。

Remote SSHはリモート環境へ直接接続可能である必要があり、Remote Tunnelsはトンネルを使うことでプライベートに閉じた環境において利用することができます。

AWS Systems Manager と VS Code Remote SSH を組み合わせる

ぱっと見でRemote Tunnelsの方が便利そうに見えますが、AWSであればAWS Systems Managerを使うことで似た構成を作ることができます。

この場合クライアントPCにAWS CLIやSSM Session Manager Pluginといった追加ソフトウェアは必要ですがEC2の管理にSSMを使っている方であれば大抵はインストール済みだと思います。

普段AWSを管理する環境をそのまま使いつつプライベートに閉じたEC2に対してVS Codeを利用できるのがこの方式のメリットでしょう。
逆にVS Codeの機能は極力VS Code側でカバーしたいという場合はRemote Tunnelsを使うと良いと思います。

構築手順

ここから具体的な構築手順を説明します。

1. EC2の用意

前回の記事と同じVPCにAmazon Linux 2のEC2インスタンスを一つ用意し検証環境にします。
配置サブネットはPublicサブネットにしていますが、全てのインバウンド通信を禁止する設定としています。

SSMを使うのでインスタンスプロファイルを適切に設定します。

今回は最低限必要なAmazonSSMManagedInstanceCoreをアタッチしたロールを事前に用意しておいたのでこれを設定します。

その他設定は環境に合わせてよしなに行ってください。

作成結果はこんな感じです。
SSM Session ManagerでOS内部にアクセスできるか確認しておくと良いでしょう。

2. クライアント側ソフトウェアの準備

クライアント環境には予め以下のソフトウェアをインストールしておく必要があります。

インストール自体はどれも簡単なので本記事では手順を割愛します。
今回の検証では以下のバージョンを使っています。

# OpenSSH client (OS標準のものを使用)
C:\> ssh -V
OpenSSH_for_Windows_8.1p1, LibreSSL 3.0.2

# VS Code
C:\> code --version
1.74.2
e8a3071ea4344d9d48ef8a4df2c097372b0c5161
x64

# AWS CLI
C:\> aws --version
aws-cli/2.9.12 Python/3.9.11 Windows/10 exe/AMD64 prompt/off

# SSM Session Manager plugin
C:\> session-manager-plugin --version
1.2.398.0

ちなみにOSはWindows 10 Pro (Ver.22H2)です。
他OSでも基本的な手順は同じですので、設定の細かい違いは適宜読み替えて頂ければと思います。

3. AWS CLI初期設定

AWS Systems Managerを使うためのAWS CLIのプロファイル設定を環境に合わせて行ってください。

こちらは完全に環境依存なので具体的な手順の説明は行いませんが、本記事ではyour_profileという名前のプロファイルを使う想定とします。

# your_profile という名前付きプロファイルを用意
C:\> aws sts get-caller-identity --profile your_profile
{
    "UserId": "AIDAXXXXXXXXXXXXXXXXX",
    "Account": "000000000000",
    "Arn": "arn:aws:iam::000000000000:user/your-user-name"
}

4. SSH接続設定

VS Codeを設定する前に~/.ssh/config(Windowsなら$USERPFOILE\.ssh\config)ファイルにEC2インスタンスへ接続するための設定を仕込みます。

SSMを使ってインスタンスにSSH接続する際は以下の様なaws ssm start-sessionコマンドをProxyCommandに設定する必要があります。

aws ssm start-session --target "インスタンスID" --document-name AWS-StartSSHSession --parameters "portNumber=22"

このため~/.ssh/configには以下の様な記述を追加してやります。

~/.ssh/config

# SSH to remote VS Code instance
host my-vscode-remote
    HostName "インスタンスID"
    Port 22
    User ec2-user
    IdentityFile "EC2キーペア秘密鍵のフルパス" 
    ProxyCommand C:\Program Files\Amazon\AWSCLIV2\aws.exe ssm start-session --target %h --document-name AWS-StartSSHSession --parameters "portNumber=%p" --profile your_profile

Windowsの場合ファイル指定は絶対パスで書いてやる必要があります。
接続に使うホスト名、ポート番号、ユーザー名、名前付きプロファイルについては環境に応じてよしなに変えてください。

これでsshコマンドで対象のインスタンスに接続できる様になります。

接続確認できた後はコンソールを閉じて構いません。
以後の設定はすべてVS Codeから可能です。

5. VS Codeの設定

ここからVS Codeの設定に移ります。

VS Codeを起動し最初にRemote - SSH拡張機能をインストールします。

その後、ウィンドウ左下の接続アイコンをクリックします。

するとリモート接続方法の選択ダイアログが表示されるので「Connect to Host... (Remote-SSH)」を選びます。

続けて接続先の選択になるので、前節で作ったホスト名(ここではmy-vscode-remote)を選びます。

対象インスタンスに接続しリモート側にVS Codeが無い場合は自動で初期設定を行ってくれます。
リモート側のプラットフォーム(ここではLinux)を選びます。

リモート側の初期設定が終わるまで少し待ちます。

無事完了するとこんな感じになります。

左下に接続先情報が表示され、ターミナルはリモート環境に接続した状態となります。

以上で完了です。

補足 : .NET 6の開発環境設定

前回の記事が.NET 6の環境設定のはなしだったので、補足として環境設定と動作確認を行っていきます。

.NET周りの構築手順はCloud9の場合と全く同じですが、AWS Deploy Tool for .NETの利用に必要なNode.jsやDockerは未インストールなので自分で追加インストールしてやる必要があります。

.NET SDKのインストール

こちらは前回同様に.NET 6 SDKをインストール。

# Install .NET SDK
sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
sudo yum -y update
# 今回はLTSバージョンである.NET 6 SDKをインストール
sudo yum -y install dotnet-sdk-6.0

追加でAWS Deploy Tool for .NETと .NET CLI extension for Lambda functionsもインストール。

# 追加インストール
dotnet tool install -g aws.deploy.tools
dotnet tool install -g Amazon.Lambda.Tools

PATHの設定も併せて行っておきます。(手順は割愛)

結果はこんな感じです。

$ dotnet --version
6.0.404

$ dotnet tool list -g
Package Id               Version      Commands     
---------------------------------------------------
amazon.lambda.tools      5.6.2        dotnet-lambda
aws.deploy.tools         1.9.4        dotnet-aws

Node.jsのインストール

Node.jsのインストールはnvmから行っています。
公式の手順通りなので特に言う事は無いですが、Amazon Linux 2ではNode 18は使えないのでNode 16をインストールしています。

# Node.jsインストール
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
. ~/.bashrc
# Amazon Linux 2ではNode 18は非サポート
nvm install 16

結果はこんな感じ。

$ node --version
v16.19.0

Dockerのインストール

DockerはExtras Libraryからインストールしてやります。

# Dockerインストール
sudo amazon-linux-extras install -y docker
# サービス起動設定
sudo systemctl start docker
sudo systemctl enable docker
# ec2-user用設定
sudo usermod -a -G docker ec2-user

結果はこんな感じ。

$ docker version
Client:
 Version:           20.10.17
 API version:       1.41
 Go version:        go1.18.6
 Git commit:        100c701
 Built:             Wed Sep 28 23:10:17 2022
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server:
 Engine:
  Version:          20.10.17
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.18.6
  Git commit:       a89b842
  Built:            Wed Sep 28 23:10:55 2022
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.8
  GitCommit:        9cd3357b7fd7218e4aec3eae239db1f68a5a6ec6
 runc:
  Version:          1.1.4
  GitCommit:        5fd4c4d144137e991c4acebb2146ab1483a97925
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

sudo無しでdockerコマンドを使うためにec2-userをdockerグループに追加したのですが、VS Code内のターミナルでこの設定を反映させるにはVS Code Serverの再起動が必要でしたのでご注意ください。(クライアントの再接続ではダメ)

動作確認

細かい手順は割愛しますが前回同様にWEB APIアプリケーションを作ってみた結果がこちらになります。

VS Codeの機能が透過的に使えますのでデバッグ実行も問題なくできますし、VS Code内蔵のブラウザを使いローカルサーバーの表示もばっちりです。ポート番号の制限もありません。

これは本当に便利ですね。

最後に

以上となります。

VS Codeのリモート接続機能は非常に充実しておりとても便利に使えます。
AWS環境でも問題なく使えましたので皆さんもぜひ試してみてください。