閉域網で利用するためのTerraform Enterprise構築について

記事タイトルとURLをコピーする

当記事は みずほリサーチ&テクノロジーズ × G-gen エンジニアコラボレーション企画 で執筆されたものです。


みずほリサーチ&テクノロジーズ株式会社の浅香です。
今回は Google Cloud 上に Terraform Enterprise を実際に構築する機会を頂いたので、その構築内容/手順をご紹介させていただきます。

当ブログは G-gen × みずほRT によるコラボ記事です

はじめに

Terraform Enterprise (TFE)は、インフラストラクチャのプロビジョニングと管理を自動化するための強力なツールです。 TFEを使用することで、チーム全体でのインフラストラクチャの共有、セキュリティの向上、作業の追跡と可視化を容易に行うことができます。

また、金融システムなど高いセキュリティを求められる場合、拠点とパブリッククラウドを専用線で結びインターネット接続を制限するケースがあると思います。 今回、構築環境として利用した Google Cloud もそのような閉域環境としています。

この記事では、閉域にした Google Cloud 上にて利用する TFE の構築手順と設定について詳しく解説します。

構築環境

今回は Google Cloud の Compute Engine (以下、GCE) 上に構築することにします。

TFE環境

当該環境は閉域網であり、インタネット経由での各種アクセスはできないものとします。
(インターネット経由で取得する必要があるものは、別環境で取得して持ち込んでいるものとします。)

前提

この記事では以下の前提や制約条件があるものとします。

airgap モジュールと TFE ライセンスファイルの調達

TFE の利用に際して必要となる airgap モジュールとライセンスファイルが必要になります。 必要な際はこちら より HashiCorp 社へお問い合わせ下さい。 なお、installer bootstrapper はこちら からダウンロード可能です。

Google Cloud での構築

  • Terraform Enterprise GCP Reference Architecture では、可用性などを高めるために Cloud SQLCloud Storage の利用を推奨されていますが、今回は便宜的に GCE インスタンスのみで構築することにします。
  • インスタンスサイズやタイプについては、同ページに記載されている Infrastructure Requirements に準拠するものとします。
  • 今回利用する OS は Supported Operating Systems にもある RHEL8 とします。
  • 構築にあたって必要となる Docker Engine は事前にインストールしているものとします。
  • SMTP の設定は割愛します。(メール発信はできません。)

ドメインと DNS 名

今回はカスタムドメイン (xxx.internal) を利用し、tfe.xxx.internal| を使用します。

インストール方法

インストール方法としては大きく分けて Interactive InstallAutomated Install の 2 種類がありますが、今回は後者の Automated Install にてインストールします。
なお、前者の Interactive Install は、こちらはブログ「Deploying Terraform Enterprise in Air Gapped Environments」が参考になります。

証明書

今回は自己証明書にて構築します。

構築手順

事前準備

  1. SSHを使用してインスタンスに接続可能
  2. 以下のディレクトリを用意

    用途 今回のディレクトリ
    TFE インストールに必要なモジュール配置先 /opt/tfe-module
    TFE 利用時に必要なデータ格納先 /opt/terraform-enterprise
  3. 自己署名証明書の発行

  4. 以下のファイルをサーバ内に格納

    用途 今回の格納先
    ライセンスファイル /opt/tfe-module/License.rli
    airgap モジュール /opt/tfe-module/tfe.airgap
    installer bootstrapper /opt/tfe-module/latest.tar.gz
    サーバ秘密鍵 /opt/tfe-module/server.crt
    自己署名証明書 /opt/tfe-module/server.key

構築作業

1. Root ユーザーにスイッチする

sudo su -

2. Docker を起動し、サービスとして登録する (状態確認)

systemctl enable --now docker
sudo systemctl status docker

3. TFE の設定ファイル (json) を作成する

cat <<EOF > /opt/tfe-module/settings.json
{
  "hostname": {
      "value": "tfe.xxx.internal"
  },
  "capacity_concurrency": {
      "value": "10"
  },
  "capacity_cpus": {
      "value": "0"
  },
  "capacity_memory": {
      "value": "512"
  },
  "enc_password": {
      "value": "<暗号化パスワード>"
  },
  "log_forwarding_enabled": {
      "value": "1"
  },
  "log_forwarding_config": {
      "value": "[OUTPUT]\n    Name                syslog\n    Match               *\n    Host                localhost\n    Port                5140\n    syslog_message_key  message\n    syslog_severity_key PRIORITY\n    syslog_hostname_key _HOSTNAME\n    syslog_appname_key  SYSLOG_IDENTIFIER\n    syslog_procid_key   _PID"
  },
  "production_type": {
      "value": "disk"
  },
  "disk_path": {
      "value": "/opt/terraform-enterprise"
  }
}
EOF

