LoginSignup
1
0

More than 1 year has passed since last update.

【Terraform de Azure】 Ubuntu の VM を作成し SSH してみました

Last updated at Posted at 2022-01-24

概要

「Infrastructure as Code」ということで、Terraform を用いて Azure環境上に Ubuntu のVMを作成し、SSH接続してみます。 この記事は Windows10 ですが、今回は Linux を構築します。

ローカル環境

  • macOS Monterey 12.1
  • python 3.8.3
  • Azure CLI 2.28.0
  • terraform v1.0.11

前提条件

  1. Azure環境がすでに用意されていること(テナント/サブスクリプション)
  2. ローカル環境に「azure cli」がインストールされていること
  3. ローカル環境に「terraform」環境が構成されていること
  4. TerraformでAzure上に環境構築するためのサービスプリンシパルが作成されており、Terraform のためのローカル環境変数が定義されていること

事前準備

ローカル環境からインターネットアクセス時に自動割当されているグローバルアドレスの取得

## 利用グローバルアドレス
$ curl inet-ip.info
153.134.22.135

構築する仮想マシンのImage情報の取得

## Image
$ az vm image list --location japaneast --offer UbuntuServer --sku 18.04-LTS --all --output table

Offer         Publisher    Sku        Urn                                               Version
------------  -----------  ---------  ------------------------------------------------  ---------------
UbuntuServer  Canonical    18.04-LTS  Canonical:UbuntuServer:18.04-LTS:18.04.201804262  18.04.201804262
UbuntuServer  Canonical    18.04-LTS  Canonical:UbuntuServer:18.04-LTS:18.04.201805170  18.04.201805170
UbuntuServer  Canonical    18.04-LTS  Canonical:UbuntuServer:18.04-LTS:18.04.201805220  18.04.201805220
UbuntuServer  Canonical    18.04-LTS  Canonical:UbuntuServer:18.04-LTS:18.04.201806130  18.04.201806130
     :
    省略
     :
UbuntuServer  Canonical    18.04-LTS  Canonical:UbuntuServer:18.04-LTS:18.04.202111300  18.04.202111300
UbuntuServer  Canonical    18.04-LTS  Canonical:UbuntuServer:18.04-LTS:18.04.202112020  18.04.202112020
UbuntuServer  Canonical    18.04-LTS  Canonical:UbuntuServer:18.04-LTS:18.04.202201060  18.04.202201060
UbuntuServer  Canonical    18.04-LTS  Canonical:UbuntuServer:18.04-LTS:18.04.202201180  18.04.202201180

Terraform で Ubuntu の VM を作成してみる

terraform 定義ファイルの作成

プロバイダの定義

main.tf
# プロバイダーの定義
terraform {
  required_providers {
    azurerm =  "~> 2.33"
  }
}

provider "azurerm" {
  features {}
  tenant_id     = var.ARM_TENANT_ID
  client_id     = var.ARM_CLIENT_ID
  client_secret = var.ARM_CLIENT_SECRET
}


# リソースグループ
resource "azurerm_resource_group" "this" {
  name     = var.resource_group_name
  location = var.region
  tags     = var.tags_def
}

パラメータ定義ファイル

variables.tf
# 環境変数(Azureサービスプリンシパル)
variable ARM_TENANT_ID {}
variable ARM_CLIENT_ID {}
variable ARM_CLIENT_SECRET {}

# タグ情報
variable tags_def {
  default = {
    owner      = "ituru"
    period     = "2022-03-31"
    CostCenter = "PSG2"
    Environment = "Demo"
    Project = "DUP_IaC"
  }
}

# 各種パラメータ
variable region {}                  // 利用リージョン
variable resource_group_name {}     // リソースグループ名

variable vnet_name {}               // vNet名
variable vnet_address_space {}      // vNetアドレス範囲
variable subnet_name {}             // サブネット名
variable subnet_address {}          // サブネットアドレス
variable public_ip_name {}          // パブリックIP名
variable security_group_name {}     // セキュリティグループ名
variable network_interface_name {}  // ネットワーク・インターフェース名

variable vm_name {}                 // 仮想マシン名
variable vm_size {}                 // 仮想マシンサイズ
variable computer_name {}           // コンピュータ名
variable admin_username {}          // 管理者名

パラメータ値定義ファイル

terraform.tfvars
# 環境変数の定義(Azureサービスプリンシパル)
ARM_TENANT_ID       = "zzzzzzzz-cccc-4645-5757-zzzzzzzzzzzz"
ARM_CLIENT_ID       = "xxxxxxxx-xxxx-4444-9922-xxxxxxxxxxxx"
ARM_CLIENT_SECRET   = "hogehogehogehogehogehogehogehogege"

