Terraform(全称:Hashicorp Terraform )是一种开源工具,用于预配和管理云基础结构。 它将基础结构编入描述云资源拓扑的配置文件中。 这些资源包括虚拟机、存储帐户和网络接口等。

本文介绍在Windows系统中,如何安装Terraform,并且根据Azure的示例模板创建,在中国区创建一个虚拟机(VM)的入门级教程。

安装Terraform

Terraform的Windows版本为一个.exe文件,下载后把放置在自定义的文件夹中,最后配置号系统的PATH即可。

  • 下载Terraform(https://www.terraform.io/downloads.html),根据情况选择Windows 32-bit版 或 64-bit版
  • 解压文件,复制到目标文件夹中,如:C:\LBWorkSpace\tool
  • 配置系统PATH路径
  • 打开CMD,使用Terraform --version测试

准备创建VM的Terraform模板

准备Terraform模板,参考Azure的官方文档:使用 Terraform 在 Azure 中创建带有基础结构的 Linux VM。可以一步一步的编写模板,也可全部COPY至本地,并命名为:terraform_azure.tf(名字可以随便改动,文件后缀名tf不可变)。

  1 # Configure the Microsoft Azure Provider
2 provider "azurerm" {
3 # The "feature" block is required for AzureRM provider 2.x.
4 # If you're using version 1.x, the "features" block is not allowed.
5 version = "~>2.0"
6 features {}
7 }
8
9 # Create a resource group if it doesn't exist
10 resource "azurerm_resource_group" "myterraformgroup" {
11 name = "myResourceGroup"
12 location = "chinaeast"
13
14 tags = {
15 environment = "Terraform Demo"
16 }
17 }
18
19 # Create virtual network
20 resource "azurerm_virtual_network" "myterraformnetwork" {
21 name = "myVnet"
22 address_space = ["10.0.0.0/16"]
23 location = "chinaeast"
24 resource_group_name = azurerm_resource_group.myterraformgroup.name
25
26 tags = {
27 environment = "Terraform Demo"
28 }
29 }
30
31 # Create subnet
32 resource "azurerm_subnet" "myterraformsubnet" {
33 name = "mySubnet"
34 resource_group_name = azurerm_resource_group.myterraformgroup.name
35 virtual_network_name = azurerm_virtual_network.myterraformnetwork.name
36 address_prefixes = ["10.0.1.0/24"]
37 }
38
39 # Create public IPs
40 resource "azurerm_public_ip" "myterraformpublicip" {
41 name = "myPublicIP"
42 location = "chinaeast"
43 resource_group_name = azurerm_resource_group.myterraformgroup.name
44 allocation_method = "Dynamic"
45
46 tags = {
47 environment = "Terraform Demo"
48 }
49 }
50
51 # Create Network Security Group and rule
52 resource "azurerm_network_security_group" "myterraformnsg" {
53 name = "myNetworkSecurityGroup"
54 location = "chinaeast"
55 resource_group_name = azurerm_resource_group.myterraformgroup.name
56
57 security_rule {
58 name = "SSH"
59 priority = 1001
60 direction = "Inbound"
61 access = "Allow"
62 protocol = "Tcp"
63 source_port_range = "*"
64 destination_port_range = "22"
65 source_address_prefix = "*"
66 destination_address_prefix = "*"
67 }
68
69 tags = {
70 environment = "Terraform Demo"
71 }
72 }
73
74 # Create network interface
75 resource "azurerm_network_interface" "myterraformnic" {
76 name = "myNIC"
77 location = "chinaeast"
78 resource_group_name = azurerm_resource_group.myterraformgroup.name
79
80 ip_configuration {
81 name = "myNicConfiguration"
82 subnet_id = azurerm_subnet.myterraformsubnet.id
83 private_ip_address_allocation = "Dynamic"
84 public_ip_address_id = azurerm_public_ip.myterraformpublicip.id
85 }
86
87 tags = {
88 environment = "Terraform Demo"
89 }
90 }
91
92 # Connect the security group to the network interface
93 resource "azurerm_network_interface_security_group_association" "example" {
94 network_interface_id = azurerm_network_interface.myterraformnic.id
95 network_security_group_id = azurerm_network_security_group.myterraformnsg.id
96 }
97
98 # Generate random text for a unique storage account name
99 resource "random_id" "randomId" {
100 keepers = {
101 # Generate a new ID only when a new resource group is defined
102 resource_group = azurerm_resource_group.myterraformgroup.name
103 }
104
105 byte_length = 8
106 }
107
108 # Create storage account for boot diagnostics
109 resource "azurerm_storage_account" "mystorageaccount" {
110 name = "diag${random_id.randomId.hex}"
111 resource_group_name = azurerm_resource_group.myterraformgroup.name
112 location = "chinaeast"
113 account_tier = "Standard"
114 account_replication_type = "LRS"
115
116 tags = {
117 environment = "Terraform Demo"
118 }
119 }
120
121 # Create (and display) an SSH key
122 resource "tls_private_key" "example_ssh" {
123 algorithm = "RSA"
124 rsa_bits = 4096
125 }
126 #output "tls_private_key" { value = tls_private_key.example_ssh.private_key_pem }
127
128 # Create virtual machine
129 resource "azurerm_linux_virtual_machine" "myterraformvm" {
130 name = "myVM"
131 location = "chinaeast"
132 resource_group_name = azurerm_resource_group.myterraformgroup.name
133 network_interface_ids = [azurerm_network_interface.myterraformnic.id]
134 size = "Standard_DS1_v2"
135
136 os_disk {
137 name = "myOsDisk"
138 caching = "ReadWrite"
139 storage_account_type = "Premium_LRS"
140 }
141
142 source_image_reference {
143 publisher = "Canonical"
144 offer = "UbuntuServer"
145 sku = "18.04-LTS"
146 version = "latest"
147 }
148
149 computer_name = "myvm"
150 admin_username = "azureuser"
151 disable_password_authentication = true
152
153 admin_ssh_key {
154 username = "azureuser"
155 public_key = tls_private_key.example_ssh.public_key_openssh
156 }
157
158 boot_diagnostics {
159 storage_account_uri = azurerm_storage_account.mystorageaccount.primary_blob_endpoint
160 }
161
162 tags = {
163 environment = "Terraform Demo"
164 }
165 }

完成 Terraform 脚本https://docs.microsoft.com/zh-cn/azure/developer/terraform/create-linux-virtual-machine-with-infrastructure#complete-terraform-script

登录到中国区Azure

本文使用Visual Studio Code工具来展示命令及Terraform脚本,也可以直接使用PowerShell窗口。

一:打开VS Code,使用 az cloud set --name AzureChinaCloud 设置登录环境为China Azure。

二:使用 az login 登录

三:如有多个订阅号,可以使用 az account set --subscription "your subscription id" 指定资源所创建的订阅

执行Terraform init, plan, apply命令

第一步:初始化 terraform init

命令

terraform init

输出

PS C:\LBWorkSpace\MyCode\24-Terraform> terraform init

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of hashicorp/tls from the dependency lock file
- Reusing previous version of hashicorp/azurerm from the dependency lock file
- Reusing previous version of hashicorp/random from the dependency lock file
- Using previously-installed hashicorp/tls v3.1.0
- Using previously-installed hashicorp/azurerm v2.56.0
- Using previously-installed hashicorp/random v3.1.0 ╷
│ Warning: Version constraints inside provider configuration blocks are deprecated

│ on terraform_azure.tf line 5, in provider "azurerm":
│ 5: version = "~>2.0"

│ Terraform 0.13 and earlier allowed provider version constraints inside the provider configuration block, but that is now deprecated and will
│ be removed in a future version of Terraform. To silence this warning, move the provider version constraint into the required_providers block.
╵ Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work. If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

第二步:检查并验证模板 terraform plan

命令

terraform plan

输出

PS C:\LBWorkSpace\MyCode\24-Terraform> terraform plan
tls_private_key.example_ssh: Refreshing state... [id=4b9fa2d1e40856b8ed19e1978c7713feb660ce9b]
azurerm_resource_group.myterraformgroup: Refreshing state... [id=/subscriptions/a9dc7515-7692-4316-9ad4-762f383eec10/resourceGroups/myResourceGroup]

│ Warning: Version constraints inside provider configuration blocks are deprecated

│ on terraform_azure.tf line 5, in provider "azurerm":
│ 5: version = "~>2.0"

│ Terraform 0.13 and earlier allowed provider version constraints inside the provider configuration block, but that is now deprecated and will be removed in a future version of Terraform. To silence this
│ warning, move the provider version constraint into the required_providers block.


│ Error: "eastus" was not found in the list of supported Azure Locations: "chinaeast,chinanorth,chinanorth2,chinaeast2"

│ on terraform_azure.tf line 10, in resource "azurerm_resource_group" "myterraformgroup":
│ 10: resource "azurerm_resource_group" "myterraformgroup" {



│ Error: Output refers to sensitive values

│ on terraform_azure.tf line 126:
│ 126: output "tls_private_key" { value = tls_private_key.example_ssh.private_key_pem }

│ Expressions used in outputs can only refer to sensitive values if the sensitive attribute is true.

PS C:\LBWorkSpace\MyCode\24-Terraform>

注意:在检查模板时候有两个错误,是因为copy的terraform模板是创建在global azure的,而当前是在中国区azure,所以需要修改location从eastus到chinaeast或其他。 第二个错误output输出可以暂时注释126行模板即可。修改完成后,再次使用terraform plan命令检查模板,输出结果中会包含模板中将要创建,修改的资源列表。

第三步:构建模板中的资源 terraform apply

命令

terraform apply

输出(apply命令需要在执行前手动输入yes,然后开始真正执行创建资源。当创建完成后,可以看见Apply complete! Resources: 9 added, 0 changed, 0 destroyed.提示消息)

PS C:\LBWorkSpace\MyCode\24-Terraform> terraform apply
tls_private_key.example_ssh: Refreshing state... [id=4b9fa2d1e40856b8ed19e1978c7713feb660ce9b]
azurerm_resource_group.myterraformgroup: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup]
random_id.randomId: Refreshing state... [id=nOAZzlk4_VY]
azurerm_network_security_group.myterraformnsg: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup]
azurerm_virtual_network.myterraformnetwork: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet]
azurerm_public_ip.myterraformpublicip: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/publicIPAddresses/myPublicIP]
azurerm_storage_account.mystorageaccount: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/diag9ce019ce5938fd56]
azurerm_subnet.myterraformsubnet: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet]
azurerm_network_interface.myterraformnic: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/networkInterfaces/myNIC]
azurerm_network_interface_security_group_association.example: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/networkInterfaces/myNIC|/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup]
azurerm_linux_virtual_machine.myterraformvm: Refreshing state... [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachines/myVM] Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create Terraform will perform the following actions: # azurerm_linux_virtual_machine.myterraformvm will be created
+ resource "azurerm_linux_virtual_machine" "myterraformvm" {
+ admin_username = "azureuser"
+ allow_extension_operations = true
+ computer_name = "myvm"
+ disable_password_authentication = true
+ extensions_time_budget = "PT1H30M"
+ id = (known after apply)
+ location = "chinaeast"
+ max_bid_price = -1
+ name = "myVM"
+ network_interface_ids = (known after apply)
+ platform_fault_domain = -1
+ priority = "Regular"
+ private_ip_address = (known after apply)
+ private_ip_addresses = (known after apply)
+ provision_vm_agent = true
+ public_ip_address = (known after apply)
+ public_ip_addresses = (known after apply)
+ resource_group_name = "myResourceGroup"
+ size = "Standard_DS1_v2"
+ tags = {
+ "environment" = "Terraform Demo"
}
+ virtual_machine_id = (known after apply)
+ zone = (known after apply) + admin_ssh_key {
+ public_key = <<-EOT
ssh-rsa xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
EOT
+ username = "azureuser"
} + boot_diagnostics {
+ storage_account_uri = (known after apply)
} + os_disk {
+ caching = "ReadWrite"
+ disk_size_gb = (known after apply)
+ name = "myOsDisk"
+ storage_account_type = "Premium_LRS"
+ write_accelerator_enabled = false
} + source_image_reference {
+ offer = "UbuntuServer"
+ publisher = "Canonical"
+ sku = "18.04-LTS"
+ version = "latest"
}
} # azurerm_network_interface.myterraformnic will be created
+ resource "azurerm_network_interface" "myterraformnic" {
+ applied_dns_servers = (known after apply)
+ dns_servers = (known after apply)
+ enable_accelerated_networking = false
+ enable_ip_forwarding = false
+ id = (known after apply)
+ internal_dns_name_label = (known after apply)
+ internal_domain_name_suffix = (known after apply)
+ location = "chinaeast"
+ mac_address = (known after apply)
+ name = "myNIC"
+ private_ip_address = (known after apply)
+ private_ip_addresses = (known after apply)
+ resource_group_name = "myResourceGroup"
+ tags = {
+ "environment" = "Terraform Demo"
}
+ virtual_machine_id = (known after apply) + ip_configuration {
+ name = "myNicConfiguration"
+ primary = (known after apply)
+ private_ip_address = (known after apply)
+ private_ip_address_allocation = "dynamic"
+ private_ip_address_version = "IPv4"
+ public_ip_address_id = (known after apply)
+ subnet_id = (known after apply)
}
} # azurerm_network_interface_security_group_association.example will be created
+ resource "azurerm_network_interface_security_group_association" "example" {
+ id = (known after apply)
+ network_interface_id = (known after apply)
+ network_security_group_id = (known after apply)
} # azurerm_network_security_group.myterraformnsg will be created
+ resource "azurerm_network_security_group" "myterraformnsg" {
+ id = (known after apply)
+ location = "chinaeast"
+ name = "myNetworkSecurityGroup"
+ resource_group_name = "myResourceGroup"
+ security_rule = [
+ {
+ access = "Allow"
+ description = ""
+ destination_address_prefix = "*"
+ destination_address_prefixes = []
+ destination_application_security_group_ids = []
+ destination_port_range = "22"
+ destination_port_ranges = []
+ direction = "Inbound"
+ name = "SSH"
+ priority = 1001
+ protocol = "Tcp"
+ source_address_prefix = "*"
+ source_address_prefixes = []
+ source_application_security_group_ids = []
+ source_port_range = "*"
+ source_port_ranges = []
},
]
+ tags = {
+ "environment" = "Terraform Demo"
}
} # azurerm_public_ip.myterraformpublicip will be created
+ resource "azurerm_public_ip" "myterraformpublicip" {
+ allocation_method = "Dynamic"
+ fqdn = (known after apply)
+ id = (known after apply)
+ idle_timeout_in_minutes = 4
+ ip_address = (known after apply)
+ ip_version = "IPv4"
+ location = "chinaeast"
+ name = "myPublicIP"
+ resource_group_name = "myResourceGroup"
+ sku = "Basic"
+ tags = {
+ "environment" = "Terraform Demo"
}
} # azurerm_resource_group.myterraformgroup will be created
+ resource "azurerm_resource_group" "myterraformgroup" {
+ id = (known after apply)
+ location = "chinaeast"
+ name = "myResourceGroup"
+ tags = {
+ "environment" = "Terraform Demo"
}
} # azurerm_storage_account.mystorageaccount will be created
+ resource "azurerm_storage_account" "mystorageaccount" {
+ access_tier = (known after apply)
+ account_kind = "StorageV2"
+ account_replication_type = "LRS"
+ account_tier = "Standard"
+ allow_blob_public_access = false
+ enable_https_traffic_only = true
+ id = (known after apply)
+ is_hns_enabled = false
+ large_file_share_enabled = (known after apply)
+ location = "chinaeast"
+ min_tls_version = "TLS1_0"
+ name = "diag9ce019ce5938fd56"
+ primary_access_key = (sensitive value)
+ primary_blob_connection_string = (sensitive value)
+ primary_blob_endpoint = (known after apply)
+ primary_blob_host = (known after apply)
+ primary_connection_string = (sensitive value)
+ primary_dfs_endpoint = (known after apply)
+ primary_dfs_host = (known after apply)
+ primary_file_endpoint = (known after apply)
+ primary_file_host = (known after apply)
+ primary_location = (known after apply)
+ primary_queue_endpoint = (known after apply)
+ primary_queue_host = (known after apply)
+ primary_table_endpoint = (known after apply)
+ primary_table_host = (known after apply)
+ primary_web_endpoint = (known after apply)
+ primary_web_host = (known after apply)
+ resource_group_name = "myResourceGroup"
+ secondary_access_key = (sensitive value)
+ secondary_blob_connection_string = (sensitive value)
+ secondary_blob_endpoint = (known after apply)
+ secondary_blob_host = (known after apply)
+ secondary_connection_string = (sensitive value)
+ secondary_dfs_endpoint = (known after apply)
+ secondary_dfs_host = (known after apply)
+ secondary_file_endpoint = (known after apply)
+ secondary_file_host = (known after apply)
+ secondary_location = (known after apply)
+ secondary_queue_endpoint = (known after apply)
+ secondary_queue_host = (known after apply)
+ secondary_table_endpoint = (known after apply)
+ secondary_table_host = (known after apply)
+ secondary_web_endpoint = (known after apply)
+ secondary_web_host = (known after apply)
+ tags = {
+ "environment" = "Terraform Demo"
} + blob_properties {
+ container_delete_retention_policy {
+ days = (known after apply)
} + cors_rule {
+ allowed_headers = (known after apply)
+ allowed_methods = (known after apply)
+ allowed_origins = (known after apply)
+ exposed_headers = (known after apply)
+ max_age_in_seconds = (known after apply)
} + delete_retention_policy {
+ days = (known after apply)
}
} + identity {
+ principal_id = (known after apply)
+ tenant_id = (known after apply)
+ type = (known after apply)
} + network_rules {
+ bypass = (known after apply)
+ default_action = (known after apply)
+ ip_rules = (known after apply)
+ virtual_network_subnet_ids = (known after apply)
} + queue_properties {
+ cors_rule {
+ allowed_headers = (known after apply)
+ allowed_methods = (known after apply)
+ allowed_origins = (known after apply)
+ exposed_headers = (known after apply)
+ max_age_in_seconds = (known after apply)
} + hour_metrics {
+ enabled = (known after apply)
+ include_apis = (known after apply)
+ retention_policy_days = (known after apply)
+ version = (known after apply)
} + logging {
+ delete = (known after apply)
+ read = (known after apply)
+ retention_policy_days = (known after apply)
+ version = (known after apply)
+ write = (known after apply)
} + minute_metrics {
+ enabled = (known after apply)
+ include_apis = (known after apply)
+ retention_policy_days = (known after apply)
+ version = (known after apply)
}
}
} # azurerm_subnet.myterraformsubnet will be created
+ resource "azurerm_subnet" "myterraformsubnet" {
+ address_prefix = (known after apply)
+ address_prefixes = [
+ "10.0.1.0/24",
]
+ enforce_private_link_endpoint_network_policies = false
+ enforce_private_link_service_network_policies = false
+ id = (known after apply)
+ name = "mySubnet"
+ resource_group_name = "myResourceGroup"
+ virtual_network_name = "myVnet"
} # azurerm_virtual_network.myterraformnetwork will be created
+ resource "azurerm_virtual_network" "myterraformnetwork" {
+ address_space = [
+ "10.0.0.0/16",
]
+ guid = (known after apply)
+ id = (known after apply)
+ location = "chinaeast"
+ name = "myVnet"
+ resource_group_name = "myResourceGroup"
+ subnet = (known after apply)
+ tags = {
+ "environment" = "Terraform Demo"
}
+ vm_protection_enabled = false
} Plan: 9 to add, 0 to change, 0 to destroy.

