RDS Environment variables not available to Elastic Beanstalk instance on AWS?

Viewed 2817

After creating a Java 8 Elastic Beanstalk instance with RDS, the RDS connection details are not visible as environment variables (they are visible on other instances that are running).

After running printenv command, the expectation was for these values to be available but they are not.

RDS_HOSTNAME=foo.com

RDS_USERNAME=foo

RDS_PASS=bar

These are required by the server config

database:
    driverClass: com.mysql.jdbc.Driver
    user: ${RDS_USERNAME}
    password: ${RDS_PASSWORD}
    url: jdbc:mysql://${RDS_HOSTNAME}/${RDS_DB_NAME}

During application firing they are not available, the logs shows a Java exception that it cannot find the environment variables.

io.dropwizard.configuration.UndefinedEnvironmentVariableException: The environment variable 'RDS_USERNAME' is not defined; could not substitute the expression '${RDS_USERNAME}'. at io.dropwizard.configuration.EnvironmentVariableLookup.lookup(EnvironmentVariableLookup.java:41) at org.apache.commons.lang3.text.StrSubstitutor.resolveVariable(StrSubstitutor.java:934) at org.apache.commons.lang3.text.StrSubstitutor.substitute(StrSubstitutor.java:855) at org.apache.commons.lang3.text.StrSubstitutor.substitute(StrSubstitutor.java:743) at org.apache.commons.lang3.text.StrSubstitutor.replace(StrSubstitutor.java:403) at io.dropwizard.configuration.SubstitutingSourceProvider.open(SubstitutingSourceProvider.java:39) at io.dropwizard.configuration.BaseConfigurationFactory.build(BaseConfigurationFactory.java:83) at io.dropwizard.cli.ConfiguredCommand.parseConfiguration(ConfiguredCommand.java:124) at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:72) at io.dropwizard.cli.Cli.run(Cli.java:75) at io.dropwizard.Application.run(Application.java:93)

However if I run the following command on the ec2 instance

sudo /opt/elasticbeanstalk/bin/get-config environment

It prints the values out in JSON:

{"CONFIG":"dev.yml","RDS_HOSTNAME":"foo.com","RDS_PASSWORD":"foo","M2":"/usr/local/apache-maven/bin","M2_HOME":"/usr/local/apache-maven","RDS_DB_NAME":"foo","JAVA_HOME":"/usr/lib/jvm/java","RDS_USERNAME":"foo","GRADLE_HOME":"/usr/local/gradle","RDS_PORT":"3306"}

Any ideas how to restore these values for the ec2-user?

I have tried:

  • Restarting the EB instance
  • Rebuilding the instance
  • cat the values into a script that sets them after eb deploy

Any ideas, why they are not visible on this particular instance?

Instance details

  Environment details foo: foo-service
  Application name: foo-service
  Region: eu-west-2
  Platform: arn:aws:elasticbeanstalk:eu-west-2::platform/Java 8 running on 64bit Amazon Linux/2.6.0
  Tier: WebServer-Standard
3 Answers

I would run the EB environment update and or replace the Instance. Or you can move to "Storing the Connection String in Amazon S3"

When the environment update is complete, the DB instance's hostname and other connection information are available to your application through the following environment properties:

RDS_HOSTNAME – The hostname of the DB instance. Amazon RDS console label – Endpoint (this is the hostname)

RDS_PORT – The port on which the DB instance accepts connections. The default value varies between DB engines. Amazon RDS console label – Port

RDS_DB_NAME – The database name, ebdb. Amazon RDS console label – DB Name

RDS_USERNAME – The user name that you configured for your database. Amazon RDS console label – Username

RDS_PASSWORD – The password that you configured for your database.

private static Connection getRemoteConnection() {
    if (System.getenv("RDS_HOSTNAME") != null) {
      try {
      Class.forName("org.postgresql.Driver");
      String dbName = System.getenv("RDS_DB_NAME");
      String userName = System.getenv("RDS_USERNAME");
      String password = System.getenv("RDS_PASSWORD");
      String hostname = System.getenv("RDS_HOSTNAME");
      String port = System.getenv("RDS_PORT");
      String jdbcUrl = "jdbc:postgresql://" + hostname + ":" + port + "/" + dbName + "?user=" + userName + "&password=" + password;
      logger.trace("Getting remote connection with connection string from environment variables.");
      Connection con = DriverManager.getConnection(jdbcUrl);
      logger.info("Remote connection successful.");
      return con;
    }
    catch (ClassNotFoundException e) { logger.warn(e.toString());}
    catch (SQLException e) { logger.warn(e.toString());}
    }
    return null;
  }

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/java-rds.html#java-rds-javase

Can you try to initialize them in /etc/environment? When I need to be sure an environment variable exists I make sure and add it there. All user shells will get that variable set that way.

Related