Lean Baseball

No Engineering, No Baseball.

Clineと一緒にAzureを学びながら, いい感じにterraformを書かせた話 - インフラタスクの自動運転と個人開発

Google Cloud歴7年ちょい*1, AWSもおそらく同じぐらい*2, Azureに入門してから3ヶ月半の人です.

今年からJoinした現職(LayerX AI・LLM事業部)では人生初のAzureに取り組む関係で, (入社前, トライアル選考を受けることが決まった昨年12月から)そっとAzureを触り始めました, そこから今日でようやっと3ヶ月半とかです.

流石にこの程度の経験(Azure3ヶ月)だと仕事にならないので,

  • 個人開発で作りたかったネタをAzureでやることを決断.
  • 題材はプロ野球ネタ(プロジェクト「uwasawa*3」), GWまでの稼働を目指す.
  • 単にAzureを覚えるだけでなく, クラウドのプロとして仕様を抑えてきれいに作る.
  • 全部自分でやると面倒くさいので生成AIに移譲しながら「インフラタスクの自動運転*4」を目指す.

という(趣味でもあり, お勉強でありかつ, マジで欲しいものを作る)営みを通して学ぶことにしました.

このエントリーでは昨年末から今日までやってきた知見. 特に,

「ClineにAzure教えてもらいながらいい感じにTerraform書けたよ」という「インフラタスクの自動運転(まだ途中ですが)」を記録として残したいと思います.

TL;DR

イチから作るサービスをClineにTerraform書かせる体験は素晴らしく良い(細かい間違いはあるが許せるレベル), インフラタスクの自動運転はイケるやろ.

個人開発で作っているもの

このブログのネタのベースとして, 今作っているもの(未完成)をblueprintを元に紹介します.

現在開発中の個人ネタ.

作っているものをざっくり紹介すると,

  • とある⚾️関連データのcrawler的なモノ(個人利用*5).
  • サイトの情報をスクレイピングしてJSONに保存(保管先はBlob Storage). このアプリはPython(FastAPI)で実装し, Container Appsでホスト.
  • 上記のアプリを定期実行するためのAzure FunctionsをPythonで実装. なおcronはFunctionsのTimer Triggerを利用.
  • 最終的にはFunctionsが定期的にクローラー(Container Apps)を起動してスクレイピング&データ保存を行う.
  • CI/CDはGitHub Actions. Docker ImageなどのArtifactはすべてAzure Container Registry(ACR)に集約.

コードベースも然程大きくない, 小さいシステムになります.

なおこのブログでのスコープは,

  • Container Appsのアプリ(クローラー). Functionsは未完成*6.
  • Blob Storageの設定. アプリとの連携部分(EntraIDでアップロードに必要な権限を渡す).
  • GitHub ActionsによるCI/CD. ACRに対するpushまで行っている.

このブログで扱う範囲.

以上に絞ったうえで書きます.

Clineにterraformを書かせる

年末年始に上モノのアプリ(どっちもPython)を書かせ, ローカルで動いて目処がたった段階でterraformのコードを書き始めました.

最初のプロジェクトとGemini

  • Clineを導入
  • 生成AIはGemini(Google)を使用.モデルは2.0系を色々と利用(うろ覚え).

ちなみに私はIntelliJ信者な私ですが, terraformとフロントエンドはVS Code使いなのでこの辺の移行はありません*7.

記念すべき一発目のプロンプトはこちらでした.

今から以下のterraformプロジェクトを作ってください。

・AzureのJapan East Regionにresource groupを作成。
・Applicationを配置するためのVNetを追加。
・Storageを配置。シングルリージョン、スタンダートクラスで定義。
・すべてのresourceのprefixは「uwa」で始める。

他に必要な情報があれば何なりと確認してください。

結果はこちらでした.

gist3f7bd985c89b2f515c0ec25e30bcf742

一発で動くコードが出てきました(&実際動いた).

  • AzureのJapan East Regionにresource groupを作成。 これは出来ている.
  • Applicationを配置するためのVNetを追加。 これもやってくれている.
  • Storageを配置。シングルリージョン、スタンダートクラスで定義。 結構ざっくりな指定だったと反省していますが雰囲気を読んだのか, 標準構成(Standard)なストレージかつ, 冗長性は持たせない最もお安いモードにしてくれた(LRS).
  • すべてのresourceのprefixは「uwa」で始める。 これは文句なしによく出来ている.
  • プロンプト以外の要素だと, 使うべきProvider(azurerm)も最初から正解を出してきた.

これが数分で出てきたのは感動すら覚えました. ジュニアなエンジニアやITコンサルだったら2日はかかるのでは?*8とも思えます.

