🥢

Terraform Enterprise を Flexible Deployment Options に移行する

2023/12/14に公開

Terraform Enteprise を Replicated 版から、Flexible Deployment Options(以下 FDO) へ移行を行った際の手順です。
移行手順はドキュメントにある以下の手順に従って実施しています。
https://developer.hashicorp.com/terraform/enterprise/replicated/replicated-migration

Notes: 実際に利用されている環境で実施される場合は、テスト環境等で確認の上移行する事をオススメ致します。

What's Terraform Enterprise

Terraform Enterprise(以下 TFE) は、エンタープライズ用途で Terraform を利用される際に必要となる機能をビルドインし、Terraform を扱う上でのベストプラクティス、一番良いやり方をすべてご用意させて頂いているセルフマネージド版の有償プロダクトになります。
また、TFE は SaaS 版として提供している Terraform Cloud の Plus Edition と同等の機能を持っています。
https://www.hashicorp.com/products/terraform

Terraform Cloud の Plus Edition と同様、TFE をお使い頂くと以下の様な機能を Out-of-the-Box で直ぐにご利用頂く事が出来ます。

Flexible Deployment Options

TFE の FDO ですが、以下のブログにある通り2023年9月にリリースされた TFE の新しいデプロイメントオプションになります。

従来の TFE のデプロイメント方法だと、TFE とは別に TFE を管理するためのコンポーネントとして Replicated が必要だったのですが、FDO では terraform-enterprise コンテナイメージだけで動く様になり、シンプルなデプロイメント構成になっています。
https://www.hashicorp.com/blog/terraform-enterprise-adds-new-flexible-deployment-options

従来の Replicated を利用した TFE 環境から、FDO への移行手順が用意されていますので、今回はそれをラボの環境で試してみた手順を記載していきます。

Migration steps

前述の通り、ドキュメントに記載のある移行手順に則って実施して行きますが、ラボ環境では、TFE を構成するコンポーネントを全て同じ仮想マシンインスタンス上で稼働させているコロケーション構成(Mounted disk operational mode)を取っていますので、その前提で FDO への移行を実施しています。

移行手順のドキュメント内の Mounted disk to Docker という章を参照しながら手順を進めて行きます。
https://developer.hashicorp.com/terraform/enterprise/replicated/replicated-migration#mounted-disk-to-docker

Step 1: Back up data tier

まずはバックアップを取得しておきます。

環境に応じた推奨バックアップ取得方法がドキュメントに記載がありますが、ここでは Replicated 構成情報のみ取得しています。
https://developer.hashicorp.com/terraform/tutorials/recommended-patterns/pattern-backups#backup-a-mounted-disk-deployment

replicatedctl app-config export > replicated-app-config.backup.json

既存の TFE の構成情報が取得できますが、この後 FDO への移行で利用する値としては、disk_path.value, enc_password.value, hostname.value です。

Step 2: Upgrade TFE to FDO compatible section

FDO へ移行する際、既存の Replicated ベースの TFE バージョンは v202309-1 以上である必要があります。既存の TFE バージョンを確認し、バージョンアップが必要であれば、実施します。
https://developer.hashicorp.com/terraform/enterprise/releases/2023

既存の TFE のバージョンを確認します。

# replicatedctl app inspect
[
    {
        "ID": "xxxxx",
        "Name": "Terraform Enterprise",
        "Sequence": 745,
        "PatchSequence": 0,
        "LicenseType": "Free",
        "Airgap": false
    }
]

Sequence の値から TFE のバージョンを確認する事が出来ます。ラボ環境では 745 となっているため、この環境の TFE バージョンは、v202312-1 になります。
https://developer.hashicorp.com/terraform/enterprise/releases/2023/v202312-1

TFE のステータスを確認し、正常である事を確認します。

# replicatedctl app status
[
    {
        "AppID": "xxxxx",
        "Sequence": 745,
        "PatchSequence": 0,
        "State": "started",
        "DesiredState": "started",
        "Error": "",
        "IsCancellable": false,
        "IsTransitioning": false,
        "LastModifiedAt": "2023-12-13T00:00:28.875383501Z"
    }
]

また、ドキュメントに記載がある通り、TFE の Docker コンテナがちゃんと稼働している事を確認します。

