【Azure】使用Terraform在现有虚拟网络中添加虚拟机
如果有人告诉你要开始在Azure环境中进行配置管理,我认为下面的情况经常会出现,因为需要导入现有资源,所以步骤会稍微长一些。我们逐步进行。在本例中,我们正在创建一个新的Ubuntu 18.04虚拟机。
安装Azure CLI和Terraform
请参考之前的文章,了解如何安装Azure CLI和Terraform的步骤。
制作一把钥匙
我們將為虛擬機創建一把鑰匙,如果您要使用現有的鑰匙,則可以省略。
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/ubuntu/.ssh/id_rsa): /ubuntu/azureuser-key/id_rsa
Enter passphrase (empty for no passphrase): ※パスフレーズを入力※
Enter same passphrase again: ※パスフレーズを入力※
※出力は省略※
$ ls -l ~/azureuser-key
total 8
-rw------- 1 root root 1766 Oct 23 06:35 id_rsa
-rw-r--r-- 1 root root 403 Oct 23 06:35 id_rsa.pub
# cat ~/azureuser-key/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2Exxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ubuntu@localhost ※以降の手順でこの鍵を設定※
创建一个空的tf文件
最初可能会感到有些难以入手(个人意见),首先要创建一个空的tf文件。
provider "azurerm" {
}
resource "azurerm_resource_group" "tf_name_resource_group" {
}
resource "azurerm_virtual_network" "tf_name_vnet" {
}
resource "azurerm_subnet" "tf_name_subnet" {
}
resource "azurerm_network_security_group" "tf_name_network_security_group" {
}
resource "azurerm_network_interface" "tf_name_nic1" {
}
resource "azurerm_virtual_machine" "tf_name_vm1" {
}
要点:
-
- 最初の providerブロック(azurerm)は必須です。
-
- resource ブロックを必要な数だけ作成します。今回新規作成するのは下の2つ(“azurerm_network_interface”と”azurerm_virtual_machine”)だけですが、関連するリソースは既存のものであっても全て追加しておく必要があります。といっても最初に完全なリストは分からないことは多いと思いますので、その場合はTerraformのドキュメント ( VMであれば https://www.terraform.io/docs/providers/azurerm/r/virtual_machine.html ) の例にあるものを追加しておき、後の手順内で追加していきます。今回の例ではリソースグループ、VNet、サブネットに加えてセキュリティグループが必要になることが分かっているので、あらかじめ追加しています。
-
- resource ブロックの3項目目はリソースローカル名で、tfファイル名でリソースを参照するための名前です。サンプルでは “main”とか”default”とかになっていますが、複数作成するとすぐに分かりづらくなるので、最初から命名規則を決めてきちんとした名前を付けた方がいいです。
- 実際に作成されるリソースの名前はname属性で指定します(後の手順で追記します)。
2) 执行 terraform init
先执行一次init命令。如果收到正常结束的消息,就可以了。
$ terraform init
Initializing the backend...
※途中省略※
Terraform has been successfully initialized!
※途中省略※
执行terraform import命令,并补充资源块。
关于现有资源,
-
- terraform importコマンドでインポート処理を実行
- resource ブロック内に情報を追記
需要根据上述情况进行相应的操作。虽然重复了相似的步骤,但以下是执行示例。
资源组
确认资源ID后,使用terraform import命令执行导入操作。
### az groupコマンドでリソースグループのidを確認
### az group show --name <リソースグループ名>
$ az group show --name resource_group_test | jq -r '.id'
/subscriptions/65b7e404-xxxxxxxxxxxxxxxxxxx/resourceGroups/resource_group_test
### idを指定してimport
### terraform import azurerm_resource_group.<リソースローカル名> <リソースグループid>
$ terraform import azurerm_resource_group.tf_name_resource_group /subscriptions/65b7e404-xxxxxxxxxxxxxxxxxxx/resourceGroups/resource_group_test
※途中省略※
Import successful!
※途中省略※
根据Terraform文档 (https://www.terraform.io/docs/providers/azurerm/r/resource_group.html),在resource块中添加信息。尽管最终需要设置足够的项目,但是直接手动完成非常困难,所以在此添加了必需的项目(稍后可以通过terraform plan命令检测到)。
resource "azurerm_resource_group" "tf_name_resource_group" {
name = "resource_group_test"
location = "Japan East"
}
虚拟网络
确认资源ID后,使用terraform import命令执行导入操作。
### az networkコマンドで仮想ネットワークのidを確認
### az network vnet show --name <仮想ネットワーク名> --resource-group <リソースグループ名>
$ az network vnet show --name vnet_test --resource-group resource_group_test | jq -r '.id'
/subscriptions/65b7e404-xxxxxxxxxxxxxxxxxxx/resourceGroups/resource_group_test/providers/Microsoft.Network/virtualNetworks/vnet_test
### idを指定してimport
### terraform import azurerm_virtual_network.<リソースローカル名> <リソースグループid>
$ terraform import azurerm_virtual_network.tf_name_vnet /subscriptions/65b7e404-xxxxxxxxxxxxxxxxxxx/resourceGroups/resource_group_test/providers/Microsoft.Network/virtualNetworks/vnet_test
※途中省略※
Import successful!
※途中省略※
参考teraform文档(https://www.terraform.io/docs/providers/azurerm/r/virtual_network.html),在资源块中添加信息。
resource "azurerm_virtual_network" "tf_name_vnet" {
name = "vnet_test"
address_space = ["10.10.0.0/16"]
location = "Japan East"
resource_group_name = "${azurerm_resource_group.tf_name_resource_group.name}"
}
子网
确认资源ID后,使用terraform import命令执行导入操作。
### az networkコマンドでサブネットのidを確認
### az network vnet show --name <仮想ネットワーク名> --resource-group <リソースグループ名>
### ※サブネット自体を取得するコマンドが無いため、vnetコマンド結果のsubnet属性で確認します。サブネットのリストが出るので対象サブネットのidを選択して下さい。
$ az network vnet show --name vnet_test --resource-group resource_group_test | jq -r '.subnets[] | [.name, .id]'
[
"subnet_test",
"/subscriptions/65b7e404-xxxxxxxxxxxxxxxxxxx/resourceGroups/resource_group_test /providers/Microsoft.Network/virtualNetworks/vnet_test/subnets/subnet_test"
]
### idを指定してimport
### terraform import azurerm_subnet.<リソースローカル名> <リソースグループid>
$ terraform import azurerm_subnet.tf_name_subnet /subscriptions/65b7e404-xxxxxxxxxxxxxxxxxxx/resourceGroups/resource_group_test /providers/Microsoft.Network/virtualNetworks/vnet_test/subnets/subnet_test
※途中省略※
Import successful!
※途中省略※
参考我们的Terraform文档(https://www.terraform.io/docs/providers/azurerm/r/subnet.html),在资源块内添加信息。
resource "azurerm_subnet" "tf_name_subnet" {
name = "subnet_test"
resource_group_name = "${azurerm_resource_group.tf_name_resource_group.name}"
virtual_network_name = "${azurerm_virtual_network.tf_name_vnet.name}"
address_prefix = "10.10.0.0/24"
}
安全组
确认资源ID后,执行terraform import命令来进行导入处理。
### az networkコマンドでセキュリティグループのidを確認
### az network nsg show --name <セキュリティグループ名> --resource-group <リソースグループ名>
$ az network nsg show --name nsg_test --resource-group resource_group_test | jq -r '.id'
/subscriptions/65b7e404-xxxxxxxxxxxxxxxxxxx/resourceGroups/resource_group_test /providers/Microsoft.Network/networkSecurityGroups/nsg_test
### idを指定してimport
### terraform import azurerm_network_security_group.<リソースローカル名> <リソースグループid>
$ terraform import azurerm_network_security_group.tf_name_network_security_group /subscriptions/65b7e404-xxxxxxxxxxxxxxxxxxx/resourceGroups/resource_group_test/providers/Microsoft.Network/networkSecurityGroups/nsg-test
※途中省略※
Import successful!
※途中省略※
参照terraform文档(https://www.terraform.io/docs/providers/azurerm/r/network_security_group.html),将信息添加到resource块内。
resource "azurerm_network_security_group" "tf_name_network_security_group" {
name = "nsg_test"
location = "Japan East"
resource_group_name = "${azurerm_resource_group.tf_name_resource_group.name}"
security_rule {
name = "allow_ssh_any"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
4) 写下要创建的资源的资源块
与现有资源类似,参考Terraform文档(https://www.terraform.io/docs/providers/azurerm/r/virtual_network.html),在资源块内追加信息。
resource "azurerm_network_interface" "tf_name_nic1" {
name = "nic-test-vm1"
location = "Japan East"
resource_group_name = "${azurerm_resource_group.tf_name_resource_group.name}"
ip_configuration {
name = "testvm1configuration1"
subnet_id = "${azurerm_subnet.tf_name_subnet.id}"
private_ip_address_allocation = "Static"
private_ip_address = "10.10.0.5"
}
}
resource "azurerm_virtual_machine" "tf_name_vm1" {
name = "vm-test1"
location = "Japan East"
resource_group_name = "${azurerm_resource_group.tf_name_resource_group.name}"
network_interface_ids = ["${azurerm_network_interface.tf_name_nic1.id}"]
vm_size = "Standard_DS2_v2"
delete_os_disk_on_termination = true
delete_data_disks_on_termination = true
storage_image_reference {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "18.04-LTS"
version = "latest"
}
storage_os_disk {
name = "testvm1osdisk1"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
os_profile {
computer_name = "vm-test1"
admin_username = "azureuser"
}
os_profile_linux_config {
disable_password_authentication = true
ssh_keys {
path = "/home/azureuser/.ssh/authorized_keys"
key_data = "${file("/ubuntu/azureuser-key/id_rsa.pub")}"
}
}
}
5) 执行 terraform plan
执行terraform plan命令,如果出现错误,则修正tf文件。
在这里期望的结果是仅显示创建(计划中)两个资源的状态。
$ terraform plan
※途中省略※
Plan: 2 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
如果出现错误或者显示资源变更(计划),请查看消息并进行修正。例如,
※途中省略※
name = "subnet_test"
resource_group_name = "resource_group_test"
~ service_endpoints = [
- "Microsoft.Storage",
- "Microsoft.ContainerRegistry",
]
virtual_network_name = "vent_test"
}
Plan: 2 to add, 1 to change, 0 to destroy.
※途中省略※
由于虚拟网络已设置了服务端点,因此需要进行更改(删除端点)。请参考文档,在tf文件(azurerm_subnet块内)中添加设置。
service_endpoints = ["Microsoft.Storage", "Microsoft.ContainerRegistry"]
如果有其他相关资源被创建,可能还需要添加资源块本身。在这种情况下,请按照步骤3)的方式进行操作。
执行terraform apply
当 plan 命令的结果没问题后,执行 terraform apply。
$ terraform apply
※途中省略※
Plan: 2 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes ※"yes"を入力
※途中省略※
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
申请已完成!一旦出现“申请完成”的消息,请在门户或其他平台上确认结果。
链接 jiē)
-
- Terraform docs : Resources
-
- Terraform docs : resource_group
-
- Terraform docs : virtual_network
-
- Terraform docs : subnet
-
- Terraform docs : azurerm_network_security_group
- Terraform docs : azurerm_virtual_machine