🥢

Terraform Enterprise Flexible Deployment Option を GCP にインストールする

2024/02/06に公開

Terraform Enterprise Flexible Deployment Option(以下TFE FDO)をGoogle CloudのCompute Engineにインストールした際のメモです。
同じ様な環境でインストールされる際、参考にしてみて下さい。

Prerequisites

今回はGoogle Cloud Compute Engine(以下GCE)上にDockerでTFE FDOをインストールします。以下ドキュメントのMounted Diskモードを前提にしています。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/install/operation-modes#operational-modes

Operational Modesに依存せず、TFE FDOのインストールに必要な要件というのが以下のドキュメントに記載されているので、これを満たす様な形でGCEや証明書を準備します。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/install/requirements

また、DockerでTFE FDOをインストールする際の個別のインストール要件は以下のドキュメントに記載されているので、こちらも満たす様に環境を準備します。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/install/docker/requirements

Preparation

Docker engine

TFE FDOでサポートされているDocker engineのバージョンがありますので、それに準拠する形でインストールしておきます。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/install/docker/requirements#docker-engine

GCEはUbuntuを利用して構築しているので、以下の様な形でDocker engineをインストールしています。

VERSION_STRING=5:24.0.0-1~ubuntu.22.04~jammy

# 必要なパッケージのインストール
sudo apt-get update
sudo apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common

# Dockerの公式GPGキーを追加
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

# Dockerの安定版リポジトリを設定
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

# Docker engine v24.0のインストール
sudo apt-get update
sudo apt-get install -y docker-ce=$VERSION_STRING docker-ce-cli=$VERSION_STRING containerd.io docker-buildx-plugin docker-compose-plugin

# Dockerを起動し、システム起動時に自動的に起動するように設定
sudo systemctl start docker
sudo systemctl enable docker

# DockerのMTUを設定
sudo mkdir -p /etc/docker
echo '{
  "mtu": 1460
}' | sudo tee /etc/docker/daemon.json

# Dockerデーモンの再起動
sudo systemctl restart docker

sudo usermod -aG docker ubuntu

また、下記ドキュメントに記載がある通り、GCP環境のみDockerのMTUを1460に設定する必要があるため、上記の設定においてもそれを設定しています。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/install/requirements/network#other-configuration

TLS certificate

TFE FDOで利用する証明書はLet's Encryptを利用して準備しています。TFE FDOインスタンスで利用するホスト名はtfegcp.<MYDOMAIN>にしています。
TFE FDO自体は自己署名証明書でも動きますが、TFE FDOでもDynamic Credential with GCPの機能を利用しようとすると、自己署名証明書では上手く動かないため、Let's Encryptを利用して、証明書を準備しています。

Warning: Dynamic Credentials with the GCP provider do not work when your TFE instance is using a custom or self-signed certificate due to restrictions on GCP's end.

Let's Encryptでの証明書発行は以下のcertbotコマンドを実行し、プロンプトで幾つかの質問に答えていきます。

certbot --server https://acme-v02.api.letsencrypt.org/directory -d "tfegcp.<MYDOMAIN>" --manual --preferred-challenges dns-01 certonly --work-dir ./wd --config-dir ./cfg --logs-dir ./logs

最後に以下の様にアクションを求められますので、利用しているDNSサーバーのレコードにこれらの情報を登録します。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name:

_acme-challenge.tfegcp.<MYDOMAIN>

with the following value:

xxxx

<...SNIP...>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue

レコードを登録したあと、別のターミナルで以下の様にnslookupコマンド等で、レコードのTXTデータとして入力した値(上記のwith the following value:の後にレスポンスされた値)がレスポンスされれば準備完了ですので、元のターミナルに戻ってEnterキーを押します。

nslookup -q=txt _acme-challenge.tfegcp.<MYDOMAIN>

Successfully received certificate.とメッセージが出力されると思いますので、certbotコマンドを実行したディレクトリから、cfg/live/tfegcp.<MYDOMAIN>ディレクトリに移動し、このディレクトリに証明書が作成されている事を確認します。

privkey.pem と fullchain.pem のみ利用します
$ ls
cert.pem      chain.pem     fullchain.pem privkey.pem

以下のドキュメントにも記載がありますが、TFE FDOで利用する証明書のファイル名とLet's Encryptで生成された証明書の紐付けは以下の通りなので、cpコマンドを使って、TFE FDOで利用する証明書のファイル名でファイルを準備しておきます。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/install/docker/requirements#tls-certificate

TFE FDOで利用する証明書 Let's Encrypt
key.pem privkey.pem
cert.pem fullchain.pem
bundle.pem fullchain.pem

準備が出来たので、TFE FDOのインストールに入っていきます。

Installation

