はじめに
Terraform の組み込み関数に templatefile という関数が用意されており、それを使うと tf や JSON などのファイルをテンプレートとしてレンダリングできる。
templatefile(path, vars)
上記のような構文で、第一引数の path でテンプレートとして使用するファイルのパスを指定し、第二引数の vars でテンプレートファイルに渡す引数をオブジェクト形式で指定する。
やり方
今回の記事では、AWS ECS の task definition のリソース定義である aws_ecs_task_definition で使用した例をあげる。
該当箇所以外は省略して記載しているのでご注意いただければと思う。
まずは、main.tf の container_definitions のところで templatefile 関数を使っている。
./templates/api.json.tpl をテンプレートファイルのパスとして指定し、vars.secrets を渡している。
aws_ecs_task_definition は結構肥大化しやすいので、container_definitions の箇所を別ファイル化しておくと可読性を維持できていいと思う。
resource "aws_ecs_task_definition" "main" {
...
(省略)
...
container_definitions = templatefile("${path.module}/templates/api.json.tpl", var.container_def_vars)
}
variable "container_def_vars" {
type = map(string)
default = {}
}
次にテンプレートファイルの JSON だが、以下のようなイメージで作ってあげればいいと思う。
例によってあまり関係ない箇所は省略しているが、${var} のような記述をしているところに注目してほしい。このように記述することで外部から引数を渡すことができる。
以下のファイルでは ${node_env} と ${port} を外部から注入している。
[
{
"name": "sample-api",
"image": "xxxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/sample-api",
"cpu": 0,
"portMappings": [
{
"name": "sample-api-tcp",
"containerPort": 4000,
"hostPort": 4000,
"protocol": "tcp"
}
],
"essential": true,
"environment": [],
"secrets": [
{
"name" : "NODE_ENV",
"valueFrom" : "${node_env}" // <-- here
},
{
"name" : "PORT",
"valueFrom" : "${port}" // <-- here
}
],
"mountPoints": [],
"volumesFrom": [],
"logConfiguration": { ... (省略) ... }
}
]
まとめ
以上、templatefile 関数を使ってテンプレートファイルに変数を埋め込む方法を紹介した。こんな書き方をできるのを知らなかったので、誰かの参考になればと思う。
参考