Thursday, May 21, 2020

Ways to change property values for Java Spring application in EKS (Kubernetes in AWS)


Issue to solve

When deploying micro services to EKS, we might need to pass different values to the same micro service for different environments.  For example, we might need to use different MSK instances or different encryption keys.  The traditional way (i.e. using application.properties file or yaml file) will not work since the values in these files will be set before docker image is built. Once micro service is deployed to cloud as container, you will have to login into the container to change values in these files and may have to restart your service to take the new value. 

When micro service is deployed through terraform code, we have to pass these values through terraform. 


Solution for passing values from terraform to container

One way to pass property value from terraform to micro service is to use following 'args' in kubernetes_deployment (spec/template/spec/container/args):

 args = [
  "--kafka.bootstrapServers =${var.msk_bootstrap_brokers_tls}",
  "--kafka.zooKeeper_hosts=${var.msk_zookeeper_hosts}",
  "--kafka.topic=mytopic",
  "--kafka.use_ssl=true",
  "--aws_encyption_key=${var.aws_encyption_key}"
]

Another way to do so is to use 'env' in the kubernetes_deployment too (spec/template/spec/container/env).

env {
  name = "kafka.hosts"
  value = ${var.msk_bootstrap_brokers_tls}"
}

env {
  name = "POD_IP"
  value_from  {
    field_ref  {
      field_path = "status.podIP"
    }
  }
}

This will pass these property values through container ENTRYPOINT or environment variables.


Solution for Java Spring code to get and use these values

One way to do so is to use @Value annotation.

@Configuration.  // or @Component
@Slf4j
public class myConfig {

    public myConfig(@Value("${NODE_IP:localhost}") String statsdNodeIP, // default value "localhost"
                    @Value("${kafka.bootstrapServers}") String kafkaServers) {
        // use these values here such as set value to class variable _xxxx;
    }
    @Bean
    public XXXX getXXXX() {
        return  _xxxx;
    }
}


Order of property value overwrite
  1. Command line arguments.
  2. Java System properties (System.getProperties()).
  3. OS environment variables.
  4. @PropertySource annotations on your @Configuration classes.
  5. Application properties outside of your packaged jar (application.properties including YAML and profile variants).
  6. Application properties packaged inside your jar (application.properties including YAML and profile variants).
  7. Default properties (specified using SpringApplication.setDefaultProperties).

Reference

https://docs.spring.io/spring-boot/docs/1.0.1.RELEASE/reference/html/boot-features-external-config.html

No comments:

Post a Comment