EKSにTerraform Enterpriseをデプロイしてみる

2023.11.29

2023年9月にTerraform EnterpriseでFlexible Deployment Optionsが発表されました。

Terraform Enterprise adds new flexible deployment options

このアップデートにより、KubernetesやDocker Engine上にTerraform Enterpriseをデプロイできるようになりました。

今回はAWSマネージドのKubernetesサービスであるEKS上に、Terraform Enterpriseをデプロイしてみます。

Flexible Deployment Options

従来Terraform EnterpriseはReplicatedというサードパーティーツールとパッケージ化されて提供されていました。

VM(AWSだったらEC2) -> Docker -> Replicated -> Terraform Enterpriseといった構成を取る必要がありました。

Flexible Deployment Optionsを使うことで、Replicatedが不要になり、KubernetesやDockerに直接デプロイすることが可能になりました。

Flexible Deployment Options - Terraform Enterprise | Terraform | HashiCorp Developer

何が嬉しい?

  • デプロイオプションの選択肢が増えて、チームにナレッジがあるツールを選びやすくなった
  • ネイティブ管理ツール(Docker Compose,Helm)使ってインストール可能になり、インストール手順がより簡単になった

従来のReplicated Deploymentはどうなる?

Replicated Deploymentはレガシーとなり、最終リリースは2024年11月です。

最終リリースのサポートは2026年4月1日までサポートされます。

Legacy Deployment Overview (Replicated) - Terraform Enterprise | Terraform | HashiCorp Developer

Flexible Deployment Optionsへの移行手順はドキュメントが用意されています。

Migrating from Replicated - Installation - Flexible Deployment Options - Terraform Enterprise | Terraform | HashiCorp Developer

やってみた

以下のガイドに従ってデプロイしてみます。

Dependency Free Terraform Enterprise Quickstart Guide

前提

Terraform Enterpriseのライセンスが必要です。

バージョンは、Terraform Enterprise v202309-1以降を使用する必要があります。

環境情報

  • Kubernetesバージョン: 1.27(※)
  • Terraform Enterpriseバージョン: v202309-1

※現時点(2023/11/27時点)EKSで利用可能な最新のKubernetesのバージョンは1.28ですが、Terrraform Enterpriseテスト済みのバージョンは1.27までのため

Releases - Terraform Enterprise | Terraform | HashiCorp Developer

EKSクラスターを用意

eksctlを使って、EKS Clusterを用意します。

$ eksctl create cluster \
--name tfe-sample \
--region ap-northeast-1 \
--with-oidc \
--node-type m5.large \
--nodes 2 \
--version 1.27

Terraform EnterpriseはDBが必要です。今回はEKS上にPostgreSQLをインストールして使うため、データの永続化が必要です。

データの永続化にEBSを使うため、EBS CSIドライバーを導入します。

IAMロールとサービスアカウントを作って、EBS CSIドライバーをアドオンとして追加します。

$ eksctl create iamserviceaccount \
    --name ebs-csi-controller-sa \
    --namespace kube-system \
    --cluster tfe-sample \
    --role-name AmazonEKS_EBS_CSI_DriverRole \
    --role-only \
    --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
    --approve
$ eksctl create addon --name aws-ebs-csi-driver --cluster tfe-sample \
--service-account-role-arn arn:aws:iam::<AWSアカウントID>:role/AmazonEKS_EBS_CSI_DriverRole \
--force

Service作成

ここからはガイドに従って手順を実行します。

まずは、上記ガイドがあるリポジトリをローカルにクローンします。

$ git clone git@github.com:hashicorp/terraform-enterprise-helm.git

一部ファイルの作成が必要なため、リポジトリ内にディレクトリを作ります。

$ cd terraform-enterprise-helm
$ mkdir tmp

tmpディレクトリにservice用のファイルを用意します。

$ touch ./tmp/service.yaml

ファイルの内容は以下とします。

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: alpha
  namespace: beta
spec:
  type: LoadBalancer
  selector:
    app.kubernetes.io/name: gamma
  ports:
    - protocol: TCP
      port: 80

用意ができたらnamespaceを作成して、applyを行います。

$ kubectl create namespace beta
$ kubectl apply -f ./tmp/service.yaml

Namespaceとシークレット作成

terraform-enterprise用のnamespaceを作成します。

$ kubectl create namespace terraform-enterprise

terraform-enterpriseのDockerイメージをPullするには、認証情報が必要です。

EKSからPullできるようにDockcerの認証情報をsecretに登録します。

$ kubectl create secret docker-registry terraform-enterprise --docker-server=images.releases.hashicorp.com \
 --docker-username=terraform \
 --docker-password=<ライセンスファイルの中身>  \
 -n terraform-enterprise