リファクタリングさせた

ただ, すべてが完璧だったわけでは無かったです.

  • すべてのリソースをmain.tf に書いていた. 流石に分けてほしい.
  • 具体のリソース名はせめてvaliableにしてほしい.

というわけで,

ありがとう。リソースごとにファイル分割してくれますか?少なくともVNetとstorageは分けてほしいです。

自分で分けるのもきっついのでやってもらいました.

分けた後の結果はこちらです.

gistc4e66db84798e923dcc68a603eb5a4ee

main.tfがあるべき姿になりました!やった.

他はどうでしょう?

gist604c77555cc88d37e0434f5aee3da139

バッチリでした, よく出来ています👏

その後,

  • リソース名がおかしい(uwa-uwaとか)から修正してください.
  • name = "uwa-uwa-vnet"みたいにリソース名を直接書いている所をVariableとして切り出してくれ.
  • Blob StorageのContainer作ってくれ.

と矢継ぎ早にプロンプトを渡したらいい感じにしてくれました.

<<<<<<< SEARCH
resource "azurerm_storage_account" "uwa_storage_account" {
  name                     = var.storage_account_name
  resource_group_name      = azurerm_resource_group.uwa_resource_group.name
  location                 = azurerm_resource_group.uwa_resource_group.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}
=======
resource "azurerm_storage_account" "uwa_storage_account" {
  name                     = var.storage_account_name
  resource_group_name      = azurerm_resource_group.uwa_resource_group.name
  location                 = azurerm_resource_group.uwa_resource_group.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
  account_replication_type = "LRS"
}

resource "azurerm_storage_container" "uwa_storage_container" {
  name                  = var.container_name
  storage_account_name  = azurerm_storage_account.uwa_storage_account.name
  container_access_type = "private"
}
>>>>>>> REPLACE

Blob Containerはちょっと間違っていましたが許容範囲内でした.

小難しいタスクでハマる -> Chat GPTにも聞いてみた

Clineでのterraformは順調にいったのですが, ここが意外とハマりました.

CIDR /24で新たにsubnetを作ったうえで、その中にContainer Appを構築するterraformを作ってください。

var.acr_name_crawlerのRegistryからimageを取ってください、tagはlatest固定でOKです。

上記のプロンプトで得られた最初のContainer Appsはこちらです.

gist802319f9e1e3ab87d1eacf17891c7ca6

ひと目で「動かないやろこのコード」ってわかってしまいました.

  • そもそも, azurerm_subnet.container_app_subnetというsubnetを作ってくれなかった(小声). この時点で CIDR /24で新たにsubnetを作ったうえで の条件は未達.
  • registryの指定が無かった. 前提条件として, ACRの設定を書いていた(plan & apply終わっててコードとしては書けている)にもかかわらず, ガン無視してきた.

このまま続けてプロンプトを書き続けるのも野暮だと思い, 結局自分で試行錯誤して実装して終わりました.

ある程度書き直しをして動くものを作った後, Chat GPT(モデルはo3-mini-high)に,

secret環境変数を設定するときのサンプルをください.

と聞いてみました(こちらはClineを使わずチャットで確認).

なお, ClineとGeminiに見切りをつけた訳ではなく, 何かを期待して興味本位でやってみました.

結果出てきたコードはこちらです.

gistcfb0a1631f4e7ee72a0515ee49850f89

雰囲気はいい感じですが, 設定が微妙に違っていました.

  • configuration という設定はない.
  • しかし, env での設定は正しい.

どちらも, terraform plan を実行するとわかる(エラーになる)のですが, 「コードの雰囲気は合ってるけど違う」というのは中々面白いと思いました.

なお, この後は自分で調べてデバッグして無事いい感じのコードになりました.

初めてのAzureをClineと一緒に学びながらやった結果, 自分がAzureの細かい部分を学びながらコードもたくさん書いてくれて最高の体験でした.

何を覚えたら「インフラタスクの自動運転」ができるのか?

これで最初に作ってもらおうと思っていた「terraformプロジェクトのテンプレ」と「アプリの配置(CI/CDの設定含む)」までいい感じにやってもらいました.

「すでに『インフラタスクの自動運転』の入口に来てるやん!?」というアハ体験も得ました.

「これ全部自分(+GitHub Copilot)頼りだと丸3日の仕事(なぜならAzure素人だから)」と見積もっていましたが, 実態としては「毎週末の土日に最長2時間ぐらい作業」の3セットぐらいで終わりました. 個人開発としてはかなりのブレークスルーです(大きく時間を溶かさずに済むため*9).

学びとして, 「素人もしくはジュニアレベルのエンジニアが『インフラタスクの自動運転』をするまではひと工夫必要」だと感じました.

