I'm am trying to use the JClouds-Chef API to both bootstrap and configure newly-provisioned Linux VMs in our vCenter. Our DevOps Team (our "Chefs") have recently introduced the concept of Environments to all our recipes, and I was told that I now need to update my JClouds-Chef code to build new environments on the fly. Currently I have the following code, which simply specifies an existing Environment to use:
// Here, "node.getEnvironment()" might return "ourapp_dev" or "ourapp_test", etc.
bootstrapConfig bootstrapConfig = BootstrapConfig.builder()
.environment(node.getEnvironment()).runList(runlist).build();
But now I have to create the Environment myself, on the fly; not use an existing one that is already available on our Chef server.
I was told I could use the Environment
object to do this creation. And it certainly looks that way, given the way the API is set up. However I can't find any working examples, and not being a "Chef" myself, its tough for me to see the forest through the trees here.
Here's the environment I was told I would need to use as a template:
name "{appname}_dev"
description "{appname} Dev Environment"
cookbook_versions({
"our_app" => "= 0.2.0",
"our_logs" => "= 0.1.0"
})
default_attributes(
"our_app" => {
"port" => "{port}",
"app_name" => "{appname}",
"config_vars" => {
"useFizz" => "true",
"host" => "devourapp",
"context" => "devourapp/{appname}"
},
"jar_file_url" => "http://ourartifactory/ourrepo/com/us/{appname}/%5BRELEASE%5D/{appname}-%5BRELEASE%5D.jar"
},
our_logs" => {
"some_resource" => "{appname}",
"log_server" => "logstash.example.com"
}
)
Apparently, anything in { }
curly braces is a variable that I need to pass in some how. So for instance, {appname}
might be fizzbuz
, in which case the first line above would have to resolve to:
name "fizzbuzz_dev"
etc. I can determine these variable names ahead of time in Java code:
String appname = getAppName();
String port = getPort();
// etc.
The problem is that I can't figure out how to use the Environment
API to reproduce the above config, especially when it comes to injecting appname
and port
as variables. Any ideas?
The cookbook versions can be set using the Environment builder object. It has a method that accepts a Map<String, String>
you can use to configure them.
The attributes are a little tricky. As the attribute structure is arbitrary, there is no practical way to represent them in a Java object. You have to use the attributes
method in the Environment builder object, and put the root level attribute names as the keys, and a JsonBall
with the literal json string as the value. Something like the following for a single attribute, but you can already provide the entire map directly to the attributes
(plural) method:
envBuilder.attribute("our_app", new JsonBall("{\"foo\":true}"));
You'll have to manually build the json String with the appropriate values in it.