diff --git a/lambdas/functions/ami-housekeeper/src/ami.ts b/lambdas/functions/ami-housekeeper/src/ami.ts index 1298ff0f6f..11845271a4 100644 --- a/lambdas/functions/ami-housekeeper/src/ami.ts +++ b/lambdas/functions/ami-housekeeper/src/ami.ts @@ -13,6 +13,8 @@ import { createChildLogger } from '@terraform-aws-github-runner/aws-powertools-u import { getTracedAWSV3Client } from '@terraform-aws-github-runner/aws-powertools-util'; const logger = createChildLogger('ami'); +const ec2Client = getTracedAWSV3Client(new EC2Client({})); +const ssmClient = getTracedAWSV3Client(new SSMClient({})); export interface AmiCleanupOptions { minimumDaysOld?: number; @@ -83,7 +85,6 @@ async function getAmisNotInUse(options: AmiCleanupOptions) { const amiIdsInSSM = await getAmisReferedInSSM(options); const amiIdsInTemplates = await getAmiInLatestTemplates(options); - const ec2Client = getTracedAWSV3Client(new EC2Client({})); logger.debug('Getting all AMIs from ec2 with filters', { filters: options.amiFilters }); const amiEc2 = await ec2Client.send( new DescribeImagesCommand({ @@ -134,7 +135,6 @@ async function deleteAmi(amiDetails: Image, options: AmiCleanupOptionsInternal): try { logger.info(`deleting ami ${amiDetails.Name || amiDetails.ImageId} created at ${amiDetails.CreationDate}`); - const ec2Client = getTracedAWSV3Client(new EC2Client({})); await ec2Client.send(new DeregisterImageCommand({ ImageId: amiDetails.ImageId, DryRun: options.dryRun })); await deleteSnapshot(options, amiDetails, ec2Client); } catch (error) { @@ -159,7 +159,6 @@ async function deleteSnapshot(options: AmiCleanupOptions, amiDetails: Image, ec2 } async function getAmiInLatestTemplates(options: AmiCleanupOptions): Promise<(string | undefined)[]> { - const ec2Client = getTracedAWSV3Client(new EC2Client({})); const launnchTemplates = await ec2Client.send( new DescribeLaunchTemplatesCommand({ LaunchTemplateNames: options.launchTemplateNames, @@ -189,7 +188,6 @@ async function getAmisReferedInSSM(options: AmiCleanupOptions): Promise<(string return []; } - const ssmClient = getTracedAWSV3Client(new SSMClient({})); const ssmParams = await ssmClient.send( new DescribeParametersCommand({ ParameterFilters: [ diff --git a/lambdas/functions/control-plane/src/aws/runners.ts b/lambdas/functions/control-plane/src/aws/runners.ts index 06296fb03b..5d73385947 100644 --- a/lambdas/functions/control-plane/src/aws/runners.ts +++ b/lambdas/functions/control-plane/src/aws/runners.ts @@ -17,6 +17,7 @@ import ScaleError from './../scale-runners/ScaleError'; import * as Runners from './runners.d'; const logger = createChildLogger('runners'); +const ec2 = getTracedAWSV3Client(new EC2Client({ region: process.env.AWS_REGION })); interface Ec2Filter { Name: string; @@ -57,7 +58,6 @@ function constructFilters(filters?: Runners.ListRunnerFilters): Ec2Filter[][] { } async function getRunners(ec2Filters: Ec2Filter[]): Promise { - const ec2 = getTracedAWSV3Client(new EC2Client({ region: process.env.AWS_REGION })); const runners: Runners.RunnerList[] = []; let nextToken; let hasNext = true; @@ -128,10 +128,9 @@ export async function createRunner(runnerParameters: Runners.RunnerInputParamete }, }); - const ec2Client = getTracedAWSV3Client(new EC2Client({ region: process.env.AWS_REGION })); const amiIdOverride = await getAmiIdOverride(runnerParameters); - const fleet: CreateFleetResult = await createInstances(runnerParameters, amiIdOverride, ec2Client); + const fleet: CreateFleetResult = await createInstances(runnerParameters, amiIdOverride, ec2); const instances: string[] = await processFleetResult(fleet, runnerParameters); diff --git a/lambdas/functions/control-plane/src/scale-runners/ssm-housekeeper.ts b/lambdas/functions/control-plane/src/scale-runners/ssm-housekeeper.ts index 78d015c921..6a0c0f8164 100644 --- a/lambdas/functions/control-plane/src/scale-runners/ssm-housekeeper.ts +++ b/lambdas/functions/control-plane/src/scale-runners/ssm-housekeeper.ts @@ -1,6 +1,5 @@ import { DeleteParameterCommand, GetParametersByPathCommand, SSMClient } from '@aws-sdk/client-ssm'; -import { logger } from '@terraform-aws-github-runner/aws-powertools-util'; -import { getTracedAWSV3Client } from '@terraform-aws-github-runner/aws-powertools-util'; +import { getTracedAWSV3Client, logger } from '@terraform-aws-github-runner/aws-powertools-util'; export interface SSMCleanupOptions { dryRun: boolean; @@ -8,6 +7,8 @@ export interface SSMCleanupOptions { tokenPath: string; } +const client = getTracedAWSV3Client(new SSMClient({ region: process.env.AWS_REGION })); + function validateOptions(options: SSMCleanupOptions): void { const errorMessages: string[] = []; if (!options.minimumDaysOld || options.minimumDaysOld < 1) { @@ -26,7 +27,6 @@ export async function cleanSSMTokens(options: SSMCleanupOptions): Promise logger.debug('Cleaning with options', { options }); validateOptions(options); - const client = getTracedAWSV3Client(new SSMClient({ region: process.env.AWS_REGION })); const parameters = await client.send(new GetParametersByPathCommand({ Path: options.tokenPath })); while (parameters.NextToken) { const nextParameters = await client.send( diff --git a/lambdas/functions/gh-agent-syncer/src/syncer/syncer.ts b/lambdas/functions/gh-agent-syncer/src/syncer/syncer.ts index d25b1c97e0..46d8785dab 100644 --- a/lambdas/functions/gh-agent-syncer/src/syncer/syncer.ts +++ b/lambdas/functions/gh-agent-syncer/src/syncer/syncer.ts @@ -9,6 +9,8 @@ import { Stream } from 'stream'; const versionKey = 'name'; const logger = createChildLogger('syncer.ts'); +const githubClient = new Octokit(); +const s3 = getTracedAWSV3Client(new S3Client({})); interface CacheObject { bucket: string; @@ -36,7 +38,6 @@ interface ReleaseAsset { } async function getReleaseAsset(runnerOs = 'linux', runnerArch = 'x64'): Promise { - const githubClient = new Octokit(); const latestRelease = await githubClient.repos.getLatestRelease({ owner: 'actions', repo: 'runner', @@ -85,8 +86,6 @@ async function uploadToS3( } export async function sync(): Promise { - const s3 = getTracedAWSV3Client(new S3Client({})); - const runnerOs = process.env.GITHUB_RUNNER_OS || 'linux'; const runnerArch = process.env.GITHUB_RUNNER_ARCHITECTURE || 'x64'; diff --git a/lambdas/functions/termination-watcher/src/termination-warning.ts b/lambdas/functions/termination-watcher/src/termination-warning.ts index 8a9fad5af6..4fda912bfe 100644 --- a/lambdas/functions/termination-watcher/src/termination-warning.ts +++ b/lambdas/functions/termination-watcher/src/termination-warning.ts @@ -9,10 +9,10 @@ import { Config } from './ConfigResolver'; import { MetricUnits } from '@aws-lambda-powertools/metrics'; const logger = createChildLogger('termination-warning'); +const ec2 = getTracedAWSV3Client(new EC2Client({ region: process.env.AWS_REGION })); async function handle(event: SpotInterruptionWarning, config: Config): Promise { logger.debug('Received spot notification warning:', { event }); - const ec2 = getTracedAWSV3Client(new EC2Client({ region: process.env.AWS_REGION })); const instance = (await ec2.send(new DescribeInstancesCommand({ InstanceIds: [event.detail['instance-id']] }))).Reservations?.[0] .Instances?.[0] ?? null; diff --git a/lambdas/libs/aws-ssm-util/src/index.ts b/lambdas/libs/aws-ssm-util/src/index.ts index 3824926d09..02cbdc5767 100644 --- a/lambdas/libs/aws-ssm-util/src/index.ts +++ b/lambdas/libs/aws-ssm-util/src/index.ts @@ -1,9 +1,11 @@ import { GetParameterCommand, PutParameterCommand, SSMClient, Tag } from '@aws-sdk/client-ssm'; import { getTracedAWSV3Client } from '@terraform-aws-github-runner/aws-powertools-util'; +let ssmClient: SSMClient; + export async function getParameter(parameter_name: string): Promise { - const client = getTracedAWSV3Client(new SSMClient({ region: process.env.AWS_REGION })); - return (await client.send(new GetParameterCommand({ Name: parameter_name, WithDecryption: true }))).Parameter + ssmClient ??= getTracedAWSV3Client(new SSMClient({ region: process.env.AWS_REGION })); + return (await ssmClient.send(new GetParameterCommand({ Name: parameter_name, WithDecryption: true }))).Parameter ?.Value as string; } @@ -13,8 +15,8 @@ export async function putParameter( secure: boolean, options: { tags?: Tag[] } = {}, ): Promise { - const client = getTracedAWSV3Client(new SSMClient({ region: process.env.AWS_REGION })); - await client.send( + ssmClient ??= getTracedAWSV3Client(new SSMClient({ region: process.env.AWS_REGION })); + await ssmClient.send( new PutParameterCommand({ Name: parameter_name, Value: parameter_value,