こんにちは、インフラエンジニアの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ポータルの上部の↓のアイコンをクリックすると起動できます。
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”ができていたら完成です。
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を入力します。
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の講座がいくつかあるので受講してみましょう!
以上で、記事を終わります!ありがとうございました。