Bicepの特徴:冪等性について

Azure

Bicepに限らずですが、IaCで使われる構成管理ツールには「冪等性」という性質があります。

前提知識

<参考>

IaCとは

Infrastructure as Codeの頭文字でインフラをコードで管理することです。

コードと聞くといかにも技術のような印象がありますが、

  • どういうシステムの完成系を目指しているか
  • 完成系に至るまで、どのように作業していくか
  • 完成系を継続的にどのように運用していくか

ということに対するGUI・CLIのような操作論・方法論の一つです。

コードでシステムの最終系を記述するので「最新の状態を維持できる」「同じ(検証)環境などを繰り返し構築できる」などのメリットがあります。

Bicepとは

宣言型の構文を利用してAzureリソースをデプロイするためのドメイン固有言語(DSL)です。

この値はこれ、このSKUはこれを使う などを宣言的に記述することでシステムの最終系を定義します。

冪等性とは

ある操作を何度繰り返しても結果が同じになるという性質

冪等性とは?意味を分かりやすく解説 - IT用語辞典 e-Words
冪等性とは、ある操作を何度繰り返しても結果が同じになるという性質。元は数学の概念だがIT分野でもほぼ同じ意味で用いられる。同じ演算や処理、操作などを1回行っても、何度繰り返し行っても常に同じ結果になる性質を指す。例えば、「与えられた実数の絶...

もっと簡単に言うと同じBicepファイルを実行するとき、

  • 既にリソースが作成されている場合は「スキップ」
  • 差分があれば「作成・変更」

を行う性質のことを指します。

Bicepだけでなく、AnsibleやTerraformというIaCツールはこの冪等性という性質を備えて、

常に最新の状態のみ反映できるようになっています。

冪等性について確認してみる

頭で理解しても、実際にどういう操作をしたときにどうなるものかがわかりにくいと思い、記事にしています。

VMを作っているBicepファイルがあるので、このNSGを変更する過程で確認してみます。

VMデプロイ用Bicepコード

VMをデプロイするBicepコードは以下のリポジトリを使います。

GitHub - naohello117/wc-vm-deploy-bicep at idempotence
Contribute to naohello117/wc-vm-deploy-bicep development by creating an account on GitHub.

まずはデプロイします。

az login //ログイン
az group create --name rg-bicep-vm --location japaneast  //リソースグループの作成
// main.bicepファイルをデプロイ
az deployment group create `
  --resource-group rg-bicep-vm `
  --template-file main.bicep `
  --parameters location=japaneast `
               vnetName=vnet-bicep `
               nsgName=nsg-bicep `
               pipName=pip-vm-bicep `
               nicName=nic-vm-bicep `
               vmName=vm-bicep `
               dataDiskName=disk-bicep `
               adminUsername=<ユーザー名> `
               adminPassword=<パスワード>

デプロイされました。

NSGのルールを確認すると、規定値以外ではパブリック受信ポート(SSH)のみ許可されていることがわかります。

NSGルールを変更する

この受信ルールに以下の2点の修正と追加という処理を加えてみましょう。

  • SSH許可ルールの送信元IPアドレスを自宅のIPに変更する
  • インターネットから8080通信を許可するルールを追加する
resource nsg 'Microsoft.Network/networkSecurityGroups@2023-11-01' = {
  name: nsgName
  location: location
  properties: {
    securityRules: [
      {
        name: 'AllowSSH'
        properties: {
          priority: 110
          protocol: 'Tcp'
          access: 'Allow'
          direction: 'Inbound'
          sourceAddressPrefix: '133.32.181.21'
          sourcePortRange: '*'
          destinationAddressPrefix: 'VirtualNetwork'
          destinationPortRange: '22'
        }
      }
      {
        name: 'AllowTCP8080'
        properties: {
          priority: 120
          protocol: 'Tcp'
          access: 'Allow'
          direction: 'Inbound'
          sourceAddressPrefix: 'Internet'
          sourcePortRange: '*'
          destinationAddressPrefix: 'VirtualNetwork'
          destinationPortRange: '8080'
        }
      }
      {
        name: 'AllowInternetOutbound'
        properties: {
          priority: 110
          protocol: '*'
          access: 'Allow'
          direction: 'Outbound'
          sourceAddressPrefix: '*'
          sourcePortRange: '*'
          destinationAddressPrefix: 'Internet'
          destinationPortRange: '*'
        }
      }
    ]
  }
}

NSGに関する記述内容が変更されました。

Bicepでは最終系を示すので、「これを削除して」「これを追加して」ということを命令的に示さずとも、最終系の形に合わせて現状を変更するように動作します。

この変更したコードをそのままもう一度デプロイします。

az deployment group create `
  --resource-group rg-bicep-vm `
  --template-file main.bicep `
  --parameters location=japaneast `
               vnetName=vnet-bicep `
               nsgName=nsg-bicep `
               pipName=pip-vm-bicep `
               nicName=nic-vm-bicep `
               vmName=vm-bicep `
               dataDiskName=disk-bicep `
               adminUsername=<ユーザー名> `
               adminPassword=<パスワード>

通常これがコマンドなどの引数を使い命令系で構成を定義している場合は、2回目のデプロイに対して「重複している」というエラーや同じリソースが作られたりすることが考えられます。

しかしながら、templateでBicepファイルを呼び出している場合は、冪等性により差分だけが反映されます。

ポータルで実行結果を確認すると全て成功となっています。

NSGを確認してみると受信セキュリティルールが更新&追加されていることがわかります。

最後に

このようにIaCには冪等性という性質があり、構成の一貫性を担う上で重要な特徴です。

スクリプトやポータル操作にはない動きではあるものの、多くのコマンドを打つ必要もなく「パラメータの変更」「確認」「決まった操作でデプロイ」を行うだけで変更が済むので、非常に完結であり運用負担が軽減されます。

一方で完全に万能というわけでもなさそうで、私も1度ハマりました。

この例は、VNETの中にSubnetを定義しないとうまくいかないということを記事にしています。

冪等性は命令的に支持しなくても作成・削除・変更などを裏側で行ってくれる一方で、裏側の出来事なので表側から明示的に制御しにくい性質があります。

ある程度決まったパターンの記述をしないとBicep定義ファイルとIaCの動きが喧嘩をしてエラーになることがあるので、そのあたりのパターンも探っていくことが大切です。

コメント