From 8a54ee410dda79a2e9454f6d10d7d10928f8fc6d Mon Sep 17 00:00:00 2001 From: kurokobo <2920259+kurokobo@users.noreply.github.com> Date: Tue, 16 Jan 2024 14:24:21 +0900 Subject: [PATCH] feat: add guide to pass values from secrets to extra_settings --- README.md | 1 + tips/README.md | 1 + tips/extra-settings.md | 156 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 tips/extra-settings.md diff --git a/README.md b/README.md index fe1fad7..4d415b3 100644 --- a/README.md +++ b/README.md @@ -284,6 +284,7 @@ Refer [📁 **Back up AWX using AWX Operator**](backup) and [📁 **Restore AWX - [📝Trust custom Certificate Authority](tips/trust-custom-ca.md) - [📝Expose `/etc/hosts` to Pods on K3s](tips/expose-hosts.md) - [📝Enable HTTP Strict Transport Security (HSTS)](tips/enable-hsts.md) + - [📝Pass values from Secrets to `extra_settings`](tips/extra-settings.md) - [📝Use HTTP proxy](tips/use-http-proxy.md) - [📝Uninstall deployed resources](tips/uninstall.md) - [📝Deploy older version of AWX Operator](tips/deploy-older-operator.md) diff --git a/tips/README.md b/tips/README.md index a524b75..71904a7 100644 --- a/tips/README.md +++ b/tips/README.md @@ -5,6 +5,7 @@ - [📝Trust custom Certificate Authority](trust-custom-ca.md) - [📝Expose `/etc/hosts` to Pods on K3s](expose-hosts.md) - [📝Enable HTTP Strict Transport Security (HSTS)](enable-hsts.md) +- [📝Pass values from Secrets to `extra_settings`](extra-settings.md) - [📝Use HTTP proxy](use-http-proxy.md) - [📝Uninstall deployed resources](uninstall.md) - [📝Deploy older version of AWX Operator](deploy-older-operator.md) diff --git a/tips/extra-settings.md b/tips/extra-settings.md new file mode 100644 index 0000000..926d3dc --- /dev/null +++ b/tips/extra-settings.md @@ -0,0 +1,156 @@ +# Pass values from Secrets to `extra_settings` + +Currently, AWX Operator does not ability to inject Secrets to `extra_settings`. + +However, since Secrets are injectable for environment variables, we can indirectly inject values from Secrets into `extra_settings` by specifying values that refers to the environment variables. + +## Concept + +Since the values for `extra_settings` will be embedded as Python code into `settings.py`, we can use any python code as values for `extra_settings`. So the key concepts are: + +- Add environment variables for both task and web pod with `valueFrom` to inject values from Secrets to environment variables. +- Specify `os.getenv()` in values for `extra_settings`. + +## Simple examples + +This is a simple example to inject values from Secrets to `extra_settings`. + +```yaml +--- +apiVersion: awx.ansible.com/v1beta1 +kind: AWX +metadata: + name: awx +spec: + ... + + # Add new environment variables with "valueFrom" to task pod + task_extra_env: | + - name: AZUREAD_OAUTH2_KEY + valueFrom: + secretKeyRef: + name: awx-azuread-oauth2-secret + key: key + - name: AZUREAD_OAUTH2_SECRET + valueFrom: + secretKeyRef: + name: awx-azuread-oauth2-secret + key: secret + + # Completely the same environment variables should be added to web pod + web_extra_env: | + - name: AZUREAD_OAUTH2_KEY + valueFrom: + secretKeyRef: + name: awx-azuread-oauth2-secret + key: key + - name: AZUREAD_OAUTH2_SECRET + valueFrom: + secretKeyRef: + name: awx-azuread-oauth2-secret + key: secret + + # Specify "os.getenv()" that refers environment variables that newly added above + extra_settings: + - setting: SOCIAL_AUTH_AZUREAD_OAUTH2_KEY + value: os.getenv("AZUREAD_OAUTH2_KEY") + - setting: SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET + value: os.getenv("AZUREAD_OAUTH2_SECRET") +``` + +## Complex examples + +This is an example to inject values from Secrets as a part of Dictionary. The Dictionary should be passed as multi-line strings. + +> [!IMPORTANT] +> If we want to pass multi-line strings including `os.getenv()` as values for `extra_settings`, indentation have to be noted since the values will be embedded into ConfigMap that templated by Jinja, and ConfigMap has 4 spaces indentation per lines. We must not destroy the indentation of the ConfigMap. + +```yaml +--- +apiVersion: awx.ansible.com/v1beta1 +kind: AWX +metadata: + name: awx +spec: + ... + + # Add new environment variables with "valueFrom" to task pod + task_extra_env: | + - name: SAML_IDP_SIGNING_CERT + valueFrom: + secretKeyRef: + name: awx-saml-idp-signing-cert + key: x509cert + + # Completely the same environment variables should be added to web pod + web_extra_env: | + - name: SAML_IDP_SIGNING_CERT + valueFrom: + secretKeyRef: + name: awx-saml-idp-signing-cert + key: x509cert + + # Specify "os.getenv()" that refers environment variables that newly added above + extra_settings: + - setting: SOCIAL_AUTH_SAML_ENABLED_IDPS + # Define value as multi-line strings with 2 spaces indentation (by "|2"), + # then pass the actual value with 6 spaces indentation + # to add 4 leading spaces for each lines to keep indentation in ConfigMap correctly + value: |2 + { + "saml_ms_adfs": { + "x509cert": os.getenv("SAML_IDP_SIGNING_CERT"), + "attr_last_name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname", + "attr_first_name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname", + "attr_email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", + "attr_username": "name_id", + "attr_user_permanent_id": "name_id", + "entity_id": "https://adfs.domain.com/adfs/services/trust", + "url": "https://adfs.domain.com/adfs/ls", + } + } +``` + +This will generate following ConfigMap. As you can see, to include all lines into under `settings`, 4 spaces indentation is important. + +```yaml +--- +apiVersion: v1 +kind: ConfigMap +... +data: + ... + settings: | + import os + import socket + ... + SOCIAL_AUTH_SAML_ENABLED_IDPS = { + "saml_ms_adfs": { + "x509cert": os.getenv("SAML_IDP_SIGNING_CERT"), + "attr_last_name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname", + "attr_first_name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname", + "attr_email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", + "attr_username": "name_id", + "attr_user_permanent_id": "name_id", + "entity_id": "https://adfs.domain.com/adfs/services/trust", + "url": "https://adfs.domain.com/adfs/ls", + } + } +``` + +> [!TIP] +> If you don't want to care about indentation, alternatively it is also possible to pass a Dictionary on a single line, as long as it follows Python syntax. + +> [!TIP] +> The above example assumes that the certificate is stored in secret as a single line of text data, not including line breaks, headers, or footers. +> +> ```bash +> kubectl -n awx create secret generic awx-saml-idp-signing-cert \ +> --from-literal=x509cert=MIIDZTCC........6xGPxz26 +> ``` +> +> If your secrets contains whole the certificate, you can use `replace()` after `getenv()`, to remove line breaks, headers, and footers. +> +> ```python +> "x509cert": os.getenv("SAML_IDP_SIGNING_CERT").replace("\n", "").replace("-----BEGIN CERTIFICATE-----", "").replace("-----END CERTIFICATE----", ""), +> ```