パラメーターと変数を使用して柔軟性を高める
テンプレートは、再利用性があり強力です。 Bicep を使用して、複数の環境またはリソースのコピーをデプロイするテンプレートを作成できます。
あなたの玩具会社は新しい製品を定期的に発売しており、あなたは Bicep テンプレートを使って、各製品の発売に必要な Azure リソースを作成する必要があります。 固定リソース名を使用しないようにする必要があります。 多くの種類の Azure リソースには一意の名前が必要であるため、テンプレートに名前を埋め込むことで、複数の製品の立ち上げにテンプレートを再利用することはできません。 また、玩具を立ち上げる場所に応じて異なる場所にリソースをデプロイする必要があります。これは、テンプレートにリソースの場所を埋め込めないということです。
このユニットでは、 パラメーター と 変数について学習します。これは、テンプレートを柔軟に再利用できるようにする 2 つの Bicep 機能です。 また、 式についても紹介します。
注意
このユニットのコマンドは、概念を説明するために示されています。 コマンドはまだ実行しないでください。 ここで学習した内容をすぐに練習します。
パラメーターと変数
パラメーターを使用すると、テンプレート ファイルの外部から値を取り込むことができます。 たとえば、Azure CLI または Azure PowerShell を使って手動でテンプレートをデプロイしている場合は、各パラメーターの値を指定するように求められます。 また、"パラメーター ファイル" を作って、デプロイに使用するすべてのパラメーターと値の一覧を示すこともできます。 テンプレートがデプロイ パイプラインのような自動プロセスからデプロイされている場合、パイプラインはパラメーター値を提供できます。
変数が定義され、テンプレート内で設定されます。 変数を使用すると、重要な情報を 1 か所に格納し、コピーして貼り付けなくてもテンプレート全体で参照できます。
通常は、次のように各デプロイ間で変更されるパラメーターを使用することをお勧めします。
- 一意である必要があるリソース名。
- リソースのデプロイ先の場所。
- SKU、価格レベル、インスタンス数など、リソースの価格に影響する設定。
- テンプレートで定義されていない他のシステムにアクセスするために必要な資格情報と情報。
通常、変数は、デプロイごとに同じ値を使うけれども、テンプレート内で値を再利用できるようにしたい場合、または式を使って複雑な値を作成したい場合に適しています。 一意な名前が必要ないリソースには、変数を使うこともできます。
ヒント
テンプレートを読みやすく理解しやすいように、パラメーターと変数には適切な名前を付けることが重要です。 明確でわかりやすい名前を使用していることを確認します。
パラメーターを追加する
Bicep では、次のようにパラメーターを定義できます。
param appServiceAppName string
この定義の各部分がどのように機能するかを見てみましょう。
param
は、パラメーターを定義していることを Bicep に通知します。appServiceAppName
は、パラメーターの名前です。 テンプレートを手動でデプロイする場合は、値の入力を求められることがあるため、名前を明確でわかりやすいものにすることが重要です。 名前は、リソース シンボル名と同じように、テンプレート内のパラメーター値を参照する方法でもあります。string
は、パラメーターの型です。 Bicep のパラメーターには、テキストの場合のstring
、数値の場合のint
、ブール値 true または false の場合のbool
など、いくつかの異なる型を指定できます。array
およびobject
の型を使用して、より複雑なパラメーターを渡すこともできます。
ヒント
多数のパラメーターを使用して、テンプレートを過剰に一般化しないようにしてください。 ビジネス シナリオに必要なパラメーターの最小数を使用する必要があります。 要件が変更された場合は、将来、いつでもテンプレートを変更できることに注意してください。
既定値を指定する
必要に応じて、パラメーターの 既定値 を指定できます。 既定値を指定すると、パラメーターは省略可能になります。 テンプレートをデプロイするユーザーは、必要に応じて値を指定できますが、指定しないと、Bicep は既定値を使います。
既定値を追加する方法を次に示します。
param appServiceAppName string = 'toy-product-launch-1'
Note
この例では、Azure App Service アプリ名にハードコーディングされた既定値があります。 App Service アプリには一意の名前が必要であるため、この方法はお勧めできません。 これはすぐに修正します。
テンプレートにパラメーター値を使用する
パラメーターを宣言したら、テンプレートの他の部分を通じて参照できます。 リソース定義内で新しいパラメーターを使用する方法を見てみましょう。
resource appServiceApp 'Microsoft.Web/sites@2024-04-01' = {
name: appServiceAppName
location: 'eastus'
properties: {
serverFarmId: appServicePlan.id
httpsOnly: true
}
}
テンプレートは、ハードコーディングされた値ではなく、パラメーターの値を使ってアプリ リソースのリソース名を設定するようになることに注意してください。
ヒント
Visual Studio Code 用の Bicep 拡張機能には、推奨プラクティスに従っていないときに通知する視覚的なインジケーターが表示されます。 たとえば、使わないパラメーターを定義している場合に警告が表示されます。 "Bicep リンター" では、作業中にこのようなチェックが継続的に実行されます。
変数を追加する
変数は次のように定義できます。
var appServicePlanName = 'toy-product-launch-plan'
変数は、パラメーターと同様の方法で定義されますが、いくつかの違いがあります。
- 変数を宣言していることを Bicep に通知するには、
var
キーワードを使用します。 - 変数の値を指定する必要があります。
- 変数には型は必要ありません。 Bicep は、ユーザーが設定した値に基づいて型を決定できます。
式
テンプレートを作成するときは、多くの場合、値をハードコーディングしたり、パラメーターで指定するように要求したりする必要はありません。 代わりに、テンプレートの実行時に値を検出する必要があります。 たとえば、テンプレート内のすべてのリソースを 1 つの Azure リージョン (リソース グループを作成したリージョン) にデプロイする場合があります。 または、会社が使用する特定の名前付け方法に基づいて、リソースの一意の名前を自動的に作成することもできます。
Bicep の式は、あらゆる種類の興味深いシナリオを処理するのに役立つ強力な機能です。 Bicep テンプレートで式を使用できる場所をいくつか見てみましょう。
リソースの場所
テンプレートを作成してデプロイする場合、多くの場合、各リソースの場所を個別に指定する必要はありません。 代わりに、"既定では、リソース グループが作成されたのと同じ場所にすべてのリソースをデプロイする" という単純なビジネス ルールを使用できます。
Bicep では、location
という名前のパラメーターを作成してから、式を使用してその値を設定できます。
param location string = resourceGroup().location
そのパラメーターの既定値を確認します。 ここでは、resourceGroup()
という名前の "関数" が使われています。これにより、テンプレートがデプロイされているリソース グループに関する情報にアクセスできます。 この例では、テンプレートで location
プロパティを使用しています。 このアプローチを使用して、リソース グループと同じ Azure リージョンにリソースをデプロイするのが一般的です。
このテンプレートをデプロイしている場合は、ここで既定値をオーバーライドし、別の場所を使用することもできます。
Note
Azure の一部のリソースは、特定の場所にのみデプロイできます。 これらのリソースの場所を設定するには、別のパラメーターが必要になる場合があります。
次のように、テンプレート内のリソースの場所パラメーターを使用できるようになりました。
resource appServiceApp 'Microsoft.Web/sites@2024-04-01' = {
name: appServiceAppName
location: location
properties: {
serverFarmId: appServicePlan.id
httpsOnly: true
}
}
リソース名
多くの Azure リソースには、一意の名前が必要です。 このシナリオでは、ストレージ アカウントと App Service アプリの一意な名前を必要とする 2 つのリソースがあります。 これらの値をパラメーターとして設定するように要求すると、他のユーザーが使用していない名前を検索する必要があるため、テンプレートの使用が難しくなります。
Bicep には、リソース名を作成するときに便利な uniqueString()
という別の関数が用意されています。 この関数を使用する際は、"シード値" を指定する必要があります。これは、それぞれのデプロイで異なると同時に、同じリソースに関してはすべてのデプロイで一貫している必要があります。
適切なシード値を選んだ場合、同じリソースのセットをデプロイするたびに同じ名前を取得できますが、同じテンプレートを使って異なるリソースのセットをデプロイしたときは常に、異なる名前を取得します。 uniqueString()
関数を使用する方法を見てみましょう。
param storageAccountName string = uniqueString(resourceGroup().id)
このパラメーターの既定値は、リソースの場所を設定するときと同様に、resourceGroup()
関数を再度使用します。 しかし、今回はリソース グループの ID を取得しています。 リソース グループ ID は次のようになります。
/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/MyResourceGroup
リソース グループ ID には、Azure サブスクリプション ID (aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e
) とリソースグループ名 (MyResourceGroup
) が含まれています。 リソース グループ ID は、多くの場合、リソース名のシード値の候補として適しています。理由は次のとおりです。
- 同じリソースをデプロイするたびに、同じリソース グループに入ります。
uniqueString()
関数により、毎回同じ値が返されます。 - Azure サブスクリプションの 2 つの異なるリソース グループにデプロイした場合、リソース グループ名が異なるため、
resourceGroup().id
値は異なります。uniqueString()
関数により、リソースの各セットに対して異なる値が提供されます。 - 2 つの異なる Azure サブスクリプションにデプロイする場合、同じリソース グループ名を使用していても、 Azure サブスクリプション ID が異なるため、
resourceGroup().id
値は異なります。uniqueString()
関数により、リソースの各セットに対して、再び、異なる値が提供されます。
ヒント
多くの場合、テンプレート式を使用してリソース名を作成することをお勧めします。 多くの種類の Azure リソースで、使用できる文字と名前の長さのルールが決まっています。 テンプレートにリソース名の作成を埋め込むと、そのテンプレートを使用するすべてのユーザーが、これらの規則自体に従うことを覚えている必要はありません。
結合された文字列
uniqueString()
関数を使用してリソース名を設定するだけの場合は、一意の名前を取得できますが、意味がありません。 リソースの目的が明確になるように、適切なリソース名はわかりやすいものにする必要もあります。 場合によっては、意味のある単語または文字列を一意の値と組み合わせることによって、名前を作成する必要があります。 これにより、意味のある 名前と一意の名前 の両方を持つリソースを使用できます。
Bicep には、文字列を組み合わせることができる 文字列補間 と呼ばれる機能があります。 そのしくみを見てみましょう。
param storageAccountName string = 'toylaunch${uniqueString(resourceGroup().id)}'
storageAccountName
パラメーターの既定値には、次の 2 つの部分が含まれるようになりました。
toylaunch
はハードコーディングされた文字列であり、Azure でデプロイされたリソースを見たユーザーが、そのストレージ アカウントの目的を理解するのに役立ちます。${uniqueString(resourceGroup().id)}
は、uniqueString(resourceGroup().id)
関数の出力を評価してから文字列に連結するように Bicep に指示する手段です。
ヒント
場合によっては、uniqueString()
関数が数値で始まる文字列を作成することがあります。 一部の Azure リソース (ストレージ アカウントなど) では、数字で始まる名前を使用することはできません。 つまり、前の例のように、文字列補間を使用してリソース名を作成することをお勧めします。
リソースの SKU の選択
チームの他のメンバーは、あなたがこれまでに構築した Bicep コードに驚かされています。 あなたたちは、テンプレートを使ってリソースをデプロイし、すべての新しい玩具の発売をサポートすることにしました。
同僚の 1 人が、製品の発売ごとに非運用環境を作成し、サイトを顧客が使用する前にマーケティング チームでテストできるようにすることを、あなたに提案しました。 ただし、非運用環境にあまり多くのコストがかからないようにしたいため、いくつかのポリシーも合わせて決定します。
- 運用環境では、高い回復性を確保するためにストレージ アカウントが
Standard_GRS
(geo 冗長ストレージ) SKU でデプロイされます。 App Service プランは、ハイ パフォーマンスのためにP2v3
SKU でデプロイされます。 - 非運用環境では、ストレージ アカウントが
Standard_LRS
(ローカルに冗長なストレージ) SKU でデプロイされます。 App Service プランは、無料のF1
SKU でデプロイされます。
これらのビジネス要件を実装する方法の 1 つは、パラメーターを使用して各 SKU を指定することです。 ただし、すべての SKU をパラメーターとして指定すると、テンプレートが大きい場合は特に、管理が困難になる可能性があります。 別の方法として、パラメーター、変数、および式の組み合わせを使用して、ビジネス ルールをテンプレートに埋め込むこともできます。
まず、展開が運用環境と非運用環境のどちらであるかを示すパラメーターを指定できます。
@allowed([
'nonprod'
'prod'
])
param environmentType string
このコードでは、environmentType
パラメーターに 使用できる値の一覧を指定するために、いくつかの新しい構文が使用されていることに注意してください。 Bicep では、これらの値のいずれかを指定しない限り、だれでもテンプレートをデプロイすることはできません。
次に、環境に基づいて ストレージ アカウントと App Service プランに使用する SKU を決定する変数を作成できます。
var storageAccountSkuName = (environmentType == 'prod') ? 'Standard_GRS' : 'Standard_LRS'
var appServicePlanSkuName = (environmentType == 'prod') ? 'P2V3' : 'F1'
ここでも新しい構文に注意してください。 いくつかに分けてみましょう。
(environmentType == 'prod')
は、environmentType
パラメーターに使われている許容値に応じて、ブール値 (true または false) に評価されます。?
は "三項演算子" と呼ばれ、if/then
ステートメントを評価します。 式が true の場合は、?
演算子の後の値が使われます。 式が false に評価された場合、コロン (:
) の後の値が使用されます。
これらのルールは、次のように変換できます。
storageAccountSkuName
変数の場合、environmentType
パラメーターがprod
に設定されている場合はStandard_GRS
SKU を使用します。 それ以外の場合はStandard_LRS
SKU を使用します。appServicePlanSkuName
変数の場合、environmentType
パラメーターがprod
に設定されている場合はP2V3
SKU とPremiumV3
層を使用します。 それ以外の場合はF1
SKU を使用します。
ヒント
このようなマルチパート式を作成する場合は、リソース プロパティに式を直接埋め込むのではなく、変数を使用する方が適切です。 これにより、ロジックでのリソース定義の煩雑さを避けることができるため、テンプレートの読み取りと理解が容易になります。
テンプレートでパラメーター、変数、式を使うと、テンプレートを再利用して、新しいリソースのセットをすばやくデプロイできます。 たとえば、マーケティング部門から次の玩具の発売のために新しい Web サイトをデプロイするよう依頼されるたびに、デプロイする環境ごとに新しいパラメーター値を指定すれば、それで終わりです。