初めてのAzureでTerraform(1)(リソースグループをデプロイ)

2021-05-10

初めてのTerraform第1回です。

TerraformとはHashiCorp社が提供するコードを利用してクラウドなどのリソースをデプロイする為のIaC(Infrastructure as Code)ツールです。

Terraform(HashiCorp公式サイト)

IaCはインフラの構成管理やプロビジョニングをコードを使って自動化するとか言われたりします。
IaCをシンプルに表現すると、設定ファイル作っておくと、コマンド1つでリソース作れて、何度も同じ事をAzure Portalでポチポチしなくても良くなる便利なツール。という感じになります。(省略しまくった表現です。)

調べているだけだとよく分からなかったので、今回は初めてのTerraformと言う事でインストールからTerraformを利用したAzureリソースグループのデプロイまでを実際にやってみました。端末はWindows10を利用しています。

今回の設定作業にあたっては、こちらのサイトを参考に実施しております。

Azure 上の Terraform のドキュメント(MS社公式)

Azure Provider(HashiCorp)

※今回はすべてのファイルをローカルにおいて作業しておりますが、ストレージアカウント等共有ディレクトリにファイルを置いて実施する事が推奨されています。こちらで試しています。
※Terraform v0.15.3(2021年5月時点での最新バージョン)を使用しております。
※2021年12月に加筆修正を行いました。

その他にもAzure+Terraformを使った構成で色々試してみてます。併せて見て頂けると幸いです。

Terraformの記事一覧

スポンサーリンク

TerraformをWindows10へインストール

Terraformを使ってAzureのリソースを操作する為には、Terraformをダウンロードしてパスを通す、Azure CLIをインストールする事が必要になります。

Terraformをダウンロードしてインストール

Terraformを利用する為にはクライアント端末にインストールですが、exeファイルのダウンロード、Windows10でのパス設定と非常にシンプルになっています。

※Terraformにはクラウド版もありますが今回は端末にインストールしてやってみました。

インストール手順

Terraformのサイトを開きます。

Terraform(HashiCorp)

Download CLIとあるのでクリックします。

Terraformのダウンロードページが表示されます。

Terraformダウンロードページ

Windowsの64bitをクリックするとダウンロードが開始されます。

※Windows環境が32bitの場合は32bitを選択してください。

terraform_0.15.3_windows_amd64.zipというZIPファイルがダウンロードされている事が確認出来ます。

※2021年5月現在の最新バージョンになります。

ダウンロードされたZIPファイルを解凍するとTerraform.exeというファイルが出来ます。このファイルを任意のフォルダーに保管します。

今回はC:\Program Files (x86)\Terraformというディレクトリを作成しその中においてます。

WindowsでTerraformへのパスを設定

Terraformはコマンドラインで実行します。コマンド実行した時にTerraformのコマンドだよと認識させる為に、Windows OS上でTerraformのパス設定を行います。

インストール手順

Windowsの検索バーでシステムの詳細設定の表示と入力選択します。

 

システムのプロパティで詳細設定が表示されます。環境変数を選択します。

環境変数でTerraformへのPath設定を行います。

ユーザーの環境変数でPathを選択、編集をクリックします。

環境変数の設定になります。Terraformのexeファイルを置いた場所をPathに追加しOKを選択します。

※今回の場合はC:\Program Files (x86)\Terraformになります。

設定完了後にWindows PowerShellを開き、terraformとコマンド入力します。

Pathが通っていると、コマンドのリストが表示されます。

これでTerraform本体のインストールは完了です。

Azure CLIをインストール

TerraformがAzureへのログインやリソース操作を行う為にAzureCLIのインストールが必要になります。
Azure CLIについてはこちらを参照願います。

Visual Studio CodeでTerraformのファイルを扱う

Visual Studio CodeにTerraformの拡張機能があります。こちらもインストールしておくと作業には便利です。

設定手順

Visual Studio Codeの拡張機能で検索欄にTerraformと入力します。

