Terraform によって Azure に完全な Linux 仮想マシンのインフラストラクチャを作成するCreate a complete Linux virtual machine infrastructure in Azure with Terraform

Terraform を利用すれば、Azure で完全なインフラストラクチャ デプロイを定義し、作成できます。Terraform allows you to define and create complete infrastructure deployments in Azure. 整合性があり、再現可能な方法で Azure リソースを作成し、構成する Terraform テンプレートを人間が読める形式でビルドします。You build Terraform templates in a human-readable format that create and configure Azure resources in a consistent, reproducible manner. この記事では、Terraform を使用して、完全な Linux 環境とサポート リソースを作成する方法を示します。This article shows you how to create a complete Linux environment and supporting resources with Terraform. Terraform をインストールし、構成する方法についても説明します。You can also learn how to Install and configure Terraform.

Azure 接続とリソース グループを作成するCreate Azure connection and resource group

それでは、Terraform テンプレートの各セクションに進みましょう。Let's go through each section of a Terraform template. Terraform テンプレートの完全版も表示できます。それをコピーし、貼り付けることができます。You can also see the full version of the Terraform template that you can copy and paste.

provider セクションは、Azure プロバイダーを使用するように Terraform に伝えます。The provider section tells Terraform to use an Azure provider. subscription_idclient_idclient_secrettenant_id の値を取得する方法については、Terraform のインストールと構成に関するページを参照してください。To get values for subscription_id, client_id, client_secret, and tenant_id, see Install and configure Terraform.

ヒント

これらの値の環境変数を作成する場合や、Azure Cloud Shell Bash エクスペリエンスを使用している場合は、このセクションに変数の宣言を含める必要はありません。If you create environment variables for the values or are using the Azure Cloud Shell Bash experience , you don't need to include the variable declarations in this section.

provider "azurerm" {
    subscription_id = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    client_id       = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    client_secret   = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    tenant_id       = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

次のセクションでは、myResourceGroup という名前のリソース グループを eastus という場所に作成します。The following section creates a resource group named myResourceGroup in the eastus location:

resource "azurerm_resource_group" "myterraformgroup" {
    name     = "myResourceGroup"
    location = "eastus"

    tags = {
        environment = "Terraform Demo"
    }
}

追加のセクションでは、 ${azurerm_resource_group.myterraformgroup.name} でリソース グループを参照します。In additional sections, you reference the resource group with ${azurerm_resource_group.myterraformgroup.name}.

Create virtual networkCreate virtual network

次のセクションでは、10.0.0.0/16 アドレス空間に、myVnet という名前の仮想ネットワークを作成しています。The following section creates a virtual network named myVnet in the 10.0.0.0/16 address space:

resource "azurerm_virtual_network" "myterraformnetwork" {
    name                = "myVnet"
    address_space       = ["10.0.0.0/16"]
    location            = "eastus"
    resource_group_name = azurerm_resource_group.myterraformgroup.name

    tags = {
        environment = "Terraform Demo"
    }
}

次のセクションでは、myVnet 仮想ネットワークに mySubnet という名前のサブネットを作成します。The following section creates a subnet named mySubnet in the myVnet virtual network:

resource "azurerm_subnet" "myterraformsubnet" {
    name                 = "mySubnet"
    resource_group_name  = azurerm_resource_group.myterraformgroup.name
    virtual_network_name = azurerm_virtual_network.myterraformnetwork.name
    address_prefix       = "10.0.2.0/24"
}

パブリック IP アドレスの作成Create public IP address

インターネット経由でリソースにアクセスするには、パブリック IP アドレスを作成して、VM に割り当てます。To access resources across the Internet, create and assign a public IP address to your VM. 次のセクションでは、myPublicIP という名前のパブリック IP アドレスを作成します。The following section creates a public IP address named myPublicIP:

resource "azurerm_public_ip" "myterraformpublicip" {
    name                         = "myPublicIP"
    location                     = "eastus"
    resource_group_name          = azurerm_resource_group.myterraformgroup.name
    allocation_method            = "Dynamic"

    tags = {
        environment = "Terraform Demo"
    }
}

ネットワーク セキュリティ グループの作成Create Network Security Group

ネットワーク セキュリティ グループは、VM から送受信されるネットワーク トラフィック フローを制御します。Network Security Groups control the flow of network traffic in and out of your VM. 次のセクションでは、myNetworkSecurityGroup という名前のネットワーク セキュリティ グループを作成して、TCP ポート 22 で SSH トラフィックを許可するルールを定義しています。The following section creates a network security group named myNetworkSecurityGroup and defines a rule to allow SSH traffic on TCP port 22:

resource "azurerm_network_security_group" "myterraformnsg" {
    name                = "myNetworkSecurityGroup"
    location            = "eastus"
    resource_group_name = azurerm_resource_group.myterraformgroup.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"
    }
}

