Terraform出力を使用してインフラストラクチャデータを管理する方法
序章
Terraform 出力は、プロジェクトの状態からインフラストラクチャリソースに関する情報を抽出するために使用されます。 Terraformが使用するHashicorp構成言語(HCL)の他の機能を使用して、リソース情報を照会し、リストやマップなどのより複雑なデータ構造に変換できます。 出力は、作成されたインフラストラクチャリソースで動作できる外部ソフトウェアに情報を提供するのに役立ちます。
このチュートリアルでは、Dropletsをデプロイする単純なインフラストラクチャを作成することにより、Terraformの出力構文とそのパラメーターについて学習します。 また、出力をJSONに変換することにより、プログラムで出力を解析します。
前提条件
- DigitalOceanパーソナルアクセストークン。DigitalOceanコントロールパネルから作成できます。 手順については、DigitalOcean製品ドキュメントパーソナルアクセストークンの作成方法を参照してください。
- ローカルマシンにインストールされたTerraformと、DigitalOceanプロバイダーでセットアップされたプロジェクト。 DigitalOcean チュートリアルでTerraformを使用する方法のステップ1およびステップ2を完了し、代わりにプロジェクトフォルダーに
terraform-outputs
という名前を付けてください。loadbalance
の。 ステップ2の間、pvt_key
変数とSSHキーリソースを含めないでください。 - HCLデータ型とループに精通していること。 詳細については、 Terraform変数、依存関係、および条件を使用して柔軟性を向上させる方法チュートリアルを参照してください。
注:このチュートリアルは、Terraform1.0.2
で特別にテストされています。
出力の定義
このセクションでは、ドロップレットを宣言してクラウドにデプロイし、ドロップレットのIPアドレスを表示するものを定義して出力について学習します。
前提条件として作成したterraform-outputs
ディレクトリから、編集用にdroplets.tf
ファイルを作成して開きます。
nano droplets.tf
次のDropletリソースと出力定義を追加します。
terraform-outputs / droplets.tf
resource "digitalocean_droplet" "web" { image = "ubuntu-20-04-x64" name = "test-droplet" region = "fra1" size = "s-1vcpu-1gb" } output "droplet_ip_address" { value = digitalocean_droplet.web.ipv4_address }
最初に、web
と呼ばれるDropletリソースを宣言します。 クラウドでの実際の名前はtest-droplet
で、リージョンfra1
で、Ubuntu20.04を実行しています。
次に、droplet_ip_address
という出力を宣言します。 Terraformでは、出力は、リソースに関する内部値と計算値、および情報をエクスポートして表示するために使用されます。 ここでは、出力するデータを受け入れるvalue
パラメーターを、宣言されたドロップレットのIPアドレスに設定します。 宣言時は不明ですが、Dropletが展開されると利用可能になります。 出力が表示され、各展開後にアクセスできます。
ファイルを保存して閉じてから、次のコマンドを実行してプロジェクトをデプロイします。
terraform apply -var "do_token=${DO_PAT}"
yes
と入力して、プロンプトが表示されたら適用します。 出力の終わりは次のようになります。
Output... digitalocean_droplet.web: Creating... ... digitalocean_droplet.web: Creation complete after 32s [id=207631771] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. Outputs: droplet_ip_address = ip_address
強調表示されたIPアドレスは、新しくデプロイされたドロップレットに属しています。 プロジェクトを適用すると、リソースがクラウドにデプロイされ、すべてのリソース属性が使用可能になると、最後に出力が表示されます。 droplet_ip_address
出力がないと、Terraformは、展開されていることを除いて、ドロップレットに関するそれ以上の情報を表示しません。
output
コマンドを使用して出力を表示することもできます。
terraform output
出力には、プロジェクト内のすべてのoutputs
が一覧表示されます。
Outputdroplet_ip_address = ip_address
特定の出力を引数として指定することにより、名前でクエリすることもできます。
terraform output output_name
droplet_ip_address
の場合、出力はIPアドレスのみで構成されます。
Outputip_address
必須のvalue
を指定することを除いて、出力にはいくつかのオプションのパラメーターがあります。
description
:出力の内容を詳しく説明した短いドキュメントを埋め込みます。depends_on
:各リソースで使用可能なメタパラメーター。これにより、出力が依存するリソースを明示的に指定でき、Terraformは計画中に自動的に推測できません。sensitive
:ブール値を受け入れます。これは、true
に設定されている場合、デプロイ後に出力のコンテンツが表示されないようにします。
sensitive
パラメーターは、Terraformデプロイメントのログが公開される場合に役立ちますが、出力内容は非表示にしておく必要があります。 これをDropletリソース定義に追加します。
droplets.tf
を開いて編集し、強調表示された行を追加します。
terraform-outputs / droplets.tf
resource "digitalocean_droplet" "web" { image = "ubuntu-20-04-x64" name = "test-droplet" region = "fra1" size = "s-1vcpu-1gb" } output "droplet_ip_address" { value = digitalocean_droplet.web.ipv4_address sensitive = true }
完了したら、ファイルを保存して閉じます。 次のコマンドを実行して、プロジェクトを再度デプロイします。
terraform apply -var "do_token=${DO_PAT}"
プロンプトが表示されたら、yes
と入力します。 出力が編集されていることがわかります。
Output... Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: droplet_ip_address = <sensitive>
sensitive
とマークされている場合でも、出力とそのコンテンツは、Terraformの状態の表示や出力の直接クエリなど、他のチャネルから引き続き利用できます。
次のステップでは、別のドロップレットと出力構造を作成するので、次を実行して現在デプロイされているものを破棄します。
terraform destroy -var "do_token=${DO_PAT}"
最後の出力は次のようになります。
Output... Destroy complete! Resources: 1 destroyed.
ドロップレットを宣言してデプロイし、そのIPアドレスを示す出力を作成しました。 ここでは、出力を使用してリストやマップなどのより複雑な構造を表示する方法について学習します。
複雑な構造の出力
このセクションでは、count
キーワードを使用して同じ定義から複数のドロップレットを展開し、それらのIPアドレスをさまざまな形式で出力します。
for
ループを使用する
ドロップレットリソース定義を変更する必要があるため、編集のために開きます。
nano droplets.tf
次のように変更します。
terraform-outputs / droplets.tf
resource "digitalocean_droplet" "web" { count = 3 image = "ubuntu-20-04-x64" name = "test-droplet-${count.index}" region = "fra1" size = "s-1vcpu-1gb" }
count
キーを使用して3つのドロップレットを作成し、現在のインデックスをドロップレット名に追加して、後でそれらを識別できるようにすることを指定しました。 以下の既存の出力を削除します。 完了したら、ファイルを保存して閉じます。
次のコマンドを実行してコードを適用します。
terraform apply -var "do_token=${DO_PAT}"
Terraformは、test-droplet-0
、test-droplet-1
、およびtest-droplet-2
と呼ばれる3つの番号付きドロップレットの作成を計画します。 プロセスを終了するように求められたら、yes
と入力します。 最後に次の出力が表示されます。
Output... Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
これは、3つのドロップレットすべてが正常にデプロイされ、それらに関するすべての情報がプロジェクト状態で保存されることを意味します。
リソース属性にアクセスする最も簡単な方法は出力を使用することですが、ドロップレットごとに出力を作成することはスケーラブルではありません。 解決策は、for
ループを使用してドロップレットのリストをトラバースし、それらの属性を収集するか、スプラット式(このステップの後半で学習します)を使用することです。
最初に、3つのドロップレットのIPアドレスをそれらの名前と組み合わせて出力する出力を定義します。 droplets.tf
を開いて編集します。
nano droplets.tf
次の行を追加します。
terraform-outputs / droplets.tf
resource "digitalocean_droplet" "web" { count = 3 image = "ubuntu-20-04-x64" name = "test-droplet-${count.index}" region = "fra1" size = "s-1vcpu-1gb" } output "droplet_ip_addresses" { value = { for droplet in digitalocean_droplet.web: droplet.name => droplet.ipv4_address } }
droplet_ip_addresses
の出力値は、for
ループを使用して作成されます。 中かっこで囲まれているため、結果のタイプはマップになります。 ループはドロップレットのリストをトラバースし、インスタンスごとに、その名前とIPアドレスをペアにして、結果のマップに追加します。
ファイルを保存して閉じてから、プロジェクトを再度適用します。
terraform apply -var "do_token=${DO_PAT}"
プロンプトが表示されたらyes
と入力すると、最後に出力コンテンツが表示されます。
OutputApply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: droplet_ip_addresses = { "test-droplet-0" = "ip_address" "test-droplet-1" = "ip_address" "test-droplet-2" = "ip_address" }
droplet_ip_addresses
出力は、展開された3つのドロップレットのIPアドレスの詳細を示します。
Terraform output
コマンドを使用すると、コマンド引数を使用して出力のコンテンツをJSONとして取得できます。
terraform output -json droplet_ip_addresses
結果は次のようになります。
Output{"test-droplet-0":"ip_address","test-droplet-1":"ip_address","test-droplet-2":"ip_address"}
JSON解析は広く使用されており、多くのプログラミング言語でサポートされています。 このようにして、デプロイされたDropletリソースに関する情報をプログラムで解析できます。
Splat式の使用
Splat式は、リストのすべての要素を反復処理し、各要素から属性の内容を収集してリストを作成するコンパクトな方法を提供します。 デプロイされた3つのドロップレットのIPアドレスを抽出するsplat式は、次の構文になります。
digitalocean_droplet.web[*].ipv4_address
[*]
シンボルは、左側のリストをトラバースし、要素ごとに、右側で指定された属性の内容を取得します。 左側の参照自体がリストでない場合は、それが唯一の要素となるリストに変換されます。
droplets.tf
を開いて編集し、次の行を変更してこれを実装できます。
terraform-outputs / droplets.tf
resource "digitalocean_droplet" "web" { count = 3 image = "ubuntu-20-04-x64" name = "test-droplet-${count.index}" region = "fra1" size = "s-1vcpu-1gb" } output "droplet_ip_addresses" { value = digitalocean_droplet.web[*].ipv4_address }
ファイルを保存した後、次のコマンドを実行してプロジェクトを適用します。
terraform apply -var "do_token=${DO_PAT}"
リストになり、ドロップレットのIPアドレスのみを含む出力が表示されます。
Output... Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: droplet_ip_addresses = [ "ip_address", "ip_address", "ip_address", ]
出力をJSONとして受け取るには、次のコマンドを実行します。
terraform output -json droplet_ip_addresses
出力は単一の配列になります。
Output["ip_address","ip_address","ip_address"]
出力をスプラット式およびfor
ループと一緒に使用して、デプロイされたドロップレットのIPアドレスをエクスポートしました。 また、出力コンテンツをJSONとして受け取ったので、jq
(指定された式に従ってJSONを動的にフィルタリングするためのツール)を使用してそれらを解析します。
jq
を使用した出力の解析
このステップでは、JSONドキュメントを操作するためのツールであるjq
をインストールして学習します。 これを使用して、Terraformプロジェクトの出力を解析します。
Ubuntuを使用している場合は、次のコマンドを実行してjq
をインストールします。
sudo snap install jq
macOSでは、Homebrewを使用してインストールできます。
brew install jq
jq
は、指定された入力に提供された処理式を適用します。これは、パイプで渡すことができます。 jq
での最も簡単なタスクは、入力をきれいに印刷することです。
terraform output -json droplet_ip_addresses | jq '.'
ID演算子(.
)を渡すことは、入力から解析されたJSONドキュメント全体を変更せずに出力する必要があることを意味します。
Output[ "first_ip_address", "second_ip_address", "third_ip_address" ]
ゼロから数えて、配列ブラケット表記を使用して2番目のIPアドレスだけを要求できます。
terraform output -json droplet_ip_addresses | jq '.[1]'
出力は次のようになります。
Output"second_ip_address"
処理の結果を配列にするには、式を括弧で囲みます。
terraform output -json droplet_ip_addresses | jq '[.[1]]'
きれいに印刷されたJSON配列が得られます。
Output[ "second_ip_address" ]
角かっこ内にインデックスの範囲を指定することにより、単一の要素の代わりに配列の一部を取得できます。
terraform output -json droplet_ip_addresses | jq '.[0:2]'
出力は次のようになります。
Output[ "first_ip_address", "second_ip_address" ]
範囲0:2
は、最初の2つの要素を返します。範囲の上部(2
)は包括的ではないため、位置0
および1
の要素のみです。フェッチされます。
これで、以下を実行して、デプロイされたリソースを破棄できます。
terraform destroy -var "do_token=${DO_PAT}"
このステップでは、jq
をインストールし、それを使用して、3つのドロップレットをデプロイするTerraformプロジェクトの出力を解析および操作しました。
結論
Terraformの出力について学習しました。これらを使用して、デプロイされたリソースの詳細を表示し、後で外部処理するためにデータ構造をエクスポートします。 また、出力を使用して、単一のリソースの属性を表示したり、作成されたマップやリソース属性を含むリストを表示したりしました。
jq
の機能の詳細については、公式ドキュメントにアクセスしてください。
このチュートリアルは、Terraformシリーズでインフラストラクチャを管理する方法の一部です。 このシリーズでは、Terraformの初めてのインストールから複雑なプロジェクトの管理まで、Terraformの多くのトピックを取り上げています。