🔖

Terraform 1.8.0 のリリースノートを読んでみた

2024/05/13に公開

こんにちは、クラウドエース SRE 部の阿部です。
この記事では、2024 年 4 月 10 日にリリースされた Terraform 1.8.0 の変更点についてざっくり説明します。

ここ最近、長くお休みをいただいていたため、気付いたら 1.8.0 どころか 1.8.3 までリリースされておりますが、淡々と紹介します。
なお、1.8.1 ~ 1.8.3 は主にマイナーなバグフィックスが中心のため、気になった箇所以外は割愛します。

1.8.0 の更新内容

Terraform 1.8.0 のリリースノートの内容を記載します。

新機能

  • プロバイダ定義関数(provider-defined functions)が使用できるようになった。
  • moved ブロックで、異なるリソースタイプでも実体として同じリソースを指している場合は State 上の所有権を移動できるようになった。
  • issensitive 関数が追加された。 issensitive 関数は参照する値が sensitive としてマークされているときに true を返す。

機能強化

  • terraform test でファイルレベル変数がグローバルで参照できるようになった。
  • import ブロックで設定を生成するとき、JSON 文字列を生成するときに単純文字列ではなく jsonencode 関数による呼び出しを含む文字列として生成する動作に変更された。
  • terraform plan 時に、リスト要素がある場合の差分表示が変更された。以前は差分があった場合にリスト全体を表示していたが、新しいバージョンでは個別の要素差分のみを表示するようになった。
    • CHANGELOG からは再現する設定を確認できなかったのですが、自分が調査した範囲では PR#34677 が該当し、 Helm Provider の helm_releasevalues 引数の差分検出を改善する修正ということでした。
  • terraform providers lock コマンドに -enable-plugin-cache オプションが追加された。
  • decode_tfvars, encode_tfvars, encode_expr ビルトイン関数が追加された。
  • terraform show コマンドで参照できるフラグに applyablecomplete が追加された。

その他の変更

  • S3 リモートバックエンドの古い認証方式が削除された。(use_legacy_workflow 引数が削除された。)
  • Terraform v1.8 にアップグレードした後の最初の plan 処理で、実際にはない差分を検出することがある。
  • macOS 10.15 Catalina のサポートが終了した。
  • jsonencode 関数で、バックスペース(U+0008)とフォームフィード(U+000C)の出力方法を変更した。

「その他の変更」に記載した項目は、Upgrading to Terraform v1.8 により詳細な内容が記載されていますので、アップグレード前に確認するとよいでしょう。

1.8.1 ~ 1.8.3 の主な更新内容

前述の通り、1.8.1 ~ 1.8.3 はマイナーなバグフィックスや改善に関する変更のみで機能追加は特にありません。
ただ、1.8.2 から Terraform の ZIP ファイルに実行ファイルとは別に LICENSE.txt を含めるようになりました。LICENSE.txt の内容は BUSL1.1 のライセンス条項です。
Terraform バイナリのダウンロードを自動化している場合は、1.8.2 のリリースノートで説明されているようにコマンド実行の引数等に注意が必要です。

個人的に気になった更新内容の紹介

ここからはリリースノートに記載されていた内容から個人的に気になった部分をピックアップして細かく説明します。

プロバイダ定義関数

Terraform の言語仕様として、値を加工するために使用する関数(ビルトイン関数)が提供されています。
Terraform における表現をより柔軟にできる関数ですが、これまではビルトイン関数を任意に実装する方法はありませんでした。
1.8.0 から、プロバイダで独自に関数を提供することができるようになりました。下記の様な形式で呼び出すことができます。

provider::provider_name::provider_defined_function(argumants)

provider_name はプロバイダの名前(例: google)

Google Cloud Provider では、v5.23.0 から以下のプロバイダ定義関数を使用できます。

  • location_from_id
  • name_from_id
  • project_from_id
  • region_from_id
  • zone_from_id
  • region_from_zone

XXX_from_id 関数は、 ID 形式または SelfLink 形式の値から、関数名になっている値(project,location,region,zone 等)を取得する関数です。例えば、project_from_id 関数の場合は projects/project-id のような形式から project-id だけ取得するときに使用します。
region_from_zone 関数は、ゾーン名からリージョン名を取得する関数です。例えば、 asia-northeast1-a から asia-northeast1 を取得するときに使用します。

