🥢

Terraform Enterprise のログを Google Cloud Logging に転送する

2024/03/27に公開

Terraform Enterprise Flexible Deployment Option(以下TFE)をGoogle Cloud上に構築し、そのTFEのログをGoogle Cloud Loggingに転送する設定をした際のメモです。

Prerequisites

TFEに関してはこちらに記載した内容をベースに構築しています。
https://zenn.dev/i10chu/articles/fcd8691c8d0194

TFE's logging

TFEのログはデフォルトの設定だと、TFEコンテナ内の/var/log/terraform-enterpriseに生成され保存されます。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/monitoring/observability/logs

terraform-enterprise@bce2c409023e:/var/log/terraform-enterprise$ ls -ltrh
total 112K
-rw-r--r-- 1 terraform-enterprise root  495 Mar 20 01:55 redis.log
-rw-r--r-- 1 terraform-enterprise root 2.0K Mar 20 01:55 postgres.log
-rw-r--r-- 1 terraform-enterprise root 3.6K Mar 20 01:55 terraform-enterprise.log
-rw-r--r-- 1 terraform-enterprise root  618 Mar 20 01:55 slug-ingress.log
-rw-r--r-- 1 terraform-enterprise root  113 Mar 20 01:55 outbound-http-proxy.log
-rw-r--r-- 1 terraform-enterprise root   58 Mar 20 01:55 nginx.log
-rw-r--r-- 1 terraform-enterprise root  260 Mar 20 01:55 metrics.log
-rw-r--r-- 1 terraform-enterprise root  300 Mar 20 01:55 terraform-state-parser.log
-rw-r--r-- 1 terraform-enterprise root   99 Mar 20 01:55 atlas-ui.log
-rw-r--r-- 1 terraform-enterprise root  116 Mar 20 01:55 tfe-health-check.log
-rw-r--r-- 1 terraform-enterprise root 4.5K Mar 20 01:55 supervisord.log
-rw-r--r-- 1 terraform-enterprise root 1.8K Mar 20 01:55 terraform-registry-worker.log
-rw-r--r-- 1 terraform-enterprise root 2.1K Mar 20 01:55 terraform-registry-api.log
-rw-r--r-- 1 terraform-enterprise root 1.3K Mar 20 01:55 backup-restore.log
-rw-r--r-- 1 terraform-enterprise root 1.5K Mar 20 01:55 archivist.log
-rw-r--r-- 1 terraform-enterprise root 2.8K Mar 20 01:56 task-worker.log
-rw-r--r-- 1 terraform-enterprise root 6.9K Mar 20 01:56 vault.log
-rw-r--r-- 1 terraform-enterprise root 9.5K Mar 20 01:56 sidekiq.log
-rw-r--r-- 1 terraform-enterprise root 9.3K Mar 20 01:56 atlas.log
-rw-r--r-- 1 terraform-enterprise root  11K Mar 20 01:56 licensing.log

TFEはFluetBit経由でログを転送する事が出来ます。サポートされている外部のログ転送先は以下のドキュメントから確認可能です。
https://developer.hashicorp.com/terraform/enterprise/flexible-deployments/monitoring/observability/logs#supported-external-destinations

TFEをGoogle Cloud上で動かしており、TFEのログをGoogle Cloud Loggingに転送し、ログを集約して管理させる必要がある場合、以下の方法を試してみてください。

Log forwarding to Google Cloud Logging

先ず、Loggingサービスに対してログを書き込める権限を持ったサービスアカウントを作成し、サービスアカウントのクレデンシャル情報(JSONファイル)をTFEが動いているインスタンス上に保存します(この環境では、/etc/terraform-enterprise/hc-xxxx.jsonとして保存しています)。

次に、ログ転送で利用する設定ファイル/etc/terraform-enterprise/logging.confに関しては、こちらのドキュメントを参考に以下の様に設定しています。

[OUTPUT]
    Name stackdriver
    Match *
    location asia-northeast1
    namespace terraform_enterprise
    node_id tfegcp
    resource generic_node
    google_service_credentials /run/terraform-enterprise/fluent-bit/gcp-credentials.json

最後に、/etc/terraform-enterprise/compose.ymlファイルを以下の通り修正します。環境変数とボリュームの設定に関しては、ログ転送で必要な設定だけ記載しています。

---
name: terraform-enterprise
services:
  tfe:
    image: images.releases.hashicorp.com/hashicorp/terraform-enterprise:v202402-1
    environment:
...
      TFE_LOG_FORWARDING_ENABLED: "TRUE"
      TFE_LOG_FORWARDING_CONFIG_PATH: "/run/terraform-enterprise/fluent-bit/logging.conf"
...
    volumes:
...
      - type: bind
        source: /etc/terraform-enterprise/logging.conf
        target: /run/terraform-enterprise/fluent-bit/logging.conf
      - type: bind
        source: /etc/terraform-enterprise/hc-xxxx.json
        target: /run/terraform-enterprise/fluent-bit/gcp-credentials.json

TFE_LOG_FORWARDING_ENABLED: "TRUE"でログ転送の機能を有効にし、TFE_LOG_FORWARDING_CONFIG_PATHでログ転送のための設定ファイルが存在するコンテナ内のパスを指定します。
TFE_LOG_FORWARDING_CONFIG_PATHに関しては、volumes:のバインド設定で、TFEが動いているインスタンス上のファイル/etc/terraform-enterprise/logging.confをソースに指定しています。