│ Warning: Version constraints inside provider configuration blocks are deprecated

│ on terraform_azure.tf line 5, in provider "azurerm":
│ 5: version = "~>2.0"

│ Terraform 0.13 and earlier allowed provider version constraints inside the provider configuration block, but that is now deprecated and will be removed in a future version of Terraform. To silence this
│ warning, move the provider version constraint into the required_providers block.
╵ 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 azurerm_resource_group.myterraformgroup: Creating...
azurerm_resource_group.myterraformgroup: Creation complete after 1s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup]
azurerm_virtual_network.myterraformnetwork: Creating...
azurerm_public_ip.myterraformpublicip: Creating...
azurerm_network_security_group.myterraformnsg: Creating...
azurerm_storage_account.mystorageaccount: Creating...
azurerm_public_ip.myterraformpublicip: Creation complete after 3s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/publicIPAddresses/myPublicIP]
azurerm_virtual_network.myterraformnetwork: Creation complete after 6s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet]
azurerm_subnet.myterraformsubnet: Creating...
azurerm_network_security_group.myterraformnsg: Creation complete after 5s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup]
azurerm_storage_account.mystorageaccount: Still creating... [10s elapsed]
azurerm_subnet.myterraformsubnet: Creation complete after 5s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet]
azurerm_network_interface.myterraformnic: Creating...
azurerm_network_interface.myterraformnic: Creation complete after 2s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/networkInterfaces/myNIC]
azurerm_network_interface_security_group_association.example: Creating...
azurerm_network_interface_security_group_association.example: Creation complete after 0s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/networkInterfaces/myNIC|/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/networkSecurityGroups/myNetworkSecurityGroup]
azurerm_storage_account.mystorageaccount: Still creating... [20s elapsed]
azurerm_storage_account.mystorageaccount: Creation complete after 23s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/diag9ce019ce5938fd56]
azurerm_linux_virtual_machine.myterraformvm: Creating...
azurerm_linux_virtual_machine.myterraformvm: Still creating... [10s elapsed]
azurerm_linux_virtual_machine.myterraformvm: Still creating... [20s elapsed]
azurerm_linux_virtual_machine.myterraformvm: Still creating... [30s elapsed]
azurerm_linux_virtual_machine.myterraformvm: Still creating... [40s elapsed]
azurerm_linux_virtual_machine.myterraformvm: Still creating... [50s elapsed]
azurerm_linux_virtual_machine.myterraformvm: Still creating... [1m0s elapsed]
azurerm_linux_virtual_machine.myterraformvm: Still creating... [1m10s elapsed]
azurerm_linux_virtual_machine.myterraformvm: Still creating... [1m20s elapsed]
azurerm_linux_virtual_machine.myterraformvm: Still creating... [1m30s elapsed]
azurerm_linux_virtual_machine.myterraformvm: Still creating... [1m40s elapsed]
azurerm_linux_virtual_machine.myterraformvm: Still creating... [1m50s elapsed]
azurerm_linux_virtual_machine.myterraformvm: Creation complete after 1m51s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Compute/virtualMachines/myVM] Apply complete! Resources: 9 added, 0 changed, 0 destroyed.

