Thursday, March 19, 2015

Maven + Packer + Bamboo, how I got that working!

Maven builds that generate war which you can bake into your favorite base AMIs, using packer and use it for whatever you want, sounds awesome right! But wait, there's a catch. Atleast, in the way I found how it was used at my workplace.

We were using Packer's variables.json and pom.xml version number to let packer provisioners know where the builds were and what version to pick. This works perfectly fine until only developer is committing the versions. In a perfectly ideal world though, thats not the case (pun intended). You work within a team and their will be developers committing their code to their branches ultimately getting merged to develop/master what not. Chances are soon you will loose the versioning if you are used to manually update the versions of both the files I mentioned.

Here's come the CI tool like Jenkins or Bamboo. Using either of those two can really help solve this problem. Allow me to explain how! -

First in your pom.xml, for the version field of the artifact produced by your pom, use placeholders. These placeholders will fill up the version number either using some timestamps, UUIDs or combination of branch and build numbers.

in pom.xml




<version>1.0.${bambooBuildNumber}</version>

when you package using maven, you will simply pass in this argument, something like this for e.g.



 mvn clean package -DbambooBuildNumber=${bamboo.buildResultKey} 


Now you need to make sure Packer knows this version of artifact that was built. As I read more about user variables in Packer template.json, I found that you can't really make use of ENV variables in your variables.json. Instead you need to use them directly in your template.json under the section where you intialize them. Sure thing, no problem, lets get that sorted out too.

Ideally Bamboo|Jenkins allow you to run shell|bash scripts, so what I did was added an ENV variable like for e.g.



 export BAMBOO_BUILD_KEY=${bamboo.buildResultKey} 


Then from my template.json, I can easily access this ENV variable by using something like this

in template.json



{
    "variables": {
        "version": "{{env `BAMBOO_BUILD_KEY`}}"
    }
}
All set and done then go ahead and run packer to bake your AMI





packer build -var-file variables.json template.json



If this above step follows the mvn package step, at the end of it you will see an AMI which will contain your artifact, provided you allowed it to be picked using one of provisioners.

As part of the same CI job, finally you push your built artifacts (war, jar etc) and the ami-id of the baked AMI using this following utility script




 grep 'ami-*' <path>/build-dir/${bamboo.buildResultKey}.log | awk 'match($0, /ami-.*/) { print substr($0, RSTART, RLENGTH) }' >  ami.txt 


The ami.txt will contain the ami-id of the just baked AMI. You can use that info to associate your build artifacts to the AMIs and trace back all the way to the commits which triggered the builds and generated those artifacts. Easy Peasy!

No comments:

Post a Comment