尽量使用Terraform的命令和选项进行实践
首先
「我突然想到,如果能系统地学习一下Terraform的命令和选项都能做些什么,不妨尽量尝试一下吧。」→截至2020年12月14日,我非常后悔。
照顾重要事项
-
- Terraformは毎月のように更新されているので、最新情報は公式ドキュメントを確認してください
-
- 今回、Terraformもproviderは諸事情により最新バージョンではありませんのでご注意ください
- 一度使ったオプションは、他のコマンドでは割愛します(ごめんなさい)
再说一下,关于本文。由于花费的时间比预期的要长,我打算逐渐追加内容…非常抱歉。
环境
苹果操作系统 X 10.14.1 x86_64
$ terraform -version
Terraform v0.13.0
+ provider registry.terraform.io/hashicorp/aws v3.3.0
$ export AWS_ACCESS_KEY_ID=...
$ export AWS_SECRET_ACCESS_KEY=...
$ export AWS_DEFAULT_REGION=ap-northeast-1
这是我在主要使用的tf文件。
根据需要进行修改。
resource "aws_instance" "ec2_instance" {
ami = "ami-0cc75a8978fbbc969"
instance_type = "t2.micro"
tags = {
Name = "qiita_example"
}
}
对应顺序
我会按照这个顺序逐一尝试。
$ 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
0.13upgrade Rewrites pre-0.13 module source code for v0.13
debug Debug output management (experimental)
force-unlock Manually unlock the terraform state
push Obsolete command for Terraform Enterprise legacy (v1)
state Advanced state management
执行土壤建设
可以创建和修改资源的命令。
在执行 terraform apply 命令时会询问是否真的要执行,输入 yes 就可以确认。
可以使用 terraform apply [options] [dir-or-plan] 的格式进行操作。
$ 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:
# aws_instance.ec2_instance will be created
+ resource "aws_instance" "ec2_instance" {
+ ami = "ami-0cc75a8978fbbc969"
+ …
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
aws_instance.ec2_instance: Creating...
aws_instance.ec2_instance: Still creating... [10s elapsed]
aws_instance.ec2_instance: Still creating... [20s elapsed]
aws_instance.ec2_instance: Creation complete after 26s [id=i-xxxxx]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
申请选项列表
$ terraform apply -h
yes
を省略する-backup=pathバックアップファイル terraform.tfstate.backup
のパスを指定する-compact-warningsエラーを含まない Warning
の場合は、省略した形で表示する-lock=truetfstate
ファイルをロックする(またはしない)ように指定する-lock-timeout=0stfstate
ファイルのロックが失敗した場合のリトライまでの時間を指定する-input=true未定義の変数がある場合に変数の入力を求めるかどうかを指定する-no-color実行中のアウトプットを色なしで表示させる-parallelism=n並列で実行するリソース数を指定する-refresh=true実行前に tfstate
ファイルを更新するかどうかを指定する-state=pathtfstate
ファイルのパスを指定する-state-out=path更新する tfstate
ファイルを指定する ※ -state
は読み込む&更新するファイル-target=resourceどのリソースを実行するかを指定する-var ‘foo=bar’変数をコマンド実行時に上書きする-var-file=foo変数を定義した tfvars
ファイルを指定する使用 Terraform 工具执行应用并自动同意
当仅使用”terraform apply”命令时,需要在执行之前确认执行计划并输入”yes”,但是现在无需输入。
$ terraform apply --auto-approve
aws_instance.ec2_instance: Creating...
aws_instance.ec2_instance: Still creating... [10s elapsed]
aws_instance.ec2_instance: Still creating... [20s elapsed]
aws_instance.ec2_instance: Creation complete after 25s [id=i-xxxxx]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
应用terraform-备份。
可以指定备份文件terraform.tfstate.backup的路径。
我尝试指定文件名并将其放置在任意位置。
$ terraform apply -backup=/Users/username/study/terraform/backup/ec2.tfstate.backup
…
aws_instance.ec2_instance: Creation complete after 35s [id=i-xxxxxx]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
备份下面有一个新创建的 ec2.tfstate.backup 文件。
$ tree
.
├── backup
│ └── ec2.tfstate.backup
├── ec2.tf
└── terraform.tfstate
terraform 应用 – 紧凑警告
如果没有包含错误的警告,它会以简化的形式显示。
如果有多个警告,它们会被紧凑地显示在一起,可能会让人感到特别高兴。
$ terraform apply -compact-warnings
…
Warnings:
- Quoted type constraints are deprecated
on ec2.tf line 2
- Interpolation-only expressions are deprecated
on ec2.tf line 11 (and 1 more)
To see the full warning notes, run Terraform without -compact-warnings.
…
如果不使用此选项而出现警告,则会提供详细说明,因此根据需要可以选择使用简易消息是否可以。
$ terraform apply
…
Warning: Quoted type constraints are deprecated
on ec2.tf line 2, in variable "aws_iam_user":
2: type = "list"
Terraform 0.11 and earlier required type constraints to be given in quotes,
but that form is now deprecated and will be removed in a future version of
Terraform. To silence this warning, remove the quotes around "list" and write
list(string) instead to explicitly indicate that the list elements are
strings.
Warning: Interpolation-only expressions are deprecated
…
(and one more similar warning elsewhere)
…
使用terraform apply命令,并设定-lock=true参数。
true : .tfstate ファイルをロックしてくれます。
なお、デフォルトは true です。なので、このオプションを使わない場合も自動的にロックをかけてくれています。
false : ロックかけないようにできる。使うならこっちかな。
然而,根据官方的说法,不对锁进行假设似乎是不推荐的,所以请注意。
所有可能写入状态的操作都会自动进行状态锁定。您不会看到任何关于正在发生的状态锁定的消息。如果状态锁定失败,Terraform将不会继续执行。您可以使用-lock标志禁用大多数命令的状态锁定,但不建议这样做。
$ terraform apply -lock=true # terraform applyと同様
$ terraform apply -lock=false
应用 terraform -lock-timeout=0s
如果.tfstate文件的锁定失败,指定多少秒后进行重试。
https://www.terraform.io/docs/commands/apply.html#lock-timeout-0s
$ terraform apply -lock-timeout=5s
执行terraform应用-输入=true
如果存在未定义的变量,可以设置是否要求输入变量的值。
默认情况下,似乎为 true。
假设我们这样定义变量。
# 未定義の変数
variable "example_instance_type" {}
# instance_typeで変数を使用
resource "aws_instance" "ec2_instance" {
ami = "ami-0cc75a8978fbbc969"
instance_type = var.example_instance_type
tags = {
Name = "qiita_example"
}
}
如果没有使用 var 或者 TF_VAR_ 设置环境变量,将要求在运行时输入。所以只需重新设置环境变量即可。
$ terraform apply -input=true
var.example_instance_type
Enter a value: t2.micro
…
あとは通常通りの動き
然而,如果在选项中将其设置为false而不是true,将不需要输入未定义的变量。因此,如果没有正确设置环境变量,则会被指责说:“嘿,它没有被定义!”所以请注意。
$ terraform apply -input=false
Error: No value for required variable
on ec2.tf line 1:
1: variable "example_instance_type" {}
The root module input variable "example_instance_type" is not set, and has no
default value. Use a -var or -var-file command line argument to provide a
value for this variable.
执行terraform apply命令时,不显示颜色。
通常,apply命令执行期间的输出会标有红色、绿色等颜色,但是现在完全没有颜色。
嗯,就是这样。
$ terraform apply -no-color

在中国境内本地化地转述以下内容,仅需提供一种选择:
使用 Terraform 执行 `terraform apply -parallelism=n` 指令。
通过增加同时执行的资源数量,可以缩短执行时间。
由于默认的并行数是10个,因此首先创建15个EC2实例并计算时间。
$ time terraform apply --auto-approve
…
Apply complete! Resources: 15 added, 0 changed, 0 destroyed.
real 1m2.131s
user 0m5.261s
sys 0m2.269s
看起来花了1分2秒对吧。
接下来,我将尝试将并行执行的数量增加到15个。
虽然我们正在使用 time 来测量时间,但通常只需要 terraform apply -parallelism=20。
$ time terraform apply -parallelism=15 --auto-approve
…
Apply complete! Resources: 15 added, 0 changed, 0 destroyed.
real 0m49.121s
user 0m5.321s
sys 0m1.984s
运行时间似乎减少了大约13秒。
如果处理的资源较多,可能会有相当大的效果。
应用terraform -refresh=true
在执行 apply 或者 plan 之前,您可以设置是否更新 tfstate 文件。默认值为 true。
※ tfstate 文件是一个记录”当前状态”的文件。详见链接:https://www.terraform.io/docs/commands/apply.html#no-color
在执行申请或计划之前,如下的操作都是存在的。(请注意这只是我的理解,如果我理解错了,请谅解)
-
- 根据tfstate文件获取供应商(我的情况是AWS)的资源信息,并更新tfstate文件(刷新)。
-
- 在tfstate文件更新后,进行资源的创建、更新和删除(应用、销毁)。
- 根据创建的资源信息再次更新tfstate文件。

如果没有选项的话,可以选择这个。
$ terraform apply --auto-approve
aws_instance.ec2_instance: Refreshing state... [id=i-xxxx]
aws_instance.ec2_instance: Modifying... [id=i-xxxx]
aws_instance.ec2_instance: Modifications complete after 3s [id=i-xxxx]
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
以下是设置了refresh=false选项的内容。
$ terraform apply --auto-approve -refresh=false
aws_instance.ec2_instance: Modifying... [id=i-xxxx]
aws_instance.ec2_instance: Modifications complete after 3s [id=i-xxxx]
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
应用terraform -state=path进行部署
您可以指定 `tfstate` 文件的路径。请参考 https://www.terraform.io/docs/commands/apply.html#state-path。
$ tree
.
└── ec2.tf
$ terraform apply -state=/Users/username/study/terraform/example/state/ec2.tfstate
$ tree
.
├── ec2.tf
└── state
└── ec2.tfstate
我认为在实际项目中,使用远程存储来管理tfstate文件。(虽然我只在个人使用过,所以还不太清楚…)
对于AWS来说,很多人使用的是”S3桶”或”Terraform云”。
无论如何,管理远程的人会优先考虑远程设置,所以即使使用这个选项也会被忽略。
使用 Terraform 执行并输出状态到指定路径:terraform apply -state-out=path
在下图中,可以指定根据第②步后创建/删除的资源信息来更新tfstate文件。
如果没有特别指定,将更新使用-state指定的文件。
-
- ①で読み込むtfstateファイル
- ①や②の後に更新するtfstateファイル

我已创建了一个用于读取的文件,并确认了其内容。
$ tree
.
├── ec2.tf
└── state.tfstate
$ cat state.tfstate
然后,我尝试加载并更新一个特定的 state.tfstate 文件,同时指定了另一个文件。
$ terraform apply --auto-approve -state=state.tfstate -state-out=newstate.tfstate
无事发生,state.tfstate 没有被更新,而 newstate.tfstate 被成功生成。
$ tree
.
├── ec2.tf
├── state.tfstate
└── newstate.tfstate
$ cat state.tfstate
$ cat new state.tfstate
应用terraform -target=resource
你可以选择特定的资源进行执行。
我会准备两个资源。
:ec2.tf
resource "aws_instance" "ec2_instance_t2" {
ami = "ami-0cc75a8978fbbc969"
instance_type = "t2.micro"
tags = {
Name = "qiita_example"
}
}
resource "aws_instance" "ec2_instance_t3" {
ami = "ami-0cc75a8978fbbc969"
instance_type = "t3.micro"
tags = {
Name = "qiita_example"
}
}
然后,只选择一个目标进行设定并应用。
$ terraform apply -target=aws_instance.ec2_instance_t2
…
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
由于指定特定资源并不是日常使用的功能,因此会出现两个警告。
这是在某种原因下使用的功能。
对于英文原文中的 `terraform apply -var ‘foo=bar’` 的中文释义可以是:使用 `terraform apply` 命令,并使用变量 `foo` 的值设为 `bar`。
您可以在命令执行时覆盖变量。详见https://www.terraform.io/docs/commands/apply.html#var-39-foo-bar-39
:ec2.tf
# 未定義の変数
variable "example_instance_type" {}
# instance_typeで変数を使用
resource "aws_instance" "ec2_instance" {
ami = "ami-0cc75a8978fbbc969"
instance_type = var.example_instance_type
tags = {
Name = "qiita_example"
}
}
你可以像这样覆盖 example_instance_type 变量。
$ terraform apply -var 'example_instance_type=t2.micro'
似乎还有其他许多写法。
使用`terraform apply -var-file=foo`命令应用此配置。
可以指定一个定义了变量的 tfvars 文件。
https://www.terraform.io/docs/commands/apply.html#var-file-foo
# 未定義の変数
variable "example_instance_type" {}
# instance_typeで変数を使用
resource "aws_instance" "ec2_instance" {
ami = "ami-0cc75a8978fbbc969"
instance_type = var.example_instance_type
tags = {
Name = "qiita_example"
}
}
变量定义文件将参考此链接:https://www.terraform.io/docs/configuration/variables.html#variable-definitions-tfvars-files。
example_instance_type = "t2.micro"
指定文件并执行。这样可以将变量提取到文件中,看起来很方便。
$ terraform apply -var-file=testing.tfvars
土地造景控制台
以下有两种选择可以做到。
-
- すでにリソースが作成されている場合の tfstate の確認
- 組み込み関数のテスト
当要结束时,可以使用ctrl + C或ctrl + D。
可以按照terraform console [options] [dir-or-plan]的方式使用。
关于用法, 打开 terraform 控制台后,您可以查看 tfstate 中任意的值。
所以,例如,如果您想知道 “EC2实例的标签”,只需键入 aws_instance.ec2_instance_t2.tags 并回车即可。
$ terraform console
> aws_instance.ec2_instance_t2.tags
{
"Name" = "qiita_example"
}
有关嵌入式函数的测试如下所示。
我认为官方会详细介绍每个函数的示例,例如使用file函数的情况可以像这样使用。
https://www.terraform.io/docs/configuration/functions/file.html
$ terraform console
> file("hello.txt")
Hello World!
在我们想要验证如何进行操作之前使用它似乎是个不错的选择。
另外,稍微偏离主题,不过嵌入函数是用这种方式来使用的。
resource "aws_instance" "ec2_instance_t2" {
ami = "ami-0cc75a8978fbbc969"
instance_type = "t2.micro"
tags = {
Name = "qiita_example"
}
}
output "hello" {
value = file("hello.txt")
}
Hello World!
控制台选项列表
$ terraform console -h
tfstate
ファイルのパスを指定する-var ‘foo=bar’変数をコマンド実行時に上書きする-var-file=foo変数を定義した tfvars
ファイルを指定する由于选项与“apply”相同,因此将省略。
销毁terraform
虽然简单,但可以删除云上的资源。
毁灭选项列表
$ terraform destroy -h
terraform.tfstate.backup
のパスを指定する-auto-approve削除予定のリソース表示や実行確認 yes
を省略する-force非推奨。 -auto-approve
と同様にリソースの削除を行える-lock=truetfstate
ファイルをロックする(またはしない)ように指定する-lock-timeout=0stfstate
ファイルのロックが失敗した場合のリトライまでの時間を指定する-no-color実行中のアウトプットを色なしで表示させる-parallelism=n並列で実行するリソース数を指定する-refresh=true実行前に tfstate
ファイルを更新するかどうかを指定する-state=pathtfstate
ファイルのパスを指定する-state-out=path更新する tfstate
ファイルを指定する ※ -state
は読み込む&更新するファイル-target=resourceどのリソースを削除するかを指定する-var ‘foo=bar’変数をコマンド実行時に上書きする-var-file=foo変数を定義した tfvars
ファイルを指定する新的是力量吧。
强制执行 terraform 销毁
与”auto-approve”相似,可以快速删除资源。
然而,官方并不推荐使用该功能。
$ terraform destroy -force
aws_instance.ec2_instance_t2: Refreshing state... [id=i-056b9686bdb0b7a24]
aws_instance.ec2_instance_t2: Destroying... [id=i-056b9686bdb0b7a24]
aws_instance.ec2_instance_t2: Still destroying... [id=i-056b9686bdb0b7a24, 10s elapsed]
aws_instance.ec2_instance_t2: Still destroying... [id=i-056b9686bdb0b7a24, 20s elapsed]
aws_instance.ec2_instance_t2: Destruction complete after 21s
Destroy complete! Resources: 1 destroyed.
顺便提一下,我试了一下这个选项,它是不是可以像 force_destroy 一样强制删除 S3 存储桶中的对象,但结果完全是另一个功能。
resource "aws_s3_bucket" "takkii_s3_bucket" {
bucket = "alb-log-pragmatic-terraform-takkii1010"
force_destroy = false
…
}
$ terraform destroy -force
aws_s3_bucket.takkii_s3_bucket: Refreshing state... [id=alb-log-pragmatic-terraform-takkii1010]
aws_s3_bucket.takkii_s3_bucket: Destroying... [id=alb-log-pragmatic-terraform-takkii1010]
Error: error deleting S3 Bucket (alb-log-pragmatic-terraform-takkii1010): BucketNotEmpty: The bucket you tried to delete is not empty. You must delete all versions in the bucket.
status code: 409, request id: 20DD64E032887A3D, host id: xxx=
土地整治环境
这个功能似乎将在未来被删除,它建议使用 terraform workspace 作为替代。
因此,我打算在 terraform workspace 中尝试使用详细信息。
$ terraform env
Warning: the "terraform env" family of commands is deprecated.
"Workspace" is now the preferred term for what earlier Terraform versions
called "environment", to reduce ambiguity caused by the latter term colliding
with other concepts.
The "terraform workspace" commands should be used instead. "terraform env"
will be removed in a future Terraform version.
Usage: terraform workspace
new, list, show, select and delete Terraform workspaces.
格式化Terraform代码
这是一个能够格式化Terraform配置文件的命令。JSON格式不被支持。
此外,由于Terraform每个版本的格式略有不同,建议在升级版本后重新格式化所有文件以统一格式。
-
- フォーマット対象
.tf
.tfvars
フォーマット対象外
.tf.json
.tfvars.json
fmt 可选列表
$ terraform fmt -h
-check
とほぼ同じ)-diffフォーマット差分をみる-checkフォーマットの修正が入るファイルがあるかどうかをチェック-no-color実行中のアウトプットを色なしで表示させる ※公式ドキュメントには記載ないですね-recursiveサブディレクトリ含めてフォーマットをかける使用命令”terraform fmt -list=false”进行格式化,不显示列表。
如果没有选项,它会输出格式化的文件列表。
$ terraform fmt
ec2_first.tf
ec2_second.tf
所以,使用此选项可以隐藏文件列表。
$ terraform fmt -list=false
$ terraform fmt -list=true
ec2_first.tf
ec2_second.tf
terraform fmt -write=false 可以改写为:terraform格式化 -write=false
您可以选择是否覆盖目标格式的文件。
如果将设置为不覆盖,则只会在控制台上显示格式错误的文件。文件当然不会被覆盖,只会告知目标文件的存在。
$ terraform fmt -write=false
ec2_first.tf
terraform fmt -check 和结果看起来一样。
terraform 格式化 – 差异性
您可以查看格式之间的差异。请访问此链接了解更多信息:
https://www.terraform.io/docs/commands/fmt.html#diff
这个可以用正负数来显示差异。
$ terraform fmt -diff
ec2_first.tf
--- old/ec2_first.tf
+++ new/ec2_first.tf
@@ -1,8 +1,8 @@
resource "aws_instance" "ec2_instance_t2" {
- ami = "ami-0cc75a8978fbbc969"
+ ami = "ami-0cc75a8978fbbc969"
instance_type = "t2.micro"
- tags = {
- Name = "qiita_example"
+ tags = {
+ Name = "qiita_example"
}
}
terraform fmt -check 可以进行格式检查。
您可以检查是否存在需要修正格式的文件。请注意,这只是一个检查,不会执行任何修正操作。
https://www.terraform.io/docs/commands/fmt.html#check
$ terraform fmt -check
ec2_first.tf
执行 `terraform fmt -no-color` 命令。
因为与”terraform apply -no-color”相同,所以省略。
递归地对Terraform进行格式化。
如果存在子目录,它会为您整体进行格式化。
默认情况下,仅指定的目录和当前目录是适用的,因此当您希望一次性整体进行操作时,这将非常方便。
https://www.terraform.io/docs/commands/fmt.html#recursive
$ terraform fmt -recursive
使用terraform获取
这个命令会帮你下载位于根目录下的模块。
https://www.terraform.io/docs/commands/get.html
Terraform的模块可以通过执行terraform init和terraform get来预先获取模块,以便使用,这就是为此提供的功能。
假设我们以这样的结构为例。
$ tree
.
├── ec2
│ └── main.tf
├── iam_role
│ └── main.tf
├── main.tf
├── terraform.tfstate
└── terraform.tfstate.backup
如果执行terraform get命令,它会读取子目录中的文件。
因此,之后执行terraform apply命令就可以一次性完成创建。
$ terraform get
- describe_regions_for_ec2 in iam_role
- ec2_instance_t2 in ec2
另外,在get命令中,似乎会将模块下载到.terraform文件夹中。
在执行get命令后,会创建module文件夹和modules.json文件。
这是内容的样子。
$ tree -a
.
├── .terraform
│ ├── modules
│ │ └── modules.json
│ └── plugins
│ ├── registry.terraform.io
…
$ cat .terraform/modules/modules.json
{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"describe_regions_for_ec2","Source":"./iam_role","Dir":"iam_role"},{"Key":"ec2_instance_t2","Source":"./ec2","Dir":"ec2"}]}
获取选项清单
$ terraform get -h
更新并获取terraform配置。
当您检查已加载的模块时,它会为您提供更新并安装任何更改。
我們先對剛剛建立的模組做一些修改,然後再執行看看。
$ terraform get -update
- describe_regions_for_ec2 in iam_role
- ec2_instance_t2_micro in ec2_updated
$ cat .terraform/modules/modules.json
{"Modules":[{"Key":"ec2_instance_t2_micro","Source":"./ec2","Dir":"ec2"},{"Key":"","Source":"","Dir":"."},{"Key":"describe_regions_for_ec2","Source":"./iam_role","Dir":"iam_role"},{"Key":"ec2_instance_t2","Source":"./ec2","Dir":"ec2"}]}
看起来,EC2实例t2微型已成功安装。从上述情况来看,并没有删除先前的安装内容,它仍然存在。
无需颜色,获取terraform
由于与 terraform apply -no-color 相同,因此省略。
Terraform 图示
通过DOT格式可以输出资源之间的依赖关系。
最终可以使用GraphViz的dot命令将其表示为图。
https://www.terraform.io/docs/commands/graph.html
另外,似乎将以下形式称为DOT形式。
$ terraform graph
digraph {
compound = "true"
newrank = "true"
subgraph "root" {
"[root] aws_instance.ec2_instance_t2 (expand)" [label = "aws_instance.ec2_instance_t2", shape = "box"]
"[root] provider[\"registry.terraform.io/hashicorp/aws\"]" [label = "provider[\"registry.terraform.io/hashicorp/aws\"]", shape = "diamond"]
"[root] aws_instance.ec2_instance_t2 (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/aws\"]"
"[root] meta.count-boundary (EachMode fixup)" -> "[root] aws_instance.ec2_instance_t2 (expand)"
"[root] provider[\"registry.terraform.io/hashicorp/aws\"] (close)" -> "[root] aws_instance.ec2_instance_t2 (expand)"
"[root] root" -> "[root] meta.count-boundary (EachMode fixup)"
"[root] root" -> "[root] provider[\"registry.terraform.io/hashicorp/aws\"] (close)"
}
}
利用GraphViz的dot命令将其转换为图形。我参考了官方指南,并尝试生成了一个jpg文件。
$ terraform graph | dot -Tjpg > graph.jpg