データベース等をプロビジョニング

Terraform Enterpriseを動かす場合、以下のサービスが必要です。

Terraform Enterprise requires the following external services to install on Kubernetes:

  1. PostgreSQL
  2. Blob Storage (AWS S3, Azure Cloud Storage, Google Cloud Storage, or any S3-compatible storage service)
  3. Redis version 6 or 7 (Redis Cluster is not currently supported)

Kubernetes - Requirements - Flexible Deployment Options - Terraform Enterprise | Terraform | HashiCorp Developerから引用

AWSで動かす場合、それぞれ該当するマネージドサービスを使うことが多いですが、このガイドは検証用途のため、EKSクラスター内に該当サービスをインストールするhelmチャートを用意しています。

以下のコマンドを実行して、必要な外部サービスをEKSクラスターにインストールします。

$ helm dependency update ./docs/example/terraform-enterprise-prereqs
$ helm install prereqs ./docs/example/terraform-enterprise-prereqs  -n terraform-enterprise --wait

実行後各Podが起動していればOKです。

$ kubectl get pods -n terraform-enterprise
NAME                                   READY   STATUS    RESTARTS   AGE
prereqs-minio-0                        1/1     Running   0          17m
prereqs-minio-1                        1/1     Running   0          17m
prereqs-minio-2                        1/1     Running   0          17m
prereqs-postgresql-0                   1/1     Running   0          17m
prereqs-redis-master-0                 1/1     Running   0          17m
prereqs-redis-replicas-0               1/1     Running   0          17m
prereqs-redis-replicas-1               1/1     Running   0          16m
prereqs-redis-replicas-2               1/1     Running   0          16m

Terraform Enterpriseをプロビジョニング

helmチャートに設定値を与えるために、override.yamlを用意します。

$ cp docs/example/override.yaml ./tmp/
$ vi override.yaml

サンプルそのままですが、tagだけ修正します。

override.yaml

# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

