Elasticsearch: GitHub Actions 與 GitLab CI
直接從您的 GitHub Actions 或 GitLab CI pipeline 啟動一個真實的 Elasticsearch 服務,執行測試,並自動銷毀服務
👋 歡迎來到 Stackhero 文件!
Stackhero 提供即用型的 Elasticsearch cloud 解決方案,帶來多項優勢,包括:
- 由專用私有 VM提供的最佳性能和強大的安全性。
- 支援 HTTPS 加密的可自訂域名。
節省時間並簡化您的生活:只需 5 分鐘即可嘗試 Stackhero 的 Elasticsearch cloud hosting 解決方案!
本指南將帶您一步步在 CI pipeline 中運行一個真實、專屬的 Elasticsearch 服務,可選擇 GitHub Actions 或 GitLab CI。依照這些步驟,您可以在接近正式環境的條件下,針對實際的 Elasticsearch 實例測試您的程式碼,無需再依賴 mock 或模擬器。Elasticsearch is a distributed search and analytics engine that turns large volumes of data into fast, relevant answers.
每次 pipeline 執行時,您都會獲得一個全新的 Elasticsearch 實例。這代表您的測試將與正式環境中用戶所見的服務完全一致。此流程會自動建立一個臨時 stack,新增 Elasticsearch,等待服務就緒,取得產生的認證資訊,利用 curl 執行 smoke test,最後在流程結束時自動清理所有資源。
您將會使用 Stackhero CLI,這是一個獨立的命令列工具,可讓您快速且簡單地啟動與管理 Stackhero 服務。
1. 建立 Access Token 並儲存為 CI 機密
為了讓 CLI 能以非互動方式運作,您需要一組 access token(格式:usr-xxxxxx:tokenId)。這個 token 只需建立一次,然後將其加入您的 CI pipeline,作為安全加密的機密變數。
- 建立 token: 在您的 Stackhero 控制台,點擊右上角的大頭貼,進入 您的帳戶,選擇 Access tokens,然後點擊 Create token。
- GitHub Actions: 在您的 repository,前往 Settings > Secrets and variables > Actions > New repository secret,將 token 輸入為
STACKHERO_TOKEN。 - GitLab CI: 在您的專案,前往 Settings > CI/CD > Variables > Add variable,將 key 設為
STACKHERO_TOKEN,並勾選 Masked(如果您的 CI 僅在受保護分支執行,也可勾選 Protected)。
請勿將 access token 直接寫在 pipeline 的 YAML 檔案中。如果 token 出現在 YAML 內,任何有 repository 存取權的人都可能看到,甚至可能出現在建置日誌中。將其儲存為 CI 機密可確保加密與遮蔽,讓您的 token 保持安全。
2. 生命週期腳本
以下是一個完整的腳本範例,涵蓋服務的全生命週期。您會發現設定非常簡單,只需幾個指令即可。您可以直接從下方各平台區段複製對應的 YAML 配置。
#!/bin/bash
set -euo pipefail
# STACKHERO_TOKEN 由 CI 機密提供,CLI 會自動讀取。
stackName="ci-elasticsearch-$$" # 每次執行唯一的 stack 名稱
serviceStore="elasticsearch" # Elasticsearch 服務 store
instance="20G" # 如有需要可調整(見步驟 3)
region="europe" # 區域名稱(可用 stackhero regions-list 查詢)
# 1. 在 runner 上安裝 CLI
curl -fsSL https://www.stackhero.io/install.sh | sh
# 2. 安裝 smoke test 所需的 client(jq + curl 為基本需求)
apt-get update && apt-get install -y --no-install-recommends jq curl
# 3. 為本次執行建立專屬 stack
stackId=$(stackhero --format=script stack-create --name="$stackName")
echo "Stack created: $stackId"
# 4. 新增 Elasticsearch 並取得其 service 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. Smoke test:Call the cluster health endpoint.
curl -fsS -u "$user:$password" "https://$host:9200/_cluster/health" | grep -q '"status"'
echo "✅ Elasticsearch 已可從 CI 存取。"
資源清理(刪除服務、等待刪除完成、再刪除 stack)會在下方各平台專屬區段說明。這種做法可確保即使 smoke test 失敗也會進行完整清理。
Stack 必須為空才能刪除。請務必先刪除服務並等待其移除,再刪除 stack。
service-wait-for指令可確保服務已啟動或已刪除,是等待刪除的最佳工具。
3. 選擇實例規格
下方範例預設使用 Elasticsearch 的入門實例 20G。這對大多數工作負載來說已相當合適,您也可依需求調整。若要查詢 Elasticsearch 所有可用實例類型,可執行:
# NAME 欄位即為 --instance 參數值
stackhero instances-store-list --service-store=elasticsearch
4. GitHub Actions
請將下列內容儲存為 .github/workflows/ci.yml。從此之後,每次 push 或 pull request 都會針對真實的 Elasticsearch 實例執行測試。
name: 使用 Elasticsearch 的 CI
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 與 client
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 實例被刪除,避免產生不必要的資源費用。
5. GitLab CI
請將下列設定儲存為 .gitlab-ci.yml。每次 pipeline 執行時都會建立一個全新的 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 區塊。這個區塊無論 job 成功或失敗都會執行,確保您的 Elasticsearch 資源被移除,避免產生不必要的費用。
在 GitLab,
after_script會在一個全新 shell中執行。為了處理這點,腳本會在 job 過程中將 service 與 stack 的 ID 寫入deploy.env,並於清理前重新載入。如此即使 job 執行中途失敗,您的資源仍能被正確清除。
這就是 Elasticsearch 的完整 CI 生命週期:建立 stack、加入服務、等待、取得認證、smoke test,並始終進行清理。每次 pipeline 執行都會獲得一個真實、隔離的服務,流程結束後不會有任何資源殘留。如需更多可用指令與非互動式 STACKHERO_TOKEN 認證說明,歡迎參考 完整 CLI 文件。