TerrafromでBastionとAzure Fliesを構成してブラウザからVMにアクセスする環境を整える
はじめに
この記事では、Terraformを使ってAzureにBastionとAzure Filesを作成する方法を紹介します。本記事は以下の人を対象にしています。
- AzureでのBastion構成方法を知りたい人
- Azure Filesでファイル共有を構成したい人
- TerraformでAzureにリソース作成をしたい人
リソースの説明
まず、BastionとAzure Filesについて簡単に説明します。
Bastionとは
BastionはAzureが提供するフルマネージド踏み台サーバサービスです。Bastionを使うことで、ブラウザから安全なRDP/SSH接続ができます。仮想マシンに接続する場合は踏み台サーバを用意して、RDP接続を構成する方法がありますが、bastionではパブリックIPを仮想マシンに追加しなくてよいので、簡単に安全な接続構成を作成できます。
Standard以上のSKUを使えば、ネイティブクライアントの機能で直接ファイルのコピー&ペーストができますが、Basicでは使えないので、ファイルのコピー&ペーストはAzure Filesを使います。
Azure Filesとは
Azure FilesはAzureが提供するフルマネージドファイル共有サービスです。ストレージアカウント内にファイル共有を作成して、仮想マシンに共有ファイルを追加することで、仮想マシンで作成したファイルなどをAzureにダウンロードしたり、Azureから仮想マシンにアップロードしたりできます。
作成するリソース
Terraformで以下のリソースを作成します。
- リソースグループ
- 仮想ネットワーク
- サブネット(Bastion用サブネットも作成)
- Bastion用パブリックIPアドレス
- Bastion
- ストレージアカウント
- ファイル共有
- ネットワークインターフェース
- 仮想マシン
コード
以下のコードをprovider.tfとmain.tfにそれぞれ記述します。
terraform {
required_version = ">=1.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>4.0"
}
}
}
provider "azurerm" {
# ここに作成先のサブスクリプションIDを入力
subscription_id = "12345678-aaaa-bbbb-cccc-123456789012"
features {
}
}
# リソースグループ
resource "azurerm_resource_group" "sample_rg" {
name = "sample-tf-rg"
location = "japaneast"
}
# 仮想ネットワーク
resource "azurerm_virtual_network" "sample_vnet" {
name = "sample-vnet"
location = azurerm_resource_group.sample_rg.location
resource_group_name = azurerm_resource_group.sample_rg.name
address_space = [ "10.110.0.0/17" ]
}
# サブネット
resource "azurerm_subnet" "sample_subnet" {
name = "sample-subnet"
resource_group_name = azurerm_resource_group.sample_rg.name
virtual_network_name = azurerm_virtual_network.sample_vnet.name
address_space = [ "10.110.11.0/24" ]
service_endpoints = [ "Microsoft.Storage" ]
}
# サブネット(Bastion用)
resource "azurerm_subnet" "sample_bastion_subnet" {
name = "AzureBastionSubnet"
resource_group_name = azurerm_resource_group.sample_rg.name
virtual_network_name = azurerm_virtual_network.sample_vnet.name
address_space = [ "10.110.10.192/26" ]
}
# パブリックIPアドレス(Bastion用)
resource "azurerm_public_ip" "sample_bastion_pip" {
name = "sample-bastion-pip"
location = azurerm_resource_group.sample_rg.location
resource_group_name = azurerm_resource_group.sample_rg.name
allocation_method = "Static"
}
# Bastion
resource "azurerm_bastion_host" "bastion" {
name = "sample-bastion"
location = azurerm_resource_group.sample_rg.location
resource_group_name = azurerm_resource_group.sample_rg.name
sku = "Basic"
ip_configuration {
name = "config"
subnet_id = azurerm_subnet.sample_bastion_subnet.id
public_ip_address_id = azurerm_public_ip.sample_bastion_pip.id
}
}
# ストレージアカウント
resource "azurerm_storage_account" "sample_sa" {
name = "azurefiles3675"
location = azurerm_resource_group.sample_rg.location
resource_group_name = azurerm_resource_group.sample_rg.name
account_tier = "Standard"
account_replication_type = "LRS"
network_rules {
default_action = "Deny"
# 自分のIPアドレスを入れる
ip_rules = [ "100.123.123.250" ]
virtual_network_subnet_ids = [ azurerm_subnet.sample_subnet.id ]
}
}
# ファイル共有
resource "azurerm_storage_share" "files" {
name = "fileshare"
storage_account_id = azurerm_storage_account.sample_sa.id
quota = 5
}
# ネットワークインターフェース
resource "azurerm_network_interface" "sample_nic" {
name = "sample-nic"
resource_group_name = azurerm_resource_group.sample_rg.name
location = azurerm_resource_group.sample_rg.location
ip_congiguration {
name = "ipconfig"
private_ip_address_allocation = "Static"
subnet_id = azurerm_subnet.sample_subnet.id
private_ip_address = "10.110.11.12"
}
}
# 仮想マシン
resource "azurerm_windows_virtual_machine" "sample_vm" {
name = "sample-vm"
resource_group_name = azurerm_resource_group.sample_rg.name
location = azurerm_resource_group.sample_rg.location
size = "Standard_D2s_v5"
admin_username = "localadmin"
admin_password = "Pass378Zenn!"
network_interface_ids = [ azurerm_network_interface.sample_nic.id ]
os_disk {
name = "sample-OS-Disk"
caching = "ReadWrite"
storage_account_type = "Premium_LRS"
}
source_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2025-Datacenter"
version = "latest"
}
}
自分のIPアドレスは、例えば以下のサイトから確認できます。
また、サブネットのサービスエンドポイントに"Microsoft.Storage"を追加するのを忘れずに!コードの実行
以下のコマンドをPowerShellから実行して、Azureにリソースを作成します。こちらの記事も参考に。
- Terraformの初期化を実行
terraform init -upgrade
- リソース作成の計画を作成
terraform plan -out main.tfplan
- リソース作成の適用
terraform apply main.tfplan
Bastion作成の注意点
Bastionの作成は約10分ほどかかります。Terraformではリソースの作成順序は自動で決まり、並列でリソースを作成してくれるので、Bastionを作成している間は仮想マシンを作ってくれないのでは?などと心配する必要はありません。(Bastionは最後のほうに作成される)
ただし、Bastionは高価なサービスで、Basicで作成しても1日で約700円ほどかかります。料金は以下を参考。
そこで、料金を抑えたい場合はこまめに削除する必要があります。Terraformで特定のリソースのみを作成/削除したい場合はplan時にtargetオプションを使います。今回のようにBastionだけ削除したい場合は以下のコマンドでplanを実行します。terraform plan -destroy -out main.destroy.tfplan -target="azurerm_bastion_host.bastion"
上のコマンドを実行すると「targetは通常時は使わないでください」という旨の警告が表示されますが、そのままapplyを実行してOKです。パブリックIPも存在するだけで課金対象なので、同じように削除しておくとよいでしょう。
仮想マシンにファイル共有を追加する
Terraformでファイル共有を作成することはできても、仮想マシンにファイル共有を追加する作業はTerraformの範囲外です。この記事では詳細の手順は省略しますが、以下の公式ドキュメントなどを参考に設定まで実施しましょう。
ざっくりな手順としては、
- Azure Portalからスクリプトをコピーする
- 設定先VMに接続
- PowerShellを開いてコピーしたスクリプトを実行する
このステップで設定できます。
うまくいかない場合はネットワークやサービスエンドポイントなどの設定が正しいか確認しましょう。
おわりに
最後までご覧いただきありがとうございます!この記事では、Terraformを使って、BastionとAzure Filesを作成する手順を紹介しました。今後、仮想マシン以外の関数アプリなどの設定方法も紹介しようと考えています。
Discussion