Elasticsearch: GitHub Actions & GitLab CI

GitHub Actions または GitLab CI パイプラインから実際の Elasticsearch サービスを起動し、テストを実行して、自動的に削除する方法

👋 Stackheroのドキュメントへようこそ!

Stackheroは、数多くの利点を提供するElasticsearchクラウドソリューションを提供しています。

  • プライベートで専用のVMによる最適なパフォーマンスと強力なセキュリティ
  • HTTPS暗号化サポートで保護されたカスタマイズ可能なドメイン名

時間を節約し、生活を簡素化:StackheroのElasticsearchクラウドホスティングソリューションを試すのに5分しかかかりません!

このガイドでは、GitHub Actions または GitLab CI を利用して、CI パイプライン内で実際の専用 Elasticsearch サービスを起動する手順を解説します。これにより、モックやシミュレーションに頼ることなく、本番環境に近い条件下で稼働する Elasticsearch インスタンスに対してコードのテストが可能になります。Elasticsearch is a distributed search and analytics engine that turns large volumes of data into fast, relevant answers.

パイプラインが実行されるたびに、新しい Elasticsearch インスタンスが作成されます。つまり、テストは本番環境でユーザーが利用するものと同じ種類のサービスとやり取りします。ワークフローは一時的なスタックを自動で作成し、Elasticsearch を追加、準備完了まで待機、生成された認証情報を取得し、curl を使ったスモークテストを実行し、最後に必ずすべてをクリーンアップします。

Stackhero CLI を使用します。これは Stackhero サービスの起動や管理を迅速かつ簡単に行えるスタンドアロンのコマンドラインツールです。

CLI を非対話的に動作させるには、アクセストークン(形式: usr-xxxxxx:tokenId)が必要です。このトークンは一度作成すれば十分で、その後は CI パイプラインの安全な暗号化シークレットとして追加します。

  1. トークンの作成: Stackhero ダッシュボードで、右上のプロフィール画像をクリックし、Your accountAccess tokensCreate token の順に進みます。
  2. GitHub Actions の場合: リポジトリの Settings > Secrets and variables > Actions > New repository secret で、トークンを STACKHERO_TOKEN として登録します。
  3. GitLab CI の場合: プロジェクトの Settings > CI/CD > Variables > Add variable で、キーを STACKHERO_TOKEN に設定し、Masked(CI が保護ブランチのみで動作する場合は Protected も)にチェックを入れます。

アクセストークンをパイプラインの YAML ファイルに直接記載しないでください。YAML 内に記載すると、リポジトリにアクセスできる誰もが閲覧でき、ビルドログにも表示される可能性があります。CI シークレットとして保存することで、暗号化・マスキングされ、トークンの安全性が保たれます。

以下はサービスのライフサイクル全体を管理する完全なサンプルスクリプトです。必要なセットアップはごくわずかで、数コマンドのみです。各プラットフォーム向けの完成済み YAML はこの後のセクションからコピーできます。

#!/bin/bash
set -euo pipefail

# STACKHERO_TOKEN は CI シークレットから供給され、CLI が自動的に取得します。

stackName="ci-elasticsearch-$$"          # 各実行ごとに一意のスタック名
serviceStore="elasticsearch"             # Elasticsearch サービスストア
instance="20G"        # 必要に応じて変更(ステップ3参照)
region="europe"                         # リージョン名(stackhero regions-list 参照)

# 1. ランナーに CLI をインストール
curl -fsSL https://www.stackhero.io/install.sh | sh

# 2. スモークテスト用クライアントをインストール(jq + curl がベース)
apt-get update && apt-get install -y --no-install-recommends jq curl

# 3. この実行用の専用スタックを作成
stackId=$(stackhero --format=script stack-create --name="$stackName")
echo "Stack created: $stackId"

# 4. Elasticsearch を追加し、サービスIDを取得
serviceId=$(stackhero --format=script service-add \
  --stack="$stackId" \
  --service-store="$serviceStore" \
  --instance="$instance" \
  --region="$region")
echo "Service added: $serviceId"

# 5. サービスが稼働するまで待機(数分かかる場合があります)
stackhero service-wait-for --service="$serviceId"

# 6. 設定情報を取得(生成された認証情報を含む)
config=$(stackhero service-configuration-get --service="$serviceId" --format=json)

# 7. 必要な認証情報を抽出
host=$(echo "$config" | jq -r '.configuration.domain')
user=$(echo "$config" | jq -r '.configuration.credentials.login')
password=$(echo "$config" | jq -r '.configuration.credentials.password')

# 8. スモークテスト: Call the cluster health endpoint.
curl -fsS -u "$user:$password" "https://$host:9200/_cluster/health" | grep -q '"status"'

echo "✅ Elasticsearch は CI から到達可能です。"

サービスの削除、削除完了待機、スタックの削除といったクリーンアップ手順は、下記のプラットフォーム別セクションで説明しています。この方法により、スモークテストが失敗した場合でも必ずクリーンアップが実行されます。

スタックは空でなければ削除できません。必ず先にサービスを削除し、その削除完了を待ってからスタックを削除してください。service-wait-for コマンドは、サービスが稼働中または削除済みであることを保証するため、削除待機にも最適です。

以下の例では、デフォルトで Elasticsearch 用のエントリーレベルインスタンス 20G を使用しています。ほとんどのワークロードで十分ですが、必要に応じて変更可能です。利用可能なインスタンスタイプ一覧は、次のコマンドで確認できます。

# NAME カラムが --instance に指定する値です
stackhero instances-store-list --service-store=elasticsearch