サービスアカウントのクレデンシャルに関しても同様に、TFEが動いているインスタンス上のファイル/etc/terraform-enterprise/hc-xxxx.jsonをコンテナ内の/run/terraform-enterprise/fluent-bit/gcp-credentials.jsonにバインドしています。

準備が整ったので、terraform-enterpriseサービスを再起動させます。

sudo systemctl restart terraform-enterprise

サービスが無事に立ち上がったら、コンテナにアクセスし、コンテナ内のサービスがちゃんと稼働しているか確認します。

docker exec -it terraform-enterprise-tfe-1 bash
$ supervisorctl status
fluent-bit                       RUNNING   pid 113, uptime 0:00:59
postgres                         RUNNING   pid 67, uptime 0:01:02
redis                            RUNNING   pid 56, uptime 0:01:04
terraform-enterprise             RUNNING   pid 30, uptime 0:01:05
tfe:archivist                    RUNNING   pid 132, uptime 0:00:56
tfe:atlas                        RUNNING   pid 133, uptime 0:00:56
tfe:atlas-ui                     RUNNING   pid 134, uptime 0:00:56
tfe:backup-restore               RUNNING   pid 135, uptime 0:00:56
tfe:licensing                    RUNNING   pid 137, uptime 0:00:56
tfe:metrics                      RUNNING   pid 140, uptime 0:00:56
tfe:nginx                        RUNNING   pid 146, uptime 0:00:56
tfe:outbound-http-proxy          RUNNING   pid 162, uptime 0:00:56
tfe:sidekiq                      RUNNING   pid 173, uptime 0:00:56
tfe:slug-ingress                 RUNNING   pid 178, uptime 0:00:56
tfe:task-worker                  RUNNING   pid 190, uptime 0:00:56
tfe:terraform-registry-api       RUNNING   pid 200, uptime 0:00:56
tfe:terraform-registry-worker    RUNNING   pid 208, uptime 0:00:56
tfe:terraform-state-parser       RUNNING   pid 222, uptime 0:00:56
tfe:tfe-health-check             RUNNING   pid 226, uptime 0:00:56
tfe:vault                        RUNNING   pid 241, uptime 0:00:56

fluent-bitサービスも問題なく動いている事を確認します。

$ ps aux |grep fluent-bit
terrafo+     114  0.3  0.2 142252 23724 ?        Sl   01:55   0:03 fluent-bit --config /run/terraform-enterprise/fluent-bit/fluent-bit.conf
terrafo+    1536  0.0  0.0   6612  2304 pts/0    S+   02:11   0:00 grep --color=auto fluent-bit

fluent-bitサービスの--configで指定されているファイル/run/terraform-enterprise/fluent-bit/fluent-bit.confに、環境変数TFE_LOG_FORWARDING_CONFIG_PATHで指定したファイルの中身が追記されているはずです。

$ cat /run/terraform-enterprise/fluent-bit/fluent-bit.conf
# Configuration for the Fluent Bit service. We configure an on-disk buffer for
# Fluent bit so it doesn't try to keep everything in memory.
[SERVICE]
    storage.path                /run/terraform-enterprise/fluent-bit/buffer
    storage.sync                normal
    storage.checksum            off
    storage.backlog.mem_limit   5M
    HTTP_Server     On
    HTTP_Listen     0.0.0.0
    HTTP_Port       2020
    Health_Check    On

# This input plugin reads all of the Terraform Enterprise service logs. It uses
# an on-disk database to keep track of which files are being monitored and
# their offsets. Each record is tagged as tfe.all so we can further process the
# record later.
[INPUT]
    name            tail
    tag             tfe.all
    path            /var/log/terraform-enterprise/*.log
    path_key        log_file
    read_from_head  true
    db              /run/terraform-enterprise/fluent-bit/tail-db
    db.locking      on
    skip_long_lines on
    buffer_chunk_size 128k
    buffer_max_size   128k

# Rewrite the tag for all tfe.all records to just be the name of the log file.
# For example, a record tagged tfe.all with the data {"log_file":
# "/var/log/terraform-enterprise/foo.log"} will be retagged as foo.
[FILTER]
    name    rewrite_tag
    match   tfe.all
    rule    $log_file ^/var/log/terraform-enterprise/(.*).log$ $1 false

# Fluent Bit does not provide a native way to inject the record tag as a field
# within the record. We call out to Lua to take the tag and inject it as a
# field on the record.
[FILTER]
    name    lua
    match   *
    script  /usr/share/fluent-bit/tfe.lua
    call    add_tag

# We no longer need the log_file field on our records. Remove it.
[FILTER]
    name        record_modifier
    match       *
    remove_key  log_file

# Output all of the records to standard output using JSON format.
[OUTPUT]
    name            stdout
    match           *
    format          json_lines
    json_date_key   off



[OUTPUT]
    Name stackdriver
    Match *
    location asia-northeast1
    namespace terraform_enterprise
    node_id tfegcp
    resource generic_node
    google_service_credentials /run/terraform-enterprise/fluent-bit/gcp-credentials.json

ここまで確認出来れば、TFEのログがGoogle Cloud Loggingに転送されているはずです。

転送されていない場合は、サービスアカウントの権限が足りているかどうかや、ログの出力を確認して切り分けを行います。TFEのトラブルシューティングをする際は、こちらのドキュメントも参考にしてみてください。

参考になりそうな部分あれば、ご活用ください!

Discussion