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
    2025 Japan AWS All Certifications Engineers
    執筆記事:https://tech.nri-net.com/archive/author/r-goto