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
}];
}
};