diff --git a/cost/aws/savings_realized/CHANGELOG.md b/cost/aws/savings_realized/CHANGELOG.md index cc88ae3f70..a6bd02d04e 100644 --- a/cost/aws/savings_realized/CHANGELOG.md +++ b/cost/aws/savings_realized/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v3.4 + +- Updated `Savings Realized On Compute Savings Plans` incident field to align value with AWS Realized Savings Dashboard. + ## v3.3 - Added the following dimensions to get costs and calculate cost per hour average: `operating_system`, `database_engine`, `database_edition`, `license_model`, `deployment_option` diff --git a/cost/aws/savings_realized/README.md b/cost/aws/savings_realized/README.md index 9d725d0f39..c1b1932e77 100644 --- a/cost/aws/savings_realized/README.md +++ b/cost/aws/savings_realized/README.md @@ -17,8 +17,8 @@ The [Provider-Specific Credentials](https://docs.flexera.com/flexera/EN/Automati - This policy supports a view of savings realized from AWS Compute Reserved Instances, Savings Plans and Spot Instances - This policy supports a view of savings realized for a list of specific billing centers or for the entire Organization. -- This policy uses the on-demand rate and the reserved instance/savings plan/spot instance rate by instance type and region to derive a savings rate. The policy then uses usage amount to calculate total savings realized. -- This policy produces a bar chart showing savings realized vs. total actual spend for the period of historical months specified. +- This policy uses [savings metric](https://docs.flexera.com/flexera/EN/Optima/TabularView.htm#tabularview_3352643092_1192596) calculated as difference between list price and cost. +- This policy produces a bar chart showing savings realized categorized by purchase option vs. total actual spend for the period of historical months specified. ### Input Parameters diff --git a/cost/aws/savings_realized/aws_savings_realized.pt b/cost/aws/savings_realized/aws_savings_realized.pt index 3d912d50b4..714b3204cf 100644 --- a/cost/aws/savings_realized/aws_savings_realized.pt +++ b/cost/aws/savings_realized/aws_savings_realized.pt @@ -7,7 +7,7 @@ default_frequency "monthly" severity "low" category "Cost" info( - version: "3.3", + version: "3.4", provider: "Flexera", service: "All", policy_set: "N/A" @@ -97,18 +97,10 @@ datasource "ds_aggregated_costs" do result do encoding "json" collect jmes_path(response, "rows") do - field "instance_type", jmes_path(col_item, "dimensions.instance_type") - field "region", jmes_path(col_item, "dimensions.region") field "purchase_option", jmes_path(col_item, "dimensions.purchase_option") - field "usage_unit", jmes_path(col_item, "dimensions.usage_unit") - field "usage_amount", jmes_path(col_item, "metrics.usage_amount") field "cost", jmes_path(col_item, "metrics.cost_amortized_unblended_adj") + field "savings", jmes_path(col_item, "metrics.savings_rate_reduction_amortized_adj") field "month", jmes_path(col_item, "timestamp") - field "database_edition", jmes_path(col_item, "dimensions.database_edition") - field "database_engine", jmes_path(col_item, "dimensions.database_engine") - field "deployment_option", jmes_path(col_item, "dimensions.deployment_option") - field "license_model", jmes_path(col_item, "dimensions.license_model") - field "operating_system", jmes_path(col_item, "dimensions.operating_system") end end end @@ -134,14 +126,6 @@ script "js_get_aggregated_costs", type: "javascript" do "type": "and", "expressions": [ { "dimension": "vendor", "type": "equal", "value": "AWS" }, - { - "type": "not", - "expression": { "dimension": "instance_type", "type": "equal", "value": "None" } - }, - { - "type": "not", - "expression": { "dimension": "category", "type": "equal", "value": "Commitments" } - }, { "type": "not", "expression": { "dimension": "purchase_option", "type": "equal", "value": "On Demand (Non-Discountable)" } @@ -149,20 +133,12 @@ script "js_get_aggregated_costs", type: "javascript" do ] }, "dimensions": [ - "instance_type", - "region", - "purchase_option", - "usage_unit", - "database_edition", - "database_engine", - "deployment_option", - "license_model", - "operating_system" + "purchase_option" ], "granularity": "month", "metrics": [ "cost_amortized_unblended_adj", - "usage_amount" + "savings_rate_reduction_amortized_adj", ] "end_at": end_date, "start_at": start_date @@ -192,6 +168,11 @@ script "js_get_savings_realized", type: "javascript" do code <<-'EOS' var savings_realized_data = [] + //Get arrays for Purchase Option + ri_costs = _.filter(all_costs, function(cost){ return cost.purchase_option == "Reserved" }) + sp_costs = _.filter(all_costs, function(cost){ return cost.purchase_option == "Savings Plan" }) + spot_costs = _.filter(all_costs, function(cost){ return cost.purchase_option == "Spot" }) + //Get list of Months months = _.pluck( _.uniq(all_costs, function(all){ return all.month }), "month" ) @@ -204,105 +185,39 @@ script "js_get_savings_realized", type: "javascript" do savings_realized_data.push({ "month": mo, "cost": total_month_cost, "dimension": "Total Actual Spend On Discountable Compute" }) }) - // create an object with all different combination of instance_type/region/operating_system/database_engine/database_edition/license_model/deployment_option and the costs records that matches that combination filtered by purchase option - instance_combinations = {} - _.each(all_costs, function(cost){ - key = [cost.instance_type, cost.region, cost.operating_system, cost.database_engine, cost.database_edition, cost.license_model, cost.deployment_option].join("---") - - if (instance_combinations[key] == null) { - instance_combinations[key] = { - "ri_costs": [], - "sp_costs": [], - "spot_costs": [], - "on_demand_total_cost" : 0, - "on_demand_counter" : 0 - } - } - - switch (cost.purchase_option) { - case "On Demand": - // these will be used to average cost calculation - instance_combinations[key].on_demand_total_cost += (cost.cost / cost.usage_amount) - instance_combinations[key].on_demand_counter++ - break; - case "Reserved": - instance_combinations[key].ri_costs.push(cost) - break; - case "Savings Plan": - instance_combinations[key].sp_costs.push(cost) - break; - case "Spot": - instance_combinations[key].spot_costs.push(cost) - break; - } - }) - var temp_result = [] - _.each(instance_combinations, function(value, key){ - - // calculate On-Demand cost of instance per hour across all months for each instance instance_type/region/operating_system/database_engine/database_edition/license_model/deployment_option combination - avg_od_cost_inst_hr = 0 - if(value.on_demand_counter > 0){ avg_od_cost_inst_hr = value.on_demand_total_cost / value.on_demand_counter } - - //Reserved Instance savings - _.each(value.ri_costs, function(ri){ - savings_realized_per_inst_hr = avg_od_cost_inst_hr - (ri.cost / ri.usage_amount) - - savings_realized = 0 - if(ri.cost > 0 ){ - savings_realized = savings_realized_per_inst_hr * ri.usage_amount + //Reserved Instance savings + _.each(ri_costs, function(ri){ + temp_result.push( + { + "month": ri.month, + "savings_realized": ri.savings, + "purchase_option": "Reservations" } + ) + }) - temp_result.push( - { - "month": ri.month, - "region": ri.region, - "instance_type": ri.instance_type, - "savings_realized": savings_realized, - "purchase_option": "Reservations" - } - ) - }) - - //Savings Plan savings - _.each(value.sp_costs, function(sp){ - savings_realized_per_inst_hr = avg_od_cost_inst_hr - (sp.cost / sp.usage_amount) - - savings_realized = 0 - if(sp.cost > 0 ){ - savings_realized = savings_realized_per_inst_hr * sp.usage_amount + //Savings Plan savings + _.each(sp_costs, function(sp){ + temp_result.push( + { + "month": sp.month, + "savings_realized": sp.savings, + "purchase_option": "Savings Plans" } + ) + }) - temp_result.push( - { - "month": sp.month, - "region": sp.region, - "instance_type": sp.instance_type, - "savings_realized": savings_realized, - "purchase_option": "Savings Plans" - } - ) - }) - - //Spot Instance savings - _.each(value.spot_costs, function(spot){ - savings_realized_per_inst_hr = avg_od_cost_inst_hr - (spot.cost / spot.usage_amount) - savings_realized = 0 - if(spot.cost > 0 ){ - savings_realized = savings_realized_per_inst_hr * spot.usage_amount + //Spot Instance savings + _.each(spot_costs, function(spot){ + temp_result.push( + { + "month": spot.month, + "savings_realized": spot.savings, + "purchase_option": "Spot Instances" } - - temp_result.push( - { - "month": spot.month, - "region": spot.region, - "instance_type": spot.instance_type, - "savings_realized": savings_realized, - "purchase_option": "Spot Instances" - } - ) - }) + ) }) //reduce list - aggregate SAVINGS REALIZED costs for same purchase option for same month @@ -456,8 +371,8 @@ policy "policy_purchase_option_by_inst_type_and_region" do validate_each $ds_chart_data do summary_template "AWS Savings Realized from Reservations" detail_template <<-EOS -# Savings Realized Per Instance Type Report -![Savings Realized Per Instance Type Chart](https://api.image-charts-auth.flexeraeng.com/ic-function?rs_org_id={{ rs_org_id }}&rs_project_id={{ rs_project_id }}&{{ with index data 0 }}{{ .chart_dimensions.chart_data }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_size }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_type }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_image }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_title }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_y_axis }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_axis_label }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_line_style }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_line_color }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_data_scale }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_legend_size }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_legend }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_axis_format }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_legend_position }}{{ end }}) +# Rate Reduction Savings Report +![Rate Reduction Savings Chart](https://api.image-charts-auth.flexeraeng.com/ic-function?rs_org_id={{ rs_org_id }}&rs_project_id={{ rs_project_id }}&{{ with index data 0 }}{{ .chart_dimensions.chart_data }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_size }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_type }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_image }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_title }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_y_axis }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_axis_label }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_line_style }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_line_color }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_data_scale }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_legend_size }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_legend }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_axis_format }}{{ end }}&{{ with index data 0 }}{{ .chart_dimensions.chart_legend_position }}{{ end }}) EOS escalate $esc_savings_realized_report check eq(0,1)