@cloudsnorkel/cdk-github-runners
Version:
CDK construct to create GitHub Actions self-hosted runners. Creates ephemeral runners on demand. Easy to deploy and highly customizable.
87 lines • 14.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = handler;
const client_ec2_1 = require("@aws-sdk/client-ec2");
const client_imagebuilder_1 = require("@aws-sdk/client-imagebuilder");
const client_ssm_1 = require("@aws-sdk/client-ssm");
const lambda_helpers_1 = require("../lambda-helpers");
const ssm = new client_ssm_1.SSMClient();
const ec2 = new client_ec2_1.EC2Client();
const ib = new client_imagebuilder_1.ImagebuilderClient();
async function handleAmi(event, ami) {
const imageDescs = (await ec2.send(new client_ec2_1.DescribeImagesCommand({ ImageIds: [ami] })));
if (imageDescs.Images?.length !== 1) {
await (0, lambda_helpers_1.customResourceRespond)(event, 'FAILED', `${ami} doesn't exist`, 'ERROR', {});
return;
}
const rootDevice = imageDescs.Images[0].RootDeviceName;
if (!rootDevice) {
await (0, lambda_helpers_1.customResourceRespond)(event, 'FAILED', `${ami} has no root device`, 'ERROR', {});
return;
}
console.log(`Root device for ${ami} is ${rootDevice}`);
await (0, lambda_helpers_1.customResourceRespond)(event, 'SUCCESS', 'OK', rootDevice, {});
return;
}
async function handler(event, context) {
try {
console.log({ ...event, ResponseURL: '...' });
const ami = event.ResourceProperties.Ami;
switch (event.RequestType) {
case 'Create':
case 'Update':
if (ami.startsWith('ami-')) {
console.log(`Checking AMI ${ami}`);
await handleAmi(event, ami);
break;
}
if (ami.startsWith('resolve:ssm:')) {
const ssmParam = ami.substring('resolve:ssm:'.length);
console.log(`Checking SSM ${ssmParam}`);
const ssmValue = (await ssm.send(new client_ssm_1.GetParameterCommand({ Name: ssmParam }))).Parameter?.Value;
if (!ssmValue) {
await (0, lambda_helpers_1.customResourceRespond)(event, 'FAILED', `${ami} has no value`, 'ERROR', {});
break;
}
await handleAmi(event, ssmValue);
break;
}
if (ami.startsWith('lt-')) {
console.log(`Checking Launch Template ${ami}`);
const lts = await ec2.send(new client_ec2_1.DescribeLaunchTemplateVersionsCommand({ LaunchTemplateId: ami, Versions: ['$Latest'] }));
if (lts.LaunchTemplateVersions?.length !== 1) {
await (0, lambda_helpers_1.customResourceRespond)(event, 'FAILED', `${ami} doesn't exist`, 'ERROR', {});
break;
}
if (!lts.LaunchTemplateVersions[0].LaunchTemplateData?.ImageId) {
await (0, lambda_helpers_1.customResourceRespond)(event, 'FAILED', `${ami} doesn't have an AMI`, 'ERROR', {});
break;
}
await handleAmi(event, lts.LaunchTemplateVersions[0].LaunchTemplateData.ImageId);
break;
}
if (ami.match('^arn:aws[^:]*:imagebuilder:[^:]+:[^:]+:image/.*$')) {
console.log(`Checking Image Builder ${ami}`);
const img = await ib.send(new client_imagebuilder_1.GetImageCommand({ imageBuildVersionArn: ami }));
const actualAmi = img.image?.outputResources?.amis?.[0]?.image;
if (!actualAmi) {
await (0, lambda_helpers_1.customResourceRespond)(event, 'FAILED', `${ami} doesn't have an AMI`, 'ERROR', {});
break;
}
await handleAmi(event, actualAmi);
break;
}
await (0, lambda_helpers_1.customResourceRespond)(event, 'FAILED', `Unknown type of AMI ${ami}`, 'ERROR', {});
break;
case 'Delete':
console.log('Nothing to delete');
await (0, lambda_helpers_1.customResourceRespond)(event, 'SUCCESS', 'OK', event.PhysicalResourceId, {});
break;
}
}
catch (e) {
console.error(e);
await (0, lambda_helpers_1.customResourceRespond)(event, 'FAILED', e.message || 'Internal Error', context.logStreamName, {});
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW1pLXJvb3QtZGV2aWNlLmxhbWJkYS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wcm92aWRlcnMvYW1pLXJvb3QtZGV2aWNlLmxhbWJkYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQStCQSwwQkF5RUM7QUF4R0Qsb0RBQThHO0FBQzlHLHNFQUFtRjtBQUNuRixvREFBcUU7QUFFckUsc0RBQTBEO0FBRTFELE1BQU0sR0FBRyxHQUFHLElBQUksc0JBQVMsRUFBRSxDQUFDO0FBQzVCLE1BQU0sR0FBRyxHQUFHLElBQUksc0JBQVMsRUFBRSxDQUFDO0FBQzVCLE1BQU0sRUFBRSxHQUFHLElBQUksd0NBQWtCLEVBQUUsQ0FBQztBQUdwQyxLQUFLLFVBQVUsU0FBUyxDQUFDLEtBQWtELEVBQUUsR0FBVztJQUN0RixNQUFNLFVBQVUsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLGtDQUFxQixDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwRixJQUFJLFVBQVUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3BDLE1BQU0sSUFBQSxzQ0FBcUIsRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLEdBQUcsR0FBRyxnQkFBZ0IsRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDbEYsT0FBTztJQUNULENBQUM7SUFFRCxNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQztJQUN2RCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDaEIsTUFBTSxJQUFBLHNDQUFxQixFQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsR0FBRyxHQUFHLHFCQUFxQixFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN2RixPQUFPO0lBQ1QsQ0FBQztJQUVELE9BQU8s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QUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqQixNQUFNLElBQUEsc0NBQXFCLEVBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRyxDQUFXLENBQUMsT0FBTyxJQUFJLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDcEgsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEZXNjcmliZUltYWdlc0NvbW1hbmQsIERlc2NyaWJlTGF1bmNoVGVtcGxhdGVWZXJzaW9uc0NvbW1hbmQsIEVDMkNsaWVudCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1lYzInO1xuaW1wb3J0IHsgR2V0SW1hZ2VDb21tYW5kLCBJbWFnZWJ1aWxkZXJDbGllbnQgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtaW1hZ2VidWlsZGVyJztcbmltcG9ydCB7IEdldFBhcmFtZXRlckNvbW1hbmQsIFNTTUNsaWVudCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1zc20nO1xuaW1wb3J0ICogYXMgQVdTTGFtYmRhIGZyb20gJ2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgY3VzdG9tUmVzb3VyY2VSZXNwb25kIH0gZnJvbSAnLi4vbGFtYmRhLWhlbHBlcnMnO1xuXG5jb25zdCBzc20gPSBuZXcgU1NNQ2xpZW50KCk7XG5jb25zdCBlYzIgPSBuZXcgRUMyQ2xpZW50KCk7XG5jb25zdCBpYiA9IG5ldyBJbWFnZWJ1aWxkZXJDbGllbnQoKTtcblxuXG5hc3luYyBmdW5jdGlvbiBoYW5kbGVBbWkoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGFtaTogc3RyaW5nKSB7XG4gIGNvbnN0IGltYWdlRGVzY3MgPSAoYXdhaXQgZWMyLnNlbmQobmV3IERlc2NyaWJlSW1hZ2VzQ29tbWFuZCh7IEltYWdlSWRzOiBbYW1pXSB9KSkpO1xuICBpZiAoaW1hZ2VEZXNjcy5JbWFnZXM/Lmxlbmd0aCAhPT0gMSkge1xuICAgIGF3YWl0IGN1c3RvbVJlc291cmNlUmVzcG9uZChldmVudCwgJ0ZBSUxFRCcsIGAke2FtaX0gZG9lc24ndCBleGlzdGAsICdFUlJPUicsIHt9KTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCByb290RGV2aWNlID0gaW1hZ2VEZXNjcy5JbWFnZXNbMF0uUm9vdERldmljZU5hbWU7XG4gIGlmICghcm9vdERldmljZSkge1xuICAgIGF3YWl0IGN1c3RvbVJlc291cmNlUmVzcG9uZChldmVudCwgJ0ZBSUxFRCcsIGAke2FtaX0gaGFzIG5vIHJvb3QgZGV2aWNlYCwgJ0VSUk9SJywge30pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnNvbGUubG9nKGBSb290IGRldmljZSBmb3IgJHthbWl9IGlzICR7cm9vdERldmljZX1gKTtcblxuICBhd2FpdCBjdXN0b21SZXNvdXJjZVJlc3BvbmQoZXZlbnQsICdTVUNDRVNTJywgJ09LJywgcm9vdERldmljZSwge30pO1xuICByZXR1cm47XG59XG5cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSB7XG4gIHRyeSB7XG4gICAgY29uc29sZS5sb2coeyAuLi5ldmVudCwgUmVzcG9uc2VVUkw6ICcuLi4nIH0pO1xuXG4gICAgY29uc3QgYW1pID0gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLkFtaSBhcyBzdHJpbmc7XG5cbiAgICBzd2l0Y2ggKGV2ZW50LlJlcXVlc3RUeXBlKSB7XG4gICAgICBjYXNlICdDcmVhdGUnOlxuICAgICAgY2FzZSAnVXBkYXRlJzpcbiAgICAgICAgaWYgKGFtaS5zdGFydHNXaXRoKCdhbWktJykpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgQ2hlY2tpbmcgQU1JICR7YW1pfWApO1xuXG4gICAgICAgICAgYXdhaXQgaGFuZGxlQW1pKGV2ZW50LCBhbWkpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGFtaS5zdGFydHNXaXRoKCdyZXNvbHZlOnNzbTonKSkge1xuICAgICAgICAgIGNvbnN0IHNzbVBhcmFtID0gYW1pLnN1YnN0cmluZygncmVzb2x2ZTpzc206Jy5sZW5ndGgpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBDaGVja2luZyBTU00gJHtzc21QYXJhbX1gKTtcblxuICAgICAgICAgIGNvbnN0IHNzbVZhbHVlID0gKGF3YWl0IHNzbS5zZW5kKG5ldyBHZXRQYXJhbWV0ZXJDb21tYW5kKHsgTmFtZTogc3NtUGFyYW0gfSkpKS5QYXJhbWV0ZXI/LlZhbHVlO1xuICAgICAgICAgIGlmICghc3NtVmFsdWUpIHtcbiAgICAgICAgICAgIGF3YWl0IGN1c3RvbVJlc291cmNlUmVzcG9uZChldmVudCwgJ0ZBSUxFRCcsIGAke2FtaX0gaGFzIG5vIHZhbHVlYCwgJ0VSUk9SJywge30pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYXdhaXQgaGFuZGxlQW1pKGV2ZW50LCBzc21WYWx1ZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYW1pLnN0YXJ0c1dpdGgoJ2x0LScpKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYENoZWNraW5nIExhdW5jaCBUZW1wbGF0ZSAke2FtaX1gKTtcblxuICAgICAgICAgIGNvbnN0IGx0cyA9IGF3YWl0IGVjMi5zZW5kKG5ldyBEZXNjcmliZUxhdW5jaFRlbXBsYXRlVmVyc2lvbnNDb21tYW5kKHsgTGF1bmNoVGVtcGxhdGVJZDogYW1pLCBWZXJzaW9uczogWyckTGF0ZXN0J10gfSkpO1xuICAgICAgICAgIGlmIChsdHMuTGF1bmNoVGVtcGxhdGVWZXJzaW9ucz8ubGVuZ3RoICE9PSAxKSB7XG4gICAgICAgICAgICBhd2FpdCBjdXN0b21SZXNvdXJjZVJlc3BvbmQoZXZlbnQsICdGQUlMRUQnLCBgJHthbWl9IGRvZXNuJ3QgZXhpc3RgLCAnRVJST1InLCB7fSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIWx0cy5MYXVuY2hUZW1wbGF0ZVZlcnNpb25zWzBdLkxhdW5jaFRlbXBsYXRlRGF0YT8uSW1hZ2VJZCkge1xuICAgICAgICAgICAgYXdhaXQgY3VzdG9tUmVzb3VyY2VSZXNwb25kKGV2ZW50LCAnRkFJTEVEJywgYCR7YW1pfSBkb2Vzbid0IGhhdmUgYW4gQU1JYCwgJ0VSUk9SJywge30pO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgYXdhaXQgaGFuZGxlQW1pKGV2ZW50LCBsdHMuTGF1bmNoVGVtcGxhdGVWZXJzaW9uc1swXS5MYXVuY2hUZW1wbGF0ZURhdGEuSW1hZ2VJZCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYW1pLm1hdGNoKCdeYXJuOmF3c1teOl0qOmltYWdlYnVpbGRlcjpbXjpdKzpbXjpdKzppbWFnZS8uKiQnKSkge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBDaGVja2luZyBJbWFnZSBCdWlsZGVyICR7YW1pfWApO1xuXG4gICAgICAgICAgY29uc3QgaW1nID0gYXdhaXQgaWIuc2VuZChuZXcgR2V0SW1hZ2VDb21tYW5kKHsgaW1hZ2VCdWlsZFZlcnNpb25Bcm46IGFtaSB9KSk7XG4gICAgICAgICAgY29uc3QgYWN0dWFsQW1pID0gaW1nLmltYWdlPy5vdXRwdXRSZXNvdXJjZXM/LmFtaXM/LlswXT8uaW1hZ2U7XG4gICAgICAgICAgaWYgKCFhY3R1YWxBbWkpIHtcbiAgICAgICAgICAgIGF3YWl0IGN1c3RvbVJlc291cmNlUmVzcG9uZChldmVudCwgJ0ZBSUxFRCcsIGAke2FtaX0gZG9lc24ndCBoYXZlIGFuIEFNSWAsICdFUlJPUicsIHt9KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGF3YWl0IGhhbmRsZUFtaShldmVudCwgYWN0dWFsQW1pKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IGN1c3RvbVJlc291cmNlUmVzcG9uZChldmVudCwgJ0ZBSUxFRCcsIGBVbmtub3duIHR5cGUgb2YgQU1JICR7YW1pfWAsICdFUlJPUicsIHt9KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdEZWxldGUnOlxuICAgICAgICBjb25zb2xlLmxvZygnTm90aGluZyB0byBkZWxldGUnKTtcbiAgICAgICAgYXdhaXQgY3VzdG9tUmVzb3VyY2VSZXNwb25kKGV2ZW50LCAnU1VDQ0VTUycsICdPSycsIGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCwge30pO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgIGF3YWl0IGN1c3RvbVJlc291cmNlUmVzcG9uZChldmVudCwgJ0ZBSUxFRCcsIChlIGFzIEVycm9yKS5tZXNzYWdlIHx8ICdJbnRlcm5hbCBFcnJvcicsIGNvbnRleHQubG9nU3RyZWFtTmFtZSwge30pO1xuICB9XG59XG4iXX0=