NRIネットコム Blog

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

Terraformプロビジョナーを使って、さらなる自動化へ

本記事は  AWSアワード記念!夏のアドベントカレンダー  20日目の記事です。
🎆🏆  19日目  ▶▶ 本記事 ▶▶  21日目  🏆🎆

こんにちは後藤です。
この度、2024 AWS All Certifications Engineersに選出していただきました。次回も選出されるように日々努力を続けていきます。

私が書いた記事を振り返ってみると、気づけばTerraformの記事ばかりになっていました。
以前に「Terraformはこんなこともできるのか」シリーズを書いたのですが、今回も「Terraformはこんなこともできるのか」系のお話です。 tech.nri-net.com

紹介したいのは「Terraformプロビジョナー」

今回、ご紹介したい機能はTerraformプロビジョナーです。
Terraformプロビジョナーとは、リソースを作成した後に追加のアクションを実行できる機能のことです。使い方としてはTerraformコード上で、リソースブロックの中にプロビジョナーブロックを記述するだけです。
以下の例ではEC2を作成したあとに、ローカル環境上でパブリックIPを表示しています。

resource "aws_instance" "example" {

    (中略)

  provisioner "local-exec" {
    command = "echo ${self.public_ip}"
  }
}

このように、リソースを作った後のアクションまで自動化できます!

また、プロビジョナーをlocal-execとしましたがremote-execを使えばリモートアクセスしてコマンドを実行できます。
以下の例ではEC2を作成したあとに、そのEC2にSSHログインしてhostnameを設定しています。

resource "aws_instance" "example" {

    (中略)

    provisioner "remote-exec" {
        connection {
            type = "ssh"
            user = "ec2-user"
            key_file = "~/.ssh/ec2.pem"
        }
        inline = [
            "hostname ec2-example"
        ]
    }
}

OS設定が少量であればプロビジョナーでOS初期設定まで済ませる、というのも手かもしれません。

また、最近ではOS設定に関してはAnsibleで管理することも多いと思うので、TerraformとAnsibleの合わせ技もお勧めです。以下の例ではEC2作成後にsleepコマンドによって、すこし間隔をあけてからansibleを実行しています。これはTerraform上ではEC2作成完了してもOS設定まで終わっていないこともあるので、その点を考慮しています。

resource "aws_instance" "example" {

    (中略)

  provisioner "local-exec" {
    command = "sleep 30 &&  ansible-playbook playbook.yml"
  }
}

このようにTerraform実行からAnsible実行への流れも自動化できます。

OS初期設定に関しては、EC2にもユーザーデータという類似の機能があります。これを使用してEC2の初期設定や構成を自動化できますが、EC2ユーザーデータは起動時に1度だけ実行されるのに対し、Terraformプロビジョナーは起動時だけでなく、リソース破棄時にも実行可能です。
また、EC2ユーザーデータは主にEC2に対しての操作になりますが、Terraformプロビジョナーはローカルマシンや他のAWSリソースに対しても操作可能で、他のクラウドプロバイダーでも使用可能です。
こういった汎用性の高さから、Terraformを使用するプロジェクトでは、プロビジョナーの使用を検討する価値はあるのではないでしょうか。

リソース削除時が便利

プロビジョナーを定義する時、特に明記しなければリソース作成時に実行されるのですが、when = destroyを明記すれば削除時にも実行可能です。
以下の例では、EC2が削除されるときにALBからデタッチするコマンドを実行しています。EC2が削除される前にALBからデタッチされることで、ALBがEC2削除を検知しないようにしています。

resource "aws_instance" "example" {

    (中略)

  provisioner "local-exec" {
    when    = destroy
    command = "aws elbv2 deregister-targets --target-group-arn ${aws_lb_target_group.example.arn} --targets Id=${self.id}"
  }
}

このようにリソース削除時に検知されないようにしておく設定を入れておけば、うっかりアラートが飛んでしまうことを防ぐことができます。この他にも、一時ファイル削除といった作業環境のクリーンアップでも活用できます。

さいごに

プロビジョナーは、Terraformを実行した後に「これもついでにしておきたい」ができる、痒い所に手が届く機能です。
アイデア次第で、使い道は大きく広がりますのでぜひ使ってみてください。
他にも良い使い方があれば、ぜひ教えてください。

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