Terraform入门笔记:Terraform命令行工具安装~在IBM Cloud VPC中创建VSI
主要参考以下内容进行实施。终端设备为Windows10。
在IBM Cloud上开始使用Terraform
为VPC提供IBM Cloud虚拟服务器
在终端上安装Terraform CLI。
创建一个Terraform目录。
PS C:\work> mkdir terraform; cd terraform
ディレクトリ: C:\work
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2021/06/16 13:17 terraform
PS C:\work\terraform>
请下载并解压Terraform软件,
链接:https://releases.hashicorp.com/terraform/
PS C:\work\terraform> dir
ディレクトリ: C:\work\terraform
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2021/06/16 13:18 terraform_0.14.11_windows_amd64
-a---- 2021/06/16 13:15 34043279 terraform_0.14.11_windows_amd64.zip
PS C:\work\terraform> dir terraform_0.14.11_windows_amd64
ディレクトリ: C:\work\terraform\terraform_0.14.11_windows_amd64
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2021/06/16 13:18 84003704 terraform.exe
PS C:\work\terraform>
通过路径执行命令进行确认。
PS C:\work\terraform> $ENV:Path=$ENV:Path+";C:\work\terraform\terraform_0.14.11_windows_amd64"
PS C:\work\terraform> terraform
Usage: terraform [global options] <subcommand> [args]
The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.
Main commands:
init Prepare your working directory for other commands
validate Check whether the configuration is valid
plan Show changes required by the current configuration
apply Create or update infrastructure
destroy Destroy previously-created infrastructure
All other commands:
console Try Terraform expressions at an interactive command prompt
fmt Reformat your configuration in the standard style
force-unlock Release a stuck lock on the current workspace
get Install or upgrade remote Terraform modules
graph Generate a Graphviz graph of the steps in an operation
import Associate existing infrastructure with a Terraform resource
login Obtain and save credentials for a remote host
logout Remove locally-stored credentials for a remote host
output Show output values from your root module
providers Show the providers required for this configuration
refresh Update the state to match remote systems
show Show the current state or a saved plan
state Advanced state management
taint Mark a resource instance as not fully functional
untaint Remove the 'tainted' state from a resource instance
version Show the current Terraform version
workspace Workspace management
Global options (use these before the subcommand, if any):
-chdir=DIR Switch to a different working directory before executing the
given subcommand.
-help Show this help output, or the help for a specified subcommand.
-version An alias for the "version" subcommand.
PS C:\work\terraform>
准备VPC环境
这次我们将使用GUI进行操作。具体细节省略。