今回みたいに「初めて触るクラウド(Azure)のインフラタスク自動運転」が出来た理由ですが,

  • 自分のGoogle Cloud, AWSなど他クラウドの経験が豊富だった. 「Googleだったらこうする」みたいな言語化(≒プロンプト)が秒で出てくるレベルなのでプロンプトの品質と試行回数を増やす下地が十分あった.
  • すべてのクラウドに通用するような「勝ちパターン」を元に事前学習していた(私が). どんなクラウドでも「権限管理(IAMとかEntraIDとかService Accountとか)」「L4, L7レベルの基礎的なNW知識」があれば切り抜けられるという経験則(いやこれは鉄板パターンかも)があり, その鉄則に従ってblueprint*10からいい感じに設計したうえで挑んだ.
  • (初学者とはいえ)ちゃんとAzureを触って本を読んでからやった. 何も作ったこと無い, 触ったこと無い状態だったら, いくらGoogle Cloud, AWS経験が長くてもここまでうまくいかなかった*11.

「クラウドに対するドメイン知識と考え方」「手触り感ある学び(座学じゃなくて実践*12)をもとにやる」という基本を自分が守っていたからこそ出来たと思っています.

Azure関係は上記の本を読んで学びました.

また「クラウドに対するドメイン知識と考え方」ですが,

この辺りの書籍を読むと同時に「クラウドネイティブとは?」を抑えていたのが大きかったです.

tech.layerx.co.jp

気になる方は(手前味噌でアレですが)この辺のブログを読むとよいかと思います.

結び - 個人開発でIaCは絶対アリ

「Clineと一緒にAzureを学びながら, いい感じにterraformを書かせた話 」という事で,

  • 何か得意なクラウドの知識があれば生成AIでTerraformはイケる(初めて使うやつでも).
  • いい感じのプロンプト, タスクをこなすのに基礎知識は必要.
  • いきなり自動運転じゃなくてちゃんと触って学んでからやれ.

という話を書きました.

最後に生成AIとは全く別(とも言えないかもですが)文脈の話を一つ.

shinyorke.hatenablog.com

ちょうど1年前に, 「個人開発でterraformまでやります?」という話題になり, ↑のブログを書きました.

自分が携わっているシステム・プロダクトが複雑かつデプロイ回数増えそうだったらIaC入れておけ, 個人開発(趣味)だったとしても.

と, 去年の自分は結論付けた&この考えは今も変わりませんが.

もう一つ付け加えることができました.

仕事も個人開発も, Terraform書いてインフラをいい感じにする仕事を全部人間がやるのはイケてない, 生成AIに課金してやらせよう!

このレイヤー(インフラエンジニアやSREな意味のレイヤー)で想像力を使うのは全体のアーキ設計やネットワーク層の検討ぐらいかな?それかて生成AIに聞きながらいい感じにできる未来があるので積極的に使っていこうと思いました.

以上でこのブログの話は終わりますが,続きの話を3/25のイベントでやれたらなーって思っています.

layerx.connpass.com

会社のイベントではありますが, 私がオーガナイズしてるので今回のブログに興味持った方はぜひ遊びに来てくれると嬉しいです.

最後までお読みいただきありがとうございました!

*1:具体的には前職アクセンチュアとその前のJX通信社で合わせて5年少し, ビザスクで1年, その他合わせて6年相当. 一応Partner Top Engineerも貰ってるので慣れている方だと思います.

*2:実は2009年, Tokyo Regionができる前から仕事で細々とやっていた.

*3:由来は察してください. なお私は許せます(何が).

*4:自動運転のニュアンスはこの記事と全く同じです, 対象が違うだけで.

*5:今回とは全く別の話でなにかのネタになります, 乞うご期待⚾️

*6:具体的にはアプリのコードは仕上がっているがまだFunctionsにホストしていない.

*7:正味な話, 仕事がVS CodeなのとClineが手放せない感じになってきたのでIntelliJ(PyCharm, Goland)とのお付き合いが終わるのでは説あります...

*8:むしろ2日かかっても出てこない可能性すらあります.

*9:勿論本業にも生きてくる事は言うまでもありません

*10:加えて, 作るもののblueprintを書くのはめっちゃ大事だと思っています. 今回とは関係ない話ですが中途採用や新卒採用の面接で出てくる課題対策にもなります.

*11:どのクラウドもベンダー資格がたくさんあって, All Certificateとかタイトルもあるけど触った人間には勝てない(座学で資格だけの人は戦力になりにくい)という持論があります.

*12:大切なので二度言いますが座学より実践, 手触り感です.