Cloud Workstations と Duet AI で始めるマネージド開発環境での開発体験

# 1. はじめに
## 1-1. Cloud Workstations って何？
Cloud Workstations とは、Google Cloud が提供するマネージドな開発環境です。 Google Cloud 上に開発端末を配置するクラスタとその中で用いる開発端末のテンプレートを定義しておくことで、  開発者に対して開発に必要なツールがインストールされた開発端末を素早く提供できます。開発者はクラウド上に構築された開発端末に対して、ブラウザやローカル IDE からアクセスして開発に取り組むことができます。

[<img width = 700 src = "https://cloud.google.com/workstations/images/overview-workstations-concepts.svg">](https://cloud.google.com/workstations/docs/overview?hl=ja)

## 1-2. マネージドな開発環境が求められる背景
### 1-2-1. 実機で開発端末を用意する際に発生する課題
Cloud Workstations のようなマネージドな開発環境サービスが求められる背景として、実機で開発端末を用意する際に発生する以下のような課題が挙げられます。
- 開発端末のスペック : 高スペックな開発 PC を手軽に用意することができない
- 開発端末の調達のリードタイム : 開発要員の増員が発生した際に、調達や環境構築に時間がかかる
- ツールのバージョンアップ管理 : バージョンアップ作業を人手で実施してもらう場合、統制をとるのが難しい

### 1-2-2. マネージドな開発環境を用いるメリット
Cloud Workstations を導入することで、プロジェクトの管理者や参画する開発者はそれぞれ以下のようなメリットを享受できます。
- 管理者目線
  - GUI 上の操作だけで必要なスペックの開発端末を用意できる
  - 開発端末の定義について、一括で作成・更新できる
- 開発者目線
  - アクセス元の端末のスペックに依存することなく開発ができる
  - 環境構築に手間取ることなく、即時に開発へ参画できる
  - 開発端末の更新作業を自身で実施する必要がなくなる

### 1-2-3. その他パブリッククラウドのマネージド開発環境
主要なパブリッククラウドサービスでは、Cloud Workstations と類似したサービスを展開しています。それぞれサービスごとに機能に個性がある (使用できる IDE、開発端末の定義方法、etc...) ため、使用用途や現行の環境とのマッチングを考慮して選定すると良いでしょう。

- AWS : [Amazon CodeCatalyst](https://aws.amazon.com/jp/codecatalyst/)
- Azure : [Microsoft Dev Box](https://azure.microsoft.com/ja-jp/products/dev-box)

## 1-3. 用語の整理
### 1-3-1. Workstation クラスタ
Workstation 端末を配置する環境を指します。ロケーションの定義や属する VPC ネットワーク/サブネットワーク の指定、ゲートウェイの種類の選択を行い作成します。

### 1-3-2. Workstation 構成
開発端末の構成を定義したものです。開発端末のマシンスペック (マシンの vCPU や memory サイズ、永続ストレージのディスクタイプやサイズ、etc..) などを指定が可能です。  開発端末は Docker Image として定義されており、予め使用できる IDE が 事前定義されたベースイメージを用いることが可能です。 2023/12/22 時点で Google Cloud が公式に提供しているベースイメージには以下のようなものがあります。

- [Code-OSS](https://github.com/microsoft/vscode) : デフォルトのベースエディタ。ブラウザでのアクセスが可能。
- JetBrains IDE (IntelliJ IDEA Ultimate IDE や PyCharm Professional IDE など) : JetBrains Gateway を介してのみアクセス可能。
- IDE 無し : SSH でアクセスが可能。

また、これらの事前定義済みイメージを基に Dockerfile でツールや拡張機能のインストールを実施したイメージを作成しておくことで、そちらのイメージを使用して Workstation 構成を作成することも可能です。

### 1-3-3. Workstation 端末
Workstation 定義を基に作成した開発者ごとの開発端末を指します。


# 2. 開発端末の作成
## 2-1. カスタムイメージを用いた Workstation 構成の作成
### 2-1-1. Artifact Registry で リポジトリの準備
カスタムイメージを管理するリポジトリを Artifact Registry で準備します。

https://cloud.google.com/artifact-registry?hl=ja

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287616/2efeabf2-8694-7354-2085-4ee748e4995d.png)

作成したリポジトリには、以下の形式で docker pull, push が可能です。(この時点ではイメージは無い状態です。)

```
asia-northeast1-docker.pkg.dev/${PROJECT_ID}/${REPOSITRY_NAME}/${IMAGE_NAME}:#{TAG}
```

### 2-1-2. Dockerfile によるイメージ定義

:::note info
#### Google Cloud CLI の有効化
Artifact Registry へ push するためには、Google Cloud CLI を有効化する必要があります。Workstation 端末では gcloud コマンドがデフォルトで使用できるので、仮の端末を用意して以下のコマンドで認証とプロジェクトの設定を行えばカスタムイメージの push が可能になります。
```
$ gcloud auth login
$ gcloud config set project ${PROJECT_ID}
```
:::

以下の Dockerfile を使用してカスタムイメージを作成します。

- gradle のインストール
- 拡張機能のインストール
    - [Extension Pack for Java](https://open-vsx.org/extension/vscjava/vscode-java-pack)
    - [Spring Boot Extension Pack](https://open-vsx.org/extension/VMware/vscode-boot-dev-pack)

```dockerfile
# ベースイメージ
FROM asia-northeast1-docker.pkg.dev/cloud-workstations-images/predefined/code-oss:latest

# gradle のインストール
RUN wget https://services.gradle.org/distributions/gradle-8.5-bin.zip && \
unzip gradle-8.5-bin.zip && \
mv gradle-8.5 /usr/local/bin/
ENV PATH $PATH:/usr/local/bin/gradle-8.5/bin

# Code-OSS の拡張機能の追加
## 1. Extension Pack for Java
### Language Support for Java(TM) by Red Hat
RUN wget https://open-vsx.org/api/redhat/java/1.26.2023121208/file/redhat.java-1.26.2023121208.vsix && \
unzip redhat.java-1.26.2023121208.vsix "extension/*" && \
mv extension /opt/code-oss/extensions/redhat-java
### Debugger for Java
RUN wget https://open-vsx.org/api/vscjava/vscode-java-debug/0.55.0/file/vscjava.vscode-java-debug-0.55.0.vsix && \
unzip vscjava.vscode-java-debug-0.55.0.vsix "extension/*" && \
mv extension /opt/code-oss/extensions/java-debug
### Test Runner for Java
RUN wget https://open-vsx.org/api/vscjava/vscode-java-test/0.40.1/file/vscjava.vscode-java-test-0.40.1.vsix && \
unzip vscjava.vscode-java-test-0.40.1.vsix "extension/*" && \
mv extension /opt/code-oss/extensions/java-test
### Maven for Java
RUN wget https://open-vsx.org/api/vscjava/vscode-maven/0.42.0/file/vscjava.vscode-maven-0.42.0.vsix && \
unzip vscjava.vscode-maven-0.42.0.vsix "extension/*" && \
mv extension /opt/code-oss/extensions/java-maven
### Project Manager for Java
RUN wget https://open-vsx.org/api/vscjava/vscode-java-dependency/0.23.3/file/vscjava.vscode-java-dependency-0.23.3.vsix && \
unzip vscjava.vscode-java-dependency-0.23.3.vsix "extension/*" && \
mv extension /opt/code-oss/extensions/java-dependency

## 2. Spring Boot Extension Pack
### Spring Boot Tools  
RUN wget https://open-vsx.org/api/VMware/vscode-spring-boot/1.51.0/file/VMware.vscode-spring-boot-1.51.0.vsix && \
unzip VMware.vscode-spring-boot-1.51.0.vsix "extension/*" && \
mv extension /opt/code-oss/extensions/spring-boot
### Spring Initializr Java Support
RUN wget https://open-vsx.org/api/vscjava/vscode-spring-initializr/0.11.2/file/vscjava.vscode-spring-initializr-0.11.2.vsix && \
unzip vscjava.vscode-spring-initializr-0.11.2.vsix "extension/*" && \
mv extension /opt/code-oss/extensions/spring-initializr
### Spring Boot Dashboard
RUN wget https://open-vsx.org/api/vscjava/vscode-spring-boot-dashboard/0.13.1/file/vscjava.vscode-spring-boot-dashboard-0.13.1.vsix && \
unzip vscjava.vscode-spring-boot-dashboard-0.13.1.vsix "extension/*" && \
mv extension /opt/code-oss/extensions/spring-boot-dashboard
```

:::note info
#### 拡張機能のインストール URL の取得
[Open VSX Registry](https://open-vsx.org/) でインストールしたい拡張機能を検索し、`DOWNLOAD` ボタンを右クリックして「リンクのアドレスをコピー」を実施することで URL の取得が可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287616/c4e843e0-f85d-c059-4189-74b51e8a65ae.png)
:::

用意した Dockerfile を使用してカスタムイメージの Build、Push を行います。 

```
$ docker build . -t asia-northeast1-docker.pkg.dev/${PROJECT_ID}/${REPOSITRY_NAME}/${IMAGE_NAME}:#{TAG}
$ docker push asia-northeast1-docker.pkg.dev/${PROJECT_ID}/${REPOSITRY_NAME}/${IMAGE_NAME}:#{TAG}
```


### 2-1-3. 作成したイメージを基に Workstation 構成を作成
Google Cloud コンソールの Cloud Workstations の画面から、Workstation 構成の作成を行います。
手順「環境設定」の使用するイメージを指定する箇所で以下の 2 つを指定します。
- コンテナイメージの URL : 上記手順で作成したカスタムイメージの URL
- サービスアカウント : コンテナイメージを pull する権限を付与したサービスアカウント

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287616/1d1380bd-3774-08d5-718d-5a0db1508b0f.png)

以上の手順で、カスタムイメージを使用した Workstation 構成から Workstation 端末の作成が可能になります。


## 2-2. 動作確認
### 2-2-1. Workstaion 端末の起動
作成した Workstation 構成から端末を作成・起動し、コンソールから「開始」のボタンを押すと、以下の URL でブラウザから Workstation 端末の Code-OSS へアクセスが可能になります。
```
https://80-${WORKSTATION_ID}.${CLUSTER_ID}.cloudworkstations.dev
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287616/62e9b1a7-dff8-c188-6db5-d409e5113883.png)

立ち上がった端末上では、ファイル編集やターミナルの操作、Git 操作など、VSCode と同等の操作が可能です。また、docker や node などがデフォルトで入っており、バージョン指定が不要な場合これらは特別な設定を行わずすぐに使用することが可能です。

また、Dockerfile で定義した gradle や Code-OSS の拡張機能についてもインストールされていることが確認できます。(上記手順でインストールした拡張機能については、手動でインストールした場合とは違い、拡張機能画面のバージョン番号の横に `Built-in` と表記されます。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287616/d4370c70-f4fa-e254-a274-077d69a5b4e0.png)


:::note warn
#### 権限を持たない Workstation 端末にアクセスした場合...
Workstation 端末へのアクセス権は、Google アカウント に対して当該端末への `Cloud Workstations User` ロールが付与されているかで判定されます。
- 未サインインの場合、Google アカウント認証の画面にリダイレクトされます。
- 別アカウントでサインイン済みの場合は、以下のように 401 エラーでアクセスを拒否されます。
```
401: The Workstations does not exist or your currently signed in account {{ Google アカウント }} does not have access to it 
```
:::

### 2-2-2. サンプリアプリへのアクセス
Workstation 端末で立てたアプリケーションには、workstation 端末にアクセスする際の URL の冒頭の `80` のポートを、アプリケーションのポート番号に変更することでアクセスが可能です。 

```
# localhost:8080 に対応
https://8080-${WORKSTATION_ID}.${CLUSTER_ID}.cloudworkstations.dev
# localhost:8080/hoge に対応
https://8080-${WORKSTATION_ID}.${CLUSTER_ID}.cloudworkstations.dev/hoge
```

:::note info
#### Workstation 端末で立てたアプリに curl でアクセスした場合...
- Workstation 端末内から : アクセス可能
```
user@inner-workstation01:~$ hostname
inner-workstation01
user@workstation01:~$ curl inner-workstation01:8080/hoge
<!DOCTYPE html>
<html>
<head>
    <title>Hoge</title>
~ 以下略 ~
```

- Workstation 端末外から : OAuth による認可を要するため直接のアクセスは不可
```
user@outer-workstation01:~$ curl https://8080-inner-workstation01.${CLUSTER_ID}.cloudworkstations.dev/hoge
<a href="https://ssh.cloud.google.com/devshell/gateway/oauth?state={hogehoge}">Found</a>.
```
:::

:::note warn
#### 権限を持たない Workstation 端末で立てたアプリにブラウザからアクセスした場合...
- 未サインインの場合、500 エラーでアプリに到達することはできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287616/f44ad50d-13de-ed4d-1736-e71012b3db87.png)
- 別アカウントでサインイン済みの場合は、Workstation 端末の際と同様に 401 エラーでアクセスを拒否されます。
:::


# 3. Duet AI を用いたコーディングアシストの活用
## 3-1. Duet AI って何？
Google Cloud が提供する AI アシスタントであり、自然言語によるチャットでの問答やコーディングのアシストが可能です。Duet AI は Cloud Workstations 上での有効化がスムーズであり、幾つかのステップを踏むことで直ぐに端末上で利用できるようになります。

:::note info
#### Duet AI の種類
Duet AI は以下の 2 種類がありますが、Cloud Workstations で用いるのは開発者向けの Duet AI for Developers です。調べる際に混同しないよう注意してください。
- Duet AI for Google Workspace : オフィスワーカー向け
- Duet AI for Developers : 開発者向け
:::

## 3-2. Cloud Workstations での Duet AI の有効化

### 3-2-1. 管理者側
管理者は、Cloud Workstations クラスタを構築したプロジェクトに対して、Duet AI を使うための API の有効化と開発者へのロール付与を行う必要があります。

1. Cloud AI Companion API の有効化
1. 開発者への IAM ロールの付与
    - Cloud AI Companion ユーザー
    - Service Usage 閲覧者

### 3-2-2. 開発者側
開発者は Workstation 端末上で、google cloud cli を有効化して Google Cloud に接続し、拡張機能で Duet AI の有効化を行う必要があります。

1. IDE 画面の左下の「Cloud Code - Sign in」をクリックし、手順に沿って Google Cloud SDK から Google アカウントへのアクセス許可を行って、Workstation 端末を Google Cloud へ接続する。
1. Workstation 端末の設定画面で、拡張機能「Google Cloud Code」の「Cloudcode>> Duet AI: Enable」にチェックを入れる。 ![スクリーンショット 2023-12-19 085757.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287616/52e27a45-6da0-fba6-9c58-e0a6962f8fbd.png)
1. Duet AI ステータスバーをクリックし、Cloud AI Companion API を有効化したプロジェクトを選択する。

以上の手順により、Workstation 端末上で Duet AI が利用できるようになります。利用できるようになると、IDE の左側の吹き出しアイコンをクリックすることで Duet AI とやりとりするためのチャット画面を表示することができます。

![スクリーンショット 2023-12-19 094117.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287616/2e804940-ff9c-c7ac-d828-01202bc96de9.png)

## 3-3. Duet AI でできること
ここでは、Workstation 端末上での Duet AI の活用方法を紹介します。ここで紹介する機能はあくまで一例であり、実際はチャットへの入力方法次第でより効果的な活用ができると思われます。

### 3-3-1. コードの説明
Duet AI は特定のソースコードを指定しなくても、現在開いているファイルに関する質問をすることができます。ファイル全体に関する質問を投げる場合は、この方法で質問を行うことで回答を受け取ることができます。

![スクリーンショット 2023-12-19 094459.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287616/e20cda62-04a9-c11e-f919-0c6185adfcda.png)

### 3-3-2. コードの修正
Duet AI は選択範囲を絞って Duet AI に質問することも可能です。範囲選択した状態で、Duet AI のチャット画面に質問を入力すると、質問と選択した範囲のソースコードがセットになった状態で質問が投げられます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287616/313e5510-0651-a4af-8830-7b3b7459583d.png)

### 3-3-3. テストコードの生成
Duet AI には「スマートアクション」という機能があり、これにより Duet AI に行ってほしいことを素早く呼び出すことが可能です。以下のスクリーンショットの「More Actions...」以下の部分が Duet AI を呼び出せるスマートアクションとなっています。

- Generate code
- Explain this
- Generate unit tests

![スクリーンショット 2023-12-19 095751.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287616/686007a6-1637-6e24-3bdb-097baea63ace.png)

ここで「Generate unit tests」を選択すると、チャット画面上に選択範囲とともに質問が作成され、Duet AI が回答を返してくれます。

![スクリーンショット 2023-12-19 095838.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287616/2edc39a9-5e3f-e85c-ed10-902773cd723c.png)

### 3-3-4. コード補完
ソースコードのコメントからソースコードを自動補完することも可能です。コメントを入力することで生成候補のソースコードを表示し、Tabを入力することで補完が完了します。

![スクリーンショット 2023-12-19 094622.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287616/b0fe1532-d76f-77ef-c2db-e352438655d2.png)


# 4. おまけ : Cloud Workstations の注目プレビュー版機能
以下の機能はまだプレビュー版として提供されている段階ですが、いずれメイン機能として使えるようになることを考えると、より Cloud Workstations の活用シーンが増えそうですね。
- GPU が使用可能なマシンタイプのサポート : NVIDIA の GPU が使用可能なマシンタイプを選択することで機械学習開発環境に利用可能
- Terraform のサポート : Terraform を用いてリソースと権限の構成ファイルで記述することでアーキテクチャを IaC で構成可能
- BeyondCorp Enterprise を使用した Cloud Workstations 環境の保護 : Google Cloud のゼロトラストソリューション「[BeyondCorp Enterprise](https://cloud.google.com/beyondcorp-enterprise?hl=ja)」を使用することで、コンテキストウェアアクセス制御やDLP(データ損失防止)機能によるソースコードのダウンロード防止等を実施することが可能


# 5. おわりに
Cloud Workstations や Duet AI によって、マネージド開発環境による開発端末の提供の高速化と、AI 協業による開発の高速化について、その実現可能性が確認できました。これらサービスは、管理者にとっても開発者にとっても有益であり、開発をより円滑にしてくれるだけのインパクトがありますね。本記事ではあくまで各種サービスの機能の紹介に留めましたが、今後はコスト面やセキュリティ面に関しても実現場に沿った考察をしていけたらと考えています。


# 6. 参考
- [Cloud Workstations のドキュメント](https://cloud.google.com/workstations?hl=ja) 
- [Duet AI のドキュメント](https://cloud.google.com/duet-ai?hl=ja)