# docker ps
CONTAINER ID   IMAGE                                                             COMMAND                  CREATED         STATUS         PORTS                                                                                                                                                                                NAMES
747a5cb45ffb   registry.replicated.com/library/retraced:1.3.56                   "/src/replicated-aud…"   2 minutes ago   Up 2 minutes   3000/tcp                                                                                                                                                                             retraced-processor
373dbc5c996d   registry.replicated.com/library/retraced:1.3.56                   "/src/replicated-aud…"   2 minutes ago   Up 2 minutes   0.0.0.0:9873->3000/tcp, :::9873->3000/tcp                                                                                                                                            retraced-api
0bf85e3d3380   registry.replicated.com/library/retraced:1.3.56                   "/bin/sh -c '/usr/lo…"   2 minutes ago   Up 2 minutes   3000/tcp                                                                                                                                                                             retraced-cron
12e1e229cfe8   registry.replicated.com/library/retraced-postgres:1.3.56          "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes   5432/tcp                                                                                                                                                                             retraced-postgres
19959bf6eccc   registry.replicated.com/library/retraced-nsq:1.3.56               "/bin/sh -c nsqd"        2 minutes ago   Up 2 minutes   4150-4151/tcp, 4160-4161/tcp, 4170-4171/tcp                                                                                                                                          retraced-nsqd
fde33290ab9b   registry.replicated.com/library/statsd-graphite:1.1.10-20230912   "/usr/bin/supervisor…"   2 minutes ago   Up 2 minutes   0.0.0.0:32788->2003/tcp, :::32788->2003/tcp, 0.0.0.0:32787->2004/tcp, :::32787->2004/tcp, 0.0.0.0:32786->2443/tcp, :::32786->2443/tcp, 0.0.0.0:32774->8125/udp, :::32774->8125/udp   replicated-statsd
2a2667c97383   registry.replicated.com/library/premkit:v1.4.8                    "/usr/bin/premkit da…"   2 minutes ago   Up 2 minutes   80/tcp, 443/tcp, 2080/tcp, 0.0.0.0:9880->2443/tcp, :::9880->2443/tcp                                                                                                                 replicated-premkit
c47e1efb0084   replicated/replicated:current                                     "/usr/bin/entrypoint…"   2 minutes ago   Up 2 minutes   0.0.0.0:9874-9879->9874-9879/tcp, :::9874-9879->9874-9879/tcp                                                                                                                        replicated
9847507b3bbb   replicated/replicated-ui:current                                  "/usr/bin/replicated…"   2 minutes ago   Up 2 minutes   0.0.0.0:8800->8800/tcp, :::8800->8800/tcp                                                                                                                                            replicated-ui
df8bee41a46e   replicated/replicated-operator:current                            "/usr/bin/replicated…"   2 minutes ago   Up 2 minutes                                                                                                                                                                                        replicated-operator
aad7b335b8d5   xxx.xxx.xx.xxx:9874/hashicorp-tfe-admin:d196e7c                   "/start-tfe-admin.sh"    12 hours ago    Up 12 hours                                                                                                                                                                                         tfe-admin
e0e9c4332a05   xxx.xxx.xx.xxx:9874/hashicorp-terraform-enterprise:dc2331d        "/usr/local/bin/supe…"   12 hours ago    Up 12 hours    0.0.0.0:80->8080/tcp, 0.0.0.0:443->8443/tcp                                                                                                                                          terraform-enterprise
fdfe2e0839df   xxx.xxx.xx.xxx:9874/hashicorp-ptfe-base:e9524f7                   "/gosu-bin/gosu nobo…"   12 hours ago    Up 12 hours                                                                                                                                                                                         tfe-anchor-isolation-network

tfe-admin コマンドを使ってヘルスチェックを実施し、ヘルスチェックも問題ない事を確認します。

# tfe-admin health-check
checking: Archivist Health Check...
|  checks that Archivist is up and healthy
|- ✓ PASS

checking: Terraform Enterprise Health Check...
|  checks that Terraform Enterprise is up and can communicate with Redis and Postgres
|- ✓ PASS

checking: Terraform Enterprise Vault Health Check...
|  checks that Terraform Enterprise can connect to Vault and is able to encrypt and decrypt tokens
|- ✓ PASS

checking: Fluent Bit Health Check...
|  checks that the configure Fluent Bit server is healthy
|- ✓ PASS

checking: Vault Server Health Check...
|  checks that the configured Vault Server is healthy
|- ✓ PASS

  All checks passed.

Step 3: Verify Docker Engine version

Docker Engine のインストール要件があるため、既存の TFE 環境がそれを満たしているか確認しておきます。
https://developer.hashicorp.com/terraform/enterprise/replicated/requirements/docker_engine

