こちらはFIXER Rookies Advent Calendar 2022の5日目の記事です。
みんな大好きAzureくん。
そんなAzureのリソースをTerraformでコード化する業務を普段行っているのですが、最近null_resource
で書かれたコードをazapi_resource
に書き換える機会が多かったためメモ代わりに共有していきたいと思います。
そもそもnull_resourceとは?
null_resource
を用いることにより、Providerが存在しない処理をTerraformで実行することができます。
resource "null_resource" "this" {
triggers = {
rg_name = local.resource_group_name
}
provisioner "local-exec" {
command = <<EOT
az group show --name ${self.triggers.rg_name}
EOT
interpreter = ["pwsh", "-Command"]
}
}
{
"mode": "managed",
"type": "null_resource",
"name": "this",
"provider": "provider[\"registry.terraform.io/hashicorp/null\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"id": "376976211",
"triggers": {
"rg_name": "<リソースグループ名>"
}
},
"sensitive_attributes": []
}
]
}
しかしnull_resource
は名前の通りリソースが存在しないプロバイダーのため、tfstate
を確認するとinstances
の中に処理の結果が記録されず、null_resource
と他のProvider間の依存関係をTerraformはサポートしません。
メリット
- Terraform上でリソースの作成 & +α が実現できる
- Terraformでサポートされていない処理を実装できる
デメリット
- コード間の依存関係を持つことが難しい
- 内部の処理を
tfstate
上で確認することができず、デバッグ等が難しい
azapi_resourceで安心安全の処理を実現
そこでazapi_resourceをできる限り使いましょう。 これはAzure REST APIをTerraformで実行&管理するProviderです。 先ほどnull_resource
で挙げた例をazapi_resource
で再現した場合、
# az group show --name <リソースグループ名>
data "azapi_resource" "this" {
type = "Microsoft.Resources/resourceGroups@2021-04-01"
name = local.resource_group_name
parent_id = "/subscriptions/${var.subscription_id}"
response_export_values = ["properties.loginServer", "properties.policies.quarantinePolicy.status"]
}
{
"mode": "data",
"type": "azapi_resource",
"name": "this",
"provider": "provider[\"registry.terraform.io/azure/azapi\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"id": "/subscriptions/<サブスクリプションID>/resourceGroups/<リソースグループ名>",
"identity": [],
"location": "westus3",
"name": "<リソースグループ名>",
"output": "{}",
"parent_id": "/subscriptions/<サブスクリプションID>",
"resource_id": null,
"response_export_values": [
"properties.loginServer",
"properties.policies.quarantinePolicy.status"
],
"tags": {},
"timeouts": null,
"type": "Microsoft.Resources/resourceGroups@2021-04-01"
},
"sensitive_attributes": []
}
]
}
tfstate
上に処理の結果が記録されるため、azapi_resource
で実行したデータを他のProviderに反映することができ、依存関係をTerraformが保証するため、Azure RedHat OpenShiftやAzure Container Appsなど作成に時間がかかるリソースはazapi_resource
を活用した方が安全安心です。
メリット
- Azure Portalで実現可能な作業 ≒ Terraformで再現可能
- tfstate上に実行ログが残るため、デバッグ時に重宝する
- 他のProviderと明確な依存関係を持つことができる
デメリット
- ignore_changesでフィールド名を個別に宣言することができず、
body
しか宣言できない。
まとめ
azapi_resource
を使うことにより、依存関係がはっきりしたコードを書くことができるため、できる限りnull_resource
で「えいや~~~」っとコードを書かないようにしましょう。 また筆者は最近Terraformの限界を感じ始めたので、「Azure SDK for GoでIaCを実現した方がリソースの作成+αが簡単にできて便利なのでは???」と模索しています。