Skip to main content

6 posts tagged with "aws"

View All Tags

AWS Lambda β†’ GitHub: Browse deployed code

Jump to the exact Git commit deployed to this Lambda
πŸ”’
https://eu-central-1.console.aws.amazon.com/lambda/home?region=eu-central-1#/functions/shop-order-processing?tab=code
preload

How does this help you?​

  • You can quickly navigate to the exact code version that's currently deployed to your Lambda function
  • No need to manually search for the repository or figure out which commit is deployed

Preview​

How it looks in the extension

ToolJumpβ€’githubBrowse code @ a1b2c3dβ€’ ... Other items ...

High level approach​

We read the repository and version tags from the Lambda function using the AWS Lambda API, then construct a GitHub URL to browse the code at that specific version/commit.

Prerequisites​

For the code below to work, please ensure you have:

  1. AWS credentials configured in your secrets
  2. Lambda functions tagged with:
    • repository tag containing your GitHub repository in org/repo format
    • version tag containing the commit SHA or version identifier

Code​

aws-lambda-browse-github-code.integration.example.js
module.exports = {
metadata: {
name: 'aws-lambda-browse-github-code',
description: 'Browse the deployed code for AWS Lambda functions by linking to the GitHub repository at the specific version',
match: {
contextType: 'aws',
context: {
'service.name': { equals: 'lambda' },
'service.arn': { exists: true },
'scope.region': { exists: true },
'service.resourceName': { exists: true }
}
},
requiredSecrets: ['AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY'],
cache: 900
},
run: async function (context, secrets = {}) {
// Get AWS region from context
const awsRegion = context.scope.region;
const functionName = context.service.resourceName;

try {
// Query AWS Lambda to get function tags
const { LambdaClient, ListTagsCommand } = require('@aws-sdk/client-lambda');

const lambdaClient = new LambdaClient({
credentials: {
accessKeyId: secrets.AWS_ACCESS_KEY_ID,
secretAccessKey: secrets.AWS_SECRET_ACCESS_KEY,
},
region: awsRegion
});

const command = new ListTagsCommand({ Resource: context.service.arn });
const tagsResponse = await lambdaClient.send(command);

// Look for repository and version tags
const repository = tagsResponse.Tags?.repository;
const version = tagsResponse.Tags?.version;

if (!repository) {
logger.warn({
operation: 'aws-lambda-browse-github-code',
step: 'no-repository-tag',
functionName: functionName
}, 'No repository tag found on Lambda function');
return [];
}

if (!version) {
logger.warn({
operation: 'aws-lambda-browse-github-code',
step: 'no-version-tag',
functionName: functionName,
repository: repository
}, 'No version tag found on Lambda function');
return [];
}

// Construct GitHub URL
const githubUrl = `https://github.com/${repository}/tree/${version}`;

const results = [
{
type: 'link',
content: `Browse code @ ${version.substring(0, 7)}`,
href: githubUrl,
icon: 'github'
}
];

logger.info({
operation: 'aws-lambda-browse-github-code',
step: 'success',
functionName: functionName,
repository: repository,
version: version,
githubUrl: githubUrl
}, 'Successfully generated GitHub code browse link');

return results;

} catch (error) {
logger.error({
operation: 'aws-lambda-browse-github-code',
step: 'aws-lambda-error',
functionName: functionName,
error: error.message
}, 'Error querying AWS Lambda tags');
return [];
}
}
};

AWS Lambda β†’ Datadog: Show active alerts & logs

See active alerts for this Lambda at a glance
πŸ”’
https://eu-central-1.console.aws.amazon.com/lambda/home?region=eu-central-1#/functions/shop-order-processing?tab=code
preload

How does this help you?​

  • You will notice any active alerts on your Lambda function, which can help you fix issues faster
  • You will be able to navigate directly to the logs for the Lambda function

Preview​

How it looks in the extension

ToolJumpβ€’datadog4 active alertsβ€’datadogLogsβ€’ ... Other items ...

High level approach​

We read the DD_SERVICE tag from the Lambda function using the AWS Lambda API, then query Datadog for active alerts using that service tag. The logs link is constructed using the same service tag.

