How can/do I configure my Spring app to check a specific tag of configs with custom directory? - spring-boot

Suppose I have the following dir:
root.properties
dev-ci
common.properties
app_dir
app.properties
prod
stage
test
test/stage/prod all follow dev-ci's dir/path structure.
How can I setup my bootstrap.yml file so that when I start my app, it'll load the following:
root.properties
dev-ci/common.properties
dev-ci/app_dir/app.properties
Is there a way to set up my yml so that it takes some parameter from commandline? Or will I have to map out all the possible 'paths' then pass in some label/name?
Lastly, where does the tag name come into play?

Related

Serverless stage environment variables using dotenv (.env)

I'm new to serverless,
So far I was be able to deploy and use .env for the app.
then, under provider in stage property in serverless.yml file, I change it to different stage. I also made new.env.{stage}.
after re-deploy using sls deploy, It still reads the default .env file.
the documentation states:
The framework looks for .env and .env.{stage} files in service directory and then tries to load them using dotenv. If .env.{stage} is found, .env will not be loaded. If stage is not explicitly defined, it defaults to dev.
So, I still don't understand "If stage is not explicitly defined, it defaults to dev". How to explicitly define it?
The dotenv File is choosen based on your stage property configuration. You need to explicitly define the stage property in your serverless.yaml or set it within your deployment command.
This will use the .env.dev file
useDotenv: true
provider:
name: aws
stage: dev # dev [default], stage, prod
memorySize: 3008
timeout: 30
Or you set the stage property via deploy command.
This will use the .env.prod file
sls deploy --stage prod
In your serverless.yml you need to define the stage property inside the provider object.
Example:
provider:
name: aws
[...]
stage: prod
As Feb 2023 I'm going to attempt to give my solution. I'm using the Nx tootling for monorepo (this shouldn't matter but just in case) and I'm using the serverless.ts instead.
I see the purpose of this to be to enhance the developer experience in the sense that it is nice to just nx run users:serve --stage=test (in my case using Nx) or sls offline --stage=test and serverless to be able to load the appropriate variables for that specific environment.
Some people went the route of using several .env.<stage> per environment. I tried to go this route but because I'm not that good of a developer I couldn't make it work. The approach that worked for the was to concatenate variable names inside the serverless.ts. Let me explain...
I'm using just one .env file instead but changing variable names based on the --stage. The magic is happening in the serverless.ts
// .env
STAGE_development=test
DB_NAME_development=mycraftypal
DB_USER_development=postgres
DB_PASSWORD_development=abcde1234
DB_PORT_development=5432
READER_development=localhost // this could be aws rds uri per db instances
WRITER_development=localhost // this could be aws rds uri per db instances
# TEST
STAGE_test=test
DB_NAME_test=mycraftypal
DB_USER_test=postgres
DB_PASSWORD_test=abcde1234
DB_PORT_test=5433
READER_test=localhost // this could be aws rds uri per db instances
WRITER_test=localhost // this could be aws rds uri per db instances
// serverless.base.ts or serverless.ts based on your configuration
...
useDotenv: true, // this property is at the root level
...
provider: {
...
stage: '${opt:stage, "development"}', // get the --stage flag value or default to development
...,
environment: {
STAGE: '${env:STAGE_${self:provider.stage}}}',
DB_NAME: '${env:DB_NAME_${self:provider.stage}}',
DB_USER: '${env:DB_USER_${self:provider.stage}}',
DB_PASSWORD: '${env:DB_PASSWORD_${self:provider.stage}}',
READER: '${env:READER_${self:provider.stage}}',
WRITER: '${env:WRITER_${self:provider.stage}}',
DB_PORT: '${env:DB_PORT_${self:provider.stage}}',
AWS_NODEJS_CONNECTION_REUSE_ENABLED: '1',
}
...
}
When one is utilizing the useDotenv: true, serverless loads your variables from the .env and puts them in the env variable so you can access them env:STAGE.
Now I can access the variable with dynamic stage like so ${env:DB_PORT_${self:provider.stage}}. If you look at the .env file each variable has the ..._<stage> at the end. In this way I can retrieve dynamically each value.
I'm still figuring it out since I don't want to have the word production in my url but still get the values dynamically and since I'm concatenating this value ${env:DB_PORT_${self:provider.stage}}... then the actual variable becomes DB_PORT_ instead of DB_PORT.

google deployment manager, can you import files in jinja template that you call directly with --template?

https://cloud.google.com/deployment-manager/docs/configuration/templates/create-basic-template
I can deploy a template directly like this: gcloud deployment-manager deployments create a-single-vm --template vm_template.jinja
But what if that template depends on other files that need to be imported? If using a --config file you can define import in that file and call the template as a resource. But you cant pass parameter/properties to a config file. I want to call a template directly to pass --properties via the command line but that template also needs to import other files.
EDIT: What I needed was a top level jinja template instead of a config. My confusion was that you cant use imports in a jinja template without a schema file- it was failing and I thought it wasnt supported. So the solution was just swap out the config with a jinja template (with schema file) and then I can use --properies
Maybe you can try importing the dependent files into your config file as follows:
imports:
- path: vm-template.jinja
- path: vm-template-2.jinja
# In the resources section below, the properties of the resources are replaced
# with the names of the templates.
resources:
- name: vm-1
type: vm-template.jinja
- name: vm-2
type: vm-template-2.jinja
and Set Arbitrary Metadata insito create a special variable that you can pass and might use in other applications outside of Deployment Manager:
properties:
size:
type: integer
default: 2
description: Number of Mongo Slaves
variable-x: ultra-secret-sauce
More info about gcloud deployment-manager deployments create optional flags and example can be found here.
More info about passing properties using a Schema can be found here
Hope it helps

Spring Cloud Config Server serving nested plain text files

I have a Config Server up and running, with the relevant application.yml setting of
spring:
application:
name: config
...
searchPaths:
- '{application}'
- '{application}/{profile}'
I would like to access a file that is not application.properties, something like myfile.txt. If I have the git layout
/myapp/nested/folder/myfile.txt
I want to be able to access that file. According to the Spring Config Server docs, I should be able to do this via /{name}/{profile}/{label}/{path}, but I can't get any paths to work.
TL;DR: How do I retrieve nested config files from a git repo via Config Server?
TL;DR: The documentation is wrong. The endpoint /{name}/{profile}/{label}/{path} should be written as /{application}/{profile}/{label}/{path}. You just need to make sure that one of your searchPaths/{path} can resolve your file.
First off, {label} is, as always, the git branch name (probably "master").
Second, {path} can can be an absolute path to the file. It uses /, i.e., myapp/nested/folder/myfile.txt, not (_) as is required in {application} or {label}.
Third, the search paths in the question are set to '{application}' and '{application}/{profile}', along with the default search path of /, the git repo's root directory. These define the places Config Server will search for a plain text file as:
/{expanded application}/{path}
/{expanded application}/{profile}/{path}
/{path}
Note that only {application} can be expanded into multiple folders with (_) and that only {path} can include multiple folders with /. For instance, with these searchPaths and a file located at /myapp/nested/folder/myfile.txt, the following requests are valid:
/asdf/asdf/master/myapp/nested/folder/myfile.txt
/myapp/asdf/master/nested/folder/myfile.txt
/myapp/nested/master/folder/myfile.txt
/myapp(_)nested(_)folder/asdf/master/myfile.txt
/myapp(_)nested/folder/master/myfile.txt
where asdf can be any arbitrary string.

Loading multiple config file from spring cloud config server

Hey I got to know how to check properties in config server i.e. http://{Config server URL}:{Port}/{ServiceID}/{Profile}
Right now I am facing a problem where I've to read multiple properties file from cloud config server. Ex: Right now I've to read properties file(huge file) from a single property file i.e. employee.properties
I don't want huge list of properties file in single folder. like
employee-dev.properties
employee-dit.properties
employee-sit.properties
employee-uat.properties
employee-preprod.properties
employee-prod.properties
customers-dev.properties
customers-dit.properties
customers-sit.properties
customers-uat.properties
customers-preprod.properties
customers-prod.properties
.
.
.
and soo on.
My requirement is I need to maitain a list of properties file and config server will provide me these values. like :
**{env}/employee.properties**
**{env}/customers.properties**
Here env could be any environment like dit, sit, prod etc.
Hope I'll get answer here.
If you don't want to have all properties files in an only folder, so you need to add this configuration on config server properties file.
1. Match all options
spring.cloud.config.server.native.searchLocations = [classpath:/, classpath:/config, classpath:/config/{application}, classpath:/config/{application}/{profile}]
2. Match only /application-name/application-name-profile.properties
spring.cloud.config.server.native.searchLocations = classpath:config/{application}
Then you'll have matched based on application name folder for example.
resources/config/application-name/application-name-properties.

Spring Boot yaml configuration doesn't load second key

I'm trying to create a config file in yaml for my Spring Boot project.
For a test I just setup some values:
user:
test: hello
Now I'm trying to get the information of user.test, but I get the error message Could not resolve placeholder 'user.test' in value "${user.test}"
The strange thing is, that if my config files just has user.test: hello, then everything works fine.
Is there something that I have to setup before to work with yml files as properties?

Resources