创建.tf文件
versions.tf 的不同版本
可以在以下链接中确认Terraform的版本。
https://registry.terraform.io/providers/IBM-Cloud/ibm/latest
terraform {
required_providers {
ibm = {
source = "IBM-Cloud/ibm"
version = "1.26.2"
}
}
}
terraform.tfvars 可以被一个名为 terraform.tfvars 的文件 natively 包含。
变量的定义
ibmcloud_api_key="xxxxxx"
resource_group="c6bcd9b18bb64c288510d19806dd12dc"
※API密钥请使用之前已创建的密钥,详细信息略过
※资源组ID可以通过下面的方式确认
PS C:\work\terraform> ibmcloud resource groups
Retrieving all resource groups under account 1234567890a1234567890b1234567890 as xxxx@jp.ibm.com...
OK
Name ID Default Group State
resourcegroup1 c6bcd9b18bb64c288510d19806dd12dc false ACTIVE
请提供provider.tf文件。
variable "ibmcloud_api_key" {}
variable "resource_group" {}
provider "ibm" {
ibmcloud_api_key = var.ibmcloud_api_key
region = "jp-tok"
resource_group = var.resource_group
}
对于VSI测试,请提供一种本地化的中文解释。
定義创建 VSI(Virtual Server Instance)和 Floating IP 所需的信息。
localsはローカル変数
dataは既存のIBM Cloudリソースの情報を取得
VPC等々既存リソースのリソース名を指定
resourceのパラメータで既存リソースのID値を指定する必要があるが、ここで取得しておけばID値を調べることなく data.xxx.id のように指定できる
resourceが作成するリソースの情報(GUIならオーダー画面で指定する項目に相当)
locals {
ZONE = "jp-tok-2"
BASENAME = "test"
}
data "ibm_is_vpc" "vpc" {
name = "vpc-${local.BASENAME}"
}
data "ibm_is_subnet" "sbn" {
name = "sbn-${local.BASENAME}"
}
data "ibm_is_security_group" "sg" {
name = "sg-${local.BASENAME}"
}
data "ibm_is_image" "centos" {
name = "ibm-centos-8-3-minimal-amd64-3"
}
data "ibm_is_ssh_key" "ssh_key" {
name = "key-test"
}
resource "ibm_is_instance" "vsi" {
name = "vsi-test"
vpc = data.ibm_is_vpc.vpc.id
zone = local.ZONE
keys = [data.ibm_is_ssh_key.ssh_key.id]
image = data.ibm_is_image.centos.id
profile = "cx2-2x4"
primary_network_interface {
subnet = data.ibm_is_subnet.sbn.id
security_groups = [data.ibm_is_security_group.sg.id]
}
resource_group = var.resource_group
}
resource "ibm_is_floating_ip" "fip" {
name = "fip-${local.BASENAME}"
target = ibm_is_instance.vsi.primary_network_interface[0].id
resource_group = var.resource_group
}
执行terraform
初始化terraform
PS C:\work\terraform> terraform init
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of ibm-cloud/ibm from the dependency lock file
- Using previously-installed ibm-cloud/ibm v1.26.2
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.
PS C:\work\terraform>
执行Terraform计划
PS C:\work\terraform> terraform plan
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# ibm_is_floating_ip.fip will be created
+ resource "ibm_is_floating_ip" "fip" {
+ address = (known after apply)
+ id = (known after apply)
+ name = "fip-test"
+ resource_controller_url = (known after apply)
+ resource_crn = (known after apply)
+ resource_group = "c6bcd9b18bb64c288510d19806dd12dc"
+ resource_group_name = (known after apply)
+ resource_name = (known after apply)
+ resource_status = (known after apply)
+ status = (known after apply)
+ tags = (known after apply)
+ target = (known after apply)
+ zone = (known after apply)
}
# ibm_is_instance.vsi will be created
+ resource "ibm_is_instance" "vsi" {
+ disks = (known after apply)
+ gpu = (known after apply)
+ id = (known after apply)
+ image = "r022-95e7a9a1-8707-49ea-bdef-693311570ce0"
+ keys = [
]
+ memory = (known after apply)
+ name = "vsi-test"
+ profile = "cx2-2x4"
+ resource_controller_url = (known after apply)
+ resource_crn = (known after apply)
+ resource_group = "c6bcd9b18bb64c288510d19806dd12dc"
+ resource_group_name = (known after apply)
+ resource_name = (known after apply)
+ resource_status = (known after apply)
+ status = (known after apply)
+ tags = (known after apply)
+ vcpu = (known after apply)
+ volume_attachments = (known after apply)
+ vpc = "r022-45600dc1-1f1a-4a09-a0a7-6131cbbdcfb4"
+ wait_before_delete = true
+ zone = "jp-tok-2"
+ boot_volume {
+ encryption = (known after apply)
+ iops = (known after apply)
+ name = (known after apply)
+ profile = (known after apply)
+ size = (known after apply)
}
+ primary_network_interface {
+ allow_ip_spoofing = false
+ id = (known after apply)
+ name = (known after apply)
+ primary_ipv4_address = (known after apply)
+ security_groups = [
+ "r022-9101424b-84e2-4081-8484-53baffaeb9b7",
]
+ subnet = "02f7-3d141b46-f9ac-46d6-9645-748471961b84"
}
}
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.
PS C:\work\terraform>
部署terraform
PS C:\work\terraform> terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# ibm_is_floating_ip.fip will be created
+ resource "ibm_is_floating_ip" "fip" {
+ address = (known after apply)
+ id = (known after apply)
+ name = "fip-test"
+ resource_controller_url = (known after apply)
+ resource_crn = (known after apply)
+ resource_group = "c6bcd9b18bb64c288510d19806dd12dc"
+ resource_group_name = (known after apply)
+ resource_name = (known after apply)
+ resource_status = (known after apply)
+ status = (known after apply)
+ tags = (known after apply)
+ target = (known after apply)
+ zone = (known after apply)
}
# ibm_is_instance.vsi will be created
+ resource "ibm_is_instance" "vsi" {
+ disks = (known after apply)
+ gpu = (known after apply)
+ id = (known after apply)
+ image = "r022-95e7a9a1-8707-49ea-bdef-693311570ce0"
+ keys = [
+ "r022-fba74a1a-c774-429f-b833-906cd913a64e",
]
+ memory = (known after apply)
+ name = "vsi-test"
+ profile = "cx2-2x4"
+ resource_controller_url = (known after apply)
+ resource_crn = (known after apply)
+ resource_group = "c6bcd9b18bb64c288510d19806dd12dc"
+ resource_group_name = (known after apply)
+ resource_name = (known after apply)
+ resource_status = (known after apply)
+ status = (known after apply)
+ tags = (known after apply)
+ vcpu = (known after apply)
+ volume_attachments = (known after apply)
+ vpc = "r022-45600dc1-1f1a-4a09-a0a7-6131cbbdcfb4"
+ wait_before_delete = true
+ zone = "jp-tok-2"
+ boot_volume {
+ encryption = (known after apply)
+ iops = (known after apply)
+ name = (known after apply)
+ profile = (known after apply)
+ size = (known after apply)
}
+ primary_network_interface {
+ allow_ip_spoofing = false
+ id = (known after apply)
+ name = (known after apply)
+ primary_ipv4_address = (known after apply)
+ security_groups = [
+ "r022-9101424b-84e2-4081-8484-53baffaeb9b7",
]
+ subnet = "02f7-3d141b46-f9ac-46d6-9645-748471961b84"
}
}
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
ibm_is_instance.vsi: Creating...
ibm_is_instance.vsi: Still creating... [10s elapsed]
ibm_is_instance.vsi: Still creating... [20s elapsed]
ibm_is_instance.vsi: Still creating... [30s elapsed]
ibm_is_instance.vsi: Creation complete after 30s [id=02f7_d2362719-28e8-4a58-8c60-102892ce46cd]
ibm_is_floating_ip.fip: Creating...
ibm_is_floating_ip.fip: Still creating... [10s elapsed]
ibm_is_floating_ip.fip: Creation complete after 15s [id=r022-512fdb3d-5525-4082-82c0-10c6a1be2456]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
PS C:\work\terraform>
确认已创建的VSI
VSI已经创建并处于运行状态。
PS C:\work\terraform> ibmcloud is instances
Listing instances for generation 2 compute in resource group resourcegroup1 and region jp-tok under account IBM as user xxxx@jp.ibm.com...
ID Name Status Address Floating IP Profile Image VPC Zone Resource group
02f7_d2362719-28e8-4a58-8c60-102892ce46cd vsi-test running yyy.yyy.yyy.yyy xxx.xxx.xxx.xxx cx2-2x4 ibm-centos-8-3-minimal-amd64-3 vpc-test jp-tok-2 resourcegroup1
PS C:\work\terraform>
浮动IP成功SSH连接。
它是在指定的操作系统上创建的。
PS C:\work\terraform> ssh -i C:\Users\AaaBbb\.ssh\key-test root@xxx.xxx.xxx.xxx
The authenticity of host 'xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)' can't be established.
ECDSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'xxx.xxx.xxx.xxx' (ECDSA) to the list of known hosts.
[root@vsi-test ~]# cat /etc/redhat-release
CentOS Linux release 8.3.2011
[root@vsi-test ~]#
當關閉 VPN 時,無法進行連接(確保安全組仍然有效)。
PS C:\work\terraform> ssh -i C:\Users\AaaBbb\.ssh\key-test root@xxx.xxx.xxx.xxx
ssh: connect to host xxx.xxx.xxx.xxx port 22: Connection timed out
PS C:\work\terraform>
删除资源
销毁terraform
可以使用terraform destroy命令来删除通过terraform创建的资源。
PS C:\work\terraform> terraform destroy
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# ibm_is_floating_ip.fip will be destroyed
- resource "ibm_is_floating_ip" "fip" {
- address = "xxx.xxx.xxx.xxx" -> null
- id = "r022-512fdb3d-5525-4082-82c0-10c6a1be2456" -> null
- name = "fip-test" -> null
- resource_controller_url = "https://cloud.ibm.com/vpc-ext/network/floatingIPs" -> null
- resource_crn = "crn:v1:bluemix:public:is:jp-tok-2:a/1fc8373f538a408187ffedbe62e5796a::floating-ip:r022-512fdb3d-5525-4082-82c0-10c6a1be2456" -> null
- resource_group = "c6bcd9b18bb64c288510d19806dd12dc" -> null
- resource_group_name = "resourcegroup1" -> null
- resource_name = "fip-test" -> null
- resource_status = "available" -> null
- status = "available" -> null
- tags = [] -> null
- target = "02f7-4b102bad-5d14-45b3-bda8-81657fec56a9" -> null
- zone = "jp-tok-2" -> null
}
# ibm_is_instance.vsi will be destroyed
- resource "ibm_is_instance" "vsi" {
- disks = [] -> null
- gpu = [] -> null
- id = "02f7_d2362719-28e8-4a58-8c60-102892ce46cd" -> null
- image = "r022-95e7a9a1-8707-49ea-bdef-693311570ce0" -> null
- keys = [
- "r022-fba74a1a-c774-429f-b833-906cd913a64e",
] -> null
- memory = 4 -> null
- name = "vsi-test" -> null
- profile = "cx2-2x4" -> null
- resource_controller_url = "https://cloud.ibm.com/vpc-ext/compute/vs" -> null
- resource_crn = "crn:v1:bluemix:public:is:jp-tok-2:a/1fc8373f538a408187ffedbe62e5796a::instance:02f7_d2362719-28e8-4a58-8c60-102892ce46cd" -> null
- resource_group = "c6bcd9b18bb64c288510d19806dd12dc" -> null
- resource_group_name = "resourcegroup1" -> null
- resource_name = "vsi-test" -> null
- resource_status = "running" -> null
- status = "running" -> null
- tags = [] -> null
- vcpu = [
- {
- architecture = "amd64"
- count = 2
},
] -> null
- volume_attachments = [
- {
- id = "02f7-b0fdfe7e-27ba-41de-a46a-671de4f15bcf"
- name = "clubbing-divisive-pointer-letdown"
- volume_crn = "crn:v1:bluemix:public:is:jp-tok-2:a/1fc8373f538a408187ffedbe62e5796a::volume:r022-708837e6-4e27-44d6-b0ac-620484213e50"
- volume_id = "r022-708837e6-4e27-44d6-b0ac-620484213e50"
- volume_name = "shawl-grime-detour-presoaked"
},
] -> null
- vpc = "r022-45600dc1-1f1a-4a09-a0a7-6131cbbdcfb4" -> null
- wait_before_delete = true -> null
- zone = "jp-tok-2" -> null
- boot_volume {
- iops = 3000 -> null
- name = "shawl-grime-detour-presoaked" -> null
- profile = "general-purpose" -> null
- size = 100 -> null
}
- primary_network_interface {
- allow_ip_spoofing = false -> null
- id = "02f7-4b102bad-5d14-45b3-bda8-81657fec56a9" -> null
- name = "stalemate-theorize-donator-steerable" -> null
- port_speed = 0 -> null
- primary_ipv4_address = "yyy.yyy.yyy.yyy" -> null
- security_groups = [
- "r022-9101424b-84e2-4081-8484-53baffaeb9b7",
] -> null
- subnet = "02f7-3d141b46-f9ac-46d6-9645-748471961b84" -> null
}
}
Plan: 0 to add, 0 to change, 2 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
ibm_is_floating_ip.fip: Destroying... [id=r022-512fdb3d-5525-4082-82c0-10c6a1be2456]
ibm_is_floating_ip.fip: Still destroying... [id=r022-512fdb3d-5525-4082-82c0-10c6a1be2456, 10s elapsed]
ibm_is_floating_ip.fip: Destruction complete after 14s
ibm_is_instance.vsi: Destroying... [id=02f7_d2362719-28e8-4a58-8c60-102892ce46cd]
ibm_is_instance.vsi: Still destroying... [id=02f7_d2362719-28e8-4a58-8c60-102892ce46cd, 10s elapsed]
ibm_is_instance.vsi: Still destroying... [id=02f7_d2362719-28e8-4a58-8c60-102892ce46cd, 20s elapsed]
ibm_is_instance.vsi: Still destroying... [id=02f7_d2362719-28e8-4a58-8c60-102892ce46cd, 30s elapsed]
ibm_is_instance.vsi: Still destroying... [id=02f7_d2362719-28e8-4a58-8c60-102892ce46cd, 40s elapsed]
ibm_is_instance.vsi: Still destroying... [id=02f7_d2362719-28e8-4a58-8c60-102892ce46cd, 50s elapsed]
ibm_is_instance.vsi: Destruction complete after 52s
Destroy complete! Resources: 2 destroyed.
PS C:\work\terraform>
确认VSI已不在
PS C:\work\terraform> ibmcloud is instances
Listing instances for generation 2 compute in resource group resourcegroup1 and region jp-tok under account IBM as user xxxx@jp.ibm.com...
No instances were found.
PS C:\work\terraform>
错误处理备忘录
到terraform执行错误和修正vsi-test.tf文件的备忘录之前,需要创建VSI。
执行terraform plan时出现错误。
错误:找不到名称为xxx的图片。
Error: No image found with name centos-8-amd64
on vsi-test.tf line 36, in data "ibm_is_image" "centos":
36: data "ibm_is_image" "centos" {
您可以通过ibmcloud is images来确认可用的image。
请使用Name的值而不是OS名称进行设置。
PS C:\work> ibmcloud is images
Listing images for generation 2 compute in resource group resourcegroup1 and region jp-tok under account IBM as user xxxx@jp.ibm.com...
ID Name Status Arch OS name OS version File size(GB) Visibility Owner type Encryption Resource group
r022-f10e4ea0-1f0b-4fb6-8cfd-1c9aad475046 ibm-centos-7-9-minimal-amd64-3 available amd64 centos-7-amd64 7.x - Minimal Install 1 public provider none -
r022-95e7a9a1-8707-49ea-bdef-693311570ce0 ibm-centos-8-3-minimal-amd64-3 available amd64 centos-8-amd64 8.x - Minimal Install 1 public provider none -
(略)
name = “centos-8-amd64”
}data “ibm_is_image” “centos” {
name = “ibm-centos-8-3-minimal-amd64-3”
}
错误:属性值类型不正确
Error: Incorrect attribute value type
on vsi-test.tf line 53, in resource "ibm_is_instance" "vsi-test":
53: keys = "r022-fba74a1a-c774-429f-b833-906cd913a64e"
Inappropriate value for attribute "keys": set of string required.
如下所示,SSH密钥需要以数组形式指定,即需要用[]括起来。
https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_instance
(略)
keys = data.ibm_is_ssh_key.ssh_key.idresource “ibm_is_instance” “vsi” {
(略)
keys = [data.ibm_is_ssh_key.ssh_key.id]
terraform执行”apply”时出现错误。
错误:用户没有权限使用默认的资源组
略
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
ibm_is_instance.vsi-test: Creating...
Error: user does not have permission to use default resource group
on vsi-test.tf line 49, in resource "ibm_is_instance" "vsi-test":
49: resource "ibm_is_instance" "vsi-test" {
(虽然在图形用户界面中也是同样的情况),需要指定资源组。
(略)
}
resource “ibm_is_instance” “vsi” {
(略)
resource_group = var.resource_group
}