Rocoto use case: Elastic Beanstalk

24 views
Skip to first unread message

Timothy Peierls

unread,
Jan 18, 2012, 1:31:46 PM1/18/12
to roc...@googlegroups.com
I turned to Rocoto to make it easier to configure a web component that I run in two different ways:
  1. locally as an executable jar within Ant (development), and
  2. on the web in an Amazon Elastic Beanstalk application (staging and production).
My application makes use of Guice's @Named annotation in several bindings in different packages; the values for these bindings come from system properties and properties files (classpath resources) that have been filtered with Ant to replace tokens with build-time values. The latter is useful for "burning in" configuration values known at build time.

Sensitive information shouldn't be burned into the executable, however. Elastic Beanstalk lets you define certain variables in the configuration of an application environment that are then available to your application as system properties. For example, you can define AWS_ACCESS_KEY_ID and AWS_SECRET_KEY through the AWS console, and your application can then use those Amazon S3 credentials to get access to a richer set of configuration data. 

I had rolled my own utility class to resolve ${x} variables as system properties -- I even supported defaults as ${x:defval} -- and bind them using Names.bindProperties, but it was still very messy and over-coupled. I wanted a way to avoid having to make a distinction about where properties came from within my Java code, I wanted to reduce coupling, and I wanted to simplify my Ant build file.

Enter Rocoto, two days ago. It has allowed me to address all of my concerns. One trick that has proved useful: Instead of defining the ElasticBeanstalk variables as system properties in the Ant target that runs my component, I define all Ant properties that affect the configuration with a common prefix, using Ant's <syspropertyset> to pass them as system properties, and accept both the Elastic Beanstalk name and my local name in the code:

    // Exposed to those who need @Named(AWS_ACCESS_KEY_ID):
    public static final String AWS_ACCESS_KEY_ID = "aws.access.key.id";

    // In module:
    @Override protected void bindConfigurations() {
        bindProperty(AWS_ACCESS_KEY_ID)
            .toValue("${common.ant.property.prefix.accesskeyid|}${AWS_ACCESS_KEY_ID|}");
    }

    // Elsewhere:
    @Inject CloudCredentials(@Named(AWS_ACCESS_KEY_ID) accessKeyId, ...) ...

Note how an empty default is supplied for each alternative. Only one of the alternatives is defined as a system property, the former when running locally, the latter when running in Elastic Beanstalk.

--tim

Simone Tripodi

unread,
Jan 20, 2012, 2:53:47 AM1/20/12
to roc...@googlegroups.com
Hi Tim,

thanks for the kind feedback, very appreciated!!! That is the real
purpose of the OSS that I like, sharing something useful with someone
else has the same needs, build a community and evolve the software :)

Just for the record: if in the future you will need
Systems/Environments properties, managed by Guice, inside your
application, you can drop the Ant dependency and just use the already
provided ConfigurationModule[1] that has some shortcuts to bind Named
variables inside Guice.

All the best, have a nice day!
-Simo

[1] http://99soft.github.com/rocoto/configuration.html

http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/

Timothy Peierls

unread,
Jan 20, 2012, 9:20:48 AM1/20/12
to roc...@googlegroups.com
On Friday, January 20, 2012 2:53:47 AM UTC-5, Simone Tripodi wrote:

Just for the record: if in the future you will need
Systems/Environments properties, managed by Guice, inside your
application, you can drop the Ant dependency and just use the already
provided ConfigurationModule[1] that has some shortcuts to bind Named
variables inside Guice.


I should have been clearer: I am using bindSystemProperties(), and it is indeed very convenient. 

My post was focused on how to deal with property values coming from one of two alternatives. In that case, I use bindProperty("X").toValue("${Y|}${Z|}"), and I have to make sure that X is not in the set of properties bound with bindSystemProperties().

This last restriction is slightly unfortunate. It would nice if bindSystemProperties came with a variant that only bound system properties that were not otherwise bound. I guess that's a feature request -- I'll think about it some more and post an issue if it still bothers me.

--tim


Simone Tripodi

unread,
Jan 20, 2012, 9:41:08 AM1/20/12
to roc...@googlegroups.com
Apologize for the misunderstanding!

Yes that would be a feature request - push requests are welcome! :)

-Simo

Reply all
Reply to author
Forward
0 new messages