Prerequisites​

For the code below to work, please follow the guide on Connecting to Datadog and ensure you have:

  1. Datadog API credentials configured in your secrets
  2. AWS credentials configured in your secrets
  3. Lambda functions tagged with DD_SERVICE tag containing your Datadog service name

Code​

aws-lambda-datadog-logs-alerts.integration.example.js
module.exports = {
metadata: {
name: 'aws-lambda-datadog-logs-alerts',
description: 'Show any active alerts from Datadog for AWS Lambda functions, and jump from AWS Lambda to Logs and Alerts for this service',
match: {
contextType: 'aws',
context: {
'service.name': { equals: 'lambda' },
'service.arn': { exists: true },
'scope.region': { exists: true },
'service.resourceName': { exists: true }
}
},
requiredSecrets: ['DATADOG_API_KEY', 'DATADOG_APP_KEY', 'AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY'],
cache: 300
},
run: async function (context, secrets = {}) {
// adjust this to your Datadog instance
const DATADOG_HOST = 'https://api.datadoghq.com';

// Get AWS region from context
const awsRegion = context.scope.region;

const functionName = context.service.resourceName;

let ddServiceName = null;

try {
// Query AWS Lambda to get function tags
const { LambdaClient, ListTagsCommand } = require('@aws-sdk/client-lambda');

const lambdaClient = new LambdaClient({
credentials: {
accessKeyId: secrets.AWS_ACCESS_KEY_ID,
secretAccessKey: secrets.AWS_SECRET_ACCESS_KEY,
},
region: awsRegion
});

const command = new ListTagsCommand({ Resource: context.service.arn });
const tagsResponse = await lambdaClient.send(command);

// Look for DD_SERVICE tag
ddServiceName = tagsResponse.Tags?.DD_SERVICE || tagsResponse.Tags?.['dd-service'];

if (!ddServiceName) {
logger.warn({
operation: 'aws-lambda-datadog-logs-alerts',
step: 'no-dd-service-tag',
functionName: functionName
}, 'No DD_SERVICE tag found on Lambda function');
return [];
}
} catch (error) {
logger.error({
operation: 'aws-lambda-datadog-logs-alerts',
step: 'aws-lambda-error',
functionName: functionName,
error: error.message
}, 'Error querying AWS Lambda tags');
return [];
}

// Query Datadog for active alerts using the service tag
const serviceTag = `service:${ddServiceName}`;
const url = `${DATADOG_HOST}/api/v1/monitor?group_states=alert&monitor_tags=${encodeURIComponent(serviceTag)}`;

try {
const response = await fetch(url, {
method: 'GET',
headers: {
'DD-API-KEY': secrets.DATADOG_API_KEY,
'DD-APPLICATION-KEY': secrets.DATADOG_APP_KEY,
'Content-Type': 'application/json'
}
});

if (!response.ok) {
throw new Error(`Datadog API error: ${response.status} ${response.statusText}`);
}

let monitorList = await response.json();
// Filter monitorList to only include monitors with overall_state === "Alert"
monitorList = Array.isArray(monitorList)
? monitorList.filter(monitor => monitor.overall_state === "Alert")
: [];
const activeAlertsCount = monitorList.length || 0;

// Build Datadog logs and alerts URLs for this service
const logsUrl = `${DATADOG_HOST}/logs?query=${encodeURIComponent(serviceTag)}`;
const alertsUrl = `${DATADOG_HOST}/monitors/manage?q=tag%3A"${encodeURIComponent(serviceTag)}`;

const results = [
{
type: 'link',
content: `${activeAlertsCount} alert${activeAlertsCount === 1 ? '' : 's'}`,
href: alertsUrl,
status: activeAlertsCount > 0 ? 'important' : 'success',
icon: 'datadog'
},
{
type: 'link',
content: 'Logs',
href: logsUrl,
icon: 'datadog'
}
];

return results;

} catch (error) {
logger.error({
operation: 'aws-lambda-datadog-logs-alerts',
step: 'datadog-api-error',
ddServiceName: ddServiceName,
error: error.message
}, 'Error querying Datadog API');
return [];
}
}
};

