Wednesday Sep 14, 2011

Automating the Beanstalk Environment

In my last blog, I showed a simple way to get a list of all the configuration options available in an Amazon Elastic Beanstalk environment. These are the options for which no explicit SDK method exists. In this blog, I'll give an example of their use to start up a Beanstalk environment with non-default settings in one step. Using the AWS console, this is normally a two-step process. Note: the AWS command-line tools offer similar capabilities, but using the SDK yields better automation. For instance, after the environment is started, I call a method that waits until the environment is green and all the instances are started.

Before getting to the code, here's a note about how I'm using the credentials. It can be useful to create a separate key pair for each developer or project or however you compartmentalize your work. The AWS key and secret key are tied to an individual account, but commonly are shared within an organization (see the identity faq for more info). You can generate multiple key pairs, however, and can use different pairs for different developers; or use a different key pair for dev vs testing vs production.

By using different key pairs to separate sets of environments, you can perform queries that use the key pair as a filter and thus only act on the environments, instances, etc, that you want. In this example, the code that waits on the Beanstalk environment to come up assumes that there is only one environment per key/secret-key/key-pair combination. To generate more key pairs, click the "Key Pairs" link on the EC2 tab in the AWS console.

The BeanstalkStarter class will start up an environment using the 32 bit Linux OS with Tomcat 7. As of this writing, the solution stack names and AMI IDs in the Beanstalk console are as follows:

Solution Stack AMI
32bit Amazon Linux running Tomcat 7 ami-23de1f4a
64bit Amazon Linux running Tomcat 7 ami-6dde1f04
32bit Amazon Linux running Tomcat 6 ami-39de1f50
64bit Amazon Linux running Tomcat 6 ami-79de1f10

The configuration option for the AMI ID has namespace aws:autoscaling:launchconfiguration and option name ImageId. If you've created your own custom AMI, use your value instead.

The rest of the information for this entry is in comments in the source code. See the code for all the information. In order to focus on setting environment configuration settings, this example starts up a new environment for an existing application. You could do the same thing for creating a new application however.

Wednesday Sep 07, 2011

Querying Amazon Elastic Beanstalk Settings with the AWS SDK

Amazon's Elastic Beanstalk simplifies the tasks of getting a web application deployed in a managed environment. The Java SDK that Amazon provides is easy to use for creating/updating Beanstalk environments. There are accessor methods for the most-used configuration settings, such as setEnvironmentName and setApplicationName.

However, many other configuration settings are not so clear. The SDK uses the generic ConfigurationOptionSetting class for most of a Beanstalk environment's information. This class wraps a namespace, option name, and the option's value. Many of the namespace and option name combinations can be found in the various API references, but there's a simpler way to find them all: ask the environment itself.

The attached BeanstalkConfigQuery class performs a query that lists all the current configuration option settings for your environment. Here are a couple lines of output showing the minimum size of my autoscale group and my AWS access key (which has not yet been set). Spacing was added for readability:

    {Namespace: aws:autoscaling:asg, OptionName: MinSize, Value: 1, }
    {Namespace: aws:elasticbeanstalk:application:environment,
        OptionName: AWS_ACCESS_KEY_ID, Value: , }
Using that information, you can easily create an UpdateEnvironmentRequest object to update a running environment:
        ConfigurationOptionSetting minCOS = new ConfigurationOptionSetting(
            "aws:autoscaling:asg", "MinSize", "3");
        ConfigurationOptionSetting awsKeyCOS = new ConfigurationOptionSetting(
            "AWS_ACCESS_KEY_ID", "my_aws_key_text");
        UpdateEnvironmentRequest updateRequest = new UpdateEnvironmentRequest()
            .withOptionSettings(minCOS, awsKeyCOS);

The BeanstalkConfigQuery class also outputs all the configuration option descriptions, which shows more information about each of the options that you can set. See the comments in the class file for more information, but here are the two descriptions that match the settings listed above. Total, there are close to 50 of these listed when I run against my Beanstalk environment.

    {Namespace: aws:autoscaling:asg, Name: MinSize, DefaultValue: 1,
        ChangeSeverity: NoInterruption, UserDefined: false,
        ValueType: Scalar, ValueOptions: null, MinValue: 1,
        MaxValue: 10000, MaxLength: null, Regex: null, }
    {Namespace: aws:elasticbeanstalk:application:environment,
        Name: AWS_ACCESS_KEY_ID, DefaultValue: ,
        ChangeSeverity: RestartApplicationServer, UserDefined: false,
        ValueType: Scalar, ValueOptions: null, MinValue: null,
        MaxValue: null, MaxLength: 200,
        Regex: {Pattern: ^\S*$, Label: nospaces, }, }

With this information available, the Beanstalk AWS SDK is straightforward to use. In a future post, I'll show an example of programmatically setting up an environment using options like the above. That saves you the step of having to start the environment, wait for it to come up, and then separately update the environment to include the desired settings.


Whatever part of GlassFish or the Java EE world that catches my attention. (Also, go Red Sox.)


« September 2011