Service management

インストールドキュメントの順番と前後しますが、ドキュメントにあるsystemd用の設定ファイルとこの後利用するディレクトリを作成しておきます。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/install/docker/install#service-management

ドキュメント上はdockerコマンドのパスは/usr/local/bin/dockerとなっていますが、上記のインストール手順を行った自分の環境では/usr/bin/dockerとなっていたので、下記の様に修正しています。

sudo mkdir -p /etc/terraform-enterprise/certs
sudo mkdir -p /opt/terrform-enterprise
sudo cat <<EOF | sudo tee /etc/systemd/system/terraform-enterprise.service
[Unit]
Description=Terraform Enterprise Service
Requires=docker.service
After=docker.service network.target

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/etc/terraform-enterprise
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target
EOF

Set up

Let's Encryptで作成し、ファイル名を変更しておいた証明書を/etc/terraform-enterprise/certs配下にコピーします。

続いて、compose.yamlファイルを/etc/terraform-enterprise/配下に作成します。Mounted Diskモードの場合のcompose.yamlファイルのサンプルがドキュメントにあるので、そちらも参考にします。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/install/docker/install#mounted-disk

自分の環境では以下の様に作成しています。TFE_LICENSETFE_HOSTNAMETFE_ENCRYPTION_PASSWORDに関しては、環境に合わせて変更して下さい。

compose.yaml
---
name: terraform-enterprise
services:
  tfe:
    image: images.releases.hashicorp.com/hashicorp/terraform-enterprise:v202401-1
    environment:
      TFE_LICENSE: "<TFE_LICENSE>"
      TFE_HOSTNAME: "tfegcp.<MYDOMAIN>"
      TFE_ENCRYPTION_PASSWORD: "<ADMIN_PASSWORD>"
      TFE_OPERATIONAL_MODE: "disk"
      TFE_DISK_CACHE_VOLUME_NAME: "${COMPOSE_PROJECT_NAME}_terraform-enterprise-cache"
      TFE_TLS_CERT_FILE: "/etc/ssl/private/terraform-enterprise/cert.pem"
      TFE_TLS_KEY_FILE: "/etc/ssl/private/terraform-enterprise/key.pem"
      TFE_TLS_CA_BUNDLE_FILE: "/etc/ssl/private/terraform-enterprise/bundle.pem"
    cap_add:
      - IPC_LOCK
    read_only: true
    tmpfs:
      - /tmp:mode=01777
      - /run
      - /var/log/terraform-enterprise
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - type: bind
        source: /var/run/docker.sock
        target: /run/docker.sock
      - type: bind
        source: ./certs
        target: /etc/ssl/private/terraform-enterprise
      - type: bind
        source: /opt/terrform-enterprise
        target: /var/lib/terraform-enterprise
      - type: volume
        source: terraform-enterprise-cache
        target: /var/cache/tfe-task-worker/terraform
volumes:
  terraform-enterprise-cache:

上記以外にも、TFE FDOの環境変数として使えるパラメータは以下のドキュメントから確認出来ますので、必要に応じてご利用下さい。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/install/configuration

Download and install

TFE FDOコンテナイメージを取得します。レジストリにログインする際にパスワードを求められますので、パスワードとしてTFE FDOライセンスファイルの内容を入力し、ログインします。

$ docker login --username terraform images.releases.hashicorp.com
Password:
WARNING! Your password will be stored unencrypted in /home/ubuntu/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

無事ログイン出来たら、レジストリからTFE FDOコンテナイメージを取得します。イメージのTagにあたるv202401-1に関しては、必要に応じて変更して下さい。

docker pull images.releases.hashicorp.com/hashicorp/terraform-enterprise:v202401-1

Run

TFE FDOを起動させる準備が出来ましたので、TFE FDOをMounted Diskモードで起動させます。

sudo systemctl enable terraform-enterprise
sudo systemctl start terraform-enterprise

上手く起動していない場合は、journalctl -xeu terraform-enterpriseコマンド等でログを確認し、トラブルシュートを行います。
また、ディレクトリ/etc/terraform-enterpriseに移動して、以下のコマンドを実行する事でTFE FDOコンテナ内のサービスのステータスを確認する事ができます。