HashiCorp TerraformとAzure Terraformをインストールします。

Visual Studio自体のインストールはこちらを参照ください。

Terraformを使ってAzureのリソース操作する

TerraformをAzureで利用する場合には認証が必要

TerraformでAzureを扱う場合にはAzureの認証処理が必要になります。
CI/CD等の場合にはサービスプリンシパル等の非対話形式のログイン方法を利用します。

実施手順

Azure CLI(Microsoft アカウント)を使用した認証

Azure CLIを使用してコマンドラインで認証します。

az loginコマンドで認証します(対話形式(ログイン画面が表示されてログインする形))。

Azure サービス プリンシパルを使用した認証

Azureサービスプリンシパルを利用してコードの中で非対話形式(自動ログイン)する形式になります。
マネージドID(Managed identities)を使用した認証

AzureマネージドIDを利用してコードの中で非対話形式(自動ログイン)する形式になります。

※テナント内のAzure VMからアクセスする場合にのみ使用可能です。(テナント外の場合はサービスプリンシパルを利用する形になります。)

AzureマネージドIDを利用した認証はこちらを参照願います。

Azure サービスプリンシパルの作成についてはこちらを参照願います。

Terraformの基本コマンド

Teraformの基本コマンドになります。今回はinit、plan、applyを利用してデプロイまでを実施しています。

Terraformのコマンド

terraform init

terraformを実行する為に一番最初に実行するコマンド。
ワークスペースを初期化するコマンドで必須のコマンドになります。
このコマンドを実行すると、.terraformと言うディレクトリが作成されます。その中にデプロイに必要なファイルがダウンロードされます。

実際に確認するとAzureにデプロイする為に必要となる、terraform-provider-azurerm_v2.46.0_x5.exeというファイルがダウンロードされていました。

terraform validate

Terraformの構文が正しいかのチェックを行います。
Teraform Planでも実行されます。

terraform plan

Terraformを実行した際に何がデプロイ(変更)されるのかを確認するコマンドになります。
事前の確認コマンドになります。実際のデプロイは行われません。

terraform apply

Terraformを利用してリソースをデプロイするコマンドになります。
terraform destroy Terraformを利用してリソースを削除するコマンドになります。

※実際の運用上で利用するコマンドは様々あります。今回はオプションを含めて最低限の利用にしております。

Terraformの記述方式

独自 DSL である HCL 形式(HashiCorp Configuration Language=HashiCorp 構成言語)にて記載されます。
Blockと言うかたまりで定義されます。ざっくり言うとこんな感じかなぁと思っています。

      • Block Type:そのブロックが何を指すのかと言う意味
      • Block Labels:ブロックの定義
      • Arguments:定義された値
リソースグループの例

Azure リソースグループの例です。
リソースグループの場合に関する書き方についてはAzure Provider(HashiCorp)に記載があります。

Block typeがresourceと言う事で作成するリソースを定義するブロックであることを示しています。
Block Labelsが"azurerm_resource_group" “test-rg"となっています。"azurerm_resource_group"はAzureのリソースグループの定義だよと言う事を指しています。"test-rg"はtest-rgと言う名前で呼び出す事が出来るよと言う事を示しています。
Argumentsは実際に作成するリソースの値になります。

 

※Terraformで扱えるAzureのリソースの書き方についてはAzure Provider(HashiCorp)にて定義されています。

Terraformのでデプロイする場合のブロックの構成について

Azureリソースグループをデプロイする場合を例に最低限必要なブロック構成を記載するとこのような感じになります。

リソースグループの例
  • Terraform Block:Terraform自体の動作を指定するブロックになります。Terraform自体が使用しているバージョン等を記載します。
  • Provider Block:使用するプロバイダーを指定します。今回の場合はAzureを指定しています。
  • Resource Block:実際に作成するリソースを記載します。

Terraformを利用する場合もAzure Portalを使う場合も指定するパラメータは同じ

