Read environment variables in revel app.conf - go

Revel uses app.conf for storing configuration. I want my configuration to get value from environment variable using os.Getenv(key)
How can I do it? Should I use revel.Config to make changes? if so where do I place it?
Or is there another way?
I use it mainly for storing database information (I don't want to enter my credential in configuration files)
Thank you

Revel uses revel/config for managing app.conf.
And the only place revel/config foes read from the environment variable is in type.go (c *Config) String() method.
// $ environment variables
computedVal, _ = c.computeVar(&value, envVarRegExp, 2, 1, func(varName *string) string {
return os.Getenv(*varName)
})
That means you could add in a config file values based on the name of environment variable, which would allow you to use said environment variable to modify the config.
See an example in the revel/config REAMD.md file.
[DEFAULT]
host: www.example.com
protocol: http://
base-url: %(protocol)s%(host)s <====
The OP pveyes points out to this comment in type.go:
// substitute by new value and take off leading '%(' and trailing ')s'
// %(foo)s => headsz=2, tailsz=2
// ${foo} => headsz=2, tailsz=1
So:
when using environment variables use ${ENV_VARS}, and
for unfolding variables use %(UNF_VARS)s

Related

Jenkinsfile environment variables not available with parameter variables

I am using a Jenkins plugin to upload test run results to Jira. Using this plugin I can send two JSON blobs of data for the import, but the variables in those JSON blobs can only be environment variables (not variables generally available in the Jenkinsfile).
When I run it is recognizing environment variables that come from the parameters block (this is a parameterized build), but it does not recognize any environment variables I set, either in an environment {} block in the pipeline or by nesting the build step in a withEnv() {} block.
As a sanity check, right before the step in question, I echo two environment variables, one from the parameters block and one from the environment block, and both spit out to the console as expected, but then, as consumed by the plugin, only the variables coming from the parameters block are read as variables, with the rest being left as string.
So is there some difference in how these environment variables are stored/managed behind the scenes that might play into this?
So, for example, here are the parameters and environment blocks:
parameters {
choice(name: 'ENVIRONMENT', choices: ['dev', 'test', 'staging', 'prod'], description: 'Select the environment to run against.')
choice(name: 'TESTS', choices: ['All', 'API', 'Web'], description: 'Select the tests to run.')
}
environment {
PROJECT_KEY = "$jiraProjectKey"
TEST_PLAN_KEY = "$testPlanKeys[$env.ENVIRONMENT]"
PRODUCT_NAME = "$productName"
TEAM_NAME = "$teamName"
}
When I used these environment variables in the JSON blobs to set the Summary field of a Test Execution in Jira with a line that looks like this:
...
"summary": "${ENVIRONMENT} - ${PRODUCT_NAME} - ${TESTS} Tests",
...
The resulting issue summary is:
dev - ${PRODUCT_NAME} - API Tests
So it will properly interpret the environment variables set by the parameters block, but not ones I set explicitly in the environment block.
In the JSON blobs that you are sending inline make sure that for multiline strings you are using """ to delimit those strings and not '''.
Replace:
... importInfo: '''{...'''
by:
...importInfo: """{..."""

Golang use bash environment variables in Buffalo database.yml

I'm new to Go and Buffalo, and am attempting use my bash environment variables in my database.yaml
I attempted to do the following in my database.yaml, but it fails to interpret the value of my bash environment var localUser
user: ${localUser}
I set the localUser with the following bash
export localUser="username"
echo $localUser
username
Thanks for any help!!
Buffalo Pop's configuration, database.yml, supports the following syntax.
production:
host: "localhost"
user: {{ envOr "localUser" "defaultuser" }}
test:
dialect: "mysql"
url: {{ envOr "TEST_DATABASE_URL" "mysql://user:pass#(localhost:3306)/test" }}
The key is the envOr directive.
As you can imagine, the production.user will be set as the value from the environment variable localUser if the value exists, but it will fall back to its default value "defaultuser" if there is no environment variable.
With this syntax, you can configure environment-specific values dynamically.
This is good for many situations such as container images that could be used in multiple different configurations. You can distribute (or publish) your application "image" with the default value, then you can run your "container" with specific environmental variables with the real values.

How do nested variables within the .env file work in CodeIgniter 4

Under the "Nesting Variables" section in Codeigniter4 site:
"To save on typing, you can reuse variables that you’ve already specified in the file by wrapping the variable name within ${...}"
link to CI nesting Variables section
example in the documentation:
BASE_DIR="/var/webroot/project-root"
CACHE_DIR="${BASE_DIR}/cache"
TMP_DIR="${BASE_DIR}/tmp"
I was trying to use the following
app.baseURL = 'http://localhost:8080/'
google.redirect = ${app.baseURL}Google
However, it's assigning it as a literal when print_r($_ENV)
[google.redirect] => ${app.baseURL}Google
I've tried using non-namespaced keys including BASE_DIR (per the example) and it keeps printing as a literal.
What's strange - When I use the following:
CI_ENVIRONMENT = development
google.redirect = ${CI_ENVIRONMENT}Google
The result when print_r is:
[CI_ENVIRONMENT] => development
[google.redirect] => developmentGoogle
My question is - What am I doing incorrectly and/or how should these be set/used correctly?
According to the documentation, I should be able to use any key within the .env file that was already assigned using
${somekeyinthisfile}
After a bit of looking, there is a more recent file up at
https://github.com/codeigniter4/CodeIgniter4/blob/develop/system/Config/DotEnv.php
with all the "other" changes...
This was a Bug Fix. So get that file and you will be good to go.
I am pretty sure that the intention wasn't to allow app.xxx settings to be used as variables as the documentation clearly shows, by not
showing them being used. ( yes its 6am now ...)
BUT it is your code to do with as you please...So if you want to use app.xxx as variables...
The Only Thing missing is the DOT (.) in the regex
If you look on Line 272 - system/Config/DotEnv.php inside method resolveNestedVariables() and add a . (dot) into the regex, that will make all your app.things work.
$value = preg_replace_callback(
'/\${([a-zA-Z0-9_.]+)}/',
function ($matchedPatterns) use ($loader) {
I have added a dot (.) at the end of the [a-zA-Z0-9_
So
'/\${([a-zA-Z0-9_]+)}/',
becomes
'/\${([a-zA-Z0-9_.]+)}/',

Terraform to read variables from environment

I have written a terraform configuration with variable definition like:
variable "GOOGLE_CLOUD_REGION" {
type = string
}
When I run terraform plan I am asked to fill in this variable even though this variable is set within my environment.
Is there a way to tell terraform to work with current env vars? Or do I have to export them and pass them somehow manually one-by-one?
You can define the environment variable TF_VAR_GOOGLE_CLOUD_REGION to set that variable.
If you are using bash, it might look like this:
export TF_VAR_GOOGLE_CLOUD_REGION="$GOOGLE_CLOUD_REGION"
terraform apply ...
From Environment Variables under Configuration Language: Input Variables.
As a fallback for the other ways of defining variables, Terraform searches the environment of its own process for environment variables named TF_VAR_ followed by the name of a declared variable.
This can be useful when running Terraform in automation, or when running a sequence of Terraform commands in succession with the same variables. For example, at a bash prompt on a Unix system:
$ export TF_VAR_image_id=ami-abc123
$ terraform plan
...
You can create a file that ends with .tfvars or .tfvars.json and then when you run a plan you specify that file:
terraform apply -var-file="example.tfvars"
If you name the file terraform.tfvars or terraform.tfvars.json or have a file with names ending in .auto.tfvars or .auto.tfvars.json
then Terraform automatically loads the variable definition file and you don't have to manually specify it when you run a plan.
An example of what the terraform.tfvars file will look like:
first_env_var = "environment_variable_one"
second_env_var = "environment_variable_two"
An example of what the terraform.tfvars.json file will look like:
{
"image_id": "ami-abc123",
"availability_zone_names": ["us-west-1a", "us-west-1c"]
}
I would approach this by creating a variables.tf file, within the project directory. with the required variable block you can specify a default:
variable "GOOGLE_CLOUD_REGION" {
type = string
default = "us-west1"
}
this will then be used as the default value during each run, and you will not be prompted.

How to read Heroku's nested process.env vars / object in nconf?

I'm trying to deploy Ghost 1.2.0 to Heroku. With previous versions of Ghost (<= 0.11.x), they used a config.js file where you could just do:
database: {
client: 'postgres',
connection: {
host: process.env.POSTGRES_HOST,
user: process.env.POSTGRES_USER,
password: process.env.POSTGRES_PASSWORD,
database: process.env.POSTGRES_DATABASE,
port: process.env.POSTGRES_PORT
},
debug: false
}, …
But in this version they're using nconf that replaces this config.js for environment dependent JSON files like config.production.json.
JSON files unlike JS objects can't have vars as values. I could hardcode my credentials to the JSON file, but I don't want to do that because:
Looks like a bad practise to me, and
Heroku rotates credentials periodically and updates applications where this database is attached. (Quoted from Heroku)
After some digging into nconf README and issues I understood that it would be possible to imitate this expected database object just with:
nconf.env({
separator: '__' // Two dashes
});
and defining vars as:
heroku config:set DATABASE__CLIENT=postgres
heroku config:set DATABASE__CONNECTION__HOST=<value>
...
but, no matter what, I get undefined when I later call:
nconf.get('database');
nconf.get('DATABASE'); // In case it was case-sensitive...
Instead, if I call:
nconf.get('DATABASE__CLIENT'); // postgres
it works. I could try (and I will) to modify Ghost scripts to read all variables this way, but as long as it expects a database object it'll be so cool to get it working the right way.
So, has anybody figured out how to correctly recreate an object with Heroku's env vars?
I've finally found the solution.
Unless you want to modify nconf.env(settings) like:
nconf.env({
separator: '__', // Two dashes
lowerCase: true
});
This will make it possible to pass lowerCase: true to env() so that if an environment variable is called SOMETHING or SOMEthing, it will also be gettable using something [Source]
I recommend to use already lowercase env vars.
So,
heroku config:set database__client=postgres
will be readable using:
nconf.get('database:client');
Looks like nconf has a different character separator to define nested variables called separator and another one to read them called logicalSeparator (its default value is :)

Resources