恭喜!踏入Terraform创建Azure资源大门。

参考资料

“Azure 上的 Terraform”文档: https://docs.microsoft.com/zh-cn/azure/developer/terraform/

使用 Terraform 在 Azure 中创建带有基础结构的 Linux VM: https://docs.microsoft.com/zh-cn/azure/developer/terraform/create-linux-virtual-machine-with-infrastructure#complete-terraform-script

Install Azure CLI on Windows:https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows?tabs=azure-powershell

【Azure 环境】在Windows系统中 使用Terraform创建中国区Azure资源步骤(入门级)的更多相关文章

  1. windows系统中 利用kibana创建elasticsearch索引等操作

    elasticsearch之借用kibana平台创建索引 1.安装好kibana平台 确保kibana以及elasticsearch正常运行 2.打开kibana平台在Dev Tools 3.创建一个 ...

  2. 关于Linux系统和Windows系统中文件夹的命名规范

    Windows系统中. 1.在创建文件夹的时候不能以"."开头(但是文件以多个点开头并且还有其他合法字符的话就是合法的) 但是在windows系统中确实见过以一个点".& ...

  3. 在Windows系统中安装集成的PHP开发环境

    原文:在Windows系统中安装集成的PHP开发环境 刚想学php的,又不会配置复杂php的环境,可以使用集成的,目前网上提供常用的PHP集成环境主要有AppServ.phpStudy.WAMP和XA ...

  4. Windows系统中环境变量不展开的问题

    Windows系统中环境变量不展开的问题 问题现象:Windows.System32等系统目录里命令,无法通过Path搜索路径来执行.查看Path环境变量结果如下: D:\>echo %Path ...

  5. Python 编程环境搭建(Windows 系统中)

    由于大家普遍使用 Windows 系统,所以本文只介绍 Windows 系统中 Python 环境的安装. 在 Windows 中安装 Python 与安装普通软件没什么差别,下载所需版本的安装包后, ...

  6. UEFI+GPT模式下的Windows系统中分区结构和默认分区大小及硬盘整数分区研究

    内容摘要:本文主要讨论和分析在UEFI+GPT模式下的Windows系统(主要是最新的Win10X64)中默认的分区结构和默认的分区大小,硬盘整数分区.4K对齐.起始扇区.恢复分区.ESP分区.MSR ...

  7. Windows系统中设置Python程序定时运行方法

    Windows系统中设置Python程序定时运行方法 一.环境 win7 + Python3.6 二.步骤 1,在Windows开始菜单中搜索“计划任务”,并且点击打开“计划任务”: 2.点击“创建基 ...

  8. Cmder命令行工具在Windows系统中的配置

    一.Cmder简介 Cmder:一款用于Windows系统中,可增强传统cmd命令行工具的控制台模拟器(类似于Linux系统中的终端控制窗口) 特点: 无需安装,解压即用 可使用较多Linux命令,如 ...

  9. python - 在Windows系统中安装Pygame及导入Eclipse

    环境:python3.6(只有一个版本)+ windows10(64 bit)  + Eclipse+pydev python3.6安装完成后,会自带 easy_install 和 pip3,在Win ...

