Terraformで外部の設定ファイルから設定を読み込む(file, template_file, template_cloudinit_config)
今日はとりあえずTerraformのTemplateプロバイダーを少しさわってみようと思います*1。
TerraformのTemplateプロバイダーには、データリソース*2として
- template_file
- template_cloudinit_config
リソースとして
- template_dir*3
がありますが、今回は template_file
を試してみます。
また、これらの前にファイル利用つながりで file
組み込み関数もためして、 template_cloudinit_config
データリソースにも少しだけふれます。
TL;DR
- 外部に書いた設定ファイルの内容を
file
組み込み関数で読み出す template_file
データリソースを使って一部の設定を変数で置き換えられるようにする- EC2の起動時の設定で
userdata
とcloud-init
の両方を使う場合はtemplate_cloudinit_config
データリソースを使うと書きやすい
外部に書いた設定ファイルの内容を file
組み込み関数で読み出す
TerraformでAWSのリソースの設定を書いていると、JSONなどHCLで書きにくい部分があると思います。
そういった部分を外部ファイルに書き出して、 file
組み込み関数で必要な箇所で読みだすことができます。
たとえば、
resource "aws_iam_role" "test_role" { name = "test_role" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "ec2.amazonaws.com" }, "Effect": "Allow", "Sid": "" } ] } EOF }
というtfファイルを書いた時、 <<EOF
から EOF
の部分を外部ファイルに抜き出して、
{ "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Principal": { "Service": "ec2.amazonaws.com" }, "Effect": "Allow", "Sid": "" } ] }
resource "aws_iam_role" "test_role" { name = "test_role" assume_role_policy = "${file("./test_policy.json")}" }
のように書くことができます。こうすることで、設定の方もシンタックスハイライトが効く環境で編集できるので捗りそうですね。
template_fileデータリソースを使って一部の設定を変数で置き換えられるようにする
設定は外部ファイルで書きたいのだけれど、設定の中で一部だけ変数を利用したい、という場合があります。
この場合は template_file
データリソースを利用すると便利です。
たとえば、
resource "aws_iam_policy" "test_role_app" { name = "test_role_app" policy = "${file("./test_policy.json")}" }
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecs:Describe*", "ecs:List*" ], "Resource": "arn:aws:ecs:region:account:cluster/my-cluster" } ] }
のようなIAMポリシーがあったとして、対象のリソースだけを変えて同じようなアクションを許可するポリシーを他にも作りたい場合、template_file データリソースが使えます。
// ファイル名は test_policy.json から test_policy.json.tpl に変更 { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecs:Describe*", "ecs:List*" ], "Resource": "arn:aws:ecs:region:account:cluster/${cluster_name}" } ] }
のように外部設定ファイルを編集すると、 ${cluster_name}
の部分を template_file
データリソースのブロック中で設定できます。
data "template_file" "test_policy" { template = "${file("./test_policy.json.tpl")}" vars { cluster_name = "my_cluster" } } resource "aws_iam_policy" "test_role_app" { name = "test_role_app" policy = "${data.template_file.test_policy.rendered}" }
EC2の起動時の設定でuserdataとcloud-initの両方を使う場合は template_cloudinit_config データリソースを使うと書きやすい
先ほどの template_file
の設定は、EC2の起動時の設定で userdata
を利用してECSのクラスターを指定する、といった設定の一部だけ置き換えたい、といった場合に便利そうですが、 ECSの設定は userdata
だけでなく cloud-init
を利用して行うことも可能です*4。
そして、単純に userdata
と cloud-init
のそれぞれの設定を書いた場合、両者の設定を共存させることはできません。
userdata
と cloud-init
の設定を共存させたい場合、両者の設定をマルチパート形式のテキストに変換し、userdata
に書き込む必要があります。
これはなかなか大変ですが、 template_cloudinit_config
データリソースの part
属性を利用するとこの変換作業を行う必要がなくなります。
現場からは以上です。
*1:今日からコマンドじゃなくてソフトウェアとしてのTerraformはTerraformと表記することにする
*2:プロバイダのページの見出し(たとえば、Templateプロバイダ https://www.terraform.io/docs/providers/template/index.html )ではData Sourcesと書いてあるが、だいたい日本語だとデータリソースと出てくる(たとえば、Terraform for さくらのクラウド データリソースとは https://sacloud.github.io/terraform-provider-sakuracloud/configuration/resources/data_resource/ )
*3:http://febc-yamamoto.hatenablog.jp/entry/2018/02/05/193735 の記事がTemplateプロバイダーのデータリソース、リソースについて詳しいです
*4:https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/user-data.html#user-data-cloud-init