Skip to content

Commit

Permalink
feat: helm enable external secrets (#16)
Browse files Browse the repository at this point in the history
* ops(helm): add support to use external secrets

* docs: updated documentation regarding helm

* Update README.md

Co-authored-by: Ricardo Lopes <ricardoapl.dev@gmail.com>

---------

Co-authored-by: Ricardo Lopes <ricardoapl.dev@gmail.com>
  • Loading branch information
lufinima and ricardoapl authored Oct 16, 2024
1 parent c794cde commit 18d4eec
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 34 deletions.
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ repos:
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
exclude: ^deploy/helm/galaxy/
- id: check-json
- id: check-toml
- id: check-yaml
Expand Down
96 changes: 82 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,12 @@ And now you have obtained the plugin token to use during installation.
2. Create a `my_values.yaml` file (name isn't important) with the variables we need to setup on the chart, example below:

```yaml
integration:
type: gitlab

env:
RELY_API_TOKEN: the_rely_api_token
RELY_API_URL: https://magneto.rely.io
RELY_INTEGRATION_ID: "1234567"
RELY_INTEGRATION_TYPE: pagerduty

```

Expand All @@ -79,9 +80,8 @@ And now you have obtained the plugin token to use during installation.
```bash
helm upgrade --install relyio-galaxy \
--set env.RELY_API_TOKEN=the_rely_api_token \
--set env.RELY_API_URL=https://magneto.rely.io \
--set env.RELY_INTEGRATION_ID=1234567 \
--set env.RELY_INTEGRATION_TYPE=pagerduty \
--set integration.type=pagerduty \
oci://registry-1.docker.io/devrelyio/galaxy-helm \
-n rely-galaxy
```
Expand All @@ -102,9 +102,8 @@ or
```bash
helm upgrade relyio-galaxy \
--set env.RELY_API_TOKEN=the_rely_api_token \
--set env.RELY_API_URL=https://magneto.rely.io \
--set env.RELY_INTEGRATION_ID=1234567 \
--set env.RELY_INTEGRATION_TYPE=pagerduty \
--set integration.type=pagerduty \
oci://registry-1.docker.io/devrelyio/galaxy-helm \
-n rely-galaxy
```
Expand All @@ -123,9 +122,8 @@ or
```bash
helm upgrade relyio-galaxy \
--set env.RELY_API_TOKEN=the_rely_api_token \
--set env.RELY_API_URL=https://magneto.rely.io \
--set env.RELY_INTEGRATION_ID=1234567 \
--set env.RELY_INTEGRATION_TYPE=pagerduty \
--set integration.type=pagerduty \
oci://registry-1.docker.io/devrelyio/galaxy-helm \
-n rely-galaxy \
--version 1.0.0
Expand All @@ -137,19 +135,89 @@ helm upgrade relyio-galaxy \

Helm chart requires the following values to be set or it will fail to install:

- `env.RELY_API_URL`: The rely api url, ex: https://magneto.rely.io/
- `env.RELY_API_TOKEN`: Go to rely app and get the token for the plugin installation
- `env.RELY_INTEGRATION_TYPE`: The name of the integration, ex: gitlab
- `env.RELY_INTEGRATION_ID`: Go to rely app and get the rely integration installation id
- `integration.apiUrl`: The rely api url, ex: https://magneto.rely.io/
- `integration.type`: The name of the integration, ex: gitlab

These are the minimum values that need to be set for the framework to work. You can also set other values that are in the [`values.yaml`](deploy/helm/galaxy/values.yaml) file.

Additionally, you can set the following values:

- `env.RELY_INTEGRATION_EXECUTION_TYPE`: The execution type of the integration. The default value is `cronjob`. If you want to run the integration in daemon mode you need to set this value to `daemon`.
- `env.RELY_INTEGRATION_DAEMON_INTERVAL`: The interval in minutes that the integration will run in daemon mode. The default value is `60`.
- `integration.executionType`: The execution type of the integration. The default value is `cronjob`. If you want to run the integration in daemon mode you need to set this value to `daemon`.
- `integration.daemonInterval`: The interval in minutes that the integration will run in daemon mode. The default value is `60`.
- `schedule`: The cronjob schedule for the integration. The default value is `59 * * * *`.

###### External Secrets

If we use external secrets with [External Secrets Operator](https://external-secrets.io/) we need to set `externalSecrets.enabled` to `true` and set the `externalSecrets.target` to the name of the secret that contains the values for the `RELY_API_TOKEN` and `RELY_INTEGRATION_ID`. When we use external secrets we can set all values from the secret file set in `target` as env vars in the helm chart if we set `externalSecrets.allAsEnv` to `true`. If we don't set this value to `true` we need to set the values we want to use in the helm chart as env vars in the `envs` section.

Example of external secrets configuration in the `my_values.yaml` file when we want to set all values from the secret file as env vars in the helm chart:

```yaml
externalSecrets
enabled: true
target: my-external-secrets
allAsEnv: true
envs: []
```
Example of external secrets configuration in the `my_values.yaml` file when we want to set only the `RELY_API_TOKEN` and `RELY_INTEGRATION_ID` values from the secret file as env vars in the helm chart:

```yaml
externalSecrets
enabled: true
target: my-external-secrets
allAsEnv: false
envs:
- name: RELY_API_TOKEN
key: RELY_API_TOKEN
- name: RELY_INTEGRATION_ID
key: RELY_INTEGRATION_ID
```

The `envs` section is an array of objects that contains the `name` of the env var that we want to set in the helm chart and the `key` that is the key of the value in the secret file.

The creation of the external secrets are outside of the scope of this documentation, but for the previous examples we can assume as example of an `ExternalSecret` resource configuration, that would be created prior to the helm chart install, look like this:

```yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: my-external-secrets
namespace: rely-galaxy
spec:
refreshInterval: "5m"
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: my-external-secrets
creationPolicy: Owner
data:
- secretKey: RELY_API_TOKEN
remoteRef:
key: "secret/data/rely"
property: rely_api_token
- secretKey: RELY_INTEGRATION_ID
remoteRef:
key: "secret/data/rely"
property: rely_integration_id
```

> NOTE:
>
> This previous example is just for demonstration purposes and assumes that the external secrets are stored on [Vault](https://www.vaultproject.io/) and the secret `rely` in the vault backend has the keys `rely_api_token` and `rely_integration_id` with the values for the `RELY_API_TOKEN` and `RELY_INTEGRATION_ID` respectively. The `target` in the `ExternalSecret` resource is the name of the secret that contains the values for the `RELY_API_TOKEN` and `RELY_INTEGRATION_ID`.

> **NOTE** <br/>
> Depending on the integration you are using you might need to set other values. You can find the values needed for each integration in its own documentation.


###### Base kubernetes secrets

If we are not using external secrets, the helm chart also requires the following environment variables to be set:

- `env.RELY_API_TOKEN`: Go to rely app and get the token for the plugin installation
- `env.RELY_INTEGRATION_ID`: Go to rely app and get the rely integration installation id

<br/>

> **NOTE** <br/>
Expand Down
17 changes: 12 additions & 5 deletions deploy/helm/galaxy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,23 @@ Rely Galaxy Framework Helm chart for Kubernetes
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| affinity | object | `{}` | Affinity settings for pod assignment |
| env | object | `{"RELY_API_TOKEN":null,"RELY_API_URL":"https://magneto.rely.io/","RELY_INTEGRATION_DAEMON_INTERVAL":60,"RELY_INTEGRATION_EXECUTION_TYPE":"cronjob","RELY_INTEGRATION_ID":null,"RELY_INTEGRATION_TYPE":null}` | Environment variables to be set in the container |
| env | object | `{"RELY_API_TOKEN":null,"RELY_INTEGRATION_ID":null}` | Environment variables to be set in the container if not using external secrets |
| env.RELY_API_TOKEN | string | `nil` | The API token for the Rely API |
| env.RELY_API_URL | string | `"https://magneto.rely.io/"` | The URL for the Rely API |
| env.RELY_INTEGRATION_DAEMON_INTERVAL | int | `60` | The interval in minutes at which the integration should run only required if the execution type is daemon |
| env.RELY_INTEGRATION_EXECUTION_TYPE | string | `"cronjob"` | The execution type of the integration can be either cronjob or daemon |
| env.RELY_INTEGRATION_ID | string | `nil` | The identifier of this integration instance |
| env.RELY_INTEGRATION_TYPE | string | `nil` | The type of the integration |
| externalSecrets | object | `{"allAsEnv":false,"enabled":false,"envs":[],"target":"my-vault-secrets"}` | External secrets configuration |
| externalSecrets.allAsEnv | bool | `false` | All keys in secrets file will be exported as environment variables |
| externalSecrets.enabled | bool | `false` | Enable external secrets |
| externalSecrets.envs | list | `[]` | environment variables to be set in the container from the external secrets if allAsEnv is false envs is an array of objects with the following keys name -- The name of the environment variable to setup key -- The key in the secret to use eg.: envs: - name: "RELY_API_TOKEN" key: "api_token" |
| externalSecrets.target | string | `"my-vault-secrets"` | The name of the external secrets |
| fullnameOverride | string | `""` | Override the fullname of the chart |
| image.pullPolicy | string | `"IfNotPresent"` | Pull policy for the image |
| image.repository | string | `"devrelyio/galaxy"` | |
| image.tag | string | `""` | Tag to use for deploying the application |
| integration | object | `{"apiUrl":"https://magneto.rely.io/","daemonInterval":60,"executionType":"cronjob","type":null}` | The configuration for the integration |
| integration.apiUrl | string | `"https://magneto.rely.io/"` | The url for the Rely API |
| integration.daemonInterval | int | `60` | The interval in minutes at which the integration should run only required if the execution type is daemon |
| integration.executionType | string | `"cronjob"` | The execution type of the integration can be either cronjob or daemon |
| integration.type | string | `nil` | The type of the integration can be any of the following: pagerduty, github, gitlab, bitbucket, sonarqube, aws, opsgenie, gcp |
| nameOverride | string | `""` | Override the name of the chart |
| nodeSelector | object | `{}` | Node labels for pod assignment |
| podAnnotations | object | `{}` | The annotations to add to the pod |
Expand All @@ -35,3 +41,4 @@ Rely Galaxy Framework Helm chart for Kubernetes
| tolerations | list | `[]` | Toleration labels for pod assignment |
| volumeMounts | list | `[]` | Additional volumeMounts on the output Deployment definition. |
| volumes | list | `[]` | Additional volumes on the output Deployment definition. |

25 changes: 23 additions & 2 deletions deploy/helm/galaxy/templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,29 @@ Create the name of the service account to use
Create a validation for required values
*/}}
{{- define "galaxy-helm.required.envs" -}}
{{- if not .Values.externalSecrets.enabled -}}
{{- required "RELY_API_TOKEN is a required value" .Values.env.RELY_API_TOKEN -}}
{{- required "RELY_API_URL is a required value" .Values.env.RELY_API_URL -}}
{{- required "RELY_INTEGRATION_ID is a required value" .Values.env.RELY_INTEGRATION_ID -}}
{{- required "RELY_INTEGRATION_TYPE is a required value" .Values.env.RELY_INTEGRATION_TYPE -}}
{{- else -}}
{{- required "externalSecrets.target is a required value" .Values.externalSecrets.target -}}
{{- if not .Values.externalSecrets.allAsEnv -}}
{{- required "externalSecrets.envs cannot be empty" .Values.externalSecrets.envs -}}
{{- end -}}
{{- end }}
{{- required "integration.apiUrl is a required value" .Values.integration.apiUrl -}}
{{- required "integration.type is a required value" .Values.integration.type -}}
{{- end }}

{{/*
Set default environment variables
*/}}
{{- define "galaxy-helm.base.envs" -}}
- name: RELY_API_URL
value: {{ .Values.integration.apiUrl | quote}}
- name: RELY_INTEGRATION_TYPE
value: {{ .Values.integration.type | quote }}
- name: RELY_INTEGRATION_EXECUTION_TYPE
value: {{ .Values.integration.executionType | quote }}
- name: RELY_INTEGRATION_DAEMON_INTERVAL
value: {{ .Values.integration.daemonInterval | quote }}
{{- end -}}
23 changes: 22 additions & 1 deletion deploy/helm/galaxy/templates/cronjob.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- $exec_mode := default "cronjob" .Values.env.RELY_INTEGRATION_EXECUTION_TYPE }}
{{- $exec_mode := default "cronjob" .Values.integration.executionType }}
{{- if eq $exec_mode "cronjob" }}
---
apiVersion: batch/v1
Expand Down Expand Up @@ -40,9 +40,30 @@ spec:
{{- end }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if and .Values.externalSecrets.enabled .Values.externalSecrets.allAsEnv}}
env:
{{- include "galaxy-helm.base.envs" . | nindent 14 }}
envFrom:
- secretRef:
name: {{ .Values.externalSecrets.target }}
{{- else if and .Values.externalSecrets.enabled (not .Values.externalSecrets.allAsEnv) }}
env:
{{- include "galaxy-helm.base.envs" . | nindent 14 }}
{{- $target := .Values.externalSecrets.target }}
{{- range .Values.externalSecrets.envs }}
- name: {{ .name }}
valueFrom:
secretKeyRef:
name: {{ $target }}
key: {{ .key }}
{{- end }}
{{- else }}
env:
{{- include "galaxy-helm.base.envs" . | nindent 14 }}
envFrom:
- secretRef:
name: {{ include "galaxy-helm.fullname" . }}
{{- end }}
restartPolicy: Never
{{- with .Values.nodeSelector }}
nodeSelector:
Expand Down
23 changes: 22 additions & 1 deletion deploy/helm/galaxy/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{- $exec_mode := default "cronjob" .Values.env.RELY_INTEGRATION_EXECUTION_TYPE }}
{{- $exec_mode := default "cronjob" .Values.integration.executionType }}
{{- if eq $exec_mode "daemon" }}
---
apiVersion: apps/v1
Expand Down Expand Up @@ -37,9 +37,30 @@ spec:
{{- end }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if and .Values.externalSecrets.enabled .Values.externalSecrets.allAsEnv}}
env:
{{- include "galaxy-helm.base.envs" . | nindent 12 }}
envFrom:
- secretRef:
name: {{ .Values.externalSecrets.target }}
{{- else if and .Values.externalSecrets.enabled (not .Values.externalSecrets.allAsEnv) }}
env:
{{- include "galaxy-helm.base.envs" . | nindent 12 }}
{{- $target := .Values.externalSecrets.target }}
{{- range .Values.externalSecrets.envs }}
- name: {{ .name }}
valueFrom:
secretKeyRef:
name: {{ $target }}
key: {{ .key }}
{{- end }}
{{- else }}
env:
{{- include "galaxy-helm.base.envs" . | nindent 12 }}
envFrom:
- secretRef:
name: {{ include "galaxy-helm.fullname" . }}
{{- end }}
ports:
- name: http
containerPort: 8000
Expand Down
44 changes: 33 additions & 11 deletions deploy/helm/galaxy/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,46 @@ image:
# -- This is a cron expression that defines the schedule for the cronjob
schedule: "*/59 * * * *" # Every 59 minutes

# -- Environment variables to be set in the container
# -- External secrets configuration
externalSecrets:
# -- Enable external secrets
enabled: false
# -- The name of the external secrets
target: "my-vault-secrets"
# -- All keys in secrets file will be exported as environment variables
allAsEnv: false
# -- environment variables to be set in the container from the external secrets if allAsEnv is false
# envs is an array of objects with the following keys
# name -- The name of the environment variable to setup
# key -- The key in the secret to use
# eg.:
# envs:
# - name: "RELY_API_TOKEN"
# key: "api_token"
envs: []

# -- The configuration for the integration
integration:
# -- The type of the integration
# can be any of the following: pagerduty, github, gitlab, bitbucket, sonarqube, aws, opsgenie, gcp
type:
# -- The execution type of the integration
# can be either cronjob or daemon
executionType: cronjob
# -- The interval in minutes at which the integration should run
# only required if the execution type is daemon
daemonInterval: 60
# -- The url for the Rely API
apiUrl: "https://magneto.rely.io/"

# -- Environment variables to be set in the container if not using external secrets
env:
# The following environment variables are required to run this container
# more environment variables can be added here as required for each integration
# env.RELY_API_TOKEN -- The API token for the Rely API
RELY_API_TOKEN:
# env.RELY_API_URL -- The URL for the Rely API
RELY_API_URL: https://magneto.rely.io/
# env.RELY_INTEGRATION_ID -- The identifier of this integration instance
RELY_INTEGRATION_ID:
# env.RELY_INTEGRATION_TYPE -- The type of the integration
RELY_INTEGRATION_TYPE:
# env.RELY_INTEGRATION_EXECUTION_TYPE -- The execution type of the integration
# can be either cronjob or daemon
RELY_INTEGRATION_EXECUTION_TYPE: cronjob
# env.RELY_INTEGRATION_DAEMON_INTERVAL -- The interval in minutes at which the integration should run
# only required if the execution type is daemon
RELY_INTEGRATION_DAEMON_INTERVAL: 60

# nameOverride -- Override the name of the chart
nameOverride: ""
Expand Down

0 comments on commit 18d4eec

Please sign in to comment.