今のところ、Google Cloud Provider で提供されるプロバイダ定義関数は全て正規表現(regex ビルトイン関数)でも実現できる内容で、そこまで積極的に使用するものでもないかなという気がします。
また、筆者のエディタである IntelliJ IDEA の拡張機能だと現時点ではうまく構文解析できず、プロバイダ定義関数を含む設定ファイルはエラー状態(赤い波線が表示され色分け表示できない状態)になりました。その意味でも、今すぐ使いたい機能ではないかなという感じです。
これから便利な関数が出てくるかもしれないので期待したいです。

import ブロックによる設定生成時の JSON 文字列の取り扱い動作

リソースの属性が JSON 形式の場合に、 terraform plan -generate-config-out で生成された場合の設定の形式が変わります。
属性が JSON 形式のリソースは、実はそんなにないのであまり効果を実感できないのですが、 Google Cloud Provider で思い当たるのは Monitoring Dashboard リソース(google_monitoring_dashboard)です。

以下のような違いがありました。

Terraform 1.7.5 の場合

# __generated__ by Terraform from "projects/********/dashboards/7424800619854541663"
resource "google_monitoring_dashboard" "test" {
  dashboard_json = "{\"displayName\":\"Log Based TESTTEST\",\"etag\":\"564cbb723b9f725e7770a914155ddfb7\",\"gridLayout\":{\"columns\":\"2\",\"widgets\":[{\"title\":\"logging/user/test/logbased-alert\",\"xyChart\":{\"chartOptions\":{\"mode\":\"COLOR\"},\"dataSets\":[{\"plotType\":\"LINE\",\"targetAxis\":\"Y1\",\"timeSeriesQuery\":{\"timeSeriesFilter\":{\"aggregation\":{\"perSeriesAligner\":\"ALIGN_SUM\"},\"filter\":\"metric.type=\\\"logging.googleapis.com/user/test/logbased-alert\\\" resource.type=\\\"gce_instance\\\"\"},\"unitOverride\":\"1\"}}],\"timeshiftDuration\":\"0s\",\"yAxis\":{\"label\":\"y1Axis\",\"scale\":\"LINEAR\"}}}]},\"name\":\"projects/********/dashboards/7424800619854541663\"}"
  project        = "********"
}

Terraform 1.8.3 の場合

# __generated__ by Terraform
# Please review these resources and move them into your main configuration files.

# __generated__ by Terraform from "projects/********/dashboards/7424800619854541663"
resource "google_monitoring_dashboard" "test" {
  dashboard_json = jsonencode({
    displayName = "Log Based TESTTEST"
    etag        = "564cbb723b9f725e7770a914155ddfb7"
    gridLayout = {
      columns = "2"
      widgets = [{
        title = "logging/user/test/logbased-alert"
        xyChart = {
          chartOptions = {
            mode = "COLOR"
          }
          dataSets = [{
            plotType   = "LINE"
            targetAxis = "Y1"
            timeSeriesQuery = {
              timeSeriesFilter = {
                aggregation = {
                  perSeriesAligner = "ALIGN_SUM"
                }
                filter = "metric.type=\"logging.googleapis.com/user/test/logbased-alert\" resource.type=\"gce_instance\""
              }
              unitOverride = "1"
            }
          }]
          timeshiftDuration = "0s"
          yAxis = {
            label = "y1Axis"
            scale = "LINEAR"
          }
        }
      }]
    }
    name = "projects/********/dashboards/7424800619854541663"
  })
  project = jsonencode(********)
}

個人の所感ではありますが、Terraform 1.8.3 で生成されたコードの方がメンテナンス性が高いと感じますね。エディタのフォーマットが効くので見やすいと思います。

まとめ

Terraform 1.8 の機能追加や変更点について紹介しました。
非互換動作が多いものの、プロバイダ定義関数以外はやや小粒な更新が多かったかなと思います。
4 月は Hashicorp が IBM に買収されたりと、Terraform ユーザーとしても大きなニュースがありましたが、引き続き Terraform が IaC ツールとして発展していけるとよいなと感じます。
この記事が、Terraform を利用する方のお役に立ちましたら幸いです。

Discussion