このクイックスタートでは、Terraform を使用して仮想マシンの負荷分散を行う標準ロード バランサーをデプロイする方法について説明します。
Terraform を使用すると、クラウド インフラストラクチャの定義、プレビュー、デプロイが可能になります。 Terraform を使用して、 HCL 構文を使用して構成ファイルを作成します。 HCL 構文を使用すると、クラウド プロバイダー (Azure など) とクラウド インフラストラクチャを構成する要素を指定できます。 構成ファイルを作成したら、インフラストラクチャの変更をデプロイする前にプレビューできる 実行プラン を作成します。 変更を確認したら、実行プランを適用してインフラストラクチャをデプロイします。
- azurerm_resource_groupを使用して Azure リソース グループを作成する
- azurerm_virtual_networkを使用して Azure Virtual Network を作成する
- azurerm_subnetを使用して Azure サブネットを作成する
- azurerm_public_ipを使用して Azure パブリック IP を作成する
- azurerm_lbを使用して Azure Load Balancer を作成する
- azurerm_network_interfaceを使用して Azure ネットワーク インターフェイスを作成する
- azurerm_network_interface_backend_address_pool_associationを使用して Azure ネットワーク インターフェイス ロード バランサーバックエンド アドレス プールの関連付けを作成する
- azurerm_linux_virtual_machineを使用して Azure Linux 仮想マシンを作成する
- azurerm_virtual_machine_extensionを使用して Azure 仮想マシン拡張機能を作成する
[前提条件]
アクティブなサブスクリプションがある Azure アカウントを作成します。 アカウントは無料で作成できます。
Terraform コードを実装する
この記事のサンプル コードは、 Azure Terraform GitHub リポジトリにあります。 Terraform の現在および以前のバージョンからのテスト結果を含むログ ファイルを表示できます。 Terraform を使用して Azure リソースを管理する方法を示すその他の記事とサンプル コードを参照してください
サンプル Terraform コードをテストして実行するディレクトリを作成し、それを現在のディレクトリにします。
providers.tf
という名前のファイルを作成し、次のコードを挿入します。terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "~>4.0" } random = { source = "hashicorp/random" version = "~>3.0" } } } provider "azurerm" { features {} }
main.tf
という名前のファイルを作成し、次のコードを挿入します。# Create a random name for the resource group using random_pet resource "random_pet" "rg_name" { prefix = var.resource_group_name_prefix } # Create a resource group using the generated random name resource "azurerm_resource_group" "example" { location = var.resource_group_location name = random_pet.rg_name.id } # Create Virtual Network resource "azurerm_virtual_network" "example" { name = var.virtual_network_name address_space = ["10.0.0.0/16"] location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name } # Create a subnet in the Virtual Network resource "azurerm_subnet" "example" { name = var.subnet_name resource_group_name = azurerm_resource_group.example.name virtual_network_name = azurerm_virtual_network.example.name address_prefixes = ["10.0.1.0/24"] } # Create Network Security Group and rules resource "azurerm_network_security_group" "example" { name = var.network_security_group_name location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name security_rule { name = "web" priority = 1008 direction = "Inbound" access = "Allow" protocol = "Tcp" source_port_range = "*" destination_port_range = "80" source_address_prefix = "*" destination_address_prefix = "10.0.1.0/24" } } # Associate the Network Security Group to the subnet resource "azurerm_subnet_network_security_group_association" "example_association" { subnet_id = azurerm_subnet.example.id network_security_group_id = azurerm_network_security_group.example.id } # Create Public IP resource "azurerm_public_ip" "example" { name = var.public_ip_name location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name allocation_method = "Static" sku = "Standard" } # Create Network Interface resource "azurerm_network_interface" "example" { count = 2 name = "${var.network_interface_name}${count.index}" location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name ip_configuration { name = "ipconfig${count.index}" subnet_id = azurerm_subnet.example.id private_ip_address_allocation = "Dynamic" primary = true } } # Associate Network Interface to the Backend Pool of the Load Balancer resource "azurerm_network_interface_backend_address_pool_association" "example" { count = 2 network_interface_id = azurerm_network_interface.example[count.index].id ip_configuration_name = "ipconfig${count.index}" backend_address_pool_id = azurerm_lb_backend_address_pool.example.id } # Generate a random password for the VM admin users resource "random_password" "example" { length = 16 special = true lower = true upper = true numeric = true } # Create Virtual Machine resource "azurerm_linux_virtual_machine" "example" { count = 2 name = "${var.virtual_machine_name}${count.index}" location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name network_interface_ids = [azurerm_network_interface.example[count.index].id] size = var.virtual_machine_size os_disk { name = "${var.disk_name}${count.index}" caching = "ReadWrite" storage_account_type = var.redundancy_type } source_image_reference { publisher = "Canonical" offer = "0001-com-ubuntu-server-jammy" sku = "22_04-lts-gen2" version = "latest" } admin_username = var.username admin_password = coalesce(var.password, random_password.example.result) disable_password_authentication = false } # Enable virtual machine extension and install Nginx resource "azurerm_virtual_machine_extension" "example" { count = 2 name = "Nginx" virtual_machine_id = azurerm_linux_virtual_machine.example[count.index].id publisher = "Microsoft.Azure.Extensions" type = "CustomScript" type_handler_version = "2.0" settings = <<SETTINGS { "commandToExecute": "sudo apt-get update && sudo apt-get install nginx -y && echo \"Hello World from $(hostname)\" > /var/www/html/index.html && sudo systemctl restart nginx" } SETTINGS } # Create Public Load Balancer resource "azurerm_lb" "example" { name = var.load_balancer_name location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name sku = "Standard" frontend_ip_configuration { name = var.public_ip_name public_ip_address_id = azurerm_public_ip.example.id } } # Create Backend Address Pool for the Load Balancer resource "azurerm_lb_backend_address_pool" "example" { loadbalancer_id = azurerm_lb.example.id name = "test-pool" } # Create Load Balancer Health Probe resource "azurerm_lb_probe" "example" { loadbalancer_id = azurerm_lb.example.id name = "test-probe" port = 80 } # Create Load Balancer Rule # This rule will forward traffic from the frontend IP configuration to the backend address pool # on port 80 using TCP protocol. It also disables outbound SNAT for the backend pool. # The probe is used to check the health of the backend instances. resource "azurerm_lb_rule" "example_rule" { loadbalancer_id = azurerm_lb.example.id name = "test-rule" protocol = "Tcp" frontend_port = 80 backend_port = 80 disable_outbound_snat = true frontend_ip_configuration_name = var.public_ip_name probe_id = azurerm_lb_probe.example.id backend_address_pool_ids = [azurerm_lb_backend_address_pool.example.id] } resource "azurerm_lb_outbound_rule" "example" { name = "test-outbound" loadbalancer_id = azurerm_lb.example.id protocol = "Tcp" backend_address_pool_id = azurerm_lb_backend_address_pool.example.id frontend_ip_configuration { name = var.public_ip_name } }
variables.tf
という名前のファイルを作成し、次のコードを挿入します。variable "resource_group_location" { type = string default = "eastus" description = "Location of the resource group." } variable "resource_group_name_prefix" { type = string default = "rg" description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription." } variable "username" { type = string default = "azureadmin" description = "The username for the local account that will be created on the new VM." } variable "password" { type = string default = "" description = "The password for the local account that will be created on the new VM." } variable "virtual_network_name" { type = string default = "test-vnet" description = "Name of the Virtual Network." } variable "subnet_name" { type = string default = "test-subnet" description = "Name of the subnet." } variable "public_ip_name" { type = string default = "test-public-ip" description = "Name of the Public IP." } variable "network_security_group_name" { type = string default = "test-nsg" description = "Name of the Network Security Group." } variable "network_interface_name" { type = string default = "test-nic" description = "Name of the Network Interface." } variable "virtual_machine_name" { type = string default = "test-vm" description = "Name of the Virtual Machine." } variable "virtual_machine_size" { type = string default = "Standard_B2s" description = "Size or SKU of the Virtual Machine." } variable "disk_name" { type = string default = "test-disk" description = "Name of the OS disk of the Virtual Machine." } variable "redundancy_type" { type = string default = "Standard_LRS" description = "Storage redundancy type of the OS disk." } variable "load_balancer_name" { type = string default = "test-lb" description = "Name of the Load Balancer." }
outputs.tf
という名前のファイルを作成し、次のコードを挿入します。output "resource_group_name" { value = azurerm_resource_group.example.name } output "public_ip_address" { value = "http://${azurerm_public_ip.example.ip_address}" } output "vm_password" { value = azurerm_linux_virtual_machine.example[0].admin_password sensitive = true }
重要
4.x azurerm プロバイダーを使用している場合は、Terraform コマンドを実行する前に、Azure に対して認証する Azure サブスクリプション ID を明示的に指定 する必要があります。
azure サブスクリプション ID を providers
ブロックに入れずに指定する 1 つの方法は、 ARM_SUBSCRIPTION_ID
という名前の環境変数にサブスクリプション ID を指定することです。
詳細については、 Azure プロバイダーのリファレンス ドキュメントを参照してください。
Terraform を初期化する
terraform init
terraform init -upgrade
重要なポイント:
-
-upgrade
パラメーターは、必要なプロバイダー プラグインを、構成のバージョン制約に準拠する最新バージョンにアップグレードします。
Terraform実行計画を作成する
terraform プランを実行して実行プランを作成します。
terraform plan -out main.tfplan
重要なポイント:
-
terraform plan
コマンドは実行プランを作成しますが、実行はしません。 代わりに、それは設定ファイルで指定された設定を作成するために必要な手順を決定します。 このパターンを使用すると、実際のリソースに変更を加える前に、実行プランが期待と一致するかどうかを確認できます。 - 任意の
-out
パラメーターを使用すると、プランの出力ファイルを指定することができます。-out
パラメーターを使用すると、レビューしたプランがそのまま適用されることが保証されます。
Terraform 実行プランを適用する
terraform apply を実行して、実行プランをクラウド インフラストラクチャに適用します。
terraform apply main.tfplan
重要なポイント:
-
terraform apply
コマンドの例では、以前にterraform plan -out main.tfplan
を実行していることを前提としています。 -
-out
パラメーターに別のファイル名を指定した場合は、terraform apply
への呼び出しで同じファイル名を使用してください。 -
-out
パラメーターを使用しなかった場合は、パラメーターを指定せずにterraform apply
を呼び出します。
結果を確認してください。
Azure リソース グループ名を表示します。
terraform output -raw resource_group_name
必要に応じて、VM (仮想マシン) のパスワードを表示します。
terraform output -raw vm_password
パブリック IP アドレスを表示します。
terraform output -raw public_ip_address
そのパブリック IP アドレスを Web ブラウザーのアドレス バーに貼り付けます。 Nginx Web サーバーのカスタム VM ページがブラウザーに表示されます。
リソースをクリーンアップする
Terraform を使用して作成されたリソースが不要になったら、次の手順を実行します。
terraform プランを実行し、
destroy
フラグを指定します。terraform plan -destroy -out main.destroy.tfplan
重要なポイント:
-
terraform plan
コマンドは実行プランを作成しますが、実行はしません。 代わりに、それは設定ファイルで指定された設定を作成するために必要な手順を決定します。 このパターンを使用すると、実際のリソースに変更を加える前に、実行プランが期待と一致するかどうかを確認できます。 - 任意の
-out
パラメーターを使用すると、プランの出力ファイルを指定することができます。-out
パラメーターを使用すると、レビューしたプランがそのまま適用されることが保証されます。
-
terraform apply を実行して実行プランを適用します。
terraform apply main.destroy.tfplan
Azure での Terraform のトラブルシューティング
Azure で Terraform を使用するときの一般的な問題のトラブルシューティング