設定可能な項目は こちら をご参照ください。 なお、今回は以下の通りとしています。

設定項目 設定値
hostname.value ドメイン名 tfe.xxx.internal
capacity_concurrency.value 同時実行数 10
capacity_cpus.value CPU コアの最大数 0(無制限)
capacity_memory.value メモリの最大量(メガバイト単位) 512
enc_password.value 内部管理型 Vault 用のパスワード <暗号化パスワード>
log_forwarding_enabled.value ログ転送を有効化 1(有効化)
log_forwarding_config.value ログ転送設定 後述
production_type.value ストレージ (blob以外) disk
disk_path.value ストレージ利用先のディレクトリ /opt/terraform-enterprise

ログ転送設定については、改行コードを \n に変換して設定する必要があるため上述の記載としていますが、改行すると以下の通りとなります。 今回はローカルホストの syslog を対象とした設定としていますが、その他の転送先については こちら をご参照ください。

[OUTPUT]
Name                syslog
Match               *
Host                localhost
Port                5140
syslog_message_key  message
syslog_severity_key PRIORITY
syslog_hostname_key _HOSTNAME
syslog_appname_key  SYSLOG_IDENTIFIER
syslog_procid_key   _PID

4. replicated の設定内容

cat <<EOF > /etc/replicated.conf
{
  "DaemonAuthenticationType":         "password",
  "DaemonAuthenticationPassword":     "<ログインパスワード>",
  "BypassPreflightChecks":            true,
  "TlsBootstrapType":                 "key-cert",
  "TlsBootstrapCert":                 "$(cat /opt/tfe-module/server.crt | sed -z 's/\n/\\n/g'| rev | cut -c 3- | rev)",
  "TlsBootstrapKey":                  "$(cat /opt/tfe-module/server.key | sed -z 's/\n/\\n/g'| rev | cut -c 3- | rev)",
  "ImportSettingsFrom":               "/opt/tfe-module/settings.json",
  "LicenseFileLocation":              "/opt/tfe-module/License.rli",
  "LicenseBootstrapAirgapPackagePath":"/opt/tfe-module/tfe.airgap"
}

設定可能な項目は こちら をご参照ください。なお、今回は以下の通りとしています。

設定項目 設定値
DaemonAuthenticationType 認証方式 password
DaemonAuthenticationPassword ログインパスワード <ログインパスワード>
BypassPreflightChecks プリフライトチェックなし起動 true
TlsBootstrapType TLS 証明書の種類 key-cert
TlsBootstrapCert サーバ秘密鍵 $(cat /opt/tfe-module/server.crt | sed -z 's/\n/\\n/g'| rev | cut -c 3- | rev)
TlsBootstrapKey 自己署名証明書 $(cat /opt/tfe-module/server.key | sed -z 's/\n/\\n/g'| rev | cut -c 3- | rev)
ImportSettingsFrom 設定ファイルパス /opt/tfe-module/settings.json
LicenseFileLocation ライセンスファイルパス /opt/tfe-module/License.rli
LicenseBootstrapAirgapPackagePath パッケージファイルパス /opt/tfe-module/tfe.airgap

サーバ秘密鍵と自己署名証明書については、ログ転送設定と同様に、改行コードを \n に変換して設定する必要があります。 今回は上述のコマンドにて実施しています。

5. カレントディレクトリの移動 & installer bootstrapper の解凍

cd /opt/tfe-module && tar xzf /opt/tfe-module/latest.tar.gz --remove-files

6. インストール実行

./install.sh \
  airgap \
  no-proxy \
  private-address=$PRIVATE_IP

7. 起動チェック

while ! curl -ksfS --connect-timeout 5 https://tfe.xxx.internal/_health_check; do
    sleep 5
done

インストールが終了したら、/_health_check エンドポイントが 200 を返します。 これによりアプリケーションが完全に起動したことを確認できます。

設定作業

初期管理ユーザの作成

構築作業が完了したら、TFE 利用に向けて各種設定を実施していきます。

最初に、製品の使用を開始するために初期管理ユーザを作成する必要があります。 いくつか方法がありますが、今回もコマンドにて実施していきます。

1. IACT(Initial Admin Creation Token) の発行 (shell)

initial_token=$(replicated admin --tty=0 retrieve-iact | tr -d '\r')

2. Admin User の作成 (API)

cat <<EOF >payload.json
{
  "username": "tfe-admin-user",
  "email": "<メールアドレス>",
  "password": "<ユーザーパスワード>"
}
EOF
curl \
  --header "Content-Type: application/json" \
  --request POST \
  --data @payload.json \
  https://tfe.xxx.internal/admin/initial-admin-user?token=$initial_token