图表选项列表
$ terraform graph -h
terraform graph-绘制循环
如果依赖关系存在循环,会进行强调显示。
首先,我们会创建一个循环的资源。
resource "aws_instance" "ec2_instance_t2_A" {
ami = "ami-0cc75a8978fbbc969"
instance_type = [ aws_instance.ec2_instance_t2_B.instance_type ]
tags = {
Name = "qiita_example"
}
}
resource "aws_instance" "ec2_instance_t2_B" {
ami = "ami-0cc75a8978fbbc969"
instance_type = [ aws_instance.ec2_instance_t2_A.instance_type ]
tags = {
Name = "qiita_example"
}
}
$ terraform graph -draw-cycles | dot -Tjpg > graph.jpg

另外,使用 terraform plan 也能检测到循环依赖的问题!虽然在其他方法中也可以进行检测,但用图表更加直观易懂呢。
terraform graph -type=plan 的中文释义是什么?
你可以选择要显示的图表类型。
可以选择的有计划,计划销毁,申请,验证,输入,刷新这六个选项。
首先创建了一个名为A的实例,并将其输出到图表中。
值得注意的是,默认情况下是没有明确指定类型为-plan的,所以这里没有明确指定。
$ terraform graph | dot -Tjpg > graph.jpg

在“type=plan-destroy”操作中,输出了将要被删除的资源。
$ terraform graph -type=plan-destroy | dot -Tjpg > graph.jpg