# Note: These certificates are self-signed, development certificates using an
# untrusted locally provisioned CA certificate. There is no exposure risk.
tls:
  certData: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZ3akNDQTZxZ0F3SUJBZ0lRQlJqK0FzUnByTmxnWm5wZjc4ZXllREFOQmdrcWhraUc5dzBCQVFzRkFEQlEKTVRJd01BWURWUVFLRXlsSVlYTm9hV052Y25BZ1JHVjJWR1Z6ZENCSmJuTjBZVzVqWlNCRFFTQXRJRlZPVkZKVgpVMVJGUkRFYU1CZ0dBMVVFQXhNUlNHRnphR2xqYjNKd0lFUmxkbFJsYzNRd0hoY05Nak13TmpBM01UZ3hOVE00CldoY05NalF3TmpBMk1UZ3hOVE00V2pCZE1Uc3dPUVlEVlFRS0V6SklZWE5vYVdOdmNuQWdSR1YyVkdWemRDQnAKYm5OMFlXNWpaU0JoY0hCc2FXTmhkR2x2YmlCalpYSjBhV1pwWTJGMFpURWVNQndHQTFVRUF4TVZTR0Z6YUdsagpiM0p3SUVSbGRsUmxjM1FnUVhCd01JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQ0NnS0NBZ0VBCjQ5NVNJMkxsOVNEbGg4bUZEOTdmSk1ibTc1Q2J0WkNadFg3NDNWYkQvcUJIT3RlR3JVL3hEZjRHamM2S20rQWIKbzdyNHBTZGN6RitRM1loN1I3N0FOQmtOTjh6UWp1eU1xNE0vQlc3cVoxeUF1V1R6OENQRnI4b2dydTUrSjZpZgplVlVXcERsb0g2YjBJMDY5Rmdhamg0OS83ZC9YNWNJUWcwOWx4SGk4ekZHQjgzcTlaRi9mUlZOZlB5MTVHTnVxCld0VUI3c0hkYkwyTVB6RmRjaUl0QVJPOURUQ0I5anV1M2tyWUlGR2RoTUw5ZkhRUVJXTjhpVnh4K1F3dHFENmwKRndBZDQ2UVZiWnNaUThPdmdLbk1vZ1VlbzZ2YWw0VHE0ZzlrTHB4TC92NFp0R1dTNTRoVlZ2UDE1WUkybUQ2KwpDMzZ3dGlSMmdtaVFiakxEWnpYWTdPQ3crbmRISEtmUjIwMG4ySFdZcllHc3JmQURNNzNzSEVkYWdvVDRxS2N5CmI0T0pWcE5PanlOOG1YRWlaTi9kWmVVM3p3dFJGT2tYR1BUdURURHBUck13VlYrZ3dMaU1EbWdRNG9WNElkVkUKbVVKUGZvdFlXTFR4SUU0N1BXMlJza0t5SGJzYlprbXV6Z1JJWVVpMkdndlFtYUZmMWVGOVVPWW5lb1pETEhjaApseFkzR1dKT1ZUVW1zQ2R1dnpoeWJhZythMjlFbk8vdUs5WFliTVdWOWRJQTdKaXluQTNrQ0dlYldIYklZd2pSCmUrdG9pZ04vQ3dRR3kvcHk0aXlXM2lqdVk2bVEyN1FialdaZGZyYm9zeHlmVm1STElBZUR5SjdTS1poeldVLzcKV1VhSEl6ZDR6eEdUTzE5TUR5bWdMWFByYzdQREROaXg4TFFQNmU0eUwzOENBd0VBQWFPQmlqQ0JoekFPQmdOVgpIUThCQWY4RUJBTUNCYUF3REFZRFZSMFRBUUgvQkFJd0FEQWZCZ05WSFNNRUdEQVdnQlRNVEx4OFZhbGs5VU9XCndvUkxHaWV1TjIwRm5UQkdCZ05WSFJFRVB6QTlnanQwWlhKeVlXWnZjbTB0Wlc1MFpYSndjbWx6WlM1MFpYSnkKWVdadmNtMHRaVzUwWlhKd2NtbHpaUzV6ZG1NdVkyeDFjM1JsY2k1c2IyTmhiREFOQmdrcWhraUc5dzBCQVFzRgpBQU9DQWdFQVplZnQrUHFzaGVQV2JPQVhVVnY4dEhsVWlIaU8vZG1haGgzWFdnbFk3L3FpVGpvWEhXeGM0azZ2CkZUNG5SSitTU0hqYkZxaFNEbVRCRTBuUFZtOUNTZ2xodi9CWi81TDdnNzBuUzVtVnU5Rjd5cnBwcG1ZK0U5OTIKUEhDVFduMmZNeFBRUktVOFBNWjBvRnN1dk8wSnZVeHNrUU95emZRQlNWQ0NPVVdydkVsOUw5WDhWVGNyb0tTYgpZdHVDSCtZd0I5dVgrOHlNRDdKeVZ6WDkramQ4a3I0SVB4UUlHT2RKaW5wRzRHQTJFU0tpTVdkZ2RkNDEvbzFzCm9ibmQveVRJVER1OStRSndJeW1CUWVyZjZOaWNVK1p3Z0hoUnBBaHN3MVkrOE51WUQwZ1EvdjNDZFVYcjArRlAKdGhrNVJFRjVuSmc4Mmo4ZDRaRXpVdzdFZUFvUWRSUW1xS1ZJZVcyY0svZ1hrSExuSElDazhDcEw2RmhTRUh5NwowMFUyaGNBbkw4TFo1UUMxSGpham84MGdhOTdDK2Y3TzRET2p5R1ZIMFI5VHF0dEtkMWRmVFNFSU9oZnhRVm5UCnI2MmMxckwveGVXbGludUd5UkZ6dHZUQVJ4NEl4Rks3SENEbnFqeHNLcXpSemtqL25WVGlvcE9uQmZQVjYrVC8KNU9hSnVLaW91bG15RTFuNTRVbmgrbyt1MHJ0NEpjUEwxeVA1SnYxOWVwZytWZmw1aStJSEFiMHIydHNJNVRncwpwMmg3RUtCcmdlMGx1ZFQwbVB6QUJWNXBZemx1eUlCbTd0L3VNT0xoc2x1allGMGN0bzQ0Wk8zUmh6SUpwOEt2CmNJZFRxaEpIYTV0QkNxVm1qUktNU0l3R0FQWFlFM3N0UjE3UTUzTXlPcG9rbi82c21Idz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
  keyData: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS1FJQkFBS0NBZ0VBNDk1U0kyTGw5U0RsaDhtRkQ5N2ZKTWJtNzVDYnRaQ1p0WDc0M1ZiRC9xQkhPdGVHCnJVL3hEZjRHamM2S20rQWJvN3I0cFNkY3pGK1EzWWg3Ujc3QU5Ca05OOHpRanV5TXE0TS9CVzdxWjF5QXVXVHoKOENQRnI4b2dydTUrSjZpZmVWVVdwRGxvSDZiMEkwNjlGZ2FqaDQ5LzdkL1g1Y0lRZzA5bHhIaTh6RkdCODNxOQpaRi9mUlZOZlB5MTVHTnVxV3RVQjdzSGRiTDJNUHpGZGNpSXRBUk85RFRDQjlqdXUza3JZSUZHZGhNTDlmSFFRClJXTjhpVnh4K1F3dHFENmxGd0FkNDZRVmJac1pROE92Z0tuTW9nVWVvNnZhbDRUcTRnOWtMcHhML3Y0WnRHV1MKNTRoVlZ2UDE1WUkybUQ2K0MzNnd0aVIyZ21pUWJqTERaelhZN09DdytuZEhIS2ZSMjAwbjJIV1lyWUdzcmZBRApNNzNzSEVkYWdvVDRxS2N5YjRPSlZwTk9qeU44bVhFaVpOL2RaZVUzend0UkZPa1hHUFR1RFREcFRyTXdWVitnCndMaU1EbWdRNG9WNElkVkVtVUpQZm90WVdMVHhJRTQ3UFcyUnNrS3lIYnNiWmttdXpnUklZVWkyR2d2UW1hRmYKMWVGOVVPWW5lb1pETEhjaGx4WTNHV0pPVlRVbXNDZHV2emh5YmFnK2EyOUVuTy91SzlYWWJNV1Y5ZElBN0ppeQpuQTNrQ0dlYldIYklZd2pSZSt0b2lnTi9Dd1FHeS9weTRpeVczaWp1WTZtUTI3UWJqV1pkZnJib3N4eWZWbVJMCklBZUR5SjdTS1poeldVLzdXVWFISXpkNHp4R1RPMTlNRHltZ0xYUHJjN1BERE5peDhMUVA2ZTR5TDM4Q0F3RUEKQVFLQ0FnQThBL2trUXM4SVFmTFNVYnhQRXNjNDIzNUZpSlBLUFZ5T2xmT2I4RmRNd0JBaXFsTlpZRjIvN3JEeApObjRCVWdSVm1sQVV4NHBFZGNNazVlWjZYZjRuZXBXbHBiY2tmWjhMS1ZVMjdDQ211cEZZd3dNUXM0dEVvbnI3Ck4rdFlMS3hiKzVJc0RNYWsxNGNqcVlCWnhjUGFWMnc5VGFDQ2JodUZTaXNtbFJvOHdoYjA5dFhkRXZjdVBpZ3UKN3A0ZmN2T3FXc0hZall6eEwvYzVTWm93RGxwR0YxbkttSVVTUW1QclBsRXdLZTdQNGI5N3dPSHNOS2kvVU83Zgp4bHBjSHF2Q3BCQTdQYU03TEFkNmRwYkp6MjhMR1VnWm1aRElLWVRucDJBZWVxSDFkaDExQ3Urbk5ad3NlN0svCkVRMnFDWlJxV0tMWVJrQkVWcC83dGprSy9QNjEzWmhiRityWVNKOUZkN2ZPYVRDNUZzeCtzMGpocHBjZ0VwQ24Ka2dQYUVKbTlkbk10MG1IQXJCWFRaL09BeWU5ZkhlbmJTWHV0aUhjcEJXaUIyRkxzcEdsTnN4RVZ6dmVpSGQ3WQpDQnhUVllqUWpXOUFmNjdnZFl1UlQ1aTB2L1dPbDVnUE9aN1dXQmwwLzMvSUFzMkEvYmdKSDFLWWVSY1VIUlZmCjVBNFF5RWJoUUhJSUY4YnhYZjQ5UHBkM2N6L096WSthWWFOc29wWHUxTjNqV1NJL1g3MThtdk4xTG1QZDU3ZmoKRWlmTm80MWNXbHBkSHBEaW5ITCtwUGswQUhER24zODJxMHpha1hjNzY0WTR6Z1Z0cE1WVmh6c2JGSXZkMlNxVgpjL095ZjA4RjljYnZnNmtMa2RrVEozSldNL1dEdUpXZG8wNlJXT1o1bU9VREVEc00yUUtDQVFFQTVzY3dKOFg5CktJanE0K2JTemwrZWc3OHp2N1ByR0IrYmtwSkV4MWVJN2ozVkZhTi9zN0ZDRys4emY1RDhTcGJ3bDA2My95OFkKb0xJbkR5Ymp3YXIxeEZtckxlOUEycWVKTzdDV2t2aVBYdnk3OWlOVHJiME5hcFQvV29wUlJxQ0JpQjFMNlJ1aQpkcjljWjNQSU1xOGQrWGh6R1JEMTZqMmgyRmNqMVVlUVA4MmIyMFd1R2dsb2xPb1lRelZtRjVvdnZYTVNMYkZtCmFVWUhMR0VEaTkybSt5cndmbXJINzRFRUFxZHJ2MUQ0ZzVxcWlRR3J2SExUS2RQcDBHVFlrcStUZ1lrS3hzQ0oKQ3Q1Z2lQczQ4VW8xZFZzSUdDS1dvMGRES0Q4cDNEYWlSQ2hPc2w3NE5lYXhqcEM1Q2tFTmxHa2NXenNiTk9rSQpndGVFZzdZRlJraCt6UUtDQVFFQS9NVzV3VVpiOFNLZE9Ub01ydWRHam03MTNtT0hldWthSjAvcURibmNiVTRJCnNpUWdRNiswbk1wZ1lxQ0NyZXdUbTRXc2pnM00wakhmeDhSTHNtcklMUjEvSWtXdDE2di9YOU51bjROTmp3Z2EKcWovT0NlTUQ2cmFzd3pGdDAxbHg2TXplZmFkUUNkQTgyQmxSWG5DbEJrVjdBVldSRlcvT3lrZk52OHkvREtKZQo3MS9RWDhMZU9kR2M2Q3hpbUVMVkZkZlNqbXNBYzVydjlJUWVQUzU5V1l0c2NTRjFZVGNSYzY3blhLd1ZueXNwCmZFbE5odDJ3dUpVYnpHblQ0MTJHUGNWa0h0QU8wWnk1K0w3RTljVzFsQjdEaTBGZnk1Lzg0Z1R2OG5GVVJWVHQKcFd3QVVEWS9kamMvb1FBdlJlNmZHbHdhQTExYUJjd2x6MG1JK3l4UGV3S0NBUUFmU21hM0hkdERnYjBIaGFhVApvTmRuV2FkMG1McUpuTStGUWh2ZFEzc25nbTYvN2xsRVRnWityeUkyYTd3cGlPbTZPa3dzWjRCWldZNStPWEdzCk1yZjhGWVJtU0FodEhVWTRONnRTNWl6YVhqNUdFMmduS0hrSE9JaWZDQjRaQzI1RXZHUXNpVGl3RFNaRVNLaWUKWnF3VHhVY2w0T3pYQStCTDZ4VEt1RmRRcjFvd2t2UVdSNnhNZEtreGc2NENDVC9yMmd4ZThhekhIVjJmb00vUQpTUTk1QXN0MCtKbC9XZWpuU3pnS3lybkhibE10SEhMaXJGY0JWdUJmQnkxdVJpd2o1aWIxNStrczloWDB2TXR0CnUvZ2ZuMllyajVVSk1vSmlsSjNpWSs0QWU4NmYxTXltMGs3RTI4NmJHMUx5Q29aendFSGlISzZ3dnZRU3Y3MWIKV0QwSkFvSUJBUUNRRW5yZnlLU2ErbW0ydG5tSUwxWXQxTnphMXN2ZnFJRTVxdmp5dmQ3L2hoeTZ2SkNQUTlTawpFVTJDcVk0U1o1NTlaR0dIemlIU0pJOHlJNVlwcVdkVEg1N1kvL0lvSFdhL1RabWQzWThWV1Q4cGpwaDNWaWRqClhwOTEyZlNKSkZBaXFyS2QyQUZzdG40WGhjYTFGMnRYK2I0MGNucnhSdnNNbklTUEw3b3REMWNoQlBHVncxSTYKamxqcWxISFY2ekhjODFpVnlETkhzU1hYcm40MXpRdXhRQ0NkRXI3K25BNmNhekoveGEzRlBTcTJKbW5EMXhQbApBVWdJNk1EV3RQWFF1M05uaEpzTnFsRHRrSDVldjBQUm12OUZuZ3RsMmxpZTBzV1k0RE55R1FnaTR6NENlZ2tOCjdrdWNEcWpqS1RFU0t6REFmakxUWHhxbDNYbnYvNytGQW9JQkFRREY3RHhZRUQwWHgyZHljUFBxRjgxdlVYMEsKb0lLTWU5dkdacmt6OTliTnJYODg2VS82N3ZoUWg2SzJ4dUZBR3UwS2RLSnBRbGlqQ1dFYzZUbGxCRUFNT2xtcgo1Y0JuZnBWS0t1UE5xN0FMbHMyUFVVU3RrVk8xUHY1dXBVMDUwak5wdW0zUUgyWTVmVTh3VjhzUHlaZWZrU2g3CnJONEU2bWxPMGUyQm43c0xJNmZER1J4aVRia3dNUEJOaGg3dXJqaFZoN1RPOHpwK0xnVE5QNDlteGxsTURpZ20KNFA3emFkT3U5c2Q3cjB0RWhJUVFOQWxHdmNXMVF0Rk1DVnAyRExneVg0Q2xBUFc0aCtmUXEvY0U2d0ZZZ2hLYQpHRzNRQ3RaY1pBNlV6UUEzaXUyMDRSVVBHaDAxNCtIZ09CZkYvN0xXS2JLSzJQelcxK0ZRVG10YlF2MFgKLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K
  caCertData: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZiRENDQTFTZ0F3SUJBZ0lRVFptRkUzZFpLU2twZ0UrMTJSQ0hyekFOQmdrcWhraUc5dzBCQVFzRkFEQlEKTVRJd01BWURWUVFLRXlsSVlYTm9hV052Y25BZ1JHVjJWR1Z6ZENCSmJuTjBZVzVqWlNCRFFTQXRJRlZPVkZKVgpVMVJGUkRFYU1CZ0dBMVVFQXhNUlNHRnphR2xqYjNKd0lFUmxkbFJsYzNRd0hoY05Nak13TmpBM01UZ3hOVE00CldoY05NalF3TmpBMk1UZ3hOVE00V2pCUU1USXdNQVlEVlFRS0V5bElZWE5vYVdOdmNuQWdSR1YyVkdWemRDQkoKYm5OMFlXNWpaU0JEUVNBdElGVk9WRkpWVTFSRlJERWFNQmdHQTFVRUF4TVJTR0Z6YUdsamIzSndJRVJsZGxSbApjM1F3Z2dJaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRRGRWS3owKzNVT1Z0aHRuTytCCjErMTJnSjFkcVRzZ254bGloOUErVXhEdzdIOUNVRmZUZHpyeDk4QkJtZDR3TW1ENUVnMEJ1M0NDTm0yMnpjRy8KZ2pIR0dBT09HMkZWSzZpOUplMndEKzVRRnZxMlBCRHIrZ2ExNXFSbmY3djUvbFo0YytxRExIRXEreVhUZE9GRQo5K0hiSjJJUERSM0tWN0FJYUV5ZitBS0hwcmxBcVVGZ1JiQlEyQkxhS3NqRWZBZlNoaGw3TDFzbWtVRThKMVloCkpzam0vSHNEc2I3ZmMwelVNYUxrUDRIalYzci9nTnJqUFZvNFlTVVo4c2FRdzh5NlNXcElWZHVjUFptZUlaNm8KZlAvenErc0wxeXovem9EcmtwYjlRWE8xa0drcXNQTkdlUXlwRGNRQzVTeFNPaHZ6bXhCbGhpNHNENzFGcXVyWQpQNE1EQlh2WjhWQzJYZk1zM3I2ejBxQWcweEVQbW9Xek9kYUhjdldvWG5jaWVvNTBFdDhadUxyWldoTGJqd1FSClpNaHJMd3B1dWJkTDJjMFZrdVU5ZE1wYnRyWFIwNzNMUWpsMWNWUW9LKzdURkszaW92MHY5VFJSalN2NHIxdTMKVklyQ0JnV0M3QXRVcHNiaVgvMVBNRmpobnNDN2pxdm1RbDBiYmJ1Z0JPcUViRFE2UHZTWXRMWmtQazcyaFFPcwpjalR1eWVBWE5sczAwRGZpcFhheHhSTERxV2kxTlB2clZXdjU4Z3pJZE0vYTJxSFlKMW1yWXI1S0tUYWtHcVp1Cmpmbk9veDVPS2E1K0dhVjZBN2xyKzB3L2ZKT1hZdEIrWGdCZC9vOFJkcFY1NkhVUmoxZzhOZm9XaWo1Y1JZWTQKUTZLRmYvaVhmeklDcGI4Z1ArMHVwT2t1SlFJREFRQUJvMEl3UURBT0JnTlZIUThCQWY4RUJBTUNBcVF3RHdZRApWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVXpFeThmRldwWlBWRGxzS0VTeG9ucmpkdEJaMHdEUVlKCktvWklodmNOQVFFTEJRQURnZ0lCQUlnd2JBaWlaWnViZGxLMlVKb2JvcnEySDg3OVdrN0VFOWZ0WVNBeUNvZjQKNHd4TnZUbDlmaEpSSjR6Q3p0eGdHUWlLYk5EV0JCNXlPV3Q5TUdUSVZRQXA3c2VMamZFeG1kelo5V1FtNW0zagprYThpYlBXWUlxaFR2a3V5TlNEa0dMUEI0ZWxISmFLWWh5eGdORjl5c3ZYZDBENElmR1hMckZLeE1McVdjNGNQCk1ZeUNyalhHWThJSzhNYnFiUElPU2xLSE5yZnNjSmxWV0NHclRuVVFYT0xQcmdvV2kxNDMzQStLLzFCeUJlcVgKOHJ4U2ZNMVZENSt6YzNTaFhLbTdpTEVHejJVMzFzeVBDUkV2dEtzbm50dTRxMXZiS1lTL2NQU2kzWUNTanpCOQpFa0pRc1BOTzZ2UzJXRmszbW83d3BEWC8wQmttSlZqbDY4N01nb0VMR2dJVDBvZHNSL2p2a0sra21nYVFpSlJjCkVVZGVLaitPRGZRL3dFVFFVakM3Z3VVckowYmdOdzlkVVJkWE1COC9kYnlMQ0ZwdDlPRnVjOHpjaXZwQnUwU1MKVnI4R3AwYlk2cTVab3lJRERSV1oxV2NzNkpPYkFBdWxoc1orZEZXNHBTYWhQWkNUTUtwRURPd0psN296RHphMQpQVG1wNzBnMmlsVHkvdDF0ZTBRZG5QbE9BbWh5S281UEZrZ2Z0RTRQdklIemJxTUlNcC81ZENRWWhLaktsb3JoCnB5dlRnYmJpTVI0L0FLUDdDRUU4UzltTzgyOTBEUmRMV0FuMURSeDcwT1Q0MHI5a2x2VTJUUU9XSjRYVVJZd0wKSndsMkF1b0tWVGR0NnYrMHNQMkpSbnBmTXRNRWY1TXhta1cvSW03N3RHSjlKQm5WRmtQM2JBNURkdEp3VG1NRQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