# docker compose version
Docker Compose version v2.17.2
# containerd --version
containerd containerd.io 1.6.20 2806fc1057397dbaeefbea0e4e17bddfbd388f38
# runc --version
runc version 1.1.5
commit: v1.1.5-0-gf19387a
spec: 1.0.2-dev
go: go1.19.7
libseccomp: 2.5.3

Step 4: Prepare the host and install your new Terraform Enterprise

新たにディレクトリ /etc/terraform-enterprise を作成し、その配下に certs ディレクトリと docker-compose.yml ファイルを作成します。

mkdir /etc/terraform-enterprise
mkdir /etc/terraform-enterprise/certs
touch /etc/terraform-enterprise/docker-compose.yml

ラボ環境の docker-compose.yml ファイルは以下のサンプルをベースに作成しています。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/install/docker/install#mounted-disk

最終的に、docker-compose.yml ファイルは以下の様に定義しています。また、以下の値については、Step 1: Back up data tier で確認した値を元に定義しています。

  • services.tfe.environment.TFE_HOSTNAME -> hostname.value
  • services.tfe.environment.TFE_ENCRYPTION_PASSWORD -> enc_password.value
  • services.tfe.volumestarget: /var/lib/terraform-enterprisesource -> disk_path.value
docker-compose.yml
---
name: terraform-enterprise
services:
  tfe:
    image: images.releases.hashicorp.com/hashicorp/terraform-enterprise:v202312-1
    environment:
      TFE_LICENSE: "<TFE FDO_HASHICORP_LICENSE>"
      TFE_LICENSE_REPORTING_OPT_OUT: true
      TFE_HOSTNAME: "tfe.<LAB_DOMAIN>"
      TFE_ENCRYPTION_PASSWORD: "<ENC_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"
      TFE_IACT_SUBNETS: "xxx.xxx.xx.0/24"
    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/tfe
        target: /var/lib/terraform-enterprise
      - type: volume
        source: terraform-enterprise-cache
        target: /var/cache/tfe-task-worker/terraform
volumes:
  terraform-enterprise-cache:

他の利用可能なオプション設定に関しては、以下をご参照下さい。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/install/configuration

続いて、既存の TFE で利用していた証明書を /etc/terraform-enterprise/certs にコピーします。既存の TFE 環境で利用していた証明書は、Self-signed 証明書を利用しているため、TFE Admin コンソールの Management console settings の TLS Key & Cert で確認しました。

Management console settings の TLS Key & Cert セクションにて、SSL Private Key Filename, SSL Certificate Filename で指定されているファイルを、それぞれ /etc/terraform-enterprise/certs/key.pem, /etc/terraform-enterprise/certs/cert.pem としてコピーしています。

また、ラボ環境では同じディレクトリに存在していた CA 証明書を、/etc/terraform-enterprise/certs/bundle.pem としてコピーしました。

次に、terraform-enterprise コンテナイメージを docker pull します。terraform.hclic は TFE FDO を利用するためのライセンスファイルになります。

cat terraform.hclic | docker login --username terraform images.releases.hashicorp.com --password-stdin
docker pull images.releases.hashicorp.com/hashicorp/terraform-enterprise:v202312-1

続いて、ドキュメントを参考に FDO 用の新しい systemd サービスを作成します。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/install/docker/install#service-management

docker コマンドのパスがラボ環境だと上記ドキュメントのサンプルと異なっていたため、ExecStartExecStop は以下の様に修正しています。

/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

Step 5: Stop Replicated and migrate

FDO へ移行する準備が出来たので、既存 TFE の Replicated を停止していきます。

# replicatedctl app stop
App is stopping
# replicatedctl app status
[
    {
        "AppID": "xxxxx",
        "Sequence": 745,
        "PatchSequence": 0,
        "State": "started",
        "DesiredState": "stopped",
        "Error": "",
        "IsCancellable": true,
        "IsTransitioning": true,
        "LastModifiedAt": "2023-12-13T00:35:15.523202373Z"
    }
]

データをバックアップしておきます。ラボ環境の既存の TFE のデータパスは、/opt/tfe になるため、それをターゲットにバックアップを取得します。

# replicatedctl app-config export --template '{{ .disk_path.Value }}' | tr -d '\r'
/opt/tfe
tar -zcvf data.tar.gz -C /opt/tfe aux postgres

事前準備が完了したので、FDO で TFE を起動します。

systemctl enable --now terraform-enterprise

terraform-enterprise サービスのステータスを確認します。

