Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/ADVANCED.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,19 @@ Splunk-Ansible ships with an inventory script in `inventory/environ.py`. The scr
| SPLUNK_ES_SSL_ENABLEMENT | Set the ssl-enablement flag in ES. Valid values are 'auto', 'strict', and 'ignore'. Defaults to auto when present. | no | no | no |
| SPLUNK_SERVICE_NAME | Used alongside `POD_NAMESPACE` and `CLUSTER_DOMAIN` to construct a k8s-supported `issuer_uri` value for oauth2 configurations | no | no | no |
| SPLUNK_HEADLESS_SERVICE_NAME | Used alongside `POD_NAME`, `POD_NAMESPACE`, and `CLUSTER_DOMAIN` to construct a k8s-supported `serverName` value. This is also used for the `search_head_uri` and `register_replication_address` settings when clustering is enabled. | no | no | no |
| SPLUNK_NOAH_ENABLED | Explicitly enables Noah-specific provisioning for supported indexer, search-head, and deployer roles. Defaults to `false`; a `noahService` stanza alone does not enable Noah mode. | no | no | no |
| POD_NAME | Defines the current pod name in a k8s environment | no | no | no |
| POD_NAMESPACE | Defines the namespace of the current pod in a k8s environment | no | no | no |
| CLUSTER_DOMAIN | Defines the domain name for DNS resolution in a k8s cluster (default: cluster.local) | no | no | no |

For Linux search-head cluster members, Ansible now writes the SHC member,
replication-listener, stable server-name, and (for classic deployments)
Cluster Manager peering configuration while splunkd is stopped. This applies
to both classic and Noah deployments. The later SHC commands still form and
verify the cluster, but they do not request duplicate restarts when the
effective pre-start configuration already matches. If splunkd is already
running, Ansible keeps the established live-configuration and restart path.

\* Password must be set either in `default.yml` or as the environment variable `SPLUNK_PASSWORD`

#### Additional Splunk Universal Forwarder variables
Expand Down
18 changes: 17 additions & 1 deletion inventory/environ.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ def getDefaultVars():
defaultVars = loadDefaults()
defaultVars["splunk"]["role"] = os.environ.get('SPLUNK_ROLE', defaultVars["splunk"].get("role") or "splunk_standalone")
overrideEnvironmentVars(defaultVars)
getNoah(defaultVars)
getAnsibleContext(defaultVars)
getASan(defaultVars)
getDisablePopups(defaultVars)
Expand Down Expand Up @@ -192,7 +193,22 @@ def getServiceName(vars_scope):
if serviceName != "" and namespace != "":
vars_scope["splunk"]["issuer_uri"] = "{}.{}.svc.{}".format(serviceName, namespace, clusterDomain)
if headlessServiceName != "" and namespace != "":
vars_scope["splunk"]["server_name"] = "{}.{}.{}.svc.{}".format(podName, headlessServiceName, namespace, clusterDomain)
server_name = "{}.{}.{}.svc.{}".format(podName, headlessServiceName, namespace, clusterDomain)
vars_scope["splunk"]["server_name"] = server_name
if vars_scope.get("splunk_noah_enabled", False):
vars_scope["splunk"]["noah_advertised_addr"] = "https://{}:{}".format(server_name, vars_scope["splunk"]["svc_port"])

def getNoah(vars_scope):
"""Enable Noah provisioning only when explicitly requested."""
value = os.environ.get("SPLUNK_NOAH_ENABLED", vars_scope.get("splunk_noah_enabled", False))
if isinstance(value, bool):
vars_scope["splunk_noah_enabled"] = value
return

normalized = str(value).strip().lower()
if normalized not in ("true", "false"):
raise ValueError("SPLUNK_NOAH_ENABLED must be either 'true' or 'false'")
vars_scope["splunk_noah_enabled"] = normalized == "true"