image:
 repository: images.releases.hashicorp.com
 name: hashicorp/terraform-enterprise
 tag: v202310-1 # 任意のバージョンに修正 https://developer.hashicorp.com/terraform/enterprise/releases
env:
  variables:
    TFE_ENCRYPTION_PASSWORD: Terraform-Enterprise!
    TFE_HOSTNAME: "terraform-enterprise.terraform-enterprise.svc.cluster.local"
    TFE_DATABASE_HOST: "prereqs-postgresql.terraform-enterprise.svc.cluster.local"
    TFE_DATABASE_NAME: tfe
    TFE_DATABASE_PASSWORD: Terraform-Enterprise!
    TFE_DATABASE_USER: postgres
    TFE_DATABASE_PARAMETERS: "sslmode=disable"
    TFE_OBJECT_STORAGE_TYPE: s3
    TFE_OBJECT_STORAGE_S3_BUCKET: "tfe"
    TFE_OBJECT_STORAGE_S3_ENDPOINT: "http://prereqs-minio.terraform-enterprise.svc.cluster.local:9000"
    TFE_OBJECT_STORAGE_S3_ACCESS_KEY_ID: "tfeclusteradmin"
    TFE_OBJECT_STORAGE_S3_SECRET_ACCESS_KEY: "Terraform-Enterprise!"
    TFE_OBJECT_STORAGE_S3_REGION: us-east-2
    TFE_REDIS_HOST: "prereqs-redis-master.terraform-enterprise.svc.cluster.local:6379"

