以前の記事で、Terraform の基本的な概念をご紹介しました。
今回は Azure のリソースを Terraform でデプロイする基本的なサンプルを公開しようと思います。
個人的な注釈も入れているので、理解するための何等かの助けになると嬉しいです。
前提条件
本サンプルを使用するには、以下の前提条件をまず確認してください。
- Azure サブスクリプションの用意
- Azure サブスクリプションにリソースを作成するための権限を持つアカウントで実施
- 権限例:「所有者」権限、「共同作成者」権限
- コマンドを実行するクライアントに、以下のツールがインストールされていること (cloud shell でも可)
- Terraform
- Azure CLI
- ある程度 Terraform の基礎知識を持っていること(下記記事を読んでったら十分です)
※ クリックスタート 記事に、Terraform のインストール方法が載っています。
Azure リソース のデプロイ
上記条件が揃ったら、サンプルを使って、リソースを作成してみましょう。
サンプルコード
下記のサンプルコードをテキストファイルで保存し、".tf" 拡張子で名前を変更してください。
# チュートリアル:https://docs.microsoft.com/ja-jp/azure/developer/terraform/get-started-cloud-shell
# 使用するプロバイダーを指定する:Azure は azurerm を指定する。また、GCPだったら google を指定する
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>2.0"
}
}
}
# プロバイダーに関する設定を定義する:例えば認証情報とか (自動化したい場合、環境変数での認証も可能なので、明文で書くことをは推奨しない)
provider "azurerm" {
# The "feature" block is required for AzureRM provider 2.x.
# If you're using version 1.x, the "features" block is not allowed.
features {}
# 認証情報をここに書くことも可能
# subscription_id = "00000000-0000-0000-0000-000000000000"
# client_id = "00000000-0000-0000-0000-000000000000"
# client_certificate_path = "xxxxx"
# client_certificate_password = "xxxxx"
# tenant_id = "00000000-0000-0000-0000-000000000000"
}
# 第一 Block laber "azurerm_resource_group" は 作成するリソースの種類を指定する
# 第二 Block laber "myrg01" は tf ファイル内のリソースの識別 ID のようなもの
# 上記の二つの要素を組み合わせすることで、tf ファイル内でリソースを特定できる。Terraform の管理下であるリソースかどうかを識別するために、ステータスファイルとこの識別子で判断する仕組みになっている
resource "azurerm_resource_group" "myrg01" {
name = "terraform-test-rg01" # Azure のリソース名
location = "japaneast"
}
# 仮想ネットワーク作成
resource "azurerm_virtual_network" "myvnet01" {
name = "myVnet"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.myrg01.location # myrg01 の location 属性を使う。他のリソースの情報を使うことで DepandsOn 関係が自動的になる
resource_group_name = azurerm_resource_group.myrg01.name # 上記 myrg01 の name 属性を使う
tags = {
environment = "Terraform Demo"
}
}
# サブネット作成
resource "azurerm_subnet" "mysubnet01" {
name = "subnet01"
resource_group_name = azurerm_resource_group.myrg01.name
virtual_network_name = azurerm_virtual_network.myvnet01.name
address_prefixes = ["10.0.2.0/24"]
}
# パブリック IP 作成
resource "azurerm_public_ip" "mypublicip01" {
name = "myPublicIP01"
location = azurerm_resource_group.myrg01.location
resource_group_name = azurerm_resource_group.myrg01.name
allocation_method = "Dynamic"
tags = {
environment = "Terraform Demo"
}
}
# NSG 作成
resource "azurerm_network_security_group" "mynsg01" {
name = "myNSG01"
location = azurerm_resource_group.myrg01.location
resource_group_name = azurerm_resource_group.myrg01.name
security_rule {
name = "SSH"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
tags = {
environment = "Terraform Demo"
}
}
# VM の NIC 作成 (Azure では NIC は独立したリソースです)
resource "azurerm_network_interface" "mynic01" {
name = "myNIC01"
location = azurerm_resource_group.myrg01.location
resource_group_name = azurerm_resource_group.myrg01.name
# NIC の設定値の定義
ip_configuration {
name = "myNicConfiguration"
subnet_id = azurerm_subnet.mysubnet01.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.mypublicip01.id
}
tags = {
environment = "Terraform Demo"
}
}
# NIC と NSG の紐づけ
resource "azurerm_network_interface_security_group_association" "mynic01_mynsg01" {
network_interface_id = azurerm_network_interface.mynic01.id
network_security_group_id = azurerm_network_security_group.mynsg01.id
}
# リソースグループ名に依存するランダム文字列を生成する(リソースグループ名が変わらない限り、この文字列も変わらない)
# ストレージアカウントは世界中に一意である必要があるため、ランダムな値を使用する
resource "random_id" "myrandomId01" {
keepers = {
# Generate a new ID only when a new resource group is defined
resource_group = azurerm_resource_group.myrg01.name
}
byte_length = 8 # 長さ定義
}
# ストレージアカウント作成
resource "azurerm_storage_account" "mystorageaccount01" {
name = "diag${random_id.myrandomId01.hex}" # 上記で定義したランダム文字列を使う
resource_group_name = azurerm_resource_group.myrg01.name
location = azurerm_resource_group.myrg01.location
account_replication_type = "LRS"
account_tier = "Standard"
tags = {
environment = "Terraform Demo"
}
}
# SSH の 秘密キーを作成 (VM ログイン用)
resource "tls_private_key" "myssh01" {
algorithm = "RSA"
rsa_bits = 4096
}
# "tls_private_key" は出力名、{...} は値
# 秘密キー を出力するのに使用する
output "tls_private_key" { value = tls_private_key.myssh01.private_key_pem }
# 仮想マシン作成
resource "azurerm_linux_virtual_machine" "myvm01" {
name = "myVM01"
location = azurerm_resource_group.myrg01.location
resource_group_name = azurerm_resource_group.myrg01.name
network_interface_ids = [azurerm_network_interface.mynic01.id]
size = "Standard_A2_v2"
# OS ディスクのリソース定義
os_disk {
name = "myOsDisk"
caching = "ReadWrite"
#Choose between Standard_LRS, StandardSSD_LRS and Premium_LRS based on your scenario
storage_account_type = "Standard_LRS"
}
# イメージ指定
source_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "18.04-LTS"
version = "latest"
}
# OS 情報を指定
computer_name = "myvm" # OS の PC名
admin_username = "azureuser" # ローカル管理者名
disable_password_authentication = true # パスワード認証を無効にする (秘密キー認証のみが使えるようになる)
# 公開キー情報の定義
admin_ssh_key {
username = "azureuser" # 認証のユーザーを指定
public_key = tls_private_key.myssh01.public_key_openssh # 上記で定義した myssh01 の公開キーを使う
}
boot_diagnostics {
storage_account_uri = azurerm_storage_account.mystorageaccount01.primary_blob_endpoint # ストレージアカウントの URL
}
tags = {
environment = "Terraform Demo"
}
}
デプロイ手順
- コマンドプロンプトを起動する(Linux でしたら、このステップをスキップしてください)
- cd コマンドで、サンプルコードの
tf
ファイルのディレクトリに移動 - 以下のコマンドで Azure 環境へログインする
- ログインコマンド:
az login
- サブスクリプション選択コマンド:
az account set --subscription="<SUBSCRIPTION_ID>"
- ログイン結果確認:
az account show --query "{subscriptionId:id, tenantId:tenantId}"
- ログインコマンド:
- Terraform コマンドでデプロイ実行
- 初期化(プロバイダーダウンロードなど):
terraform init
- デプロイ内容の確認(plan run):
terraform plan
- デプロイ実施:
terraform apply
- 初期化(プロバイダーダウンロードなど):
Terraform の Azure 認証について
上記の手順で、 az login コマンドを使って、Azure へログインしていますが、自動化のために認証を省けたい要件はよくあります。その場合、Azure サービスプリンシパルを使うことを推奨します。
サービスプリンシパルがよくわからない方は、以前の記事をご参考をいただければと思います。
また、Terraform では環境変数にサービスプリンシパルの情報を設定することで、az login
を使わなくても、自動的に認証してくれるので、自動化する時に結構役に立ちます。
設定する環境変数名は以下となります:
- ARM_SUBSCRIPTION_ID
- ARM_CLIENT_ID
- ARM_CLIENT_SECRET
- ARM_TENANT_ID
- ARM_ENVIRONMENT
最後に
今回は実際に Azure でデプロイできるサンプルコードとデプロイの流れを簡単にご紹介しました。
Terraform はコードを再利用するためにモジュールの仕組みもありますが、いきなりモジュールを分けて説明すると、理解が難しくなりますので、今回はすべてのデプロイ内容を一つの tf ファイルに記載しています。
モジュールに関しては、terraform-module記事で整理していたので、実際の運用で使いたい方は、ぜひ参考にしていただければと思います。
コメント