file / fileexists / fileset — ファイル操作関数

1. 概要

  • file — ファイルの内容を文字列として読み込む
  • fileexists — ファイルが存在するか確認する
  • fileset — パターンにマッチするファイルのパス一覧を取得する
  • filebase64 — ファイルの内容をBase64エンコードして読み込む
  • 実際のユースケース(公開鍵・設定ファイル・ラムダZIPなど)

Terraformのファイル操作関数を使うと、SSHの公開鍵・ユーザーデータスクリプト・設定ファイルなど、外部ファイルの内容をHCLコード内で直接参照できます。


2. file — ファイルを読み込む

file(path)は、指定したパスのファイルを読み込んで文字列として返します。パスは.tfファイルからの相対パス、または絶対パスで指定します。

# terraform consoleで確認
> file("./files/user_data.sh")
"#!/bin/bash\nset -e\n..."

SSHの公開鍵を読み込む

terraform {
  required_version = ">= 1.9"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

variable "environment" {
  description = "環境名"
  type        = string
  default     = "dev"
}

# ローカルの公開鍵ファイルを読み込んでキーペアを作成
resource "aws_key_pair" "deployer" {
  key_name   = "${var.environment}-deployer-key"
  public_key = file("~/.ssh/id_rsa.pub")  # ローカルの公開鍵を読み込む

  tags = {
    Name        = "${var.environment}-deployer-key"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

ユーザーデータスクリプトを外部ファイルから読み込む

data "aws_ami" "amazon_linux_2023" {
  most_recent = true
  owners      = ["amazon"]
  filter {
    name   = "name"
    values = ["al2023-ami-*-x86_64"]
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.micro"
  key_name      = aws_key_pair.deployer.key_name

  # 外部ファイルからユーザーデータを読み込む
  user_data = file("${path.module}/scripts/user_data.sh")

  root_block_device {
    volume_size = 20
    volume_type = "gp3"
    encrypted   = true
  }

  tags = {
    Name        = "${var.environment}-web"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

3. fileexists — ファイルの存在確認

fileexists(path)は、指定パスにファイルが存在すればtrue、存在しなければfalseを返します。

locals {
  # カスタム設定ファイルが存在すれば使用、なければデフォルトを使用
  config_file = fileexists("${path.module}/config/custom.conf") ? file("${path.module}/config/custom.conf") : file("${path.module}/config/default.conf")

  # 環境固有の公開鍵があれば使用、なければ共通鍵を使用
  public_key = fileexists("~/.ssh/${var.environment}_rsa.pub") ? file("~/.ssh/${var.environment}_rsa.pub") : file("~/.ssh/id_rsa.pub")
}

4. fileset — ファイル一覧を取得する

fileset(path, pattern)は、pathディレクトリ内でpattern(glob)にマッチするファイルのパス一覧をsetで返します。

# terraform consoleで確認
# fileset("ベースパス", "パターン")
> fileset("./policies", "*.json")
toset(["admin.json", "readonly.json", "s3-access.json"])

> fileset("./lambda", "**/*.py")
toset(["handlers/auth.py", "handlers/api.py", "utils/helper.py"])

IAMポリシーファイルを一括作成する

locals {
  # policiesディレクトリ内の全JSONファイルを取得
  policy_files = fileset("${path.module}/policies", "*.json")
  # → toset(["admin.json", "readonly.json"])
}

resource "aws_iam_policy" "from_files" {
  # 各JSONファイルからIAMポリシーを作成
  for_each = local.policy_files

  name        = "${var.environment}-${replace(each.value, ".json", "")}"
  description = "Policy from ${each.value}"
  policy      = file("${path.module}/policies/${each.value}")

  tags = {
    Name        = "${var.environment}-${replace(each.value, ".json", "")}"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

5. filebase64 — Base64エンコードで読み込む

filebase64(path)は、ファイルをBase64エンコードした文字列として返します。バイナリファイル(ZIP・画像など)を扱うときに使います。

# Lambda関数のZIPファイルをBase64で渡す場合
resource "aws_lambda_function" "api" {
  function_name    = "${var.environment}-api"
  role             = aws_iam_role.lambda.arn
  handler          = "index.handler"
  runtime          = "nodejs20.x"
  filename         = "${path.module}/lambda/function.zip"
  source_code_hash = filebase64sha256("${path.module}/lambda/function.zip")

  tags = {
    Name        = "${var.environment}-api"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

6. path変数との組み合わせ

ファイルパスを指定する際によく使うTerraform組み込みのpath変数です。

変数意味
path.module現在の.tfファイルが存在するディレクトリ
path.rootルートモジュールのディレクトリ
path.cwdTerraformコマンドを実行したディレクトリ
# path.moduleを使うと、モジュール化しても正しいパスで動作する
user_data = file("${path.module}/scripts/user_data.sh")

7. 関連記事


8. まとめ

  • file(path) — ファイルを読み込んで文字列として返す。SSHキー・ユーザーデータ・設定ファイルの読み込みに使う
  • fileexists(path) — ファイルの存在確認。条件式と組み合わせてフォールバック処理に使う
  • fileset(path, pattern) — globパターンでファイル一覧をset取得。for_eachとの組み合わせで複数リソースを一括作成できる
  • filebase64(path) — バイナリファイルをBase64エンコードして返す
  • ファイルパスにはpath.moduleを使うとモジュール化に対応できる

動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/language/functions/file