使用-type=refresh会导致meta.count-boundary消失。
虽然在刷新时显示了资源,但我不太明白为什么会消失…
https://github.com/hashicorp/terraform/issues/20063
$ terraform graph -type=refresh | dot -Tjpg > graph.jpg

使用”type=apply”时,资源消失了…。
$ terraform graph -type=apply | dot -Tjpg > graph.jpg

不,对不起,我对type的使用方法还不太了解。。。
我感觉我的使用方式是不正确的。这是一个作业吧。。。
使用 Terraform 导入
使用 Terraform 之外的方式来导入并获取已经创建的资源。
之前一直用手工設定,但現在考慮轉移到Terraform時可以使用。
terraform import命令的用法如下:[options]为可选项,需要提供ADDRESS和ID这两个参数。
ADDRESS代表资源名称,可以使用aws_instance.ec2_instance_t2来表示。
在控制台上随意创建EC2实例后,在本地创建一个空的 main.tf 文件。
resource "aws_instance" "ec2_instance_t2" {}
terraform {
required_version = "0.13.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "3.3.0"
}
}
}
从控制台上复制EC2实例的ID并执行。
$ terraform init
$ $ terraform import aws_instance.ec2_instance_t2 i-xxxxxxxx
aws_instance.ec2_instance_t2: Importing from ID "i-xxxxxxxx"...
aws_instance.ec2_instance_t2: Import prepared!
Prepared aws_instance for import
aws_instance.ec2_instance_t2: Refreshing state... [id=i-xxxxxx]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
当检查 terraform.tfstate 时,发现已经进行了更新。
$ cat terraform.tfstate
{
"version": 4,
"terraform_version": "0.13.0",
"serial": 1,
"lineage": "def80f38-083c-bd15-1aef-529e894a5533",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "aws_instance",
"name": "ec2_instance_t2",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 1,
"attributes": {
"ami": "ami-00f045aed21a55240",
"arn": "arn:aws:ec2:ap-northeast-1:xxxxx:instance/i-xxxxxxxxx",
"associate_public_ip_address": true,
"availability_zone": "ap-northeast-1d",
"cpu_core_count": 1,
"cpu_threads_per_core": 1,
"credit_specification": [
{
"cpu_credits": "standard"
}
],
…
然而,它仅仅更新 terraform.tfstate 文件,并不更新 main.tf 文件。
也就是说,如果 main.tf 和 terraform.tfstate 之间存在差异,就必须修改 main.tf(太麻烦了)。
你是打算用看到的这些东西填满周围吗?
$ terraform state show aws_instance.ec2_instance_t2
# aws_instance.ec2_instance_t2:
resource "aws_instance" "ec2_instance_t2" {
ami = "ami-00f045aed21a55240"
arn = "arn:aws:ec2:ap-northeast-1:xxxxxx:instance/i-xxxxxxx"
associate_public_ip_address = true
availability_zone = "ap-northeast-1d"
…
目前的 Terraform 导入实现只能将资源导入状态中,无法生成配置文件。未来的 Terraform 版本将会添加生成配置文件的功能。
将来似乎也会做main.tf。
导入选项列表
$ terraform import -h
terraform.tfstate.backup
のパスを指定する-config=path設定ファイルやディレクトリへのパスを指定する-allow-missing-configresource
blockがなくても実行可能にする-input=true未定義の変数がある場合に変数の入力を求めるかどうかを指定する-lock=truetfstate
ファイルをロックする(またはしない)ように指定する-lock-timeout=0stfstate
ファイルのロックが失敗した場合のリトライまでの時間を指定する-no-color実行中のアウトプットを色なしで表示させる-state-out=PATH更新する tfstate
ファイルを指定する ※ -state
は読み込む&更新するファイル-var ‘foo=bar’変数をコマンド実行時に上書きする-var-file=foo変数を定義した tfvars
ファイルを指定する看起来没有使用过的选项有两个:-config和-allow-missing-config。
土壤引入-配置=路径。
您可以指定导入文件或目录的路径来进行导入。
举个例子,当想要使用位于另一个目录中的文件时
$ tree
.
├── import_config_file
│ └── main.tf
└── import_ec2
可以这样使用。
$ terraform import -config=../import_config_file aws_instance.ec2_instance_t2 i-xxxxxxx
aws_instance.ec2_instance_t2: Importing from ID "i-xxxxxxx"...
aws_instance.ec2_instance_t2: Import prepared!
Prepared aws_instance for import
aws_instance.ec2_instance_t2: Refreshing state... [id=i-xxxxxxx]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
$ tree
.
├── import_config_file
│ └── main.tf
└── import_ec2
└── terraform.tfstate
批次导入 – 允许缺少配置
假设没有设置资源的阻塞。
provider "aws" {}
使用 “allow-missing-config” 选项,似乎可以在没有设置的情况下进行导入。
$ terraform import -allow-missing-config aws_instance.ec2_instance_t2 i-xxxxxx
aws_instance.ec2_instance_t2: Importing from ID "i-xxxxxx"...
aws_instance.ec2_instance_t2: Import prepared!
Prepared aws_instance for import
aws_instance.ec2_instance_t2: Refreshing state... [id=i-xxxxxxx]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
Import does not generate resource configuration, you must create a resource
configuration block that matches the current or desired state manually.
If there is no matching resource configuration block for the imported
resource, Terraform will delete the resource on the next "terraform apply".
It is recommended that you run "terraform plan" to verify that the
configuration is correct and complete.
最后
有许多命令和选项,我自己的理解速度较慢,需要花费很多时间。
所以,我打算从现在开始逐渐添加并推进。
如果有任何地方有错或者需要纠正的地方,请务必告诉我。