随机推荐

  1. scala:函数作为值或参数进行传递、作为返回值进行返回

    @ 目录 函数可以作为值进行传递 函数可以作为参数进行传递 函数可以作为返回值进行返回 什么是匿名函数 函数可以作为值进行传递 语法var f = 函数名 _ 如果明确了变量的数据类型,那么下划线可以 ...

  2. 导出----用Excel导出数据库表

    根据条件导出表格: 前端 <el-form-item label=""> <el-button type="warning" icon=&qu ...

  3. Kubernetes: NGINX/PHP-FPM 502错误和优雅结束

    我们有一个运行在Kubernetes上的PHP应用,每个POD由两个独立的容器组成 - Nginx和PHP-FPM. 在我们对应用进行缩容时,遇到了502错误,例如,当一个POD在结束中时,POD里面 ...

  4. CMD(命令提示符)的基本操作(文件夹)

    打开CMD窗口,接下来将介绍如何使用CMD来创建.删除.修改.查看文件夹(目录) ps:以下所有文件夹将统一写成目录 1.1 使用CMD创建空目录(为了更好的演示,本文皆以D盘为当前路径),命令如下: ...

  5. 2021-2-28:调用 System.gc() 后究竟发生了什么?

    首先,根据 DisableExplicitGC 这个 JVM 启动参数的状态,确定是否会 GC,如果需要 GC,不同 GC 会有不同的处理. 1. G1 GC 的处理 如果是 System.gc() ...

  6. es6 快速入门 —— 函数

    其他章节请看: es6 快速入门 系列 函数 函数是所有编程语言的重要组成部分,es6之前函数语法一直没什么变化,遗留了许多问题,javaScript开发者多年来不断抱怨,es6终于决定大力度更新函数 ...

  7. tibco EMS 8.2.0安装

    安装环境 序号 项目 值 1 OS版本 Red Hat Enterprise Linux Server release 7.1 (Maipo) 2 内核版本 3.10.0-229.el7.x86_64 ...

  8. POJ-1459(最大流+EK算法)

    Power Network POJ-1459 这题值得思索的就是特殊的输入,如何输入一连串字符.这里采用的方法是根据输入已知的输入格式,事先预定好要接受的数据类型. 这里套用的板子也是最大流的模板,但 ...

  9. 记一次Drone无法触发构建的问题

    问题 好巧不巧,当你晚上准备上线的时候,在下午临近下班的时候CI&CD工具出问题了,提交代码不能触发构建,不能上线了,Drone平台那边也下班了,正好CICD依赖的公司git仓库也出问题了(就 ...

  10. 设计模式之抽象工厂模式(Abstract Factory Pattern)

    一.抽象工厂模式的由来 抽象工厂模式,最开始是为了解决操作系统按钮和窗体风格,而产生的一种设计模式.例如:在windows系统中,我们要用windows设定的按钮和窗体,当我们切换Linux系统时,要 ...