Terraform変数、依存関係、および条件を使用して柔軟性を向上させる方法
序章
Terraform が使用するHashicorp構成言語(HCL)は、他のプログラミング言語に存在する多くの便利な構造と機能を提供します。 インフラストラクチャコードでループを使用すると、コードの重複が大幅に減少し、読みやすさが向上するため、将来のリファクタリングが容易になり、柔軟性が向上します。 HCLは、リストやマップ(他の言語ではそれぞれ配列や辞書とも呼ばれます)などのいくつかの一般的なデータ構造や、実行パスの分岐の条件も提供します。
Terraformに固有の機能は、依存するリソースを手動で指定できることです。 コードの実行時に作成される実行グラフには、検出されたリンク(ほとんどのシナリオで正しい)がすでに含まれていますが、Terraformが検出できなかった依存関係を強制する必要がある場合があります。
この記事では、HCLが提供するデータ構造、リソースのループ機能( count
鍵、 for_each
、 と for
)、既知および未知の値を処理するための条件、およびリソース間の依存関係。
前提条件
- DigitalOceanパーソナルアクセストークン。DigitalOceanコントロールパネルから作成できます。 手順については、DigitalOcean製品ドキュメントパーソナルアクセストークンの作成方法を参照してください。
- ローカルマシンにインストールされたTerraformと、DigitalOceanプロバイダーでセットアップされたプロジェクト。 DigitalOcean チュートリアルでTerraformを使用する方法のステップ1およびステップ2を完了し、プロジェクトフォルダーに名前を付けてください
terraform-flexibility
、 それ以外のloadbalance
. ステップ2の間に、pvt_key
プロバイダーを構成するときの変数とSSHキーリソース。
注:このチュートリアルはTerraformで特別にテストされています 1.0.2
.
HCLのデータ型
コードをより柔軟にするHCLのループやその他の機能について学ぶ前に、まず利用可能なデータ型とその使用法について説明します。
Hashicorp構成言語は、プリミティブおよびコンプレックスデータ型をサポートします。 プリミティブデータ型は、文字列、数値、およびブール値です。これらは、他のデータ型から派生できない基本的な型です。 一方、複合型は、複数の値を1つにグループ化します。 複雑な値の2つのタイプは、構造タイプとコレクションタイプです。
構造タイプを使用すると、さまざまなタイプの値をグループ化できます。 主な例は、インフラストラクチャがどのようになるかを指定するために使用するリソース定義です。 構造タイプと比較すると、コレクションタイプも値をグループ化しますが、同じタイプのもののみです。 私たちが関心を持っているHCLで利用可能な3つのコレクションタイプは、リスト、マップ、およびセットです。
リスト
リストは他のプログラミング言語の配列に似ています。 それらには、同じタイプの既知の数の要素が含まれており、配列表記を使用してアクセスできます([]
)0から始まる整数インデックスによる。 次の手順でデプロイするドロップレットの名前を保持するリスト変数宣言の例を次に示します。
variable "droplet_names" {
type = list(string)
default = ["first", "second", "third"]
}
のために type
、要素タイプが文字列であるリストであることを指定してから、 default
価値。 HCLでは、括弧内に列挙された値はリストを示します。
マップ
マップはキーと値のペアのコレクションであり、各値はそのタイプのキーを使用してアクセスされます string
. 中括弧内のマップを指定するには、次の2つの方法があります。コロン(:
)または等号(=
)値を指定します。 どちらの場合も、値は引用符で囲む必要があります。 コロンを使用する場合は、キーも囲む必要があります。
さまざまな環境のドロップレット名を含む次のマップ定義は、等号を使用して記述されています。
variable "droplet_env_names" {
type = map(string)
default = {
development = "dev-droplet"
staging = "staging-droplet"
production = "prod-droplet"
}
}
キーが数字で始まる場合は、コロン構文を使用する必要があります。
variable "droplet_env_names" {
type = map(string)
default = {
"1-development": "dev-droplet"
"2-staging": "staging-droplet"
"3-production": "prod-droplet"
}
}
セット
セットは要素の順序付けをサポートしていません。つまり、トラバースセットが毎回同じ順序を生成することは保証されておらず、それらの要素にターゲットを絞った方法でアクセスすることはできません。 それらには、1回だけ繰り返される一意の要素が含まれており、同じ要素を複数回指定すると、それらは合体され、セットに存在するインスタンスは1つだけになります。
セットの宣言はリストの宣言に似ていますが、唯一の違いは変数のタイプです。
variable "droplet_names" {
type = set(string)
default = ["first", "second", "third", "fourth"]
}
HCLが提供するデータ構造のタイプについて学習し、このチュートリアル全体で使用するリスト、マップ、およびセットの構文を確認したので、次に、複数のインスタンスをデプロイするいくつかの柔軟な方法を試してみましょう。 Terraformの同じリソース。
を使用したリソース数の設定 count
鍵
このセクションでは、を使用して同じリソースの複数のインスタンスを作成します count
鍵。 The count
keyは、作成するインスタンスの数を指定する、すべてのリソースで使用可能なパラメーターです。
Dropletリソースを作成することで、それがどのように機能するかを確認できます。Dropletリソースは、という名前のファイルに保存されます。 droplets.tf
前提条件の一部として作成したプロジェクトディレクトリ。 次のコマンドを実行して、編集用に作成して開きます。
- nano droplets.tf
次の行を追加します。
resource "digitalocean_droplet" "test_droplet" {
count = 3
image = "ubuntu-20-04-x64"
name = "web"
region = "fra1"
size = "s-1vcpu-1gb"
}
このコードは、と呼ばれるドロップレットリソースを定義します test_droplet
、1GBのRAMとCPUコアを搭載したUbuntu20.04を実行しています。
の値に注意してください count
に設定されています 3
、これは、Terraformが同じリソースの3つのインスタンスを作成しようとすることを意味します。 完了したら、ファイルを保存して閉じます。
プロジェクトを計画して、Terraformが実行するアクションを確認できます。
- terraform plan -var "do_token=${DO_PAT}"
出力は次のようになります。
Output...
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated
with the following symbols:
+ create
Terraform will perform the following actions:
# digitalocean_droplet.test_droplet[0] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
name = "web"
...
}
# digitalocean_droplet.test_droplet[1] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
name = "web"
...
}
# digitalocean_droplet.test_droplet[2] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
name = "web"
...
}
Plan: 3 to add, 0 to change, 0 to destroy.
...
Terraformが3つのインスタンスを作成する出力の詳細 test_droplet
、すべて同じ名前 web
. 可能ではありますが、好ましくないので、Droplet定義を変更して、各インスタンスの名前を一意にします。 開ける droplets.tf
編集用:
- nano droplets.tf
強調表示された行を変更します。
resource "digitalocean_droplet" "test_droplet" {
count = 3
image = "ubuntu-20-04-x64"
name = "web.${count.index}"
region = "fra1"
size = "s-1vcpu-1gb"
}
ファイルを保存して閉じます。
The count
オブジェクトはを提供します index
パラメータ。0から始まる現在の反復のインデックスが含まれます。 現在のインデックスは、文字列補間を使用してドロップレットの名前に置き換えられます。これにより、変数を置き換えることで文字列を動的に作成できます。 プロジェクトを再度計画して、変更を確認できます。
- terraform plan -var "do_token=${DO_PAT}"
出力は次のようになります。
Output...
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated
with the following symbols:
+ create
Terraform will perform the following actions:
# digitalocean_droplet.test_droplet[0] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
name = "web.0"
...
}
# digitalocean_droplet.test_droplet[1] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
name = "web.1"
...
}
# digitalocean_droplet.test_droplet[2] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
name = "web.2"
...
}
Plan: 3 to add, 0 to change, 0 to destroy.
...
今回は、 test_droplet
名前にインデックスが含まれるため、追跡が容易になります。
これで、を使用してリソースの複数のインスタンスを作成する方法を理解しました。 count
キー、およびプロビジョニング中にインスタンスのインデックスをフェッチして使用します。 次に、リストからドロップレットの名前を取得する方法を学習します。
リストからの液滴名の取得
同じリソースの複数のインスタンスにカスタム名を付ける必要がある場合は、定義したリスト変数からそれらを動的に取得できます。 チュートリアルの残りの部分では、名前のリストからDropletの展開を自動化し、柔軟性と使いやすさを促進するいくつかの方法を説明します。
最初に、ドロップレット名を含むリストを定義する必要があります。 というファイルを作成します variables.tf
編集のために開きます。
- nano variables.tf
次の行を追加します。
variable "droplet_names" {
type = list(string)
default = ["first", "second", "third", "fourth"]
}
ファイルを保存して閉じます。 このコードは、というリストを定義します droplet_names
、文字列を含む first
, second
, third
、 と fourth
.
開ける droplets.tf
編集用:
- nano droplets.tf
強調表示された行を変更します。
resource "digitalocean_droplet" "test_droplet" {
count = length(var.droplet_names)
image = "ubuntu-20-04-x64"
name = var.droplet_names[count.index]
region = "fra1"
size = "s-1vcpu-1gb"
}
柔軟性を向上させるために、一定数の要素を手動で指定する代わりに、 droplet_names
リストに count
パラメータ。常にリスト内の要素の数を返します。 名前については、次の場所にあるリストの要素をフェッチします count.index
、配列ブラケット表記を使用します。 完了したら、ファイルを保存して閉じます。
プロジェクトの計画を再試行してください。 次のような出力が表示されます。
Output...
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated
with the following symbols:
+ create
Terraform will perform the following actions:
# digitalocean_droplet.test_droplet[0] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
+ name = "first"
...
}
# digitalocean_droplet.test_droplet[1] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
+ name = "second"
...
}
# digitalocean_droplet.test_droplet[2] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
+ name = "third"
...
}
# digitalocean_droplet.test_droplet[3] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
+ name = "fourth"
...
Plan: 4 to add, 0 to change, 0 to destroy.
...
これらの変更の結果として、4つのドロップレットが展開され、次の要素にちなんで名前が付けられます。 droplet_names
リスト。
あなたはについて学びました count
、その機能と構文、およびリソースインスタンスを変更するためのリストと一緒に使用しています。 これで、その欠点と、それらを克服する方法がわかります。
のデメリットを理解する count
countの使用方法がわかったので、使用するリストを変更するときの欠点を調べてみましょう。
ドロップレットをクラウドにデプロイしてみましょう。
- terraform apply -var "do_token=${DO_PAT}"
入る yes
プロンプトが表示されたら。 出力の終わりは次のようになります。
OutputApply complete! Resources: 4 added, 0 changed, 0 destroyed.
次に、を拡大して、もう1つのDropletインスタンスを作成しましょう。 droplet_names
リスト。 開ける variables.tf
編集用:
- nano variables.tf
リストの先頭に新しい要素を追加します。
variable "droplet_names" {
type = list(string)
default = ["zero", "first", "second", "third", "fourth"]
}
完了したら、ファイルを保存して閉じます。
プロジェクトを計画します。
- terraform plan -var "do_token=${DO_PAT}"
次のような出力が表示されます。
Output...
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated
with the following symbols:
+ create
~ update in-place
Terraform will perform the following actions:
# digitalocean_droplet.test_droplet[0] will be updated in-place
~ resource "digitalocean_droplet" "test_droplet" {
...
~ name = "first" -> "zero"
...
}
# digitalocean_droplet.test_droplet[1] will be updated in-place
~ resource "digitalocean_droplet" "test_droplet" {
...
~ name = "second" -> "first"
...
}
# digitalocean_droplet.test_droplet[2] will be updated in-place
~ resource "digitalocean_droplet" "test_droplet" {
...
~ name = "third" -> "second"
...
}
# digitalocean_droplet.test_droplet[3] will be updated in-place
~ resource "digitalocean_droplet" "test_droplet" {
...
~ name = "fourth" -> "third"
...
}
# digitalocean_droplet.test_droplet[4] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
+ name = "fourth"
...
}
Plan: 1 to add, 4 to change, 0 to destroy.
...
出力は、Terraformが最初の4つのドロップレットの名前を変更し、5番目のドロップレットを作成することを示しています。 fourth
、インスタンスを順序付きリストと見なし、リスト内のインデックス番号によって要素(ドロップレット)を識別するためです。 これは、Terraformが最初に4つのドロップレットを考慮する方法です。
インデックス番号 | 0 | 1 | 2 | 3 |
---|---|---|---|---|
液滴名 | 最初 | 2番目 | 第3 | 第4 |
新しい液滴が zero
が先頭に追加されると、その内部リスト表現は次のようになります。
インデックス番号 | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
液滴名 | 零 | 最初 | 2番目 | 第3 | 第4 |
これで、最初の4つのドロップレットが1つ右にシフトされます。 次に、Terraformは、テーブルに表されている2つの状態を比較します。 0
、ドロップレットは first と呼ばれ、2番目のテーブルで異なるため、更新アクションを計画します。 これは位置まで続きます 4
、これは最初のテーブルに同等の要素がなく、代わりにドロップレットプロビジョニングアクションが計画されています。
これは、リストの最後以外の場所に新しい要素を追加すると、必要のないときにリソースが変更されることを意味します。 の要素が droplet_names
リストが削除されました。
不完全なリソース追跡は、使用の主な欠点です count
同じリソースの異なるインスタンスの動的な数をデプロイするため。 一定数の定数インスタンスの場合、 count
うまく機能するシンプルなソリューションです。 ただし、このような状況では、一部の属性が変数から取得されている場合、 for_each
このチュートリアルの後半で学習するループは、はるかに優れた選択です。
現在のリソースを参照する(self
)
のもう1つの欠点 count
リソースの任意のインスタンスをそのインデックスで参照できない場合があります。
主な例は、破棄時間プロビジョナーです。これは、リソースが破棄される予定のときに実行されます。 その理由は、要求されたインスタンスが存在しない(すでに破棄されている)か、相互依存サイクルを作成する可能性があるためです。 このような状況では、インスタンスのリストからオブジェクトを参照する代わりに、 self
キーワード。
その使用法を示すために、破棄時のローカルプロビジョナーをに追加します。 test_droplet
定義。実行時にメッセージが表示されます。 開ける droplets.tf
編集用:
- nano droplets.tf
次の強調表示された行を追加します。
resource "digitalocean_droplet" "test_droplet" {
count = length(var.droplet_names)
image = "ubuntu-20-04-x64"
name = var.droplet_names[count.index]
region = "fra1"
size = "s-1vcpu-1gb"
provisioner "local-exec" {
when = destroy
command = "echo 'Droplet ${self.name} is being destroyed!'"
}
}
ファイルを保存して閉じます。
The local-exec
プロビジョニング担当者は、Terraformが実行されているローカルマシンでコマンドを実行します。 なぜなら when
パラメータがに設定されている destroy
、リソースが破棄される場合にのみ実行されます。 実行するコマンドは、文字列をエコーします stdout
、を使用して現在のリソースの名前を置き換えます self.name
.
次のセクションでは別の方法でドロップレットを作成するため、次のコマンドを実行して、現在展開されているドロップレットを破棄します。
- terraform destroy -var "do_token=${DO_PAT}"
入る yes
プロンプトが表示されたら。 あなたは受け取るでしょう local-exec
4回実行されているプロビジョナー:
Output...
digitalocean_droplet.test_droplet[0] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet first is being destroyed!'"]
digitalocean_droplet.test_droplet[1] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet second is being destroyed!'"]
digitalocean_droplet.test_droplet[1] (local-exec): Droplet second is being destroyed!
digitalocean_droplet.test_droplet[2] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet third is being destroyed!'"]
digitalocean_droplet.test_droplet[2] (local-exec): Droplet third is being destroyed!
digitalocean_droplet.test_droplet[3] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet fourth is being destroyed!'"]
digitalocean_droplet.test_droplet[3] (local-exec): Droplet fourth is being destroyed!
digitalocean_droplet.test_droplet[0] (local-exec): Droplet first is being destroyed!
...
このステップでは、 count
. これで、 for_each
それらを克服し、より幅広い変数型の配列で機能するループ構造。
を使用してループ for_each
このセクションでは、 for_each
ループ、その構文、および複数のインスタンスでリソースを定義する際の柔軟性にどのように役立つか。
for_each
各リソースで使用可能なパラメータですが、 count
、作成するには多数のインスタンスが必要ですが、 for_each
マップまたはセットを受け入れます。 提供されたコレクションの各要素は1回トラバースされ、そのためのインスタンスが作成されます。 for_each
キーと値を each
属性としてのキーワード(ペアのキーと値として each.key
と each.value
、 それぞれ)。 セットが提供される場合、キーと値は同じになります。
の現在の要素を提供するため each
オブジェクトの場合、リストで行ったように、目的の要素に手動でアクセスする必要はありません。 セットの場合、内部で観察可能な順序がないため、それは不可能です。 リストを渡すこともできますが、最初にリストを使用してセットに変換する必要があります。 toset
関数。
使用の主な利点 for_each
、3つのコレクションデータ型すべてを列挙できることを除けば、影響を受ける要素のみが変更、作成、または削除されます。 入力内の要素の順序を変更した場合、アクションは計画されません。入力から要素を追加、削除、または変更した場合、適切なアクションはその要素に対してのみ計画されます。
ドロップレットリソースをから変換してみましょう count
に for_each
実際にどのように機能するかを確認してください。 開ける droplets.tf
実行による編集の場合:
- nano droplets.tf
強調表示された行を変更します。
resource "digitalocean_droplet" "test_droplet" {
for_each = toset(var.droplet_names)
image = "ubuntu-20-04-x64"
name = each.value
region = "fra1"
size = "s-1vcpu-1gb"
}
あなたは削除することができます local-exec
プロビジョニング担当者。 完了したら、ファイルを保存して閉じます。
最初の行が置き換えられます count
呼び出します for_each
、渡す droplet_names
を使用したセット形式のリスト toset
指定された入力を自動的に変換する関数。 ドロップレット名には、次のように指定します each.value
、ドロップレット名のセットからの現在の要素の値を保持します。
次のコマンドを実行してプロジェクトを計画します。
- terraform plan -var "do_token=${DO_PAT}"
出力には、Terraformが実行する手順の詳細が示されます。
Output...
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated
with the following symbols:
+ create
Terraform will perform the following actions:
# digitalocean_droplet.test_droplet["first"] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
+ name = "first"
...
}
# digitalocean_droplet.test_droplet["fourth"] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
+ name = "fourth"
...
}
# digitalocean_droplet.test_droplet["second"] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
+ name = "second"
...
}
# digitalocean_droplet.test_droplet["third"] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
+ name = "third"
...
}
# digitalocean_droplet.test_droplet["zero"] will be created
+ resource "digitalocean_droplet" "test_droplet" {
...
+ name = "zero"
...
}
Plan: 5 to add, 0 to change, 0 to destroy.
...
使用するのとは対照的に count
、Terraformは、順序付きリストの要素としてではなく、各インスタンスを個別に考慮するようになりました。 各インスタンスは、作成される各リソースの横の括弧内に示されている文字列要素によって示されるように、指定されたセットの要素にリンクされています。
次のコマンドを実行して、プランをクラウドに適用します。
- terraform apply -var "do_token=${DO_PAT}"
入る yes
プロンプトが表示されたら。 終了したら、から1つの要素を削除します droplet_names
他のインスタンスが影響を受けないことを示すためのリスト。 開ける variables.tf
編集用:
- nano variables.tf
リストを次のように変更します。
variable "droplet_names" {
type = list(string)
default = ["first", "second", "third", "fourth"]
}
ファイルを保存して閉じます。
プロジェクトを再度計画すると、次の出力が表示されます。
Output...
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated
with the following symbols:
- destroy
Terraform will perform the following actions:
# digitalocean_droplet.test_droplet["zero"] will be destroyed
- resource "digitalocean_droplet" "test_droplet" {
...
- name = "zero" -> null
...
}
Plan: 0 to add, 0 to change, 1 to destroy.
...
今回は、Terraformは削除されたインスタンスのみを破棄します(zero
)、他のインスタンスには触れません。これは正しい動作です。
このステップでは、 for_each
、それを使用する方法、およびその利点 count
. 次に、 for
ループ、その構文と使用法、および特定のタスクを自動化するために使用できる場合。
を使用してループ for
The for
ループはコレクションで機能し、入力の各要素に変換を適用することで新しいコレクションを作成します。 出力の正確なタイプは、ループが角かっこで囲まれているかどうかによって異なります([]
)または中括弧({}
)、それぞれリストまたはマップを提供します。 そのため、リソースのクエリや、後の処理のための構造化された出力の形成に適しています。
の一般的な構文 for
ループは次のとおりです。
for element in collection:
transform(element)
if condition
他のプログラミング言語と同様に、最初にトラバーサル変数に名前を付けます(element
)を指定し、 collection
列挙します。 ループの本体は変換ステップであり、オプションです if
句は、入力コレクションのフィルタリングに使用できます。
次に、出力を使用していくつかの例を実行します。 それらをという名前のファイルに保存します outputs.tf
. 次のコマンドを実行して、編集用に作成します。
- nano outputs.tf
デプロイされたドロップレット名とそのIPアドレスのペアを出力するには、次の行を追加します。
output "ip_addresses" {
value = {
for instance in digitalocean_droplet.test_droplet:
instance.name => instance.ipv4_address
}
}
このコードは、と呼ばれる出力を指定します ip_addresses
、およびを指定します for
のインスタンスを反復処理するループ test_droplet
前の手順でカスタマイズしたリソース。 ループは中括弧で囲まれているため、出力はマップになります。 マップの変換手順は、他のプログラミング言語のラムダ関数に似ており、ここでは、キーとしてのインスタンス名とその値としてのプライベートIPを組み合わせて、キーと値のペアを作成します。
ファイルを保存して閉じてから、Terraformの状態を更新して、次のコマンドを実行して新しい出力を考慮します。
- terraform refresh -var "do_token=${DO_PAT}"
テラフォーム refresh
コマンドは、ローカル状態をクラウド内の実際のインフラストラクチャ状態で更新します。
次に、出力の内容を確認します。
Outputip_addresses = {
"first" = "ip_address"
"fourth" = "ip_address"
"second" = "ip_address"
"third" = "ip_address"
}
テラフォームは、の内容を示しています ip_addresses
出力、これはによって構築されたマップです for
ループ。 (エントリの順序は異なる場合があります。)ループはエントリの数ごとにシームレスに機能します。つまり、新しい要素をエントリに追加できます。 droplet_names
リストと、手動入力なしで作成される新しいドロップレットも、この出力に自動的に表示されます。
を囲むことによって for
角かっこでループすると、出力をリストにすることができます。 たとえば、Droplet IPアドレスのみを出力できます。これは、データを解析している可能性のある外部ソフトウェアに役立ちます。 コードは次のようになります。
output "ip_addresses" {
value = [
for instance in digitalocean_droplet.test_droplet:
instance.ipv4_address
]
}
ここで、変換ステップはIPアドレス属性を選択します。 次の出力が得られます。
Outputip_addresses = [
"ip_address",
"ip_address",
"ip_address",
"ip_address",
]
前に述べたように、を使用して入力コレクションをフィルタリングすることもできます if
句。 これは、次の方法でフィルタリングするループを作成する方法です。 fra1
領域:
output "ip_addresses" {
value = [
for instance in digitalocean_droplet.test_droplet:
instance.ipv4_address
if instance.region == "fra1"
]
}
HCLでは、 ==
演算子は、両側の値が等しいかどうかをチェックします。ここでは、次のことをチェックします。 instance.region
に等しい fra1
. そうである場合、チェックは合格し、 instance
変換されて出力に追加されます。それ以外の場合はスキップされます。 このコードの出力は前の例と同じになります。これは、すべてのDropletインスタンスが fra1
地域によると、 test_droplet
リソース定義。 The if
条件付きは、ドロップレットのサイズや分布など、プロジェクト内の他の値の入力コレクションをフィルタリングする場合にも役立ちます。
次のセクションでは別の方法でリソースを作成するため、次のコマンドを実行して、現在デプロイされているリソースを破棄します。
- terraform destroy -var "do_token=${DO_PAT}"
入る yes
プロセスを終了するように求められたとき。
私たちは行きました for
ループ、その構文、および出力での使用例。 ここで、条件文と、それらを一緒に使用する方法について学習します。 count
.
ディレクティブと条件
前のセクションの1つで、 count
キーとそれがどのように機能するか。 ここでは、Terraformコードの他の場所で使用できる3値条件演算子と、それらを使用する方法について学習します。 count
.
三項演算子の構文は次のとおりです。
condition ? value_if_true : value_if_false
condition
ブール値(trueまたはfalse)に計算される式です。 条件が真の場合、式は次のように評価されます。 value_if_true
. 一方、条件がfalseの場合、結果は次のようになります。 value_if_false
.
三元演算子の主な用途は、変数の内容に応じて単一のリソースの作成を有効または無効にすることです。 これは、比較の結果を渡すことで実現できます(どちらか 1
また 0
)に count
目的のリソースをキー入力します。
三項演算子を使用してリストまたはセットから単一の要素をフェッチする場合は、 one
関数。 指定されたコレクションが空の場合、 null
. それ以外の場合は、コレクション内の単一の要素を返すか、複数ある場合はエラーをスローします。
という変数を追加しましょう create_droplet
、ドロップレットを作成するかどうかを制御します。 まず、開く variables.tf
編集用:
- nano variables.tf
強調表示された行を追加します。
variable "droplet_names" {
type = list(string)
default = ["first", "second", "third", "fourth"]
}
variable "create_droplet" {
type = bool
default = true
}
このコードは、 create_droplet
タイプの変数 bool
. ファイルを保存して閉じます。
次に、ドロップレット宣言を変更するには、 droplets.tf
実行による編集の場合:
- nano droplets.tf
次のようにファイルを変更します。
resource "digitalocean_droplet" "test_droplet" {
count = var.create_droplet ? 1 : 0
image = "ubuntu-20-04-x64"
name = "test_droplet"
region = "fra1"
size = "s-1vcpu-1gb"
}
為に count
、三項演算子を使用していずれかを返します 1
の場合 create_droplet
変数がtrue、または 0
falseの場合、ドロップレットはプロビジョニングされません。 完了したら、ファイルを保存して閉じます。
次のコマンドを実行して、変数をfalseに設定してプロジェクト実行プランを計画します。
- terraform plan -var "do_token=${DO_PAT}" -var "create_droplet=false"
次の出力が表示されます。
OutputChanges to Outputs:
+ ip_addresses = {}
You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.
なぜなら create_droplet
の値で渡されました false
、 count
インスタンスの 0
、およびドロップレットは作成されないため、出力するIPアドレスはありません。
三元条件演算子をと一緒に使用する方法を確認しました count
必要なリソースを展開するかどうかを選択する際に、より高いレベルの柔軟性を実現するためのキー。 次に、リソースのリソース依存関係を明示的に設定する方法について学習します。
リソースの依存関係を明示的に設定する
プロジェクトの実行プランを作成する際、Terraformはリソース間の依存関係チェーンを検出し、適切な順序で構築されるように暗黙的にそれらを順序付けます。 ほとんどの場合、リソース内のすべての式をスキャンしてグラフを作成することにより、関係を検出できます。
ただし、1つのリソースをプロビジョニングするために、アクセス制御設定をクラウドプロバイダーに既にデプロイする必要がある場合、それらが関連していることをTerraformに明確に示すことはできません。 次に、Terraformは、それらが相互に動作的に依存していることを認識しません。 このような場合、依存関係は、を使用して手動で指定する必要があります。 depends_on
口論。
The depends_on
キーは各リソースで使用可能であり、特定のリソース間の非表示の依存関係リンクを指定するために使用されます。 隠された依存関係は、リソースが宣言でデータを使用せずに他のリソースの動作に依存している場合に形成されます。これにより、Terraformはそれらを一方向に接続するように促されます。
これがその方法の例です depends_on
コードで指定されています:
resource "digitalocean_droplet" "droplet" {
image = "ubuntu-20-04-x64"
name = "web"
region = "fra1"
size = "s-1vcpu-1gb"
depends_on = [
# Resources...
]
}
他のリソースへの参照のリストを受け入れ、任意の式を受け入れません。
depends_on
慎重に使用し、他のすべてのオプションが使い果たされた場合にのみ使用する必要があります。 その使用は、宣言しようとしていることがTerraformの自動依存検知システムの境界の外に出ていることを意味します。 これは、リソースが必要以上のリソースに明示的に依存していることを示している場合があります。
これで、リソースの追加の依存関係を明示的に設定する方法について学習しました。 depends_on
キー、およびそれを使用する必要がある場合。
結論
この記事では、コードの柔軟性とスケーラビリティを向上させるHCLの機能について説明しました。 count
デプロイするリソースインスタンスの数を指定し、 for_each
コレクションのデータ型をループし、インスタンスをカスタマイズする高度な方法として。 正しく使用すると、コードの重複と、展開されたインフラストラクチャを管理するための運用上のオーバーヘッドが大幅に削減されます。
また、条件演算子と3項演算子、およびそれらを使用してリソースをデプロイするかどうかを制御する方法についても学習しました。 Terraformの自動依存関係分析システムは非常に優れていますが、を使用してリソースの依存関係を手動で指定する必要がある場合があります。 depends_on
鍵。
このチュートリアルは、Terraformシリーズでインフラストラクチャを管理する方法の一部です。 このシリーズでは、Terraformの初めてのインストールから複雑なプロジェクトの管理まで、Terraformの多くのトピックを取り上げています。