ポストCloud9?クラウドIDE CoderでPlatform Engineeringを実践する

Yutaro Shirayama

2024.10.3

はじめに

こんにちは、Sreake事業部の志羅山です。

早いものでもう10月。私が住む長野県はもう朝晩の気温は10℃台となり、日中もとても過ごしやすい気候です。振り返ると今年の夏は天気も不安定で、とても暑い夏でしたね・・。

Cloud9の新規受付が終了

そんな夏のリリースとして7月25日に発表されたAWS DevOps Blogの”How to migrate from AWS Cloud9 to AWS IDE Toolkits or AWS Cloudshell”にて、AWSのクラウドIDEサービスである”Cloud9”が、7月25日より新規利用を終了することがアナウンスされました。

After careful consideration, we have made the decision to close new customer access to AWS Cloud9, effective July 25, 2024. AWS Cloud9 existing customers can continue to use the service as normal. AWS continues to invest in security, availability, and performance improvements for AWS Cloud9, but we do not plan to introduce new features.

既にCloud9を利用しているアカウントでは、引き続き既存の環境を利用したり新しいインスタンスを作成することはできるようですが、最近弊社で作成した社内検証用AWSアカウントではCloud9にアクセスすると以下のように表示され、サービスを利用することができなくなっています。

後継クラウドIDEとして…

正式にサービス終了がアナウンスされた訳ではありませんが、”we do not plan to introduce new features”とあるように新規機能開発は今後されなくなるということで、代替サービスを検討してもいいタイミングかもしれません。

本記事では、数あるクラウドIDEプロダクトの中からCoderにスポットを当て、Platformチームが開発プラットフォームとしてCoderを採用するメリットや考慮すべき点を紹介します。具体的な構成例や各種機能についても解説しますが、他のクラウドIDEとの詳細な比較については割愛します。

Coderの概要

クラウドIDEとは

そもそも「クラウドIDEとは何か?」という問いの理解にあたっては、2022年に投稿された以下のCoder公式ブログが助けになります。

https://coder.com/blog/what-is-a-cloud-ide

「ビルドやデバッグのための計算リソースがクラウド上に構成されている」ことがクラウドIDEの特徴ですが、更に細かい分類として、

  • インターフェース含めたすべてをクラウド上で独自仕様で提供するアプローチ(Cloud9はこっちに該当)
  • よく知られたローカルIDEをクラウドベースのサービスとして提供するアプローチ

という区分が提唱されており、Coderは「VSCodeのように馴染みのあるIDEをベースとしたインターフェースを提供している」という点で後者に分類されています。

Coderの外観を見てみる

まずは雰囲気を掴むために、CoderのUIを実際に見てみましょう。

CoderのUIにブラウザからログインすると、自分が作成したワークスペースと呼ばれる開発環境の操作画面にアクセスできます。

中央のボタンそれぞれから、異なるインターフェースでワークスペースに接続できます。

中でも最も便利な機能が、一番左の「VS Code Desktop」経由の接続です。

このボタンを押すと、クラウド上のワークスペースに接続した状態でローカルのVS Codeが起動します。

VS Codeの拡張機能もターミナルでのプロンプト操作もGit操作も、ローカル開発と同じ感覚で使用できますが、計算リソースの実体はクラウド上のワークスペースであるため、ビルドやデバッグでローカル端末のリソースを消費することがありません。

また、端末がMacの場合に考慮するべき事項(例えば、開発環境とリリース先環境のCPUアーキテクチャの差異の対応)も、接続先のワークスペースがLinuxであれば気にする必要がありません。

他にも、ローカルにVS Codeが存在しない場合でもブラウザ上でVSCodeライクなエディタを使用できる「code-server」機能、ブラウザからターミナル接続できる「Terminal」機能、ワークスペースの任意の解放ポートにブラウザで接続する「Open ports」機能と、とても充実しています。

↑上記はcode-serverのUI。Terminalも拡張機能も使えるので、使用感はVS Codeとあまり変わりません。

また、ワークスペースの操作画面にはワークスペースを起動・停止・再起動・削除するボタンが実装されており、各開発者が自分のワークスペースを自分で操作・管理できるようになっています。このあたりのセルフサービス的デザインも、Coderの大きな特徴の一つです。

Coderの構成・仕組み

ここからは、Coderの詳しい構成を見ていきましょう。

Coderを構成するコンポーネント

Coderを構成するコンポーネントを以下に示します。

