pathexpand / abspath / basename / dirname — パス操作関数

1. 概要

  • pathexpand~をホームディレクトリに展開
  • abspath — 相対パスを絶対パスに変換
  • basename — パスのファイル名部分を取得
  • dirname — パスのディレクトリ部分を取得
  • path.module / path.root / path.cwd の参照式

2. pathexpand — チルダを展開する

pathexpand(path)~で始まるパスをOSのホームディレクトリに展開します。ローカルの設定ファイルを参照する場合に使います。

# terraform consoleで確認
> pathexpand("~/.ssh/terraform_key.pub")
"/home/user/.ssh/terraform_key.pub"  # ユーザーのホームディレクトリに展開

> pathexpand("/etc/terraform.conf")
"/etc/terraform.conf"  # 絶対パスはそのまま

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"
}

variable "ssh_public_key_path" {
  description = "SSHの公開鍵ファイルパス"
  type        = string
  default     = "~/.ssh/terraform_key.pub"
}

resource "aws_key_pair" "deployer" {
  key_name   = "${var.environment}-deployer"
  public_key = file(pathexpand(var.ssh_public_key_path))

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

3. abspath — 相対パスを絶対パスに変換

abspath(path)は相対パスをTerraformが実行されているディレクトリ(カレントディレクトリ)を基準にした絶対パスに変換します。

# terraform consoleで確認
> abspath("./scripts/setup.sh")
"/home/user/infra/scripts/setup.sh"

> abspath("modules/shared")
"/home/user/infra/shared"

4. basename / dirname — パスの分解

basename(path)はパスの最後の要素(ファイル名)を返します。dirname(path)はパスのディレクトリ部分(最後の要素を除いたパス)を返します。

# terraform consoleで確認
> basename("/home/user/scripts/setup.sh")
"setup.sh"

> basename("scripts/setup.sh")
"setup.sh"

> dirname("/home/user/scripts/setup.sh")
"/home/user/scripts"

> dirname("scripts/setup.sh")
"scripts"

ファイル名からリソース名を生成する

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

variable "script_paths" {
  description = "アップロードするスクリプトファイルのパス"
  type        = list(string)
  default = [
    "scripts/setup.sh",
    "scripts/deploy.sh",
    "scripts/backup.sh"
  ]
}

locals {
  # パスからファイル名を取り出してS3キー名に使う
  scripts = {
    for path in var.script_paths :
    basename(path) => path
  }
  # → {"setup.sh" = "scripts/setup.sh", "deploy.sh" = "scripts/deploy.sh", ...}
}

resource "aws_s3_object" "scripts" {
  for_each = local.scripts

  bucket = "${var.environment}-scripts"
  key    = "scripts/${each.key}"
  source = each.value
  etag   = filemd5(each.value)

  tags = {
    Name        = each.key
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

5. path.module / path.root / path.cwd

これらはTerraformの組み込み参照式です(関数ではなく式)。

locals {
  # path.module: このTerraformファイルが含まれるモジュールのディレクトリ
  module_dir = path.module

  # path.root: ルートモジュール(terraform initを実行したディレクトリ)
  root_dir = path.root

  # path.cwd: terraform実行時のカレントディレクトリ
  current_dir = path.cwd
}

# モジュール内のファイルを参照するときはpath.moduleを使う
resource "aws_instance" "web" {
  ami           = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.micro"

  # path.moduleで相対パスを確実に解決
  user_data = filebase64("${path.module}/scripts/userdata.sh")

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

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

6. 比較表

関数/式動作ユースケース
pathexpand(path)~をホームディレクトリに展開ローカルのSSHキー参照
abspath(path)相対パスを絶対パスに変換パスの正規化
basename(path)ファイル名を取り出すリソース名の生成
dirname(path)ディレクトリ部分を取り出す親ディレクトリの取得
path.moduleモジュールのディレクトリモジュール内のファイル参照
path.rootルートモジュールのディレクトリルートからの相対パス

7. 関連記事


8. まとめ

  • pathexpand(path)~をホームディレクトリに展開。SSHキーの参照に使う
  • abspath(path) — 相対パスを絶対パスに変換
  • basename(path) — ファイル名部分を取り出す。for_eachのキー生成に便利
  • dirname(path) — ディレクトリ部分を取り出す
  • path.module — モジュール内でファイルを参照するときは必ず${path.module}/を付ける

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