このあとは、helmを使ってTerraform Entepriseをプロビジョニングします。

.kuberlrディレクトリが前の手順で作成されていると思うので、このディレクトリは削除しておきます。(残っていると、Request entity too largeのエラーがhelm install時に出ます。)

$ helm install terraform-enterprise . -n terraform-enterprise --values ./tmp/override.yaml --wait

Terraform Enterprise用のPodが起動していればOKです。

$ kubectl get pods -n terraform-enterprise
NAME                                   READY   STATUS    RESTARTS   AGE
prereqs-minio-0                        1/1     Running   0          17m
prereqs-minio-1                        1/1     Running   0          17m
prereqs-minio-2                        1/1     Running   0          17m
prereqs-postgresql-0                   1/1     Running   0          17m
prereqs-redis-master-0                 1/1     Running   0          17m
prereqs-redis-replicas-0               1/1     Running   0          17m
prereqs-redis-replicas-1               1/1     Running   0          16m
prereqs-redis-replicas-2               1/1     Running   0          16m
terraform-enterprise-ff8cd777d-nbqq9   1/1     Running   0          7m1s

Terraform Enterprise用のMinIOバケット作成

MinIOでバケットを作成します。MinIOはS3と互換性のあるストレージサーバーです。Kubernetes上にインストールして使います。

