■ はじめに
Terraform に関する Tips を徐々にだけど ここに書き溜めていく
目次
【1】デバッグログレベルを切り替えるには 【2】タイムアウト時間を変更するには 【3】依存関係を指定するには 1) resourceセクションから別リソースを参照 2) depends_on を指定 補足:terraform graphで依存関係を可視化する 【4】同じリソースを複数作成するには 1)count を使う 2)for_each を使う 【5】ZIPファイル作成するには 【6】コマンドを実行するには
【1】デバッグログレベルを切り替えるには
* 実行コマンド前に「TF_LOG=<ログレベル>」を付加する
https://developer.hashicorp.com/terraform/internals/debugging
コマンド例
# コマンド一回限りでTF_LOGを設定する場合 TF_LOG=DEBUG terraform plan # TRACE, DEBUG, INFO, WARN or ERROR
https://www.bioerrorlog.work/entry/terraform-debug-logging
【2】タイムアウト時間を変更するには
https://stackoverflow.com/questions/58771440/how-to-set-timeout-for-terraform-apply
# より抜粋 resource "<resource_name>" "<resource_name>" { ... # ★ここ★ timeouts { create = "1h30m" update = "2h" delete = "20m" } }
https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts
【3】依存関係を指定するには
* 以下の2通り 1) resourceセクションから別リソースを参照 2) depends_on を指定
https://sdpf.ntt.com/services/docs/terraform/tutorials/rsts/Terraform/tips.html
1) resourceセクションから別リソースを参照
例:VPC
data "aws_region" "current" {} resource "aws_vpc_ipam" "test" { operating_regions { region_name = data.aws_region.current.name } } resource "aws_vpc_ipam_pool" "test" { address_family = "ipv4" # ★ここに注目★(別ファイルでも可能) ipam_scope_id = aws_vpc_ipam.test.private_default_scope_id locale = data.aws_region.current.name }
2) depends_on を指定
https://developer.hashicorp.com/terraform/language/meta-arguments/depends_on
例:VPC
resource "aws_vpc_ipam_pool_cidr" "test" { ipam_pool_id = aws_vpc_ipam_pool.test.id cidr = "172.2.0.0/16" } resource "aws_vpc" "test" { ipv4_ipam_pool_id = aws_vpc_ipam_pool.test.id ipv4_netmask_length = 28 # ★ここに注目★ depends_on = [ aws_vpc_ipam_pool_cidr.test ] }
補足:terraform graphで依存関係を可視化する
* terraform graphで、Terraformの依存関係をグラフ化することが可能 => 詳細は、以下の関連記事を参照のこと
Terraform ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2019/12/09/222057
【4】同じリソースを複数作成するには
https://tellme.tokyo/post/2022/06/12/terraform-count-for-each/
1)count を使う
https://developer.hashicorp.com/terraform/language/meta-arguments/count
resource "aws_instance" "server" { count = 4 # create four similar EC2 instances ami = "ami-a1b2c3d4" instance_type = "t2.micro" tags = { Name = "Server ${count.index}" } }
2)for_each を使う
https://developer.hashicorp.com/terraform/language/meta-arguments/for_each
resource "aws_iam_user" "the-accounts" { for_each = toset( ["Todd", "James", "Alice", "Dottie"] ) name = each.key }
【Terraform】(初心者向け)for_eachの使い方(実例つき) - 自由気ままに書いちゃおう
【5】ZIPファイル作成するには
* data "archive_file"で行う
https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file
https://registry.terraform.io/providers/hashicorp/archive/latest/docs/resources/file.html
使用上の注意
* Terraform 上で生成したものをZIP化する場合、 depends_on を指定すること
サンプル
main.tf
resource "local_file" "for_test1" { content = "hello!" filename = "${path.module}/test/hello.txt" } resource "local_file" "for_test2" { content = "world!" filename = "${path.module}/test/world.txt" } resource "local_file" "for_test3" { content = "test!" filename = "${path.module}/test/test.txt" } data "archive_file" "for_zip_file" { type = "zip" source_dir = "${path.module}/test" output_path = "${path.module}/output.zip" excludes = [ "test.txt" ] depends_on = [ local_file.for_test1, local_file.for_test2, local_file.for_test3 ] }
コマンド例
terraform init terraform apply # output.zipってファイルができて、 # 解凍すると「hello.txt」「world.txt」ができているはず
【6】コマンドを実行するには
* data "external" を使う
https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external
使用上の注意
* コマンドの戻り値は、Json形式 => 「Program output must be a JSON encoded map of string keys and string values.」 って怒られる
サンプル
main.tf
data "external" "hello_world" { # 実行したいコマンド program = ["python", "hello_world.py"] # 他にも、以下のような例がある # ex1. program = ["bash", "hello_world.sh"] # ex2. program = ["aws", "s3", "ls"] # 引数 query = { name = "Mike" } } output "result" { value = data.external.hello_world.result["result"] }
hello_world.py
#!/usr/bin/env python # -*- coding: utf-8 -*- import json import sys def main(): input_data = json.load(sys.stdin) name = input_data['name'] json.dump({ "result": f"Hello, {name}!!"}, sys.stdout) if __name__ == '__main__': main()
コマンド例
terraform init terraform apply ・・・略・・・ Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: result = "Hello, Mike!!"
関連記事
Terraform ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2023/04/05/000224
Terraform ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2019/12/09/222057
Terraform ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2023/05/03/000000
Terraform ~ テンプレート ~
https://dk521123.hatenablog.com/entry/2023/05/22/101325
Terraform ~ AWS IAM ~
https://dk521123.hatenablog.com/entry/2023/04/12/214311
Terraform ~ AWS S3 ~
https://dk521123.hatenablog.com/entry/2023/04/09/104204
Terraform ~ AWS EC2 ~
https://dk521123.hatenablog.com/entry/2023/05/21/003048
Terraform ~ AWS MSK ~
https://dk521123.hatenablog.com/entry/2023/05/14/122215
Terraform ~ 機密情報の扱いを考える ~
https://dk521123.hatenablog.com/entry/2023/05/18/005103