Terraform 関数、式、メタ引数について - AWS 規範ガイダンス

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

Terraform 関数、式、メタ引数について

一般的なプログラミング言語ではなく宣言型設定ファイルを使用する IaC ツールの 1 つの批判は、カスタムプログラムロジックの実装が困難になることです。Terraform 設定では、この問題は関数、式、メタ引数を使用して対処されます。

関数

コードを使用してインフラストラクチャをプロビジョニングする大きな利点の 1 つは、一般的なワークフローを保存して繰り返し再利用し、多くの場合、毎回異なる引数を渡すことです。Terraform 関数は AWS CloudFormation 組み込み関数 に似ていますが、構文はプログラムによる言語での関数の呼び出し方法に似ています。このガイドの例では、substr 、concat 、length base64decode など、いくつかの Terraform 関数に既に気付いているかもしれません。https://developer.hashicorp.com/terraform/language/functions/length組み込み関数 CloudFormation と同様に、Terraform には、設定で使用できる一連の組み込み関数があります。例えば、特定のリソース属性がファイルに直接貼り付けるのが非効率な非常に大きな JSON オブジェクトを取り込む場合、そのオブジェクトを .json ファイルに入れ、Terraform 関数を使用してそれにアクセスできます。次の例では、 file関数はファイルの内容を文字列形式で返し、それを オブジェクトタイプjsondecodeに変換します。

resource "example_resource" "example_resource_name" { json_object = jsondecode(file("/path/to/file.json")) }

表現

Terraform では、条件式 も許可されます。条件式 は、より従来の 3 項演算子構文を使用する点を除いて、 関数に似 CloudFormation conditionています。次の例では、2 つの式はまったく同じ結果を返します。2 番目の例は、Terraform がスプラット式 を呼び出すものです。アスタリスクにより、Terraform はリストをループし、各項目の idプロパティのみを使用して新しいリストを作成します。

resource "example_resource" "example_resource_name" { boolean_value = var.value ? true : false numeric_value = var.value > 0 ? 1 : 0 string_value = var.value == "change_me" ? "New value" : var.value string_value_2 = var.value != "change_me" ? var.value : "New value" } There are two ways to express for loops in a Terraform configuration: resource "example_resource" "example_resource_name" { list_value = [for object in var.ids : object.id] list_value_2 = var.ids[*].id }

メタ引数

前のコード例では、 list_valueおよび list_value_2引数 と呼ばれます。これらのメタ引数の一部については、すでに理解しているかもしれません。Terraform にはいくつかのメタ引数 もあり、引数と同じように動作しますが、いくつかの追加機能があります。

他のメタ引数を使用すると、関数と式の機能をリソースに直接追加できます。例えば、カウントメタ引数は、複数の類似リソースを同時に作成するための便利なメカニズムです。次の例は、メタ引数を使用せずに 2 つの Amazon Elastic Container Service (Amazon EKS) count クラスターを作成する方法を示しています。

resource "aws_eks_cluster" "example_0" { name = "example_0" role_arn = aws_iam_role.cluster_role.arn vpc_config { endpoint_private_access = true endpoint_public_access = true subnet_ids = var.subnet_ids[0] } } resource "aws_eks_cluster" "example_1" { name = "example_1" role_arn = aws_iam_role.cluster_role.arn vpc_config { endpoint_private_access = true endpoint_public_access = true subnet_ids = var.subnet_ids[1] } }

次の例は、メタ引数を使用して count 2 つの Amazon EKS クラスターを作成する方法を示しています。

resource "aws_eks_cluster" "clusters" { count = 2 name = "cluster_${count.index}" role_arn = aws_iam_role.cluster_role.arn vpc_config { endpoint_private_access = true endpoint_public_access = true subnet_ids = var.subnet_ids[count.index] } }

各 にユニット名を付けるには、 のリソースブロック内のリストインデックスにアクセスできますcount.index。しかし、より複雑な類似リソースを複数作成する場合はどうなりますか? そこで for_each メタ引数が入ります。for_each メタ引数は、数値の代わりにリストまたはオブジェクトを渡すことcountを除いて、 と非常によく似ています。Terraform は、リストまたはオブジェクトのメンバーごとに新しいリソースを作成します。これは、ループインデックスではなくリストの内容にアクセスできることを除いてcount = length(list)、 を設定する場合と似ています。

これは、項目のリストまたは単一のオブジェクトの両方で機能します。次の例では、ID id-1として id-0と を持つ 2 IDs つのリソースを作成します。

variable "ids" { default = [ { id = "id-0" }, { id = "id-1" }, ] } resource "example_resource" "example_resource_name" { # If your list fails, you might have to call "toset" on it to convert it to a set for_each = toset(var.ids) id = each.value }

次の例では、Sparky の場合は poodle、Fluffy の場合は chihuahua の 2 つのリソースも作成します。

variable "dogs" { default = { poodle = "Sparky" chihuahua = "Fluffy" } } resource "example_resource" "example_resource_name" { for_each = var.dogs breed = each.key name = each.value }

count.index を使用してカウント内のループインデックスにアクセスできるのと同様に、各オブジェクトを使用して for_each ループ内の各項目のキーと値にアクセスできます。for_each はリストとオブジェクトの両方を反復処理するため、各キーと値は少し混乱して追跡される可能性があります。次の表は、 for_each メタ引数を使用するさまざまな方法と、反復ごとに値を参照する方法を示しています。

for_each タイプ 最初の反復 2 回目の反復
A
[“poodle”, “chihuahua”]
each.key = "poodle" each.value = null
each.key = "chihuahua" each.value = null
B
[ { type = "poodle", name = "Sparky" }, { type = "chihuahua", name = "Fluffy" } ]
each.key = { type = “poodle”, name = “Sparky” } each.value = null
each.key = { type = “chihuahua”, name = “Fluffy” } each.value = null
C
{ poodle = “Sparky”, chihuahua = “Fluffy” }
each.key = “poodle” each.value = “Sparky”
each.key = “chihuahua” each.value = “Fluffy”
D
{ dogs = { poodle = “Sparky”, chihuahua = “Fluffy” }, cats = { persian = “Felix”, burmese = “Morris” } }
each.key = “dogs” each.value = { poodle = “Sparky”, chihuahua = “Fluffy” }
each.key = “cats” each.value = { persian = “Felix”, burmese = “Morris” }
E
{ dogs = [ { type = “poodle”, name = “Sparky” }, { type = “chihuahua”, name = “Fluffy” } ], cats = [ { type = “persian”, name = “Felix” }, { type = “burmese”, name = “Morris” } ] }
each.key = “dogs” each.value = [ { type = “poodle”, name = “Sparky” }, { type = “chihuahua”, name = “Fluffy” } ]
each.key = “cats” each.value = [ { type = “persian”, name = “Felix” }, { type = “burmese”, name = “Morris” } ]

 

したがって、 var.animalsが行 E と等しい場合、次のコードを使用して動物ごとに 1 つのリソースを作成できます。

resource "example_resource" "example_resource_name" { for_each = var.animals type = each.key breeds = each.value[*].type names = each.value[*].name }

または、次のコードを使用して、動物ごとに 2 つのリソースを作成することもできます。

resource "example_resource" "example_resource_name" { for_each = var.animals.dogs type = "dogs" breeds = each.value.type names = each.value.name } resource "example_resource" "example_resource_name" { for_each = var.animals.cats type = "cats" breeds = each.value.type names = each.value.name }