# パラメータ値の定義
region                  = "japaneast"           // 利用リージョン
resource_group_name     = "rg_ituru_vm02"       // リソースグループ名

vnet_name               = "vnet_ituru_vm02"     // vNet名
vnet_address_space      = "10.0.0.0/16"         // vNetアドレス範囲
subnet_name             = "snet_ituru_vm02"     // サブネット名
subnet_address          = "10.0.1.0/24"         // サブネットアドレス
public_ip_name          = "pip_ituru_vm02"      // パブリックIP名
security_group_name     = "nsg_ituru_vm02"      // セキュリティグループ名
network_interface_name  = "nic_ituru_vm02"      // ネットワーク・インターフェース名

vm_name                 = "vm-ituru-ubuntu"     // 仮想マシン名
vm_size                 = "Standard_D11_v2"     // 仮想マシンサイズ
computer_name           = "ubuntu1804"          // コンピュータ名
admin_username          = "nmcadmin"            // 管理者名

仮想マシン定義ファイル

computer.tf
# Linux(Ubuntu 18.04) 仮想マシン
resource "azurerm_linux_virtual_machine" "this" {
  name                  = var.vm_name
  location              = azurerm_resource_group.this.location
  resource_group_name   = azurerm_resource_group.this.name
  size                  = var.vm_size
  computer_name         = var.computer_name
  admin_username        = var.admin_username
  network_interface_ids = [
    azurerm_network_interface.this.id,
  ]

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

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  admin_ssh_key {
    username       = var.admin_username
    public_key     = tls_private_key.this.public_key_openssh
  }

  tags  = var.tags_def
}

# SSHキーの作成
resource "tls_private_key" "this" {
  algorithm = "RSA"
  rsa_bits = 4096
}

ネットワーク+セキュリティ定義ファイル

network.tf
// 仮想ネットワーク
resource "azurerm_virtual_network" "this" {
  name                = var.vnet_name
  address_space       = [var.vnet_address_space]
  location            = azurerm_resource_group.this.location
  resource_group_name = azurerm_resource_group.this.name
  tags                = var.tags_def
}

// サブネット
resource "azurerm_subnet" "internal" {
  name                  = var.subnet_name
  resource_group_name   = azurerm_resource_group.this.name
  virtual_network_name  = azurerm_virtual_network.this.name
  address_prefixes      = [var.subnet_address]
}

// パブリック IP アドレス
resource "azurerm_public_ip" "this" {
  name                = var.public_ip_name
  location            = azurerm_resource_group.this.location
  resource_group_name = azurerm_resource_group.this.name
  allocation_method   = "Dynamic"
  tags                = var.tags_def
}

// ネットワーク セキュリティ グループ
resource "azurerm_network_security_group" "this" {
  name                = var.security_group_name
  location            = azurerm_resource_group.this.location
  resource_group_name = azurerm_resource_group.this.name

  security_rule {
    name                       = "SSH"
    description                = "Allow SSH Access"
    priority                   = 1002
    direction                  = "Inbound"   
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "22"
    source_address_prefix      = "153.134.22.135/32"
    destination_address_prefix = "*"
  }

  tags  = var.tags_def
}

// ネットワーク インターフェイス
resource "azurerm_network_interface" "this" {
  name                = var.network_interface_name
  location            = azurerm_resource_group.this.location
  resource_group_name = azurerm_resource_group.this.name

  ip_configuration {
    name                          = "ipconfig"
    subnet_id                     = azurerm_subnet.internal.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.this.id
  }

  tags  = var.tags_def
}

// ネットワークインターフェースへのネットワークセキュリティグループの割当
resource "azurerm_network_interface_security_group_association" "this" {
    network_interface_id      = azurerm_network_interface.this.id
    network_security_group_id = azurerm_network_security_group.this.id
}

terraform の実行

## init
$ terraform init
    :
Terraform has been successfully initialized!

## plan
$ terraform plan
    :
Plan: 9 to add, 0 to change, 0 to destroy.

## apply
$ terraform apply
    :
Apply complete! Resources: 9 added, 0 changed, 0 destroyed.

Outputs:

admin_username = "nmcadmin"
public_ip_id = [
  "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_vm02/providers/Microsoft.Network/publicIPAddresses/pip_ituru_vm02",
]
tls_private_key = <sensitive>

