Created
October 12, 2018 17:54
-
-
Save logemann/62efc6db2133da19711cb3e93cc07063 to your computer and use it in GitHub Desktop.
Route53 updater in conjunction with ECS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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