はじめに
前回の記事では、AWS Systems Manager Run Commandを使い、対象EC2へSplunk Enterpriseを一括インストールしました。
Splunkの分散基盤をつくる【第2回】SSM Run CommandでSplunkの一括インストール
今回は、公開リポジトリのテンプレートからホスト別の設定ファイルを作成し、Run Commandで対象EC2へ一括配布します。
使用する手順
この記事では、公開リポジトリの次の手順とスクリプトを使用します。
前提
- 公開リポジトリを取得し、リポジトリルートへ移動済みである
- 対象EC2へSplunk Enterpriseを
/opt/splunkにインストール済みである - 対象EC2のSSM Agentがオンラインである
- 対象EC2にCloudFormationの
Environmentパラメーターと同じ値のEnvironmentタグが付いている - EC2のIAMロールから、配置先の非公開S3バケットを読み取れる
- ホスト名が
mgmt、cm、indexer-1~indexer-3、shc-1、shc-2のいずれかである
検証環境
| 項目 | 内容 |
|---|---|
| Splunk Enterprise | 10.2.3 |
| OS | Amazon Linux 2023 |
| AWSリージョン | ap-northeast-1 |
| 検証日 | 2026-08-23 |
ホスト別の設定ファイルを作成する
1. 設定テンプレートをコピーする
ホスト別の公開用テンプレートを、Git管理外のsplunk/configへコピーします。既存の設定を誤って上書きしないよう、同名ディレクトリがある場合は処理を中止します。
CONFIG_DIR=splunk/config
if ! git check-ignore -q "${CONFIG_DIR}"; then
echo "Not ignored by Git: ${CONFIG_DIR}" >&2
exit 1
fi
if [[ -e "${CONFIG_DIR}" ]]; then
echo "Already exists: ${CONFIG_DIR}" >&2
exit 1
fi
mkdir -p "${CONFIG_DIR}"
cp -a \
splunk/config-templates/{mgmt,cm,indexer-1,indexer-2,indexer-3,shc-1,shc-2} \
"${CONFIG_DIR}/"
2. 環境固有値へ置き換える
CloudFormationで指定したプライベートホストゾーン名と、Indexer Cluster、Search Head Clusterで使用する2種類のpass4SymmKeyを対話入力します。
(
set -euo pipefail
read -rp 'PrivateZoneName: ' PRIVATE_ZONE_NAME
read -rsp 'Indexer Cluster pass4SymmKey: ' INDEXER_CLUSTER_SECRET
printf '\n'
read -rsp 'SHC pass4SymmKey: ' SHC_SECRET
printf '\n'
PRIVATE_ZONE_NAME=${PRIVATE_ZONE_NAME%.}
if [[ -z "${PRIVATE_ZONE_NAME}" || "${PRIVATE_ZONE_NAME}" == example.com ||
-z "${INDEXER_CLUSTER_SECRET}" || -z "${SHC_SECRET}" ]]; then
echo 'Values must not be empty or use example.com.' >&2
exit 1
fi
escape_sed_replacement() {
local value=$1
value=${value//\\/\\\\}
value=${value//&/\\&}
value=${value//|/\\|}
printf '%s' "${value}"
}
sed_script=$(mktemp)
trap 'rm -f -- "${sed_script}"' EXIT
chmod 600 "${sed_script}"
printf 's|example[.]com|%s|g\n' \
"$(escape_sed_replacement "${PRIVATE_ZONE_NAME}")" >"${sed_script}"
printf 's|<INDEXER_CLUSTER_SECRET>|%s|g\n' \
"$(escape_sed_replacement "${INDEXER_CLUSTER_SECRET}")" >>"${sed_script}"
printf 's|<SHC_SECRET>|%s|g\n' \
"$(escape_sed_replacement "${SHC_SECRET}")" >>"${sed_script}"
find "${CONFIG_DIR}" -type f -name '*.conf' \
-exec sed -i -f "${sed_script}" {} +
find "${CONFIG_DIR}" -type f -exec chmod 600 {} +
)
置換前の値が残っていないことを確認します。何も表示されなければ完了です。
rg -n '<INDEXER_CLUSTER_SECRET>|<SHC_SECRET>|example\.com' "${CONFIG_DIR}"
設定ファイルを配布する
1. ホスト別のアーカイブを作成する
設定ファイルからホスト別のtarとSHA-256ファイルをsplunk/config-archivesへ作成します。
bash splunk/procedures/04-config-distribution/create_config_archives.sh
2. アーカイブと配布スクリプトをS3へ配置する
<...>を利用する環境の値へ置き換えます。
AWS_PROFILE='<AWS_PROFILE>'
DEPLOYMENT_REGION='<DEPLOYMENT_REGION>'
DEPLOYMENT_BUCKET='<DEPLOYMENT_BUCKET>'
DEPLOYMENT_ENVIRONMENT='<DEPLOYMENT_ENVIRONMENT>'
1つ目のコマンドで設定アーカイブを、2つ目で各EC2へ設定を展開するスクリプトを非公開S3バケットへアップロードします。
aws s3 cp splunk/config-archives/ \
"s3://${DEPLOYMENT_BUCKET}/splunk/config/" \
--recursive \
--exclude '*' \
--include '*.tar' \
--include '*.tar.sha256' \
--profile "${AWS_PROFILE}" \
--region "${DEPLOYMENT_REGION}"
aws s3 cp \
splunk/procedures/04-config-distribution/apply_config_archive.sh \
"s3://${DEPLOYMENT_BUCKET}/splunk/scripts/apply-config-archive.sh" \
--profile "${AWS_PROFILE}" \
--region "${DEPLOYMENT_REGION}"
アーカイブにはpass4SymmKeyが含まれるため、GitHubへ追加せず、非公開S3バケットへ配置します。
3. Run Commandの入力ファイルを作成する
send-command.example.jsonから入力ファイルを作成し、S3バケットとリージョンを実行環境の値へ置き換えます。
SEND_COMMAND_JSON=splunk/procedures/04-config-distribution/send-command.json
if [[ ! "${DEPLOYMENT_ENVIRONMENT}" =~ ^[A-Za-z0-9-]+$ ]]; then
echo 'DEPLOYMENT_ENVIRONMENT must contain only letters, numbers, and hyphens.' >&2
exit 1
fi
sed \
-e "s|<DEPLOYMENT_BUCKET>|${DEPLOYMENT_BUCKET}|g" \
-e "s|<ENVIRONMENT>|${DEPLOYMENT_ENVIRONMENT}|g" \
-e "s|DEPLOYMENT_REGION=[^ ]*|DEPLOYMENT_REGION=${DEPLOYMENT_REGION}|g" \
-e "s|--region [a-z0-9-]*|--region ${DEPLOYMENT_REGION}|g" \
splunk/procedures/04-config-distribution/send-command.example.json \
>"${SEND_COMMAND_JSON}"
4. 設定ファイルを一括配布する
Run Commandを送信し、Command IDを保存します。
COMMAND_ID=$(aws ssm send-command \
--cli-input-json "file://${SEND_COMMAND_JSON}" \
--query 'Command.CommandId' \
--output text \
--profile "${AWS_PROFILE}" \
--region "${DEPLOYMENT_REGION}")
printf 'Command ID: %s\n' "${COMMAND_ID}"
EnvironmentタグとSplunkRoleタグの両方に一致するEC2が、ホスト名に対応するアーカイブを取得します。SHA-256を確認して/opt/splunk/etcへ展開した後、splunk btool checkを実行します。
実行結果を確認する
aws ssm list-command-invocations \
--command-id "${COMMAND_ID}" \
--details \
--query 'CommandInvocations[*].{InstanceId:InstanceId,Status:Status,ResponseCode:CommandPlugins[0].ResponseCode}' \
--output table \
--profile "${AWS_PROFILE}" \
--region "${DEPLOYMENT_REGION}"
送信直後はPendingまたはInProgressと表示されます。時間を置いて再実行し、すべての対象がSuccess、ResponseCodeが0になれば配布完了です。
Splunkを一括再起動する
設定配布が7台すべて成功したことを確認してから、Splunkを一括再起動します。今回はインストール直後でクラスタ運用を開始していないため、MaxConcurrencyを100%にします。運用開始後は、クラスタ状態を確認して役割ごとに再起動してください。
RESTART_COMMAND_ID=$(aws ssm send-command \
--document-name AWS-RunShellScript \
--targets \
"Key=tag:Environment,Values=${DEPLOYMENT_ENVIRONMENT}" \
'Key=tag:SplunkRole,Values=shc-member,mgmt,cluster-manager,indexer-peer' \
--parameters \
'commands=["set -euo pipefail","systemctl restart Splunkd.service","for attempt in {1..60}; do if systemctl is-active --quiet Splunkd.service && /opt/splunk/bin/splunk status >/dev/null 2>&1; then echo Splunk-ready; exit 0; fi; sleep 5; done; systemctl status Splunkd.service --no-pager -l; exit 1"]' \
--comment 'Restart Splunk after initial configuration distribution' \
--timeout-seconds 600 \
--max-concurrency '100%' \
--max-errors '0' \
--query 'Command.CommandId' \
--output text \
--profile "${AWS_PROFILE}" \
--region "${DEPLOYMENT_REGION}")
printf 'Restart Command ID: %s\n' "${RESTART_COMMAND_ID}"
Splunkはsystemdの起動直後もプロセス初期化を続けることがあります。このコマンドでは最大5分間、Splunkd.serviceとsplunk statusの両方が正常になるまで待機します。
ライセンスを設定する
managementホストをlicense managerとして利用します。
- CloudFormationの出力
MgmtSplunkWebUrlをブラウザで開き、adminでログインする - Settings > Licensing > Add licenseを開く
- ライセンスファイルを選択するか、ライセンスXMLを貼り付けてInstallを選択する
- Settings > Licensingに追加したライセンスが表示されることを確認する
- Settings > Server controls > Restart Splunkを選択し、managementホストを再起動する
初回のEnterpriseライセンス追加時に表示されるRestart required by handler '/services/licenser/licenses', method 'POST'.は、ライセンス登録の失敗ではなく、再起動が必要であることを示す通知です。Splunk Webから再起動できない場合は、前節のRun Commandをmanagementホストだけに実行します。
他のホストはserver.confの[license]でmanagementホストを参照するため、Splunk Webで個別にライセンスを追加する必要はありません。
開発者用ライセンスはSplunk Developerから申請できます。
Search Head Clusterをbootstrapする
shc-1とshc-2のserver.confにはSearch Head Cluster設定を配布済みです。そのため、今回の手順ではsplunk init shcluster-configを実行せず、captainのbootstrapだけを行います。
AWS Systems ManagerのFleet Manager > Managed nodesでshc-1を選択し、Node actions > Start terminal sessionからターミナルを開きます。
hostname -f
PRIVATE_ZONE_NAME=$(hostname -d)
read -rsp 'Splunk admin password: ' SPLUNK_ADMIN_PASSWORD
printf '\n'
sudo -u splunk /opt/splunk/bin/splunk bootstrap shcluster-captain \
-servers_list \
"https://shc-1.${PRIVATE_ZONE_NAME}:8089,https://shc-2.${PRIVATE_ZONE_NAME}:8089" \
-auth "admin:${SPLUNK_ADMIN_PASSWORD}"
sudo -u splunk /opt/splunk/bin/splunk show shcluster-status \
--verbose \
-auth "admin:${SPLUNK_ADMIN_PASSWORD}"
unset SPLUNK_ADMIN_PASSWORD
hostname -fがshc-1.<PrivateZoneName>であることを確認してから実行します。bootstrapコマンドにSuccessfully bootstrapped this node as the captain with the given servers.と表示され、次の状態を満たせば構成完了です。
- captainの
initialized_flagとservice_ready_flagが1 -
shc-1とshc-2のstatusがUp - 両memberの
restart_requiredが0
この2台構成は学習・機能確認用です。高可用性を備えたSearch Head Clusterでは3台以上のmemberを使用してください。
Splunk Webで正常性を確認する
CloudFormationのパラメーターに指定した各レコード名を使い、次の画面を確認します。
| 確認対象 | URL | 最低限確認する状態 |
|---|---|---|
| Monitoring Console | https://<MgmtAlbRecordName>/ja-JP/app/splunk_monitoring_console/monitoringconsole_overview |
監視対象のSplunkインスタンスに重大なエラーがない |
| Indexer Cluster | https://<CmAlbRecordName>/ja-JP/manager/system/clustering |
Cluster Managerと3台のpeer nodeが稼働し、Replication FactorとSearch Factorを満たしている |
| Search Head Cluster | https://<AlbRecordName>/ja-JP/manager/system/search_head_clustering |
captainが選出され、shc-1とshc-2が稼働している |
最後に、Search HeadのSearch & Reporting画面で次の検索を実行し、直近の内部ログを7ホスト分確認します。
index="_internal"
| stats latest(_time) AS latest BY host
| convert ctime(latest)
まとめ
おつかれさまでした。
本記事では、ホスト別configの一括配布、Splunkの再起動、ライセンス登録、Search Head Clusterのbootstrap、Splunk Webでの正常性確認まで実施しました。
筆者の検証では、前提となるAWSリソースが揃っている状態でも、一連の作業に約1時間を要しました。手順を再現可能な形で残しておくことで、次回以降の検証環境を準備しやすくなります。
Splunkを活用する際は、基盤構築そのものよりも、Appの設定、データの取り込み、CIMへの対応などに注力したい場面が多いと考えています。本記事が環境準備の負担を減らし、データを使った検証へ早く着手するための参考になれば幸いです。