Reconfiguring an AWS Elastic IP with Pallet

December 8, 2013

I was recently playing around with Pallet (as an offshoot of some of the DevOps-style cloud provisioning work I do on Project Clearwater), and had a bit of trouble getting from Pallet to the underlying jClouds API (I was using 1.5.5).

Specifically, I wanted to associate an EC2 elastic IP address with the new node I'd created with Pallet, effectively making it a drop-in replacement for a failed box.

This is the code I ended up with, relying on the fact that pallet.api/converge returns a map with a :environment parameter, which in turn has a :compute object which is a jClouds ComputeService object, which you can do Java interop on:

(let [node-data (pallet.api/converge ...)
      node (:node (first (:new-nodes node-data)))
      compute (:compute (:environment node-data))]
    (-> compute
        .getContext
        .getProviderSpecificContext ; AWS-specific function
        .getApi ; [1]
        .getElasticIPAddressServices
        (.associateAddressInRegion "us-east-1", "54.204.28.146", (.getProviderId node)))) ; [2]

[1] .getApi returns an AWSEC2Client, which you can use to access other EC2 services.

[2] Obviously, this elastic IP was specific to me (and I've since deleted it).

Since then, I've found that there is a nicer Clojure interface to jClouds. I haven't tested it, but the above code should then look something like this:

(let [node-data (pallet.api/converge ...)
      node (:node (first (:new-nodes node-data)))
      compute (:compute (:environment node-data))
      eip (org.jclouds.aws.elastic-ip/eip-service compute)]
      (with-compute-service [compute]
        (org.jclouds.aws.elastic-ip/associate node "54.204.28.146")))