メインコンテンツにスキップ

文字列とテンプレート

文字列リテラルは、OpenTofuで最も複雑な種類のリテラル式であり、最も一般的に使用されるものでもあります。

OpenTofuは、文字列に対して引用符付き構文と「ヒアドキュメント」構文の両方をサポートしています。これらの構文はどちらも、値を補間し、テキストを操作するためのテンプレートシーケンスをサポートしています。

引用符付き文字列

引用符付き文字列は、ストレートな二重引用符文字(")で区切られた一連の文字です。

コードブロック
"hello"

エスケープシーケンス

引用符付き文字列では、バックスラッシュ文字がエスケープシーケンスとして機能し、次の文字がエスケープ動作を選択します。

シーケンス置換
\n改行
\rキャリッジリターン
\tタブ
\"リテラル引用符(文字列を終了させずに)
\\リテラルバックスラッシュ
\uNNNN基本多言語面からのUnicode文字(NNNNは4桁の16進数)
\UNNNNNNNN補助面からのUnicode文字(NNNNNNNNは8桁の16進数)

バックスラッシュを使用しない2つの特別なエスケープシーケンスもあります。

シーケンス置換
$${リテラル${。補間シーケンスを開始しません。
%%{リテラル%{。テンプレートディレクティブシーケンスを開始しません。

ヒアドキュメント文字列

OpenTofuは、Unixシェル言語に触発された「ヒアドキュメント」スタイルの文字列リテラルもサポートしており、複数行の文字列をより明確に表現できます。

コードブロック
<<EOT
hello
world
EOT

ヒアドキュメント文字列は、以下で構成されます。

  • 次の構成要素で構成される開始シーケンス
    • ヒアドキュメントマーカー(<<または<<- — 2つの小なり記号で、インデントされたヒアドキュメントの場合はオプションでハイフンを付けます)
    • 自分で選択したデリミタ単語
    • 改行
  • 任意の行数にまたがることができる文字列の内容
  • 選択したデリミタ単語。単独の行に記述します(インデントされたヒアドキュメントではインデントが許可されます)。

行末に任意の識別子が続く<<マーカーは、シーケンスを導入します。OpenTofuは、導入子で指定された識別子だけで構成される行が見つかるまで、後続の行を処理します。

上記の例では、EOTが選択された識別子です。任意の識別子を使用できますが、慣例ではこの識別子はすべて大文字で、EOで始まります。これは「end of」を意味します。この場合、EOTは「end of text(テキストの終わり)」を表します。

JSONまたはYAMLの生成

JSONまたはYAMLを生成するために「ヒアドキュメント」文字列を使用しないでください。代わりに、jsonencode関数またはyamlencode関数を使用して、OpenTofuが有効なJSONまたはYAML構文を保証できるようにしてください。

コードブロック
  example = jsonencode({
a = 1
b = "hello"
})

インデントされたヒアドキュメント

標準のヒアドキュメント形式(上記参照)では、すべてのスペース文字がリテラルスペースとして扱われます。各行をスペースで開始したくない場合は、各行を左マージンに揃える必要があり、インデントされたブロックの式では不自然になる可能性があります。

コードブロック
block {
value = <<EOT
hello
world
EOT
}

これを改善するために、OpenTofuは<<-シーケンスで導入されるインデントされたヒアドキュメント文字列のバリアントも受け入れます。

コードブロック
block {
value = <<-EOT
hello
world
EOT
}

この場合、OpenTofuはシーケンス内の行を分析して、先頭スペースの数が最も少ない行を見つけ、その数のスペースをすべての行の先頭からトリムします。これにより、次の結果が得られます。

コードブロック
hello
world

エスケープシーケンス

バックスラッシュシーケンスは、ヒアドキュメント文字列式ではエスケープとして解釈されません。代わりに、バックスラッシュ文字はリテラルとして解釈されます。

ヒアドキュメントは、バックスラッシュを使用しない2つの特別なエスケープシーケンスをサポートしています。

シーケンス置換
$${リテラル${。補間シーケンスを開始しません。
%%{リテラル%{。テンプレートディレクティブシーケンスを開始しません。

文字列テンプレート

引用符付きおよびヒアドキュメント文字列式内では、シーケンス${および%{テンプレートシーケンスを開始します。テンプレートを使用すると、式を文字列リテラルに直接埋め込み、他の値から動的に文字列を構築できます。

補間

${ ... } シーケンスは補間であり、マーカーの間で与えられた式を評価し、必要に応じて結果を文字列に変換し、最後にそれを最終的な文字列に挿入します。

コードブロック
"Hello, ${var.name}!"

上記の例では、名前付きオブジェクト var.name にアクセスし、その値を文字列に挿入して、「Hello, Juan!」のような結果を生成します。

ディレクティブ

%{ ... } シーケンスはディレクティブであり、条件式や for 式と同様に、条件付きの結果やコレクションの反復を可能にします。

以下のディレクティブがサポートされています

  • %{if <BOOL>}/%{else}/%{endif} ディレクティブは、ブール式の値に基づいて2つのテンプレートを選択します。

    コードブロック
    "Hello, %{ if var.name != "" }${var.name}%{ else }unnamed%{ endif }!"

    else 部分は省略できます。その場合、条件式が false を返す場合は、結果は空の文字列になります。

  • %{for <NAME> in <COLLECTION>} / %{endfor} ディレクティブは、指定されたコレクションまたは構造値の要素を反復処理し、各要素に対して指定されたテンプレートを1回評価し、結果を連結します。

    コードブロック
    <<EOT
    %{ for ip in aws_instance.example[*].private_ip }
    server ${ip}
    %{ endfor }
    EOT

    for キーワードの直後に指定された名前は、一時変数名として使用され、ネストされたテンプレートから参照できます。

空白の削除

テンプレートディレクティブを読みやすくフォーマットできるようにし、結果に不要なスペースや改行を追加しないようにするために、すべてのテンプレートシーケンスには、開始文字の直後または終了の直前に、オプションのストリップマーカー (~) を含めることができます。ストリップマーカーが存在する場合、テンプレートシーケンスは、シーケンスの前 (マーカーが先頭にある場合) または後 (マーカーが末尾にある場合) のすべてリテラル空白 (スペースと改行) を消費します。

コードブロック
<<EOT
%{ for ip in aws_instance.example[*].private_ip ~}
server ${ip}
%{ endfor ~}
EOT

上記の例では、各ディレクティブ後の改行は出力に含まれませんが、server ${ip} シーケンス後の改行は保持されるため、各要素に対して1行のみが生成されます。

コードブロック
server 10.1.16.154
server 10.1.16.1
server 10.1.16.34

テンプレートディレクティブを使用する場合は、常に「heredoc」文字列リテラル形式を使用し、読みやすくするためにテンプレートを複数行にフォーマットすることをお勧めします。引用符で囲まれた文字列リテラルには、通常、補間シーケンスのみを含める必要があります。