Response

{
  "status": "created",
  "token": "aabbccdd.v1.atlas.ddeeffgghhiijjkkllmmnnooppqqrrssttuuvvxxyyzz"
}

Organization (組織) の作成

次に、Terraform Enterprise 上の Organization (組織) を作成します。設定に際しては、上述の Admin User 作成手順の Reeponse の token を使用します。 今回は 1 組織のみとしていますが、複数組織を作成する場合は、必要な個所を修正したうえで以下の手順を繰り返してください。

1. 組織の作成 (API)

cat <<EOF >payload.json
{
  "data": {
    "type": "organizations",
    "attributes": {
      "name": "test-org",
      "email": "sample.adrdess@xxx.com"
    }
  }
}
EOF
curl \
  --header "Authorization: Bearer $TOKEN" \
  --header "Content-Type: application/vnd.api+json" \
  --request POST \
  --data @payload.json \
  http://tfe.xxx.internal/api/v2/organizations

Bundle ファイルを作成

ここまでで組織の作成まで終わりましたが、TFE で利用可能な Terraform の Bundle ファイルが初期設定では https://releases.hashicorp.com/terraform/<version>/terraform_<version>_linux_amd64.zip" 等になっているため、閉域網で実行するとクライアント側 (terraform planterraform apply を実行する側) でエラーになってしまいます。

そこで、Terrafom-bundle と API を使用して、閉域網内で実行可能なように設定していきます。

まずは Bundle ファイルを作成します。 ただし、Bundle ファイルの作成にあたってはインターネット接続環境が必要になります。今回は Cloud Shell で実施します。

1. Cloud Shell の起動

2. Github リポジトリのクローン

git clone --single-branch --branch=v0.15 --depth=1 https://github.com/hashicorp/terraform.git

3. カレントディレクトリの移動

cd terraform

4. Go 言語でビルド

go build -o ../terraform-bundle ./tools/terraform-bundle

5. 確認

~/terraform-bundle -help

6. Bundle 用の HCL ファイルを作成

cat <<EOF>~/tfe_bundle.tf
terraform {
  version = "<作成したいTerrafomのバージョン>"
}
providers {
    <Provider 名> = {
      source  = "<ソース>"
      versions  = [<バージョン>]
    }
    google = {
      source = "hashicorp/google"
      versions  = ["~> 4"]
    }
}
EOF

7. Bundle ファイルの作成

~/terraform-bundle package -os=linux -arch=amd64 ~/tfe_bundle.tf

Response

~省略~
Creating terraform_<指定したTerrafomのバージョン>-bundle<YYYYMMDDHH>_linux_amd64.zip ...
All done!

Bundle ファイルの登録

これで Bundle ファイルは完成したので、これを閉域環境に持ち込みます。 最後に Admin Terraform Versions API を利用して、作成した組織に登録していきます。

1. Bundle ファイルの配置

Bundle ファイルを、TFE が認証なくアクセス可能な WEB サーバ上に配置します。

2. URL および checksum 結果の取得

以降の手順で使用するため、Bundle を取得可能な URL と、Bundle の SHA-256 checksum 結果 (sha256sum <Bundle-PATH>|awk '{print $1}') を取得します。

3. Bundle ファイルの登録 (新規登録)

cat <<EOF>payload.json
{
  "data": {
    "type": "terraform-versions",
    "attributes": {
      "version": "指定したTerrafomのバージョン",
      "url": "Bundleファイルの配置先URL",
      "sha": "BundleファイルのSHA-256 checksum結果",
      "official": true,
      "enabled": true,
      "beta": false
    }
  }
}
EOF
curl \
  --header "Authorization: Bearer $TOKEN" \
  --header "Content-Type: application/vnd.api+json" \
  --request POST\
  --data @payload.json \
  http://tfe.xxx.internal/api/v2/admin/terraform-versions

これにより Terrafom 実行時の Provider が作成した Bundle ファイルを使用するようになるため、実行可能になります。

終わりに

この記事では、Terraform Enterprise の構築手順と設定について説明しました。
TFE を使用することで、インフラストラクチャの自動化と可視化、チーム作業の効率化とセキュリティの向上など様々な効果が期待されます。 閉域網でも活用することが可能なことが分かったので、今回紹介した設定以外の見直しも含め、今後も積極的に活用していければと思います。

最後までご覧いただきありがとうございました。本記事がどなたかの一助となれれば幸いです。

浅香 樹

みずほリサーチ&テクノロジーズ

先端技術研究部に所属。2019年から、CCoEとしてAWSの社内利活用の推進に従事。 Google Cloudは2022年より利用開始し、それを機にTerraformにも取り組んでいます。