Skip to main content

GitHub → AWS: Show infrastructure (Lambdas) for this repo

View Lambda functions belonging to this repo
🔒
https://github.com/mycompany/webshop
preload

How does this help you?

  • See your AWS infrastructure (Lambda functions) directly from your Github repositories
  • Jump directly to each function in the AWS Console
tip

You can easily modify this integration to return other tagged resources, including EC2s, ECS, EKS, SQS, etc

Preview

How it looks in the extension

ToolJump
lambdaAWS Infra (4 lambdas)
... Other items ...

High level approach

We assume Lambda functions are tagged with the repository name (tag key repository, value matching the GitHub repo, e.g. company/webshop). We use the AWS Resource Groups Tagging API to query lambda:function resources in us-east-1 filtered by that tag, then render a dropdown of the first 10 functions. If there are more, a final "More…" item links to the Lambda console filtered by the repository tag.

Notes:

  • Only the us-east-1 region is scanned to keep things simple and fast.
  • Each item links to the function details page in the AWS console.

Prerequisites

For the code below to work, please follow the guide on Connecting to AWS. Provide AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as secrets.

In addition, the AWS identity used by the integration must allow querying the Resource Groups Tagging API. At minimum, grant tag:GetResources:

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["tag:GetResources"],
"Resource": "*"
}
]
}

No lambda:ListFunctions permission is required for this example.

Code

github.aws.infrastructure.integration.example.js
module.exports = {
metadata: {
name: 'github-aws-infrastructure',
description: 'Show Lambda functions in us-east-1 tagged with this repository as a dropdown',
match: {
contextType: 'github',
context: {
'page.repository': { startsWith: 'my-org/' }
}
},
requiredSecrets: ['AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY'],
cache: 1800
},
run: async function (context, secrets = {}) {
const { ResourceGroupsTaggingAPIClient, GetResourcesCommand } = require('@aws-sdk/client-resource-groups-tagging-api');

const region = 'us-east-1';
const tagKey = 'repository';
const tagValue = context.page.repository; // e.g., "company/webshop"

const tagging = new ResourceGroupsTaggingAPIClient({
region,
credentials: {
accessKeyId: secrets.AWS_ACCESS_KEY_ID,
secretAccessKey: secrets.AWS_SECRET_ACCESS_KEY,
},
});

const matched = [];
let token;
do {
const out = await tagging.send(new GetResourcesCommand({
ResourceTypeFilters: ['lambda:function'],
TagFilters: [{ Key: tagKey, Values: [tagValue] }],
PaginationToken: token,
}));

const list = out.ResourceTagMappingList || [];
for (const m of list) {
if (matched.length > 10) break; // collect up to 11 to know if there are more
const arn = m.ResourceARN || '';
const name = arn.split(':').pop();
if (name) {
matched.push({ name, arn });
}
}

token = out.PaginationToken;
if (matched.length > 10) break;
} while (token);

if (matched.length === 0) {
return [];
}

// First 10 items
const items = matched.slice(0, 10).map(m => ({
content: m.name,
href: `https://${region}.console.aws.amazon.com/lambda/home?region=${region}#/functions/${encodeURIComponent(m.name)}?tab=configuration`
}));

// If more than 10, add a More… item linking to Lambda list filtered by tag
if (matched.length > 10) {
const moreUrl = `https://${region}.console.aws.amazon.com/lambda/home?region=${region}#/functions?search=${encodeURIComponent('tag:repository=' + tagValue)}`;
items.push({ content: 'More…', href: moreUrl, status: 'relevant' });
}

return [{
type: 'dropdown',
content: `AWS Infra (${matched.length} Lambdas)`,
items
}];
}
};