Amazon EC2上にHCP Terraform Agentをセットアップしてみる

Amazon EC2上にHCP Terraform Agentをセットアップしてみる

2025.06.14

HCP Terraformはデフォルトでは、HCP Terraformの使い捨てVM上でTerraformの実行が行われます。

HCP Terraform Agentを使うことで、Terraformの実行をオンプレやEC2等で行うことが可能です。

HCP Terraformの使い捨てVMではIPアドレスが固定できません。

この機能は送信元IPアドレスが制限されている環境で便利です。

今回は、Amazon EC2上にHCP Terraform Agentをセットアップしてみました。

EC2・HCP Terraform Agentプールの準備

Terraformを使ってセットアップします。

コードの全体は以下を確認ください。

https://github.com/msato0731/terraform-sample/tree/main/hcp-tf-agent-ec2

ブログ上では、EC2とHCP Terraform Agentプール部分を紹介します。

まずは、EC2です。

ec2.tf
locals {
  name   = "hcp-tf-agent"
  region = "ap-northeast-1"
}

module "vpc" {
  source             = "terraform-aws-modules/vpc/aws"
  name               = local.name
  cidr               = "10.0.0.0/16"
  azs                = ["ap-northeast-1a", "ap-northeast-1c"]
  public_subnets     = ["10.0.1.0/24", "10.0.2.0/24"]
  enable_nat_gateway = false
}

data "aws_ssm_parameter" "amazonlinux_2023" {
  name = "/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64"
}

resource "aws_instance" "hcp_tf_agent" {
  ami                         = data.aws_ssm_parameter.amazonlinux_2023.value
  associate_public_ip_address = true
  security_groups             = [aws_security_group.hcp_tf_agent.id]
  instance_type               = "t3.small"
  vpc_security_group_ids      = [aws_security_group.hcp_tf_agent.id]
  iam_instance_profile        = aws_iam_instance_profile.ssm_profile.name
  tags = {
    Name = local.name
  }
}

resource "aws_iam_role" "ssm_role" {
  name = "${local.name}-ssm-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect = "Allow"
      Principal = {
        Service = "ec2.amazonaws.com"
      }
      Action = "sts:AssumeRole"
    }]
  })
}

resource "aws_iam_role_policy_attachment" "ssm_managed" {
  role       = aws_iam_role.ssm_role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}

resource "aws_iam_instance_profile" "ssm_profile" {
  name = "${local.name}-ssm-profile"
  role = aws_iam_role.ssm_role.name
}

resource "aws_security_group" "hcp_tf_agent" {
  name        = local.name
  description = local.name
  vpc_id      = module.vpc.vpc_id
}

resource "aws_vpc_security_group_egress_rule" "allow_all_outbound" {
  security_group_id = aws_security_group.hcp_tf_agent.id
  ip_protocol       = "-1"
  cidr_ipv4         = "0.0.0.0/0"
}

HCP Terraform Agentのハードウェア要件は以下になります。

HCP Terraform agent requirements | Terraform | HashiCorp Developer

ポイントを抜粋します。

  • 4GBの空きディスク容量
  • 2GBのシステムメモリ
  • 以下ホスト名に対するHTTPSアウトバウンド通信
    • app.terraform.io
    • registry.terraform.io
    • release.hashicorp.com
    • archivist.terraform.io
  • 以下ホスト名に対するtcp/7146アウトバウンド通信
    • agent.terraform.io

要件を満たすために、インスタンスサイズはt系であればsmall以上を利用します。

今回は、検証環境のためアウトバウンド通信は全て許可しています。(本来ならSecurity Groupで必要なアウトバウンド通信だけ開けてあげたほうがいいかと思います。)

またコスト節約のために、NAT Gatewayは作成せずにEC2インスタンスにPublicIPを付与しています。VPC内にNatGatewayを用意している場合は、EC2へのPublic IP付与は不要です。

このあとの手順で、EC2上で設定が必要なためEC2にログインするために、セッションマネージャー用のIAMロールをセットしています。

Agentプールの設定は以下です。

agent-pool.tf
resource "tfe_agent_pool" "this" {
  name                = "sato-blog-test"
  organization        = var.hcp_tf_organization_name
  organization_scoped = true
}

resource "tfe_agent_token" "this" {
  agent_pool_id = tfe_agent_pool.this.id
  description   = "sato-blog-test"
}

sato-blog-testの部分は環境に合わせて置き換えてもらえればと思います。

tfe_agent_tokenもTerraformで作成しています。Statefile上にtokenが残るため、本番運用時はご注意ください。(Tokenの発行は手動とする等)

EC2インスタンスにHCP Terraform Agentをインストール

公式ドキュメントに従って、HCP Terraform Agentのインストールを行います。