AWS Lambda β†’ PagerDuty: Show who's on‑call

See who’s on‑call for this Lambda’s service right now
πŸ”’
https://eu-central-1.console.aws.amazon.com/lambda/home?region=eu-central-1#/functions/shop-order-processing?tab=code
preload

How does this help you?​

  • See who is currently on‑call for the service associated with your Lambda function
  • Jump directly to PagerDuty's On‑Call view filtered to the service

Preview​

How it looks in the extension

ToolJumpβ€’pagerdutyOn-call: Johnβ€’ ... Other items ...

High level approach​

We read the service tag from the Lambda function using the AWS Lambda API, then search for a PagerDuty service with a matching name. We resolve the service's escalation policy, fetch the current L1 on‑call user, and show their first name.

Prerequisites​

For the code below to work, please ensure you have:

  1. AWS credentials configured in your secrets (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
  2. PagerDuty API token configured in your secrets (PAGERDUTY_API_TOKEN)
  3. Lambda functions tagged with:
    • service tag containing the PagerDuty service name (exact match required)
  4. PagerDuty service with a name that exactly matches the Lambda function's service tag value

Code​

aws-lambda-pagerduty-oncall.integration.example.js
module.exports = {
metadata: {
name: 'aws-lambda-pagerduty-oncall',
description: 'Show current L1 on-call for the PagerDuty service associated with this Lambda function',
match: {
contextType: 'aws',
context: {
'service.name': { equals: 'lambda' },
'service.arn': { exists: true },
'scope.region': { exists: true },
'service.resourceName': { exists: true }
}
},
requiredSecrets: ['AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'PAGERDUTY_API_TOKEN'],
cache: 900
},
run: async function (context, secrets = {}) {
// Get AWS region from context
const awsRegion = context.scope.region;
const functionName = context.service.resourceName;

try {
// Query AWS Lambda to get function tags
const { LambdaClient, ListTagsCommand } = require('@aws-sdk/client-lambda');

const lambdaClient = new LambdaClient({
credentials: {
accessKeyId: secrets.AWS_ACCESS_KEY_ID,
secretAccessKey: secrets.AWS_SECRET_ACCESS_KEY,
},
region: awsRegion
});

const command = new ListTagsCommand({ Resource: context.service.arn });
const tagsResponse = await lambdaClient.send(command);

// Look for service tag
const serviceName = tagsResponse.Tags?.service;

if (!serviceName) {
logger.warn({
operation: 'aws-lambda-pagerduty-oncall',
step: 'no-service-tag',
functionName: functionName
}, 'No service tag found on Lambda function');
return [];
}

// Query PagerDuty for the service
const PD_HOST = 'https://api.pagerduty.com'; // US API
const headers = {
'Authorization': `Token token=${secrets.PAGERDUTY_API_TOKEN}`,
'Accept': 'application/vnd.pagerduty+json;version=2',
'Content-Type': 'application/json'
};

// Search for services by name
const servicesResp = await fetch(`${PD_HOST}/services?query=${encodeURIComponent(serviceName)}&limit=25`, { headers });
if (!servicesResp.ok) {
throw new Error(`PagerDuty API error (services): ${servicesResp.status} ${servicesResp.statusText}`);
}
const servicesJson = await servicesResp.json();
const service = (servicesJson.services || []).find(s => s.name === serviceName);

if (!service) {
logger.warn({
operation: 'aws-lambda-pagerduty-oncall',
step: 'service-not-found',
functionName: functionName,
serviceName: serviceName
}, 'PagerDuty service not found');
return [];
}

// Fetch service to get escalation policy
const serviceResp = await fetch(`${PD_HOST}/services/${encodeURIComponent(service.id)}?include[]=escalation_policy`, { headers });
if (!serviceResp.ok) {
throw new Error(`PagerDuty API error (service): ${serviceResp.status} ${serviceResp.statusText}`);
}
const serviceJson = await serviceResp.json();
const ep = serviceJson.service && serviceJson.service.escalation_policy;
if (!ep || !ep.id) {
logger.warn({
operation: 'aws-lambda-pagerduty-oncall',
step: 'no-escalation-policy',
functionName: functionName,
serviceName: serviceName,
serviceId: service.id
}, 'No escalation policy found for service');
return [];
}

// Query on-calls for this escalation policy and pick L1
const oncallsResp = await fetch(`${PD_HOST}/oncalls?limit=25&escalation_policy_ids[]=${encodeURIComponent(ep.id)}`, { headers });
if (!oncallsResp.ok) {
throw new Error(`PagerDuty API error (oncalls): ${oncallsResp.status} ${oncallsResp.statusText}`);
}
const oncallsJson = await oncallsResp.json();
const l1 = (oncallsJson.oncalls || []).find(o => o.escalation_level === 1);
if (!l1 || !l1.user) {
logger.warn({
operation: 'aws-lambda-pagerduty-oncall',
step: 'no-oncall-user',
functionName: functionName,
serviceName: serviceName,
serviceId: service.id
}, 'No L1 on-call user found');
return [];
}

// Extract first name
const fullName = l1.user.name || l1.user.summary || '';
const firstName = fullName.split(' ')[0] || fullName;

// Build deep link to On-Call view filtered by service
const oncallUrl = `https://app.pagerduty.com/oncalls?service_ids[]=${encodeURIComponent(service.id)}`;

const results = [
{
type: 'link',
content: `On-call: ${firstName}`,
href: oncallUrl,
icon: 'pagerduty'
}
];

return results;

} catch (error) {
logger.error({
operation: 'aws-lambda-pagerduty-oncall',
step: 'error',
functionName: functionName,
error: error.message
}, 'Error retrieving on-call information');
return [];
}
}
};

AWS Lambda Production Check

This Lambda is in production β€” proceed with caution
πŸ”’
https://eu-central-1.console.aws.amazon.com/lambda/home?region=eu-central-1#/functions/shop-order-processing?tab=code
preload

This integration helps engineers quickly identify when they're working with AWS Lambda functions in production environments. It displays a warning when the AWS account ID matches a configured production account.

How does it help?​

A large number of mistakes are being done when engineers believe a resource is not in production, when it actually is.

This integration:

  • Displays "In production env!" with important status if it's a production account
  • Shows nothing if it's not a production account

Preview​

How it looks in the extension

ToolJumpβ€’In production env!β€’ ... Other items ...

Configuration​

The integration uses a simple account ID check. You'll need to update the PRODUCTION_ACCOUNT_ID constant in the integration file with your actual production AWS account ID.

const PRODUCTION_ACCOUNT_ID = '12345678'; // Replace with your production account ID

When it runs​

This integration runs when:

  • You're on an AWS Lambda function page (console.aws.amazon.com/lambda)
  • The AWS account ID is available in the context
  • The service type is lambda
Alternative Detection Methods

While this integration only checks the account ID, you could also modify it to check for function name patterns like -prod or -production suffixes for additional environment detection.

Installation​

  1. Copy the integration file to your examples/data/ directory
  2. Update the PRODUCTION_ACCOUNT_ID with your actual production account ID
  3. The integration will automatically be available when you visit AWS Lambda function pages

Security Note​

This integration only reads the account ID from the page context and doesn't make any external API calls, making it safe to use without additional AWS credentials.

Code​

aws-lambda-production-check.integration.example.js
module.exports = {
metadata: {
name: 'aws-lambda-production-check',
description: 'Shows production environment status for AWS Lambda functions',
match: {
contextType: 'aws',
context: {
'service.name': { equals: 'lambda' },
'global.accountId': { exists: true }
}
},
cache: 3600
},

async run(context, secrets = {}, dataFiles = []) {
logger.info({
operation: 'aws-lambda-production-check',
step: 'initialization',
contextService: context.service.name,
accountId: context.global.accountId
}, 'AWS Lambda production check starting');

// Production account ID - replace with your actual production account ID
const PRODUCTION_ACCOUNT_ID = '12345678';

if (context.global.accountId === PRODUCTION_ACCOUNT_ID) {
logger.info({
operation: 'aws-lambda-production-check',
step: 'production-detected',
accountId: context.global.accountId,
functionName: context.service.resourceName
}, 'Production environment detected');

return [{
type: 'text',
content: 'In production env!',
status: 'important'
}];
}

logger.debug({
operation: 'aws-lambda-production-check',
step: 'no-production',
contextService: context.service.name,
accountId: context.global.accountId
}, 'Not in production environment');

return [];
}
};

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

GitHub β†’ AWS: Show infrastructure costs

See last 30‑day AWS cost for resources tagged to this repo
πŸ”’
https://github.com/mycompany/webshop
preload

How does this help you?​

  • See the last 30 days AWS cost for infra tagged with this repository
  • Jump directly to AWS Cost Explorer pre-filtered by the repo tag

Preview​

How it looks in the extension

ToolJumpβ€’costCosts 30d: $2950β€’ ... Other items ...

High level approach​

We assume AWS resources are tagged with the repository name (tag key repository, value matching the GitHub repo, e.g. company/webshop). We then query AWS Cost Explorer for the past 30 days, filtered by that tag across all services, and sum the total cost.

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 Cost Explorer API. At minimum, grant ce:GetCostAndUsage:

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

Code​

github.aws.costs.integration.example.js
module.exports = {
metadata: {
name: 'github-aws-costs',
description: 'Show last 30 days AWS cost for resources tagged with this GitHub repository and link to Cost Explorer',
match: {
contextType: 'github',
context: {
'page.repository': { startsWith: 'my-org/' }
}
},
requiredSecrets: ['AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY'],
cache: 300
},
run: async function (context, secrets = {}) {
// Import AWS SDK v3 Cost Explorer client only at runtime
const { CostExplorerClient, GetCostAndUsageCommand } = require('@aws-sdk/client-cost-explorer');

// Tag key and value derived from GitHub context
const tagKey = 'repository';
const tagValue = context.page.repository; // e.g. "company/webshop"

// Cost Explorer is in us-east-1
const client = new CostExplorerClient({
region: 'us-east-1',
credentials: {
accessKeyId: secrets.AWS_ACCESS_KEY_ID,
secretAccessKey: secrets.AWS_SECRET_ACCESS_KEY,
},
});

// Build a 30-day window (End is exclusive per AWS API)
function toYMD(d) {
const y = d.getUTCFullYear();
const m = String(d.getUTCMonth() + 1).padStart(2, '0');
const day = String(d.getUTCDate()).padStart(2, '0');
return `${y}-${m}-${day}`;
}
const endDate = new Date(); // today (exclusive)
const startDate = new Date();
startDate.setUTCDate(endDate.getUTCDate() - 30);

const params = {
TimePeriod: { Start: toYMD(startDate), End: toYMD(endDate) },
Granularity: 'DAILY',
Metrics: ['UnblendedCost'],
Filter: {
Tags: { Key: tagKey, Values: [tagValue] }
}
};

let total = 0;
let unit = 'USD';
let nextToken;
do {
const resp = await client.send(new GetCostAndUsageCommand({ ...params, NextPageToken: nextToken }));
if (Array.isArray(resp.ResultsByTime)) {
for (const p of resp.ResultsByTime) {
const metric = p.Total && p.Total.UnblendedCost;
if (metric && metric.Amount) {
total += parseFloat(metric.Amount);
unit = metric.Unit || unit;
}
}
}
nextToken = resp.NextPageToken;
} while (nextToken);

// Build a deep link to AWS Cost Explorer filtered by the tag and last 30 days
const ceFilter = { Tags: { Key: tagKey, Values: [tagValue] } };
const ceUrl = 'https://us-east-1.console.aws.amazon.com/cost-management/home' +
'?region=us-east-1#/cost-explorer' +
`?timeRange=LAST_30_DAYS&granularity=DAILY&costMetric=UnblendedCost&filter=${encodeURIComponent(JSON.stringify(ceFilter))}`;

// Format amount (simple two-decimal string)
const currencySymbol = unit === 'USD' ? '$' : `${unit} `;
const pretty = `${currencySymbol}${total.toFixed(2)}`;

const results = [
{ type: 'link', content: `Costs 30d: ${pretty}`, href: ceUrl }
];

return results;
}
};