fum is a tool for managing Amazon Web Services Elastic beanstalk lifecycle stages. fum assists with the following:
-
Managing DNS changes associated with deployments
-
Application version management and deployment
-
Maintaing multiple lifecycle stages (test/staging/production) of an application.
Getting started
fum is a Ruby DSL (Domain Specific Language) similar to rake, chef, and other tools. You declare application lifecycle stages using the fum language, and then use the fum command to manage those stages.
Installing fum is simple:
sudo gem install fum
Create a file named hello.fum
with the following:
application_name 'HelloWorld'
stage :hello do
solution_stack "32bit Amazon Linux running Tomcat 7"
end
Tell fum about your credentials by creating a file named .fum
in your home directory with your AWS credentials (Note, we recommend running these examples only in a development account until you are comfortable using fum):
access_key_id: <YOUR_ACCESS_KEY>
secret_access_key: <YOUR_SECRET_KEY>
Now, let’s go ahead and launch it:
fum hello.fum launch --create hello
This command tells fum to launch a new environment using the “hello” stage definition you have provided in hello.fum
. By default fum will not create new applications or versions, but if you specify the --create
flag, then fum will create the application and a sample version for you if none exists. In this example, fum will create an application named “HelloWorld”. It will also create an environment named “hello” corresponding to the stage you specified.
Adding DNS support.
The previous examle was simple, and possibly a time saver, but is not particularly interesting. If you are developing an app on elastic beanstalk, you most likely don’t want your end users to access your app using “example.elasticbeantalk.com” as the URL. Instead, you most likely want them to access your app using your own hostname such as “www.example.com” or even “example.com” directly. The most flexible way to accomplish this is to use AWS Route 53 which supports alias records that map a domain name to an elastic load balancer. The example below shows how one can map a few different records types to an AWS Route 53 zone name ‘example.com’:
stage :hello do
solution_stack "32bit Amazon Linux running Tomcat 7"
zone 'example.com'
elb_alias :apex # Create an alias entry to the load balancer at the zone apex 'myapp.com.'
elb_alias 'www' # Create an alias entry to the load balancer at 'www.myapp.com.'
elb_cname 'www2' # Create a CNAME to the load balancer rather than an alias record.
cname 'www3' # Create a CNAME to the elastic beanstalk CNAME (useful when using swap cname feature)
end
end
Each stage declaration can have multiple zones and each zone can declare multiple records to create/update when a stage is launched. The elb_alias
directive provides a domain name that should be mapped, you can specify :apex
if you would like to map an alias to the zone apex, in this case ‘example.com’. The elb_cname
creates a CNAME record to the load balancer’s DNS name, while the cname
record creates a CNAME record pointing to the elastic beanstalk environment’s cname.
To run this configuration create a zone named ‘example.com’ using the AWS Managmenent Console and run the following command:
fum hello_r53.fum launch hello
When you run the command, you will notice a few differences in the output from before. First, the newly created environment is
As an alternative to using AWS Route 53, you can use elastic beanstalk’s cname prefix and swapping features to manage your environments. This is configured as follows:
stage :hello do
solution_stack "32bit Amazon Linux running Tomcat 7"
cname_prefix "example", :swap => true
end
The cname_prefix
declaration tells fum what prefix to request for the beanstalk environment when it is launched. By default, fum does not specify a prefix, and lets AWS assign a name dynamically. If you specify a cname prefix, then you must ensure that the name is unique across all AWS customers. You can also specify an option to cname_prefix
to turn on cname swapping. By specifying :swap => true as an option, a newly launched environment will always try to take over the CNAME from any currently running environments.
Let’s try it (Note, if you want to run this sample, you will most likely need to pick a cname prefix other than “example” as it likely not available.):
fum hello_cname.fum launch hello
Login to the AWS Management Console and observe your environment is launched correctly and has the correct CNAME, take note of the environment name created, and then launch another:
fum hello_cname.fum launch hello
Afer the command is complete, login to the AWS Management Console and observe the newly created environemnt now is using the specified CNAME, while the previously created environment is using a dynamically assigned CNAME.
Multiple environments per stage
Stages typically have only one elastic beanstalk environment active at any given time. However, fum uses multiple environments per stage combined with DNS to mask lifecycle changes from the end users of the application. When deploying a new version of your application, or updaing an environment configuration, fum manages the environments and DNS records to provide a seamless rollout for your users.
stage :multi
solution_stack "32bit Amazon Linux running Tomcat 7"
name timestamp_name('multi')
matcher timestamp_name_matcher('multi')
description "Environment multi launched on #{Time.now}."
end
The name directive tells fum what name to give an environment upon launch. You can provide a string as an argument to the name
directive, but then fum will only be able to launch.
Launch two instances:
fum multi.fum launch multi
And the launch another:
fum multi.fum launch multi
You can login to the AWS Managment Console to view them, but you can also use the fum list command as follow:
fum multi.fum status multi
You will notice that the status command displays the name of each environment, followed by
fum multi.fm terminate --all multi
This will terminate all environments that match the
Configuration templates
stage :production
template "production-config"
end
stage :latest
template "latest-config"
end
Version promotion
Up to this point, we haven’t talked about how fum handles application versions. You can specify what version a particular stage uses using the version
directive as follows:
stage :last_release
version "last-release-label"
end
If you run:
fum launch last_release
It will launch an environment. In a typical application environment, you will
# An environment that whose version is automatically updated via a build server.
stage :build do
template 'build-config'
zone 'example.com'
elb_alas 'build' # build.myapp.com will point to this environment.
end
end
stage :staging do
template 'staging-config'
version :from_stage => :build
zone 'example.com'
elb_alias 'staging'
end
end
stage :production do
template 'produciton-config'
version :from_stage => :staging
zone 'example.com'
elb_alias :apex
elb_alias 'www'
end
end
Let’s launch it:
In this example, the “build” stage is
Utility commands
Fum also provides a number of utility commands to aid in manging elastic beanstalk.
The list command allows you to list various beanstalk components. For example:
fum list stacks # List all solutions stacks
fum list env # Lists all environments
The tail command allows you to tail the event log
fum tail
The template command allows for manipulating configuration templates
Why is the tool called “fum”?
Because fum is the final word in managing your AWS Elastic Beanstalk infrastructure.