Install and run HCP Terraform agents | Terraform | HashiCorp Developer

セッションマネージャーを使って、EC2インスタンスにログインします。

接続後、ec2-userにユーザーを切り替えます。

sudo su ec2-user
cd /home/ec2-user

必要なソフトウェアに関して、ドキュメント上に記載があります。

HCP Terraform agent requirements | Terraform | HashiCorp Developer

一部Amazon Linux 2023のデフォルトではインストールされていないものがあるため、インストールします。

sudo dnf install git jq

次にAgentをインストールします。

Agentの実行形式はバイナリとDockerの2つから選べます。

今回はバイナリを使用します。

Agentは以下からダウンロードできます。

Tfc-Agent Versions | HashiCorp Releases

以下では1.22.3を利用していますが、上記から最新のものを選択してください。

# Agentインストール
wget https://releases.hashicorp.com/tfc-agent/1.22.3/tfc-agent_1.22.3_linux_amd64.zip
unzip tfc-agent_1.22.3_linux_amd64.zip

HCP Terraform Agent トークンを確認します。

トークンもTerraformで作成したため、Statefileから確認できます。(tfe_agent_tokenとかで検索)

Agentの動作を確認します。

# 環境変数セット
export TFC_AGENT_TOKEN=<Token>
export TFC_AGENT_NAME=agent # 任意で変更可能
# agent起動
./tfc-agent

デフォルトではフォアグラウンドで実行されますので、エラーがでないことを確認してcmd + c(Mac)で終了します。

出力例
025-06-13T10:24:22.357Z [INFO]  agent: Starting: agent_name=agent agent_version=1.22.3 os=linux arch=amd64
2025-06-13T10:24:22.374Z [INFO]  core: Starting: version=1.22.3
2025-06-13T10:24:23.111Z [INFO]  core: Agent registered successfully with HCP Terraform: agent_id=agent-gydDEA3GFSrSfETT agent_pool_id=apool-oMMEnwmbsRHZd1Jc
2025-06-13T10:24:23.152Z [INFO]  agent: Core update is available: version=1.22.4
2025-06-13T10:24:24.494Z [INFO]  agent: Core successfully updated: version=1.22.4
2025-06-13T10:24:24.498Z [INFO]  agent: Core plugin is shutting down
2025-06-13T10:24:24.683Z [INFO]  core: Shutdown complete
2025-06-13T10:24:24.690Z [INFO]  plugin: plugin process exited: plugin=/home/ec2-user/tfc-agent-core id=26567
2025-06-13T10:24:24.706Z [INFO]  core: Starting: version=1.22.4
2025-06-13T10:24:25.401Z [INFO]  core: Agent registered successfully with HCP Terraform: agent_id=agent-p34j1oGXPKT6jgZb agent_pool_id=apool-oMMEnwmbsRHZd1Jc
2025-06-13T10:24:25.407Z [INFO]  agent: Core version is up to date: version=1.22.4
2025-06-13T10:24:25.407Z [INFO]  core: Waiting for next job

tfc-agentをSystemdに登録

We strongly recommend pairing the agent with a process supervisor to ensure that it automatically restarts in case of an error.

Install and run HCP Terraform agents | Terraform | HashiCorp Developer

ドキュメント上ではプロセススーパーバイザーの利用が推奨されています。

今回はSystemdを使ってtfc-agentプロセスをサービス化します。

手順は以下を参考にしました。

How to run tfc-agent binary as a Service with systemd – HashiCorp Help Center

/opttfc_agentをコピーして、TOKEN等を記載したファイルを用意します。

sudo mkdir /opt/tfc_agent
sudo cp tfc-agent /opt/tfc_agent/
sudo cp tfc-agent-core /opt/tfc_agent/
ls -1 /opt/tfc_agent/

/opt/tfc_agent配下が以下になっていればOKです。

出力例
tfc-agent
tfc-agent-core
# https://developer.hashicorp.com/terraform/cloud-docs/agents/agents#cli-options
# Run the following command as root
cat > tfc-agent.env << EOF
TFC_AGENT_TOKEN=$TFC_AGENT_TOKEN
TFC_AGENT_NAME=$TFC_AGENT_NAME
TFC_AGENT_LOG_LEVEL=INFO
EOF
sudo mv tfc-agent.env /opt/tfc_agent/

Systemdサービスファイルを作成します。

cat > tfc-agent.service << EOF
[Unit]
Description=Service to automatically start TFC/E Agent
After=network.target

[Install]
WantedBy=multi-user.target

[Service]
EnvironmentFile=/opt/tfc_agent/tfc-agent.env
Type=simple
ExecStart=/opt/tfc_agent/tfc-agent
KillSignal=SIGINT
WorkingDirectory=/opt/tfc_agent
Restart=always
RestartSec=5
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n
EOF
sudo mv tfc-agent.service /etc/systemd/system/tfc-agent.service
sudo chown root:root /etc/systemd/system/tfc-agent.service