Azure Portalを利用する場合もTerraformを利用する場合も指定するパラメータは同じです。

Azure Portalの画面

Terraformを使ってAzureリソースグループをデプロイする場合に、設定ファイルで指定する内容(必須)は名前、locationになるのですが、この設定値はAzure Portalで作成する場合と同じになります。

※任意の設定項目としてタグの指定も可能です。

Terraformを使ってAzureリソースグループをデプロイ

Azure リソースグループをデプロイする為にファイルを作成する

Azureリソースグループをデプロイする場合のファイルになります。

リソースグループの例

Terraformで利用するファイルは.tfと言う拡張子で保存します。Terraformはコマンド実行ディレクトリにある.tfと言う拡張子のファイルを読み込んで実行します。
今回はC:\Temp\terraform配下に保管します。

※本記事の最後にあるファイルを分割した場合で詳細は記載しています。

terraform {
  required_version = “>= 0.12"
  required_providers {
    azurerm = {
      source  = “hashicorp/azurerm"
      version = “=2.46.0"
    }
  }
}

provider “azurerm" {
  features {}
}

resource “azurerm_resource_group" “demo" {
  name     = test-rg
  location = eastus2
}

Terraformを使ってAzureリソースグループをデプロイ

Terraformを使ってAzureリソースグループをデプロイしてみます。
事前にAzure CLI(az loginコマンド)を使ってログインしておく必要があります。
ログイン後はコマンドを順番に実行するだけです。

※az group listと入力してリソースグループの一覧が表示されればAzure CLIを使ってログインが完了しています。
※マネージドIDを使って認証を行う方法はこちらを参照ください。

実施手順

terraform initを実行する

 

PS C:\Temp\terraform> terraform init

Initializing the backend…

Initializing provider plugins…
– Using previously-installed hashicorp/azurerm v2.46.0

Terraform has been successfully initialized!

<以下略>

Terraform has been successfully initialized!と表示されていれば成功です。

terraform planを実行する。

PS C:\Temp\terraform> terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
+ create

Terraform will perform the following actions:

# azurerm_resource_group.demo will be created
+ id = (known after apply)
+ location = “eastus2"
+ name = “test-rg"
}

Plan: 1 to add, 0 to change, 0 to destroy.

<以下略>

メッセージに作成されるリソースが表示されます。

  • to add:追加されるリソース
  • to change:変更されるリソース
  • to destroy:削除されるリソース

今回は、1 to addなので1つのリソースグループのみが追加され、その他のリソースに影響がないことが分かります。

terraform applyを実行する。

PS C:\Temp\terraform> terraform apply

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the
following symbols:
+ create

Terraform will perform the following actions:

# azurerm_resource_group.demo will be created
+ resource “azurerm_resource_group" “demo" {
+ id = (known after apply)
+ location = “eastus2"
+ name = “test-rg"
}

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes’ will be accepted to approve.

Enter a value: yes

azurerm_resource_group.demo: Creating…
<中略>

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Enter a value: という確認メッセージが表示されます。作成を継続する場合はyesと入力します。(”Y”等ではなく、yesと入力する必要があります。)

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.と表示され、リソース作成が成功して事がメッセージから分かります。

Azure Portalで作成後のリソース確認すると出来ている事が分かります。

Terraformを使ってデプロイしたら.tfstateというファイルが出来てました

デプロイが完了するとxxx.tfstateと言うファイルが出来ています。これは何でしょうか。
一言でいうとTerraformが管理しているリソースの状態を表すファイルになります。
実際に中身を確認すると、ARMテンプレートと同じようなJSON形式のファイルが出来ています。

Terraformはこのファイルをリソースの状態と認識してデプロイの操作等を行います。
他の方がTerraformを使って更新されたりして最新化されていないものを参照した場合は、実環境のリソースの最新情報と実際の情報に差分が発生したりという事になります。
これがtfstateファイルの保管には共有ディレクトリを使ってねと言われる理由の1つになってたりします。