ローカルの作業ディレクトの状況

$ tree -a
.
├── .terraform
│   └── providers
│       └── registry.terraform.io
│           └── hashicorp
│               ├── azurerm
│               │   └── 2.93.0
│               │       └── darwin_amd64
│               │           └── terraform-provider-azurerm_v2.93.0_x5
│               └── tls
│                   └── 3.1.0
│                       └── darwin_amd64
│                           └── terraform-provider-tls_v3.1.0_x5
├── .terraform.lock.hcl
├── compute.tf
├── main.tf
├── network.tf
├── outputs.tf
├── terraform.tfstate
├── terraform.tfstate.backup
├── terraform.tfvars
├── variables.tf
└── vm_ubuntu.pem

terraform 実行後の確認

リソースグループ の確認

$ az group show --name <Resource_Group_name>
{
  "id": "/subscriptions/xxxxxxxx-1717-dada-9779-zzzzzzzzzzzz/resourceGroups/rg_ituru_vm02",
  "location": "japaneast",
  "managedBy": null,
  "name": "rg_ituru_vm02",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": {
    "CostCenter": "PSG2",
    "Environment": "Demo",
    "Project": "DUP_IaC",
    "owner": "ituru",
    "period": "2022-03-31"
  },
  "type": "Microsoft.Resources/resourceGroups"
}

仮想マシン の確認

$ az vm list -g <Resource_Group_Name> -d --output table

Name             ResourceGroup    PowerState    PublicIps      Fqdns    Location    Zones
---------------  ---------------  ------------  -------------  -------  ----------  -------
vm-ituru-ubuntu  rg_ituru_vm02    VM running    20.188.24.42            japaneast

ネットワークセキュリティグループ の確認

$ az network nsg rule list -g <Resource_Group_Name> --nsg-name <Network_Security_Group_Namr> -o table

Name    ResourceGroup    Priority    SourcePortRanges    SourceAddressPrefixes    SourceASG    Access    Protocol    Direction    DestinationPortRanges    DestinationAddressPrefixes    DestinationASG
------  ---------------  ----------  ------------------  -----------------------  -----------  --------  ----------  -----------  -----------------------  ----------------------------  ----------------
SSH     rg_ituru_vm02    1002        *                   153.134.22.135/32        None         Allow     Tcp         Inbound      22                       *                             None

仮想マシンへの接続

グローバルアドレスの取得

$ az vm list-ip-addresses --resource-group <Resource_Group_Name> --name <VM_Name> --output table
VirtualMachine    PublicIPAddresses    PrivateIPAddresses
----------------  -------------------  --------------------
vm-ituru-ubuntu   20.188.24.42         10.0.1.4

秘密鍵の取得とパーミッションの変更

$ terraform output -raw tls_private_key > vm_ubuntu.pem
$ chmod 600 vm_ubuntu.pem

SSH接続

$ ssh -i vm_ubuntu.pem nmcadmin@20.188.24.42

The authenticity of host '20.188.24.42 (20.188.24.42)' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx64.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '20.188.24.42' (ED25519) to the list of known hosts.
Welcome to Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-1067-azure x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Mon Jan 24 09:05:02 UTC 2022

  System load:  0.0               Processes:           116
  Usage of /:   4.6% of 28.90GB   Users logged in:     0
  Memory usage: 1%                IP address for eth0: 10.0.1.4
  Swap usage:   0%

0 updates can be applied immediately.


The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

nmcadmin@ubuntu1804:~$ 

接続(ログイン)後の確認

## OSバージョン
nmcadmin@ubuntu1804:~$ uname -a
Linux ubuntu1804 5.4.0-1067-azure #70~18.04.1-Ubuntu SMP Thu Jan 13 19:46:01 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

## IPアドレス
nmcadmin@ubuntu1804:~$ ip add show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:22:48:e7:02:80 brd ff:ff:ff:ff:ff:ff
    inet 10.0.1.4/24 brd 10.0.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::222:48ff:fee7:280/64 scope link 
       valid_lft forever preferred_lft forever

## グローバルアドレス
nmcadmin@ubuntu1804:~$ curl ifconfig.me
20.188.24.42

terraform による作成したリソースの削除

$ terraform destroy

まとめ

これで、Terraform でサクッと Azure環境上に Ubuntu を構成し SSH接続 できました。 Azure Portal や Azure CLI で構築するのもいいですが、IaC化もいいですね。

参考記事

以下の記事を参考にさせていただきました。感謝申し上げます。
SSH公開鍵認証で接続するまで

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0