def getSplunkPaths(vars_scope):
"""
Expand Down
1 change: 1 addition & 0 deletions inventory/splunk_defaults_linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ retry_num: 60
hide_password: false
wait_for_splunk_retry_num: 60
shc_sync_retry_num: 60
splunk_noah_enabled: false

config:
max_retries: 3
Expand Down
25 changes: 23 additions & 2 deletions roles/splunk_common/handlers/restart_splunk.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
---
- name: "Restart the splunkd service - Via CLI"
- name: "Restart Noah-managed splunkd - Via bounded CLI stop and start"
shell: |
set -e
if {{ splunk.exec }} status >/dev/null 2>&1; then
{{ splunk.exec }} stop --answer-yes
fi
{{ splunk.exec }} start --answer-yes --accept-license
args:
executable: /bin/sh
become: yes
become_user: "{{ splunk.user }}"
register: task_result
until: task_result.rc == 0
retries: "{{ retry_num }}"
delay: "{{ restart_retry_delay }}"
when:
- not splunk.enable_service
- splunk_noah_enabled | default(false) | bool

- name: "Restart classic splunkd service - Via CLI"
command: "{{ splunk.exec }} restart --answer-yes --accept-license"
become: yes
become_user: "{{ splunk.user }}"
register: task_result
until: task_result.rc == 0
retries: "{{ retry_num }}"
delay: "{{ restart_retry_delay }}"
when: not splunk.enable_service
when:
- not splunk.enable_service
- not (splunk_noah_enabled | default(false) | bool)

- name: "Restart the splunkd service - Via Linux systemd or init"
service:
Expand Down
69 changes: 69 additions & 0 deletions roles/splunk_common/tasks/configure_deployer_prestart.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
- name: Validate pre-start SHC deployer configuration inputs
assert:
that:
- splunk.shc.pass4SymmKey | default("") | length > 0
- splunk.shc.label | default("") | length > 0
fail_msg: >-
Pre-start SHC deployer configuration requires the SHC label and shared
symmetric key.
no_log: true

- name: Create the local Splunk configuration directory for the SHC deployer
file:
path: "{{ splunk.home }}/etc/system/local"
state: directory
mode: 0770
owner: "{{ splunk.user }}"
group: "{{ splunk.group }}"
become: yes
become_user: "{{ splunk.user }}"

- name: Configure the SHC deployer before the first splunkd start
ini_file:
path: "{{ splunk.home }}/etc/system/local/server.conf"
section: "shclustering"
option: "{{ item.option }}"
value: "{{ item.value }}"
allow_no_value: false
state: present
mode: 0660
owner: "{{ splunk.user }}"
group: "{{ splunk.group }}"
loop:
- option: "pass4SymmKey"
value: "{{ splunk.shc.pass4SymmKey }}"
- option: "shcluster_label"
value: "{{ splunk.shc.label }}"
loop_control:
label: "{{ item.option }}"
become: yes
become_user: "{{ splunk.user }}"
no_log: true

- name: Read effective pre-start SHC deployer configuration
command:
argv:
- "{{ splunk.exec }}"
- "btool"
- "server"
- "list"
- "shclustering"
- "--no-log"
register: deployer_prestart_btool
changed_when: false
become: yes
become_user: "{{ splunk.user }}"
no_log: true

- name: Validate effective pre-start SHC deployer configuration
assert:
that:
- (deployer_prestart_btool.stdout | regex_search("(?m)^pass4SymmKey\\s*=\\s*\\S+\\s*$")) is not none
- ("shcluster_label = " ~ splunk.shc.label) in deployer_prestart_btool.stdout
fail_msg: "Effective pre-start SHC deployer configuration does not match the requested SHC."
no_log: true

- name: Record declarative SHC deployer pre-start configuration
set_fact:
deployer_prestart_configured: true
186 changes: 186 additions & 0 deletions roles/splunk_common/tasks/configure_shc_prestart.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
---
- name: Set expected pre-start SHC configuration
set_fact:
shc_prestart_server_name: "{{ splunk.server_name | default(splunk.hostname, true) }}"
shc_prestart_mgmt_uri: "{{ cert_prefix }}://{{ splunk.hostname }}:{{ splunk.svc_port }}"
shc_prestart_deployer_uri: "{{ cert_prefix }}://{{ splunk.deployer_url }}:{{ splunk.svc_port }}"
shc_prestart_server_conf: "{{ splunk.home }}/etc/system/local/server.conf"
shc_prestart_indexer_peer_enabled: >-
{{
not (splunk_noah_enabled | default(false) | bool)
and (splunk_indexer_cluster | bool)
and (splunk.multisite_master is not defined)
and (splunk.set_search_peers | default(false) | bool)
}}

- name: Validate pre-start SHC configuration inputs
assert:
that:
- cert_prefix in ["http", "https"]
- shc_prestart_server_name | length > 0
- splunk.hostname | default("") | length > 0
- splunk.deployer_url | default("") | length > 0
- splunk.shc.pass4SymmKey | default("") | length > 0
- splunk.shc.replication_factor | int > 0
- splunk.shc.replication_port | int > 0
- splunk.shc.replication_port | int <= 65535
- splunk.shc.replication_port | int != splunk.svc_port | int
- splunk.shc.replication_port | int != splunk.http_port | int
- splunk.shc.replication_port | int != splunk.s2s.port | int
- splunk.shc.replication_port | int != splunk.kvstore.port | int
fail_msg: >-
Pre-start SHC configuration requires stable identity, valid non-conflicting
ports, a deployer endpoint, replication factor, and shared secret.
no_log: true

- name: Validate classic pre-start indexer peering inputs
assert:
that:
- splunk.cluster_master_url | default("") | length > 0
- splunk.idxc.pass4SymmKey | default("") | length > 0
fail_msg: >-
Classic SHC pre-start indexer peering requires a Cluster Manager endpoint
and indexer-cluster shared secret.
when: shc_prestart_indexer_peer_enabled | bool
no_log: true

- name: Create the local Splunk configuration directory
file:
path: "{{ splunk.home }}/etc/system/local"
state: directory
mode: 0770
owner: "{{ splunk.user }}"
group: "{{ splunk.group }}"
become: yes
become_user: "{{ splunk.user }}"

- name: Configure stable SHC identity before splunkd starts
ini_file:
path: "{{ shc_prestart_server_conf }}"
section: "general"
option: "serverName"
value: "{{ shc_prestart_server_name }}"
allow_no_value: false
state: present
mode: 0660
owner: "{{ splunk.user }}"
group: "{{ splunk.group }}"
become: yes
become_user: "{{ splunk.user }}"

- name: Configure SHC formation before splunkd starts
ini_file:
path: "{{ shc_prestart_server_conf }}"
section: "shclustering"
option: "{{ item.option }}"
value: "{{ item.value }}"
allow_no_value: false
state: present
mode: 0660
owner: "{{ splunk.user }}"
group: "{{ splunk.group }}"
loop:
- option: "disabled"
value: "false"
- option: "mgmt_uri"
value: "{{ shc_prestart_mgmt_uri }}"
- option: "replication_factor"
value: "{{ splunk.shc.replication_factor }}"
- option: "conf_deploy_fetch_url"
value: "{{ shc_prestart_deployer_uri }}"
- option: "shcluster_label"
value: "{{ splunk.shc.label }}"
- option: "register_replication_address"
value: "{{ shc_prestart_server_name }}"
- option: "search_head_uri"
value: "{{ shc_prestart_server_name }}"
become: yes
become_user: "{{ splunk.user }}"

- name: Write the SHC symmetric key before the first splunkd start
ini_file:
path: "{{ shc_prestart_server_conf }}"
section: "shclustering"
option: "pass4SymmKey"
value: "{{ splunk.shc.pass4SymmKey }}"
allow_no_value: false
state: present
mode: 0660
owner: "{{ splunk.user }}"
group: "{{ splunk.group }}"
when: first_run | bool
become: yes
become_user: "{{ splunk.user }}"
no_log: true

- name: Configure the SHC replication listener before splunkd starts
ini_file:
path: "{{ shc_prestart_server_conf }}"
section: "replication_port://{{ splunk.shc.replication_port }}"
option: "disabled"
value: "false"
allow_no_value: false
state: present
mode: 0660
owner: "{{ splunk.user }}"
group: "{{ splunk.group }}"
become: yes
become_user: "{{ splunk.user }}"

- name: Configure classic indexer-cluster peering before splunkd starts
ini_file:
path: "{{ shc_prestart_server_conf }}"
section: "clustering"
option: "{{ item.option }}"
value: "{{ item.value }}"
allow_no_value: false
state: present
mode: 0660
owner: "{{ splunk.user }}"
group: "{{ splunk.group }}"
loop:
- option: "mode"
value: "searchhead"
- option: "master_uri"
value: "{{ cert_prefix }}://{{ splunk.cluster_master_url }}:{{ splunk.svc_port }}"
- option: "pass4SymmKey"
value: "{{ splunk.idxc.pass4SymmKey }}"
when: shc_prestart_indexer_peer_enabled | bool
become: yes
become_user: "{{ splunk.user }}"
no_log: true

- name: Read effective pre-start SHC configuration
command:
argv:
- "{{ splunk.exec }}"
- "btool"
- "server"
- "list"
- "--no-log"
register: shc_prestart_btool
changed_when: false
become: yes
become_user: "{{ splunk.user }}"
no_log: true

- name: Validate effective pre-start SHC configuration
assert:
that:
- (shc_prestart_btool.stdout | regex_search("(?m)^serverName\\s*=\\s*" ~ (shc_prestart_server_name | regex_escape) ~ "\\s*$")) is not none
- (shc_prestart_btool.stdout | regex_search("(?m)^disabled\\s*=\\s*(0|false)\\s*$")) is not none
- ("mgmt_uri = " ~ shc_prestart_mgmt_uri) in shc_prestart_btool.stdout
- ("replication_factor = " ~ (splunk.shc.replication_factor | string)) in shc_prestart_btool.stdout
- ("conf_deploy_fetch_url = " ~ shc_prestart_deployer_uri) in shc_prestart_btool.stdout
- (shc_prestart_btool.stdout | regex_search("(?m)^pass4SymmKey\\s*=\\s*\\S+\\s*$")) is not none
- ("register_replication_address = " ~ shc_prestart_server_name) in shc_prestart_btool.stdout
- ("search_head_uri = " ~ shc_prestart_server_name) in shc_prestart_btool.stdout
- ("[replication_port://" ~ (splunk.shc.replication_port | string) ~ "]") in shc_prestart_btool.stdout
fail_msg: "Effective pre-start SHC configuration does not match the requested member configuration."
no_log: true

- name: Record declarative SHC pre-start configuration
set_fact:
shc_prestart_configured: true
shc_prestart_defer_initial_restart: true
shc_prestart_indexer_peer_configured: "{{ shc_prestart_indexer_peer_enabled | bool }}"
Loading