Skip to content

Instantly share code, notes, and snippets.

@logemann
Created October 12, 2018 17:54
Show Gist options
  • Save logemann/62efc6db2133da19711cb3e93cc07063 to your computer and use it in GitHub Desktop.
Save logemann/62efc6db2133da19711cb3e93cc07063 to your computer and use it in GitHub Desktop.
Route53 updater in conjunction with ECS
let AWS = require('aws-sdk');
let ec2 = new AWS.EC2();
let ecs = new AWS.ECS();
let route53 = new AWS.Route53();
/**
* expects an environment variable with name "entryparam" and the following value / structure:
* [{
* "cluster": "mycluster1",
* "domain": "demo.mydomain.com",
* "zoneid": "Z1Q3ZVS8H41111"
* },
* {
* "cluster": "mycluster2",
* "domain": "demo.mydomain2.de",
* "zoneid": "Z1Q3Z44444EG25"
* }]
*
* The cluster is the ecs cluster name to look into. The domain indicates the records to create
* for the zone with the zoneid in Route53.
*
* @param event Lambda event object
* @param context Lambda context object
*/
exports.handler = function (event, context) {
console.log("********************************************");
console.log(context.functionName);
console.log("event: ", JSON.stringify(event));
console.log("entryparam:", process.env.entryparam);
console.log("********************************************");
const result = async () => {
let configArray = JSON.parse(process.env.entryparam);
for (let i = 0; i < configArray.length; i++) {
console.log("--- Processing Cluster: " + configArray[i].cluster + " ---");
let publicIp = await getPublicIpForCluster(configArray[i].cluster);
console.log("Updating record '" + configArray[i].domain
+ "' (" + configArray[i].zoneid + ") with Public IP: " + publicIp);
modifyDnsRecord(configArray[i].cluster, configArray[i].domain, publicIp, configArray[i].zoneid);
console.log("--- End of Processing Cluster ---");
}
};
result().then(() => {
context.done(null, event);
}).catch(reason => {
let error = new Error('failed!');
context.done(error, event);
});
};
function modifyDnsRecord(clusterName, domain, publicIp, hostedZoneId) {
let param = {
ChangeBatch: {
"Comment": "Auto generated Record for ECS Fargate Instance " + clusterName,
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": domain,
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": publicIp
}
]
}
}
]
},
HostedZoneId: hostedZoneId
};
route53.changeResourceRecordSets(param, function (err, data) {
if (err) {
console.log(err, err.stack);
}
});
}
async function getPublicIpForCluster(clusterName) {
// lists tasks of cluster
let data = await ecs.listTasks({
cluster: clusterName
}).promise();
let taskId = data.taskArns[0].split("/")[1];
// get Task data
data = await ecs.describeTasks({
cluster: clusterName,
tasks: [
taskId
]
}).promise();
let eniId = "";
// extract "Elastic Network Interface" ENI Id
let detailsArray = data.tasks[0].attachments[0].details;
for (let i = 0; i < detailsArray.length; i++) {
if (detailsArray[i].name === "networkInterfaceId") {
eniId = detailsArray[i].value;
break;
}
}
// get Public IP of the extracted ENI
data = await ec2.describeNetworkInterfaces({
NetworkInterfaceIds: [
eniId
]
}).promise();
return data.NetworkInterfaces[0].PrivateIpAddresses[0].Association.PublicIp;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment