Skip to content

Instantly share code, notes, and snippets.

@bernays
Last active February 22, 2020 12:20
Show Gist options
  • Save bernays/db62c2af7d3b865410c71a68716b4bf6 to your computer and use it in GitHub Desktop.
Save bernays/db62c2af7d3b865410c71a68716b4bf6 to your computer and use it in GitHub Desktop.
Lambda-Assign-EIP-Lifecyclehook
/*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