一時的なPodを作成して、Pod内でコマンドを実行しMinIOバケットを作成します。

$ kubectl run mc-shell --rm -i --tty -n terraform-enterprise  --image minio/mc --command /bin/bash
bash-5.1# 
bash-5.1# mc alias set home http://prereqs-minio.terraform-enterprise.svc.cluster.local:9000 tfeclusteradmin 'Terraform-Enterprise!'
mc: Configuration written to `/root/.mc/config.json`. Please update your access credentials.
mc: Successfully created `/root/.mc/share`.
mc: Initialized share uploads `/root/.mc/share/uploads.json` file.
mc: Initialized share downloads `/root/.mc/share/downloads.json` file.
Added `home` successfully.
bash-5.1# 
bash-5.1# mc mb tfe
Bucket created successfully `tfe`.
bash-5.1# 
bash-5.1# mc ls # tfeバケットが確認できればOK
[2021-08-09 22:13:01 UTC]     6B afs/
[2023-11-20 23:54:21 UTC]    16B bin/
[2021-08-09 22:13:01 UTC]     6B boot/
[2023-11-27 02:19:11 UTC]   380B dev/
[2023-11-27 02:19:11 UTC]    41B etc/
[2021-08-09 22:13:01 UTC]     6B home/
[2023-11-01 13:59:23 UTC]   213B lib/
[2023-11-01 13:59:24 UTC] 4.0KiB lib64/
[2023-11-20 23:54:21 UTC]    21B licenses/
[2021-08-09 22:13:01 UTC]     6B media/
[2021-08-09 22:13:01 UTC]     6B mnt/
[2021-08-09 22:13:01 UTC]     6B opt/
[2023-11-27 02:19:11 UTC]     0B proc/
[2023-11-27 02:19:44 UTC]    17B root/
[2023-11-27 02:19:11 UTC]    21B run/
[2023-11-01 13:59:24 UTC]   123B sbin/
[2021-08-09 22:13:01 UTC]     6B srv/
[2023-11-27 02:19:06 UTC]     0B sys/
[2023-11-27 02:19:49 UTC]     6B tfe/
[2021-08-09 22:13:01 UTC]     6B tmp/
[2023-11-01 13:59:23 UTC]    17B usr/
[2023-11-01 13:59:23 UTC]   219B var/
bash-5.1# exit # シェルを抜ける