Terraformのファイルを分割したり変数を利用してみた

Terraformのファイルを分割してみる

先ほどリソースグループを作成したファイルを分割してみます。
Terraform BlockやProvider Blockは重複して記載する必要がないため別ファイルで作成した方が管理しやすくなります。
今回分割して作成したファイルは5つになります。ファイル分割に併せてリソースグループ名を変数化してみました。

      • Terraform Block(Terraform自体の動作を規定):main.tf、version.tf
      • Provider Block(Terraform自体が利用するプロバイダーを規定):provider.tf
      • Resource Block(Terraformが作成するリソースを規定):resourcegroup.tf
      • 変数値を指定するファイル:terraform.tfvars
作成したファイル

main.tf

required_providersを指定しています。Terraformがどのプロバイダー(Azure等)を利用するのか指定します。

Provider Requirements(Terraform)

※0.13以降で登場したようです。

provider.tf

デプロイするproviderを指定しています。Azureのリソースをデプロイする事を宣言しています。
デプロイするサブスクリプションやテナントをはproviderの宣言の中で指定します。

resourcegroup.tf

デプロイするリソースの情報を指定しています。
設定値自体はterraform.tfvarsから読み込んでいます。

terraform.tfvars

設定値を記載しています。今回はリソースグループ名やデプロイするロケーションを指定しています。

※Terraformデフォルトの変数設定ファイル名がterraform.tfvarsになります。このファイル名だと変数を指定しているのはこのファイルだよとデプロイ時に指定しなくても読み込んでくれます。

version.tf Terraform自体のVersionを指定しています。Terraform自体がVerにより挙動が異なる為、このVerを使用しているよと指定します。

Terraformで変数を利用する

Terraformでは変数を利用する事が出来ます。変数にはlocal(ローカル変数)などもありますが、今回は外部から設定値を読み込むという事でvariableを使用します。
変数値の指定は実行時に指定したり設定ファイルによる指定が出来ます。今回は設定値により指定しています。

    • 実施した設定内容
      • Variableで変数を定義
      • resource内で、var.変数名で変数を呼び出し
      • terraform.tfvarsで変数値を指定する

※変数を指定したファイルはファイル名を指定する事で読み込む事が可能です。デフォルトではterraform.tfvarsを読み込みます。

分割後のファイル

分割後のファイルはこのような感じになります。1つのファイルで作成した時と同じようにリソースグループをデプロイ出来ます。

※ファイルはGithubにもおいてあります。

作成したファイル

main.tf

 

terraform {
  required_providers {
    azurerm = {
      source  = “hashicorp/azurerm"
      version = “=2.46.0"
    }
  }
}
Terraform公式ページのこちらを参照しています。

provider.tf

provider “azurerm" {
  features {}
}
Terraform公式ページのこちらを参照しています。

resourcegroup.tf

variable rg-name {}
variable rg-location {}

resource “azurerm_resource_group" “demo" {
  name     = var.rg-name
  location = var.rg-location
}

Terraform公式ページのこちらを参照しています。

今回は、nameとlocationは変数化して別ファイルから読み込んでいます。

  • 変数の指定
    • variableで変数を定義
    • var.変数名で呼び出して設定値

terraform.tfvars

rg-location = “eastus2"
rg-name     = “test-rg"

今回利用する変数の値を設定しています。変数名は任意です。

version.tf

terraform {
  required_version = “>= 0.12"
}
Terraform公式ページのこちらを参照しています。

最後に

今回はTerraformを初めて触ってAzureのリソースをデプロイするという所までの基本的な例をやってみました。
Terraformを自体を使えるようにする所までや、実際に使うのってこんな感じなんだと言うような雰囲気が分かってきた感じです。
今後もTerraformを使って色々やってみたいと思います。VMデプロイ等のTerraform関連の記事はこちらに記載しております。併せて見て頂ければと。

Terraformの記事一覧