名称説明
ワークスペース開発者単位で作成されるクラウドリソースのセット。実体はKubernetes Podや、EC2等のコンピュートサービス。開発者はブラウザやローカルのVSCodeからワークスペースに接続して開発を行う
coderdcoderのコアコンポーネント。管理UIの提供、ユーザがワークスペースにアクセスする際のリバースプロキシ、coderエージェントとの通信など、役割が多岐に渡る
coderエージェントワークスペースに常駐するエージェントコンポーネント。ワークスペースのヘルスチェックやポートフォワード実行時の処理、カスタムスクリプトの実行等を担当する
provisionerdワークスペースの実体となるクラウドリソースをterraformによって管理するコンポーネント

参考:https://coder.com/docs/architecture/architecture

これに加えて、ワークスペースの構成情報やユーザ情報などの情報を保持するPostgreSQLがあり、coderdによって管理されます。

ここまでの情報を簡易的に図示すると、このような形になります。

CoderをKubernetesでホスティングしている環境では、provisionerdという名前のPodは存在しなかったので、真ん中の箱の部分は実体は1つのコンポーネントと捉えた方が分かりやすいかもしれません。

前節で紹介したVS Code Desktop経由の接続は、「端末のVSCode DesktopからのHTTPS接続がcoderdによって中継されて、ワークスペースに到達している」というのが実際の動きです。上記図では簡素化していますが、coderdはALBなどの外接サービスを構成して開発者に公開する必要があります。

Coderワークスペースの管理

provisionerd の説明で突然のTerraformの登場に「??」となっている方もいるのではないかと。

Coderは各開発者に対してデプロイするワークスペースのひな形を、Terraformのコードを中心とした「ワークスペーステンプレート」というオブジェクトで管理しています。

この「各開発者のワークスペースをTerraformで管理する」というアーキテクチャこそ、Coderの最も注目すべき特徴であり、CoderがPlatformチームにとっての開発者プラットフォームの優位な選択肢になり得る要素かもしれません。

例として、Coderがデフォルトで提供しているStarter TemplatesのサンプルコードAWS EC2(Linux)を見てみましょう(EC2以外にも、Azure VM、GCE、kubernetes Podなど様々な形式でワークスペースを払い出すためのテンプレートが用意されています)。

AWS EC2(Linux) テンプレートの冒頭では、Terraform Providerとしてcoder/coderhashicorp/awsがロードされています。それぞれのプロバイダの利用方法について、実際のリソースを例に見ていきましょう。

terraform {
  required_providers {
    coder = {
      source = "coder/coder"
    }
    aws = {
      source = "hashicorp/aws"
    }
  }
}

以下のcoder_parameter リソースはcoder プロバイダのリソースですが、ここでは開発者がワークスペースを作成する際の画面の入力値としてインスタンスタイプをオプション型で選択させる画面上のUIを定義しています。

