使用 Terraform(v0.12.25)进行初始设置以构建 GCP 环境
中国人专为你解答!
“お題” 的本地化中文解释如下:
– 话题 (huà tí)
– 题目 (tí mù)
– 提问 (tí
– 主题 (zhǔ tí)
– 答题 (dá tí)
– 课题 (kè tí)
– 作文题 (zuò tí)
– 讨论议题 yì tí)
– 考题 tí)
– 命题 tí)
如标题所述。
的一个前提是
-
- GCPプロジェクト作成済み
- ローカル開発マシンに gcloud コマンド実行環境が既にある。
开发环境
操作系统 – Linux(Ubuntu)
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
云原生架构平台
$ terraform version
Terraform v0.12.25
# 谷歌云
$ gcloud version
Google Cloud SDK 294.0.0
实践
让您能够使用Terraform。
请从以下链接下载并选择“Linux 64位”的Terraform软件。
https://www.terraform.io/downloads.html
将zip解压并移动到/bin目录下。
查看版本
$ terraform version
Terraform v0.12.25
进行使用Terraform进行GCP环境操作之前的设置。
我以此为参考。
将GCP项目ID设置为环境变量。
假设本次使用Terraform进行环境构建的GCP项目ID为”my-gcp-prj-01″。
请确认您已在本地开发机上进行了与目标GCP项目的连接配置,
前提是已完成了通过gcloud auth login进行的身份验证。
$ gcloud config list
〜〜〜
project = my-gcp-prj-01
将上述的项目ID设置为环境变量。
$ export GCP_PROJECT_ID=$(gcloud config get-value project)
Your active configuration is: [my-gcp-prj-01]
$
$ env | grep GCP_PROJECT_ID
GCP_PROJECT_ID=my-gcp-prj-01
创建一个专门用于Terraform的服务账号。
由于涉及IAM,所以我要查找命令菜单。
$ gcloud iam
ERROR: (gcloud.iam) Command name argument expected.
Available groups for gcloud iam:
roles Create and manipulate roles.
service-accounts Create and manipulate service accounts.
Available commands for gcloud iam:
list-grantable-roles List IAM grantable roles for a resource.
list-testable-permissions List IAM testable permissions for a resource.
For detailed information on this command and its flags, run:
gcloud iam --help
使用service-accounts子命令应该可以做到。最终可以使用以下命令实现。
$ gcloud iam service-accounts create terraform
Created service account [terraform].
给Terraform专用的服务账号分配编辑器角色。
由于这个服务账号目前无法做任何事,我们需要给予权限。
根据教程文章提到,应选择“Project -> Editor”作为角色。
如果从基本角色中选择“roles/editor”就可以了。
参考链接:https://cloud.google.com/iam/docs/understanding-roles?hl=ja#primitive_roles
学习命令的使用方法,请参考以下链接:
https://cloud.google.com/iam/docs/granting-changing-revoking-access?hl=ja#granting-gcloud-manual
$ gcloud projects add-iam-policy-binding ${GCP_PROJECT_ID} --member serviceAccount:terraform@${GCP_PROJECT_ID}.iam.gserviceaccount.com --role roles/editor
Updated IAM policy for project [my-gcp-prj-01].
bindings:
- members:
- serviceAccount:terraform@my-gcp-prj-01.iam.gserviceaccount.com
role: roles/editor
获取具有编辑器角色的服务帐户的凭据JSON。
既然涉及到服务帐户,所以应该在之前的`gcloud iam service-accounts`菜单中可以找到。
$ gcloud iam service-accounts
ERROR: (gcloud.iam.service-accounts) Command name argument expected.
Available groups for gcloud iam service-accounts:
keys Manage service account keys.
Available commands for gcloud iam service-accounts:
add-iam-policy-binding Add an IAM policy binding to an IAM service
account.
create Create a service account for a project.
delete Delete a service account from a project.
describe Show metadata for a service account from a
project.
〜〜〜
使用钥匙的感觉吧。
$ gcloud iam service-accounts keys
ERROR: (gcloud.iam.service-accounts.keys) Command name argument expected.
Available commands for gcloud iam service-accounts keys:
create Create a private key for a service account.
delete Delete a user-managed key from a service account.
list List the keys for a service account.
$ gcloud iam service-accounts keys create
ERROR: (gcloud.iam.service-accounts.keys.create) argument OUTPUT-FILE --iam-account: Must be specified.
Usage: gcloud iam service-accounts keys create OUTPUT-FILE --iam-account=IAM_ACCOUNT [optional flags]
只需指定输出文件的名称以及所属的服务帐户即可。
$ gcloud iam service-accounts keys create ~/.config/gcloud/my-gcp-prj-01-terraform-credential.json --iam-account terraform@my-gcp-prj-01.iam.gserviceaccount.com
created key [532a~~~~~~~~5802~~~~~~~~f30b~~~~~~~~e7uy9] of type [json] as [/home/sky0621/.config/gcloud/my-gcp-prj-01-terraform-credential.json] for [terraform@my-gcp-prj-01.iam.gserviceaccount.com]
下面是创建的JSON的内容,大概是这样的。
$ cat ~/.config/gcloud/my-gcp-prj-01-terraform-credential.json
{
"type": "service_account",
"project_id": "my-gcp-prj-01",
"private_key_id": "xxxxxxxxxx33580xxxxxxxxxx30b99xxxxxxxxxx",
"private_key": "-----BEGIN PRIVATE KEY-----\nXX【鍵の中身】XXXX=\n-----END PRIVATE KEY-----\n",
"client_email": "terraform@my-gcp-prj-01.iam.gserviceaccount.com",
"client_id": "11111111111111111111",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/terraform%40my-gcp-prj-01.iam.gserviceaccount.com"
}
准备工作已经完成了。
我试着根据以下步骤,在GCP上编写一个试验性的tf文件来创建资源。
https://learn.hashicorp.com/terraform/gcp/build#configuration
provider "google" {
version = "3.5.0"
region = "asia-northeast1"
zone = "asia-northeast1-c"
}
resource "google_compute_network" "vpc_network" {
name = "terraform-network"
}
从参考页面上的内容中省略了以下部分。
-
- credentials
- project
我們決定使用上述兩個隱含的環境變數來指定。以下是參考資料。
https://www.terraform.io/docs/providers/google/guides/provider_reference.html#full-reference
好的,开始行动。
第一次使用时,首先执行 terraform init。
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "google" (hashicorp/google) 3.5.0...
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的文件夹。
其内容如下:
$ ls -la .terraform/plugins/linux_amd64/
合計 50484
drwxr-xr-x 2 sky0621 sky0621 4096 5月 28 23:47 .
drwxr-xr-x 3 sky0621 sky0621 4096 5月 28 23:47 ..
-rwxrwxr-x 1 sky0621 sky0621 82 5月 28 23:47 lock.json
-rwxr-xr-x 1 sky0621 sky0621 51679232 5月 28 23:47 terraform-provider-google_v3.5.0_x5
然后执行 terraform plan ,以了解执行后会是下面这种情况。
但是,在此之前。
首先,terraform命令有哪些子命令?
子命令 (zǐ
$ terraform
Usage: terraform [-version] [-help] <command> [args]
The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.
Common commands:
apply Builds or changes infrastructure
console Interactive console for Terraform interpolations
destroy Destroy Terraform-managed infrastructure
env Workspace management
fmt Rewrites config files to canonical format
get Download and install modules for the configuration
graph Create a visual graph of Terraform resources
import Import existing infrastructure into Terraform
init Initialize a Terraform working directory
login Obtain and save credentials for a remote host
logout Remove locally-stored credentials for a remote host
output Read an output from a state file
plan Generate and show an execution plan
providers Prints a tree of the providers used in the configuration
refresh Update local state file against real resources
show Inspect Terraform state or plan
taint Manually mark a resource for recreation
untaint Manually unmark a resource as tainted
validate Validates the Terraform files
version Prints the Terraform version
workspace Workspace management
All other commands:
0.12upgrade Rewrites pre-0.12 module source code for v0.12
debug Debug output management (experimental)
force-unlock Manually unlock the terraform state
push Obsolete command for Terraform Enterprise legacy (v1)
state Advanced state management
以下是经常使用(或者说是在教程级别经常出现的)一些命令:apply、destroy、init、plan。
顺便说一句(?),我们也做以下两个无害的命令。
-
- fmt
- validate
故意地将格式略微调整,执行 terraform fmt。
$ cat main.tf
provider "google"{
version = "3.5.0"
region = "asia-northeast1"
zone= "asia-northeast1-c"
}
resource "google_compute_network" "vpc_network" {
name = "terraform-network"
}
$
$ terraform fmt
main.tf
$
$ cat main.tf
provider "google" {
version = "3.5.0"
region = "asia-northeast1"
zone = "asia-northeast1-c"
}
resource "google_compute_network" "vpc_network" {
name = "terraform-network"
}
哦,完美了。
接下来是验证。
一般情况下,
$ terraform validate
Success! The configuration is valid.
如果我试着给你一些奇怪的东西,比如版本2或者xyz等于123。
$ cat main.tf
provider "google" {
version2 = "3.5.0"
region = "asia-northeast1"
zone = "asia-northeast1-c"
}
resource "google_compute_network" "vpc_network" {
name = "terraform-network"
xyz = 123
}
$
$ terraform validate
Error: Unsupported argument
on main.tf line 2, in provider "google":
2: version2 = "3.5.0"
An argument named "version2" is not expected here.
$
xyz = 123就不会被生气了。如果修正version2并重新运行,
$ terraform validate
Error: Unsupported argument
on main.tf line 8, in resource "google_compute_network" "vpc_network":
8: xyz = 123
An argument named "xyz" is not expected here.
哎呀,一旦发现问题,验证就会被中断……
终于,计划。
玩乐到此为止,执行terraform plan。
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
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:
# google_compute_network.vpc_network will be created
+ resource "google_compute_network" "vpc_network" {
+ auto_create_subnetworks = true
+ delete_default_routes_on_create = false
+ gateway_ipv4 = (known after apply)
+ id = (known after apply)
+ ipv4_range = (known after apply)
+ name = "terraform-network"
+ project = (known after apply)
+ routing_mode = (known after apply)
+ self_link = (known after apply)
}
Plan: 1 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.
只要写入main.tf的内容只是创建一个网络资源,所以可以简单地像这样完成。
一旦定义了必要的GCP资源,适用于开发一定规模的服务,将会变得非常复杂。
终于将GCP环境应用上了。
$ 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:
# google_compute_network.vpc_network will be created
+ resource "google_compute_network" "vpc_network" {
+ auto_create_subnetworks = true
+ delete_default_routes_on_create = false
+ gateway_ipv4 = (known after apply)
+ id = (known after apply)
+ ipv4_range = (known after apply)
+ name = "terraform-network"
+ project = (known after apply)
+ routing_mode = (known after apply)
+ self_link = (known after apply)
}
Plan: 1 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
google_compute_network.vpc_network: Creating...
Error: Error creating Network: googleapi: Error 403: Access Not Configured. Compute Engine API has not been used in project 691957547651 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/compute.googleapis.com/overview?project=691957547651 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry., accessNotConfigured
on main.tf line 6, in resource "google_compute_network" "vpc_network":
6: resource "google_compute_network" "vpc_network" {
好的,失败了。
由于没有启用所使用资源的 API。它是关于 GCE 的。
并且,错误消息中还给了我们一个链接,要求我们访问此处。
https://console.developers.google.com/apis/api/compute.googleapis.com/overview?project=xxxxxxxxxx
所以嗯,在这里,虽然你可以点击”启用”,但是除了确认terraform执行结果之外,尽可能使用gcloud命令来完成。
激活API
请参考以下链接,以展示可用的服务列表:
https://cloud.google.com/endpoints/docs/openapi/enable-api?hl=ja
$ gcloud services list --available
NAME TITLE
abusiveexperiencereport.googleapis.com Abusive Experience Report API
acceleratedmobilepageurl.googleapis.com Accelerated Mobile Pages (AMP) URL API
〜〜〜
composer.googleapis.com Cloud Composer API
compute.googleapis.com Compute Engine API
computescanning.googleapis.com Compute Scanning API
contacts.googleapis.com Contacts API
container.googleapis.com Kubernetes Engine API
〜〜〜
youtubereporting.googleapis.com YouTube Reporting API
zync.googleapis.com Zync Render API
直接大量出现,但由于错误信息中提到的是GCE,因此可以猜测是以”compute.googleapis.com”开头的。
因此,我会尝试运行”gcloud services enable SERVICE_NAME”来启用它。
$ gcloud services enable compute.googleapis.com
ERROR: (gcloud.services.enable) FAILED_PRECONDITION: Billing must be enabled for activation of service '[compute.googleapis.com, compute.googleapis.com, compute.googleapis.com]' in project 'xxxxxxxxxx' to proceed.
- '@type': type.googleapis.com/google.rpc.PreconditionFailure
violations:
- description: "billing-enabled: Project's billing account is not found. https://console.developers.google.com/project/xxxxxxxxxx/settings"
subject: 'xxxxxxxxxx'
type: serviceusage/billing-enabled
那个?
啊,总之先准备好谷歌账号,已经创建了GCP项目,不过还没有设置计费。
可以试用一下免费试用版,点击下方的”启用”按钮。
在设置过程中会需要信用卡,但是可以免费使用300美元,而且如果不自己设置,不会自动从信用卡扣费。
所以,就像这样,免费试用开始了。
所以,我刚刚重新尝试激活了之前失败的API。
$ gcloud services enable compute.googleapis.com
Operation "operations/xxx.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" finished successfully.
请再次执行terraform apply。
$ 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:
# google_compute_network.vpc_network will be created
+ resource "google_compute_network" "vpc_network" {
+ auto_create_subnetworks = true
+ delete_default_routes_on_create = false
+ gateway_ipv4 = (known after apply)
+ id = (known after apply)
+ ipv4_range = (known after apply)
+ name = "terraform-network"
+ project = (known after apply)
+ routing_mode = (known after apply)
+ self_link = (known after apply)
}
Plan: 1 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
google_compute_network.vpc_network: Creating...
google_compute_network.vpc_network: Still creating... [10s elapsed]
google_compute_network.vpc_network: Still creating... [20s elapsed]
google_compute_network.vpc_network: Still creating... [30s elapsed]
google_compute_network.vpc_network: Still creating... [40s elapsed]
google_compute_network.vpc_network: Creation complete after 50s [id=projects/my-gcp-prj-01/global/networks/terraform-network]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
这次顺利完成了。
让我们来确认成果。
重新确认一下 main.tf 的内容。
$ cat main.tf
provider "google" {
version = "3.5.0"
region = "asia-northeast1"
zone = "asia-northeast1-c"
}
resource "google_compute_network" "vpc_network" {
name = "terraform-network"
}
嗯,已经创建了一个名为terraform-network的VPC网络。
通过Terraform构建的GCP环境的状态
Terraform通过tfstate文件来管理通过命令执行的当前状态。
所以,如果没有这个文件,就无法了解当前状态。
因此,默认情况下,通过执行terraform命令时,会将此文件输出到AWS的S3或GCP的Cloud Storage中,以便(无论谁在哪台机器上执行terraform命令)可以共享相同的状态,这是实际运营中的标准方法。
好的,我来收拾。 de, wǒ .)
因为这只是个试验,虽然创建了 VPC 网络,但是会将其删除。
$ terraform destroy
google_compute_network.vpc_network: Refreshing state... [id=projects/my-gcp-prj-01/global/networks/terraform-network]
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:
# google_compute_network.vpc_network will be destroyed
- resource "google_compute_network" "vpc_network" {
- auto_create_subnetworks = true -> null
- delete_default_routes_on_create = false -> null
- id = "projects/my-gcp-prj-01/global/networks/terraform-network" -> null
- name = "terraform-network" -> null
- project = "my-gcp-prj-01" -> null
- routing_mode = "REGIONAL" -> null
- self_link = "https://www.googleapis.com/compute/v1/projects/my-gcp-prj-01/global/networks/terraform-network" -> null
}
Plan: 0 to add, 0 to change, 1 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
google_compute_network.vpc_network: Destroying... [id=projects/my-gcp-prj-01/global/networks/terraform-network]
google_compute_network.vpc_network: Still destroying... [id=projects/my-gcp-prj-01/global/networks/terraform-network, 10s elapsed]
google_compute_network.vpc_network: Still destroying... [id=projects/my-gcp-prj-01/global/networks/terraform-network, 20s elapsed]
google_compute_network.vpc_network: Still destroying... [id=projects/my-gcp-prj-01/global/networks/terraform-network, 30s elapsed]
google_compute_network.vpc_network: Destruction complete after 39s
Destroy complete! Resources: 1 destroyed.
总结
只要掌握了基本要点,之后就没什么问题了。
在此之后,首先需要了解GCP的服务并学习GCP提供商的配置方法,同时还需要了解Terraform的最佳实践。总之,唯一的办法就是实际操作。