TerraformのData Sourcesといえば既存のリソースを参照するときに利用するアレだ。
見るシーンとしては「AWSコンソール側ですでに作成済みのリソースがあるんだけど、Terraformで参照だけしたい」みたいな。
# lambda.tf data "aws_lambda_function" "hoge_function" { provider = aws.us-east-1 function_name = "hogeFunction" } # cloudfront.tf origin { # ~省略~ lambda_function_association { event_type = "origin-request" include_body = true lambda_arn = data.aws_lambda_function.hoge_function.qualified_arn } # ~省略~ }
私はこのData resourcesはリモート側にあるものを参照する場合に利用するものだと思っていたので、特殊なData sourcesがあることを意識していなかった。
aws_iam_policy_documentはリモートに存在していなくても参照できる
これが今回の本題というか、知らなかった話。
TerraformでIAM系を書く場合、ポリシーの設定方法はいくつかあって、私はjsonファイルを定義して参照させていた。
例えばこう。
// ./templates/assume-policy.json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::${aws_account_id}:root" }, "Action": "sts:AssumeRole" } ] }
で、tfファイル側で引数と一緒に定義する。
resource "aws_iam_role_policy" "hoge_policy" { policy = templatefile("./templates/assume-policy.json", { aws_account_id = "1234567" }) role = aws_iam_role.hoge.id }
もちろん↑の方法でも定義できるのだが、次のようにaws_iam_policy_document
を定義して、data.aws_iam_policy_document.assume_role.json
でアクセスすることもできる。
data "aws_iam_policy_document" "assume_role" { statement { actions = ] "sts:AssumeRole" ] principals { type = "Federated" identifiers = ["arn:aws:iam::${var.aws_account_id}:saml-provider/${var.provider_name}", "cognito-identity.amazonaws.com"] } } resource "aws_iam_policy" "example" { name = "example_policy" path = "/" policy = data.aws_iam_policy_document.assume_role.json }
ローカルで動くData Sourcesについて
aws_iam_policy_document
による結果はローカルのTerraform操作中の一時的な状況でだけデータを持っていて、planが走る度に再計算するようになっているらしい。
The behavior of local-only data sources is the same as all other data sources, but their result data exists only temporarily during a Terraform operation, and is re-calculated each time a new plan is created.
そしてこのような特殊な(リモートオブジェクトにアクセスしない)Data Sourcesはaws_iam_policy_document, template_file, local_fileの3つがあるようだ。
ずっとaws_iam_policy_document
はリモートにアクセスしていると思っていたので、案外雰囲気でTerraformを使っていたなあと思った。