まず、以下の内容を .github/workflows/ci.yml として保存してください。これ以降、push や pull request ごとに実際の Elasticsearch インスタンスでテストが実行されます。

name: CI with Elasticsearch

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    env:
      STACKHERO_TOKEN: ${{ secrets.STACKHERO_TOKEN }}
      STACK_NAME: ci-elasticsearch-${{ github.run_id }}-${{ github.run_attempt }}
      INSTANCE: "20G"   # 必要に応じて変更(ステップ3参照)
      REGION: europe
    steps:
      - uses: actions/checkout@v4

      - name: Stackhero CLI とクライアントのインストール
        run: |
          curl -fsSL https://www.stackhero.io/install.sh | sh
          apt-get update && apt-get install -y --no-install-recommends jq curl

      - name: Elasticsearch サービスの作成
        run: |
          set -euo pipefail
          STACK_ID=$(stackhero --format=script stack-create --name="$STACK_NAME")
          echo "STACK_ID=$STACK_ID" >> "$GITHUB_ENV"
          SERVICE_ID=$(stackhero --format=script service-add \
            --stack="$STACK_ID" \
            --service-store="elasticsearch" \
            --instance="$INSTANCE" \
            --region="$REGION")
          echo "SERVICE_ID=$SERVICE_ID" >> "$GITHUB_ENV"
          stackhero service-wait-for --service="$SERVICE_ID"

      - name: Elasticsearch でテストを実行
        run: |
          set -euo pipefail
          config=$(stackhero service-configuration-get --service="$SERVICE_ID" --format=json)
          host=$(echo "$config" | jq -r '.configuration.domain')
user=$(echo "$config" | jq -r '.configuration.credentials.login')
password=$(echo "$config" | jq -r '.configuration.credentials.password')
          # Call the cluster health endpoint.
          curl -fsS -u "$user:$password" "https://$host:9200/_cluster/health" | grep -q '"status"'
          echo "✅ Elasticsearch は CI から到達可能です。"
          # 上記の認証情報を使って独自のテストスイートも実行できます ...

      - name: クリーンアップ(常に実行、失敗時も)
        if: always()
        run: |
          if [ -n "${SERVICE_ID:-}" ]; then
            stackhero service-delete --service="$SERVICE_ID" --confirm
            stackhero service-wait-for --service="$SERVICE_ID"
          fi
          if [ -n "${STACK_ID:-}" ]; then
            stackhero stack-delete --stack="$STACK_ID" --confirm
          fi

クリーンアップステップは if: always() で設定されているため、どんな場合でも必ず実行され、Elasticsearch インスタンスが削除され、未使用リソースの課金を防ぎます。

以下の設定を .gitlab-ci.yml として保存してください。この構成では、パイプラインごとに新しい実際の Elasticsearch がテスト用に起動されます。

test:
  image: ubuntu:24.04
  variables:
    STACK_NAME: "ci-elasticsearch-$CI_PIPELINE_ID-$CI_JOB_ID"
    INSTANCE: "20G"   # 必要に応じて変更(ステップ3参照)
    REGION: "europe"
    SERVICE_STORE: "elasticsearch"
  # STACKHERO_TOKEN はステップ1で作成した CI/CD 変数から供給されます。
  script:
    - set -euo pipefail
    - curl -fsSL https://www.stackhero.io/install.sh | sh
    - apt-get update && apt-get install -y --no-install-recommends jq curl
    - STACK_ID=$(stackhero --format=script stack-create --name="$STACK_NAME")
    - echo "STACK_ID=$STACK_ID" >> deploy.env
    - SERVICE_ID=$(stackhero --format=script service-add --stack="$STACK_ID" --service-store="$SERVICE_STORE" --instance="$INSTANCE" --region="$REGION")
    - echo "SERVICE_ID=$SERVICE_ID" >> deploy.env
    - stackhero service-wait-for --service="$SERVICE_ID"
    - config=$(stackhero service-configuration-get --service="$SERVICE_ID" --format=json)
    - host=$(echo "$config" | jq -r '.configuration.domain')
user=$(echo "$config" | jq -r '.configuration.credentials.login')
password=$(echo "$config" | jq -r '.configuration.credentials.password')
    # Call the cluster health endpoint.
    - curl -fsS -u "$user:$password" "https://$host:9200/_cluster/health" | grep -q '"status"'
    - echo "✅ Elasticsearch は CI から到達可能です。"
    # 上記の認証情報を使って独自のテストスイートも実行できます ...
  after_script:
    - test -f deploy.env && . ./deploy.env || true
    - >
      if [ -n "${SERVICE_ID:-}" ]; then
        stackhero service-delete --service="$SERVICE_ID" --confirm
        stackhero service-wait-for --service="$SERVICE_ID"
      fi
    - >
      if [ -n "${STACK_ID:-}" ]; then
        stackhero stack-delete --stack="$STACK_ID" --confirm
      fi

GitLab ではクリーンアップは after_script 内で行われます。このセクションはジョブが失敗しても必ず実行されるため、Elasticsearch リソースが確実に削除され、不要な課金を防げます。

GitLab では after_script新しいシェルで実行されます。そのため、ジョブ中にサービスIDやスタックIDを deploy.env に書き出し、クリーンアップ前に再ロードしています。これにより、ジョブ途中で失敗してもリソースが確実に削除されます。

以上が Elasticsearch の CI ライフサイクルの全体像です。スタック作成、サービス追加、待機、認証情報取得、スモークテスト、そして必ずクリーンアップ。各パイプライン実行ごとに実際の分離されたサービスが提供され、実行後は何も残りません。利用可能なコマンドや非対話型 STACKHERO_TOKEN 認証については、CLI の詳細ドキュメント もご参照ください。