Azure Advent Calendar 2021 9日目です。
はじめに
Infrastrucure as Code を始めると、GitHub 上で Pull Request ベースであれば、関連する Issue やなぜこの Pull Request が作られたのか。また誰が作り、誰がマージしたのか?またマージできる人が誰なのかといった事業の根幹となるインフラ部分について、議論の歴史を残しながら技術的意思決定と同時に構築することができます。Infrastructure as Code は、単にインフラの自動化やデプロイのためではなく、根幹となるインフラリソースをチームで議論を残せるかつ監査観点で統制をとる方法として有効な仕組みです。
さて、既存の Azure リソースから Infrastrucure as Code をはじめる場合に Terraform の活用が選択肢の一つしてあると思います。ただ、すでに Azure で運用している場合や他のチームとの連携など含めると、始めるに当たり壁があると感じられることが多いかなと思います。 そこで既存の Azure リソースを Terraform の管理下に置くためのツールとして、Azure Terrafy がありますので、このツールについて社内の Hackthon で知り、 Contribute していたのでここの場で紹介します。
Azure Terrafy とは
Azure Terrafy は、 Resource Group 単位でかつ、ほしいリソースを利用者が選んで tf
ファイルや tfstate
ファイルを生成してくれます。既存の Azure リソースを Terraform を始める上で、様々な壁があります。 Azure Terrafy は、次のような困った場合に活躍できそうです。
- 他チームやプロダクトに影響を与えたくない
- 他のリソースがある中で Try & Error がしにくい
- 限定された範囲で portal 上でポチポチして試したものを export して、書き方がわかった状態から管理しているリポジトリにコミットしたい
これは、 Azure Terrafy 自身の Goal が terraform plan
した際に no diff になることを目指して作られており、tf ファイルを利用できるようにするために ARM temaple の依存関係の考慮を含めて生成してくれるからです。
How to install
Releases からダウンロードして利用します。( Homebrew などに対応したい。。
その他、利用する前に Terraform の install と Azure CLI が必要です。
Usage
$ aztfy
aztfy [option] <resource group name>
-o string
Specify output dir. Default is a dir under the user cache dir, which is named after the resource group name
-v Print version
リソースグループを指定して実行すると、 README の demo にあるようにユーザー自身でOS の user cache に tf
と tfstate
また backup を生成してくれます。
デモ
以前、ブログ で書いた AKS を構築する script がある distributed-load-testing-using-locust-on-aks を使って試したいと思います
$ git clone https://github.com/koudaiii/distributed-load-testing-using-locust-on-aks
$ cd distributed-load-testing-using-locust-on-aks
$ script/bootstrap
デフォルトだと DistributedLoadTesting
という名前の Resource Group が作られるようになっています。こちらを実際に aztfy で Terraform 化を行ってみましょう。
$ mkdir sample
$ aztfy -o sample DistributedLoadTesting
初期化が終わると作られたリソースが表示されます。
Azure Terrafy
DistributedLoadTesting Possible resource type(s): azurerm_kubernetes_cluster_node_pool
3 items
/subscriptions/xxxx-xxxx/resourceGroups/DistributedLoadTesting/providers/Microsoft.ContainerService/managedClusters/LocustOnAKS
(Skip)
│ /subscriptions/xxx-xxx/resourceGroups/DistributedLoadTesting/providers/Microsoft.ContainerService/managedClusters/LocustOnAKS/agentPools/nodepool1
│ (Skip)
/subscriptions/xxx-xxx/resourceGroups/DistributedLoadTesting
(Skip)
画面下にキー操作の案内があります。
↑/k up • ↓/j down • / filter • w save • e show error • r show recommendation • q quit • ? more
キー操作をもとに自身がほしいリソースを移動して、Enter 押すことで書き込めます。各 Azure リソースの Terraform リソースタイプ と 任意の名前 を、<リソースタイプ>.<名前>
(例:azurerm_linux_virtual_machine.example
)の形で書く必要があります。この場合、 Terraform のリソースタイプについては、 Terraform の公式ページから取ってくる必要があります。または、 r
を押すと、候補がでてきます。
DistributedLoadTesting Possible resource type(s): azurerm_kubernetes_cluster_node_pool # <--- 各 Azure リソースの Terraform リソースタイプ
※ユーザーは r
を押すことで、選択したインポートアイテムに可能なリソースタイプを確認することができますが、これは100%正確というわけではないことに注意してください。(こちらは、 Azure のプロバイダーの Terrafom に依存し、さらに Terraform は ARM Template という Azure のテンプレートに依存するためです。)
Azure Terrafy
DistributedLoadTesting
3 items
│ /subscriptions/xxx-xxx/resourceGroups/DistributedLoadTesting/providers/Microsoft.ContainerService/managedClusters/LocustOnAKS
(Skip)
/subscriptions/xxx-xxx/resourceGroups/DistributedLoadTesting/providers/Microsoft.ContainerService/managedClusters/LocustOnAKS/agentPools/nodepool1
azurerm_kubernetes_cluster_node_pool.sample
/subscriptions/xxx-xxx/resourceGroups/DistributedLoadTesting
azurerm_resource_group.sample
出力したいリソースが決まったら w
を押します。ここから aztfy
の仕組みですが、その後 aztfy
は、中で terraform import
や terraform add -from-state
を実行し、生成ファイルの準備をします。最後に、ARMテンプレートを活用して、各リソース間に依存関係を解決します。最後に Terraform テンプレートが生成されます。
Azure Terrafy
Terraform state and the config are generated at: sample
Press any key to quit
生成されたファイルが如何のようにできています。
[2021/12/09 22:06:03] ~/src/github.com/Azure/aztfy (main)(LocustOnAKS)
$ ll sample
total 48
drwxr-xr-x 9 sakabekodai staff 288B Dec 9 22:05 .
drwxr-xr-x 22 sakabekodai staff 704B Dec 9 21:49 ..
drwxr-xr-x 3 sakabekodai staff 96B Dec 9 21:50 .terraform
-rw-r--r-- 1 sakabekodai staff 1.1K Dec 9 21:50 .terraform.lock.hcl
-rw------- 1 sakabekodai staff 221B Dec 9 22:05 .terraform.tfstate.lock.info
-rw-r--r-- 1 sakabekodai staff 741B Dec 9 22:05 main.tf
-rw-r--r-- 1 sakabekodai staff 161B Dec 9 21:49 provider.tf
-rw-r--r-- 1 sakabekodai staff 3.3K Dec 9 22:05 terraform.tfstate
-rw-r--r-- 1 sakabekodai staff 2.4K Dec 9 22:05 terraform.tfstate.backup
main.tf
resource "azurerm_kubernetes_cluster_node_pool" "sample" {
kubernetes_cluster_id = "/subscriptions/xxx-xxxx/resourceGroups/DistributedLoadTesting/providers/Microsoft.ContainerService/managedClusters/LocustOnAKS"
mode = "System"
name = "nodepool1"
os_disk_type = "Ephemeral"
vm_size = "Standard_DS3_v2"
depends_on = [
# Depending on "/subscriptions/xxx-xxx/resourceGroups/DistributedLoadTesting/providers/Microsoft.ContainerService/managedClusters/LocustOnAKS", which is not imported by Terraform.
]
}
resource "azurerm_resource_group" "sample" {
location = "eastus"
name = "DistributedLoadTesting"
}
provider.tf
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "2.88.0"
}
}
}
provider "azurerm" {
features {}
}
このように選択した部分だけが template 化されております。最後に terraform plan
で no diff を確認します。
$ terraform plan
azurerm_resource_group.sample: Refreshing state... [id=/subscriptions/xxx-xxx/resourceGroups/DistributedLoadTesting]
azurerm_kubernetes_cluster_node_pool.sample: Refreshing state... [id=/subscriptions/xxx-xxx/resourceGroups/DistributedLoadTesting/providers/Microsoft.ContainerService/managedClusters/LocustOnAKS/agentPools/nodepool1]
No changes. Your infrastructure matches the configuration.
Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
🎉
さいごに
一連の作業については、Demo 動画 でみるとよりイメージがしやすいです。(こちらは README からも見られます) その他制約事項があるようなので、 README をご確認ください。 Azure Terrafy は出たばかりで、今後利用者が増えていく中で便利になっていくと思います。一緒に Contribute していきましょう!