仮想ネットワーク インターフェイス カードの作成Create virtual network interface card

仮想ネットワーク インターフェイス カード (NIC) は、VM を特定の仮想ネットワーク、パブリック IP アドレス、およびネットワーク セキュリティ グループに接続します。A virtual network interface card (NIC) connects your VM to a given virtual network, public IP address, and network security group. Terraform テンプレートの次のセクションでは、作成した仮想ネットワーク リソースに接続された myNIC という名前の仮想 NIC を作成しています。The following section in a Terraform template creates a virtual NIC named myNIC connected to the virtual networking resources you have created:

resource "azurerm_network_interface" "myterraformnic" {
    name                        = "myNIC"
    location                    = "eastus"
    resource_group_name         = azurerm_resource_group.myterraformgroup.name
    network_security_group_id   = azurerm_network_security_group.myterraformnsg.id

    ip_configuration {
        name                          = "myNicConfiguration"
        subnet_id                     = "${azurerm_subnet.myterraformsubnet.id}"
        private_ip_address_allocation = "Dynamic"
        public_ip_address_id          = "${azurerm_public_ip.myterraformpublicip.id}"
    }

    tags = {
        environment = "Terraform Demo"
    }
}

診断のためのストレージ アカウントを作成するCreate storage account for diagnostics

VM のブート診断を格納するには、ストレージ アカウントを作成する必要があります。To store boot diagnostics for a VM, you need a storage account. このブート診断は、問題の解決や VM 状態の監視に役立ちます。These boot diagnostics can help you troubleshoot problems and monitor the status of your VM. ここでは、ブート診断データを保存するためだけにストレージ アカウントを作成します。The storage account you create is only to store the boot diagnostics data. ストレージ アカウントごとに一意の名前を使用する必要があるため、次のセクションはランダム テキストを生成します。As each storage account must have a unique name, the following section generates some random text:

resource "random_id" "randomId" {
    keepers = {
        # Generate a new ID only when a new resource group is defined
        resource_group = azurerm_resource_group.myterraformgroup.name
    }
    
    byte_length = 8
}

これでストレージ アカウントを作成できます。Now you can create a storage account. 次のセクションはストレージ アカウントを作成します。前の手順で生成されたランダム テキストに基づく名前が使用されます。The following section creates a storage account, with the name based on the random text generated in the preceding step:

resource "azurerm_storage_account" "mystorageaccount" {
    name                        = "diag${random_id.randomId.hex}"
    resource_group_name         = azurerm_resource_group.myterraformgroup.name
    location                    = "eastus"
    account_replication_type    = "LRS"
    account_tier                = "Standard"

    tags = {
        environment = "Terraform Demo"
    }
}

仮想マシンの作成Create virtual machine

最後の手順は、VM を作成し、作成したすべてのリソースを使用することです。The final step is to create a VM and use all the resources created. 次のセクションでは、myVM という名前の VM を作成し、myNIC という名前の仮想 NIC を接続しています。The following section creates a VM named myVM and attaches the virtual NIC named myNIC. 最新の Ubuntu 16.04-LTS イメージが使用されます。azureuser という名前のユーザーが作成されます。その際、パスワード認証は無効になります。The latest Ubuntu 16.04-LTS image is used, and a user named azureuser is created with password authentication disabled.

SSH キー データは ssh_keys セクションで与えられます。SSH key data is provided in the ssh_keys section. key_data フィールドに有効な SSH 公開キーを与えます。Provide a valid public SSH key in the key_data field.

resource "azurerm_virtual_machine" "myterraformvm" {
    name                  = "myVM"
    location              = "eastus"
    resource_group_name   = azurerm_resource_group.myterraformgroup.name
    network_interface_ids = [azurerm_network_interface.myterraformnic.id]
    vm_size               = "Standard_DS1_v2"

    storage_os_disk {
        name              = "myOsDisk"
        caching           = "ReadWrite"
        create_option     = "FromImage"
        managed_disk_type = "Premium_LRS"
    }

    storage_image_reference {
        publisher = "Canonical"
        offer     = "UbuntuServer"
        sku       = "16.04.0-LTS"
        version   = "latest"
    }

    os_profile {
        computer_name  = "myvm"
        admin_username = "azureuser"
    }

    os_profile_linux_config {
        disable_password_authentication = true
        ssh_keys {
            path     = "/home/azureuser/.ssh/authorized_keys"
            key_data = "ssh-rsa AAAAB3Nz{snip}hwhqT9h"
        }
    }

    boot_diagnostics {
        enabled     = "true"
        storage_uri = azurerm_storage_account.mystorageaccount.primary_blob_endpoint
    }

    tags = {
        environment = "Terraform Demo"
    }
}

完全な Terraform スクリプトComplete Terraform script

以上のセクションをまとめ、Terraform の動作を確認するには、terraform_azure.tf という名前のファイルを作成し、次のコンテンツを貼り付けます。To bring all these sections together and see Terraform in action, create a file called terraform_azure.tf and paste the following content:

# Configure the Microsoft Azure Provider
provider "azurerm" {
    subscription_id = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    client_id       = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    client_secret   = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    tenant_id       = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

# Create a resource group if it doesn’t exist
resource "azurerm_resource_group" "myterraformgroup" {
    name     = "myResourceGroup"
    location = "eastus"

    tags = {
        environment = "Terraform Demo"
    }
}

# Create virtual network
resource "azurerm_virtual_network" "myterraformnetwork" {
    name                = "myVnet"
    address_space       = ["10.0.0.0/16"]
    location            = "eastus"
    resource_group_name = azurerm_resource_group.myterraformgroup.name

    tags = {
        environment = "Terraform Demo"
    }
}

# Create subnet
resource "azurerm_subnet" "myterraformsubnet" {
    name                 = "mySubnet"
    resource_group_name  = azurerm_resource_group.myterraformgroup.name
    virtual_network_name = azurerm_virtual_network.myterraformnetwork.name
    address_prefix       = "10.0.1.0/24"
}

# Create public IPs
resource "azurerm_public_ip" "myterraformpublicip" {
    name                         = "myPublicIP"
    location                     = "eastus"
    resource_group_name          = azurerm_resource_group.myterraformgroup.name
    allocation_method            = "Dynamic"

    tags = {
        environment = "Terraform Demo"
    }
}

# Create Network Security Group and rule
resource "azurerm_network_security_group" "myterraformnsg" {
    name                = "myNetworkSecurityGroup"
    location            = "eastus"
    resource_group_name = azurerm_resource_group.myterraformgroup.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"
    }
}

# Create network interface
resource "azurerm_network_interface" "myterraformnic" {
    name                      = "myNIC"
    location                  = "eastus"
    resource_group_name       = azurerm_resource_group.myterraformgroup.name
    network_security_group_id = azurerm_network_security_group.myterraformnsg.id

    ip_configuration {
        name                          = "myNicConfiguration"
        subnet_id                     = azurerm_subnet.myterraformsubnet.id
        private_ip_address_allocation = "Dynamic"
        public_ip_address_id          = azurerm_public_ip.myterraformpublicip.id
    }

    tags = {
        environment = "Terraform Demo"
    }
}

# Generate random text for a unique storage account name
resource "random_id" "randomId" {
    keepers = {
        # Generate a new ID only when a new resource group is defined
        resource_group = azurerm_resource_group.myterraformgroup.name
    }
    
    byte_length = 8
}

# Create storage account for boot diagnostics
resource "azurerm_storage_account" "mystorageaccount" {
    name                        = "diag${random_id.randomId.hex}"
    resource_group_name         = azurerm_resource_group.myterraformgroup.name
    location                    = "eastus"
    account_tier                = "Standard"
    account_replication_type    = "LRS"

    tags = {
        environment = "Terraform Demo"
    }
}

# Create virtual machine
resource "azurerm_virtual_machine" "myterraformvm" {
    name                  = "myVM"
    location              = "eastus"
    resource_group_name   = azurerm_resource_group.myterraformgroup.name
    network_interface_ids = [azurerm_network_interface.myterraformnic.id]
    vm_size               = "Standard_DS1_v2"

    storage_os_disk {
        name              = "myOsDisk"
        caching           = "ReadWrite"
        create_option     = "FromImage"
        managed_disk_type = "Premium_LRS"
    }

    storage_image_reference {
        publisher = "Canonical"
        offer     = "UbuntuServer"
        sku       = "16.04.0-LTS"
        version   = "latest"
    }

    os_profile {
        computer_name  = "myvm"
        admin_username = "azureuser"
    }

    os_profile_linux_config {
        disable_password_authentication = true
        ssh_keys {
            path     = "/home/azureuser/.ssh/authorized_keys"
            key_data = "ssh-rsa AAAAB3Nz{snip}hwhqT9h"
        }
    }

    boot_diagnostics {
        enabled = "true"
        storage_uri = azurerm_storage_account.mystorageaccount.primary_blob_endpoint
    }

    tags = {
        environment = "Terraform Demo"
    }
}

インフラストラクチャをビルドし、デプロイするBuild and deploy the infrastructure

Terraform テンプレートが作成されたら、最初に Terraform を初期化します。With your Terraform template created, the first step is to initialize Terraform. これによって、Azure でテンプレートをビルドするためのあらゆる前提条件が Terraform に与えられます。This step ensures that Terraform has all the prerequisites to build your template in Azure.

terraform init

次に、Terraform にテンプレートを検証させます。The next step is to have Terraform review and validate the template. この手順では、要求されたリソースが Terraform によって保存された状態情報と比較され、予定されている実行が出力されます。This step compares the requested resources to the state information saved by Terraform and then outputs the planned execution. リソースは Azure では作成されませんResources are not created in Azure.

terraform plan

上記のコマンドを実行すると、次のような画面が表示されます。After you execute the previous command, you should see something like the following screen:

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


...

Note: You didn’t specify an “-out” parameter to save this plan, so when
“apply” is called, Terraform can’t guarantee this is what will execute.
  + azurerm_resource_group.myterraform
      <snip>
  + azurerm_virtual_network.myterraformnetwork
      <snip>
  + azurerm_network_interface.myterraformnic
      <snip>
  + azurerm_network_security_group.myterraformnsg
      <snip>
  + azurerm_public_ip.myterraformpublicip
      <snip>
  + azurerm_subnet.myterraformsubnet
      <snip>
  + azurerm_virtual_machine.myterraformvm
      <snip>
Plan: 7 to add, 0 to change, 0 to destroy.

すべてが正しく思われ、Azure でインフラストラクチャをビルドする準備ができていれば、Terraform でテンプレートを適用します。If everything looks correct and you are ready to build the infrastructure in Azure, apply the template in Terraform:

terraform apply

Terraform が完了すると、VM インフラストラクチャが準備完了となります。Once Terraform completes, your VM infrastructure is ready. az vm show で VM のパブリック IP アドレスを取得します。Obtain the public IP address of your VM with az vm show:

az vm show --resource-group myResourceGroup --name myVM -d --query [publicIps] --o tsv

VM に SSH 接続できます。You can then SSH to your VM:

ssh azureuser@<publicIps>

次の手順Next steps

Terraform を使用して、Azure に基本的なインフラストラクチャを作成しました。You have created basic infrastructure in Azure by using Terraform. さらに複雑なシナリオ (ロード バランサーや仮想マシン スケール セットを使用する例など) については、Azure を対象とした Terraform の例を参照してください。For more complex scenarios, including examples that use load balancers and virtual machine scale sets, see numerous Terraform examples for Azure. サポートされている Azure プロバイダーの最新の一覧については、Terraform のドキュメントを参照してください。For an up-to-date list of supported Azure providers, see the Terraform documentation.