NRIネットコム Blog

NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

Terraformでローカルファイルを操作する方法  ~よくある使い方3選~

こんにちは、後藤です。
Terraform開発を進める中で「こんなことできるのか」と思った機能があったので、備忘録も兼ねて紹介します。

それはローカルのファイルを操作できる、という機能です。
TerraformではAWSやAzure、GCPなどのパブリッククラウドプロバイダを扱えますが、localやarchiveといったHashiCorp社によるプロバイダがあります。 このプロバイダを使えば、Terraformを実行するローカル環境のファイル操作が可能になります。

当記事では、よく使われるであろう方法を3つ紹介していきます。
※Terraformバージョン1.5.6で検証しております。

1つ目:local_file

local_fileリソースを記述すればローカル環境にファイルを作成できます。resourceブロックによってファイルを作成し、dataブロックによってファイルを読み込むことができます。
またfile_permissionといった設定項目があり、作成したファイルのパーミッションを設定することもできます。

resource "local_file" "example" {
  content  = "hello"
  filename = "./hello.txt"
  file_permission = "0600"
}

local_fileの使用例①

パラメータをtfファイル内に記載せず、別のテキストファイルで管理したいときに使えます。
以下の例ではdataブロックを使ってローカルにあるIPリストファイルを読み込み、読み込んだ内容をS3に格納しています。このS3を他のAWSサービスから参照する構成にしていれば有効的です。

data "local_file" "ip_list" {
  filename = "./ip_list.txt"
}

resource "aws_s3_object" "object" {
  bucket  = "my-bucket"
  key     = "my-key"
  content = data.local_file.ip_list.content
}

パラメータを編集する際は特定ファイルのみに絞ることができ、tfファイルを操作する必要がなくなるので、セキュリティ強化にもなります。

2つ目:local_sensitive_file

local_sensitive_fileリソースを記述すれば、パスワードなど機微情報をbase64エンコードしてローカル環境にファイルを作成することができます。
local_file同様、file_permission項目が設定可能です。

resource "local_sensitive_file" "example_secret" {
  content  = "keypair.pem"
  filename = "./foo.bar"
}

local_sensitive_fileの使用例

EC2-Windowsを作成して、OSにログインするときに使えます。 EC2-WindowsへOSログインするには事前にキーペアを作成しておき、それを登録する必要があります。 以下例ではキーペアを作成し、それを使ってEC2を作成していますが、ローカルにpemファイルを保存するようにもしています。

resource "tls_private_key" "ssh-keygen" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

resource "aws_key_pair" "key-pair" {
  key_name   = "ec2-keypair"
  public_key = tls_private_key.ssh-keygen.public_key_openssh
}

resource "aws_instance" "ec2-windows" {
  ami           = "abcd123456789"
  instance_type = "t3.large"
  key_name = aws_key_pair.key-pair.key_name
}

resource "local_sensitive_file" "key-pair-pem" {
  content  = tls_private_key.ssh-keygen.private_key_pem
  filename = "./keypair.pem"
}

1~9行目でキーペアを作り、11~15行目でそのキーペアを用いてEC2を作成、17~20行目でローカルに保存しています。

3つ目:archive_file

archive_fileリソースを記述すれば、ローカルファイルをzip化することができます。

data "archive_file" "example-archive" {
  type        = "zip"
  source_file = "./function.py"
  output_path = "./files/function.zip"
}

archive_fileの使用例

Lambdaスクリプトをローカルで管理する場合に有効です。

data "archive_file" "function-code" {
  type        = "zip"
  source_dir  = "lambda/function"
  output_path = "lambda/upload/function.zip"
}

resource "aws_lambda_function" "function" {
  filename         = data.archive_file.function-code.output_path
  function_name    = "function-example"
  role             = aws_iam_role.lambda_function_role.arn
  handler          = "lambda_function.lambda_handler"
  source_code_hash = data.archive_file.function-code.output_base64sha256
  runtime          = "python3.12"
  memory_size = 128
  timeout     = 30
}

Lambdaスクリプトをtfファイルではなく、外部ファイルで管理できるようになります。

おまけ

local_fileを使った一風変わった使い方も紹介しておきます。リージョンを跨いでリソースを動的参照する方法です。

複数リージョン構成では、以下のようにリージョンごとにフォルダを分けることが多いと思います。

env/
  ├─ap-northeast-1/
  |   ├─terraform.tf
  |   ├─alb.tf
  |   ├─s3.tf
  |   └─route53.tf
  |
  ├─ap-northeast-3/
  |   ├─terraform.tf
  |   └─alb.tf
  |


しかし別リージョンのリソースを参照する場合、aws_lb.test.zone_idのような動的参照ができないので、取得したいリソースの値をべた書きすることになります。

そこで、local_fileを使って動的に取得できるようにします。
local_fileを使って値をファイルに出力し、他リージョンのリソースからそのファイルを読み込む仕組みです。 以下の例では大阪リージョンにあるALBの値をファイルに出力し、東京リージョンではそのファイルを読み込んで、Route53に設定しています。

値のべた書きを避けられるのは良いですね。

参考

local_fileリファレンス registry.terraform.io

local_sensitive_fileリファレンス registry.terraform.io

archive_fileリファレンス registry.terraform.io

執筆者: 後藤 涼太
AWSをメインとするクラウドエンジニア
2024 Japan AWS All Certifications Engineers
執筆記事:https://tech.nri-net.com/archive/author/r-goto