docker compose exec tfe /bin/bash
$ supervisorctl status
fluent-bit                       RUNNING   pid 113, uptime 0:01:00
postgres                         RUNNING   pid 66, uptime 0:01:02
redis                            RUNNING   pid 49, uptime 0:01:04
terraform-enterprise             RUNNING   pid 30, uptime 0:01:04
tfe:archivist                    RUNNING   pid 131, uptime 0:00:58
tfe:atlas                        RUNNING   pid 132, uptime 0:00:58
tfe:atlas-ui                     RUNNING   pid 133, uptime 0:00:58
tfe:backup-restore               RUNNING   pid 135, uptime 0:00:58
tfe:licensing                    RUNNING   pid 138, uptime 0:00:58
tfe:metrics                      RUNNING   pid 144, uptime 0:00:58
tfe:nginx                        RUNNING   pid 148, uptime 0:00:58
tfe:outbound-http-proxy          RUNNING   pid 150, uptime 0:00:58
tfe:sidekiq                      RUNNING   pid 158, uptime 0:00:58
tfe:slug-ingress                 RUNNING   pid 170, uptime 0:00:58
tfe:task-worker                  RUNNING   pid 180, uptime 0:00:58
tfe:terraform-registry-api       RUNNING   pid 189, uptime 0:00:58
tfe:terraform-registry-worker    RUNNING   pid 202, uptime 0:00:58
tfe:terraform-state-parser       RUNNING   pid 213, uptime 0:00:58
tfe:tfe-health-check             RUNNING   pid 222, uptime 0:00:58
tfe:vault                        RUNNING   pid 229, uptime 0:00:57

Create initial admin user

TFE FDOインストールの最後のステップを実行していきます。ドキュメントに記載がある通り、initial admin creation token(IACT)を取得します。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/install/initial-admin-user

IACTを取得するために、TFE FDOコンテナの名前を確認します。この環境では、terraform-enterprise-tfe-1となっています。

$ docker ps
CONTAINER ID   IMAGE                                                                    COMMAND                  CREATED         STATUS         PORTS                                                                      NAMES
d682050b6bfe   images.releases.hashicorp.com/hashicorp/terraform-enterprise:v202401-1   "/usr/local/bin/supe…"   2 minutes ago   Up 2 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp   terraform-enterprise-tfe-1

次のコマンドを実行して、無事成功するとIACTがレスポンスされます。

docker exec terraform-enterprise-tfe-1 tfectl admin token

IACTを取得したら、TFE FDOにアクセス出来る環境のブラウザでhttps://${TFE_HOSTNAME}/admin/account/new?token=<IACT_TOKEN>にアクセスします。
アクセスするとTFEユーザーを作成する様に促されるので、必要な情報を入力し、TFEユーザーを作成します。

TFEユーザーの作成

続いて、TFEのOrganizationの作成を促されますので、Organizationを作成し、TFE FDOのインストールとしては完了です。

Terraform Run

TFE FDOもインストールが完了してしまえば、Terraform Cloudと同様にお使い頂く事が可能です。Agent設定をしていない状況で、ワークスペースのExecモードをRemote-Execとしている場合、Terraform Runを実行すると、以下のようにterraform planterraform apply毎にtfc-agentコンテナが実行されます。

terraform plan/apply 毎に tfc-agent コンテナが実行される
$ docker ps
CONTAINER ID   IMAGE                                                                    COMMAND                  CREATED         STATUS         PORTS                                                                      NAMES
28a8343dbaba   hashicorp/tfe-agent:now                                                  "/home/tfc-agent/bin…"   9 seconds ago   Up 7 seconds                                                                              tfe-agent-e4903400-a955-4a58-84a5-4ed3ac6d8ec9
d682050b6bfe   images.releases.hashicorp.com/hashicorp/terraform-enterprise:v202401-1   "/usr/local/bin/supe…"   22 hours ago    Up 22 hours    0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp   terraform-enterprise-tfe-1

また、TFE FDOでもCustom Worker ImageAgentが利用可能ですので、必要に応じてお使い下さい。

Dynamic Credentials with the GCP Provider with TFE

上記環境のTFE FDO環境を利用し、Dynamic Credentialsを問題なく利用する事が出来ています。別の記事で記載させて頂いた以下の内容ほぼそのままで設定可能です。
https://zenn.dev/i10chu/articles/393a517eeb6dce

注意点としては、以下2点になります。ご利用の際は以下の点に注意して頂き、設定して頂ければと思います。

  1. Terraform変数は環境に合わせて修正して下さい。以下の変数あたりが対象になります。
variable "tfc_hostname" {
  type        = string
  default     = "app.terraform.io"
  description = "The hostname of the TFC or TFE instance"
}

variable "tfc_organization_name" {
  type        = string
  description = "The name of your TFC / TFE organization"
}

variable "tfc_project_name" {
  type        = string
  default     = "Default Project"
  description = "The project under which a workspace will be created"
}
  1. tfeプロバイダでhostnameを指定するようにして下さい。Terraform Cloudの場合は、指定する必要ないのですが、TFEを対象としてtfeプロバイダを利用する際には指定が必要になります。
provider "tfe" {
  hostname = var.tfc_hostname
}

References

Discussion