🐶

Terraform 1.5 の新機能

2023/08/08に公開

こちらに記事を書くタイミングは 1.5 リリースより遅れましたが、一応備忘録的に貼っておきます
https://github.com/hashicorp/terraform/releases/tag/v1.5.0

import blocks / Generating configuration for imported resources

https://www.hashicorp.com/blog/terraform-1-5-brings-config-driven-import-and-checks

terraform 1.5 から plannable import という機能が追加されます
管理対象となるリソース(AWS、GCP、Datadog 等)にのみ定義されている内容を、terraform plan を実施しながら安全に Terraform 管理下に Import することができる機能です

この機能を応用することによって、リソース側にのみ定義されている内容をもとに HCL ファイルを生成することができます。

この機能の使い方、手順については詳細が長くなるので、この記事の末尾にあらためて後述します。

check blocks

https://www.hashicorp.com/blog/terraform-1-5-brings-config-driven-import-and-checks
https://developer.hashicorp.com/terraform/tutorials/configuration-language/checks?product_intent=terraform

Terraform の設定の中で、特定の処理の結果の assertion を行なうことができるように成りました

terraform apply の結果が意図通りか否かについて terraform 単独で確認ができるようになった、ということです。

以下は公式サイトに貼られていた記述例です

check "health_check" {
  data "http" "example" {
    url = "https://${aws_lb.example.dns_name}"
  }
 
  assert {
    condition     = data.http.example.status_code == 200
    error_message = "${data.http.example.url} returned an unhealthy status code"
  }
}

(設定した LB 経由でアクセスして、ステータスコード200が返却されるか確認)

check "certificate" {
  assert {
    condition     = aws_acm_certificate.cert.status == "ERRORED"
    error_message = "Certificate status is ${aws_acm_certificate.cert.status}"
  }
}

(ACMで管理している証明書が ERRORED かどうか確認。概ねのケース(ACM で error が発生していないケース)で、こちらの check は fail する)

デプロイやプロビジョニング後のリソース状況の監視は、会社や現場によって様々なやり方をしていると思いますが、選択肢の一つとして terraform の check で行う、というのも頭に入れておいても良いかな、と感じました。

plantimestamp の追加

terraform plan を行った時間の timestamp を取得するための機能が追加されたようです
https://github.com/hashicorp/terraform/pull/32980
具体的なユースケースはちょっとわかってません

strcontains の追加

第一引数で渡された文字列に、第二引数で渡された文字列が含まれているかどうか、を判定する関数です
https://github.com/hashicorp/terraform/pull/33069

軽微な修正ですが、使い所はありそうです

> strcontains("hello world", "wor")
true

> strcontains("hello world", "wod")
false

Appendix. plannable import の手順

terraform

terraform 1.5 を有効にします。以下では tfenv を用いています

$ tfenv install 1.5.0
$ tfenv use 1.5.0
$ tfenv list
* 1.5.0 (set by /opt/homebrew/Cellar/tfenv/3.0.0/version)
  1.4.6
  1.4.5
$ terraform init -upgrade

import ファイル

https://registry.terraform.io/providers/DataDog/datadog/latest/docs/data-sources/monitor

今回 Import するのは Datadog の Monitor とします。
以下のような形で、import したい Monitor の設定を記述します

import {
  id = 1234567890
  to = datadog_monitor.sada_activity
}

id には monitor の id (URL の末尾に記載されているもの)
to には、生成後の TF ファイルの resource 名を記載します
上記の記述だと、生成後の resource 名は以下のようになります

resource "datadog_monitor" "sada_activity" {

terraform plan

上記まで準備した段階で、terraform plan コマンドを実行すると、以下のようなエラーが表示されます

Planning failed. Terraform encountered an error while generating this plan.

╷
│ Error: Import block target does not exist
│ 
│   on import_sada.tf line 1:
│    1: import {
│ 
│ The target for the given import block does not exist. If you wish to automatically generate config for this resource, use the -generate-config-out option within
│ terraform plan. Otherwise, make sure the target resource exists within your configuration. For example:
│ 
│   terraform plan -generate-config-out=generated.tf
╵

これは、import ブロックで定義している内容がどの TF ファイルにも存在してないためエラーになっています。
plan 実行時に自動的に HCL の生成まで行う場合は、エラーログでも表示されているように以下の生成する TF ファイルを指定してコマンドを実行します

terraform plan -generate-config-out=generated.tf

生成時に場合によってエラーが発生しますが、インポートされた内容を適宜最適なものに手で修正し、差分が発生しなくなるまで修正を行います

Planning failed. Terraform encountered an error while generating this plan.

╷
│ Warning: Config generation is experimental
│ 
│ Generating configuration during import is currently experimental, and the generated configuration format may change in future versions.
╵
╷
│ Error: Conflicting configuration arguments
│ 
│   with datadog_monitor.sada_activity,
│   on generated.tf line 11:
│   (source code not available)
│ 
│ "no_data_timeframe": conflicts with on_missing_data
╵
╷
│ Error: Conflicting configuration arguments
│ 
│   with datadog_monitor.sada_activity,
│   on generated.tf line 15:
│   (source code not available)
│ 
│ "notify_no_data": conflicts with on_missing_data
╵
╷
│ Error: Conflicting configuration arguments
│ 
│   with datadog_monitor.sada_activity,
│   on generated.tf line 16:
│   (source code not available)
│ 
│ "on_missing_data": conflicts with notify_no_data
╵

terraform plan で差分が無くなったら、あとは terraform apply を実施すると、対象リソースの情報が terraform の tfstate に書き込まれ、terraform 管理下に置かれるようになります

usecase

Datadog 等、HCL ファイルでイチから定義を書いていくのが大変なツールの場合、

  • いったん Datadog の画面から定義を作成
  • その内容を import で取り込んで terraform 配下におく

というプロセスが取れるため、定義を書くのが以前より楽になる可能性があります
(今までも import 自体は行えましたが、以前より手順が楽になりました)

また、既存のリソースの import 処理について import 定義を記載して宣言的に行うことで、import 処理自体も PullRequest のレビュー対象に置くことができるようになります。
このことは大規模で重要なリソースについて terraform 管理を行っている場合、安全に作業を行う補助になると思います。

Discussion