Amazon EC2上にHCP Terraform Agentをセットアップしてみる
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を使ってセットアップします。
コードの全体は以下を確認ください。
ブログ上では、EC2とHCP Terraform Agentプール部分を紹介します。
まずは、EC2です。
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"
subnet_id = module.vpc.public_subnets[0]
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
from_port = 0
to_port = 0
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で必要なアウトバウンド通信だけ開けてあげたほうがいいかと思います。)
このあとの手順で、EC2上で設定が必要なためEC2にログインするために、セッションマネージャー用のIAMロールをセットしています。
Agentプールの設定は以下です。
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
/opt
にtfc_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を指定します。
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
おわりに
EC2インスタンスにHCP Terraform Agentをセットアップしてみました。
1つのAgentが1つのRunを実行します。
2つのRun(Run A,B)が作成されたら、Run A 処理中はRun Bは待ち状態になります。
Agentのスケールには、HCP Terraform Operator v2が良さそうです。今度試してみようと思います。
Manage agent pools with the HCP Terraform Operator v2 | Terraform | HashiCorp Developer
以上、AWS事業本部の佐藤(@chari7311)でした。