Last active
February 22, 2020 12:20
-
-
Save bernays/db62c2af7d3b865410c71a68716b4bf6 to your computer and use it in GitHub Desktop.
Lambda-Assign-EIP-Lifecyclehook
This file contains hidden or 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
/*Problem: Integration into 3rd party API requires IP whitelisting. Servers are dynamically started and stopped. | |
Solution: assign predefined EIPs to EC2 instances as the Auto Scaling group size increases | |
Limitations: Need to predefine and preallocate all IP addresses | |
Other possible solutions: | |
1) Proxy all requests through single NAT instance | |
i. limitation: single point of failure | |
ii. need similar solution to make sure NAT is highly available | |
2) Remove whitelisting requirement | |
i. no...just no ... not gonna happen | |
3) Possibly integrate with 3rd party to dynamically whitelist new IP addresses | |
i. Not all APIs have that ability | |
*/ | |
//Steps: | |
// 1: Create Auto Scale Group | |
// 2: Create Role for Lambda | |
// 3: Create Lambda Function | |
// 4: Attach | |
aws autoscaling put-lifecycle-hook \ | |
--lifecycle-hook-name 'Name' \ | |
--auto-scaling-group-name 'ASG Name' \ | |
--lifecycle-transition autoscaling:EC2_INSTANCE_LAUNCHING \ | |
--notification-target-arn 'SNS Topic' \ | |
--role-arn 'Role' | |
//TODO: send email when running "low" on Elastic IPs | |
var AWS = require('aws-sdk'); | |
exports.handler = (event, context, callback) => { | |
var Lifecycleparams = { | |
AutoScalingGroupName: event.detail.AutoScalingGroupName, | |
LifecycleActionResult: 'CONTINUE', | |
LifecycleHookName: event.detail.LifecycleHookName, | |
LifecycleActionToken: event.detail.LifecycleActionToken | |
}; | |
var autoscaling = new AWS.AutoScaling(); | |
var ec2 = new AWS.EC2(); | |
//EIPs that are whitelisted on 3rd party service | |
var descr_EIP_params = { | |
//Replace with own EIPs that you have already created | |
PublicIps: ['192.168.1.2', '192.168.1.3', '192.168.1.4'], | |
Filters: [{ | |
Name: "domain", | |
Values: [ | |
"vpc" | |
] | |
}] | |
}; | |
//Get EIP AssociationId and AllocationId | |
ec2.describeAddresses(descr_EIP_params, function(err, data) { | |
if (err) { | |
console.log(err, err.stack); | |
callback(err); | |
} // an error occurred | |
else { | |
//Iterate through EIPs that are whitelisted to find an open one | |
for (var i = 0; i < data.Addresses.length; i++) { | |
if (data.Addresses[i].AssociationId == undefined) { | |
var assoc_EIP_params = { | |
AllowReassociation: true, | |
DryRun: false, | |
InstanceId: event.detail.EC2InstanceId | |
}; | |
assoc_EIP_params.AllocationId = data.Addresses[i].AllocationId; | |
//Associate unattached EIP with new instance | |
ec2.associateAddress(assoc_EIP_params, function(err, data) { | |
if (err) { | |
console.log(err, err.stack); | |
callback(err); | |
} // an error occurred | |
else { | |
//Complete autoscaling Lifecycle action | |
autoscaling.completeLifecycleAction(Lifecycleparams, function(err, data) { | |
if (err) { | |
console.log(err, err.stack); | |
callback(err); | |
} // an error occurred | |
else { | |
//End lambda | |
callback(null,'Success'); | |
} | |
}); | |
} | |
}); | |
break; | |
} | |
} | |
} | |
}); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment