Environmentalize your YAML configuration

Learn how to environmentalize your YAML configuration.

6 minute read

The XML federated configuration provides different ways to environmentalize parts of the configuration. See Environmentalize configuration for details.

The YAML configuration format replaces any environmentalization done via Policy Studio, which is enabled in Policy Studio through Preferences > Environmentalization > Allow environmentalization, with an improved method of environmentalization using the {{ env "XYZ" }} syntax. The conversion process will look after the replacement of this type of environmentalization. Selectors such as ${environment.XYZ} and ${env.XYZ} will continue to work as before.

YAML environmentalization capabilities can be applied to:

  • All entities.
  • The value of a field. This is possible for all types of fields: numeric, string, references, passwords.
  • Part of the value of a string.
  • Some or all of the content in externalized files such as Scripts, Messages, and JSON Schemas. For more information, see Environmentalization possible inside file content column of the Externalized files naming Scheme table.

The following table describes all of the supported environmentalization options for the YAML format:

Feature / File Syntax Description
YAML style {{ env "XYZ" }} This syntax is allowed anywhere, and it replaces the Policy Studio Environmentalization feature. Evaluated by API Gateway at load time using system environment variables, which means that you are warned about missing system environment variables sooner.
Environment selector ${environment.XYZ} Only supported for fields that support selectors in the runtime. Evaluated by API Gateway at runtime using system environment variables. This can be replaced by the {{ env “XYZ” }} syntax.
envSettings.properties ${env.xyz} Evaluated by API Gateway, at load time, using envSettings.props content specific to an instance. It is likely these settings will remain as they are as they are instance-specific as opposed to environment-specific.
system.properties ${system.xyz} Evaluated by API Gateway, at load time, using system.properties file content.

Enable environmentalization

To enable environmentalization, create a file named values.yaml in the root directory where your YAML entity store is installed.

The following is an example of environmentalization:

# Environmentalized entity in the YAML configuration
---
type: "DbConnection"
fields:
   name: MySQL
   url: "jdbc:mysql://{{ db.host }}:3306/DefaultDb"
   password: {{ db.password }}
   username: "{{ db.username }}"

db:
  host: localhost
  username: scott
  password: HDidnjekj=

# Content of the value.yaml
---
type: "DbConnection"
fields:
   name: MySQL
   url: "jdbc:mysql://localhost:3306/DefaultDb"
   password: HDidnjekj=
   username: "scott"
# Resolved YAML Entity (in memory at runtime)
---
type: "DbConnection"
fields:
   name: MySQL
   url: "jdbc:mysql://localhost:3306/DefaultDb"
   password: HDidnjekj=
   username: "scott"

{{ ... }} placeholders are replaced when the configuration is loaded by the API Gateway or in ES Explorer.

When you environmentalize references, the certificates also get environmentalized. For example:

# Environmentalized FilterCircuit entity in the YAML configuration
---
type: FilterCircuit
fields:
  name: cert
  start: ./XML Signature Generation
  description: ""
children:
- type: GenerateSignatureFilter
  fields:
    name: XML Signature Generation
    signingCert: {{ certs.sign }}
# ...
# Content of the value.yaml
---
certs:
  sign: /Environment Configuration/Certificate Store/Samples Test CA
# Resolved YAML Entity (in memory at runtime)
---
type: FilterCircuit
fields:
  name: cert
  start: ./XML Signature Generation
  description: ""
children:
- type: GenerateSignatureFilter
  fields:
    name: XML Signature Generation
    signingCert: /Environment Configuration/Certificate Store/Samples Test CA
# ...

The values.yaml above could also point to a system environment variable CERT_DNAME that would determine the certificate to be used at runtime.

# Content of the value.yaml
certs:
  sign: /Environment Configuration/Certificate Store/{{ env "CERT_DNAME" }}

Your CI/CD pipeline must ensure that any certificates and keys are packaged up correctly for each environment in the .tar.gz that gets deployed. If you attempt to validate a YAML configuration that uses a system environment variable on a system that does not have a value set for that environment variable, you will need to use the --allow-invalid-ref option. For more information, see Disabling entity reference check.

In a nutshell, the YAML configuration is a template where you can environmentalize all types of values.

Environmentalization syntax

The following are elements of the environmentalization syntax.

Variables

Scope: YAML Entity files or compatible externalized files.

{{ expression }} or {{expression}}

Expression can contain:

  • Simple properties: {{ foo }}
  • Nested properties: {{ foo.bar }}
  • Indexed properties: {{ foo.bar.[0] }}, or the equivalent {{ foo.bar.0}}. This syntax is useful for multiple values of the field.

Environment and JVM variables

Scope:

  • YAML entity files
  • values.yaml files

You can environmentalize the settings using system environment variables, like ${environment.XYZ}, except that it can be done anywhere; and JVM properties -Dxyz, when starting a java process, such as the API Gateway.

Environmentalize with no default value:

{{ env "XYZ" }} or {{ env 'XYZ' }}

Environmentalize with a default value:

{{ env "XYZ" "The end of the alphabet"}} or {{ env "XYZ" default="The end of the alphabet"}}

The value of XYZ is evaluated by the first true condition from this list:

  • An environment variable with name XYZ exists.
  • An environment variable with name xyz exists (lowercase).
  • The JVM was started with -DXYZ.
  • The JVM was started with -Dxyz (lowercase).
  • A default value is set.

