-
-
Save ivankatliarchuk/0e48f26551cb2e938fd18bc5ebdccd58 to your computer and use it in GitHub Desktop.
Update an AWS Security Group to allow access by a specific AWS service.
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
'use strict'; | |
const AWS = require('aws-sdk'); | |
const https = require('https'); | |
const ec2 = new AWS.EC2(); | |
const ipRangesUrl = 'https://ip-ranges.amazonaws.com/ip-ranges.json'; | |
const target = { | |
port: 5432, | |
protocol: 'tcp', | |
region: 'ap-southeast-2', | |
securityGroupId: 'sg-12345678', | |
service: 'EC2' | |
}; | |
const getIngressRules = () => { | |
return new Promise((resolve, reject) => { | |
console.log(`Getting SG Ingress rules for ${target.securityGroupId}`); | |
let params = { GroupIds: [ target.securityGroupId ] }; | |
ec2.describeSecurityGroups(params, (err, data) => { | |
if (err) return reject(err); | |
return resolve(data); | |
}); | |
}); | |
}; | |
// Remove all given SG Ingress rules | |
const removeIngressRules = (data) => { | |
return new Promise((resolve, reject) => { | |
let params = data.SecurityGroups[0]; | |
if (params.IpPermissions.length > 0) { | |
console.log(`Removing ${params.IpPermissions.length} ingress rules`); | |
// Convert describeSecurityGroups to revokeSecurityGroupIngress format. | |
delete params.OwnerId; | |
delete params.Description; | |
delete params.IpPermissionsEgress; | |
delete params.VpcId; | |
delete params.Tags; | |
delete params.IpPermissions[0].PrefixListIds; | |
delete params.IpPermissions[0].UserIdGroupPairs; | |
ec2.revokeSecurityGroupIngress(params, (err) => { | |
if (err) return reject(err); | |
return resolve(); | |
}); | |
} else { | |
console.log('No ingress rules found'); | |
return resolve(); | |
} | |
}); | |
}; | |
// Get IP ranges from AWS | |
const getIpRanges = () => { | |
return new Promise((resolve, reject) => { | |
https.get('https://ip-ranges.amazonaws.com/ip-ranges.json', (response) => { | |
let data = ''; | |
response.setEncoding('utf8'); | |
response.on('data', (d) => { data += d; }); | |
response.on('error', (e) => { return reject(e); }); | |
response.on('end', () => { | |
return resolve(JSON.parse(data)); | |
}); | |
}); | |
}); | |
}; | |
// Convert an IP range object to a SG Ingress Rule. | |
const toRule = (rangeObject) => { | |
return { | |
FromPort: target.port, | |
ToPort: target.port, | |
IpProtocol: target.protocol, | |
IpRanges: [ | |
{ | |
CidrIp: rangeObject.ip_prefix, | |
} | |
] | |
}; | |
}; | |
// Add Ingress Rules to SG | |
const addIngressRules = (ipRanges) => { | |
return new Promise((resolve, reject) => { | |
const rules = ipRanges. | |
prefixes. | |
filter((i) => { | |
return i.service === target.service && i.region === target.region; | |
}). | |
map(toRule); | |
const params = { GroupId: target.securityGroupId, IpPermissions: rules }; | |
console.log(`Adding ${rules.length} ingress rules (as one rule)`); | |
ec2.authorizeSecurityGroupIngress(params, (err, data) => { | |
if (err) return reject(err); | |
return resolve(); | |
}); | |
}); | |
}; | |
exports.handle = (event, context) => { | |
getIngressRules(target.securityGroupId). | |
then(removeIngressRules). | |
then(getIpRanges). | |
then(addIngressRules). | |
then(() => { context.succeed(true); }). | |
catch((err) => { context.fail(err); }); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment