Microsoft Azure

【Azure】IaCとは?リソースを自動で作成する

こんにちは、インフラエンジニアのryuです。

今回の記事では、AzureのリソースをIaCで作る方法を解説します。Terraformというツールを使い、LinuxのVMを作成します。インフラの設定をコードで書くことによって、サーバーの環境構築を自動化できます。

【Azure】IaCとは?リソースを自動で作成する

IaCって何・・・?

今回の記事では、AzureでIaCを実装する方法を解説します。

初心者の方に向けて、IaCとは何なのかから説明していきます。

IaCをすることによって、インフラ構築の工数を大幅に削減できます。理由は、自動化するからです。まずIaCが何なのかを説明します。

IaCとは?

まずは、IaCについての説明をします。Wikipediaでは次のように定義されております。

Infrastructure as Code(IaC) はコンピューティング・インフラ(プロセス、ベアメタルサーバー、仮想サーバーなど)の構成管理・機械処理可能な定義ファイルの設定・プロビジョニングを自動化するプロセスである。

(wikipediaより)

つまり、インフラの設定をファイルに書いておいて、それを基に自動でインフラを作ることです。

AzureでIaCを実装するために

AzureでIaCを実装するためには、いくつかの方法がありますが3つ紹介します。

  • Terraformを使用する
  • AzureARMテンプレートを使用する
  • PowerShellを使用する

Terraformは今回の記事で後ほど紹介しますが、インフラを自動で構築するオープンソースです。AWSなどその他のクラウドサービスでも使用することができます。

ARMテンプレートはAzure内のサービスで、インフラをテンプレートとして定義します。

今回の記事では、Terraformを使用してIaCを実施したいと思います。早速、Terraformのインストール方法から説明します。

IaCのツールをインストールする

IaCのツールはTerraformを使います。 Terraformのインストール方法については、Microsoftのドキュメントを参考にしてください。

https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/terraform-install-configure

ドキュメントの内容を簡単に説明します。

1. Azure Cloud Shell を起動

Terraformをローカル環境でもインストール可能ですが、Azure Cloud Shellを使うと、すでにTerraformがインストールされているので手順が省けます。

Azure Cloud ShellはAzureポータルの上部の↓のアイコンをクリックすると起動できます。

Azure Cloud Shellの作成

bashかpowershellの選択がありますが、bashで起動しておきましょう。

2.AzureADサービスプリンシパルの作成

サービス プリンシパルを作成することでTerraformがリソースを自動で作ってもいいよ!というアクセス許可を出します。

以下のコマンドを実行します。

az account list --query "[].{name:name, subscriptionId:id, tenantId:tenantId}"
az account set --subscription="${SUBSCRIPTION_ID}"
az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/${SUBSCRIPTION_ID}"

最後のコマンドでappIdとpasswordが返されるのでメモっておきます。

3.スクリプトを実行して初期設定

新しくディレクトリを作りカレントディレクトリを変えます。

もしくは、そのままのディレクトリでもよいです。

ドキュメントのサンプルコードをコピーしtest.tfを作ります。

test.tfがあるディレクトリで以下のコマンドを実行します。

terraform init

” Terraform has been successfully initialized! “と返されます。

エラーが出た場合は、test.tfが正しく作られているか確認してください。

エラーについては、こちらの記事を参照してください。

そして最後に、

terraform apply

を実行します。途中でリソースグループを作ってもよいですか?と聞かれるので「yes」と入力します。

これで完了です。

Azureリソースグループに、”testResourceGroup”ができていたら完成です。

Iacの準備

Terraformでコードからリソースを作成する。

ここからは、Terraformのテンプレートを作成してデプロイまでを解説します。

Azureリソースをコード化する

まず、テンプレートを作成しましょう。”terraform_azure.tf”というファイル名で以下の内容をコピペしてください。

# Configure the Microsoft Azure Provider
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.
    version = "~>2.0"
    features {}
}

# 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_prefixes       = ["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

    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"
    }
}

# Connect the security group to the network interface
resource "azurerm_network_interface_security_group_association" "example" {
    network_interface_id      = azurerm_network_interface.myterraformnic.id
    network_security_group_id = azurerm_network_security_group.myterraformnsg.id
}

# 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 (and display) an SSH key
resource "tls_private_key" "example_ssh" {
  algorithm = "RSA"
  rsa_bits = 4096
}
output "tls_private_key" { value = tls_private_key.example_ssh.private_key_pem }

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

    os_disk {
        name              = "myOsDisk"
        caching           = "ReadWrite"
        storage_account_type = "Premium_LRS"
    }

    source_image_reference {
        publisher = "Canonical"
        offer     = "UbuntuServer"
        sku       = "18.04-LTS"
        version   = "latest"
    }

    computer_name  = "myvm"
    admin_username = "azureuser"
    disable_password_authentication = true

    admin_ssh_key {
        username       = "azureuser"
        public_key     = tls_private_key.example_ssh.public_key_openssh
    }

    boot_diagnostics {
        storage_account_uri = azurerm_storage_account.mystorageaccount.primary_blob_endpoint
    }

    tags = {
        environment = "Terraform Demo"
    }
}

ここの内容がAzureリソースをコード化したものです。

provider “azurerm” { ……}のxxxxxxxxは自分のidを入力します。

IaCの準備方法

Terraformのコマンドを入力してAzureリソースをデプロイする

スクリプトが完成したら、先ほど作った”test.tf”を消して、以下のコマンドを入力してTerraformの環境を初期化します。

terraform init

次にテンプレートの検証です。

terraform plan

すると Plan:9 to add, 0 to change, 0 to destroy.

という文が返されます。特にエラーが出ていなければ、リソースを作成します。

terraform apply

よし!完成と思ったら・・・

Error: compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=400 — Original Error: Code=”InvalidParameter” Message=”The value of parameter linuxConfiguration.ssh.publicKeys.keyData is invalid.” Target=”linuxConfiguration.ssh.publicKeys.keyData”

こんなエラーがでしまいました。

SSHで使用する公開鍵でエラーがでていましたね。

とりあえず、エラーを解消するために公開鍵を作ります。

ssh-keygen -t rsa -b 2048

公開鍵の中身の見方は、

cat ~/.ssh/id_rsa.pub

これで表示されたものを、 terraform_azure.tf

key_data = “公開鍵”

の公開鍵の部分に貼り付けます。

これでもう一度、”terraform apply”を実行すると、

リソースを自動で作成

Apply complete!ようやく完成しました。

Azure内のリソースグループ内を確認すると、リソースが自動でつくられていることが分かります。

自動作成完了

さいごに

Terraformを使い、AzureのリソースをIaCで作る方法を解説していきました。 インフラをコードで作るIaCはインフラエンジニアとして覚えておきたい技術の1つです。今回はLinuxでしたが、ほかのリソースもIaCで作成できるので便利ですね!

また、Azureをさらに勉強したい方は、こちらの参考書がオススメです。

UdemyでもAzureの講座がいくつかあるので受講してみましょう!

以上で、記事を終わります!ありがとうございました。

ABOUT ME
ryu
大手メーカのIT部門でインフラエンジニアやってます。 サーバ、ネットワーク、セキュリティ、クラウドについて投稿します。 AI、ARも勉強中です! youtubeでも技術ネタを発信していきます。↓のアイコンよりご覧ください!