証明書をローカルに登録

Terraform EnterpriseはTLS接続が必須のため、証明書をローカルに登録する必要があります。

Macの場合は、キーチェーンアクセスアプリを使用して、サンプル証明書を登録します。

Finder等で上記サンプル証明書のディレクトリを開き、キーチェーンアクセスアプリの項目「システム」にドラックアンドドロップで登録します。

Macでキーチェーンアクセスを使用してキーチェーンに証明書を追加する - Apple サポート (日本)

追加した証明書(Hashicorp DevTest)を選択して、信頼常に信頼に変更します。

Hostsファイルエントリの追加

ローカルのHostsファイルにTerraform Enterpriseのエンドポイント用にエントリを登録する必要があります。

アプリケーションを公開するために、CLBを利用しています。

CLBのIPアドレスをHostsファイルに登録します。

まずは、CLBのIPアドレスを確認します。

$ kubectl get service terraform-enterprise -n terraform-enterprise

NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP                                                                   PORT(S)         AGE
terraform-enterprise   LoadBalancer   10.100.12.173   <CLBのDNS名>   443:30471/TCP   119m
$ dig <CLBのDNS名>
# 省略

;; ANSWER SECTION:
<CLBのDNS名> 60 IN A <CLBのIPアドレスA>
<CLBのDNS名> 60 IN A <CLBのIPアドレスB>
# 省略

