UNPKG

@cloud-carbon-footprint/aws

Version:

The core logic to get cloud usage data and estimate energy and carbon emissions from Amazon Web Services.

148 lines (131 loc) 5.18 kB
/* * © 2021 Thoughtworks, Inc. */ import { CloudConstants, COMPUTE_PROCESSOR_TYPES, MemoryEstimator, MemoryUsage, FootprintEstimate, FootprintEstimatesDataBuilder, calculateGigabyteHours, getPhysicalChips, CloudConstantsEmissionsFactors, } from '@cloud-carbon-footprint/core' import { AWS_CLOUD_CONSTANTS } from '../domain' import { BURSTABLE_INSTANCE_BASELINE_UTILIZATION, EC2_INSTANCE_TYPES, INSTANCE_TYPE_COMPUTE_PROCESSOR_MAPPING, REDSHIFT_INSTANCE_TYPES, } from './AWSInstanceTypes' import RightsizingRecommendation from './Recommendations/Rightsizing/RightsizingRecommendation' import CostAndUsageReportsRow from './CostAndUsageReportsRow' import { EC2CurrentComputeOptimizerRecommendation } from './Recommendations/ComputeOptimizer' export default class AWSMemoryEstimatesBuilder extends FootprintEstimatesDataBuilder { constructor( rowData: | RightsizingRecommendation | CostAndUsageReportsRow | EC2CurrentComputeOptimizerRecommendation, memoryEstimator: MemoryEstimator, emissionsFactors: CloudConstantsEmissionsFactors, ) { super(rowData) this.vCpuHours = rowData.vCpuHours this.instanceType = rowData.instanceType this.usageAmount = rowData.usageAmount this.region = rowData.region this.powerUsageEffectiveness = AWS_CLOUD_CONSTANTS.getPUE(this.region) this.computeProcessors = rowData.getComputeProcessors() this.memoryUsage = this.getMemoryUsage() this.memoryConstants = this.getMemoryConstants() this.memoryFootprint = this.getMemoryFootprint( memoryEstimator, this.memoryUsage, this.memoryConstants, this.region, emissionsFactors, ) } private getGigabytesFromInstanceTypeAndProcessors(): number { if (!this.instanceType) return 0 const [instanceFamily, instanceSize] = this.instanceType.split('.') // check to see if the instance type is contained in the AWSInstanceTypes lists // or if the instance type is not a burstable instance, otherwise return void const { isValidInstanceType, isBurstableInstance } = this.checkInstanceTypes(instanceFamily) if (!isValidInstanceType || isBurstableInstance) return 0 // grab the list of processors per instance type // and then the aws specific memory constant for the processors const processors = INSTANCE_TYPE_COMPUTE_PROCESSOR_MAPPING[ this.instanceType ] || [COMPUTE_PROCESSOR_TYPES.UNKNOWN] const processorMemoryGigabytesPerPhysicalChip = AWS_CLOUD_CONSTANTS.getMemory(processors) // grab the instance type vcpu from the AWSInstanceTypes lists const instanceTypeMemory = EC2_INSTANCE_TYPES[instanceFamily]?.[instanceSize]?.[1] || REDSHIFT_INSTANCE_TYPES[instanceFamily]?.[instanceSize]?.[1] // grab the entire instance family that the instance type is classified within const familyInstanceTypes: number[][] = Object.values( EC2_INSTANCE_TYPES[instanceFamily] || REDSHIFT_INSTANCE_TYPES[instanceFamily], ) // grab the vcpu and memory (gb) from the largest instance type in the family const [largestInstanceTypevCpus, largestInstanceTypeMemory] = familyInstanceTypes[familyInstanceTypes.length - 1] // there are special cases for instance families m5zn and z1d where they are always 2 const physicalChips = ['m5zn', 'z1d'].includes(instanceFamily) ? 2 : getPhysicalChips(largestInstanceTypevCpus) return calculateGigabyteHours( physicalChips, largestInstanceTypeMemory, processorMemoryGigabytesPerPhysicalChip, instanceTypeMemory, this.usageAmount, ) } public checkInstanceTypes(instanceFamily: string): { [key: string]: boolean } { // a valid instance type is one that is mapped in the AWSInstanceTypes lists const isValidInstanceType = Object.keys(EC2_INSTANCE_TYPES).includes(instanceFamily) || Object.keys(REDSHIFT_INSTANCE_TYPES).includes(instanceFamily) // we are not able to calculate memory usage for burstable (t family) instances // unlike other instance families, the largest t instance is not equal to a full machine const isBurstableInstance = Object.keys( BURSTABLE_INSTANCE_BASELINE_UTILIZATION, ).includes(this.instanceType) return { isValidInstanceType, isBurstableInstance } } private getMemoryUsage(): MemoryUsage { return { gigabyteHours: this.getGigabytesFromInstanceTypeAndProcessors(), } } private getMemoryConstants(): CloudConstants { return { minWatts: AWS_CLOUD_CONSTANTS.getMinWatts(this.computeProcessors), maxWatts: AWS_CLOUD_CONSTANTS.getMaxWatts(this.computeProcessors), powerUsageEffectiveness: this.powerUsageEffectiveness, replicationFactor: this.replicationFactor, } } private getMemoryFootprint( memoryEstimator: MemoryEstimator, memoryUsage: MemoryUsage, memoryConstants: CloudConstants, region: string, emissionsFactors: CloudConstantsEmissionsFactors, ): FootprintEstimate { return memoryEstimator.estimate( [memoryUsage], region, emissionsFactors, memoryConstants, )[0] } }