ものぐさプログラマの為のWaypoint
HashiCorpから新しいツール「Waypoint」が発表されました。個人的に、buildpacks を利用したDockerfileレスなビルドセットアップを学んでいた流れもあり、自身の理解も兼ねて記事にしました。
記事内ではWaypointの簡単な概要から、Goプロジェクトをビルド、最近私が愛用しているGoogle Cloud Runへのリリースまでを行います。
今回のサンプルリポジトリはこちら
Waypointとはなにか?
ぶら下がるインフラ(Docker, k8s, Serverless etc.. )やPaaSベンダに依存しない、ビルド・デプロイ・リリースが行える単一のワークフローを提供するもの。必要なものは、対象のソースコード、シンプルな構成ファイル、そして waypoint up
のコマンドのみで実現出来ます。
現実に即してるなと思ったのであえてタイトルにも冠してますが、私自身がWaypointを好きになれそうな点が2つあります。
1つ目は上記の動画で説明がある通り、一般的にプログラマが辿る工程は
Write -> Test -> Build -> Deploy -> Release -> Operate -> Measure
となっており、左からプログラマは興味関心が高く、右に行くほど薄くなるという点です。これは全プログラマとは言わなくとも、多くのプログラマ(少なくとも私には)当てはまるのではないでしょうか。
デプロイされる先や、何で動いているかは興味を持つべき範囲なのはわかりますが、じゃあ積極的に知りたいか、学びたいかと言われると僕自身はちょっと…って思ってしまうんですよね。このように、アプリが何で、どこで動いているかに関わらず、アプリをビルド・デプロイ・リリースするための一貫した方法が欲しいというのはまさに私自身が思ってたことでした。(あとyamlが個人的に苦手)
2つ目に、Waypoint自体が方法論に固執していないことです。「すべき論」で語れば、ビルド、デプロイ、リリースというフェーズはCI/CDに組み込んでみたり、GitOpsをベースとしたアプローチを用いるべきかもしれませんが、Waypoint自体はCLIからの直接操作やChatOpsだったり、Waypointが提供するUIからだったりなど、チームやプロジェクトの状態によって一番良い方法が取れる柔軟性があります。
Waypointの使い方
Waypointインストールから、Goの簡単なプロジェクトのビルド、Google Cloud Runへのデプロイ、リリースまでの手順を一通り説明します。前述の通りWaypointはAmazon ECS/EKSやGoogle Cloud Runなど複数のPaaSベンダやサービスに適用出来ますので、公式ドキュメントをまず確認し、自身に一番沿った環境で実践することをお勧めします。
インストール
macOSかつDocker Desktopインストール済が前提です。
brew tap hashicorp/tap
brew install hashicorp/tap/waypoint
waypoint
コマンドが使えるようになります。
次にサーバーをインストールします。
docker pull hashicorp/waypoint:latest
waypoint install -platform=docker -accept-tos
※重要
-accept-tos
はWaypoint URL Serviceを有効にするフラグです。詳細は左記ドキュメントと利用規約をよく読んでください。
Advertise Address: waypoint-server:9701
HTTP UI Address: localhost:9702
localhost:9702
にアクセスし、
Authenticate... をクリック。
waypoint token new
上記で発行されたトークンを貼り付けます。
GCP環境準備
GCPのプロジェクト作成とCloud Runの有効化は省きます。
GCPのプロジェクトからIAMと管理 > サービスアカウントを選択し、Waypointで利用するサービスアカウントを作成、名前は分かりやすい一意の名前をつけます。
ロールには「Cloud Run 管理者」を付与し、完了。
作成したサービスアカウントの一覧オプションから「鍵を作成」をクリックし、ファイルをダウンロード。
環境変数にGOOGLE_APPLICATION_CREDENTIALS
をセットし、上記の鍵のパスをセット。
※鍵の細かい取り回しについては本筋ではないので省きますが、取り扱いに注意してください
Goのサンプルアプリを準備
せっかく(?)なのでWAFのFiberを使って見ましょう。
mkdir go-fiber-waypoint && cd go-fiber-waypoint
go mod init
main.go
package main
import (
"log"
"os"
"github.com/gofiber/fiber/v2"
)
func main() {
app := fiber.New()
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Hello, World!")
})
log.Fatal(app.Listen(":" + os.Getenv("PORT")))
}
PORTを環境変数から注入してください。direnvがおすすめ。
go run main.go
┌───────────────────────────────────────────────────┐
│ Fiber v2.1.0 │
│ http://127.0.0.1:8080 │
│ │
│ Handlers ............. 2 Threads ............. 4 │
│ Prefork ....... Disabled PID ............. 34090 │
└───────────────────────────────────────────────────┘
ローカルでアプリの起動は成功しました。
構成ファイルの作成
プロジェクトルートに waypoint.hcl
を作成します。
project = "go-fiber-waypoint"
// アプリケーション
app "go-fiber-waypoint" {
labels = {
"service" = "go-fiber-waypoint"
}
// ビルド
build {
// buildpacksを利用
use "pack" {}
registry {
// dockerのレジストリを設定
use "docker" {
// GCRへ
image = "asia.gcr.io/${GCP_PROJECT_ID}/go-fiber-waypoint"
tag = "latest"
}
}
}
// デプロイ
deploy {
// Cloud Runを利用
use "google-cloud-run" {
// GCPプロジェクト
* project = "${GCP_PROJECT_ID}"
// 東京リージョン
location = "asia-northeast1"
// Cloud Run固有の設定
capacity {
memory = 128
cpu_count = 1
max_requests_per_container = 10
request_timeout = 300
}
auto_scaling {
max = 2
}
}
}
// リリース
release {
use "google-cloud-run" {}
}
}
さて、この状態まで出来たら、waypointのセットアップ及び実行を行います。丁寧でありがたかったのは、事前にwaypoint.hcl
を解析してinit
の時点で、GCPの接続で足りないAuthn部分の設定などをエラー吐いてくれます。
waypoint init
waypoint up
» Building...
Creating new buildpack-based image using builder: heroku/buildpacks:18
✓ Creating pack client
✓ Building image
│ [exporter] Reusing layer 'heroku/go:profile'
✓ Injecting entrypoint binary to image
Generated new Docker image: go-fiber-waypoint:latest
...
* » Deploying...
» Releasing...
The deploy was successful! A Waypoint deployment URL is shown below. This
can be used internally to check your deployment and is not meant for external
traffic. You can manage this hostname using "waypoint hostname."
Release URL: ${ $CLOUDRUN_URL }
Deployment URL: ${ $WAYPOINT_URL_SERVICE }
このように表示されたのち、Release URLを開いてCloud Run上にアプリが開いていたら成功です。
コードを変更し再デプロイ
main.go
を変更してみましょう。
app.Get("/", func(c *fiber.Ctx) error {
// return c.SendString("Hello, World!")
return c.SendString("Hello, Waypoint!")
})
waypoint.hcl
のbuildも変更してみます、デフォルトのbuildpacks(packs{}
)はheroku/buildpacks:18
が使われるようです。distrolessを使いたいのでpaketobuildpacks/builder:tiny
を指定してみましょう。
// buildpacksを利用
use "pack" {
builder="paketobuildpacks/builder:tiny"
}
さて、この状態で再度 waypoint up
を再度実行します。
Release URL: ${ $CLOUDRUN_URL }
Deployment URL: ${ $WAYPOINT_URL_SERVICE --v2 }
URLにアクセス出来て正常稼働していれば成功です。
UI上からプロジェクトの状況を確認
waypoint ui
で、ブラウザからプロジェクトの状態を確認出来る管理画面が表示されます。
プロジェクトの削除
waypoint destroy
で削除可能。Cloud Runのようなサービス上でリリースされている場合は、稼働中ということで削除が出来ないようになっているようです。
感想
ある程度直感的かつ、デプロイまで一括して管理してくれるのは助かるの一言です。hcl
ファイル自体今回初めて触ったんですが、特別難しい部分もなく。反面「こんなん無くてもmakefileでええやんけ!」という主張も非常にわかります、なんだかんだで全く苦労せずに出来たかというと概念の理解に時間取られたりもしましたし。
今回は直接Cloud Runへのデプロイでしたが、Github Actionsへの組み込みなども今後試していきます。
Discussion