data "coder_parameter" "instance_type" {
  name         = "instance_type"
  display_name = "Instance type"
  description  = "What instance type should your workspace use?"
  default      = "t3.micro"
  mutable      = false
  option {
    name  = "2 vCPU, 1 GiB RAM"
    value = "t3.micro"
  }
  option {
    name  = "2 vCPU, 2 GiB RAM"
    value = "t3.small"

~略~

上記リソースで作成される実際の画面はこちら。UIもTerraformのコードでデザインできるという点が画期的に感じます。

テキスト型のパラメータも定義できるほか、パラメータにバリデーションをかけたり、Immutable 属性を付与して変更不可にしたりすることもできます。

次に、hashicorp/aws プロバイダのリソースを見てみましょう。ここでは実際にワークスペースとして作成されるEC2やEBSなどのリソースが定義されています。

resource "aws_instance" "dev" {
  ami               = data.aws_ami.ubuntu.id
  availability_zone = "${data.coder_parameter.region.value}a"
  instance_type     = data.coder_parameter.instance_type.value

  user_data = local.user_data
  tags = {
    Name = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}"
    # Required if you are using our example policy, see template README
    Coder_Provisioned = "true"
  }
  lifecycle {
    ignore_changes = [ami]
  }
}

前述のcoder_parameter は、UIの入力画面を作成するリソースであると同時に、dataリソースとしても利用可能で、

"${data.coder_parameter.region.value}a"

のような形式で他のAWSリソースにユーザが設定した値を渡すことができます。

このテンプレートに必要な値を入力してワークスペースの作成を実行すると、ワークスペース作成処理が開始され、以下のようなログが表示されます。

コンポーネント一覧で紹介したprovisionerd がワークスペーステンプレートのTerraformコードをterraform apply し、裏でEC2インスタンスやEBSが作成されていることが分かります。Terraformのコードで定義できるリソースであれば何でもワークスペーステンプレートに含めることができるので、例えばRDSなどもテンプレート化することも可能です。

以下のテンプレートのようにcount パラメータを活用することで、EBSボリュームを除いたEC2インスタンスなどを、起動停止ごとに作成・削除するというKubernetes Podに似た構成にすることも可能です。

https://github.com/bpmct/coder-templates/blob/main/aws-linux-ephemeral/main.tf

ここで注目すべきは、Coderのテンプレートコードをカスタマイズすることで、platformチームは「ユーザがどのような入力値を設定し、どんなワークスペースを作成・運用できるか?」をコードベースで中央集権的に管理できる、という点です。

EC2リソースのベースAMIにPlatformチームが管理しているAMIを指定したり、EC2インスタンス作成時に渡すuserdataを独自に記述することで、プラットフォームチームはソフトウェアや統制的設定をコードで統合的に実装・管理できるのです。

しかも、ワークスペースの実際のライフサイクル管理は開発者自身が行うため、Platformチームはワークスペースの払い出し等に手間をかける必要がありません。

この、「作成・起動・停止・削除のライフサイクルはセルフサービス型でユーザ側に委任されている」「払い出すワークスぺースの構成はテンプレートとしてプラットフォームチームが管理する」という、いわばプラットフォームエンジニアリングの思想に沿った運用が可能である点が、Coderの大きな特徴です。

プラットフォームとしてのCoderのアーキテクチャの検討

Coderの基本的な構成、ワークスペースのライフサイクル管理の仕組みに一通り触れたところで、ここでは開発者向けプラットフォームとしてCoderを組織内で提供するためのアーキテクチャを、AWSを例に考えてみます。

プラットフォーム全体で考えると監視やセキュリティなど要素は多岐に渡りますが、Coderに関連する部分にフォーカスすると、主なポイントは「coderd をどう構成するか?」「ワークスペースをどう払い出すか?」の2つです。

coderd をどう構成するか?

コアコンポーネントであるcoderd を構成する選択肢としては、プラットフォームとして提供するのであればEC2かEKSのどちらかになるかと思います。

EC2で動かしたい場合、AMIマーケットプレイスにある公式イメージを利用するか、自分でEC2インスタンスにインストールすることで構成可能です。

EKSで動かしたい場合は、Helm Chartが公開されているのでこれを利用して構成可能です。

仮に全てEC2で構成する場合の構成例を以下に示します。外接部分はインバウンド通信をALBで制御し、アウトバウンドはNAT Gatewayを経由するように構成します。

セキュリティ要件に応じてWAFやNetwork Firewallを追加したりすることも可能です。デプロイ先のクラウドプロバイダの機能を自由に組み合わせることができるのは、セルフホスト型のクラウドIDEならではの利点ですね。

ワークスペースをどう払い出すか?

ここが、開発者体験・Platformチームの管理負荷・コストなどに大きく影響する部分です。

AWS上で提供する場合、ワークスペースのホスティング方式は「EC2方式」と「Kubernetes(EKS) Pod方式」の2つが主な選択肢になると想定して、いくつかのキーポイントを比較します。

開発者体験の観点

EC2型の場合、EKS Pod型よりもセキュリティを厳しく設定する必要があるため、開発者体験の観点からはEKS Pod型の方が優位になる可能性があります。

例えば、EC2型ではインスタンスを丸ごと払い出すために、以下のようなセキュリティ実装を検討する必要があります。

  • rootユーザへのスイッチを禁止する
  • sudoでの実行可能なコマンドを制限する
  • DockerはRootlessモードで提供する

EC2型の場合Dev Containerが利用できるので環境構築はどうとでもなるのですが、「自由に使えるEC2インスタンス」としては提供しにくいかもしれません。

また、EKS Podに比べてEC2はどうしても起動速度が遅くなるので、手軽に起動して使いたいという場合には少しストレスを感じます。

ベースイメージ管理の観点

ワークスペースに独自のカスタマイズを行いたい場合、EC2型の場合はカスタムAMIを、EKS Pod型の場合はベースイメージを管理します。

EC2型の場合、userdataをテンプレートにバンドルすることで共通設定を行うこともできますが、userdataが肥大すればそれだけワークスペースの起動が遅くなります。可能であればPackerなどであらかじめ必要な設定を行ったAMIを作成しておくのがよいでしょう。

EKS Pod型の場合、Dockerfileで定義したベースイメージをECRに格納しておくことで管理可能です。コンテナを使った開発に慣れている組織であれば、こちらの方が馴染みがあるでしょう。

課金管理の観点

プラットフォームチームがCoderの利用コストを各開発チームに従量課金制で請求する場合、「誰が何をどれくらい使ったか?」を集計する必要があります。

EC2型の場合、ワークスペースリソースに持ち主を特定できるコスト配分タグを付与することができれば、基本的にはCost Explorerが算出したデータを利用するだけでよいため、独自ロジックも最小限で済みます。インスタンスサイズに対して独自の時間単価を設定したい場合は、使用タイプごとのusage_amount (EC2の場合は起動時間)を活用できます。

EKS Pod型の場合、PVとして作成されたEBSを除くとリソースの抽象度が高いため、ユーザごとの各ワークスペースの利用量の算出には工夫が必要です。

例えば、CoderはPostgreSQLに各ワークスペースの起動停止の記録を保持しているため、このデータを利用すればプロダクトから見たときの「誰がどれくらい使ったか?」を可視化することができます。また、2024年4月にリリースされたCURのSplit Cost Allcation Dataを活用すれば、Pod単位でのコストを算出することもできます。

ただし、これらの情報を抽出・処理するSQLやロジックを実装したり、Cost Explorerで確認できる実際の利用量や請求額のデータと整合させるのはかなり大変なので、コスト請求を厳格に行いたい場合はEKS Pod型は厳しいかもしれません。

コスト効率の観点

ここでいうコスト効率とは、「プラットフォームとしてユーザ(開発者)に提供するコンピュートリソース(CPU・RAM)の単価がどれくらい適切か?」という観点です。

結論から示すと、EC2型の方がコスト効率が高い可能性があるので、自組織における計測・チューニングは時間をかけて行った方がよいでしょう。

例えば、EKS Pod型でワークスペースを提供する場合を考えてみます。

ワークスペースPodをスケジュールするノードとして8CPU/32GiBのコンピュートリソースを持つt2.2xlargeのEC2が1台起動しています。

単純計算すれば2CPU/8GiBのワークスペースPodはこのノードに4つスケジュールできますが、実際にはノードのオーバーヘッドや、fluentbitやPrometheus Node ExporterなどのDarmonSetを構成する場合これらのPodが消費するリソースも含まれるため、綺麗に4つスケジュールするにはワークスペースPodのRequest値を0.x掛けにするなどの工夫が必要です。

また、ノードをKarpenterで管理すればノードの空き容量などに応じてKarpenterがいい感じにPodをスケジュールしてくれそうですが、ワークスペースはワークロードとしての性質上「様々なサイズのPodが全く異なるタイミングで起動したり停止したりする」ため、Karpenterによるノードリソースの最適化にも限界があります。

結果として、EKSノードのリソース全量に対する、実施に使われているワークスペースPodのリソース量の割合が上がらず、Cost Explorerの請求額をベースにすると各Podのリソース単価がEC2のリソース単価よりも高くなってしまう可能性があります。

参考として、Karpenterを利用した状態の業務時間帯の利用効率(ワークスペースPodのRequest値の総量÷ノードのリソース総量)は最大で70-80%、誰も使っていないはずの夜間でも起動しっぱなしのワークスペースがあると40%程度までしか下がらないという例もありました(弊社実績)。

こういった要因によってKubernetes Pod型でも想定よりコスト効率が上がらない可能性もあることを加味し、コスト効率を重視する場合は十分な計測とチューニング期間を設けるのがよいでしょう。

OSS版とEnterprise版の違い

最後に、CoderのOSS版とEnterprise版の機能差異についても触れておきましょう。

https://coder.com/docs/enterprise

上記ページにあるように、CoderにはOSS版に加えてより機能が充実した有償版(Enterprise版)が存在します。

例えば、OSS版ではcoderd を冗長化することができませんが、Enterprise版では可能です(Pod型の場合であれば、Replica数を2以上に出来る)。

他にも、グループごとに利用できるワークスぺーステンプレートの制御、Terraformのランナーをcoderdから独立して実行する構成など、利用規模が大きくなると必要になる機能はほぼEnterprise版でしか利用できません。

組織規模に応じてEnterprise版の利用も検討するのがよいでしょう。

おわりに

Coderは、

  • ユーザがポータルを通じてセルフサービス型で利用できる
  • 管理者は、ワークスペースのテンプレートをコードとして管理できる
  • セルフホスト型であるが故に、組織の方針に準じて様々なサービスをインテグレーションできる

という特徴を持ったクラウドIDEプロダクトです。

プラットフォームチームとしてCoderを開発チームに提供する場合、プロダクトの機能だけでプラットフォームエンジニアリングの思想に則ったサービス運用ができるので、これまで社内IDEの運用に苦労していたプラットフォームチームであれば、導入する価値は十分にあると思います。

ブログ一覧へ戻る

お気軽にお問い合わせください

SREの設計・技術支援から、
SRE運用内で使用する
ツールの導入など、
SRE全般についてご支援しています。

資料請求・お問い合わせ