Systemdをリロードします。

sudo systemctl daemon-reload
sudo systemctl enable tfc-agent
sudo systemctl start tfc-agent

ステータスを確認します。

sudo systemctl status tfc-agent

service: enabledになっていることを確認します。

出力例
● tfc-agent.service - Service to automatically start TFC/E Agent
     Loaded: loaded (/etc/systemd/system/tfc-agent.service; enabled; preset: disabled)
     Active: active (running) since Fri 2025-06-13 10:51:50 UTC; 4s ago
   Main PID: 28673 (tfc-agent)
      Tasks: 15 (limit: 2253)
     Memory: 18.2M
        CPU: 101ms
     CGroup: /system.slice/tfc-agent.service
             ├─28673 /opt/tfc_agent/tfc-agent
             └─28687 /opt/tfc_agent/tfc-agent-core

Jun 13 10:51:50 ip-10-0-1-138.ap-northeast-1.compute.internal systemd[1]: Started tfc-agent.service - Service to automatically start TFC/E Agent.
Jun 13 10:51:50 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T10:51:50.638Z [INFO]  agent: Starting: agent_name=agent agen>
Jun 13 10:51:50 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T10:51:50.656Z [INFO]  core: Starting: version=1.22.4
Jun 13 10:51:51 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T10:51:51.358Z [INFO]  core: Agent registered successfully wi>
Jun 13 10:51:51 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T10:51:51.435Z [INFO]  agent: Core version is up to date: ver>
Jun 13 10:51:51 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T10:51:51.435Z [INFO]  core: Waiting for next job

動作確認

WorkspaceのExecution ModeをAgentに変更します。

今回作成したAgent Poolを指定します。

Cursor_と_General_Settings___classmethod-sandbox___HCP_Terraform.png

EC2上でコマンドを実行して、ログを確認します。

sudo journalctl -xu tfc-agent -f

Runを行うとログが流れていることが確認できると思います。

HCP Terraform 上からもRunが正常に実行されたことを確認できました。

ログ出力例
Jun 13 11:02:43 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T11:02:43.109Z [INFO]  terraform: Handling run: run_id=run-qqGq6aBzvAe76bKt run_operation=plan organization_name=classmethod-sandbox workspace_name=sample-ec2
Jun 13 11:02:43 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T11:02:43.679Z [INFO]  terraform: Extracting Terraform from release archive
Jun 13 11:02:44 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T11:02:44.392Z [INFO]  terraform: Terraform CLI details: version=1.11.0
Jun 13 11:02:44 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T11:02:44.392Z [INFO]  terraform: Preparing authentication for AWS provider
Jun 13 11:02:44 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T11:02:44.393Z [INFO]  terraform: Downloading Terraform configuration
Jun 13 11:02:44 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T11:02:44.598Z [INFO]  terraform: Running terraform init
Jun 13 11:03:01 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T11:03:01.194Z [INFO]  terraform: Checking for eol module versions
Jun 13 11:03:01 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T11:03:01.270Z [INFO]  terraform: Running terraform plan
Jun 13 11:03:10 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T11:03:10.727Z [INFO]  terraform: Generating and uploading plan JSON
Jun 13 11:03:15 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T11:03:15.180Z [INFO]  terraform: Generating and uploading provider schemas JSON
Jun 13 11:03:24 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T11:03:24.059Z [INFO]  terraform: Generating and uploading redacted plan JSON
Jun 13 11:03:25 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T11:03:25.144Z [INFO]  terraform: Persisting filesystem to remote storage
Jun 13 11:03:26 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T11:03:26.068Z [INFO]  terraform: Finished handling run
Jun 13 11:03:26 ip-10-0-1-138.ap-northeast-1.compute.internal tfc-agent.service[28673]: 2025-06-13T11:03:26.675Z [INFO]  core: Waiting for next job

run-qqGq6aBzvAe76bKt___Runs___classmethod-sandbox___HCP_Terraform.png

おわりに

EC2インスタンスにHCP Terraform Agentをセットアップしてみました。

1つのAgentが1つのRunを実行します。

2つのRun(Run A,B)が作成されたら、Run A 処理中はRun Bは待ち状態になります。

規模が拡大して待ち時間が気になるようになった場合は、Agentのスケールを検討する必要があります。

Agentのスケールには、HCP Terraform Operator v2が良さそうです。今度試してみようと思います。

Manage agent pools with the HCP Terraform Operator v2 | Terraform | HashiCorp Developer

この記事をシェアする

facebookのロゴhatenaのロゴtwitterのロゴ

© Classmethod, Inc. All rights reserved.