Skip to content

Commit 8e6fafc

Browse files
amierzwickikush982
andauthored
DEVPROD-3811 Added support for OpenSearch for Jira. (#1099)
Co-authored-by: Kushagra Shandilya <kshandilya@atlassian.com>
1 parent f42a34c commit 8e6fafc

18 files changed

Lines changed: 692 additions & 4 deletions

File tree

‎.github/workflows/kind.yaml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ jobs:
8585
sleep 10
8686
kubectl wait --for=condition=ready pod/${DC_APP}-1 -n atlassian --timeout=360s
8787
88+
- name: Verify ${{inputs.dc_app}} OpenSearch integration
89+
run: |
90+
source src/test/scripts/kind/deploy_app.sh
91+
verify_opensearch
92+
8893
- name: Verify ${{inputs.dc_app}} metrics availability
8994
run: |
9095
source src/test/scripts/kind/deploy_app.sh

‎docs/docs/containers/JIRA.md‎

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,55 @@ information, please refer to
219219

220220
Override the default AWS API endpoint with a custom one (optional).
221221

222+
### OpenSearch configuration
223+
224+
Starting with Jira 11.2, you can configure Jira to use OpenSearch as the search platform.
225+
For the full list of available OpenSearch properties and requirements, see
226+
[Configuring OpenSearch for Jira](https://confluence.atlassian.com/adminjiraserver/configuring-opensearch-for-jira-1620511851.html).
227+
228+
OpenSearch properties are injected into `jira-config.properties` using
229+
`ADDITIONAL_JIRA_CONFIG_*` environment variables (see
230+
[Custom `jira-config.properties`](#custom-jira-configproperties) for details on
231+
the mechanism).
232+
233+
The minimum required properties are:
234+
235+
* `search.platform`
236+
237+
The search platform to use. Set to `opensearch` to enable OpenSearch.
238+
239+
* `opensearch.http.url`
240+
241+
HTTP(S) URL of the OpenSearch cluster, or multiple URLs separated by commas.
242+
243+
* `opensearch.username`
244+
245+
Username for the OpenSearch cluster.
246+
247+
* `opensearch.password`
248+
249+
Password for the OpenSearch cluster.
250+
251+
The `__EXPAND_ENV` suffix lets you keep the password in a separate environment
252+
variable rather than embedding it directly in the property line. In the example
253+
below `MY_OPENSEARCH_PASSWORD` is passed inline for brevity:
254+
255+
```bash
256+
docker run \
257+
-e MY_OPENSEARCH_PASSWORD=my-secret \
258+
-e ADDITIONAL_JIRA_CONFIG_01="search.platform=opensearch" \
259+
-e ADDITIONAL_JIRA_CONFIG_02="opensearch.http.url=http://opensearch-host:9200" \
260+
-e ADDITIONAL_JIRA_CONFIG_03="opensearch.username=admin" \
261+
-e ADDITIONAL_JIRA_CONFIG_04__EXPAND_ENV="opensearch.password={MY_OPENSEARCH_PASSWORD}" \
262+
atlassian/jira-software:latest
263+
```
264+
265+
!!! warning "Sensitive values on the command line"
266+
Passing secrets via `-e` exposes them in shell history, process listings,
267+
and `docker inspect` output. In production, use `--env-file` with a
268+
permission-protected file or an external secrets manager to supply
269+
`MY_OPENSEARCH_PASSWORD`.
270+
222271
### S3 Attachments storage configuration
223272
Starting with Jira 9.9, you can configure Jira to [store attachment files in Amazon S3](https://confluence.atlassian.com/adminjiraserver/storing-attachments-in-amazon-s3-1282250191.html). For requirements and additional
224273
information, please refer to [Configuring Amazon S3 Object Storage](https://confluence.atlassian.com/pages/viewpage.action?spaceKey=JSERVERM&title=.Configuring+Amazon+S3+object+storage+vJira_admin_9.9).
@@ -523,6 +572,85 @@ as a non-root user.
523572

524573
The default Tomcat session timeout (in minutes) for all newly created sessions which is set in web.xml. Defaults to 30.
525574

575+
### Custom `jira-config.properties`
576+
577+
Additional properties can be injected into `jira-config.properties` using
578+
environment variables prefixed with `ADDITIONAL_JIRA_CONFIG_`.
579+
580+
Each variable's value must be a complete property line in `key=value` format.
581+
Environment variable names are sorted for consistent file generation; order has
582+
no effect on runtime behavior.
583+
584+
```bash
585+
docker run \
586+
-e ADDITIONAL_JIRA_CONFIG_01="jira.websudo.is.disabled=true" \
587+
-e ADDITIONAL_JIRA_CONFIG_02="jira.lf.top.bgcolour=#003366" \
588+
atlassian/jira-software:latest
589+
```
590+
591+
#### How properties are written
592+
593+
The properties are written to a clearly marked auto-generated section at the end
594+
of the file. Any manually added content outside this section is preserved across
595+
container restarts.
596+
597+
#### Injecting secrets via `__EXPAND_ENV`
598+
599+
For values that reference secrets stored in separate environment variables
600+
(common in Kubernetes where secrets are mounted as env vars), use the
601+
`__EXPAND_ENV` suffix. Placeholders in `{VAR_NAME}` format are replaced with
602+
the corresponding environment variable value at startup:
603+
604+
```bash
605+
docker run \
606+
-e MY_OPENSEARCH_PASSWORD=my-secret \
607+
-e ADDITIONAL_JIRA_CONFIG_01="search.platform=opensearch" \
608+
-e ADDITIONAL_JIRA_CONFIG_02__EXPAND_ENV="opensearch.password={MY_OPENSEARCH_PASSWORD}" \
609+
atlassian/jira-software:latest
610+
```
611+
612+
This generates the following in `jira-config.properties`:
613+
614+
```properties
615+
# ---- AUTO GENERATED ADDITIONAL PROPERTIES FROM DOCKER IMAGE ---
616+
# DO NOT MODIFY this section - it is auto-generated during container startup
617+
# from ADDITIONAL_JIRA_CONFIG_* environment variables
618+
search.platform=opensearch
619+
opensearch.password=my-secret
620+
# ---- END OF AUTO GENERATED ADDITIONAL PROPERTIES ---
621+
```
622+
623+
If a referenced environment variable is not set, the placeholder is left
624+
unchanged and a warning is logged.
625+
626+
#### Limitations and requirements
627+
628+
* **Local home directory only**: `jira-config.properties` is written to
629+
`$JIRA_HOME` which must be the node-local home directory (not shared storage).
630+
Using `ADDITIONAL_JIRA_CONFIG_*` when `jira-config.properties` is stored on a
631+
shared filesystem (e.g. NFS, EFS) may cause unexpected outcomes due to update
632+
races across different container instances during rolling deployments.
633+
634+
* **Read-only mounts not supported**: If `jira-config.properties` is mounted as
635+
a read-only file (e.g. via a Kubernetes ConfigMap volume mount), the
636+
`ADDITIONAL_JIRA_CONFIG_*` variables will have no effect. A warning is logged
637+
in this case. Manage the file content entirely through the mount instead — do
638+
not combine both approaches.
639+
640+
* **Auto-generated section**: The generated properties are placed inside clearly
641+
marked comment boundaries at the end of the file. Manual edits outside these
642+
markers are preserved. Do not edit content within the markers — it will be
643+
overwritten on the next container startup.
644+
645+
| Aspect | Detail |
646+
|-------------------------|-------------------------------------------------------------|
647+
| Env var prefix | `ADDITIONAL_JIRA_CONFIG_` |
648+
| Secret expansion suffix | `__EXPAND_ENV` (double underscore) |
649+
| Target file | `$JIRA_HOME/jira-config.properties` |
650+
| Ordering | Sorted for reproducibility; order has no effect on behavior |
651+
| Existing content | Preserved (only auto-generated section is replaced) |
652+
| No matching env vars | File is not created; stale section is removed if present |
653+
526654
### Advanced Configuration
527655

528656
As mentioned at the top of this section, the settings from the environment are

‎docs/docs/examples/.pages‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ nav:
88
- bamboo
99
- bitbucket
1010
- confluence
11+
- jira
1112
- logging
1213
- ...

‎docs/docs/examples/jira/.pages‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
collapse_single_pages: false
2+
nav:
3+
- JIRA_OPENSEARCH.md
4+
- ...
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Configuring OpenSearch for Jira
2+
3+
!!!info "Jira and Helm chart version"
4+
OpenSearch is supported in Jira 11.2 and Helm chart 2.0.10 onwards.
5+
6+
As Jira instances grow in size and scale, the default search engine, Lucene, may be slower to index and return search results. To address this, Jira Data Center offers an alternative search engine as an opt-in feature — OpenSearch.
7+
8+
## Deploy OpenSearch Helm Chart with Jira
9+
10+
!!!warning "Support disclaimer"
11+
Atlassian does not officially support OpenSearch Helm chart that can be installed with the Jira Helm release. Should you encounter any issues with the deployment, maintenance and upgrades, reach out to the [vendor](https://github.com/opensearch-project/helm-charts/tree/main/charts/opensearch){.external}.
12+
Moreover, if you intend to deploy OpenSearch to a critical Kubernetes environment, make sure you follow all the best practices, i.e. deploy a multi node cluster, use taints and tolerations, affinity rules, sufficient resources requests, have DR and backup strategies etc.
13+
14+
## Deploy with the default settings
15+
16+
To deploy OpenSearch Helm chart and automatically configure Jira to use it as a search platform, set the following in your Helm values file:
17+
18+
```yaml
19+
opensearch:
20+
enabled: true
21+
```
22+
This will:
23+
24+
* auto-generate the initial OpenSearch admin password and create a Kubernetes secret with `OPENSEARCH_INITIAL_ADMIN_PASSWORD` key
25+
* deploy [OpenSearch Helm chart](https://github.com/opensearch-project/helm-charts/tree/main/charts/opensearch){.external} to the target namespace with the default settings: single node, 1Gi memory/1 vCPU resources requests, 10Gi storage request
26+
* configure Jira to use the deployed OpenSearch cluster by setting opensearch properties, which are written to `jira-config.properties` at startup. The following properties are configured: `search.platform=opensearch`, `opensearch.http.url=http://opensearch-cluster-master:9200`, `opensearch.username=admin`, and `opensearch.password`.
27+
28+
## Override OpenSearch Helm chart values
29+
30+
You can configure your OpenSearch cluster and the deployment options by overriding any values that the [Helm chart](https://github.com/opensearch-project/helm-charts/blob/main/charts/opensearch/values.yaml){.external} exposes. OpenSearch values must be nested under `opensearch` stanza in your Helm values file, for example:
31+
32+
```yaml
33+
opensearch:
34+
singleNode: false
35+
replicas: 5
36+
config:
37+
opensearch.yml: |
38+
cluster.name: opensearch-cluster
39+
```
40+
41+
## Use an existing OpenSearch secret
42+
43+
If you have a pre-created Kubernetes secret with the OpenSearch admin password, you can reference it instead of having the chart auto-generate one:
44+
45+
```yaml
46+
opensearch:
47+
enabled: true
48+
credentials:
49+
createSecret: false
50+
existingSecretRef:
51+
name: my-opensearch-secret
52+
```
53+
54+
The secret must contain a key named `OPENSEARCH_INITIAL_ADMIN_PASSWORD`.
55+
56+
## Connect to an external OpenSearch instance
57+
58+
If you already have an OpenSearch cluster running outside of Kubernetes (or
59+
managed separately), you can configure Jira to use it without deploying the
60+
bundled OpenSearch Helm chart. OpenSearch properties are written to
61+
`jira-config.properties` at container startup via the
62+
`additionalConfigProperties` mechanism (see
63+
[Additional config properties](../../userguide/CONFIGURATION.md#additional-config-properties)).
64+
65+
First, create a Kubernetes Secret containing the OpenSearch password:
66+
67+
```bash
68+
kubectl create secret generic opensearch-credentials \
69+
--from-literal=password='<your-opensearch-password>'
70+
```
71+
72+
Then reference it in your Helm values file. The `additionalEnvironmentVariables`
73+
entry injects the secret as an environment variable, and
74+
`additionalConfigPropertiesExpandEnv` expands it into the property value at
75+
startup:
76+
77+
```yaml
78+
jira:
79+
additionalEnvironmentVariables:
80+
- name: MY_OPENSEARCH_PASSWORD
81+
valueFrom:
82+
secretKeyRef:
83+
name: opensearch-credentials
84+
key: password
85+
86+
additionalConfigProperties:
87+
- "search.platform=opensearch"
88+
- "opensearch.http.url=http://opensearch-host:9200"
89+
- "opensearch.username=admin"
90+
91+
additionalConfigPropertiesExpandEnv:
92+
- "opensearch.password={MY_OPENSEARCH_PASSWORD}"
93+
```
94+
95+
For the full list of available OpenSearch properties, see
96+
[Configuring OpenSearch for Jira](https://confluence.atlassian.com/adminjiraserver/configuring-opensearch-for-jira-1620511851.html){.external}.

‎docs/docs/userguide/CONFIGURATION.md‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,58 @@ jira:
461461
* dash `-` becomes underscore `_`
462462
* Example: `this.new-property` becomes `THIS_NEW_PROPERTY`
463463

464+
## :material-book-cog: Additional config properties
465+
466+
!!!info "Jira only"
467+
This feature is currently available for Jira only. It requires a Jira
468+
container image version that supports the `ADDITIONAL_JIRA_CONFIG_*`
469+
environment variables. See the
470+
[Docker image documentation](../containers/JIRA.md#custom-jira-configproperties)
471+
for full details on the underlying mechanism.
472+
473+
The Helm chart provides dedicated values for injecting properties into
474+
`jira-config.properties` without constructing environment variable names
475+
manually:
476+
477+
```yaml
478+
jira:
479+
additionalConfigProperties:
480+
- "jira.websudo.is.disabled=true"
481+
- "jira.lf.top.bgcolour=#003366"
482+
```
483+
484+
These are equivalent to setting `ADDITIONAL_JIRA_CONFIG_*` environment
485+
variables directly. The values can also be set via `--set`:
486+
487+
```bash
488+
helm install jira atlassian-data-center/jira \
489+
--set 'jira.additionalConfigProperties[0]=jira.websudo.is.disabled=true'
490+
```
491+
492+
### Injecting secrets
493+
494+
For values that reference Kubernetes Secrets (e.g. passwords), use
495+
`additionalConfigPropertiesExpandEnv`. Placeholders in `{VAR_NAME}` format are
496+
replaced with the corresponding environment variable value at container
497+
startup:
498+
499+
```yaml
500+
jira:
501+
additionalEnvironmentVariables:
502+
- name: MY_SECRET
503+
valueFrom:
504+
secretKeyRef:
505+
name: my-k8s-secret
506+
key: password
507+
508+
additionalConfigPropertiesExpandEnv:
509+
- "some.password={MY_SECRET}"
510+
```
511+
512+
Alternatively, you can use `jira.additionalEnvironmentVariables` to pass the
513+
`ADDITIONAL_JIRA_CONFIG_*` environment variables explicitly if you need full
514+
control over naming.
515+
464516
## :material-book-cog: Additional libraries & plugins
465517

466518
The products' Docker images contain the default set of bundled libraries and plugins.

‎src/main/charts/jira/Chart.lock‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,8 @@ dependencies:
22
- name: common
33
repository: https://atlassian.github.io/data-center-helm-charts
44
version: 1.2.7
5-
digest: sha256:6dc6e131380a4f43edcaae60ee0f8341a463013d8460bd657ca798139d4f428a
6-
generated: "2024-09-10T03:31:09.693286348Z"
5+
- name: opensearch
6+
repository: https://opensearch-project.github.io/helm-charts
7+
version: 3.5.0
8+
digest: sha256:1bd020af24c471b52a62f6b9330a0f1d94e27a60087fa48d6f1f152e91bec9ea
9+
generated: "2026-03-13T14:50:45.468195+01:00"

‎src/main/charts/jira/Chart.yaml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,7 @@ dependencies:
2828
- name: common
2929
version: 1.2.7
3030
repository: https://atlassian.github.io/data-center-helm-charts
31+
- name: opensearch
32+
version: 3.5.0
33+
repository: https://opensearch-project.github.io/helm-charts
34+
condition: opensearch.enabled

0 commit comments

Comments
 (0)