If none of the above conditions are true, an error is raised in the logs when the API Gateway loads the YAML configuration.

Base64 encoding

Scope:

  • values.yaml files
  • YAML Entity files (not recommended)

You can encode a string value in base64 using:

{{ base64 "changeme" }}

This is very useful for development or local environment, when your YAML configuration does not required to be encrypted. This will not work when your YAML configuration is encrypted as recommended for production environments.

Sub expression

Scope:

  • values.yaml files
  • YAML Entity files (not recommended)
  • You can combine several expression together

{{ base64 (env "DB_PASSSWORD" "s3cr3t") }}

This base64 example encodes the content of the environment variable DB_PASSSWORD, or s3cr3t if unset.

Reserved words

The following words are not allowed at the beginning of a {{ ... }} expression:

  • null
  • true and false
  • undefined
  • Digits as first characters. For example, {{ 42_foo.bar }}

In values.yaml, you can only use letters (including _) and digits (not at starting position).

Examples:

# Invalid because of reserved word
null_user:
  name: ""
  
false_expressions:
  - F
  - N
  - 0

#idem for 'true' or 'undefined' reserved words

# Invalid because digit at starting position
1_Services:
   registration: Registration Service

# Valid examples
user_is_null_if:
  name: ""
  
falsy_expressions:
  - F
  - N
  - 0

_1_Services:
   registration: Registration Service

# Valid because the resolved expression {{ validation_schemas.1_user }} does not start with a digit
validation_schemas:
   1_user: http://acme.com/schemas/users
   2_group: http://acme.com/schemas/group

Escape quotation marks in values.yaml

Follow these guidelines to avoid issues when using quotation marks in strings:

  • Use two single quotation marks for double quotation marks enclosed string (" ").
  • Use four single quotation marks for single quotation marks enclosed string (' ').

For example, when your environmentalization placeholder is surrounded by single quotation marks:

fields:
  url: '{{ foo.bar.url.value }}'

For example, to set value with a message with 'single quotation marks', you can use:

value: "a message with ''single quotation marks'' "

or

value: 'a message with ''''single quotation marks'''' '

Environmentalization in values.yaml

To decouple where the value of an environment variable is coming from and where it is used, use the {{ env "XYZ" }} syntax in the values.yaml file:

---
db:
  host: {{ env "DB_HOST" }} # you set a value an environment variable per environment

If you want to set a fixed value that does not change between all environments, change the values.yaml to:

---
db:
  host: db.com

Alternatively, to use a different values.yaml for each environment, set it as follows:

# values.yaml for staging
---
db:
  host: staging.db.acme.com

and for the production environment you could have:

# values.yaml for prod
---
db:
  host: prod.db.acme.com

This can all be done without changing the YAML file for the entity that always point to db.host environmentalized property:

#Some Entity.yaml
---
type: DBConnection
fields:
    # just showing environmentalization fields
    host: {{ db.host }}

Refer to Environmentalization example for a complete example of the different capabilities offered by the YAML configuration environmentalization.

Convert Policy Studio environmentalization for XML federated configurations to YAML syntax

When XML federated configurations that contain fields environmentalized via Policy Studio are converted to YAML format:

  • A values.yaml is created.
  • Each environmentalized field with a value yields an entry.
    • In values.yaml, with the environmentalized values.
    • In values-original.yaml, with the value of the field before being environmentalized in Policy Studio.
  • A placeholder replaces the value in entity YAML file. The naming follows the YamlPK logic with sanitization that is compliant with the environmentalization syntax.

The following is an example for entity with an environmentalized URL, username, and password:

Entity in XML federated configuration:

  • Type: LdapDirectory (LDAP Connection)
  • Name: api-env LDAP
  • Environmentalized fields: url, userName, password
  • Contained in LDAP Connections

YAML configuration after conversion:

---
type: LdapDirectory
fields:
  name: api-env LDAP
  url: {{ LDAP_Connection.api_env_LDAP.url }}
  userName: {{ LDAP_Connection.api_env_LDAP.userName }}
  password: {{ LDAP_Connection.api_env_LDAP.password }}

Content of values.yaml:

LDAP_Connection:
  api_env_LDAP:
    url: ldap://api-env:389
    userName: cn=Administrator,dc=demo.axway,dc=com
    password: KLJH95dHS7djshkjas54sa45s4d==

The following is an example for an entity with an environmentalized certificate:

Entity in XML federated configuration:

  • Type: ConnectToURLFilter
  • Name: name: Connect to URL
  • Environmentalized Fields: sslUsers
  • Contained in Policies/YAML Demo/Connect with SSL

YAML configuration after conversion:

---
type: FilterCircuit
fields:
  name: Connect with SSL
  start: ./Connect to URL
  description: ""
children:
- type: ConnectToURLFilter
  fields:
    name: Connect to URL
    sslUsers: '{{ YAML_Demo.Connect_with_SSL.Connect_to_URL.sslUsers }}'
    url: https://localhost:5555/cert-verifier
    name: Connect to URL
# ...

Content of values.yaml:

---
YAML_Demo:
  Connect_with_SSL:
    Connect_to_URL:
      sslUsers: /Environment Configuration/Certificate Store/O=DEV,CN=localhost