Atlassian uses cookies to improve your browsing experience, perform analytics and research, and conduct advertising. Accept all cookies to indicate that you agree to our use of cookies on your device. Atlassian cookies and tracking notice, (opens new window)
@Shelley Doljack is next, followed by @Jeff Gerhard
Reminder: Please copy/paste the Zoom chat into the notes. If you miss it, this is saved along with the meeting recording, but having it here has benefits.
3 min
Current State
ALL
FOLIO modules exhibit significant inconsistency in environment variable management:
mod-agreements/mod-licenses use GLOBAL_S3_SECRET_KEY(no other S3 env variables in these apps)
System User Variables: Mixed usage of SYSTEM_USER_NAME (mod-bulk-operations, mod-requests-mediated, mod-pubsub) vs SYSTEM_USER_USERNAME (mod-circulation-bff, mod-tlr, mod-search, mod-marc-migrations)
Documentation Gaps:
Well-documented modules (minority):
mod-users-keycloak: Comprehensive README tables with Name | Default | Required | Description
mod-data-export-spring: Simpler tables with Name | Default | Description
READMEs for these modules state that the table contains a ‘non-exhaustive list’ of environment variables
Undocumented modules (majority): Environment variables only in ModuleDescriptor.json with minimal or no description field
Configuration Approaches:
Most modules define env vars in descriptors/ModuleDescriptor-template.json
No standardized approach for required vs optional variables
Notes:
Brought up as a topic in the shoulder meeting at WOLFCon 25.
As a SysOps person, you should be able easily find these env vars.
The readme should have a list but not all of them do.
Modules that use common frameworks (like Spring or RMB), they don’t necessarily need to document environmental variables in their readme but maybe point to the framework.
15 min
Naming Standards & Conventions
What naming convention will we adopt as the standard?
Category
Inconsistency Found
Modules Affected
Recommendation Needed
S3/AWS Services
`AWS_*` vs `S3_*`
mod-users (AWS_*), mod-bulk-operations (S3_*)
Choose one prefix
System User
SYSTEM_USER_NAME vs SYSTEM_USER_USERNAME
mod-bulk-operations, mod-requests-mediated vs mod-circulation-bff, mod-tlr
Do we grandfather existing variables or mandate migration?
Options
Hard cutoff: Set deadline, all modules must comply
Deprecation period: Support both old and new names with warnings for 2-3 releases
Grandfather clause: New modules only, existing modules migrate as able
Notes:
HTTP port env var - seems there are many different ways to configure it because of the framework used. We’re almost forced to use the variety due to the various frameworks used.
The goal is to provide a consistent experience for system operators.
AWS or S3? Some modules used a version of the dependency libraries that wanted S3 or AWS and that’s why we are where we are with that one.
When the framework changes, we should change our mapping and not have to change our environment variables.
Having AWS is sometimes useful so you know which modules depend on a cloud provider.
S3 makes more sense because you’re using the S3 API in order to use cloud storage.
We prefer S3_ .
We prefer SYSTEM_USER_NAME.
Side note re: system user, not sure if all modules allow you to set the system user username and not give the operator a chance to set it.
If system user name is configurable and an operator chooses one for all, it has security implications.
We want configuration to not be hardcoded and SYSTEM_USER_NAME is one of them.
Is there an easy way to get all the environment variables that folio modules use? Okapi might have a feature that gets the env vars.
Spring boot allows the application.yaml to have whatever env var you want but we should set it in the default to use other env variables and avoid Spring boot’s dynamic environment variable naming convention.
It would be nice to have our standard env var align with frameworks but that’s a big ask.
Do we grandfather existing variables or mandate migration?
hard cutoff and deprecation aren’t really mutually exclusive.
The choice is really hard cutoff or grandfather. If we tell modules to comply, then we address deprecation.
Preference is support standardized env vars as well.
10 min
Documentation Requirements
What is the minimum acceptable documentation for each environment variable?
Current Best Practice Example (mod-users-keycloak):
Name
Default value
Required
Description
DB_HOST
localhost
false
Postgres hostname
DB_PORT
5432
false
Postgres port
KC_URL
true
Keycloak URL used to perform HTTP requests by KeycloakClient
SYSTEM_USER_RETRY_COUNT
10
false
Number of retry attempts to create a system user
Proposed Required Fields:
Name (required)
Default value (required, "-" if none)
Required/Optional flag (required)
Description (required, including purpose and valid values)
Where must it be documented?
Examples:
// Current minimal approach (mod-users)
{ "name": "DB_HOST", "value": "postgres" }
// Better approach with description (mod-camunda)
{ "name": "OKAPI_URL", "value": "http://10.0.2.15:9130",
"description": "The URL to the OKAPI service." }
Recommendation Needed:
ModuleDescriptor mandatory + README optional?
Both mandatory?
README mandatory with detailed table format?
ENV_VARS.md(link in the README.md) + ModuleDescriptor + Jira for Ops for automation from ModuleDescriptor
Notes:
Not all modules have a written list of env vars in their readme.
Proposed required fields, valid values should definitely be documented somewhere, either in the description column or another column.
Maybe keep to 4 columns b/c landscaping issues on github. Or have separate tables for required and for optional env vars.
We decided to keep it as 4 columns b/c that’s what some readmes currently have.
Where is must be documented: either human or machine-readable format.
If it’s in the module descriptor, we can write a tool that will generate it in a wiki for human-readable format.
History about why they’re in the module descriptor:
When building snapshot in okapi-based environments, they needed to be in the module descriptor in the LaunchDescriptor so that they are set when the container spins up, if they are required.
It serves as documentation but there is a technical reason why it is there now.
It is more likely that all the env vars a module uses will be in the module descriptor.
Kevin’s idea of a tool to generate a human-readable doc from the module descriptor sounds like a great idea. Could be added to CI.
If we tie the human-readable doc to being generated from the module descriptor, how would we make changes to env vars in order to be consistent?
TC should request the DevOps team to do this work.
ENV_VARS.md, the module descriptor would have to change a bit to include data about required fields, optional fields, etc.
How would we expect development teams to communicate deprecation?
It would be in the description field of the module descriptor.
Maybe add a deprecated property to the module descriptor?
We shouldn’t make any schema changes to module descriptors b/c it could be hairy to do.
Although technically, it shouldn’t be too hard a change.
We are trying to make our requirements easily-digestable to the FOLIO community.
Nobody is against option 4 for recommendations needed.
10 min
Mandatory vs. Optional Variables
What happens when required variables are missing?
Current Behavior (inconsistent):
Some modules: Fail fast on startup with exceptions
Some modules: Use default values silently
Some modules: Log warnings and continue with degraded functionality
mod-users-keycloak example (from README):
KC_URL marked as "Required: true" - module fails to start if missing
DB_HOST marked as "Required: false" with default "localhost"
Recommendation Needed:
Fail fast: Module refuses to start, clear error message
Default with warning: Use default value, log warning
Tiered approach: Critical vars fail fast, optional vars use defaults
Notes:
If it’s using a default value, then it’s not a required variable.
Fail fast and loudly
Setting them as empty strings or is that considered not specified?
If the env is required and it is empty, it should throw an error.
Some env vars are booleans, so it’s different for application to application. Making too strong of an opinion could cause problems with 3rd party libraries we use.
Fail fast is great but we have this criteria in module evaluation that we should be able to handle failures better and not fail fast.
Fail fast is contradictory to our module evaluation criteria.
15 min
Migration Strategy
Breaking changes: How do we handle deprecated variables?
Example:
// Support both
{ "name": "OKAPI_URL", "value": "http://okapi:9130",
"description": "DEPRECATED: Use GATEWAY_URL instead" },
{ "name": "GATEWAY_URL", "value": "http://okapi:9130" }
// Log warnings
// Module logs: "WARNING: OKAPI_URL is deprecated, please use GATEWAY_URL"
// Only new variable
{ "name": "GATEWAY_URL", "value": "http://okapi:9130" }
For new modules:
What criteria must be completed before acceptance?
Proposed Additional Module Evaluation Criteria:
[ ] All environment variables follow naming convention (DB_, KAFKA_, S3_/AWS_ per standard)
[ ] ModuleDescriptor includes description for each variable
[ ] README.md includes environment variable table with: Name | Default | Required | Description
[ ] Required vs optional variables clearly marked
[ ] Feature flags use consistent naming (e.g., *_ENABLED suffix)
[ ] Module startup validates required variables and fails fast with clear errors
Observability
Should modules log their configuration on startup?
Proposed Standard:
Startup Configuration Logging:
INFO Starting mod-bulk-operations v2.5.0
INFO Configuration loaded:
INFO DB_HOST: postgres
INFO DB_PORT: 5432
INFO DB_DATABASE: okapi_modules
INFO DB_USERNAME: folio_admin
INFO DB_PASSWORD: ******** (8 characters)
INFO KAFKA_HOST: kafka
INFO KAFKA_PORT: 9092
INFO S3_URL: http://minio:9000
INFO S3_BUCKET: bulk-operations
INFO S3_ACCESS_KEY_ID: AKIA******AMPLE (redacted)
INFO S3_SECRET_ACCESS_KEY: ******** (40 characters)
INFO SYSTEM_USER_ENABLED: true
INFO ENV: folio
Benefits:
Easier debugging of configuration issues
Confirms which values are actually being used
Validates env vars were loaded correctly
Helps identify missing or default values in production
Security Considerations:
Passwords: Show only character count
API Keys/Tokens: Show first 4 and last 4 characters with middle redacted
Standardized Error Messages
Current Problem: Inconsistent error messages when env vars are misconfigured
Proposed Standard Error Format:
ERROR: Required environment variable missing
Variable: DB_PASSWORD
Description: Postgres database password
Required: true
Documentation: See https://github.com/folio-org/mod-bulk-operations#environment-variables
ERROR: Invalid environment variable value
Variable: DB_PORT
Current Value: "invalid"
Expected Type: integer (1-65535)
Documentation: See https://github.com/folio-org/mod-bulk-operations#environment-variables
ERROR: Environment variable connection test failed
Variable: OKAPI_URL
Current Value: http://okapi:9130
Error: Connection refused
Suggestion: Verify that Okapi is running and accessible at this URL
Benefits:
Faster troubleshooting
Clearer guidance for operators
Consistent experience across all modules
Links to documentation
Enforcement
What can we do to ensure continuous adherence?
NA
Zoom Chat
2025-10-22 09:17:31 From Wayne Schneider to Everyone: mod-users is one of the most recent S3 implementations but maybe the devs missed the memo
2025-10-22 09:36:28 From Wayne Schneider to Everyone: Please not the wiki, please the README Matt Weaver:❤️ Day, Kevin:👍
2025-10-22 09:47:02 From Wayne Schneider to Everyone: The work would be something for the FOLIO DevOps team
2025-10-22 09:58:19 From Maccabee Levine to Everyone: There is a module review criterion "Gracefully handles the absence of third party systems or related configuration. (3, 5, 12)"
2025-10-22 09:59:41 From Day, Kevin to Everyone: Fail fast would require a migration guide, probably.
2025-10-22 09:59:41 From Matt Weaver to Everyone: One example on my team, which is a bit of a balancing act: mod-lists requires S3 to be configured, and will fail fast if it’s not set up right. But you can disable that fail-fast behavior with another environment var