Skip to content

Instantly share code, notes, and snippets.

@ippeiukai
Created October 5, 2016 02:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ippeiukai/e12b2cd3ae6424d220f2a802443e5548 to your computer and use it in GitHub Desktop.
Save ippeiukai/e12b2cd3ae6424d220f2a802443e5548 to your computer and use it in GitHub Desktop.
For running something only on one instance in an ElasticBeanstalk environment. Inspired by http://blog.rotaready.com/scheduled-tasks-elastic-beanstalk-cron/
"use strict";
const AWS = require('aws-sdk');
const bluebird = require('bluebird');
/**
* @returns {Promise.<boolean>} - is on 'master' instance or not
*/
module.exports = bluebird.coroutine(function* (opts) {
if (opts == null) {
opts = {
// default to use the credentials for the ec2 instance
credentials: new AWS.EC2MetadataCredentials(),
};
}
let instanceId = yield findCurrentInstanceId(opts);
let beanstalkEnvironmentId = yield findEbEnvironmentId(instanceId, opts);
let instanceIds = yield findEbInstanceIds(beanstalkEnvironmentId, opts);
// first in the list is the master
return instanceId === instanceIds[0]
});
const findCurrentInstanceId = function (opts) {
return requestMatadata('/latest/meta-data/instance-id', opts)
};
const findEbEnvironmentId = function (instanceId, opts) {
let params = {
Filters: [
{
Name: "resource-id",
Values: [
instanceId,
]
}
]
};
return requestEc2Tags(params, opts).then(tags => {
let envIdTag = tags.find(t => t.Key === 'elasticbeanstalk:environment-id');
if (envIdTag == null) {
return Promise.reject(new Error('failed to find the value of "elasticbeanstalk:environment-id" tag.'));
}
return envIdTag.Value
})
};
const findEbInstanceIds = function (environmentId, opts) {
let params = {
EnvironmentId: environmentId
};
return requestEbEnvironmentResources(params, opts)
.then(envResources => envResources.Instances.map(it => it.Id))
};
const promisifyMethod = function (obj, name) {
return bluebird.promisify(obj[name], {context: obj})
};
const requestMatadata = function (path, opts) {
let metadata = new AWS.MetadataService(opts);
return promisifyMethod(metadata, 'request')(path)
};
const requestEc2Tags = function (params, opts) {
let ec2 = new AWS.EC2(opts);
return promisifyMethod(ec2, 'describeTags')(params).then(data => data.Tags);
};
const requestEbEnvironmentResources = function (params, opts) {
let elasticbeanstalk = new AWS.ElasticBeanstalk(opts);
return promisifyMethod(elasticbeanstalk, 'describeEnvironmentResources')(params)
.then(data => data.EnvironmentResources)
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment