前書き
現在所属している組織では Azure を利用しており、これから IaC を推進していくために技術検証をはじめました。ARM templates のチュートリアル、Terraform for Azure のチュートリアル、HashiCorp on Azure のウェビナー 、ドキュメント読み漁りで得た情報をまとめて行きます。
なお、記事作成時の筆者のスペックは Azure経験:2週間程度、ARM templates経験:20時間程度、Terraformの経験:40時間程度のぺいぺいである事をご了承ください。 GCP では僅かながら IaC (Google Cloud SDK や Terraform) を用いた構成管理の経験があります。
何を使うべきかを検討する上での私のスタンス
構成管理は"1つのツールで全てやろうとするのはあまり良い考えでは無い"という考えに共感しています。なぜなら、課題に合ったツールを採用すべきであり、目的のシステムを取り巻く課題は刻々と変化するためです。
ゴールはあくまで "インフラを継続的に再利用可能にする"であるかなと思います。
そのため、各比較象限で ARM templates と Terraform の優劣を決めて行くのではなく、特徴を書いて行きます。
参考1:
We compare Terraform to a number of these tools, but it should be noted that Terraform is not mutually exclusive with other systems
by https://www.terraform.io/intro/vs/index.html
参考2:
自動化関連のツールの流行り廃りは早いので、1つのツールで全てやろうとするのはあまり良い考えでは無いと思います
https://engineering.mobalab.net/2018/01/10/terraform-%E3%81%AB%E3%82%88%E3%82%8B%E3%82%A4%E3%83%B3%E3%83%95%E3%83%A9%E6%A7%8B%E7%AF%89/
Terraform に関して
特徴
マルチプロバイダーでも統一されたワークフローを提供する
Terraform はとにかく統一されたインフラ構築のワークフローをもたらします。インフラの構築先が Azure であっても、 GCP であっても、オンプレであっても、構築対象が VM であっても k8s であってもです。planでインフラの変更差分を確認して、apply でインフラ構築を実行します。以下の様な流れです。
構成ファイル(.tf)を記述
↓
init (provider plugins の取得。)
↓
plan (新規作成した場合の構築内容を表示。)
↓
apply (インフラを新規構築。stateファイルの作成。)
↓
(インフラの変更が必要になる。)
↓
構成ファイル(.tf)を修正
↓
plan -out=newplan (インフラの変更内容の確認。変更プランとして書き出し。)
↓
apply "new_plan" (変更プランを適用。)
↓
(インフラが不要になる。)
↓
destroy (インフラの破棄。)
コードレビュー + CI の運用に乗せやすそう
ウェビナーでおすすめされていた運用は以下の様なものでした。
- state ファイルを blob ストレージ (または Terraform Cloud)で管理する
- 構成ファイルを記述したらコードレビューを入れる
- CI で plan を実行させ、構成ファイルと plan コマンドで出力される変更の両方を確認する
- apply は必ず CI に実行させる
- 新規にインフラを作る場合は必ず Terraform を使って Azure Portal から作成をしない
- Azure の Provider できない値指定は ARM templates と併用するか Provider に Pull Request を投げる
インフラ構築・修正がコードレビューした上で、CIから実行するフローはとても素敵ですね
ちなみに、既存AzureリソースはHCLに置き換えるとができないとウェビナーでは回答頂いたのですが、terraform import
を利用する事で、stateファイルを作成する事ができました。
運用のためのTerraform Cloud が用意されている
私は試していませんがこちらの記事を拝見させて頂いた限り、とても良さそうです
https://blog.shibayan.jp/entry/20200910/1599749096
その他特徴
- 構成ファイル(.tf)が読みやすい
- 構成ファイルはコメントが書ける
- VS Code にも JetBrain のIDEでもプラグインがある
気になるところ
気になるところもいくつかありました。
Provider が Azure の変更に対応するか
ウェビナーで質問したところ、OSS なので Azure の変更への追随には多少遅れが生じるため、是非コントリビュートして欲しいという言葉をいただきました。 Go (Terraform本体・Provider共に)で書かれており、私には残念ながら難しいかもしれません。
ソースの更新は頻繁であるように感じました。
https://github.com/terraform-providers/terraform-provider-azurerm/pulse/monthly
HashiCorp のサイトには強力なパートナーシップが長年実現されてきた旨が書かれています。
https://www.hashicorp.com/cloud-partners/microsoft?product=terraform
Terraform はあくまで Wrapper であること
Azureの各インフラのAPIバージョンなどの細かい指定や細かな属性調整ができるのか不安です。
(ろくに内部のコードを読まずにこんなことを言って申し訳ない)
手を動かしてみる
チュートリアル+アルファを実行したメモを置いておくので、雰囲気を見るのに役立ててください。
環境設定
- azsure cli を install する
- install
brew install hashicorp/tap/terraform
Terraform v0.13.5
terraform -install-autocomplete
- vscode の pligin を install
hashicorp.terraform
- azure でリソースグループ
terra_test
を作成- location:
japaneast
だけを設定する
- location:
cat ~/ghq/github.com/github/gitignore/Terraform.gitignore >> .gitignore
既存のインフラを後からコード化する
-
ex. recource group のマイニング
- https://www.terraform.io/docs/providers/azurerm/r/resource_group.html
- (
terraform import azurerm_resource_group.rg /subscriptions/<subscription_id>/resourceGroups/terra_test
)
-
tfstateが存在する場合に、状態を確認する流れ
$ terraform state list
azurerm_resource_group.rg
$ terraform state show azurerm_resource_group.rg
# azurerm_resource_group.rg:
resource "azurerm_resource_group" "rg" {
id = "/subscriptions/<subscription_id>/resourceGroups/terra_test"
location = "japaneast"
name = "terra_test"
tags = {}
timeouts {}
}
インフラを変更する
main.tf
を以下のように変更する
resource "azurerm_resource_group" "rg" {
name = "terra_test"
location = "japaneast"
tags = {
Environment = "Terraform Getting Started"
}
}
terraform plan -out=newplan
を実行する。
変更箇所が分かりやすい。
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
# azurerm_resource_group.rg will be updated in-place
~ resource "azurerm_resource_group" "rg" {
id = "/subscriptions/<subscription_id>/resourceGroups/terra_test"
location = "japaneast"
name = "terra_test"
~ tags = {
+ "Environment" = "Terraform Getting Started"
}
timeouts {}
}
Plan: 0 to add, 1 to change, 0 to destroy.
-
terraform apply "newplan"
を適用する。-
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
が表示される -
terraform state show azurerm_resource_group.rg
すると結果が変わっている
-
インフラを削除する
-
terraform destroy
-
実行するかどうかが表示される
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# azurerm_resource_group.rg will be destroyed
- resource "azurerm_resource_group" "rg" {
- id = "/subscriptions/<subscription_id>/resourceGroups/terra_test" -> null
- location = "japaneast" -> null
- name = "terra_test" -> null
- tags = {
- "Environment" = "Terraform Getting Started"
} -> null
- timeouts {}
}
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value:
Terraform 関連のリンク
有用だったリンクや公式ドキュメントのリンクを置いておきます。
- Azure Doc 上の Terraform
- Terraform Doc の Azure Provider
- Terraform ソース
- Azure Provider ソース
- とにかくここからはじめよう
- Terraform Cloudのレビュー記事
- チュートリアル + アルファの手順
ARM templates に関して
ARM Templates の特徴
Azure の新しいサービスと機能をすぐに利用できる
公式の"ARM テンプレートを選択する理由"に記載があります。
https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/templates/overview#why-choose-arm-templates
パラメータをファイル管理できる
テンプレートとパラメータに分けて管理できます
https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/templates/parameter-files
what-if と呼ばれるもので dry run ができる (preview)
状態ファイルが無くても what-if コマンドで dry run ができます
既存リソースを定義ファイルにエクスポートができる
ポータルから手軽に作成済のリソースをテンプレートとしてエクスポートする事ができます
その他特徴
- モジュール化できる
- 状態ファイルを管理しない
- 相互に依存するリソースのデプロイが調整され、正しい順序で作成される
- Azure Key Vault と連携してセキュアな管理ができる
- 日本語ドキュメントが充実している
- VScode の Azure Resource Manager (ARM) Tools のスニペットが強力
- 定義ファイルはJSON
- パラメーターを説明は metadata に記載する
"parameters": {
"storageAccountType": {
"type": "string",
"metadata": {
"description": "The type of the new storage account created to store the VM disks."
}
}
}
手を動かしてみる
チュートリアル - 初めての ARM テンプレートを作成してデプロイするを実施し、VM の立ち上げ + VMリソースの修正をしました。雰囲気を感じられると思うので手順と結果を置いておきます。
- VSCodeの拡張機能(ARMTools) を準備する
- 拡張機能を準備する
-
.net core
が入ってないと、パラメータのスニペットが動かない - mac に wget のコマンドが入っていなかったので、 VSCode をがエラーを吐いていた
- VSCode を再起動すると
.net core
が再度インストールが始まる - "azuredeploy.json"のファイルタイプを
AzureResourveManagerTemplate
に変更しないとスニペットが効かない
- チュートリアル 初めての ARM テンプレートを作成してデプロイするを実施する
- VM をデプロイする用のリソースグループを作成する
az group create --name armt_test --location japaneast
- ポータルからVMのスペックを選択して、テンプレートとパラメータをエクスポートする
- スクラッチでいきなり書くのは厳しいので
- エクスポートしたテンプレートとパラメータを DRY RUN する
- エクスポートしたテンプレートとパラメータをデプロイする
az deployment group create --resource-group armt_test --template-file template.json --parameters parameters.json
- VMが作成された事をポータルから確認する
- VMのパラメータを変更した parameters2.json を作成する
- parameters2.json を DRY RUN する
- parameters2.json を適用する
az deployment group create --resource-group armt_test --template-file template.json --parameters parameters2.json
- リソースグループを削除する
az group delete --name armt_test
所感
少し触ったり調べた程度だと どちらも DRY RUN 、 コードレビューができ、IaC をする上で申し分ないように感じます。
ただし、大規模化すると使い勝手も変わってくるかもしれません。
以上でございます。