インフラもバックエンドもフロントエンドも Go で書いてみた
先日 CDK for Terraform が GA になりました。
CDK for Terraform を使うことにより、 TypeScript や Go などといったプログラミング言語を使って Terraform エコシステムを利用したインフラの定義やプロビジョニングを行うことができます。
「Go でインフラが書ける」と聞き、ふと思ったことがこちらです。
というわけで書きました。
(2022/10/27 追記) CI/CD も Go で書いた記事を公開しました。
作ったもの
GoGoGo
猫の画像をランダムで表示するサンプルアプリです。
主な利用技術について簡単に紹介します。
利用技術
Go
説明不要ですね。
Google 様が作ったプログラミング言語です。
Gin
Go の軽量な Web フレームワークです。
公式の紹介に「パフォーマンスは Martini の最大 40 倍です」と書かれているように、速さが売りのようです。
こんな感じでシンプルに小さく始められます。
// 引用: https://github.com/gin-gonic/gin#quick-start
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "pong",
})
})
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
類似のフレームワークとしては echo や Iris などがあります。
Vecty
Go + WebAssembly を使用してフロントエンドを構築することができるパッケージです。
「Near-zero dependencies」と謳っているように、標準ライブラリである reflect
と strings
にしか依存しておらず、そのため生成されるバイナリファイルのサイズが小さくなっています。
類似のパッケージとしては Vugu があります。
「Vecty vs. Vugu」で紹介されているツイートによると、「Vecty は React に近く、 Vugu は Vue.js に近い」とのことです。
個人的に React が好きなので今回は Vecty を採用してみました。
こんな感じで書けます。
package main
import (
"github.com/hexops/vecty"
"github.com/hexops/vecty/elem"
)
type View struct {
vecty.Core
}
func (c *View) Render() vecty.ComponentOrHTML {
// <body>
// <h1>Title</h1>
// <p>hello world</p>
// </body>
return elem.Body(
elem.Heading1(vecty.Text("Title")),
elem.Paragraph(vecty.Text("hello world")),
)
}
func main() {
v := &View{}
vecty.RenderBody(v)
}
これを WebAssembly にコンパイルしてブラウザ上で実行することでフロントエンドを構築することができます。
CDK for Terraform
使い慣れたプログラミング言語を使って Terraform エコシステムを利用したインフラの定義やプロビジョニングを行うことができます。
2022年08月12日現在、次の言語をサポートしています。
- TypeScript
- Python
- Java
- C#
- Go
CDK for Terraform は cdktf-cli を使って開発を行います。
# go テンプレートでプロジェクトを作成する
$ cdktf init --template=go
例えば AWS で S3 バケットを作成する場合はこんな感じに書きます。
package main
import (
"github.com/aws/constructs-go/constructs/v10"
"github.com/aws/jsii-runtime-go"
"github.com/hashicorp/cdktf-provider-aws-go/aws/v9"
"github.com/hashicorp/cdktf-provider-aws-go/aws/v9/s3"
"github.com/hashicorp/terraform-cdk-go/cdktf"
)
func NewMyStack(scope constructs.Construct, id string) cdktf.TerraformStack {
stack := cdktf.NewTerraformStack(scope, &id)
// provider
aws.NewAwsProvider(stack, jsii.String("AWS"), &aws.AwsProviderConfig{
Region: jsii.String("us-east-1"),
})
// s3 バケットを作成
b := s3.NewS3Bucket(stack, jsii.String("test-bucket"), &s3.S3BucketConfig{
Bucket: jsii.String("test-bucket"),
})
// パブリックアクセスブロックを設定
s3.NewS3BucketPublicAccessBlock(stack, jsii.String("test-bucket-public-access-block"), &s3.S3BucketPublicAccessBlockConfig{
Bucket: b.Bucket(),
BlockPublicAcls: jsii.Bool(true),
BlockPublicPolicy: jsii.Bool(true),
IgnorePublicAcls: jsii.Bool(true),
RestrictPublicBuckets: jsii.Bool(true),
})
return stack
}
func main() {
app := cdktf.NewApp(nil)
NewMyStack(app, "example")
app.Synth()
}
これで cdktf plan
で差分を確認 ( = terraform plan
) したり、 cdktf apply
でリソースを作成・更新・削除 ( = terraform apply
) したりできます。
また、ユニットテスト用のライブラリも公式から提供されており、これでインフラコードのテストを書くこともできるみたいです。
まとめ
結構面白かったです。
Discussion