AWS Cloud9とVS Code Remote SSHを組み合わせて使ってみた

2023.01.22

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

しばたです。

以前.NETの開発環境を用意するためにAWS Cloud9を試してみた記事とVS Code Remote SSHを使った開発環境構築の記事を書きました。

環境構築はAWS Cloud9が容易で.NETの開発環境はVS Codeが優れている感じなのですが、「じゃあ両者を組み合わせてAWS Cloud9環境にVS Codeで接続すれば良いのでは?」となるのは誰もが思いつくことでしょう。

そんなわけで実際にやってみることにしました。

まさかのAWS Blog

誰もが思いつく話なので先人はたくさんいるだろうと調べてみたところ普通にAWS Architecture Blogに記事がありました...

流石にこれは予想外でしたが私のやりたい事とバッチリ一致するので参考にさせてもらいます。

こちらの記事を要約すると、

  • SSM接続でAWS Cloud9環境を初期構築する
  • AWS Cloud9環境ではSSHキーペアが設定されないので、自分でSSH鍵をセットアップする
  • AWS Cloud9環境は一定時間(デフォルト30分)でシャットダウンされるため、シャットダウンスクリプトに手を加えVS Code接続中はシャットダウンしない様にする
  • VS Code Remote SSHの設定手順は公式通り

といった感じになっています。
他にも

  • クライアントからのSSH接続時にEC2インスタンスの自動起動処理を仕込む

といったこともしていますが、これは必須ではないので本記事では無視します。

やってみた

それでは早速やっていきます。

前提条件

以前の記事で作成したCloud9環境をそのまま使います。
新規に環境を用意する場合はSSM接続を使う設定で作成してください。

SSM接続を使う場合、構築したEC2インスタンスにはAWSCloud9SSMInstanceProfileというインスタンスプロファイルがアタッチされ、これにはSSM Session Managerで接続可能な権限が設定済みです。

このためSSMセッション用の追加設定は不要です。

1. SSH鍵の用意

Cloud9の実体となるEC2インスタンスにはキーペアが設定されていません。

代わりに~/.ssh/authorized_keysにはCloud9専用の公開鍵が初期設定されます。

~/.ssh/authorized_keys (初期状態)

# 通常ユーザーは ec2-user ( /home/ec2-user/.ssh/authorized_keys )
$ cat ~/.ssh/authorized_keys
# Important
# ---------
# The following public key is required by Cloud9 IDE
# Removing this key will make this EC2 instance inaccessible by the IDE
#
cert-authority ssh-rsa XXXXX・・・(中略)・・・XXXXX xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@cloud9.amazon.com


#
# Add any additional keys below this line
#

このため自前で新規にキーペアを用意するか、既存キーペアの公開鍵を手動で追記してやる必要があります。
今回はssh-keygen -yコマンドを使い既存の秘密鍵から公開鍵を作成します。

# ssh-keygen -y で秘密鍵から公開鍵を読みだす
ssh-keygen -y -f "秘密鍵のパス"

(~/.ssh/authorized_keysの末尾に公開鍵を追記)

2. シャットダウンスクリプトの変更

AWS Architecture Blogの手順に倣いCloud9シャットダウンスクリプトの内容を更新します。

# Cloud9 IDE内で実行してください

# 最初に元スクリプトを移動してバックアップ
sudo mv ~/.c9/stop-if-inactive.sh ~/.c9/stop-if-inactive.sh-SAVE
# AWSで用意してくれたスクリプトをダウンロード
curl https://raw.githubusercontent.com/aws-samples/cloud9-to-power-vscode-blog/main/scripts/stop-if-inactive.sh -o ~/.c9/stop-if-inactive.sh
# アクセス権の更新
sudo chown root:root ~/.c9/stop-if-inactive.sh
sudo chmod 755 ~/.c9/stop-if-inactive.sh

ちなみに元のスクリプトとdiffを取ると以下の通りとなり、VS Code Serverの状態をチェックするis_vscode_connected関数を増やしてインスタンスのシャットダウン条件を変更しています。

$ git diff --  ~/.c9/stop-if-inactive.sh-SAVE ~/.c9/stop-if-inactive.sh
diff --git a/home/ec2-user/.c9/stop-if-inactive.sh-SAVE b/home/ec2-user/.c9/stop-if-inactive.sh
index 57c8e9e..d3aa29e 100755
--- a/home/ec2-user/.c9/stop-if-inactive.sh-SAVE
+++ b/home/ec2-user/.c9/stop-if-inactive.sh
@@ -1,3 +1,6 @@
+# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+# SPDX-License-Identifier: MIT-0
+
 #!/bin/bash
 set -euo pipefail
 CONFIG=$(cat /home/ec2-user/.c9/autoshutdown-configuration)
@@ -37,12 +40,16 @@ is_vfs_connected() {
     pgrep -f vfs-worker >/dev/null
 }
 
+is_vscode_connected() {
+    pgrep -u ec2-user -f .vscode-server/bin/ >/dev/null
+}
+
 if is_shutting_down; then
-    if [[ ! $SHUTDOWN_TIMEOUT =~ ^[0-9]+$ ]] || is_vfs_connected; then
+    if [[ ! $SHUTDOWN_TIMEOUT =~ ^[0-9]+$ ]] || is_vfs_connected || is_vscode_connected; then
         sudo shutdown -c
     fi
 else
-    if [[ $SHUTDOWN_TIMEOUT =~ ^[0-9]+$ ]] && ! is_vfs_connected; then
+    if [[ $SHUTDOWN_TIMEOUT =~ ^[0-9]+$ ]] && ! is_vfs_connected && ! is_vscode_connected; then
         sudo shutdown -h $SHUTDOWN_TIMEOUT
     fi
-fi
+fi
\ No newline at end of file

Cloud9側の準備はこれで完了です。

3. クライアントの準備

ここからはクライアント側の作業となります。

前の記事と同じ手順でクライアント側のSSH接続の設定を行います。
細かい手順は前の記事をご覧ください。

今回クライアントの~/.ssh/configの設定は以下の様にしています。

~/.ssh/config (クライアント)

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

4. VS Codeで接続

あとはVS CodeからRemote-SSH接続するだけです。

Cloud9側でVS Code Serverの初期設定が終われば無事接続完了です。

補足

前の記事で用意したWEB APIアプリケーションをデバッグ実行したところ一応できました。
ただ、Cloud9ではローカルサーバーのポートが8080 - 8082に制限されているため、これらのポートを使った場合はVS Code側で期待した動作にはなりませんでした。

VS Codeを使う場合はこれらのポート以外を使うと良さそうです。
(根本原因を追究する気力は湧きませんでした...)

最後に

以上となります。

Cloud9環境に対してVS Code Remoteで無事接続できました。
ただ、両者のいいとこ取りとはならず、Cloud9の制約に注意しながらVS Codeを使う感じになりました。
Cloud9 IDEで使いにくいと感じるところをVS Codeで補完する使い方が良いのかな?と思った次第です。