尽量使用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
オプション内容-auto-approve作成予定のリソース表示や実行確認 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
undefined

在中国境内本地化地转述以下内容,仅需提供一种选择:

使用 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

在执行申请或计划之前,如下的操作都是存在的。(请注意这只是我的理解,如果我理解错了,请谅解)

    1. 根据tfstate文件获取供应商(我的情况是AWS)的资源信息,并更新tfstate文件(刷新)。

 

    1. 在tfstate文件更新后,进行资源的创建、更新和删除(应用、销毁)。

 

    根据创建的资源信息再次更新tfstate文件。
undefined

如果没有选项的话,可以选择这个。

$ 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ファイル
undefined

我已创建了一个用于读取的文件,并确认了其内容。

$ 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
オプション内容-state=pathtfstate ファイルのパスを指定する-var ‘foo=bar’変数をコマンド実行時に上書きする-var-file=foo変数を定義した tfvars ファイルを指定する

由于选项与“apply”相同,因此将省略。

销毁terraform

虽然简单,但可以删除云上的资源。

毁灭选项列表

$ terraform destroy -h
オプション内容-backup=pathバックアップファイル 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
オプション内容-list=falseフォーマットをかけたファイル一覧を表示するか-write=falseファイルの上書きをするかどうか(下の -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
オプション内容-updateすでに一度読み込んだモジュールに更新がないかチェックし、変更があればインストールする-no-color実行中のアウトプットを色なしで表示させる

更新并获取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
graph.jpg
graph.jpg

图表选项列表

$ terraform graph -h
オプション内容-draw-cycles依存関係に循環があった場合、強調表示ができる-type=plan表示するグラフのタイプを選択できる-module-depth=n(非推奨)表示するmoduleの深さを指定する

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
graph.jpg

另外,使用 terraform plan 也能检测到循环依赖的问题!虽然在其他方法中也可以进行检测,但用图表更加直观易懂呢。

terraform graph -type=plan 的中文释义是什么?

你可以选择要显示的图表类型。

可以选择的有计划,计划销毁,申请,验证,输入,刷新这六个选项。

首先创建了一个名为A的实例,并将其输出到图表中。
值得注意的是,默认情况下是没有明确指定类型为-plan的,所以这里没有明确指定。

$ terraform graph | dot -Tjpg > graph.jpg
graph.jpg

在“type=plan-destroy”操作中,输出了将要被删除的资源。

$ terraform graph -type=plan-destroy | dot -Tjpg > graph.jpg
graph.jpg

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

$ terraform graph -type=refresh | dot -Tjpg > graph.jpg
graph.jpg

使用”type=apply”时,资源消失了…。

$ terraform graph -type=apply | dot -Tjpg > graph.jpg
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
オプション内容-backup=pathバックアップファイル 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.

最后

有许多命令和选项,我自己的理解速度较慢,需要花费很多时间。
所以,我打算从现在开始逐渐添加并推进。

如果有任何地方有错或者需要纠正的地方,请务必告诉我。

bannerAds