🦐

【学習ログ】AIに書いてもらったBicepコードを模写する

に公開

はじめに

昨今、AIにコードを書かせて「とりあえずコピペで動かす」ことが増えました。
しかし、自分自身で理解せずに貼り付けているだけでは、本質的な学びが無いと危機感を覚えました。
そこで今回は「とりあえずやってみよう」精神で、AIに生成してもらったBicepコードを模写しながら、意味を理解する取り組みを行いました。本記事ではその学習ログを共有します。

やったこと

  • Microsoft LearnにあるBicepの基本コードを参考に、AIに「Storage AccountをデプロイするBicepコード」を書いてもらいました。
  • 生成されたコードを模写しながら、各ファイルの役割やパラメータの意味をひとつずつ確認しました。

Bicepとは

Bicepとは、Azure専用のIaC(Infrastructure as Code)言語です。
ARMテンプレートよりもシンプルで読みやすく、インデントや構文もスッキリしています。Azureリソースをコードで管理するための標準的な手段として利用が広がっています。

コードの生成方法

  • Microsoft Learnに掲載されているサンプルをAIに提示し、「Storage Accountをデプロイするコードを書いて」と依頼。
  • モジュールを使って複数ストレージを作成するBicepコードを生成してもらいました。

ディレクトリ構成

.
├─ main.bicep
├─ main.dev.bicepparam
└─ modules/
   └─ storageAccount.bicep

デプロイ

az deployment group create `
  -g MUIT `
  -f .\main.bicep `
  -p .\main.dev.bicepparam

模写したコード①(main.bicep)

targetScope = 'resourceGroup'

@description('デプロイ先リージョン(リソースグループと同じにする)')
param location string = resourceGroup().location

@description('全ストレージ共通で付与するタグ')
param tags object = {
  project: 'demo'
  owner: 'infra-team'
}

type AccountSpec = {
  name: string
  skuName: string
  accessTier: string
}

@description('作成したいストレージアカウントの一覧')
param accounts array = [
  {
    name: 'stsondemo0001'
    skuName: 'Standard_LRS'
    accessTier: 'Cool'
  }
  {
    name: 'stsondemo0002'
    skuName: 'Standard_ZRS'
    accessTier: 'Cool'
  }
]

module sa './modules/storageAccount.bicep' = [
  for account in accounts: {
    name: 'sa-${account.name}'
    params: {
      name: account.name
      skuName: account.skuName
      accessTier: account.accessTier
      location: location
      tags: tags
    }
  }
]

output storageIds array   = [for (account, i) in accounts: sa[i].outputs.id]
output storageNames array = [for (account, i) in accounts: sa[i].outputs.name]
output endpoints array    = [for (account, i) in accounts: sa[i].outputs.primaryEndpoints]

模写したコード②(storageAccount.bicep)

targetScope = 'resourceGroup'

@description('ストレージアカウント名(3〜24文字、小文字と数字のみ)')
param name string

@allowed([
  'Standard_LRS'
  'Standard_GRS'
  'Standard_RAGRS'
  'Standard_ZRS'
  'Premium_LRS'
  'Premium_ZRS'
])
@description('SKU(冗長性/性能)')
param skuName string = 'Standard_LRS'

@allowed(['StorageV2'])
@description('ストレージの種類(通常は StorageV2)')
param kind string = 'StorageV2'

@description('リージョン。既定はRGと同じ')
param location string = resourceGroup().location

@description('タグ(任意)')
param tags object = {}

@allowed(['Hot', 'Cool'])
@description('アクセス層(Blob)')
param accessTier string = 'Hot'

resource stg 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: name
  location: location
  sku: {
    name: skuName
  }
  kind: kind
  tags: tags
  properties: {
    accessTier: accessTier
    minimumTlsVersion: 'TLS1_2'
    allowBlobPublicAccess: false
  }
}

output id string = stg.id
output name string = stg.name
output primaryEndpoints object = stg.properties.primaryEndpoints

模写したコード③(main.dev.bicepparam)

using './main.bicep'

param location = 'japaneast'
param tags = { project: 'demo', env: 'dev' }
param accounts = [
  { name: 'stsondev0001', skuName: 'Standard_LRS', accessTier: 'Hot' }
  { name: 'stsondev0002', skuName: 'Standard_ZRS', accessTier: 'Cool' }
]

学び

  • @description : Bicepのデコレーターのひとつ。パラメータや変数、リソースに「説明文」を付与する。
  • @allowed : Bicepのデコレーターのひとつ。パラメータで指定できる値を制限する。
  • resource stg 'Microsoft.Storage/storageAccounts@2023-01-01' AMR APIのバージョン。今回は2023-01-01で実行。
  • param : デプロイ時に外部から渡す値。環境差分はここで表現する。
  • var と type : 共通定義や型制約を与えることで、チームでも安全に利用できる。
  • module : 別ファイルに切り出した処理を呼び出す。配列+for文で複数リソースを一気にデプロイできる。
  • for文 : Bicepでは「配列を生成するためのループ」として使われる。[for (x,i) in array: ...] の形式で書く。
  • output : デプロイ後にIDやエンドポイントを返せる。次の処理に渡すためのインターフェースとして便利。

今回の気づき

  • ディレクトリ構造がかなり大事
    → main.bicep と modules/ 配下を分けるだけで見通しが良くなる。構築の際には、基本設計(なんのリソースをどの値で使用するのか)を決定・把握しディレクトリ構造を考えなければならないことが分かった。

  • モジュール化をして見やすく
    → リソースごとに分割しておくと、レビューや修正がしやすい。

  • 同じ処理は使い回せるように書く
    → 何度も使うストレージやネットワーク設定は module 化して再利用するのが効率的。

感想

  • 結論、やってみてよかったと思う。というのもただ模写するだけでも、不明点がとんでもなく出てきたため、都度調べて知っていく過程が学びになった。
  • コードをコピペしてそのまま動かすのは簡単だが、「なぜそう書いてあるのか」を追いかけると理解が一気に深まった。
  • 模写しながらエラー(BCP144など)に遭遇すると、「Bicepの制約や正しい書き方」が自然に身につく。
  • AIに頼るのは効率的だが、自分で書いてみるプロセスを省くと知識が血肉にならないと痛感した。
ヘッドウォータース

Discussion