HostsファイルにIPアドレスを登録します。2つIPが返ってきますが、どちらでも大丈夫です。(本来ならあまり良くないですが、検証用のため。)

Macだったら、/private/etc/hostsにHostsファイルがあります。

このファイルにエントリを追加します。

$ sudo vi /private/etc/hosts
# 以下を追加
<CLBのIPアドレス> terraform-enterprise.terraform-enterprise.svc.cluster.local

動作確認

最後に動作確認です。

Curlで疎通確認してみます。OKが返ってきたら正常です。

$ curl https://terraform-enterprise.terraform-enterprise.svc.cluster.local/_health_check
OK

最後にTerraform Enterpriseのコンソールにアクセスしてみます。以下のURLにブラウザでアクセスします。

https://terraform-enterprise.terraform-enterprise.svc.cluster.local/session

Terraform Enterpriseの画面が表示されれば成功です。

おわりに

EKSへのTerraform Enterpriseのデプロイを試してみたでした。

サクッと試したかったので、リソースが最小限ですむQuickStartの手順でやってみました。

需要があったら、本番稼働を意識した構成でデプロイとかもやってみたいと思います。

今回はインストールまででしたが、その後の手順を試したい場合は以下を参考に試すことが可能です。

Initial Admin User - Installation - Flexible Deployment Options - Terraform Enterprise | Terraform | HashiCorp Developer

以上、AWS事業本部の佐藤(@chari7311)でした。