Notes: 下記においては、terraform-enterprise サービスは正常に起動している状況ですが、問題がある場合は、ログ等確認してトラブルシューティングを行って下さい。

# systemctl status terraform-enterprise
● terraform-enterprise.service - Terraform Enterprise Service
     Loaded: loaded (/etc/systemd/system/terraform-enterprise.service; enabled; vendor preset: enabled)
     Active: active (exited) since Wed 2023-12-13 00:55:35 UTC; 6s ago
    Process: 2016096 ExecStart=/usr/bin/docker compose up -d (code=exited, status=0/SUCCESS)
   Main PID: 2016096 (code=exited, status=0/SUCCESS)
        CPU: 109ms

Dec 13 00:55:34 tfe systemd[1]: Starting Terraform Enterprise Service...
Dec 13 00:55:34 tfe docker[2016117]:  Network terraform-enterprise_default  Creating
Dec 13 00:55:35 tfe docker[2016117]:  Network terraform-enterprise_default  Created
Dec 13 00:55:35 tfe docker[2016117]:  Container terraform-enterprise-tfe-1  Creating
Dec 13 00:55:35 tfe docker[2016117]:  Container terraform-enterprise-tfe-1  Created
Dec 13 00:55:35 tfe docker[2016117]:  Container terraform-enterprise-tfe-1  Starting
Dec 13 00:55:35 tfe docker[2016117]:  Container terraform-enterprise-tfe-1  Started
Dec 13 00:55:35 tfe systemd[1]: Finished Terraform Enterprise Service.

TFE FDO のヘルスチェック用のエンドポイントでもステータスを確認する事が出来ますので、必要に応じて多方面から確認しておきます。

# curl -k https://tfe.<LAB_DOMAIN>/_health_check
{"postgres":"UP","redis":"UP","vault":"UP"}
# curl -k https://tfe.<LAB_DOMAIN>/_health_check
OK

FDO で TFE が無事に立ち上がったので、既存の TFE デプロイメントで利用されていた Replicated サービスを停止して行きます。

systemctl disable --now replicated replicated-ui replicated-operator
docker stop replicated-statsd
docker rm -f replicated replicated-ui replicated-operator replicated-premkit replicated-statsd retraced-api retraced-processor retraced-cron retraced-nsqd retraced-postgres

ラボ環境において最終的に起動している Docker コンテナは以下の様な形になり、非常にスッキリした形になりました。

# docker ps
CONTAINER ID   IMAGE                                                                    COMMAND                  CREATED         STATUS         PORTS                                                                      NAMES
bf64e2df2a9e   images.releases.hashicorp.com/hashicorp/terraform-enterprise:v202312-1   "/usr/local/bin/supe…"   5 minutes ago   Up 5 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

Step 6: Validate migration success

ドキュメントに記載がある通り、FDO が正しく稼働しているか確認するための検証ステップがありますので、それを以て TFE FDO を使った Terraform ワークフローが問題なく実行されるか確認します。
https://developer.hashicorp.com/terraform/enterprise/replicated/replicated-migration#step-6-validate-migration-success

ラボ環境では、CLI-driven ワークフローのみ利用しているため、全てをテスト出来ているわけではありませんが、上記手順で FDO へ移行した後も問題なく、TFE 環境を用いて、Terraform ワークフローを実行する事が出来ています。

また、TFE を Replicated でインストールされている環境が Air-gapped 環境の場合、Terraform Bundle を作成し、作成した Terraform Bundle を TFE 環境から利用出来るようにしていると思います。
https://github.com/hashicorp/terraform/blob/v0.15/tools/terraform-bundle/README.md#installing-a-bundle-in-terraform-enterprise

FDO に移行後も TFE の Admin Settings -> Terraform Versions から Replicated 版の時と同じように Terraform Bundle を確認する事が出来ます。

Terraform Bundle の登録方法も Replicated 版 TFE と同じですので、FDO 移行前後で TFE が稼働している仮想マシンインスタンスに変更が無ければ、FDO 移行後も独自に登録されている Terraform Bundle は問題なく利用出来るはずです。

Summary

コロケーション構成(Mounted disk operational mode)の Replicated 版 TFE を、ドキュメントの手順に従って、問題なく FDO に移行する事が出来ました。
詳細は環境に応じて異なる部分があると思いますが、Mounted disk operational mode で Replicated 版 TFE をお使い頂いている環境にて、TFE を FDO へ移行される際の参考情報としてご活用下さい。

References

Discussion