Spring profiles
Things to keep in mind
Is it a good idea to use “dev” as the default profile?
By default, the application should have as much restrictions as possible and default profile should not be ‘dev’ (because in dev mode you can have opened debug ports, so on, and you can just forget to disable all such debug stuff later).
How to handle profiles in deployed environments?
How is the name of the profile to be used specified for deployed environments?
Without putting an entry in application.properties file like profile=default
or profile=develop
or profile=production
?
If you don’t specify a profile specifically, spring works with the default
profile.
All the properties that you want to use in the local computer can go into the application-default.properties
" file.
For the rest of the environments, we need to set-up environment specific property files like application-develop.properties
, application-prod.properties
, etc.
For deployed environments, the name of the profile must be injected while the application is being deployed and started. What is the process to do that?
It is done using the docker-entrypoint.sh
file.
docker-entrypoint.sh
is used in Dockerfile.
Configuring profiles using docker-entrypoint.sh
#!/bin/bash
echo Container TIER is: "$TIER"
echo Container AWS_REGION is: "$REGION"
# These are injected from the pipeline
case "$TIER" in
"prod")
LOG_LEVEL="WARN"
COMPANY_ENV="prod"
;;
"uat" | "qa" | "stage")
LOG_LEVEL="INFO"
COMPANY_ENV=$(echo "$TIER" | tr '[A-Z]' '[a-z]')
;;
*)
LOG_LEVEL="INFO"
COMPANY_ENV="dev"
;;
esac
# end of case statement
case "$REGION" in
"us-east-1" | "us-east-2"
TIMEZONE="America/New_York"
;;
"us-west-1" | "us-west-2"
TIMEZONE="America/Los_Angeles"
;;
*)
TIMEZONE="America/New_York"
;;
esac
# end of case statement
COMPANY_ENV_REGION="$COMPANY_ENV"-"$REGION"
echo Container COMPANY_ENV_REGION is: "$COMPANY_ENV_REGION"
echo Container TIMEZONE is: "$TIMEZONE"
java \
-XX:MaxRAMPercentage=75.0 \
-XshowSettings:vm \
-javaagent:BOOT-INF/lib/aws-opentelemetry-agent-1.17.0.jar \
-Duser.timezone="${TIMEZONE}" \
-Dspring.profiles.active=${COMPANY_ENV},${COMPANY_ENV_REGION} \
-Dotel.javaagent.configuration-file=BOOT-INF/classes/application-${COMPANY-ENV}.properties \
-Dotel.javaagent.extensions=BOOT-INF/lib/edm-opentelemetry-extension-1.4.jar \
org.springframework.boot.loader.JarLauncher
Config for S3 based on different profiles
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
@Configuration
public class AmazonS3ClientConfig {
@Value("${cloud.aws.credentials.accessKey}")
private String awsId;
@Value("${cloud.aws.credentials.secretKey}")
private String awsKey;
@Value("${cloud.aws.region.static}")
private String awsRegion;
@Value("${proxy.host}")
private String proxyHost;
@Value("${proxy.port}")
private String proxyPort;
@Value("${proxy.username}")
private String proxyUserName;
@Value("${proxy.password}")
private String proxyPassword;
private AmazonS3 amazonS3;
// To be used in local development workspace. Using credentials. Avoid this as much as possible.
@Bean
@Profile("default")
public AmazonS3 s3client() {
BasicAWSCredentials awsCredentials = new BasicAWSCredentials(awsId, awsKey);
AmazonS3 amazonS3Client = AmazonS3ClientBuilder.standard().withRegion(Regions.fromName(awsRegion))
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials)).build();
return amazonS3Client;
}
// To be used in local development workspace. Using proxy.
@Bean
@Profile("default")
public AmazonS3 amazonS3() {
amazonS3 = AmazonS3ClientBuilder
.standard()
.withClientCredentials(new ProfileCredentialsProvider("saml"))
.withRegion(Regions.fromName(awsRegion))
.withClientConfiguration(
PredefinedClientConfigurations.defaultConfig()
.withProxyHost(proxyHost)
.withProxyPort(Integer.parseInt(proxyPort))
.withProxyUsername(proxyUserName)
.withProxyPassword(proxyPassword)
)
.build();
return amazonS3Client;
}
// To be used in deployed environments
@Bean
@Profile("!default")
public AmazonS3 amazonS3() {
amazonS3 = AmazonS3ClientBuilder
.standard()
.withRegion(Regions.fromName(awsRegion))
.build();
return amazonS3Client;
}
}
For examples about using BasicAWSCredentials
, look at the internal examples.