diff --git a/.dangerfile/readme_tests.rb b/.dangerfile/readme_tests.rb index ce640afce2..e7754910d7 100644 --- a/.dangerfile/readme_tests.rb +++ b/.dangerfile/readme_tests.rb @@ -264,8 +264,10 @@ def readme_invalid_credentials?(file, file_lines) fail_message += "```- [**AWS Credential**](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm#automationadmin_1982464505_1121575) (*provider=aws*) which has the following permissions:```\n\n" end - aws_perm_tester = /`[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*:[a-zA-Z0-9]+`(?:\*)?$/ - asterix_found = 0 + aws_perm_tester = /`[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*:[a-zA-Z0-9]+`(?:[\*\u2020\u2021\u00a7\u2016\u00b6])?$/ + + # Hash to track the presence of each footnote symbol in the permission list + footnote_symbols = { "*" => false, "†" => false, "‡" => false, "§" => false, "‖" => false, "¶" => false } permission_list_found = 0 aws_permission_text.each_with_index do |line, index| @@ -277,31 +279,51 @@ def readme_invalid_credentials?(file, file_lines) if !line.start_with?(" - ") permission_list_found = 2 else - asterix_found = 1 if line.strip.end_with?("*") - - if !line.split(" - ")[1].match?(aws_perm_tester) + footnote_symbols["*"] = true if line.strip.end_with?("*") + footnote_symbols["†"] = true if line.strip.end_with?("\u2020") + footnote_symbols["‡"] = true if line.strip.end_with?("\u2021") + footnote_symbols["§"] = true if line.strip.end_with?("\u00a7") + footnote_symbols["‖"] = true if line.strip.end_with?("\u2016") + footnote_symbols["¶"] = true if line.strip.end_with?("\u00b6") + + permission_action = line.split(" - ")[1] + if permission_action.nil? || !permission_action.match?(aws_perm_tester) fail_message += "Line #{line_number.to_s}: AWS permission list item formatted incorrectly. Please make sure all list items are formatted like the following examples:\n\n" fail_message += "``` - `rds:DeleteDBSnapshot`*```\n" + fail_message += "``` - `ec2:TerminateInstances`†```\n" fail_message += "``` - `sts:GetCallerIdentity` ```\n" fail_message += "``` - `cloudtrail:LookupEvents` ```\n\n" end end end + end - asterix_found = 2 if asterix_found == 1 && line.start_with?(' \* ') + # Check for missing footnotes for any symbols that were found in the permissions list + footnote_symbols.each do |symbol, found| + next unless found # Only check if the symbol was found in the permission list + + # Search for corresponding footnote explanation + if symbol == "*" + if !aws_permission_text.any? { |line| line.strip.start_with?("\\*") } + fail_message += "Permission list contains a permission with an asterisk (*), but no corresponding footnote explaining it. Please add a footnote starting with ` \\* ` like so:\n\n" + fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n" + end + else + if !aws_permission_text.any? { |line| line.strip.start_with?(symbol) } + fail_message += "Permission list contains a permission with a #{symbol} symbol, but no corresponding footnote explaining it. Please add a footnote starting with ` #{symbol} ` like so:\n\n" + fail_message += "``` #{symbol} Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n" + end + end end + # Check if no permission list was found if permission_list_found == 0 fail_message += "AWS permission list missing or formatted incorrectly. Please ensure there is a list of permissions beneath the AWS permission statement. Each list item should begin with [space][space][hyphen][space] like so:\n\n" fail_message += "``` - `rds:DeleteDBSnapshot`*```\n" + fail_message += "``` - `ec2:TerminateInstances`†```\n" fail_message += "``` - `sts:GetCallerIdentity` ```\n" fail_message += "``` - `cloudtrail:LookupEvents` ```\n\n" end - - if asterix_found == 1 - fail_message += "AWS permission list contains a permission with an asterix but no footnote explaning why or the footnote is formatted incorrectly. The footnote should indicate what is special about these permissions; in most cases, this will be an explanation that the permission is optional and only needed for policy actions. Please add a footnote that begins with [space][space][backslash][asterix][space] like so:\n\n" - fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n\n" - end end if azure_permission_line @@ -310,8 +332,10 @@ def readme_invalid_credentials?(file, file_lines) fail_message += "```- [**Azure Resource Manager Credential**](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm#automationadmin_109256743_1124668) (*provider=azure_rm*) which has the following permissions:```\n\n" end - azure_perm_tester = /^`Microsoft\.[a-zA-Z]+\/[a-zA-Z]+\/[a-zA-Z]+(?:\/[a-zA-Z]+)*`(?:\*)?$/ - asterix_found = 0 + azure_perm_tester = /^`Microsoft\.[a-zA-Z]+\/[a-zA-Z]+\/[a-zA-Z]+(?:\/[a-zA-Z]+)*`(?:[\*\u2020\u2021\u00a7\u2016\u00b6])?$/ + + # Hash to track the presence of each footnote symbol in the permission list + footnote_symbols = { "*" => false, "†" => false, "‡" => false, "§" => false, "‖" => false, "¶" => false } permission_list_found = 0 azure_permission_text.each_with_index do |line, index| @@ -323,9 +347,15 @@ def readme_invalid_credentials?(file, file_lines) if !line.start_with?(" - ") permission_list_found = 2 else - asterix_found = 1 if line.strip.end_with?("*") - - if !line.split(" - ")[1].match?(azure_perm_tester) + footnote_symbols["*"] = true if line.strip.end_with?("*") + footnote_symbols["†"] = true if line.strip.end_with?("\u2020") + footnote_symbols["‡"] = true if line.strip.end_with?("\u2021") + footnote_symbols["§"] = true if line.strip.end_with?("\u00a7") + footnote_symbols["‖"] = true if line.strip.end_with?("\u2016") + footnote_symbols["¶"] = true if line.strip.end_with?("\u00b6") + + permission_action = line.split(" - ")[1] + if permission_action.nil? || !permission_action.match?(azure_perm_tester) fail_message += "Line #{line_number.to_s}: Azure permission list item formatted incorrectly. Please make sure all list items are formatted like the following examples:\n\n" fail_message += "``` - `Microsoft.Compute/snapshots/delete`*```\n" fail_message += "``` - `Microsoft.Compute/snapshots/read` ```\n" @@ -333,21 +363,33 @@ def readme_invalid_credentials?(file, file_lines) end end end + end + + # Check for missing footnotes for any symbols that were found in the permissions list + footnote_symbols.each do |symbol, found| + next unless found # Only check if the symbol was found in the permission list - asterix_found = 2 if asterix_found == 1 && line.start_with?(' \* ') + # Search for corresponding footnote explanation + if symbol == "*" + if !azure_permission_text.any? { |line| line.strip.start_with?("\\*") } + fail_message += "Permission list contains a permission with an asterisk (*), but no corresponding footnote explaining it. Please add a footnote starting with ` \\* ` like so:\n\n" + fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n" + end + else + if !azure_permission_text.any? { |line| line.strip.start_with?(symbol) } + fail_message += "Permission list contains a permission with a #{symbol} symbol, but no corresponding footnote explaining it. Please add a footnote starting with ` #{symbol} ` like so:\n\n" + fail_message += "``` #{symbol} Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n" + end + end end + # Check if no permission list was found if permission_list_found == 0 fail_message += "Azure permission list missing or formatted incorrectly. Please ensure there is a list of permissions beneath the Azure permission statement. Each list item should begin with [space][space][hyphen][space] like so:\n\n" fail_message += "``` - `Microsoft.Compute/snapshots/delete`*```\n" fail_message += "``` - `Microsoft.Compute/snapshots/read` ```\n" fail_message += "``` - `Microsoft.Insights/metrics/read` ```\n\n" end - - if asterix_found == 1 - fail_message += "Azure permission list contains a permission with an asterix but no footnote explaning why or the footnote is formatted incorrectly. The footnote should indicate what is special about these permissions; in most cases, this will be an explanation that the permission is optional and only needed for policy actions. Please add a footnote that begins with [space][space][backslash][asterix][space] like so:\n\n" - fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n\n" - end end if google_permission_line @@ -356,8 +398,10 @@ def readme_invalid_credentials?(file, file_lines) fail_message += "```- [**Google Cloud Credential**](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm#automationadmin_4083446696_1121577) (*provider=gce*) which has the following:```\n\n" end - google_perm_tester = /^`[a-zA-Z]+\.[a-zA-Z]+\.[a-zA-Z]+(?:\.[a-zA-Z]+)*`(?:\*)?$/ - asterix_found = 0 + google_perm_tester = /^`[a-zA-Z]+\.[a-zA-Z]+\.[a-zA-Z]+(?:\.[a-zA-Z]+)*`(?:[\*\u2020\u2021\u00a7\u2016\u00b6])?$/ + + # Hash to track the presence of each footnote symbol in the permission list + footnote_symbols = { "*" => false, "†" => false, "‡" => false, "§" => false, "‖" => false, "¶" => false } permission_list_found = 0 google_permission_text.each_with_index do |line, index| @@ -369,31 +413,50 @@ def readme_invalid_credentials?(file, file_lines) if !line.start_with?(" - ") permission_list_found = 2 else - asterix_found = 1 if line.strip.end_with?("*") + footnote_symbols["*"] = true if line.strip.end_with?("*") + footnote_symbols["†"] = true if line.strip.end_with?("\u2020") + footnote_symbols["‡"] = true if line.strip.end_with?("\u2021") + footnote_symbols["§"] = true if line.strip.end_with?("\u00a7") + footnote_symbols["‖"] = true if line.strip.end_with?("\u2016") + footnote_symbols["¶"] = true if line.strip.end_with?("\u00b6") if !line.split(" - ")[1].match?(google_perm_tester) fail_message += "Line #{line_number.to_s}: Google permission list item formatted incorrectly. Please make sure all list items are formatted like the following examples:\n\n" fail_message += "``` - `resourcemanager.projects.get`*```\n" + fail_message += "``` - `recommender.computeInstanceMachineTypeRecommendations.list`†```\n" fail_message += "``` - `compute.regions.list` ```\n" fail_message += "``` - `billing.resourceCosts.get` ```\n\n" end end end + end - asterix_found = 2 if asterix_found == 1 && line.start_with?(' \* ') + # Check for missing footnotes for any symbols that were found in the permissions list + footnote_symbols.each do |symbol, found| + next unless found # Only check if the symbol was found in the permission list + + # Search for corresponding footnote explanation + if symbol == "*" + if !google_permission_text.any? { |line| line.strip.start_with?("\\*") } + fail_message += "Permission list contains a permission with an asterisk (*), but no corresponding footnote explaining it. Please add a footnote starting with ` \\* ` like so:\n\n" + fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n" + end + else + if !google_permission_text.any? { |line| line.strip.start_with?(symbol) } + fail_message += "Permission list contains a permission with a #{symbol} symbol, but no corresponding footnote explaining it. Please add a footnote starting with ` #{symbol} ` like so:\n\n" + fail_message += "``` #{symbol} Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n" + end + end end + # Check if no permission list was found if permission_list_found == 0 fail_message += "Google permission list missing or formatted incorrectly. Please ensure there is a list of permissions beneath the Google permission statement. Each list item should begin with [space][space][hyphen][space] like so:\n\n" fail_message += "``` - `resourcemanager.projects.get`*```\n" + fail_message += "``` - `recommender.computeInstanceMachineTypeRecommendations.list`†```\n" fail_message += "``` - `compute.regions.list` ```\n" fail_message += "``` - `billing.resourceCosts.get` ```\n\n" end - - if asterix_found == 1 - fail_message += "Google permission list contains a permission with an asterix but no footnote explaning why or the footnote is formatted incorrectly. The footnote should indicate what is special about these permissions; in most cases, this will be an explanation that the permission is optional and only needed for policy actions. Please add a footnote that begins with [space][space][backslash][asterix][space] like so:\n\n" - fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n\n" - end end if flexera_permission_line @@ -402,8 +465,10 @@ def readme_invalid_credentials?(file, file_lines) fail_message += "```- [**Flexera Credential**](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm) (*provider=flexera*) which has the following roles:```\n\n" end - flexera_perm_tester = /^`[a-zA-Z0-9\-_\.]+`(?:\*)?$/ - asterix_found = 0 + flexera_perm_tester = /^`[a-zA-Z0-9\-_\.]+`(?:[\*\u2020\u2021\u00a7\u2016\u00b6])?$/ + + # Hash to track the presence of each footnote symbol in the permission list + footnote_symbols = { "*" => false, "†" => false, "‡" => false, "§" => false, "‖" => false, "¶" => false } permission_list_found = 0 flexera_permission_text.each_with_index do |line, index| @@ -415,7 +480,12 @@ def readme_invalid_credentials?(file, file_lines) if !line.start_with?(" - ") permission_list_found = 2 else - asterix_found = 1 if line.strip.end_with?("*") + footnote_symbols["*"] = true if line.strip.end_with?("*") + footnote_symbols["†"] = true if line.strip.end_with?("\u2020") + footnote_symbols["‡"] = true if line.strip.end_with?("\u2021") + footnote_symbols["§"] = true if line.strip.end_with?("\u00a7") + footnote_symbols["‖"] = true if line.strip.end_with?("\u2016") + footnote_symbols["¶"] = true if line.strip.end_with?("\u00b6") if !line.split(" - ")[1].match?(flexera_perm_tester) fail_message += "Line #{line_number.to_s}: Flexera permission list item formatted incorrectly. Please make sure all list items are formatted like the following examples:\n\n" @@ -423,19 +493,31 @@ def readme_invalid_credentials?(file, file_lines) end end end + end - asterix_found = 2 if asterix_found == 1 && line.start_with?(' \* ') + # Check for missing footnotes for any symbols that were found in the permissions list + footnote_symbols.each do |symbol, found| + next unless found # Only check if the symbol was found in the permission list + + # Search for corresponding footnote explanation + if symbol == "*" + if !flexera_permission_text.any? { |line| line.strip.start_with?("\\*") } + fail_message += "Permission list contains a permission with an asterisk (*), but no corresponding footnote explaining it. Please add a footnote starting with ` \\* ` like so:\n\n" + fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n" + end + else + if !flexera_permission_text.any? { |line| line.strip.start_with?(symbol) } + fail_message += "Permission list contains a permission with a #{symbol} symbol, but no corresponding footnote explaining it. Please add a footnote starting with ` #{symbol} ` like so:\n\n" + fail_message += "``` #{symbol} Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n" + end + end end + # Check if no permission list was found if permission_list_found == 0 fail_message += "Flexera permission list missing or formatted incorrectly. Please ensure there is a list of permissions beneath the Flexera permission statement. Each list item should begin with [space][space][hyphen][space] like so:\n\n" fail_message += "``` - `billing_center_viewer`*```\n\n" end - - if asterix_found == 1 - fail_message += "Flexera permission list contains a permission with an asterix but no footnote explaning why or the footnote is formatted incorrectly. The footnote should indicate what is special about these permissions; in most cases, this will be an explanation that the permission is optional and only needed for policy actions. Please add a footnote that begins with [space][space][backslash][asterix][space] like so:\n\n" - fail_message += "``` \\* Only required for taking action; the policy will still function in a read-only capacity without these permissions.```\n\n" - end end fail_message = "README.md has problems with how credential permissions are presented:\n\n" + fail_message if !fail_message.empty? diff --git a/.github/workflows/generate-azure-sqlmi-storage-pricing-json b/.github/workflows/generate-azure-sqlmi-storage-pricing-json new file mode 100644 index 0000000000..43cdf561f3 --- /dev/null +++ b/.github/workflows/generate-azure-sqlmi-storage-pricing-json @@ -0,0 +1,53 @@ +name: Generate Azure SQL MI Storage Pricing JSON + +on: + schedule: + # ┌───────────── minute (0 - 59) + # │ ┌───────────── hour (0 - 23) + # │ │ ┌───────────── day of the month (1 - 31) + # │ │ │ ┌───────────── month (1 - 12 or JAN-DEC) + # │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT) + # │ │ │ │ │ + # │ │ │ │ │ + # │ │ │ │ │ + # * * * * * + # At 05:00 UTC on Sundays + - cron: "0 5 * * 0" + + # Workflow dispatch trigger allows manually running workflow + workflow_dispatch: {} + +jobs: + azure_db_storage_pricing: + name: "Generate Azure SQL MI Storage Pricing" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # Speed up checkout by not fetching history + + - uses: actions/setup-python@v5 + with: + python-version: 3.10.12 + cache: 'pip' # caching pip dependencies + + - run: pip install -r requirements.txt + + - run: python3 tools/cloud_data/azure/azure_sqlmi_storage_pricing.py + + - name: Create Pull Request + id: cpr + uses: peter-evans/create-pull-request@v4 + with: + commit-message: "Update Azure SQL MI Storage Pricing Data" + title: "Update Azure SQL MI Storage Pricing Data" + body: "Updated Azure SQL MI Storage Pricing from GitHub Actions Workflow [${{ github.workflow }}](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})" + branch: "task/update-azure-sqlmi-storage-pricing" + delete-branch: true + labels: "automation, data, azure" + + - name: Check outputs + if: ${{ steps.cpr.outputs.pull-request-number }} + run: | + echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}" + echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}" diff --git a/.spellignore b/.spellignore index 518cc45ba8..9e3b060535 100644 --- a/.spellignore +++ b/.spellignore @@ -567,6 +567,7 @@ CCO untagged README readme +GetCallerIdentity expiryDate licenseDuration licenseId @@ -615,7 +616,14 @@ dataset Datasets datasets failsafe +MSP +msp +onboarding +Onboarding +onboard +Onboard +Customizations +customizations ElastiCache elasticache -oversized freeable diff --git a/HISTORY.md b/HISTORY.md index a9179e9926..77ff0c0eeb 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -6,6 +6,128 @@ This document contains the last 100 policy template merges for the `flexera-publ ## History +### PR [#2616](https://github.com/flexera-public/policy_templates/pull/2616): POL-1330 New Policy: AWS Account Credentials + +#### Description + +> This adds a new, unpublished policy template along with a custom meta parent. The purpose of this policy template is to test all of the various cross-account roles implied by an AWS credential to see if they were working as expected or not. Please see the README for more details. +> +> (A custom meta parent is used because the policy engine does not allow you to ignore_status on a signing error, so the meta parent will compare the aggregated incident results to the status of the child policies to determine if the API request succeeded or failed.) +> + +#### Metadata + +- **Policies**: Not displayed due to PR with no published policies. Please see [Github Pull Request](https://github.com/flexera-public/policy_templates/pull/2616) for details about unpublished policies. +- **Merged At**: 2024-10-11 19:31:30 UTC + +--- + +### PR [#2728](https://github.com/flexera-public/policy_templates/pull/2728): POL-1379 Azure SQL MI Storage Pricing Automation + +#### Description + +> This adds automation to gather Azure SQL MI Storage Pricing and updates the Azure SQL MI Storage policy template to use this pricing data. In most cases, this will not matter (the generic SQL DB storage pricing is the same in most cases), but this ensures that any deviations in storage pricing specific to SQL MI are accounted for. + +#### Metadata + +- **Policies**: [Azure Rightsize SQL Managed Instance Storage](https://github.com/flexera-public/policy_templates/tree/master/cost/azure/rightsize_managed_sql_storage/README.md), [Meta Parent: Azure Rightsize SQL Managed Instance Storage](https://github.com/flexera-public/policy_templates/tree/master/cost/azure/rightsize_managed_sql_storage/README.md) +- **Merged At**: 2024-10-11 17:53:41 UTC + +--- + +### PR [#2726](https://github.com/flexera-public/policy_templates/pull/2726): POL-1375 Google Label Cardinality Report: BigQuery Fix + +#### Description + +> Fixes an issue caused by the BigQuery API returning both the project ID and dataset ID in the "id" field when listing datasets. This caused errors when attempting to use this id to query for BigQuery tables in the dataset. +> + +#### Metadata + +- **Policies**: [Google Label Cardinality Report](https://github.com/flexera-public/policy_templates/tree/master/operational/google/label_cardinality/README.md), [Meta Parent: Google Label Cardinality Report](https://github.com/flexera-public/policy_templates/tree/master/operational/google/label_cardinality/README.md) +- **Merged At**: 2024-10-11 17:53:29 UTC + +--- + +### PR [#2743](https://github.com/flexera-public/policy_templates/pull/2743): POL-1382 Currency Conversion: Multiple Dimension Support + +#### Description + +> Adds support for multiple dimension filters for the `Currency Conversion` policy template. +> + +#### Metadata + +- **Policies**: [Currency Conversion](https://github.com/flexera-public/policy_templates/tree/master/cost/flexera/cco/currency_conversion/README.md) +- **Merged At**: 2024-10-11 13:18:16 UTC + +--- + +### PR [#2712](https://github.com/flexera-public/policy_templates/pull/2712): POL-1139 New Policy: AWS S3 Usage Type Rule-Based Dimension + +#### Description + +> This new unpublished policy template, `AWS S3 Usage Type Rule-Based Dimension`, creates a single rule-based dimension based on the usage_type values for AWS S3. The intent is to provide a more general and human readable alternative to the built-in dimension, whose values tend to be very specific and not very human readable. +> + +#### Metadata + +- **Policies**: Not displayed due to PR with no published policies. Please see [Github Pull Request](https://github.com/flexera-public/policy_templates/pull/2712) for details about unpublished policies. +- **Merged At**: 2024-10-10 18:09:28 UTC + +--- + +### PR [#2702](https://github.com/flexera-public/policy_templates/pull/2702): POL-1355 New Policy: AWS Rightsize ElastiCache + +#### Description + +> New policy template to produce rightsizing recommendations for AWS ElastiCache clusters. See README for more details. +> + +#### Metadata + +- **Policies**: [AWS Rightsize ElastiCache](https://github.com/flexera-public/policy_templates/tree/master/cost/aws/rightsize_elasticache/README.md), [Meta Parent: AWS Rightsize ElastiCache](https://github.com/flexera-public/policy_templates/tree/master/cost/aws/rightsize_elasticache/README.md) +- **Merged At**: 2024-10-09 17:11:27 UTC + +--- + +### PR [#2709](https://github.com/flexera-public/policy_templates/pull/2709): POL-1374 Email Cost Optimization Recommendations: Added Policy Support + +#### Description + +> Updates to Email Cost Optimization Recommendations. From the CHANGELOG: +> +> - Added support for additional recommendation policy templates +> - Changed "Disks" option to "Storage" for `Recommendation List` parameter to better reflect functionality +> - Added "PaaS" option to `Recommendation List` parameter +> + +#### Metadata + +- **Policies**: [Email Cost Optimization Recommendations](https://github.com/flexera-public/policy_templates/tree/master/cost/flexera/cco/email_recommendations/README.md) +- **Merged At**: 2024-10-09 17:11:10 UTC + +--- + +### PR [#2721](https://github.com/flexera-public/policy_templates/pull/2721): POL-1377 Cloud Bill Processing Error Notification: Fixes/Improvements + +#### Description + +> Fixes for `Cloud Bill Processing Error Notification`. From the CHANGELOG: +> +> - Updated some API requests to use newer internal Flexera API +> - Fixed error that sometimes caused functioning bill connections to appear in results +> - Fixed error that sometimes caused the policy template to fail +> - Modified incident table to include more useful information +> + +#### Metadata + +- **Policies**: [Cloud Bill Processing Error Notification](https://github.com/flexera-public/policy_templates/tree/master/operational/flexera/cco/bill_processing_errors_notification/README.md) +- **Merged At**: 2024-10-09 17:10:55 UTC + +--- + ### PR [#2708](https://github.com/flexera-public/policy_templates/pull/2708): POL-1373 Update AWS Superseded EBS Volumes - fix incorrect "New Monthly List Price" value #### Description @@ -1605,151 +1727,3 @@ This document contains the last 100 policy template merges for the `flexera-publ --- -### PR [#2371](https://github.com/flexera-public/policy_templates/pull/2371): POL-1276 New Policy: Fixed Cost Common Bill Ingestion - -#### Description - -> This is a new policy template, `Fixed Cost Common Bill Ingestion`, that inserts fixed costs into Flexera CCO via CBI. It will automatically create the necessary CBI endpoint, if it does not already exist, generate the CSV, and upload it to the endpoint. -> -> This PR also includes a small tweak to the Dangerfile to avoid false positives for comma separation when a comma is being referenced inside of a replace statement, such as "/,/" -> - -#### Metadata - -- **Policies**: [Fixed Cost Common Bill Ingestion](https://github.com/flexera-public/policy_templates/tree/master/cost/flexera/cco/fixed_cost_cbi/README.md) -- **Merged At**: 2024-07-01 15:07:25 UTC - ---- - -### PR [#2355](https://github.com/flexera-public/policy_templates/pull/2355): POL-1271 Azure Rightsize Managed Disks: SKU Filtering - -#### Description - -> This update to the `Azure Rightsize Managed Disks` policy adds support for filtering by disk SKU so that certain disks, such as HDDs, can be omitted from the results. -> - -#### Metadata - -- **Policies**: [Azure Rightsize Managed Disks](https://github.com/flexera-public/policy_templates/tree/master/cost/azure/rightsize_managed_disks/README.md), [Meta Parent: Azure Rightsize Managed Disks](https://github.com/flexera-public/policy_templates/tree/master/cost/azure/rightsize_managed_disks/README.md) -- **Merged At**: 2024-07-01 12:35:05 UTC - ---- - -### PR [#2261](https://github.com/flexera-public/policy_templates/pull/2261): FOPTS-3684 Azure Synapse SQL Pools - -#### Description - -> Policy to get optimization recommendations for Azure Synapse service to realize more savings. -> -> ### Issues Resolved -> -> Policy can recommend rightsizing dedicated pool compute resources or recommend to pause them to result in substantial potential savings. -> - -#### Metadata - -- **Policies**: [Azure Rightsize Synapse SQL Pools](https://github.com/flexera-public/policy_templates/tree/master/cost/azure/rightsize_synapse_sql_pools/README.md), [Meta Parent: Azure Rightsize Synapse SQL Pools](https://github.com/flexera-public/policy_templates/tree/master/cost/azure/rightsize_synapse_sql_pools/README.md) -- **Merged At**: 2024-06-27 22:32:04 UTC - ---- - -### PR [#2354](https://github.com/flexera-public/policy_templates/pull/2354): POL-1270 GitHub Policy Revamps - -#### Description - -> This is a revamp of all of the GitHub policy templates. Additionally, the policy master permission automation has been updated to handle GitHub. -> - -#### Metadata - -- **Policies**: Not displayed due to PR with > 5 policies. Please see [Github Pull Request](https://github.com/flexera-public/policy_templates/pull/2354) for these details. -- **Merged At**: 2024-06-27 12:05:44 UTC - ---- - -### PR [#2345](https://github.com/flexera-public/policy_templates/pull/2345): POL-1260 Cloud Spend Forecast - Straight-Line Revamp - -#### Description - -> NOTE: Errors are false positives from files being moved around. -> -> This is a revamp of the `Cloud Spend Forecast - Straight-Line` policy template. From the CHANGELOG: -> -> - Fixed issue where graph would not render if dimension name contains an ampersand -> - Several parameters altered to be more descriptive and human-readable -> - Added support for both simple and linear regression models via parameter -> - Added support for splitting cost by any arbitrary dimension -> - Added ability to filter by Billing Center via an allow or deny list -> - Streamlined code for better readability and faster execution -> -> Additionally, the `Cloud Spend Forecast - Straight-Line (Simple Model)` policy template has been deprecated. Its functionality has been folded into this policy template instead. -> - -#### Metadata - -- **Policies**: Not displayed due to PR with > 5 policies. Please see [Github Pull Request](https://github.com/flexera-public/policy_templates/pull/2345) for these details. -- **Merged At**: 2024-06-26 15:17:34 UTC - ---- - -### PR [#2336](https://github.com/flexera-public/policy_templates/pull/2336): POL-1259 Cloud Spend Moving Average Report Revamp - -#### Description - -> This is a revamp of the previously-named `Cloud Spend Forecast - Moving Average` policy template. It is now named `Cloud Spend Moving Average Report`. I did a fair bit of investigating into the history of this policy, and from what I can tell, it has never been a forecasting policy template, and a moving average is not a formula one can meaningfully use to forecast future cost. The policy template was originally named `Moving Average` and did not claim to provide a forecast, but this was changed at some point without any forecasting functionality being added to the policy template. -> -> From the CHANGELOG: -> -> - Renamed policy template and updated description to better reflect functionality -> - Added ability to filter by Billing Center as an allow list or a deny list -> - Added logic to ensure redundant Billing Centers don't skew results -> - Improvements made to moving average calculation for better accuracy -> - Incident table now used to display the moving average data used in the chart -> - Streamlined code for better readability and faster execution -> - -#### Metadata - -- **Policies**: [Cloud Spend Moving Average Report](https://github.com/flexera-public/policy_templates/tree/master/cost/flexera/cco/moving_average/README.md) -- **Merged At**: 2024-06-26 12:08:07 UTC - ---- - -### PR [#2339](https://github.com/flexera-public/policy_templates/pull/2339): POL-1269 Publish Meta Parent Policies - -#### Description - -> This makes several changes to add meta parent policies to the catalog: -> -> - Removes the `publish: false` flag from meta parent policies. -> - Changes their names to start with "Meta Parent: " to reduce risk of confusion with regular policies. -> - Changes their category to "Meta" to reduce risk of confusion with regular policies. -> - Policy description now contains information about meta policies and directs user to the meta policy README. -> - The meta policy README has been updated to better guide users on the functionality. - -#### Metadata - -- **Policies**: Not displayed due to PR with > 5 policies. Please see [Github Pull Request](https://github.com/flexera-public/policy_templates/pull/2339) for these details. -- **Merged At**: 2024-06-25 20:58:16 UTC - ---- - -### PR [#2334](https://github.com/flexera-public/policy_templates/pull/2334): POL-1267 AWS Accounts Missing Service Control Policies Revamp - -#### Description - -> This is a revamp of the `AWS Accounts Missing Service Control Policies` policy. From the CHANGELOG: -> -> - Changed policy template name to `AWS Accounts Missing Service Control Policies` to better reflect its functionality -> - Added ability to audit for multiple Service Control Policies in a single execution -> - Streamlined code for better readability and faster execution -> - Policy template now requires a valid Flexera credential -> - -#### Metadata - -- **Policies**: [AWS Accounts Missing Service Control Policies](https://github.com/flexera-public/policy_templates/tree/master/compliance/aws/missing_scps/README.md) -- **Merged At**: 2024-06-24 17:13:54 UTC - ---- - diff --git a/automation/aws/aws_account_credentials/CHANGELOG.md b/automation/aws/aws_account_credentials/CHANGELOG.md new file mode 100644 index 0000000000..a1ed544621 --- /dev/null +++ b/automation/aws/aws_account_credentials/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## v0.1.0 + +- Initial release diff --git a/automation/aws/aws_account_credentials/META_README.md b/automation/aws/aws_account_credentials/META_README.md new file mode 100644 index 0000000000..9938876be9 --- /dev/null +++ b/automation/aws/aws_account_credentials/META_README.md @@ -0,0 +1,11 @@ +# Meta Parent: AWS Account Credentials + +## What It Does + +This meta parent policy template consolidates the results of all of the associated child policy templates to provide reports of all AWS accounts in the Flexera organization. Each AWS account will be presented in one of three reports based on their status, which will be one of the below values: + +- *Passed* - The AWS cross-account role exists and the child applied policy was able to successfully make a GetCallerIdentity request to AWS STS with it. +- *Failed* - Either the AWS cross-account role does not exist or is not configured correctly, resulting in failure when making a GetCallerIdentity request to AWS STS with it. +- *Unknown* - The child applied policy has not yet been created or completed execution, and as a result, the status of the AWS cross-account role is unknown. This is most commonly seen soon after applying the meta parent policy and should mostly disappear after 24 hours. + +__NOTE: This meta parent policy template is not automatically generated and is customized for this specific use case. It needs to be manually updated and maintained whenever the child policy template is updated.__ diff --git a/automation/aws/aws_account_credentials/README.md b/automation/aws/aws_account_credentials/README.md new file mode 100644 index 0000000000..ea0da27bcb --- /dev/null +++ b/automation/aws/aws_account_credentials/README.md @@ -0,0 +1,57 @@ +# AWS Account Credentials + +## What It Does + +This policy template tests whether the selected AWS credential is able to successfully make a GetCallerIdentity request to AWS STS. If this request succeeds, an incident is raised reporting the success, and optionally, this incident can be emailed. If this request fails, the policy template will fail to complete and will show an error in Flexera One. + +__NOTE: This policy template is intended to be used in conjunction with its associated meta parent policy template to provide a complete report of all AWS accounts and the status of their associated cross-account roles. Please see the [Meta README](https://github.com/flexera-public/policy_templates/tree/master/automation/aws/aws_account_credentials/META_README.md) for more information.__ + +## Input Parameters + +- *Email Addresses* - Email addresses of the recipients you wish to notify when new incidents are created. +- *Account Number* - The Account number for use with the AWS STS Cross Account Role. Leave blank when using AWS IAM Access key and secret. It only needs to be passed when the desired AWS account is different than the one associated with the Flexera One credential. [More information is available in our documentation.](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm#automationadmin_1982464505_1123608) + +## Policy Actions + +- Sends an email notification + +## Prerequisites + +This Policy Template uses [Credentials](https://docs.flexera.com/flexera/EN/Automation/ManagingCredentialsExternal.htm) for authenticating to datasources -- in order to apply this policy you must have a Credential registered in the system that is compatible with this policy. If there are no Credentials listed when you apply the policy, please contact your Flexera Org Admin and ask them to register a Credential that is compatible with this policy. The information below should be consulted when creating the credential(s). + +### Credential Configuration + +For administrators [creating and managing credentials](https://docs.flexera.com/flexera/EN/Automation/ManagingCredentialsExternal.htm) to use with this policy, the following information is needed: + +- [**AWS Credential**](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm#automationadmin_1982464505_1121575) (*provider=aws*) which has the following permissions: + - `sts:GetCallerIdentity` + + Example IAM Permission Policy: + + ```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "sts:GetCallerIdentity" + ], + "Resource": "*" + } + ] + } + ``` + +- [**Flexera Credential**](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm) (*provider=flexera*) which has the following roles: + - `billing_center_viewer` + +The [Provider-Specific Credentials](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm) page in the docs has detailed instructions for setting up Credentials for the most common providers. + +## Supported Clouds + +- AWS + +## Cost + +This Policy Template does not incur any cloud costs. diff --git a/automation/aws/aws_account_credentials/aws_account_credentials.pt b/automation/aws/aws_account_credentials/aws_account_credentials.pt new file mode 100644 index 0000000000..ffa8391604 --- /dev/null +++ b/automation/aws/aws_account_credentials/aws_account_credentials.pt @@ -0,0 +1,289 @@ +name "AWS Account Credentials" +rs_pt_ver 20180301 +type "policy" +short_description "Reports whether the AWS credential has access to the AWS account. See the [README](https://github.com/flexera-public/policy_templates/tree/master/automation/aws/aws_account_credentials/) and [docs.flexera.com/flexera/EN/Automation](https://docs.flexera.com/flexera/EN/Automation/AutomationGS.htm) to learn more." +long_description "" +category "Cost" +severity "low" +default_frequency "daily" +info( + version: "0.1.0", + provider: "AWS", + service: "IAM", + policy_set: "Authentication", + publish: "false" +) + +############################################################################### +# Parameters +############################################################################### + +parameter "param_email" do + type "list" + category "Policy Settings" + label "Email Addresses" + description "Email addresses of the recipients you wish to notify when new incidents are created" + default [] +end + +parameter "param_aws_account_number" do + type "string" + category "Policy Settings" + label "Account Number" + description "This is for automated use with Meta Policies. See README for more details." + min_length 1 + # No default value, user input required +end + +############################################################################### +# Authentication +############################################################################### + +credentials "auth_aws" do + schemes "aws", "aws_sts" + label "AWS" + description "Select the AWS Credential from the list" + tags "provider=aws" + aws_account_number $param_aws_account_number +end + +credentials "auth_flexera" do + schemes "oauth2" + label "Flexera" + description "Select Flexera One OAuth2 credentials" + tags "provider=flexera" +end + +############################################################################### +# Datasources & Scripts +############################################################################### + +# Get applied policy metadata for use later +datasource "ds_applied_policy" do + request do + auth $auth_flexera + host rs_governance_host + path join(["/api/governance/projects/", rs_project_id, "/applied_policies/", policy_id]) + header "Api-Version", "1.0" + end +end + +# Get region-specific Flexera API endpoints +datasource "ds_flexera_api_hosts" do + run_script $js_flexera_api_hosts, rs_optima_host +end + +script "js_flexera_api_hosts", type: "javascript" do + parameters "rs_optima_host" + result "result" + code <<-EOS + host_table = { + "api.optima.flexeraeng.com": { + flexera: "api.flexera.com", + fsm: "api.fsm.flexeraeng.com" + }, + "api.optima-eu.flexeraeng.com": { + flexera: "api.flexera.eu", + fsm: "api.fsm-eu.flexeraeng.com" + }, + "api.optima-apac.flexeraeng.com": { + flexera: "api.flexera.au", + fsm: "api.fsm-apac.flexeraeng.com" + } + } + + result = host_table[rs_optima_host] +EOS +end + +# Get AWS account info +datasource "ds_cloud_vendor_accounts" do + request do + auth $auth_flexera + host val($ds_flexera_api_hosts, 'flexera') + path join(["/finops-analytics/v1/orgs/", rs_org_id, "/cloud-vendor-accounts"]) + header "Api-Version", "1.0" + # Header X-Meta-Flexera has no affect on datasource query, but is required for Meta Policies + # Forces `ds_is_deleted` datasource to run first during policy execution + header "Meta-Flexera", val($ds_is_deleted, "path") + end + result do + encoding "json" + collect jmes_path(response, "values[*]") do + field "id", jmes_path(col_item, "aws.accountId") + field "name", jmes_path(col_item, "name") + field "tags", jmes_path(col_item, "tags") + end + end +end + +datasource "ds_get_caller_identity" do + request do + auth $auth_aws + verb "GET" + host "sts.amazonaws.com" + path "/" + query "Action", "GetCallerIdentity" + query "Version", "2011-06-15" + header "User-Agent", "RS Policies" + ignore_status [422] + end + result do + encoding "xml" + collect xpath(response, "//GetCallerIdentityResponse/GetCallerIdentityResult") do + field "account", xpath(col_item, "Account") + end + end +end + +datasource "ds_aws_account_status" do + run_script $js_aws_account_status, $ds_cloud_vendor_accounts, $ds_get_caller_identity, $ds_applied_policy, $param_aws_account_number +end + +script "js_aws_account_status", type:"javascript" do + parameters "ds_cloud_vendor_accounts", "ds_get_caller_identity", "ds_applied_policy", "param_aws_account_number" + result "result" + code <<-EOS + account = _.find(ds_cloud_vendor_accounts, function(account) { + return account['id'] == param_aws_account_number + }) + + name = "" + if (account != undefined) { name = account['name'] } + + credential_status = "Failed" + if (ds_get_caller_identity.length > 0) { credential_status = "Passed" } + + result = [{ + id: param_aws_account_number, + name: name, + status: credential_status, + policy_name: ds_applied_policy['name'] + }] +EOS +end + +############################################################################### +# Policy +############################################################################### + +policy "pol_credentials" do + validate_each $ds_aws_account_status do + summary_template "{{ with index data 0 }}{{ .policy_name }}{{ end }}: {{ len data }} AWS Account Credentials Tested" + check logic_or($ds_parent_policy_terminated, eq(val(item, "resourceID"), "")) + escalate $esc_email + export do + resource_level true + field "id" do + label "Account ID" + end + field "name" do + label "Account Name" + end + field "status" do + label "Status" + end + end + end +end + +############################################################################### +# Escalations +############################################################################### + +escalation "esc_email" do + automatic true + label "Send Email" + description "Send incident email" + email $param_email +end + +############################################################################### +# Meta Policy [alpha] +# Not intended to be modified or used by policy developers +############################################################################### + +# If the meta_parent_policy_id is not set it will evaluate to an empty string and we will look for the policy itself, +# if it is set we will look for the parent policy. +datasource "ds_get_policy" do + request do + auth $auth_flexera + host rs_governance_host + ignore_status [404] + path join(["/api/governance/projects/", rs_project_id, "/applied_policies/", switch(ne(meta_parent_policy_id, ""), meta_parent_policy_id, policy_id)]) + header "Api-Version", "1.0" + end + result do + encoding "json" + field "id", jmes_path(response, "id") + end +end + +datasource "ds_parent_policy_terminated" do + run_script $js_decide_if_self_terminate, $ds_get_policy, policy_id, meta_parent_policy_id +end + +# If the policy was applied by a meta_parent_policy we confirm it exists if it doesn't we confirm we are deleting +# This information is used in two places: +# - determining whether or not we make a delete call +# - determining if we should create an incident (we don't want to create an incident on the run where we terminate) +script "js_decide_if_self_terminate", type: "javascript" do + parameters "found", "self_policy_id", "meta_parent_policy_id" + result "result" + code <<-EOS + var result + if (meta_parent_policy_id != "" && found.id == undefined) { + result = true + } else { + result = false + } + EOS +end + +# Two potentials ways to set this up: +# - this way and make a unneeded 'get' request when not deleting +# - make the delete request an interate and have it iterate over an empty array when not deleting and an array with one item when deleting +script "js_make_terminate_request", type: "javascript" do + parameters "should_delete", "policy_id", "rs_project_id", "rs_governance_host" + result "request" + code <<-EOS + + var request = { + auth: 'auth_flexera', + host: rs_governance_host, + path: "/api/governance/projects/" + rs_project_id + "/applied_policies/" + policy_id, + headers: { + "API-Version": "1.0", + "Content-Type":"application/json" + }, + } + + if (should_delete) { + request.verb = 'DELETE' + } + EOS +end + +datasource "ds_terminate_self" do + request do + run_script $js_make_terminate_request, $ds_parent_policy_terminated, policy_id, rs_project_id, rs_governance_host + end +end + +datasource "ds_is_deleted" do + run_script $js_check_deleted, $ds_terminate_self +end + +# This is just a way to have the check delete request connect to the farthest leaf from policy. +# We want the delete check to the first thing the policy does to avoid the policy erroring before it can decide whether or not it needs to self terminate +# Example a customer deletes a credential and then terminates the parent policy. We still want the children to self terminate +# The only way I could see this not happening is if the user who applied the parent_meta_policy was offboarded or lost policy access, the policies who are impersonating the user +# would not have access to self-terminate +# It may be useful for the backend to enable a mass terminate at some point for all meta_child_policies associated with an id. +script "js_check_deleted", type: "javascript" do + parameters "response" + result "result" + code <<-EOS + result = {"path":"/"} + EOS +end diff --git a/automation/aws/aws_account_credentials/aws_account_credentials_meta_parent.pt b/automation/aws/aws_account_credentials/aws_account_credentials_meta_parent.pt new file mode 100644 index 0000000000..7a0e95e977 --- /dev/null +++ b/automation/aws/aws_account_credentials/aws_account_credentials_meta_parent.pt @@ -0,0 +1,1359 @@ +name "Meta Parent: AWS Account Credentials" +rs_pt_ver 20180301 +type "policy" +short_description "**NOTE: Meta policies are an alpha feature. Please consult the [README](https://github.com/flexera-public/policy_templates/blob/master/README_META_POLICIES.md) before use.** Applies and manages \"child\" [AWS Account Credentials](https://github.com/flexera-public/policy_templates/tree/master/automation/aws/aws_account_credentials) Policies." +severity "low" +category "Meta" +default_frequency "15 minutes" +info( + provider: "AWS", + version: "0.1.0", # This version of the Meta Parent Policy Template should match the version of the Child Policy Template as it appears in the Catalog for best reliability + publish: "false", + deprecated: "false" +) + +############################################################################## +# Parameters +############################################################################## + +## Meta Parent Parameters +## These are params specific to the meta parent policy. +parameter "param_combined_incident_email_passed" do + type "list" + label "Email Addresses: Passed Accounts" + description "A list of email addresses to send the report of accounts with working credentrials to. Leave empty to not email this report." + default [] +end + +parameter "param_combined_incident_email_failed" do + type "list" + label "Email Addresses: Failed Accounts" + description "A list of email addresses to send the report of accounts with failing credentrials to. Leave empty to not email this report." + default [] +end + +parameter "param_combined_incident_email_unknown" do + type "list" + label "Email Addresses: Unknown Accounts" + description "A list of email addresses to send the report of accounts with credentrials of unknown status to. Leave empty to not email this report." + default [] +end + +parameter "param_combined_incident_email_child" do + type "list" + label "Email Addresses: Child Policies" + description "A list of email addresses to send the report of child policy status to. Primarily for debugging purposes. Leave empty to not email this report." + default [] +end + +parameter "param_dimension_filter_includes" do + type "list" + label "Dimension Include Filters" + description <<-EOS + Filters [`dimension_name=dimension_value` and `dimension_name=~dimension_value` pairs] to determine which AWS Accounts returned by the Flexera Bill Analysis API to **INCLUDE** and be applied to. + Use = to match the entire value and =~ to match a substring contained in the value. + During each run this policy will select AWS Accounts who match **all** the filters defined and apply a child policy for each. + If no include filters are provided, then all AWS Accounts are included by default. + Most of the dimensions in Flexera can be used [default dimensions, custom tag dimensions, rule-based dimensions]. Full list of available dimensions documented in the [Bill Analysis API Docs](https://reference.rightscale.com/bill_analysis/). + EOS + default [] +end + +parameter "param_dimension_filter_excludes" do + type "list" + label "Dimension Exclude Filters" + description <<-EOS + Filters [`dimension_name=dimension_value` and `dimension_name=~dimension_value` pairs] to determine which AWS Accounts returned by the Flexera Bill Analysis API to **EXCLUDE** and *not* have policy applied to. + Use = to match the entire value and =~ to match a substring contained in the value. + During each run this policy will select AWS Accounts who match **all** the filters defined here and excludes them from results. + Can be used to exclude specific AWS Accounts [`vendor_account=123456789012`] + Most of the dimensions in Flexera can be used [default dimensions, custom tag dimensions, rule-based dimensions]. Full list of available dimensions documented in the [Bill Analysis API Docs](https://reference.rightscale.com/bill_analysis/). + EOS + default [] +end + +parameter "param_policy_schedule" do + type "string" + label "Child Policy Schedule" + description "The interval at which the child policy checks for conditions and generates incidents." + default "daily" + allowed_values "daily", "weekly", "monthly" +end + +parameter "param_template_source" do + type "string" + label "Child Policy Template Source" + description "By default, will use the \"AWS Account Credentials\" Policy Template from Catalog. Optionally, you can use the \"AWS Account Credentials\" Policy Template uploaded in the current Flexera Project." + default "Uploaded Template" + allowed_values "Published Catalog Template", "Uploaded Template" +end + +## Child Policy Parameters + + +############################################################################### +# Authentication +############################################################################### +credentials "auth_aws" do + schemes "aws", "aws_sts" + label "AWS" + description "Select the AWS Credential from the list" + tags "provider=aws" + aws_account_number $param_aws_account_number +end + +credentials "auth_flexera" do + schemes "oauth2" + label "Flexera" + description "Select Flexera One OAuth2 credentials" + tags "provider=flexera" +end + +############################################################################### +# Datasources +############################################################################### + +# Get Applied Parent Policy Details +datasource "ds_self_policy_information" do + request do + auth $auth_flexera + host rs_governance_host + path join(["/api/governance/projects/", rs_project_id, "/applied_policies/", policy_id]) + header "Api-Version", "1.0" + end + result do + encoding "json" + field "name", jmes_path(response, "name") + field "creator_id", jmes_path(response, "created_by.id") + field "credentials", jmes_path(response, "credentials") + field "options", jmes_path(response, "options") + end +end + +datasource "ds_child_policy_options" do + run_script $js_child_policy_options, $ds_self_policy_information +end + +script "js_child_policy_options", type: "javascript" do + parameters "ds_self_policy_information" + result "options" + code <<-EOS + // Filter Options that are not appropriate for Child Policy + var options = _.map(ds_self_policy_information.options, function(option){ + // param_combined_incident_email, param_dimension_filter_includes, param_dimension_filter_excludes, param_policy_schedule are exclusion to Meta Parent Policy Parameters + if (!_.contains(["param_combined_incident_email", "param_combined_incident_email_passed", "param_combined_incident_email_failed", "param_combined_incident_email_unknown", "param_dimension_filter_includes", "param_dimension_filter_excludes", "param_policy_schedule", "param_template_source"], option.name)) { + return { "name": option.name, "value": option.value }; + } + }); + // Explicitly add param_email which is disabled/does not exist in meta parent policy + options.push({ + "name": "param_email", + "value": [] + }); + EOS +end + +datasource "ds_child_policy_options_map" do + run_script $js_child_policy_options_map, $ds_child_policy_options +end + +script "js_child_policy_options_map", type: "javascript" do + parameters "ds_child_policy_options" + result "options" + code <<-EOS + function format_options_keyvalue(options) { + var options_keyvalue_map = {}; + _.each(options, function(option) { + options_keyvalue_map[option.name] = option.value; + }); + return options_keyvalue_map; + } + var options = format_options_keyvalue(ds_child_policy_options) + EOS +end + +datasource "ds_format_self" do + run_script $js_format_self, $ds_self_policy_information, $ds_child_policy_options_map +end + +script "js_format_self", type: "javascript" do + parameters "ds_self_policy_information", "ds_child_policy_options_map" + result "formatted" + code <<-EOS + var formatted = { + "name": ds_self_policy_information["name"], + "creator_id": ds_self_policy_information["creator_id"], + "credentials": ds_self_policy_information["credentials"], + "options": ds_child_policy_options_map + }; + EOS +end + +# Get Pulished Policy Details +datasource "ds_get_published_child_policy_information" do + request do + auth $auth_flexera + host rs_governance_host + path join(["/api/governance/orgs/", rs_org_id, "/published_templates"]) + header "Api-Version", "1.0" + end + result do + encoding "json" + collect jmes_path(response, "items[*]") do + field "name", jmes_path(col_item, "name") + field "created_by", jmes_path(col_item, "created_by.email") + field "href", jmes_path(col_item, "href") + field "short_description", jmes_path(col_item, "short_description") + end + end +end + +# Select the published policy that is published by "support@flexera.com" and matches the name of the child policy template +datasource "ds_published_child_policy_information" do + run_script $js_published_child_policy_information, $ds_get_published_child_policy_information +end + +script "js_published_child_policy_information", type: "javascript" do + parameters "ds_get_published_child_policy_information" + result "result" + code <<-EOS + result = _.filter(ds_get_published_child_policy_information, function(item) { + return item['name'] == "AWS Account Credentials" && item['created_by'] == "support@flexera.com" + }) +EOS +end + +# Get Uploaded Policy Details +datasource "ds_get_project_child_policy_information" do + request do + auth $auth_flexera + host rs_governance_host + path join(["/api/governance/projects/", rs_project_id, "/policy_templates"]) + header "Api-Version", "1.0" + end + result do + encoding "json" + collect jmes_path(response, "items[*]") do + field "name", jmes_path(col_item, "name") + field "href", jmes_path(col_item, "href") + field "short_description", jmes_path(col_item, "short_description") + end + end +end + +# Select the uploaded policy that matches the name of the child policy template +datasource "ds_project_child_policy_information" do + run_script $js_project_child_policy_information, $ds_get_project_child_policy_information +end + +script "js_project_child_policy_information", type: "javascript" do + parameters "ds_get_project_child_policy_information" + result "result" + code <<-EOS + result = _.filter(ds_get_project_child_policy_information, function(item) { + return item['name'] == "AWS Account Credentials" + }) +EOS +end + +datasource "ds_get_billing_centers" do + request do + auth $auth_flexera + host rs_optima_host + path join(["/analytics/orgs/",rs_org_id,"/billing_centers"]) + header "Api-Version", "1.0" + header "User-Agent", "RS Policies" + query "view", "allocation_table" + ignore_status [403] + end + result do + encoding "json" + # Select the Billing Centers that have "parent_id" undefined or "" (i.e. top-level Billing Centers) + collect jq(response, '.[] | select(.parent_id == null)' ) do + field "href", jq(col_item,".href") + field "id", jq(col_item,".id") + field "name", jq(col_item,".name") + field "parent_id", jq(col_item,".parent_id") + end + end +end + +script "js_make_billing_center_request", type: "javascript" do + parameters "rs_org_id", "rs_optima_host", "billing_centers_unformatted", "param_dimension_filter_includes", "param_dimension_filter_excludes" + result "request" + code <<-EOS + + billing_centers_formatted = [] + + for (x=0; x< billing_centers_unformatted.length; x++) { + billing_centers_formatted.push(billing_centers_unformatted[x]["id"]) + } + + finish = new Date() + finishFormatted = finish.toJSON().split("T")[0] + start = new Date() + start.setDate(start.getDate() - 30) + startFormatted = start.toJSON().split("T")[0] + + // Default dimensions and filter expressions required for meta parent policy + var dimensions = ["vendor_account", "vendor_account_name"]; + var filter_expressions = [ + { dimension: "vendor", type: "equal", value: "AWS" } + ] + + // Append to default dimensions and filter expressions using parent policy params + _.each(param_dimension_filter_includes, function (v) { + // split key=value string + if (v.indexOf('=~') == -1) { + var split = v.split("="); + var type = "equal" + } else { + var split = v.split("=~"); + var type = "substring" + } + + var k = split[0]; + var v = split[1]; + + // append to lists + dimensions.push(k); + + if (type == "equal") { + filter_expressions.push({ dimension: k, type: "equal", value: v }); + } else { + filter_expressions.push({ dimension: k, type: "substring", substring: v }); + } + }); + + // Append to filter expressions using exclude policy params + _.each(param_dimension_filter_excludes, function (v) { + // split key=value string + if (v.indexOf('=~') == -1) { + var split = v.split("="); + var type = "equal" + } else { + var split = v.split("=~"); + var type = "substring" + } + + var k = split[0]; + var v = split[1]; + + // append to lists + dimensions.push(k); + + if (type == "equal") { + filter_expressions.push({ "type": "not", "expression": { "dimension": k, "type": "equal", "value": v } }); + } else { + filter_expressions.push({ "type": "not", "expression": { "dimension": k, "type": "substring", "substring": v } }); + } + }); + + // Produces a duplicate-free version of the array + dimensions = _.uniq(dimensions); + + var body = { + "dimensions": dimensions, + "granularity":"day", + "start_at": startFormatted, + "end_at": finishFormatted, + "metrics":["cost_amortized_unblended_adj"], + "billing_center_ids": billing_centers_formatted, + "filter": + { + "type": "and", + "expressions": filter_expressions + }, + "summarized": true + } + var request = { + auth: 'auth_flexera', + host: rs_optima_host, + scheme: 'https', + verb: 'POST', + path: "/bill-analysis/orgs/"+ rs_org_id + "/costs/aggregated", + headers: { + "API-Version": "1.0", + "Content-Type":"application/json" + }, + body: JSON.stringify(body) + } + EOS +end + +# Get the AWS acounts +datasource "ds_get_aws_accounts" do + request do + run_script $js_make_billing_center_request, rs_org_id, rs_optima_host, $ds_get_billing_centers, $param_dimension_filter_includes, $param_dimension_filter_excludes + end + result do + encoding "json" + collect jmes_path(response,"rows[*]") do + field "aws_account_id", jmes_path(col_item,"dimensions.vendor_account") + field "aws_account_name", jmes_path(col_item,"dimensions.vendor_account_name") + end + end +end + +# Get Child policies +datasource "ds_get_existing_policies" do + request do + auth $auth_flexera + host rs_governance_host + path join(["/api/governance/projects/", rs_project_id, "/applied_policies"]) + header "Api-Version", "1.0" + query "meta_parent_policy_id", policy_id + end + result do + encoding "json" + collect jmes_path(response, "items[*]") do + field "name", jmes_path(col_item, "name") + field "applied_policy_id", jmes_path(col_item, "id") + field "options", jmes_path(col_item, "options") + field "updated_at", jmes_path(col_item, "updated_at") + field "status", jmes_path(col_item, "status") + end + end +end + +# Get Child policies incidents +datasource "ds_get_existing_policies_incidents" do + request do + auth $auth_flexera + host rs_governance_host + path join(["/api/governance/projects/", rs_project_id, "/incidents"]) + header "Api-Version", "1.0" + query "meta_parent_policy_id", policy_id + query "state", "triggered" + end + result do + encoding "json" + collect jmes_path(response, "items[*]") do + field "incident_id", jmes_path(col_item, "id") + field "applied_policy_id", jmes_path(col_item, "applied_policy.id") + field "summary", jmes_path(col_item, "summary") + field "state", jmes_path(col_item, "state") + field "violation_data_count", jmes_path(col_item, "violation_data_count") + field "updated_at", jmes_path(col_item, "updated_at") + field "meta_parent_policy_id", jmes_path(col_item, "meta_parent_policy_id") + end + end +end + +datasource "ds_format_incidents" do + run_script $js_format_existing_policies_incidents, $ds_get_existing_policies_incidents +end + +script "js_format_existing_policies_incidents", type: "javascript" do + parameters "unformatted" + result "formatted" + code <<-EOS + formatted={} + + _.each(unformatted, function(incident) { + if (formatted[incident['applied_policy_id']] == undefined) { + formatted[incident['applied_policy_id']] = [] + } + + formatted[incident['applied_policy_id']].push(incident) + }) +EOS +end + +datasource "ds_format_existing_policies" do + run_script $js_format_existing_policies, $ds_get_existing_policies, $ds_format_incidents +end + +# format +# duplicates logic should compare updated at +# we can validate update here when destructring the existing policy options, don't need updated at +# format options +script "js_format_existing_policies", type: "javascript" do + parameters "ds_get_existing_policies", "ds_format_incidents" + result "result" + code <<-EOS + function format_options_keyvalue(options) { + var options_keyvalue_map = {}; + _.each(options, function(option) { + options_keyvalue_map[option.name] = option.value; + }); + return options_keyvalue_map; + } + + result = {} + formatted = {} + duplicates = [] + // tracking holds all existing policies and later can be used to determine if existing policies should be deleted [i.e. if cloud account was removed] + tracking = {} + + for (x=0; x newDate) { + duplicates.push({ + "applied_policy_id":ds_get_existing_policies[x]["applied_policy_id"], + "applied_policy_name":ds_get_existing_policies[x]["name"], + "status":ds_get_existing_policies[x]["status"], + "updated_at":ds_get_existing_policies[x]["updated_at"], + "incident": incident, + "incident2": incident2 + }) + } else { + duplicates.push({ + "applied_policy_id":current["applied_policy_id"], + "applied_policy_name":current["applied_policy_name"], + "status":current["status"], + "updated_at":current["updated_at"], + "incident": current["incident"], + "incident2": current["incident2"] + }) + formatted[aws_account_id] = { + "applied_policy_id":ds_get_existing_policies[x]["applied_policy_id"], + "applied_policy_name":ds_get_existing_policies[x]["name"], + "status":ds_get_existing_policies[x]["status"], + "updated_at":ds_get_existing_policies[x]["updated_at"], + "incident": incident, + "incident2": incident2, + "options": options + } + + } + } + } + + result.formatted=formatted + result.duplicates=duplicates + result.tracking=tracking + EOS +end + +datasource "ds_take_in_parameters" do + run_script $js_take_in_parameters, $ds_get_aws_accounts, $ds_format_self, first($ds_published_child_policy_information), first($ds_project_child_policy_information), $ds_format_existing_policies, $ds_child_policy_options, $ds_child_policy_options_map, $param_template_source, $param_policy_schedule, policy_id, f1_app_host, rs_org_id, rs_project_id +end + +# hardcode template href with id from catalog +# catalog policies show in customer's published templates with their org id +# "template_href": "/api/governance/orgs/" + rs_org_id + "/published_templates/62618616e3dff80001572bf0" +# update logic: the only reason we're going to update the child policies for is changes to options +# and only some options, email is always blank and aws_account_id is tied to the idenity of each policy, so: new account creation, removal of account: termination +# param_automatic_action is a list with only one action, unless the person is applying using an API and putting the same value multiple times this should either be a length of 0 or 1 +# param_log_to_cm_audit_entries is a String of Yes or No +# param_exclude_tags and param_allowed_regions are arrays. I'm doing an update on the order changing but the values remaining the same. +# If we only want to do an update on the values changing we could sort before doing the equality check. +script "js_take_in_parameters", type: "javascript" do + parameters "ds_get_aws_accounts", "ds_format_self", "ds_published_child_policy_information", "ds_project_child_policy_information", "ds_format_existing_policies", "ds_child_policy_options", "ds_child_policy_options_map", "param_template_source", "param_policy_schedule", "meta_parent_policy_id", "f1_app_host", "rs_org_id", "rs_project_id" + result "grid_and_cwf" + code <<-EOS + + // Set Child Policy Information based on param_template_source value + if (param_template_source == "Published Catalog Template") { + child_policy_information = ds_published_child_policy_information + } else { + child_policy_information = ds_project_child_policy_information + } + + max_actions = 50; + + grid_and_cwf={grid:[], to_create:[], to_update:[], to_delete:[], parent_policy:ds_format_self}; + + should_keep = ds_format_existing_policies.tracking; + + // Construct UI URL prefixes for policy template summary + ui_url_prefix = "https://" + f1_app_host + "/orgs/" + rs_org_id; + applied_policy_url_prefix = ui_url_prefix + "/automation/applied-policies/projects/" + rs_project_id + "?noIndex=1&policyId="; + incident_url_prefix = ui_url_prefix + "/automation/incidents/projects/" + rs_project_id + "?noIndex=1&incidentId="; + + function add_to_grid(ep, action) { + policy_status={ + "id": ep["applied_policy_id"], + "policy_name": ep["applied_policy_name"] + '||' + applied_policy_url_prefix + ep["applied_policy_id"], + "meta_policy_status": action, + "policy_status": ep["status"], + "policy_last_update": ep["updated_at"], + }; + + if (ep.incident != null && ep.incident != undefined) { + // Remove policy name from summary when applicable + summary_parts = ep.incident.summary.split(':') + summary = summary_parts[summary_parts.length - 1].trim() + + policy_status["incident_summary"] = summary + '||' + incident_url_prefix + ep.incident.incident_id; + policy_status["incident_state"] = ep.incident.state; + policy_status["incident_violation_data_count"] = ep.incident.violation_data_count; + policy_status["incident_last_update"] = ep.incident.updated_at; + } + + if (ep.incident2 != null && ep.incident2 != undefined) { + // Remove policy name from summary when applicable + summary_parts = ep.incident2.summary.split(':') + summary = summary_parts[summary_parts.length - 1].trim() + + policy_status["incident_summary"] = summary + '||' + incident_url_prefix + ep.incident2.incident_id; + policy_status["incident_state"] = ep.incident2.state; + policy_status["incident2_violation_data_count"] = ep.incident2.violation_data_count; + policy_status["incident2_last_update"] = ep.incident2.updated_at; + } + + grid_and_cwf.grid.push(policy_status); + } + + for (x=0; x -1) { + _.each(incident["violation_data"], function(violation) { + result.push(violation) + }) + } + }) + + policies_by_account = {} + + _.each(ds_get_existing_policies, function(policy) { + param_aws_account_number = _.find(policy['options'], function(option) { + return option['name'] == 'param_aws_account_number' + }) + + policies_by_account[param_aws_account_number["value"]] = policy + }) + + non_passed_accounts = _.reject(ds_get_aws_accounts, function(account) { + return typeof(account['aws_account_id']) != 'string' || account['aws_account_id'] == '' || _.contains(_.pluck(result, 'id'), account['aws_account_id']) + }) + + _.each(non_passed_accounts, function(account) { + status = "Unknown" + + if (policies_by_account[account['aws_account_id']] != undefined && policies_by_account[account['aws_account_id']]['status'] == "error") { + status = "Failed" + } + + result.push({ + id: account['aws_account_id'], + name: account['aws_account_name'], + status: status, + orgId: rs_org_id, + orgName: rs_org_name + }) + }) + + result = _.sortBy(result, 'id') + result = _.sortBy(result, 'status') +EOS +end + +datasource "ds_aws_account_status_incident_passed" do + run_script $js_aws_account_status_incident_sorter, $ds_aws_account_status_combined_incidents, "Passed" +end + +datasource "ds_aws_account_status_incident_failed" do + run_script $js_aws_account_status_incident_sorter, $ds_aws_account_status_combined_incidents, "Failed" +end + +datasource "ds_aws_account_status_incident_unknown" do + run_script $js_aws_account_status_incident_sorter, $ds_aws_account_status_combined_incidents, "Unknown" +end + +script "js_aws_account_status_incident_sorter", type: "javascript" do + parameters "ds_aws_account_status_combined_incidents", "status" + result "result" + code <<-EOS + result = _.filter(ds_aws_account_status_combined_incidents, function(item) { + return item['status'] == status + }) +EOS +end + +# Summary and a conditional incident which will show up if any policy is being applied, updated or deleted. +# Minimum of 1 incident, max of four +# Could swap the summary to only showing running +# Could also just have one incident and use meta_status to determine which escalation happens +policy "policy_scheduled_report" do + validate $ds_aws_account_status_incident_passed do + summary_template "{{ rs_org_name }} ({{ rs_org_id }}): AWS Account Credentials Passed: {{ len data }}" + detail_template "Note: Results will likely be incomplete, with a number of accounts showing a status of \"Unknown\", until parent policy has been running for ~24 hours." + check eq(size(data), 0) + escalate $esc_email_passed + export do + resource_level true + field "orgId" do + label "Flexera Org ID" + end + field "orgName" do + label "Flexera Org Name" + end + field "id" do + label "Account ID" + end + field "name" do + label "Account Name" + end + field "status" do + label "Status" + end + end + end + + validate $ds_aws_account_status_incident_failed do + summary_template "{{ rs_org_name }} ({{ rs_org_id }}): AWS Account Credentials Failed: {{ len data }}" + check eq(size(data), 0) + escalate $esc_email_failed + export do + resource_level true + field "orgId" do + label "Flexera Org ID" + end + field "orgName" do + label "Flexera Org Name" + end + field "id" do + label "Account ID" + end + field "name" do + label "Account Name" + end + field "status" do + label "Status" + end + end + end + + validate $ds_aws_account_status_incident_unknown do + summary_template "{{ rs_org_name }} ({{ rs_org_id }}): AWS Account Credentials Unknown: {{ len data }}" + detail_template "Note: These accounts should transition to either the 'Passed' or 'Failed' results over time. Please allow up to 24 hours after initial policy application for this to occur." + check eq(size(data), 0) + escalate $esc_email_unknown + export do + resource_level true + field "orgId" do + label "Flexera Org ID" + end + field "orgName" do + label "Flexera Org Name" + end + field "id" do + label "Account ID" + end + field "name" do + label "Account Name" + end + field "status" do + label "Status" + end + end + end + + # Status Incident Check + validate $ds_take_in_parameters do + summary_template "Meta Parent: Status of Child Policies" + detail_template <<-EOS +The current status of Child Policies for **{{ data.parent_policy.name }}**: + +Total Child Applied Policies: {{ len data.grid }} +EOS + check false # always trigger this status incident + escalate $esc_email_child_policies + export "grid" do + resource_level true + field "id" do + label "Applied Policy ID" + end + field "policy_name" do + label "Applied Policy Name" + format "link-external" + end + field "meta_policy_status" do + label "Meta Child Policy Status" + end + field "policy_status" do + label "Policy Status" + end + field "policy_last_update" do + label "Policy Last Update" + end + field "incident_summary" do + label "Incident Summary" + format "link-external" + end + field "incident_state" do + label "Incident State" + end + field "incident_violation_data_count" do + label "Incident Violation Count" + end + field "incident_last_update" do + label "Incident Last Update" + end + field "incident2_summary" do + label "Incident 2 Summary" + format "link-external" + end + field "incident2_state" do + label "Incident 2 State" + end + field "incident2_violation_data_count" do + label "Incident 2 Violation Count" + end + field "incident2_last_update" do + label "Incident 2 Last Update" + end + end + end + + # Create Child Policies Incident Check + validate $ds_to_create do + summary_template "Meta Parent: Policies being created" + detail_template <<-EOS + Policies Being Created: + + | Applied Policy | + | --------------- | + {{ range data -}} + | {{ .name }} | + {{ end -}} + EOS + escalate $create_policies + check eq(size(data),0) + end + + # Update Child Policies Incident Check + validate $ds_to_update do + summary_template "Meta Parent: Policies being updated" + detail_template <<-EOS + Policies Being Updated: + + | Applied Policy | + | --------------- | + {{ range data -}} + | {{ .name }} | + {{ end -}} + EOS + escalate $update_policies + check eq(size(data),0) + end + + # Delete Child Policies Incident Check + validate $ds_to_delete do + summary_template "Meta Parent: Policies being deleted" + detail_template <<-EOS + Policies being Deleted: + + | Applied Policy | + | --------------- | + {{ range data -}} + | {{ .name }} | + {{ end -}} + EOS + escalate $delete_policies + check eq(size(data),0) + end +end + +# Begin Shared Functions for Child Actions from Consolidated Incident +define groupByIncidentID($data) return $incidents do + # Empty hash to store incidents is incident_id + $incidents = {} + + task_label("Grouping items by Incident ID") + $index = 1 + foreach $item in $data do + task_label("Grouping items by Incident ID. "+to_s($index)+"/"+to_s(size($data))) + if !$incidents[$item["incident_id"]] + #task_label("Grouping items by Incident ID. "+to_s($index)+"/"+to_s(size($data))". New Incident: "+$item["incident_id"]) + $incidents[$item["incident_id"]] = {"id": $item["incident_id"], "resource_ids": []} + end + #task_label("Grouping items by Incident ID. "+to_s($index)+"/"+to_s(size($data))". Appending Resource: "+$item["id"]) + # Append resource id to the list for the incident + $incidents[$item["incident_id"]]["resource_ids"] = $incidents[$item["incident_id"]]["resource_ids"] + [$item["id"]] + end +end + +define child_run_action($data, $governance_host, $rs_project_id, $action_label, $action_options) do + # Empty global array for log strings, helpful for debugging + $$debug = [] + + # Group Resources by Incident ID + # This reduces the number of requests made to the Flexera API + call groupByIncidentID($data) retrieve $incidents + $$debug_incidents = to_json($incidents) + + call runActions($incidents, $action_label, $governance_host, $rs_project_id, $action_options) + + # If we encountered any errors, use `raise` to mark the CWF process as errored + if inspect($$errors) != "null" + raise join($$errors,"\n") + end + + # If we made it here, all actions completed successfully + # Celebrate Success! + task_label("All \""+$action_label+"\" actions completed successfully!") +end + +define runActions($incidents, $action_label, $governance_host, $rs_project_id, $action_options) do + foreach $id in keys($incidents) do + sub on_error: handle_error() do + $incident = $incidents[$id] + task_label("Triggering action \""+$action_label+"\" on "+size($incident["resource_ids"])+" count resources via incident "+$incident["id"]) + $request = { + auth: $$auth_flexera, + verb: "get", + https: true, + host: $governance_host, + href: join(["/api/governance/projects/", $rs_project_id, "/incidents/", $incident["id"]]), + headers: { "Api-Version": "1.0" }, + query_strings: { "view": "extended" } + } + $response = http_request($request) + $$debug << to_json({ + "request": $request, + "response": $response + }) + $action_id = "" + foreach $action in $response["body"]["available_actions"] do + # If we have not already found the action id, and the label matches, set the action id + # The first check is to prevent looking through the entire list if we already have the id + if $action["label"] == $action_label + $action_id = $action["id"] + end + end + if $action_id == "" + raise "Could not find action id for \""+$action_label+"\" response="+to_json($response) + end + # Now we are reach to trigger the action + $request = { + auth: $$auth_flexera, + verb: "post", + https: true, + host: $governance_host, + href: join(["/api/governance/projects/", $rs_project_id, "/incidents/", $incident["id"],"/actions/", $action_id,"/run_action"]), + headers: { "Api-Version": "1.0" }, + body: { "options":[{ "name": "ids", "value": $incident["resource_ids"] }] } + } + # If the action has parameters, add them to the request body + if type($action_options) == "array" && size($action_options) > 0 + $request["body"]["options"] = $request["body"]["options"] + $action_options + end + $response = http_request($request) + $$debug << to_json({ + "request": $request, + "response": $response + }) + # Get the action status from response header + $action_location = $response["headers"]["Location"] + + # Setup some variables for the wait loop + $action_status = "" + $loop_count = 0 + $loop_endtime = now() + (3600*2) # 2 hours from now + # [ queued, aborted, pending, running, completed, failed, denied ] + while ($action_status !~ /^(aborted|completed|failed|denied)/) && (now() <= $loop_endtime) do + # Using Loop Count to slowly increment the sleep time + # This is to prevent the loop from hammering our APIs + $loop_count = $loop_count + 1 + task_label("action_status=\""+$action_status+"\" Sleeping for "+to_s($loop_count)+" seconds") + sleep($loop_count) + task_label("action_status=\""+$action_status+"\" Getting action status") + $request = { + auth: $$auth_flexera, + verb: "get", + https: true, + host: $governance_host, + href: $action_location, + headers: { "Api-Version": "1.0" }, + query_strings: { "view": "extended" } + } + $response = http_request($request) + $$debug << to_json({ + "request": $request, + "response": $response + }) + $action_status = $response["body"]["status"] + end + if ($action_status != "completed") + # Check if we are out of time first + if (now() > $loop_endtime) + raise "action_status=\""+$action_status+"\" Action did not complete in time. Aborting to prevent endless loop. action_status_json="+to_json($response) + else + # If not, then it was aborted, failed or denied + raise "action_status=\""+$action_status+"\" Action did not complete as expected. action_status_json="+to_json($response) + end + end + # If we made it here, the action completed successfully + task_label("action_status=\""+$action_status+"\" Action completed successfully") + end + end +end +# End Shared Functions for Child Actions from Consolidated Incident + +# CWF function to handle errors +define handle_error() do + if !$$errors + $$errors = [] + end + $$errors << $_error["type"] + ": " + $_error["message"] + # We check for errors at the end, and raise them all together + # Skip errors handled by this definition + $_error_behavior = "skip" +end + +# Used only for emailing the combined child incident if so desired +escalation "esc_email_passed" do + automatic true + label "Send Email" + description "Send incident email" + email $param_combined_incident_email_passed +end + +escalation "esc_email_failed" do + automatic true + label "Send Email" + description "Send incident email" + email $param_combined_incident_email_failed +end + + +escalation "esc_email_unknown" do + automatic true + label "Send Email" + description "Send incident email" + email $param_combined_incident_email_unknown +end + +escalation "esc_email_child_policies" do + automatic true + label "Send Email" + description "Send incident email" + email $param_combined_incident_email_child +end + +escalation "create_policies" do + run "create_applied_policies", data, rs_governance_host, rs_project_id +end + +# if name !=null +define create_applied_policies($data, $governance_host, $rs_project_id) return $responses do + $responses = [] + $$debug = [] + $item_index = 0 + $item_total = size($data) + foreach $item in $data do + $item_index = $item_index + 1 + $status = to_s("("+$item_index+"/"+$item_total+")") + task_label($status+" Creating Applied Policy with Options: " + to_json($item["options"])) + $response = http_request( + auth: $$auth_flexera, + verb: "post", + https: true, + host: $governance_host, + href: join(["/api/governance/projects/", $rs_project_id, "/applied_policies"]), + headers: { "Api-Version": "1.0" }, + body: { + "name": $item["name"], + "description": $item["description"], + "template_href": $item["template_href"], + "frequency": $item["frequency"], + "options": $item["options"], + "credentials": $item["credentials"], + "meta_parent_policy_id": $item["meta_parent_policy_id"] + } + ) + $responses << $response + $$debug << to_json({ + "response": $response, + "item": $item, + "governance_host": $governance_host + }) + end +end + +escalation "update_policies" do + run "update_applied_policies", data, rs_governance_host, rs_project_id +end + +define update_applied_policies($data, $governance_host, $rs_project_id) return $responses do + $responses = [] + $$debug = [] + $item_index = 0 + $item_total = size($data) + foreach $item in $data do + $item_index = $item_index + 1 + $status = to_s("("+$item_index+"/"+$item_total+")") + task_label($status+" Updating Applied Policy with Options: " + to_json($item["options"])) + $response = http_request( + auth: $$auth_flexera, + verb: "patch", + https: true, + host: $governance_host, + href: join(["/api/governance/projects/", $rs_project_id, "/applied_policies/", $item["applied_policy_id"]]), + headers: { "Api-Version": "1.0" }, + body: { + "options": $item["options"] + } + ) + $responses << $response + $$debug << to_json({ + "response": $response, + "item": $item, + "governance_host": $governance_host + }) + end +end + +escalation "delete_policies" do + run "delete_applied_policies", data, rs_governance_host, rs_project_id +end + +define delete_applied_policies($data, $governance_host, $rs_project_id) return $responses do + $responses = [] + $$debug = [] + $item_index = 0 + $item_total = size($data) + foreach $item in $data do + $item_index = $item_index + 1 + $status = to_s("("+$item_index+"/"+$item_total+")") + task_label($status+" Deleting Applied Policy: " + $item["id"]) + $response = http_request( + auth: $$auth_flexera, + verb: "delete", + https: true, + host: $governance_host, + href: join(["/api/governance/projects/", $rs_project_id, "/applied_policies/", $item["id"]]), + headers: { "Api-Version": "1.0" } + ) + $responses << $response + $$debug << to_json({ + "response": $response, + "item": $item, + "governance_host": $governance_host + }) + end +end diff --git a/automation/aws/aws_s3_usage_type_rbd/CHANGELOG.md b/automation/aws/aws_s3_usage_type_rbd/CHANGELOG.md new file mode 100644 index 0000000000..5cbf9fec3b --- /dev/null +++ b/automation/aws/aws_s3_usage_type_rbd/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## v0.1.0 + +- initial release diff --git a/automation/aws/aws_s3_usage_type_rbd/README.md b/automation/aws/aws_s3_usage_type_rbd/README.md new file mode 100644 index 0000000000..6b580c386a --- /dev/null +++ b/automation/aws/aws_s3_usage_type_rbd/README.md @@ -0,0 +1,42 @@ +# AWS S3 Usage Type Rule-Based Dimension + +## What It Does + +This policy template creates and updates a custom Rule-Based Dimension for S3 usage types. This rule-based dimension will contain more general, human-readable usage types than the built-in `Usage Type` dimension that comes with the Flexera One platform. + +## How It Works + +- A full list of all `usage_type` dimension values for AWS S3 for the last 12 months is pulled from the Flexera CCO platform via the [Flexera Bill Analysis API](https://reference.rightscale.com/bill_analysis/#/costs/costs_aggregated) +- Each value is then analyzed to determine what value the new Rule-Based Dimension should have. For example, if the `usage_type` value contains the substring "-CloudFront", the value of the Rule-Based Dimension will be set to "CloudFront" +- A set of rules are generated based on the above and the new Rule-Based Dimension is created/updated via the [FinOps Customizations API](https://developer.flexera.com/docs/api/finops-customizations/v1) + +## Input Parameters + +This policy has the following input parameters required when launching the policy. + +- *Effective Date* - The month and year in YYYY-MM format that you want the rules to apply. This should be left at its default value in most cases to ensure that the rules apply to all costs, including historical costs. +- *Rule-Based Dimension ID* - The ID of the Rule-Based Dimension to create/update. ID must begin with `rbd_` and contain only lowercase letters, numbers, and underscores. *Note that, if a Rule-Based Dimension with the specified ID already exists, this policy template will overwrite its name and rules with the ones generated by this policy template.* +- *Rule-Based Dimension Name* -The Name of the Rule-Based Dimension to create/update. + +## Policy Actions + +- Create/update rule-based dimension + +## Prerequisites + +This Policy Template uses [Credentials](https://docs.flexera.com/flexera/EN/Automation/ManagingCredentialsExternal.htm) for authenticating to datasources -- in order to apply this policy you must have a Credential registered in the system that is compatible with this policy. If there are no Credentials listed when you apply the policy, please contact your Flexera Org Admin and ask them to register a Credential that is compatible with this policy. The information below should be consulted when creating the credential(s). + +- [**Flexera Credential**](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm) (*provider=flexera*) which has the following roles: + - `observer` + - `billing_center_viewer` + - `rule_based_dimensions_manager` + +The [Provider-Specific Credentials](https://docs.flexera.com/flexera/EN/Automation/ProviderCredentials.htm) page in the docs has detailed instructions for setting up Credentials for the most common providers. + +## Supported Clouds + +- AWS + +## Cost + +This policy template does not incur any cloud costs. diff --git a/automation/aws/aws_s3_usage_type_rbd/aws_s3_usage_type_rbd.pt b/automation/aws/aws_s3_usage_type_rbd/aws_s3_usage_type_rbd.pt new file mode 100644 index 0000000000..86e3639091 --- /dev/null +++ b/automation/aws/aws_s3_usage_type_rbd/aws_s3_usage_type_rbd.pt @@ -0,0 +1,398 @@ +name "AWS S3 Usage Type Rule-Based Dimension" +rs_pt_ver 20180301 +type "policy" +short_description "Creates and/or updates a single Rule-Based Dimension for S3 usage types. See the [README](https://github.com/flexera-public/policy_templates/tree/master/automation/aws/aws_s3_usage_type_rbd) and [docs.flexera.com/flexera/EN/Automation](https://docs.flexera.com/flexera/EN/Automation/AutomationGS.htm) to learn more." +long_description "" +severity "low" +category "Cost" +default_frequency "daily" +info( + version: "0.1.0", + provider: "Flexera", + service: "Cloud Cost Optimization", + policy_set: "Automation", + publish: "false" +) + +############################################################################### +# Parameters +############################################################################### + +parameter "param_effective_date" do + type "string" + category "Policy Settings" + label "Effective Date" + description "Year/month you want rules to start applying in YYYY-MM format" + allowed_pattern /^\d{4}-\d{2}$/ + default "2010-01" +end + +parameter "param_rbd_id" do + type "string" + category "Policy Settings" + label "Rule-Based Dimension ID" + description "The ID of the Rule-Based Dimension to create/update. ID must begin with 'rbd_' and contain only lowercase letters, numbers, and underscores." + allowed_pattern /^rbd_[a-z0-9_]+$/ + default "rbd_s3_usage_type" +end + +parameter "param_rbd_name" do + type "string" + category "Policy Settings" + label "Rule-Based Dimension Name" + description "The Name of the Rule-Based Dimension to create/update." + default "S3 Usage Type" +end + +############################################################################### +# Authentication +############################################################################### + +credentials "auth_flexera" do + schemes "oauth2" + label "flexera" + description "Select FlexeraOne OAuth2 credential." + tags "provider=flexera" +end + +############################################################################### +# Datasources & Scripts +############################################################################### + +# Get region-specific Flexera API endpoints +datasource "ds_flexera_api_hosts" do + run_script $js_flexera_api_hosts, rs_optima_host +end + +script "js_flexera_api_hosts", type: "javascript" do + parameters "rs_optima_host" + result "result" + code <<-EOS + host_table = { + "api.optima.flexeraeng.com": { + flexera: "api.flexera.com", + fsm: "api.fsm.flexeraeng.com" + }, + "api.optima-eu.flexeraeng.com": { + flexera: "api.flexera.eu", + fsm: "api.fsm-eu.flexeraeng.com" + }, + "api.optima-apac.flexeraeng.com": { + flexera: "api.flexera.au", + fsm: "api.fsm-apac.flexeraeng.com" + } + } + + result = host_table[rs_optima_host] +EOS +end + +datasource "ds_billing_centers" do + request do + auth $auth_flexera + host rs_optima_host + path join(["/analytics/orgs/", rs_org_id, "/billing_centers"]) + query "view", "allocation_table" + header "Api-Version", "1.0" + header "User-Agent", "RS Policies" + ignore_status [403] + end + result do + encoding "json" + collect jmes_path(response, "[*]") do + field "href", jmes_path(col_item, "href") + field "id", jmes_path(col_item, "id") + field "name", jmes_path(col_item, "name") + field "parent_id", jmes_path(col_item, "parent_id") + end + end +end + +# Gather top level billing center IDs for when we pull cost data +datasource "ds_top_level_bcs" do + run_script $js_top_level_bcs, $ds_billing_centers +end + +script "js_top_level_bcs", type: "javascript" do + parameters "ds_billing_centers" + result "result" + code <<-EOS + filtered_bcs = _.filter(ds_billing_centers, function(bc) { + return bc['parent_id'] == null || bc['parent_id'] == undefined + }) + + result = _.compact(_.pluck(filtered_bcs, 'id')) +EOS +end + +datasource "ds_flexera_s3_costs" do + request do + run_script $js_flexera_s3_costs, $ds_top_level_bcs, rs_org_id, rs_optima_host + end + result do + encoding "json" + collect jmes_path(response, "rows[*]") do + field "usage_type", jmes_path(col_item, "dimensions.usage_type") + end + end +end + +script "js_flexera_s3_costs", type:"javascript" do + parameters "ds_top_level_bcs", "rs_org_id", "rs_optima_host" + result "request" + code <<-EOS + year = Number(new Date().toISOString().substring(0, 4)) + month = Number(new Date().toISOString().substring(5, 7)) + month += 1 + if (month == 13) { year += 1; month = 1 } + if (month < 10) { month = '0' + month } + end_date = year.toString() + '-' + month.toString() + + past_year = year - 1 + start_date = past_year.toString() + '-' + month.toString() + + var request = { + auth: "auth_flexera", + host: rs_optima_host, + verb: "POST", + path: "/bill-analysis/orgs/" + rs_org_id + "/costs/aggregated", + body_fields: { + "dimensions": [ "usage_type" ], + "granularity": "month", + "start_at": start_date, + "end_at": end_date, + "metrics": [ "cost_amortized_unblended_adj" ], + "billing_center_ids": ds_top_level_bcs, + "limit": 100000, + "filter": { dimension: "service", type: "equal", value: "AmazonS3" } + }, + headers: { + "User-Agent": "RS Policies", + "Api-Version": "1.0" + }, + ignore_status: [400] + } +EOS +end + +datasource "ds_s3_usage_types" do + run_script $js_s3_usage_types, $ds_flexera_s3_costs +end + +script "js_s3_usage_types", type: "javascript" do + parameters "ds_flexera_s3_costs" + result "result" + code <<-EOS + // Function to check for presence of substring in a string in a case-insensitive way + function strContains(string, value) { return string.toLowerCase().indexOf(value.toLowerCase()) != -1 } + + // Grab the fill list of usage types with invalid or duplicate values removed + usage_type_list = _.uniq(_.compact(_.pluck(ds_flexera_s3_costs, "usage_type"))) + + // Determine the RBD value based on the presence of substrings in the usage type + usage_type_map = _.map(usage_type_list, function(usage_type) { + value = null + + if (strContains(usage_type, "STANDARD")) { value = "Standard" } + if (strContains(usage_type, "TimedStorage-ByteHrs")) { value = "Standard" } + if (strContains(usage_type, "Select-Scanned-Bytes")) { value = "Standard" } + if (strContains(usage_type, "Select-Returned-Bytes")) { value = "Standard" } + + if (strContains(usage_type, "BatchOperations")) { value = "Batch Operations" } + if (strContains(usage_type, "Bulk-Retrieval")) { value = "Bulk Retrieval" } + if (strContains(usage_type, "CloudFront")) { value = "CloudFront" } + if (strContains(usage_type, "S3DSSE")) { value = "Dual Encrypted" } + if (strContains(usage_type, "C3DataTransfer")) { value = "EC2 DataTransfer" } + if (strContains(usage_type, "Expedited")) { value = "Expedited" } + if (strContains(usage_type, "-XZ") || strContains(usage_type, "XZ-")) { value = "Express One Zone" } + if (strContains(usage_type, "GLACIER")) { value = "Glacier" } + if (strContains(usage_type, "-GDA") || strContains(usage_type, "GDA-")) { value = "Glacier Deep Archive" } + if (strContains(usage_type, "EarlyDelete-ByteHrs")) { value = "Glacier Flexible Retrieval" } + if (strContains(usage_type, "-GIR") || strContains(usage_type, "GIR-")) { value = "Glacier Instance Retrieval" } + if (strContains(usage_type, "Inventory")) { value = "Inventory" } + if (strContains(usage_type, "-MRAP") || strContains(usage_type, "MRAP-")) { value = "Multi Region Access Point" } + if (strContains(usage_type, "-ZIA") || strContains(usage_type, "ZIA-")) { value = "One Zone Infrequent Access" } + if (strContains(usage_type, "-RRS") || strContains(usage_type, "RRS-")) { value = "Reduced Redundancy Storage" } + if (strContains(usage_type, "-S3RTC") || strContains(usage_type, "S3RTC-")) { value = "Replication Time Control" } + if (strContains(usage_type, "-SIA") || strContains(usage_type, "SIA-")) { value = "Standard Infrequent Access" } + if (strContains(usage_type, "StorageAnalytics")) { value = "Storage Analytics" } + if (strContains(usage_type, "StorageObjectCount")) { value = "Storage Object Count" } + if (strContains(usage_type, "TagStorage")) { value = "Tag Storage" } + + if (strContains(usage_type, "-INT") || strContains(usage_type, "INT-")) { + if (strContains(usage_type, "INT-FA")) { + value = "Intelligent Tiering Storage Frequent Access" + } else if (strContains(usage_type, "INT-IA")) { + value = "Intelligent Tiering Storage Infrequent Access" + } else if (strContains(usage_type, "INT-AA")) { + value = "Intelligent Tier Storage Archive Access" + } else if (strContains(usage_type, "INT-AIA")) { + value = "Intelligent Tier Storage Archive Infrequent Access" + } else if (strContains(usage_type, "INT-DAA")) { + value = "Intelligent Tier Storage Deep Archive Access" + } else { + value = "Intelligent Tiering Storage" + } + } + + if (strContains(usage_type, "Requests")) { + if (strContains(usage_type, "-GDA") || strContains(usage_type, "GDA-")) { + value = "Glacier Deep Archive Requests" + } else if (strContains(usage_type, "-XZ") || strContains(usage_type, "XZ-")) { + value = "Express One Zone Requests" + } else { + value = "Requests" + } + } + + if (strContains(usage_type, "DataTransfer")) { + if (strContains(usage_type, "DataTransfer-Regional")) { + value = "Regional Data Transfer" + } else if (strContains(usage_type, "S3G-DataTransfer")) { + value = "S3G Data Transfer" + } else { + value = "Internet Data Transfer" + } + } + + if (strContains(usage_type, "StorageLens")) { + if (strContains(usage_type, "StorageLensFreeTier")) { + value = "Storage Lens" + } else { + value = "Storage Lens Free Tier" + } + } + + if (value == null) { + if (strContains(usage_type, "-AWS-In") || strContains(usage_type, "AWS-In-")) { value = "Regions Data Transferred" } + if (strContains(usage_type, "-AWS-Out") || strContains(usage_type, "AWS-Out-")) { value = "Regions Data Transferred" } + } + + return { + usage_type: usage_type, + value: value + } + }) + + // Filter out any usage types where we did not find a valid value to assign + result = _.filter(usage_type_map, function(item) { return item["value"] }) +EOS +end + +datasource "ds_existing_rbds" do + request do + auth $auth_flexera + host rs_optima_host + path join(["/bill-analysis/orgs/", rs_org_id, "/settings/rule_based_dimensions"]) + header "Api-Version", "1.0" + header "content-type", "application/json" + end + result do + encoding "json" + collect jmes_path(response, "rule_based_dimensions") do + field "id", jmes_path(col_item, "id") + field "name", jmes_path(col_item, "name") + field "dated_rules", jmes_path(col_item, "dated_rules") + end + end +end + +datasource "ds_rbds" do + run_script $js_rbds, $ds_s3_usage_types, $ds_existing_rbds, $param_rbd_id, $param_rbd_name, $param_effective_date +end + +script "js_rbds", type: "javascript" do + parameters "ds_s3_usage_types", "ds_existing_rbds", "param_rbd_id", "param_rbd_name", "param_effective_date" + result "result" + code <<-'EOS' + verb = "POST" + if (_.contains(_.pluck(ds_existing_rbds, 'id'), param_rbd_id)) { verb = "PATCH" } + + rules = _.map(ds_s3_usage_types, function(item) { + return { + condition: { + type: "and", + expressions: [ + { type: "dimension_equals", dimension: "service", value: "AmazonS3" }, + { type: "dimension_equals", dimension: "usage_type", value: item["usage_type"] } + ] + }, + value: { text: item["value"] } + } + }) + + rules.push({ + condition: { type: "dimension_equals", dimension: "service", value: "AmazonS3GlacierDeepArchive" }, + value: { text: "Glacier Deep Archive" } + }) + + result = [{ + id: param_rbd_id, + name: param_rbd_name, + verb: verb, + effective_at: param_effective_date, + rules: rules + }] +EOS +end + +datasource "ds_create_rbds" do + iterate $ds_rbds + request do + run_script $js_create_rbds, val(iter_item, "id"), val(iter_item, "verb"), val(iter_item, "name"), val($ds_flexera_api_hosts, "flexera"), rs_org_id + end + result do + encoding "text" + end +end + +script "js_create_rbds", type: "javascript" do + parameters "rbd_id", "verb", "name", "api_host", "rs_org_id" + result "request" + code <<-EOS + var request = { + auth: "auth_flexera", + verb: verb, + host: api_host, + path: ["/finops-customizations/v1/orgs/", rs_org_id, "/rule-based-dimensions/", rbd_id].join(''), + body_fields: { name: name } + } +EOS +end + +datasource "ds_apply_rbds" do + iterate $ds_rbds + request do + # ds_create_rbds is a parameter to ensure that it executes before ds_apply_rbds does + run_script $js_apply_rbds, val(iter_item, "id"), val(iter_item, "effective_at"), val(iter_item, "rules"), val($ds_flexera_api_hosts, "flexera"), $ds_create_rbds, rs_org_id + end + result do + encoding "text" + end +end + +script "js_apply_rbds", type: "javascript" do + parameters "rbd_id", "effective_at", "rules", "api_host", "ds_create_rbds", "rs_org_id" + result "request" + code <<-EOS + var request = { + auth: "auth_flexera", + verb: "PUT", + host: api_host, + path: ["/finops-customizations/v1/orgs/", rs_org_id, "/rule-based-dimensions/", rbd_id, "/rules/", effective_at].join(''), + body_fields: { rules: rules } + } +EOS +end + +############################################################################### +# Policy +############################################################################### + +policy "pol_s3_rbd" do + validate $ds_apply_rbds do + summary_template "AWS S3 Usage Type RBD Generated & Applied" + detail_template "" + check eq(0, 0) + end +end diff --git a/cost/azure/rightsize_managed_sql_storage/CHANGELOG.md b/cost/azure/rightsize_managed_sql_storage/CHANGELOG.md index 341687ee97..e43bc6b275 100644 --- a/cost/azure/rightsize_managed_sql_storage/CHANGELOG.md +++ b/cost/azure/rightsize_managed_sql_storage/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v0.2.0 + +- List prices used to calculate savings are now specific to SQL Managed Instances and should be more accurate + ## v0.1.0 - Initial Release diff --git a/cost/azure/rightsize_managed_sql_storage/azure_rightsize_managed_sql_storage.pt b/cost/azure/rightsize_managed_sql_storage/azure_rightsize_managed_sql_storage.pt index 0786e70ef7..c3cfd388d1 100644 --- a/cost/azure/rightsize_managed_sql_storage/azure_rightsize_managed_sql_storage.pt +++ b/cost/azure/rightsize_managed_sql_storage/azure_rightsize_managed_sql_storage.pt @@ -7,7 +7,7 @@ category "Cost" severity "low" default_frequency "weekly" info( - version: "0.1.0", + version: "0.2.0", provider: "Azure", service: "SQL", policy_set: "Rightsize Database Instances", @@ -591,21 +591,21 @@ script "js_oversized_azure_sql_instances", type: "javascript" do EOS end -datasource "ds_azure_db_storage_cost_map" do +datasource "ds_azure_sqlmi_storage_cost_map" do request do verb "GET" host "raw.githubusercontent.com" - path "/flexera-public/policy_templates/master/data/azure/azure_db_storage_pricing.json" + path "/flexera-public/policy_templates/master/data/azure/azure_sqlmi_storage_pricing.json" header "User-Agent", "RS Policies" end end datasource "ds_azure_sql_instances_incident" do - run_script $js_azure_sql_instances_incident, $ds_oversized_azure_sql_instances, $ds_azure_db_storage_cost_map, $ds_currency, $ds_applied_policy, $param_recommendation_threshold, $param_min_savings + run_script $js_azure_sql_instances_incident, $ds_oversized_azure_sql_instances, $ds_azure_sqlmi_storage_cost_map, $ds_currency, $ds_applied_policy, $param_recommendation_threshold, $param_min_savings end script "js_azure_sql_instances_incident", type: "javascript" do - parameters "ds_oversized_azure_sql_instances", "ds_azure_db_storage_cost_map", "ds_currency", "ds_applied_policy", "param_recommendation_threshold", "param_min_savings" + parameters "ds_oversized_azure_sql_instances", "ds_azure_sqlmi_storage_cost_map", "ds_currency", "ds_applied_policy", "param_recommendation_threshold", "param_min_savings" result "result" code <<-'EOS' // Used for formatting numbers to look pretty @@ -630,7 +630,7 @@ script "js_azure_sql_instances_incident", type: "javascript" do total_savings = 0.0 _.each(ds_oversized_azure_sql_instances, function(db) { - cost = ds_azure_db_storage_cost_map[db["region"]][db["sku"]["tier"]]["unitPrice"] + cost = ds_azure_sqlmi_storage_cost_map[db["region"]][db["sku"]["tier"]]["unitPrice"] savings = ((db["storageSizeInGB"] * cost) - (db["newSizeGB"] * cost)) * ds_currency["exchange_rate"] if (savings >= param_min_savings) { diff --git a/cost/azure/rightsize_managed_sql_storage/azure_rightsize_managed_sql_storage_meta_parent.pt b/cost/azure/rightsize_managed_sql_storage/azure_rightsize_managed_sql_storage_meta_parent.pt index 5aaafc791d..2b1489c9be 100644 --- a/cost/azure/rightsize_managed_sql_storage/azure_rightsize_managed_sql_storage_meta_parent.pt +++ b/cost/azure/rightsize_managed_sql_storage/azure_rightsize_managed_sql_storage_meta_parent.pt @@ -7,7 +7,7 @@ category "Meta" default_frequency "15 minutes" info( provider: "Azure", - version: "0.1.0", # This version of the Meta Parent Policy Template should match the version of the Child Policy Template as it appears in the Catalog for best reliability + version: "0.2.0", # This version of the Meta Parent Policy Template should match the version of the Child Policy Template as it appears in the Catalog for best reliability publish: "true", deprecated: "false" ) diff --git a/cost/flexera/cco/currency_conversion/CHANGELOG.md b/cost/flexera/cco/currency_conversion/CHANGELOG.md index 90b451beb2..bf6018ff60 100644 --- a/cost/flexera/cco/currency_conversion/CHANGELOG.md +++ b/cost/flexera/cco/currency_conversion/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v5.0.0 + +- Multiple dimension/value pairs can now be used when applying currency conversion + ## v4.0.0 - Policy now accepts any arbitrary cost dimension/value instead of requiring that currency conversion be done for a specific cloud provider diff --git a/cost/flexera/cco/currency_conversion/README.md b/cost/flexera/cco/currency_conversion/README.md index c55578b6e1..33abc61781 100644 --- a/cost/flexera/cco/currency_conversion/README.md +++ b/cost/flexera/cco/currency_conversion/README.md @@ -2,7 +2,7 @@ ## What It Does -This policy template creates adjustment rules that convert the currency of the costs associated with the cost dimension of choice. It utilizes xe.com to retrieve the latest exchange rates. +This policy template creates adjustment rules that convert the currency of the costs associated with the cost dimensions of choice. It utilizes xe.com to retrieve the latest exchange rates. ## How It Works @@ -20,7 +20,8 @@ This policy has the following input parameters required when launching the polic - *Backfill Adjustments* - Whether to add/modify currency conversion to just the current month or to backfill previous months. - *Backfill Start Date* - The month and year in YYYY-MM format to backfill adjustments to. Only applicable if `Backfill Previous Months` is selected for the `Backfill Adjustments` parameter. - *Backfill Exchange Rates* - Whether or not to use the current exchange rate, or the exchange rate at the time, when applying currency conversion to previous months. Only applicable if `Backfill Previous Months` is selected for the `Backfill Adjustments` parameter. -- *Dimension* - The Flexera CCO cost dimension name/id and value to apply the currency conversion to in 'Dimension=Value' format. Example: Cloud Vendor=AWS +- *Dimensions* - The Flexera CCO cost dimension names/ids and values to apply the currency conversion to in 'Dimension=Value' format. Example: Cloud Vendor=AWS +- *Dimensions Boolean* - Whether to apply the currency conversion to costs that match any of the criteria in the `Dimensions` parameter or only those that match all of them. Only applicable if more than one value is specified for the `Dimensions` parameter. - *Currency From* - Currency you want to convert from (based on ISO 4217 codes - e.g., 'USD' for US Dollar) - *Currency To* - Currency you want to convert to (based on ISO 4217 codes - e.g., 'EUR' for Euro) - *Set Organization Currency* - Whether or not to configure the Flexera CCO user interface to present costs in the currency specified in the `Currency To` parameter. If set to `Yes`, this will be done, and all costs in Flexera CCO for this organization will be presented in the currency costs are converted to. diff --git a/cost/flexera/cco/currency_conversion/currency_conversion.pt b/cost/flexera/cco/currency_conversion/currency_conversion.pt index b75dc6b508..8bddd3fa02 100644 --- a/cost/flexera/cco/currency_conversion/currency_conversion.pt +++ b/cost/flexera/cco/currency_conversion/currency_conversion.pt @@ -7,7 +7,7 @@ severity "low" default_frequency "monthly" category "Cost" info( - version: "4.0.0", + version: "5.0.0", provider: "Flexera", service: "Cloud Cost Optimization", policy_set: "Cloud Cost Optimization" @@ -17,16 +17,25 @@ info( # Parameters ############################################################################### -parameter "param_dimension" do - type "string" +parameter "param_dimensions" do + type "list" category "Policy Settings" - label "Dimension" - description "The Flexera CCO cost dimension name/id and value to apply the currency conversion to in 'Dimension=Value' format. Example: Cloud Vendor=AWS" + label "Dimensions" + description "The Flexera CCO cost dimension names/ids and values to apply the currency conversion to in 'Dimension=Value' format. Example: Cloud Vendor=AWS" allowed_pattern /.+=.+/ min_length 1 # No default value, user input required end +parameter "param_dimensions_boolean" do + type "string" + category "Policy Settings" + label "Dimensions Boolean" + description "Whether to apply the currency conversion to costs that match any of the criteria in the 'Dimensions' parameter or only those that match all of them. Only applicable if more than one value is specified for the 'Dimensions' parameter." + allowed_values "Any", "All" + default "All" +end + parameter "param_backfill" do type "string" category "Policy Settings" @@ -112,31 +121,35 @@ datasource "ds_dimensions" do end end -datasource "ds_dimension" do - run_script $js_dimension, $ds_dimensions, $param_dimension +datasource "ds_filter_dimensions" do + run_script $js_filter_dimensions, $ds_dimensions, $param_dimensions end -script "js_dimension", type: "javascript" do - parameters "ds_dimensions", "param_dimension" +script "js_filter_dimensions", type: "javascript" do + parameters "ds_dimensions", "param_dimensions" result "result" code <<-'EOS' - result = {} + result = _.map(param_dimensions, function(item) { + key = item.split('=')[0] + value = item.split('=')[1] - key = param_dimension.split('=')[0] - value = param_dimension.split('=')[1] + dimension = _.find(ds_dimensions, function(dimension) { + return dimension['id'] == key || dimension['name'] == key + }) - dimension = _.find(ds_dimensions, function(dimension) { - return dimension['id'] == key || dimension['name'] == key + if (dimension) { + return { + id: dimension['id'], + name: dimension['name'], + type: dimension['type'], + value: value + } + } else { + return null + } }) - if (dimension) { - result = { - id: dimension['id'], - name: dimension['name'], - type: dimension['type'], - value: value - } - } + result = _.compact(result) EOS end @@ -302,11 +315,11 @@ datasource "ds_current_adjustments" do end datasource "ds_updated_adjustments" do - run_script $js_updated_adjustments, $ds_exchange_rates, $ds_current_adjustments, $ds_month_list, $ds_dimension, $param_currency_from, $param_currency_to, $param_backfill_exchange_rate, $param_backfill, $param_backfill_start_date + run_script $js_updated_adjustments, $ds_exchange_rates, $ds_current_adjustments, $ds_month_list, $ds_filter_dimensions, $param_currency_from, $param_currency_to, $param_backfill_exchange_rate, $param_backfill, $param_backfill_start_date, $param_dimensions_boolean end script "js_updated_adjustments", type: "javascript" do - parameters "ds_exchange_rates", "ds_current_adjustments", "ds_month_list", "ds_dimension", "param_currency_from", "param_currency_to", "param_backfill_exchange_rate", "param_backfill", "param_backfill_start_date" + parameters "ds_exchange_rates", "ds_current_adjustments", "ds_month_list", "ds_filter_dimensions", "param_currency_from", "param_currency_to", "param_backfill_exchange_rate", "param_backfill", "param_backfill_start_date", "param_dimensions_boolean" result "result" code <<-'EOS' // Get most recent exchange rate @@ -325,7 +338,14 @@ script "js_updated_adjustments", type: "javascript" do }) // Dimension details - pretty_dimension = ds_dimension['name'] + '=' + ds_dimension['value'] + if (ds_filter_dimensions.length > 1) { + pretty_dimension = param_dimensions_boolean + ": " + _.map(ds_filter_dimensions, function(item) { + return item['name'] + '=' + item['value'] + }).join(" | ") + } else { + pretty_dimension = ds_filter_dimensions[0]['name'] + '=' + ds_filter_dimensions[0]['value'] + } + new_adj_name = "Currency Conversion - " + pretty_dimension // Rule information stored for incident @@ -341,11 +361,33 @@ script "js_updated_adjustments", type: "javascript" do } // Create the currency conversion rule + if (ds_filter_dimensions.length > 1) { + boolean_type = "or" + if (param_dimensions_boolean == "All") { boolean_type = "and" } + + condition = { + type: boolean_type, + expressions: _.map(ds_filter_dimensions, function(item) { + return { + type: "dimension_equals", + dimension: item['id'], + value: item['value'] + } + }) + } + } else { + condition = { + type: "dimension_equals", + dimension: ds_filter_dimensions[0]['id'], + value: ds_filter_dimensions[0]['value'] + } + } + currency_conversion_rule = { name: new_adj_name, rules: [ { - condition: { type: "dimension_equals", dimension: ds_dimension['id'], value: ds_dimension['value'] }, + condition: condition, cost_multiplier: conversion_rate - 1, label: param_currency_from + " to " + param_currency_to } @@ -402,24 +444,25 @@ script "js_updated_adjustments", type: "javascript" do result = { list: { dated_adjustment_lists: new_adjustments }, - message: message + message_rules.join("\n") + message: message + message_rules.join("\n"), + dimension: pretty_dimension } EOS end # Include ds_set_org_currency to ensure it executes, not because it's used by this script datasource "ds_updated_adjustments_payload" do - run_script $js_updated_adjustments_payload, $ds_updated_adjustments, $ds_set_org_currency, $ds_dimension + run_script $js_updated_adjustments_payload, $ds_updated_adjustments, $ds_set_org_currency end script "js_updated_adjustments_payload", type: "javascript" do - parameters "ds_updated_adjustments", "ds_set_org_currency", "ds_dimension" + parameters "ds_updated_adjustments", "ds_set_org_currency" result "result" code <<-'EOS' result = [{ list: JSON.stringify(ds_updated_adjustments['list']), message: ds_updated_adjustments['message'], - dimension: ds_dimension['name'] + '=' + ds_dimension['value'] + dimension: ds_updated_adjustments['dimension'] }] EOS end @@ -449,7 +492,7 @@ end policy "pol_currency_conversion" do validate_each $ds_new_adjustments do - summary_template "Currency Conversion - {{ with index data 0 }}{{ .dimension }}{{ end }} - {{ parameters.param_currency_from }} to {{ parameters.param_currency_to }}" + summary_template "Currency Conversion - {{ parameters.param_currency_from }} to {{ parameters.param_currency_to }} - {{ with index data 0 }}{{ .dimension }}{{ end }}" detail_template "{{ with index data 0 }}{{ .message }}{{ end }}" check eq(0, 1) end diff --git a/data/active_policy_list/active_policy_list.json b/data/active_policy_list/active_policy_list.json index 7db76c6a43..d0713537fe 100644 --- a/data/active_policy_list/active_policy_list.json +++ b/data/active_policy_list/active_policy_list.json @@ -2502,7 +2502,7 @@ { "name": "Azure Rightsize SQL Managed Instance Storage", "file_name": "cost/azure/rightsize_managed_sql_storage/azure_rightsize_managed_sql_storage.pt", - "version": "0.1.0", + "version": "0.2.0", "change_log": "cost/azure/rightsize_managed_sql_storage/CHANGELOG.md", "description": "Reports on SQL Managed instances that have high maximum storage space relative to their storage usage. See the [README](https://github.com/flexera-public/policy_templates/tree/master/cost/azure/rightsize_managed_sql_storage/) and [docs.flexera.com/flexera/EN/Automation](https://docs.flexera.com/flexera/EN/Automation/AutomationGS.htm) to learn more.", "category": "Cost", @@ -2512,7 +2512,7 @@ "service": "SQL", "policy_set": "Rightsize Database Instances", "recommendation_type": "Usage Reduction", - "updated_at": "2024-10-01T12:29:26Z", + "updated_at": "2024-10-11T17:53:41Z", "generally_recommended": false, "deprecated": false }, @@ -3488,7 +3488,7 @@ { "name": "Currency Conversion", "file_name": "cost/flexera/cco/currency_conversion/currency_conversion.pt", - "version": "4.0.0", + "version": "5.0.0", "change_log": "cost/flexera/cco/currency_conversion/CHANGELOG.md", "description": "A policy that creates an adjustment rule that converts the currency of the cost of the Cloud Vendor of choice. It utilizes xe.com to retrieve the latest exchange rates. See the [README](https://github.com/flexera-public/policy_templates/tree/master/cost/flexera/cco/currency_conversion/) and [docs.flexera.com/flexera/EN/Automation](https://docs.flexera.com/flexera/EN/Automation/AutomationGS.htm) to learn more.", "category": "Cost", @@ -3498,7 +3498,7 @@ "service": "Cloud Cost Optimization", "policy_set": "Cloud Cost Optimization", "recommendation_type": null, - "updated_at": "2024-09-26T19:43:53Z", + "updated_at": "2024-10-11T13:18:16Z", "generally_recommended": false, "deprecated": false }, @@ -3879,7 +3879,7 @@ { "name": "Google Label Cardinality Report", "file_name": "operational/google/label_cardinality/google_label_cardinality.pt", - "version": "0.1.0", + "version": "0.1.1", "change_log": "operational/google/label_cardinality/CHANGELOG.md", "description": "Generates a label cardinality report for Google Projects and Resources. See the [README](https://github.com/flexera-public/policy_templates/tree/master/operational/google/label_cardinality) and [docs.flexera.com/flexera/EN/Automation](https://docs.flexera.com/flexera/EN/Automation/AutomationGS.htm) to learn more.", "category": "Operational", @@ -3889,7 +3889,7 @@ "service": "Tags", "policy_set": "Tag Cardinality", "recommendation_type": null, - "updated_at": "2024-08-16T20:22:13Z", + "updated_at": "2024-10-11T17:53:29Z", "generally_recommended": false, "deprecated": false }, @@ -5783,7 +5783,7 @@ { "name": "Meta Parent: Azure Rightsize SQL Managed Instance Storage", "file_name": "cost/azure/rightsize_managed_sql_storage/azure_rightsize_managed_sql_storage_meta_parent.pt", - "version": "0.1.0", + "version": "0.2.0", "change_log": "cost/azure/rightsize_managed_sql_storage/CHANGELOG.md", "description": "**NOTE: Meta policies are an alpha feature. Please consult the [README](https://github.com/flexera-public/policy_templates/blob/master/README_META_POLICIES.md) before use.** Applies and manages \"child\" [Azure Rightsize SQL Managed Instance Storage](https://github.com/flexera-public/policy_templates/tree/master/cost/azure/rightsize_managed_sql_storage) Policies.", "category": "Meta", @@ -5793,7 +5793,7 @@ "service": null, "policy_set": null, "recommendation_type": null, - "updated_at": "2024-10-01T12:29:26Z", + "updated_at": "2024-10-11T17:53:41Z", "generally_recommended": false, "deprecated": false }, @@ -6514,7 +6514,7 @@ { "name": "Meta Parent: Google Label Cardinality Report", "file_name": "operational/google/label_cardinality/google_label_cardinality_meta_parent.pt", - "version": "0.1.0", + "version": "0.1.1", "change_log": "operational/google/label_cardinality/CHANGELOG.md", "description": "**NOTE: Meta policies are an alpha feature. Please consult the [README](https://github.com/flexera-public/policy_templates/blob/master/README_META_POLICIES.md) before use.** Applies and manages \"child\" [Google Label Cardinality Report](https://github.com/flexera-public/policy_templates/tree/master/operational/google/label_cardinality) Policies.", "category": "Meta", @@ -6524,7 +6524,7 @@ "service": null, "policy_set": null, "recommendation_type": null, - "updated_at": "2024-09-03T18:11:14Z", + "updated_at": "2024-10-11T17:53:29Z", "generally_recommended": false, "deprecated": false }, diff --git a/data/aws/aws_ec2_pricing.json b/data/aws/aws_ec2_pricing.json index 539506cd96..4954b96794 100644 --- a/data/aws/aws_ec2_pricing.json +++ b/data/aws/aws_ec2_pricing.json @@ -92816,6 +92816,162 @@ "sku": "3GTF3U9P5BHXCCS2" } }, + "d3en.12xlarge": { + "Linux": { + "pricePerUnit": 8.69827, + "sku": "EG3XP94SHF3TFUTW" + }, + "RHEL": { + "pricePerUnit": 9.21667, + "sku": "TEUXZ6H5Q799M7J4" + }, + "Red Hat Enterprise Linux with HA": { + "pricePerUnit": 9.88867, + "sku": "67X7WYVG7755TUC5" + }, + "SUSE": { + "pricePerUnit": 8.82327, + "sku": "UQDDRD3JMWF3ZCCX" + }, + "Ubuntu Pro": { + "pricePerUnit": 8.78227, + "sku": "BUZKB4EBD2M9FXT2" + }, + "Windows": { + "pricePerUnit": 7.90752, + "sku": "WR7XU2VAJSF4VYKK" + } + }, + "d3en.2xlarge": { + "Linux": { + "pricePerUnit": 1.318, + "sku": "SMK8ENUT9QWF74C8" + }, + "RHEL": { + "pricePerUnit": 1.433, + "sku": "4HETJFSQS76H9N9Q" + }, + "Red Hat Enterprise Linux with HA": { + "pricePerUnit": 1.573, + "sku": "6GEEWBMUN2WGCMCM" + }, + "SUSE": { + "pricePerUnit": 1.443, + "sku": "RUHHHT9Q6CKX5JKZ" + }, + "Ubuntu Pro": { + "pricePerUnit": 1.332, + "sku": "29ZBSXFKPNKG5VC5" + }, + "Windows": { + "pricePerUnit": 1.45, + "sku": "UXBVQW7727WCVTAA" + } + }, + "d3en.4xlarge": { + "Linux": { + "pricePerUnit": 2.899, + "sku": "3QE6QQPM6WCFJE8R" + }, + "RHEL": { + "pricePerUnit": 2.809, + "sku": "HDV6FKB7T7JADEMV" + }, + "Red Hat Enterprise Linux with HA": { + "pricePerUnit": 3.033, + "sku": "ADNAZS7SWV253QPC" + }, + "SUSE": { + "pricePerUnit": 2.761, + "sku": "3RPTBT72UUBF7GEV" + }, + "Ubuntu Pro": { + "pricePerUnit": 2.927, + "sku": "6G3WR9QVKTA2NFT3" + }, + "Windows": { + "pricePerUnit": 2.899, + "sku": "5DJPT2MAMYCWN3CU" + } + }, + "d3en.6xlarge": { + "Linux": { + "pricePerUnit": 3.954, + "sku": "A3ZF4VF7FEKUY483" + }, + "RHEL": { + "pricePerUnit": 4.213, + "sku": "NUUGQBZAY7EQRZ36" + }, + "Red Hat Enterprise Linux with HA": { + "pricePerUnit": 4.549, + "sku": "T5WCXN88MMZU6DS3" + }, + "SUSE": { + "pricePerUnit": 4.079, + "sku": "G5N6V9TNXKS8YA96" + }, + "Ubuntu Pro": { + "pricePerUnit": 3.996, + "sku": "KMZRFMS8QGVJCC5S" + }, + "Windows": { + "pricePerUnit": 3.954, + "sku": "Y4X2B8XS4T6NQ37V" + } + }, + "d3en.8xlarge": { + "Linux": { + "pricePerUnit": 5.79885, + "sku": "YV6EU3EDUEZSPSJ4" + }, + "RHEL": { + "pricePerUnit": 5.61728, + "sku": "YR5NT5NR4J627DS3" + }, + "Red Hat Enterprise Linux with HA": { + "pricePerUnit": 6.06528, + "sku": "RNK55AR4VARF34T7" + }, + "SUSE": { + "pricePerUnit": 5.39668, + "sku": "9HJMK8UN5A9XZRCZ" + }, + "Ubuntu Pro": { + "pricePerUnit": 5.32768, + "sku": "C7NCEWN3CK7WNFJU" + }, + "Windows": { + "pricePerUnit": 5.27168, + "sku": "7EE45NQ92S23PRWV" + } + }, + "d3en.xlarge": { + "Linux": { + "pricePerUnit": 0.725, + "sku": "VJ4XS68NY3Q9SBAR" + }, + "RHEL": { + "pricePerUnit": 0.717, + "sku": "2JCHAAQJCNH5DCUY" + }, + "Red Hat Enterprise Linux with HA": { + "pricePerUnit": 0.852, + "sku": "BF9XGXBUVHNUGUWM" + }, + "SUSE": { + "pricePerUnit": 0.715, + "sku": "S4GQMZWANZ6YSNHC" + }, + "Ubuntu Pro": { + "pricePerUnit": 0.666, + "sku": "NUGV7EDH72CWC8G3" + }, + "Windows": { + "pricePerUnit": 0.725, + "sku": "KK8WMNJ8C7DJ8WX6" + } + }, "f1.16xlarge": { "Linux": { "pricePerUnit": 15.848, diff --git a/data/aws/aws_rds_pricing.json b/data/aws/aws_rds_pricing.json index e0b8f11a1c..3fb09d469d 100644 --- a/data/aws/aws_rds_pricing.json +++ b/data/aws/aws_rds_pricing.json @@ -13196,7 +13196,7 @@ }, "Single-AZ": { "pricePerUnit": 0.235, - "sku": "CDRQ8ZC29GR7K2FQ" + "sku": "U76N7B48QZSP5R4A" } }, "PostgreSQL": { @@ -13258,7 +13258,7 @@ }, "Single-AZ": { "pricePerUnit": 0.47, - "sku": "9HFBTED95TY3GDSH" + "sku": "MGGTK4DQH2E3N73G" } }, "PostgreSQL": { @@ -16356,7 +16356,7 @@ }, "Single-AZ": { "pricePerUnit": 1.34, - "sku": "DKS44J9KH5N5C66S" + "sku": "9GP4H3PW5HY9RHYN" } }, "PostgreSQL": { @@ -16672,7 +16672,7 @@ }, "Single-AZ": { "pricePerUnit": 0.67, - "sku": "2NEZA3N5H3YUSBDG" + "sku": "W2JXABNY5CMRC69S" } }, "PostgreSQL": { @@ -18280,7 +18280,7 @@ }, "Single-AZ": { "pricePerUnit": 2.216, - "sku": "KFWVJSSS2WCQZNU7" + "sku": "9PZKH5AZQQ5X9WBP" } }, "PostgreSQL": { @@ -20484,7 +20484,7 @@ }, "Single-AZ": { "pricePerUnit": 0.832, - "sku": "SP2SJ2C59GDNMZMZ" + "sku": "G8PFZTD3HENGHSKA" } }, "PostgreSQL": { @@ -20558,7 +20558,7 @@ }, "Single-AZ": { "pricePerUnit": 0.208, - "sku": "V4Y48GCR94MSK2DP" + "sku": "J5BHABRRS4M5QUZH" } }, "PostgreSQL": { @@ -20788,7 +20788,7 @@ }, "Single-AZ": { "pricePerUnit": 0.416, - "sku": "GU26C93GFVVBMVHG" + "sku": "W6X43DCREN5Z87PX" } }, "PostgreSQL": { @@ -21484,7 +21484,7 @@ }, "Single-AZ": { "pricePerUnit": 4.401, - "sku": "ZU4GNC2KAADDCPU7" + "sku": "8NBR784T36H5CB4X" } } }, @@ -23616,7 +23616,7 @@ }, "Single-AZ": { "pricePerUnit": 5.664, - "sku": "AJHX2JMNV7NTEXDV" + "sku": "AWWEUM28CAY67WR5" } }, "PostgreSQL": { @@ -23988,7 +23988,7 @@ }, "Single-AZ": { "pricePerUnit": 3.776, - "sku": "NQ8HNMPKNGAU9NR5" + "sku": "W7HE8GGVYER3QTJT" } }, "PostgreSQL": { @@ -24112,7 +24112,7 @@ }, "Single-AZ": { "pricePerUnit": 0.472, - "sku": "H7GZH5WCA5W9BURW" + "sku": "6U7AJM6TEP9QYUTW" } }, "PostgreSQL": { @@ -25868,7 +25868,7 @@ }, "Single-AZ": { "pricePerUnit": 10.538, - "sku": "RDX5JC2YHYTNXEM6" + "sku": "RQ6UQ3465Q2WPWCF" } }, "SQL Server": { @@ -25890,7 +25890,7 @@ }, "Single-AZ": { "pricePerUnit": 15.806, - "sku": "J3K7XJWHGAEMUQV4" + "sku": "QW4C8M2FU5KVJYPD" } }, "SQL Server": { @@ -25912,7 +25912,7 @@ }, "Single-AZ": { "pricePerUnit": 1.317, - "sku": "SJWZKWS8KQE6Z9Z3" + "sku": "2VWDXJPDDMF6BXDZ" } }, "SQL Server": { @@ -26074,7 +26074,7 @@ }, "Single-AZ": { "pricePerUnit": 0.329, - "sku": "6FV6CSQY79N5WUTH" + "sku": "2JCM23BNR233P288" } }, "SQL Server": { @@ -26108,7 +26108,7 @@ }, "Single-AZ": { "pricePerUnit": 0.659, - "sku": "PSZ29ESQPFPGAUBU" + "sku": "8EUQKSYU4B8MEUK8" } }, "SQL Server": { @@ -27032,7 +27032,7 @@ }, "Single-AZ": { "pricePerUnit": 6.648, - "sku": "D89RAUARTPBD7A5P" + "sku": "WAZQK4FG72NR47KY" } }, "PostgreSQL": { @@ -27106,7 +27106,7 @@ }, "Single-AZ": { "pricePerUnit": 8.864, - "sku": "KEM8UKQ3R7RTKPMC" + "sku": "BK5WMKTF5ANZ6NW3" } }, "PostgreSQL": { @@ -27254,7 +27254,7 @@ }, "Single-AZ": { "pricePerUnit": 1.108, - "sku": "C2MCVTJ53B8ZZZSQ" + "sku": "88YJ3P5J2WVU44TC" } }, "PostgreSQL": { @@ -27364,7 +27364,7 @@ }, "Single-AZ": { "pricePerUnit": 17.728, - "sku": "8D3X5S7FB9B2D82H" + "sku": "7T5NARVZNAFS4GKX" } }, "PostgreSQL": { @@ -27437,8 +27437,8 @@ "sku": "KDBGKJHJUYPZECDU" }, "Single-AZ": { - "pricePerUnit": 2.216, - "sku": "SH9AFGSW8CXKB27W" + "pricePerUnit": 4.448, + "sku": "YN94YEUY48AHWD7Y" } }, "PostgreSQL": { @@ -27658,7 +27658,7 @@ }, "Single-AZ": { "pricePerUnit": 0.277, - "sku": "UWXYX3WKGNTAR3H9" + "sku": "NWZEGDMWJU9MVR5T" } }, "PostgreSQL": { @@ -27744,7 +27744,7 @@ }, "Single-AZ": { "pricePerUnit": 0.554, - "sku": "MPJMWN34QDJRXE66" + "sku": "A5ZUA6BBVA8EJUWU" } }, "PostgreSQL": { @@ -28580,7 +28580,7 @@ }, "Single-AZ": { "pricePerUnit": 0.104, - "sku": "RRCUS2M3B5477DZF" + "sku": "CRMNZFCT85UJ8P86" } }, "PostgreSQL": { @@ -28740,7 +28740,7 @@ }, "Single-AZ": { "pricePerUnit": 0.416, - "sku": "RM6T4P5TD7W2HQRW" + "sku": "8G3HF4JDHJTH783D" } }, "PostgreSQL": { @@ -29241,8 +29241,8 @@ "sku": "WQ55QRRMHM2DHJYU" }, "Single-AZ": { - "pricePerUnit": 81.792, - "sku": "E5ZADYPM8MXH493E" + "pricePerUnit": 81.825, + "sku": "6TX4QGHQZ6RCPQK4" } }, "SQL Server": { @@ -29273,8 +29273,8 @@ "sku": "BS9T7R4NXCQMZNJG" }, "Single-AZ": { - "pricePerUnit": 6.816, - "sku": "B38MRBR4RPJS7EM7" + "pricePerUnit": 6.819, + "sku": "2627MC396R3M6DU4" } }, "SQL Server": { @@ -29337,8 +29337,8 @@ "sku": "YEZKMY29B5NUP6G9" }, "Single-AZ": { - "pricePerUnit": 13.632, - "sku": "NKGE63ZVQMAANPST" + "pricePerUnit": 13.638, + "sku": "EMCTUMSZU9VX6XSP" } }, "SQL Server": { @@ -29369,8 +29369,8 @@ "sku": "VKCKXHDPVV6P62WM" }, "Single-AZ": { - "pricePerUnit": 27.264, - "sku": "RMAGU2KJ7CV6WAHH" + "pricePerUnit": 27.275, + "sku": "KQSYA5Q4AZDHEGT6" } }, "SQL Server": { @@ -29401,8 +29401,8 @@ "sku": "UBKMZGS258FB3WYY" }, "Single-AZ": { - "pricePerUnit": 3.408, - "sku": "KQ35UPJCVUT6Y8PT" + "pricePerUnit": 3.409, + "sku": "DDAWFUEAMYH784YA" } }, "SQL Server": { @@ -31340,7 +31340,7 @@ }, "Single-AZ": { "pricePerUnit": 5.988, - "sku": "3EJH8PMPPTW5HHF8" + "sku": "KVTE6XKNKS3ZUJBF" } }, "PostgreSQL": { @@ -31464,7 +31464,7 @@ }, "Single-AZ": { "pricePerUnit": 11.976, - "sku": "AQ4GTWAQRD85HMRB" + "sku": "GK5FM6FEYPMJWH4S" } }, "PostgreSQL": { @@ -31526,7 +31526,7 @@ }, "Single-AZ": { "pricePerUnit": 0.998, - "sku": "RKP3VKREYPNK59WJ" + "sku": "J476EKTW5TDG7BTX" } }, "PostgreSQL": { @@ -31650,7 +31650,7 @@ }, "Single-AZ": { "pricePerUnit": 1.996, - "sku": "JZHU767ARQ4PSG2F" + "sku": "G4C3R4NTDQWWH8U8" } }, "PostgreSQL": { @@ -31774,7 +31774,7 @@ }, "Single-AZ": { "pricePerUnit": 0.25, - "sku": "WDM6XAQ2JBUCW6XX" + "sku": "D4NA4KJS4696GUBT" } }, "PostgreSQL": { @@ -31836,7 +31836,7 @@ }, "Single-AZ": { "pricePerUnit": 0.499, - "sku": "HRP8ZERU2TR9VW7M" + "sku": "X4EVZ6KSUJVU95A6" } }, "PostgreSQL": { @@ -33668,7 +33668,7 @@ }, "Single-AZ": { "pricePerUnit": 8.864, - "sku": "YSS3D6SF7S557ER2" + "sku": "ZKKX2644TQH3GYJJ" } }, "PostgreSQL": { @@ -33742,7 +33742,7 @@ }, "Single-AZ": { "pricePerUnit": 13.296, - "sku": "VCGP2VCD8Z8WTMAQ" + "sku": "57FG2JXKARA6YNMU" } }, "PostgreSQL": { @@ -33816,7 +33816,7 @@ }, "Single-AZ": { "pricePerUnit": 1.108, - "sku": "EX84MKJANMKJ8SF2" + "sku": "QEA9GFZ8V8YN9375" } }, "PostgreSQL": { @@ -34000,7 +34000,7 @@ }, "Single-AZ": { "pricePerUnit": 2.216, - "sku": "9WD92EKK7T9MXGM3" + "sku": "ZUZQR76N7JMJE8RY" } }, "PostgreSQL": { @@ -34306,7 +34306,7 @@ }, "Single-AZ": { "pricePerUnit": 0.554, - "sku": "VBFPXY9DY8VYDM3M" + "sku": "P6ARWJRH6XYJDX6H" } }, "PostgreSQL": { @@ -34529,8 +34529,8 @@ "sku": "BXYSEGV5PTWFCV5E" }, "Single-AZ": { - "pricePerUnit": 0.836, - "sku": "MWZBVKRT22NUJR5Q" + "pricePerUnit": 1.644, + "sku": "AQAMUR4D8BMB5Q3F" } }, "PostgreSQL": { @@ -34604,7 +34604,7 @@ }, "Single-AZ": { "pricePerUnit": 0.209, - "sku": "TFUA5MCNSRS38JQ8" + "sku": "PZA68SF7869UBVJG" } }, "PostgreSQL": { @@ -34674,7 +34674,7 @@ }, "Single-AZ": { "pricePerUnit": 0.105, - "sku": "XKAR6CFAYYPREBHR" + "sku": "EVY87JFR947JPAXZ" } }, "PostgreSQL": { @@ -34834,7 +34834,7 @@ }, "Single-AZ": { "pricePerUnit": 0.418, - "sku": "SJH2R42RKNC25RSZ" + "sku": "2253PS6MDCKDCM3G" } }, "PostgreSQL": { @@ -35114,7 +35114,7 @@ }, "Single-AZ": { "pricePerUnit": 81.792, - "sku": "WFEENEV7P9AJ9XS2" + "sku": "TTMA23N4NX4NK5QH" } } }, @@ -35158,7 +35158,7 @@ }, "Single-AZ": { "pricePerUnit": 109.056, - "sku": "ZH63387D3YSX56TF" + "sku": "ETBF5EGT7T55YCXT" } } }, @@ -35180,7 +35180,7 @@ }, "Single-AZ": { "pricePerUnit": 13.632, - "sku": "2VD5X8MSBMEGK6DC" + "sku": "8GAMRF9T7Q2T2T6Z" } } }, @@ -35224,7 +35224,7 @@ }, "Single-AZ": { "pricePerUnit": 3.408, - "sku": "DW33PRGABXHRVQ2C" + "sku": "6BSQSB5K8EW3C33W" } } } @@ -37300,7 +37300,7 @@ }, "Single-AZ": { "pricePerUnit": 5.784, - "sku": "WCC7FWZPWVXF663V" + "sku": "BF8KFF2SMJ3KNJWS" } }, "PostgreSQL": { @@ -37486,7 +37486,7 @@ }, "Single-AZ": { "pricePerUnit": 0.964, - "sku": "89CJNJY84M6WKJHZ" + "sku": "G5FXMDCB94BDHKYC" } }, "PostgreSQL": { @@ -37548,7 +37548,7 @@ }, "Single-AZ": { "pricePerUnit": 15.424, - "sku": "U2T4WMBNFW6MTWA5" + "sku": "G8A878V5N38GJ8N3" } }, "PostgreSQL": { @@ -37610,7 +37610,7 @@ }, "Single-AZ": { "pricePerUnit": 1.928, - "sku": "J2KPPGXVHBCEW352" + "sku": "JS2XH5QBNHPVYYKD" } }, "PostgreSQL": { @@ -37734,7 +37734,7 @@ }, "Single-AZ": { "pricePerUnit": 0.241, - "sku": "F4YFBUBUEDDZS3GM" + "sku": "PKPBDWJF9BJAYGVP" } }, "PostgreSQL": { @@ -37796,7 +37796,7 @@ }, "Single-AZ": { "pricePerUnit": 0.482, - "sku": "E465WM6ZX677NNWB" + "sku": "PAG56NKMRSFXA27V" } }, "PostgreSQL": { @@ -40824,7 +40824,7 @@ }, "Single-AZ": { "pricePerUnit": 12.624, - "sku": "B9SCQKCYJUVEADUV" + "sku": "S2FCV2NKND67KEC8" } }, "PostgreSQL": { @@ -40898,7 +40898,7 @@ }, "Single-AZ": { "pricePerUnit": 1.052, - "sku": "9BG8ACTECPN7TVDF" + "sku": "HS94ESCDEGGG6U4V" } }, "PostgreSQL": { @@ -41008,7 +41008,7 @@ }, "Single-AZ": { "pricePerUnit": 16.832, - "sku": "8XRFVXCQMUHU8TYE" + "sku": "3VR5NQYPY3X86E9C" } }, "PostgreSQL": { @@ -41302,7 +41302,7 @@ }, "Single-AZ": { "pricePerUnit": 0.263, - "sku": "44J7T8AEZ725KVZY" + "sku": "Z6SSJP978HH4PQJC" } }, "PostgreSQL": { @@ -41388,7 +41388,7 @@ }, "Single-AZ": { "pricePerUnit": 0.526, - "sku": "JCBSRT5SNQM7DCXM" + "sku": "3NSXCDUHA8TAYF5K" } }, "PostgreSQL": { @@ -42154,7 +42154,7 @@ }, "Single-AZ": { "pricePerUnit": 0.196, - "sku": "BMKWTA2FHS6FNB59" + "sku": "TUZN25W5UVSE3537" } }, "PostgreSQL": { @@ -42223,8 +42223,8 @@ "sku": "9ZRUVDUGDCYSAX3Z" }, "Single-AZ": { - "pricePerUnit": 0.098, - "sku": "NBKD99QKAQXEEJR7" + "pricePerUnit": 0.144, + "sku": "J3NFYHUURM2UDNHQ" } }, "PostgreSQL": { @@ -42384,7 +42384,7 @@ }, "Single-AZ": { "pricePerUnit": 0.392, - "sku": "FWCP4MNX5FR3EZRR" + "sku": "T7Y73FAG84T86YQ6" } }, "PostgreSQL": { @@ -42759,8 +42759,8 @@ "sku": "7NZ5QXGAT7DKVJW9" }, "Single-AZ": { - "pricePerUnit": 58.176, - "sku": "TXBQ7G55AVG7E2TH" + "pricePerUnit": 58.214, + "sku": "VBX6P5T9E66GG4BV" } }, "SQL Server": { @@ -42791,8 +42791,8 @@ "sku": "KXD53YAPRT8V2RR2" }, "Single-AZ": { - "pricePerUnit": 4.848, - "sku": "9X4AFES4M8DTEYMQ" + "pricePerUnit": 4.851, + "sku": "R5A6FWGCUB3Q7H8J" } }, "SQL Server": { @@ -42855,8 +42855,8 @@ "sku": "YBZQ3CBAMC3YXZB7" }, "Single-AZ": { - "pricePerUnit": 9.696, - "sku": "96WJA4HJDZQ7HRED" + "pricePerUnit": 9.702, + "sku": "NRDM8H7GEDK5WHV8" } }, "SQL Server": { @@ -42919,8 +42919,8 @@ "sku": "VD5R7JUS8SNWAC4C" }, "Single-AZ": { - "pricePerUnit": 2.424, - "sku": "GZ8Y46EHYT38GKBY" + "pricePerUnit": 2.426, + "sku": "Z9U7RCBVXWM6H4J5" } }, "SQL Server": { @@ -49492,7 +49492,7 @@ }, "Single-AZ": { "pricePerUnit": 5.64, - "sku": "RXG985KXHC63AMUV" + "sku": "CSV5BDMNQG2QUQKX" } }, "PostgreSQL": { @@ -49554,7 +49554,7 @@ }, "Single-AZ": { "pricePerUnit": 7.52, - "sku": "48MS3U6TH7GQYJK9" + "sku": "W3VNBEGHGBJX6XHY" } }, "PostgreSQL": { @@ -49616,7 +49616,7 @@ }, "Single-AZ": { "pricePerUnit": 11.28, - "sku": "NPYNJRNYB24XG5S2" + "sku": "S3J5T4RR3DA9NFDF" } }, "PostgreSQL": { @@ -49740,7 +49740,7 @@ }, "Single-AZ": { "pricePerUnit": 15.04, - "sku": "MCJZ98EFHF39KF5G" + "sku": "5D7F2XAS2QZSFR7K" } }, "PostgreSQL": { @@ -49802,7 +49802,7 @@ }, "Single-AZ": { "pricePerUnit": 1.88, - "sku": "9M87AVUY4MR4ZD4J" + "sku": "5A5BYVBPJ6GA5UUR" } }, "PostgreSQL": { @@ -49926,7 +49926,7 @@ }, "Single-AZ": { "pricePerUnit": 0.235, - "sku": "Z9QANEXDHZSYM7X9" + "sku": "QVZYNAH4A6DBTAJW" } }, "PostgreSQL": { @@ -49988,7 +49988,7 @@ }, "Single-AZ": { "pricePerUnit": 0.47, - "sku": "S2NWB2QGY29RWA9H" + "sku": "J4M3RM6KH5CKFZDM" } }, "PostgreSQL": { @@ -51793,8 +51793,8 @@ "sku": "PKY9APZHGJKXVT2H" }, "Single-AZ": { - "pricePerUnit": 10.528, - "sku": "RA6V3XQUVQ26QBFB" + "pricePerUnit": 10.538, + "sku": "Q4EEEEJV29BAMRBP" } }, "PostgreSQL": { @@ -51845,8 +51845,8 @@ "sku": "CJJUTA4BUAQ8ZCRZ" }, "Single-AZ": { - "pricePerUnit": 15.792, - "sku": "KX4YQV5TBCNYDVM2" + "pricePerUnit": 15.806, + "sku": "46W7GG8JEHZU8PHD" } }, "PostgreSQL": { @@ -51897,8 +51897,8 @@ "sku": "69A4WGKA3UTQJRTW" }, "Single-AZ": { - "pricePerUnit": 1.316, - "sku": "VDBJTVWYXCD8Q67J" + "pricePerUnit": 1.317, + "sku": "EPRV76CHVFT64MTR" } }, "PostgreSQL": { @@ -51986,7 +51986,7 @@ }, "Single-AZ": { "pricePerUnit": 2.632, - "sku": "HEVJ2BT9GXZB73UT" + "sku": "DWE2ZJZKFCXRSVC2" } }, "PostgreSQL": { @@ -52085,8 +52085,8 @@ "sku": "GERAJFKEH7H8DSVC" }, "Single-AZ": { - "pricePerUnit": 5.264, - "sku": "TWADFHF9SDPGNFHX" + "pricePerUnit": 5.269, + "sku": "N2XNC6HAF7X843JU" } }, "PostgreSQL": { @@ -52150,7 +52150,7 @@ }, "Single-AZ": { "pricePerUnit": 0.329, - "sku": "4VDZZ7HZBN2HTSQT" + "sku": "MRQ4PUF8JUNP3S4V" } }, "PostgreSQL": { @@ -52214,7 +52214,7 @@ }, "Single-AZ": { "pricePerUnit": 0.658, - "sku": "WS5QKZVJUNKN5NPS" + "sku": "26BWK26GWXXE5PH9" } }, "PostgreSQL": { @@ -53638,7 +53638,7 @@ }, "Single-AZ": { "pricePerUnit": 1.108, - "sku": "6SB8PW7CY82S65SF" + "sku": "7NETK252SVZNDCYH" } }, "PostgreSQL": { @@ -53748,7 +53748,7 @@ }, "Single-AZ": { "pricePerUnit": 17.728, - "sku": "6NUJCWTTEN9U4GDK" + "sku": "7MQ2TTREJS6PCCJD" } }, "PostgreSQL": { @@ -53822,7 +53822,7 @@ }, "Single-AZ": { "pricePerUnit": 2.216, - "sku": "QWV659FBHJ92SCQQ" + "sku": "9FAE6HZ87RBKQG43" } }, "PostgreSQL": { @@ -53944,7 +53944,7 @@ }, "Single-AZ": { "pricePerUnit": 4.432, - "sku": "2HS4AB2GRZNWJS2S" + "sku": "UAD3HNU5PN2SFK3T" } }, "PostgreSQL": { @@ -54841,8 +54841,8 @@ "sku": "76QDYAHWNPPFNEQN" }, "Single-AZ": { - "pricePerUnit": 0.832, - "sku": "E4KJRM9XNHFVRDKE" + "pricePerUnit": 1.408, + "sku": "UCNG84TBRE7QDTNC" } }, "PostgreSQL": { @@ -54916,7 +54916,7 @@ }, "Single-AZ": { "pricePerUnit": 0.208, - "sku": "4CTXU7FHREGFZWJC" + "sku": "WCGA2Y7UJW24FUN4" } }, "PostgreSQL": { @@ -54985,8 +54985,8 @@ "sku": "5JZUN5MNYPMYFQCN" }, "Single-AZ": { - "pricePerUnit": 0.104, - "sku": "ZU4SRVCEXW7U5AWH" + "pricePerUnit": 0.176, + "sku": "Q7246G27E4JVATM6" } }, "PostgreSQL": { @@ -55146,7 +55146,7 @@ }, "Single-AZ": { "pricePerUnit": 0.416, - "sku": "H4R6DETRCUM6GDUX" + "sku": "BYX4CM4XF6CV4E8A" } }, "PostgreSQL": { @@ -55679,8 +55679,8 @@ "sku": "R48ABSVB8CSKGV9T" }, "Single-AZ": { - "pricePerUnit": 6.816, - "sku": "545GTNRGAK7DZM43" + "pricePerUnit": 6.819, + "sku": "NC2UFZ9BAR8K42WR" } }, "SQL Server": { @@ -55711,8 +55711,8 @@ "sku": "2GAYJP6P9PA6Y7MS" }, "Single-AZ": { - "pricePerUnit": 109.056, - "sku": "Q8A5DUJ8ZEPDKTUX" + "pricePerUnit": 109.1, + "sku": "QV4VSP7Q7QYEH6UJ" } }, "SQL Server": { @@ -55743,8 +55743,8 @@ "sku": "Z6SCNWGAPE4UT9Q4" }, "Single-AZ": { - "pricePerUnit": 13.632, - "sku": "PJ55Y5DJ695B8HZE" + "pricePerUnit": 13.638, + "sku": "CNTC6NAME2BSUUKV" } }, "SQL Server": { @@ -55775,8 +55775,8 @@ "sku": "GMZYZ6DG9EDJ5GF9" }, "Single-AZ": { - "pricePerUnit": 27.264, - "sku": "P5ZWV5Z2MQZESS2C" + "pricePerUnit": 27.275, + "sku": "8X2YBZ3RZ8BFWK94" } }, "SQL Server": { @@ -55807,8 +55807,8 @@ "sku": "AXPESC624Q3TFVR4" }, "Single-AZ": { - "pricePerUnit": 3.408, - "sku": "9JNKBP933Z5UGQY5" + "pricePerUnit": 3.409, + "sku": "24UMN53DP8UEVYSU" } }, "SQL Server": { @@ -58406,7 +58406,7 @@ }, "Single-AZ": { "pricePerUnit": 7.52, - "sku": "2UDGTEWMK7TZCJDR" + "sku": "P44FFEZWNA8RFSTY" } }, "PostgreSQL": { @@ -58468,7 +58468,7 @@ }, "Single-AZ": { "pricePerUnit": 11.28, - "sku": "FMMPHETERC475JQH" + "sku": "T2JGXN55VDYKTNS2" } }, "PostgreSQL": { @@ -58530,7 +58530,7 @@ }, "Single-AZ": { "pricePerUnit": 0.94, - "sku": "MCSW887VN5JKMMW6" + "sku": "AH65XDXTAAJXXK6M" } }, "PostgreSQL": { @@ -58654,7 +58654,7 @@ }, "Single-AZ": { "pricePerUnit": 1.88, - "sku": "BYZKE8Z65YFZUR56" + "sku": "G3E88U74EG2JBPFU" } }, "PostgreSQL": { @@ -58778,7 +58778,7 @@ }, "Single-AZ": { "pricePerUnit": 0.235, - "sku": "G8CXFJ6WFDCYE8WJ" + "sku": "XMHYQF3X3NTVZC8E" } }, "PostgreSQL": { @@ -60934,7 +60934,7 @@ }, "Single-AZ": { "pricePerUnit": 8.036, - "sku": "F9B85BSXDPAH249K" + "sku": "8P9Z5BEKQFGXQZ8A" } }, "SQL Server": { @@ -60956,7 +60956,7 @@ }, "Single-AZ": { "pricePerUnit": 10.715, - "sku": "NPF9ME3XDF8UWJCA" + "sku": "CTXA4V2RXWCSA62V" } }, "SQL Server": { @@ -60978,7 +60978,7 @@ }, "Single-AZ": { "pricePerUnit": 16.073, - "sku": "4AJ7EE8Q7X9UW8X7" + "sku": "MMNM6UB24Q4HNZVQ" } }, "SQL Server": { @@ -61000,7 +61000,7 @@ }, "Single-AZ": { "pricePerUnit": 1.339, - "sku": "PMZP78W9GRF6DJVF" + "sku": "TE7HZMWWB7B5UYBB" } }, "SQL Server": { @@ -62461,8 +62461,8 @@ "sku": "BCM6SV73UUVWACAB" }, "Single-AZ": { - "pricePerUnit": 8.832, - "sku": "YPHD8WFCBC67SMF3" + "pricePerUnit": 8.848, + "sku": "C8P97XF9N2SV2VCW" } }, "PostgreSQL": { @@ -62609,8 +62609,8 @@ "sku": "RFBM67STZHRAMQMD" }, "Single-AZ": { - "pricePerUnit": 1.104, - "sku": "2SKPU39CH2Z88Q2K" + "pricePerUnit": 1.106, + "sku": "E4D49VUKFSEXEZCK" } }, "PostgreSQL": { @@ -62720,7 +62720,7 @@ }, "Single-AZ": { "pricePerUnit": 17.664, - "sku": "QKN75FPU4TMNH648" + "sku": "HYBKBBY9TX4APAZR" } }, "PostgreSQL": { @@ -62793,8 +62793,8 @@ "sku": "CNHDB6737G26Q3Z8" }, "Single-AZ": { - "pricePerUnit": 2.208, - "sku": "Q9J5S645KWACSG3B" + "pricePerUnit": 2.211, + "sku": "VV8BP2QJJBV3D6GS" } }, "PostgreSQL": { @@ -62915,8 +62915,8 @@ "sku": "EHZVB3CZE5VCUWEK" }, "Single-AZ": { - "pricePerUnit": 4.416, - "sku": "PAMUEHETTDN77H4K" + "pricePerUnit": 4.424, + "sku": "NG7QMQ4Q898GZQ5S" } }, "PostgreSQL": { @@ -63099,8 +63099,8 @@ "sku": "W63EY3M89JC629V7" }, "Single-AZ": { - "pricePerUnit": 0.552, - "sku": "4B4DQGK49E9UPGUS" + "pricePerUnit": 0.553, + "sku": "KYRZUWZMYKUZQWPQ" } }, "PostgreSQL": { @@ -64170,7 +64170,7 @@ }, "Single-AZ": { "pricePerUnit": 0.832, - "sku": "N9A4JZKRCTHSS6HG" + "sku": "RB5SYBSMSHT268S9" } }, "PostgreSQL": { @@ -64243,8 +64243,8 @@ "sku": "JNGE2S84YNFB7RVS" }, "Single-AZ": { - "pricePerUnit": 0.208, - "sku": "W76T4TTPGY44DSJB" + "pricePerUnit": 0.352, + "sku": "F2WF7MX5984VSRUS" } }, "PostgreSQL": { @@ -65151,8 +65151,8 @@ "sku": "UBSZQWYW2V36V53X" }, "Single-AZ": { - "pricePerUnit": 81.792, - "sku": "YEFTPGEUAFK54H9J" + "pricePerUnit": 81.825, + "sku": "HHH3KUVFWPYMPVE6" } }, "PostgreSQL": { @@ -65221,8 +65221,8 @@ "sku": "SQJEUZNQYCVZFY6S" }, "Single-AZ": { - "pricePerUnit": 6.816, - "sku": "YN8KMY9QC8H2KG5S" + "pricePerUnit": 6.819, + "sku": "YKNEPBFJXV987KE3" } }, "PostgreSQL": { @@ -65361,8 +65361,8 @@ "sku": "JKSJ59CU3KNZVNM8" }, "Single-AZ": { - "pricePerUnit": 13.632, - "sku": "U9JA96VZ3PNEZTTH" + "pricePerUnit": 13.638, + "sku": "VJAWBRN3KPQ55JQQ" } }, "PostgreSQL": { @@ -65501,8 +65501,8 @@ "sku": "P3YWQHR99QVW97RQ" }, "Single-AZ": { - "pricePerUnit": 3.408, - "sku": "SQ73T3MVU9SZ7RKQ" + "pricePerUnit": 3.409, + "sku": "D77UU7ENF46HQU3K" } }, "PostgreSQL": { @@ -67040,7 +67040,7 @@ }, "Single-AZ": { "pricePerUnit": 5.64, - "sku": "B36BFSG9V2T3ACQR" + "sku": "XFRPD9E2ZSWDGYBP" } }, "SQL Server": { @@ -67104,7 +67104,7 @@ }, "Single-AZ": { "pricePerUnit": 11.28, - "sku": "NHZVK5DQBRMSYEUZ" + "sku": "NPHRGCHN4H8BWNNR" } }, "SQL Server": { @@ -67136,7 +67136,7 @@ }, "Single-AZ": { "pricePerUnit": 0.94, - "sku": "HHMYSGBXFCF6X2RZ" + "sku": "TNFS7T8AX49ZDP7V" } }, "SQL Server": { @@ -67168,7 +67168,7 @@ }, "Single-AZ": { "pricePerUnit": 15.04, - "sku": "YGNPGZ2G696G84BS" + "sku": "45DYAMTKTXX326WC" } }, "SQL Server": { @@ -67264,7 +67264,7 @@ }, "Single-AZ": { "pricePerUnit": 0.235, - "sku": "TC8SQC64M75R7JR9" + "sku": "D9ME6ZY7VXUG8VFQ" } }, "SQL Server": { @@ -67296,7 +67296,7 @@ }, "Single-AZ": { "pricePerUnit": 0.47, - "sku": "Y9KZ2ATSYCQHM74P" + "sku": "SVRJQGADFB8KY3JC" } }, "SQL Server": { @@ -67349,8 +67349,8 @@ "sku": "2D2F7A542EDW8UQ4" }, "Single-AZ": { - "pricePerUnit": 7.978, - "sku": "9MG3UMHF239Q43VW" + "pricePerUnit": 6.648, + "sku": "Q6YUW8E4SFEZRNWH" } }, "PostgreSQL": { @@ -67553,8 +67553,8 @@ "sku": "WAGDPNTE4DU3E6QU" }, "Single-AZ": { - "pricePerUnit": 1.33, - "sku": "745KQHZWEASF9UC6" + "pricePerUnit": 1.108, + "sku": "N6XC3TR6T58HWT6Y" } }, "PostgreSQL": { @@ -67653,8 +67653,8 @@ "sku": "759SB5ZW39THMGR7" }, "Single-AZ": { - "pricePerUnit": 2.659, - "sku": "HXJGJCV7G7ZC5HKY" + "pricePerUnit": 4.448, + "sku": "AZCEW2AXYB8YQ55J" } }, "PostgreSQL": { @@ -67765,8 +67765,8 @@ "sku": "937JBGJ9G2ZZ94FC" }, "Single-AZ": { - "pricePerUnit": 5.318, - "sku": "SMC86MHK5R84SC5H" + "pricePerUnit": 4.432, + "sku": "E2P5MX4RBA56ZCZK" } }, "PostgreSQL": { @@ -69271,8 +69271,8 @@ "sku": "J2ECXXQ72HHVM4S2" }, "Single-AZ": { - "pricePerUnit": 0.832, - "sku": "EEK9U2C4W2F6R4GP" + "pricePerUnit": 1.408, + "sku": "TZMRDDH8HTGD46DW" } }, "PostgreSQL": { @@ -69345,8 +69345,8 @@ "sku": "SJ8VHCM58FH6T6SM" }, "Single-AZ": { - "pricePerUnit": 0.208, - "sku": "3QV2APVAW96JX6CF" + "pricePerUnit": 0.352, + "sku": "DUAAES2SGZCHUT56" } }, "PostgreSQL": { @@ -69415,8 +69415,8 @@ "sku": "R9ATAYP6E7DD59RX" }, "Single-AZ": { - "pricePerUnit": 0.104, - "sku": "Z4BTU2TQUR2A48WH" + "pricePerUnit": 0.176, + "sku": "NKTU9B8TRJ8E8G2U" } }, "PostgreSQL": { @@ -69576,7 +69576,7 @@ }, "Single-AZ": { "pricePerUnit": 0.416, - "sku": "7E52YHEE6EPY9DXW" + "sku": "VYVRKRR85DQYV7Z3" } }, "PostgreSQL": { @@ -69856,7 +69856,7 @@ }, "Single-AZ": { "pricePerUnit": 81.792, - "sku": "XH5VDQG64V7FJB5N" + "sku": "9RMPK4AYEDD5DF3P" } } }, @@ -69878,7 +69878,7 @@ }, "Single-AZ": { "pricePerUnit": 6.816, - "sku": "D47HU7JTEBP448MC" + "sku": "BGKC5ATSPBFNUHEF" } } }, @@ -69944,7 +69944,7 @@ }, "Single-AZ": { "pricePerUnit": 27.264, - "sku": "8Z9RG4VA64SH6GRY" + "sku": "BS6DGYPXHMZ34QTX" } } }, @@ -69966,7 +69966,7 @@ }, "Single-AZ": { "pricePerUnit": 3.408, - "sku": "G23Y958RAW5CMMHN" + "sku": "Y8S3QR55X4XCSGRU" } } } @@ -73040,10 +73040,6 @@ "pricePerUnit": 10.608, "sku": "PF7RNMSXUZM96YCV" }, - "Multi-AZ (readable standbys)": { - "pricePerUnit": 14.761, - "sku": "XQ6UBN3MDKH2ZSAG" - }, "Single-AZ": { "pricePerUnit": 5.304, "sku": "HYZMY9P7DCQDEAZ2" @@ -73084,10 +73080,6 @@ "pricePerUnit": 14.144, "sku": "M8FZTA2T9NX8QJS9" }, - "Multi-AZ (readable standbys)": { - "pricePerUnit": 19.682, - "sku": "U6ZCDP9M4RMSQFGZ" - }, "Single-AZ": { "pricePerUnit": 7.072, "sku": "9MU2B5EFGZ5CV3F2" @@ -73128,10 +73120,6 @@ "pricePerUnit": 1.768, "sku": "8BF6F2K5ZDPFRR8M" }, - "Multi-AZ (readable standbys)": { - "pricePerUnit": 2.46, - "sku": "H5JYZQREGRGAK8GS" - }, "Single-AZ": { "pricePerUnit": 0.884, "sku": "8Z39HKXRZG8PPRG4" @@ -73172,10 +73160,6 @@ "pricePerUnit": 3.536, "sku": "UF7EAU27SCUP42NW" }, - "Multi-AZ (readable standbys)": { - "pricePerUnit": 4.921, - "sku": "X8RMK5JTB29EAAQU" - }, "Single-AZ": { "pricePerUnit": 1.768, "sku": "JGQSEUV76RXKVGPZ" @@ -73216,10 +73200,6 @@ "pricePerUnit": 7.072, "sku": "JF5JKNXD53DR4HRT" }, - "Multi-AZ (readable standbys)": { - "pricePerUnit": 9.841, - "sku": "KRFCB8XSM9KG6YH5" - }, "Single-AZ": { "pricePerUnit": 3.536, "sku": "B7UJUH4TU5UJPCSY" @@ -73260,10 +73240,6 @@ "pricePerUnit": 0.442, "sku": "GDUD6RYBHQHB2ZYU" }, - "Multi-AZ (readable standbys)": { - "pricePerUnit": 0.615, - "sku": "8P9ZJDPXPRGQBZDU" - }, "Single-AZ": { "pricePerUnit": 0.221, "sku": "ZDT6U8FQZ9EFXK5T" @@ -73304,10 +73280,6 @@ "pricePerUnit": 0.884, "sku": "CSM97VJ3C8BNWUGJ" }, - "Multi-AZ (readable standbys)": { - "pricePerUnit": 1.23, - "sku": "BNBRD9KTKKYHGVEZ" - }, "Single-AZ": { "pricePerUnit": 0.442, "sku": "83CH9WTBS8JMJXEH" @@ -73541,7 +73513,7 @@ }, "SQL Server": { "Multi-AZ": { - "pricePerUnit": 4.136, + "pricePerUnit": 5.132, "sku": "CS3XR2KVDW8HRMF2" }, "Single-AZ": { @@ -73645,7 +73617,7 @@ }, "SQL Server": { "Multi-AZ": { - "pricePerUnit": 8.273, + "pricePerUnit": 10.262, "sku": "Q9RW3FVKRAS7RZTG" }, "Single-AZ": { @@ -73749,12 +73721,12 @@ }, "SQL Server": { "Multi-AZ": { - "pricePerUnit": 1.283, + "pricePerUnit": 1.78, "sku": "T32XXP8DRKMCR5H3" }, "Single-AZ": { - "pricePerUnit": 1.137, - "sku": "2T92DRVGC3TDAY7V" + "pricePerUnit": 0.89, + "sku": "JJX7TAXGAN2CXX9J" } } }, @@ -73801,7 +73773,7 @@ }, "SQL Server": { "Multi-AZ": { - "pricePerUnit": 2.068, + "pricePerUnit": 2.566, "sku": "PEDQWTSQ3UFW88AB" }, "Single-AZ": { @@ -74703,12 +74675,6 @@ } }, "db.r6gd.12xlarge": { - "Aurora MySQL": { - "Single-AZ": { - "pricePerUnit": 7.656, - "sku": "2JRK6U7GTJJKD92P" - } - }, "Aurora PostgreSQL": { "Single-AZ": { "pricePerUnit": 7.656, @@ -74720,10 +74686,6 @@ "pricePerUnit": 12.624, "sku": "SGG6MEAE2CNZRJF4" }, - "Multi-AZ (readable standbys)": { - "pricePerUnit": 17.675, - "sku": "3BYM7D2QTA9WDX9B" - }, "Single-AZ": { "pricePerUnit": 6.312, "sku": "FKJSZ6WK8QXXUPWM" @@ -74759,12 +74721,6 @@ } }, "db.r6gd.16xlarge": { - "Aurora MySQL": { - "Single-AZ": { - "pricePerUnit": 10.208, - "sku": "K7QB5REPN5JQDK2A" - } - }, "Aurora PostgreSQL": { "Single-AZ": { "pricePerUnit": 13.27, @@ -74776,10 +74732,6 @@ "pricePerUnit": 16.832, "sku": "Z4E8WJG4VGSZR9B7" }, - "Multi-AZ (readable standbys)": { - "pricePerUnit": 23.566, - "sku": "VRNTJ4GVY3R8BM3P" - }, "Single-AZ": { "pricePerUnit": 8.416, "sku": "YSGZFR696A2Q3754" @@ -74815,12 +74767,6 @@ } }, "db.r6gd.2xlarge": { - "Aurora MySQL": { - "Single-AZ": { - "pricePerUnit": 1.276, - "sku": "FA38PJBBANRBQ8WJ" - } - }, "Aurora PostgreSQL": { "Single-AZ": { "pricePerUnit": 1.276, @@ -74832,10 +74778,6 @@ "pricePerUnit": 2.104, "sku": "YQWHQ7FKFQV6DCGD" }, - "Multi-AZ (readable standbys)": { - "pricePerUnit": 2.946, - "sku": "9PRBQBQTXVUUU8NF" - }, "Single-AZ": { "pricePerUnit": 1.052, "sku": "EWVZ8PVH45VD6QYH" @@ -74871,12 +74813,6 @@ } }, "db.r6gd.4xlarge": { - "Aurora MySQL": { - "Single-AZ": { - "pricePerUnit": 2.552, - "sku": "FU65JPXEMQZHVXE6" - } - }, "Aurora PostgreSQL": { "Single-AZ": { "pricePerUnit": 2.552, @@ -74888,10 +74824,6 @@ "pricePerUnit": 4.208, "sku": "DBBEDED35ES6HWQS" }, - "Multi-AZ (readable standbys)": { - "pricePerUnit": 5.891, - "sku": "4GCNWDSDHNKWZBVH" - }, "Single-AZ": { "pricePerUnit": 2.104, "sku": "ADVHVD3WK2DXBBB7" @@ -74927,12 +74859,6 @@ } }, "db.r6gd.8xlarge": { - "Aurora MySQL": { - "Single-AZ": { - "pricePerUnit": 5.104, - "sku": "PE4VEN9CKX8PTYTA" - } - }, "Aurora PostgreSQL": { "Single-AZ": { "pricePerUnit": 5.104, @@ -74944,10 +74870,6 @@ "pricePerUnit": 8.416, "sku": "WHPHBHQFYDWDMQQB" }, - "Multi-AZ (readable standbys)": { - "pricePerUnit": 11.783, - "sku": "2M2DDZBE6NGAJCYC" - }, "Single-AZ": { "pricePerUnit": 4.208, "sku": "3JC38M6A9F7S3CP8" @@ -74988,10 +74910,6 @@ "pricePerUnit": 0.526, "sku": "T2HNFJC27DBWSXVH" }, - "Multi-AZ (readable standbys)": { - "pricePerUnit": 0.736, - "sku": "9JDCP3XN49YDW8YR" - }, "Single-AZ": { "pricePerUnit": 0.263, "sku": "3P8HCHEUZX9UTXGV" @@ -75027,12 +74945,6 @@ } }, "db.r6gd.xlarge": { - "Aurora MySQL": { - "Single-AZ": { - "pricePerUnit": 0.638, - "sku": "ECR2HTGEQMPQBKRG" - } - }, "Aurora PostgreSQL": { "Single-AZ": { "pricePerUnit": 0.829, @@ -75044,10 +74956,6 @@ "pricePerUnit": 1.052, "sku": "MV6VM2CESNTUM2MX" }, - "Multi-AZ (readable standbys)": { - "pricePerUnit": 1.473, - "sku": "TD32PV7U7E3HW5C3" - }, "Single-AZ": { "pricePerUnit": 0.526, "sku": "GVC84NU96JDT9XTA" @@ -76522,7 +76430,7 @@ "Oracle": { "Multi-AZ": { "pricePerUnit": 0.404, - "sku": "WT6MY3TJQHB8D9R7" + "sku": "PFDRZ7FTM386UHPQ" }, "Single-AZ": { "pricePerUnit": 0.202, @@ -76540,10 +76448,6 @@ } }, "SQL Server": { - "Multi-AZ": { - "pricePerUnit": 1.127, - "sku": "F42PXXCM35GMH946" - }, "Single-AZ": { "pricePerUnit": 0.265, "sku": "P4VH37F5P97WFFQ3" @@ -76590,7 +76494,7 @@ }, "Single-AZ": { "pricePerUnit": 0.101, - "sku": "57GHRAKDF3CV52HA" + "sku": "VEZBW4QE4NFCWP6M" } }, "PostgreSQL": { @@ -76697,8 +76601,8 @@ }, "SQL Server": { "Single-AZ": { - "pricePerUnit": 0.089, - "sku": "KSPGQ2FXQQ35FRKN" + "pricePerUnit": 0.058, + "sku": "DC3MJNDCQK8JMF8H" } } }, @@ -76726,7 +76630,7 @@ "Oracle": { "Multi-AZ": { "pricePerUnit": 0.808, - "sku": "2U427H5XNJPK8R4G" + "sku": "KHKK49J824JNJX3H" }, "Single-AZ": { "pricePerUnit": 0.404, @@ -78992,7 +78896,7 @@ }, "Single-AZ": { "pricePerUnit": 6.048, - "sku": "4Y42PQRUWESR8H5N" + "sku": "QSQ46XXNPP65K7JM" } }, "PostgreSQL": { @@ -79054,7 +78958,7 @@ }, "Single-AZ": { "pricePerUnit": 9.072, - "sku": "8MTZ5YURJHE6RMUE" + "sku": "USPZNEXRW64VWEJY" } }, "PostgreSQL": { @@ -79116,7 +79020,7 @@ }, "Single-AZ": { "pricePerUnit": 0.756, - "sku": "FG9HBATG9RN8JV7A" + "sku": "RRUTKC5X4PJWGY2R" } }, "PostgreSQL": { @@ -79178,7 +79082,7 @@ }, "Single-AZ": { "pricePerUnit": 12.096, - "sku": "YXXPDKW65ZJUD7NH" + "sku": "VH3YAU57N3X3FTWP" } }, "PostgreSQL": { @@ -80970,7 +80874,7 @@ }, "Single-AZ": { "pricePerUnit": 7.237, - "sku": "S2V59254PE5BFQFE" + "sku": "VTUG4YBRH59CNJF6" } }, "SQL Server": { @@ -80992,7 +80896,7 @@ }, "Single-AZ": { "pricePerUnit": 9.65, - "sku": "V7AZWU57KZYJXB4S" + "sku": "NQ375SSVBZQXHKWS" } }, "SQL Server": { @@ -81014,7 +80918,7 @@ }, "Single-AZ": { "pricePerUnit": 14.474, - "sku": "NG9VA685VY5SC5VT" + "sku": "YTAMZWAWJJC3RYWS" } }, "SQL Server": { @@ -81232,7 +81136,7 @@ }, "Single-AZ": { "pricePerUnit": 0.603, - "sku": "4ZJZEGEZTFCQC8EQ" + "sku": "8KMPH7S3BA6585RH" } }, "SQL Server": { @@ -82572,7 +82476,7 @@ }, "Single-AZ": { "pricePerUnit": 12.288, - "sku": "NTEFNWPQC2XM5UJF" + "sku": "K2C2HBPSBQV57XDN" } }, "PostgreSQL": { @@ -82645,8 +82549,8 @@ "sku": "H5J2ZA89YCC3CY2V" }, "Single-AZ": { - "pricePerUnit": 1.024, - "sku": "DYMCDSJQVNAP6WGM" + "pricePerUnit": 1.008, + "sku": "XX2U7Y3ADWBGH9JF" } }, "PostgreSQL": { @@ -82952,7 +82856,7 @@ }, "Single-AZ": { "pricePerUnit": 4.096, - "sku": "DBNTCN2DMDKBJSNM" + "sku": "FDW2KGKXTZJV5TS9" } }, "PostgreSQL": { @@ -83135,8 +83039,8 @@ "sku": "T8EXM3S8V5JC9CTA" }, "Single-AZ": { - "pricePerUnit": 0.512, - "sku": "M29HJZM5CQGAJPKE" + "pricePerUnit": 0.504, + "sku": "Y4K28N35HNRM2BZ3" } }, "PostgreSQL": { @@ -83812,7 +83716,7 @@ }, "Single-AZ": { "pricePerUnit": 0.592, - "sku": "HXFRY6WSJZBH7ZFV" + "sku": "N8RUTCH8PVBXE24M" } }, "PostgreSQL": { @@ -83886,7 +83790,7 @@ }, "Single-AZ": { "pricePerUnit": 0.148, - "sku": "U5FHJWCXF2RWJ8V6" + "sku": "E9T9B4BSJM3BSCDX" } }, "PostgreSQL": { @@ -83956,7 +83860,7 @@ }, "Single-AZ": { "pricePerUnit": 0.074, - "sku": "BW93KX4YGRD2R5W5" + "sku": "98QF589Q4MUR7ZMG" } }, "PostgreSQL": { @@ -84115,8 +84019,8 @@ "sku": "6XX6Q6X9MH9FJ67J" }, "Single-AZ": { - "pricePerUnit": 0.296, - "sku": "A6EGRSFM842NM4K6" + "pricePerUnit": 0.664, + "sku": "4E22YAPWPDNJ6BHZ" } }, "PostgreSQL": { @@ -84591,8 +84495,8 @@ "sku": "ADXZMJPW4K2B45XU" }, "Single-AZ": { - "pricePerUnit": 41.344, - "sku": "AQESYGVE3PJZFG2E" + "pricePerUnit": 41.375, + "sku": "UBR35M9CCMK24836" } }, "PostgreSQL": { @@ -84731,8 +84635,8 @@ "sku": "XHR56YHAE7JWAAK4" }, "Single-AZ": { - "pricePerUnit": 5.168, - "sku": "GWS4SFYZW5YJCVD2" + "pricePerUnit": 5.172, + "sku": "ZDU6J59GEZAVXVDK" } }, "PostgreSQL": { @@ -84801,8 +84705,8 @@ "sku": "DUHF4MD35S4BKX44" }, "Single-AZ": { - "pricePerUnit": 82.688, - "sku": "SM3MAEPPEXUPGPUV" + "pricePerUnit": 82.75, + "sku": "XDACWBXJ7UJ2PGPW" } }, "PostgreSQL": { @@ -84871,8 +84775,8 @@ "sku": "3RD2J5JFFJDXMS6Y" }, "Single-AZ": { - "pricePerUnit": 10.336, - "sku": "G4XS8YZBAW4HTGTU" + "pricePerUnit": 10.344, + "sku": "2MWZRXX759EG355V" } }, "PostgreSQL": { @@ -84941,8 +84845,8 @@ "sku": "KM6NE5JYYSAP6SY5" }, "Single-AZ": { - "pricePerUnit": 20.672, - "sku": "7UNVCAT7BEUU3PUY" + "pricePerUnit": 20.688, + "sku": "YFPHZ5S8SR9UBWGD" } }, "PostgreSQL": { @@ -85011,8 +84915,8 @@ "sku": "94GKHCEHRHQHH5K6" }, "Single-AZ": { - "pricePerUnit": 2.584, - "sku": "WNBMTR4CWHZSBSC8" + "pricePerUnit": 2.586, + "sku": "U4EQCQ4D5EV96NEJ" } }, "PostgreSQL": { @@ -90436,7 +90340,7 @@ }, "Single-AZ": { "pricePerUnit": 12.992, - "sku": "Z62CPXHYQGZC64N8" + "sku": "KBKJ8RMN2NWT3FTP" } }, "PostgreSQL": { @@ -90684,7 +90588,7 @@ }, "Single-AZ": { "pricePerUnit": 0.406, - "sku": "GYPEFNG4PTRWUGYP" + "sku": "7KDKF345DVQ45BFS" } }, "PostgreSQL": { @@ -92849,8 +92753,8 @@ "sku": "V9R3FSV5CKUTGM7W" }, "Single-AZ": { - "pricePerUnit": 10.528, - "sku": "VXJ88FE5XHS4XQSQ" + "pricePerUnit": 10.538, + "sku": "7UMZHBNYSWJ4DEQ2" } }, "PostgreSQL": { @@ -92901,8 +92805,8 @@ "sku": "ZMH4YVKN9FNMM9C4" }, "Single-AZ": { - "pricePerUnit": 15.792, - "sku": "5V9YX3V8CE7M98QN" + "pricePerUnit": 15.806, + "sku": "GCMAR3B8U25SYSWC" } }, "PostgreSQL": { @@ -92953,8 +92857,8 @@ "sku": "3HJCMQNH376Y4FCG" }, "Single-AZ": { - "pricePerUnit": 1.316, - "sku": "KWH8CSR2Y77MKMEV" + "pricePerUnit": 1.317, + "sku": "XYVPR74JYEW4G6ZX" } }, "PostgreSQL": { @@ -93269,8 +93173,8 @@ "sku": "7ARGTGN9DTKWT769" }, "Single-AZ": { - "pricePerUnit": 0.658, - "sku": "XQS7RDFNFHS8QWH4" + "pricePerUnit": 0.659, + "sku": "VF8QT5N3E49V5Z8W" } }, "PostgreSQL": { @@ -94472,7 +94376,7 @@ }, "Single-AZ": { "pricePerUnit": 6.768, - "sku": "H2VQKWV6NU58GUHG" + "sku": "8P8Y3CNGK777V28U" } }, "PostgreSQL": { @@ -94546,7 +94450,7 @@ }, "Single-AZ": { "pricePerUnit": 9.024, - "sku": "KZCZTTDJUFGFZ5KD" + "sku": "E98EQKUYDFT9JZM6" } }, "PostgreSQL": { @@ -94620,7 +94524,7 @@ }, "Single-AZ": { "pricePerUnit": 13.536, - "sku": "8C3W26GM3BS52PVZ" + "sku": "3Y99KCHUZ46BA7UF" } }, "PostgreSQL": { @@ -94694,7 +94598,7 @@ }, "Single-AZ": { "pricePerUnit": 1.128, - "sku": "4GECFKBT62FDKGQN" + "sku": "ZV5CT6T5NUTBJ6KZ" } }, "PostgreSQL": { @@ -94878,7 +94782,7 @@ }, "Single-AZ": { "pricePerUnit": 2.256, - "sku": "T58EZQXDM5AJSJF9" + "sku": "MF7UUB9YRXPTAWX5" } }, "PostgreSQL": { @@ -95000,7 +94904,7 @@ }, "Single-AZ": { "pricePerUnit": 4.512, - "sku": "D9MKD3Y2BV8ZXHNR" + "sku": "V9QPHJCK9RTMAJH8" } }, "PostgreSQL": { @@ -95098,7 +95002,7 @@ }, "Single-AZ": { "pricePerUnit": 0.282, - "sku": "52SNPDKEFVSWGCPM" + "sku": "2SKM3FFCE96Z2MZT" } }, "PostgreSQL": { @@ -95184,7 +95088,7 @@ }, "Single-AZ": { "pricePerUnit": 0.564, - "sku": "ZC4YX9CFQT5MN4M3" + "sku": "E78427FQEZWSPBJH" } }, "PostgreSQL": { @@ -96232,7 +96136,7 @@ }, "Single-AZ": { "pricePerUnit": 0.64, - "sku": "SEQ7AUT7PX5KGPCR" + "sku": "CZ2H3V8EUZTFZ6Y8" } }, "PostgreSQL": { @@ -96376,7 +96280,7 @@ }, "Single-AZ": { "pricePerUnit": 0.08, - "sku": "FZAVC435DV8ZSV8S" + "sku": "VCB2DGC7TXRMUXEM" } }, "PostgreSQL": { @@ -97143,8 +97047,8 @@ "sku": "T5FZKCYKAGDTD4E2" }, "Single-AZ": { - "pricePerUnit": 52.608, - "sku": "7FTSVSB6EZ5KK5AG" + "pricePerUnit": 52.655, + "sku": "JSX7E3D39FSZGP7U" } }, "PostgreSQL": { @@ -97213,8 +97117,8 @@ "sku": "8YQ4UUX5FV9DZA8F" }, "Single-AZ": { - "pricePerUnit": 78.912, - "sku": "WZ9UJNJEHF7ZFP6B" + "pricePerUnit": 78.983, + "sku": "QHY5AA8GTHXXBS5K" } }, "PostgreSQL": { @@ -97283,8 +97187,8 @@ "sku": "DNZ38JFZAGWV8F37" }, "Single-AZ": { - "pricePerUnit": 6.576, - "sku": "YPRXBDK4G5PTZAQD" + "pricePerUnit": 6.582, + "sku": "5VZRN3PGF6YDVTYX" } }, "PostgreSQL": { @@ -97423,8 +97327,8 @@ "sku": "7FC9P783XEFGEM2D" }, "Single-AZ": { - "pricePerUnit": 13.152, - "sku": "D4WW3WWKEU8SYUY5" + "pricePerUnit": 13.164, + "sku": "WUJ6QNE94NG3GM2M" } }, "PostgreSQL": { @@ -97493,8 +97397,8 @@ "sku": "Y4V6JGE9MX2M66SP" }, "Single-AZ": { - "pricePerUnit": 26.304, - "sku": "9V3X8DCA3XQ35KWC" + "pricePerUnit": 26.328, + "sku": "SUEUKQGBHTEFBTUV" } }, "PostgreSQL": { @@ -97563,8 +97467,8 @@ "sku": "JE23CE9X3XN3TWXY" }, "Single-AZ": { - "pricePerUnit": 3.288, - "sku": "TQ2GRWVS7PAEJZU5" + "pricePerUnit": 3.291, + "sku": "EX4ZZVWURQJGDUXS" } }, "PostgreSQL": { @@ -102292,7 +102196,7 @@ }, "Single-AZ": { "pricePerUnit": 4.32, - "sku": "F6DVX9Q9R7URS8Y4" + "sku": "X37ZA5QKM4YPM8HC" } }, "PostgreSQL": { @@ -102354,7 +102258,7 @@ }, "Single-AZ": { "pricePerUnit": 5.76, - "sku": "6FJF4KK2QCFVSFBW" + "sku": "QQHCZXRMAHGBYCR8" } }, "PostgreSQL": { @@ -102478,7 +102382,7 @@ }, "Single-AZ": { "pricePerUnit": 0.72, - "sku": "RZCRRENNFSWBPN4X" + "sku": "52DVC4VMETRFVDZG" } }, "PostgreSQL": { @@ -102726,7 +102630,7 @@ }, "Single-AZ": { "pricePerUnit": 0.18, - "sku": "PH82PBAP2N7J3RNM" + "sku": "NAVTBQD37HHTFS2E" } }, "PostgreSQL": { @@ -102788,7 +102692,7 @@ }, "Single-AZ": { "pricePerUnit": 0.36, - "sku": "BSUG9U4FW43KSVKV" + "sku": "YKJFFVW4BCBZXAW7" } }, "PostgreSQL": { @@ -103928,7 +103832,7 @@ }, "Single-AZ": { "pricePerUnit": 14.025, - "sku": "ZXFWRQ9MR44ZA547" + "sku": "44CE4942486D42DR" } } }, @@ -103940,7 +103844,7 @@ }, "Single-AZ": { "pricePerUnit": 1.169, - "sku": "2GP9T59SANBJN9DQ" + "sku": "2EAHD24EDS2RXMK9" } } }, @@ -103988,7 +103892,7 @@ }, "Single-AZ": { "pricePerUnit": 2.338, - "sku": "XE5WZW6XEJDVFSPU" + "sku": "U324WFGCZUCWH46G" } } }, @@ -104048,7 +103952,7 @@ }, "Single-AZ": { "pricePerUnit": 4.675, - "sku": "PC5MY4ZD79EYBHCW" + "sku": "32HM2HFSRH9FAZB2" } } }, @@ -104096,7 +104000,7 @@ }, "Single-AZ": { "pricePerUnit": 0.584, - "sku": "42JG9YFM63GM6PU5" + "sku": "8GRBXGEBCQGTRQTJ" } } }, @@ -105010,7 +104914,7 @@ }, "Single-AZ": { "pricePerUnit": 5.88, - "sku": "BG2CKJK85H5M3GZV" + "sku": "XZ3JTYAY3MGG72E6" } }, "PostgreSQL": { @@ -105232,7 +105136,7 @@ }, "Single-AZ": { "pricePerUnit": 0.98, - "sku": "ASF3PQ8F39JXJYGG" + "sku": "WKFJDXF9V78ADY2C" } }, "PostgreSQL": { @@ -105342,7 +105246,7 @@ }, "Single-AZ": { "pricePerUnit": 15.68, - "sku": "NTY3REMVCFW8UFQM" + "sku": "9YAWSVBH6VQ5GHGH" } }, "PostgreSQL": { @@ -105416,7 +105320,7 @@ }, "Single-AZ": { "pricePerUnit": 1.96, - "sku": "99DW5AJ6PZ9ASXCP" + "sku": "NEYHTBVTMJZ82F6W" } }, "PostgreSQL": { @@ -105538,7 +105442,7 @@ }, "Single-AZ": { "pricePerUnit": 3.92, - "sku": "VFZGDWQ6E64QX9W3" + "sku": "2RWEV4FCHRED3CWD" } }, "PostgreSQL": { @@ -105636,7 +105540,7 @@ }, "Single-AZ": { "pricePerUnit": 0.245, - "sku": "CURXJYK6U8Q9J43Z" + "sku": "UBDZEE4HVC2VYM6P" } }, "PostgreSQL": { @@ -105722,7 +105626,7 @@ }, "Single-AZ": { "pricePerUnit": 0.49, - "sku": "JXHXS4QTZXRQBDCH" + "sku": "AU5CYT8G2ZZKYUBE" } }, "PostgreSQL": { @@ -106115,8 +106019,8 @@ "sku": "Z7ZSPMNF5FPUWDYM" }, "Single-AZ": { - "pricePerUnit": 0.548, - "sku": "E8XA7DP4JNQHYKVQ" + "pricePerUnit": 0.547, + "sku": "R94NM4E82V665WVW" } }, "PostgreSQL": { @@ -106189,8 +106093,8 @@ "sku": "ZN9VK6VF5VZNFM3J" }, "Single-AZ": { - "pricePerUnit": 0.137, - "sku": "CFABWG478T6YPWC3" + "pricePerUnit": 0.293, + "sku": "HJFUGFS6ZJ6NA5M6" } }, "PostgreSQL": { @@ -106260,7 +106164,7 @@ }, "Single-AZ": { "pricePerUnit": 0.069, - "sku": "UEVGAF8NWJ3C2KJG" + "sku": "XBUTEZGK6KMUQMNR" } }, "PostgreSQL": { @@ -106420,7 +106324,7 @@ }, "Single-AZ": { "pricePerUnit": 0.274, - "sku": "QR4X23CBUKNVAJK4" + "sku": "TFVA3VX24WSRN2EG" } }, "PostgreSQL": { @@ -106851,8 +106755,8 @@ "sku": "GPP76QX9XRFG83FR" }, "Single-AZ": { - "pricePerUnit": 42.88, - "sku": "4CW7U98U4WNNGFZ3" + "pricePerUnit": 42.896, + "sku": "H3QEC63CRKYSHMA9" } }, "PostgreSQL": { @@ -106991,8 +106895,8 @@ "sku": "U2QA2XBUJWPG5FPT" }, "Single-AZ": { - "pricePerUnit": 5.36, - "sku": "KVW3PK8RK2ATQ6JN" + "pricePerUnit": 5.362, + "sku": "2AGSDU6AET8RDJY8" } }, "PostgreSQL": { @@ -107061,8 +106965,8 @@ "sku": "NKDMNY34ZAPNTF5R" }, "Single-AZ": { - "pricePerUnit": 85.76, - "sku": "T46UQ9SZ79FHP7VX" + "pricePerUnit": 85.793, + "sku": "3YY9Z5XZ9FTVHWB8" } }, "PostgreSQL": { @@ -107131,8 +107035,8 @@ "sku": "MAFD4GMJ59ZFU2YP" }, "Single-AZ": { - "pricePerUnit": 10.72, - "sku": "62YD8YNX9YS7KWKU" + "pricePerUnit": 10.724, + "sku": "MMUSDYFHUFMV9ZW8" } }, "PostgreSQL": { @@ -107271,8 +107175,8 @@ "sku": "KFCF8KY7YEF58HF6" }, "Single-AZ": { - "pricePerUnit": 2.68, - "sku": "5C5YKJ3PME5DN3BB" + "pricePerUnit": 2.681, + "sku": "R5XKAW4TUGR72MZF" } }, "PostgreSQL": { @@ -109072,7 +108976,7 @@ }, "Single-AZ": { "pricePerUnit": 9.504, - "sku": "DW52VZ6DJUHGF4FG" + "sku": "PXCGB9SKQJSWVTPE" } }, "PostgreSQL": { @@ -109134,7 +109038,7 @@ }, "Single-AZ": { "pricePerUnit": 0.792, - "sku": "AMKZHFVNHUMRRPK5" + "sku": "N2TJE2CG72PKQER5" } }, "PostgreSQL": { @@ -109258,7 +109162,7 @@ }, "Single-AZ": { "pricePerUnit": 1.584, - "sku": "JHJMEZT8GWENPF6P" + "sku": "YBNBAA685UYN9YCB" } }, "PostgreSQL": { @@ -109444,7 +109348,7 @@ }, "Single-AZ": { "pricePerUnit": 0.396, - "sku": "3GUER2X4Y57EVQAX" + "sku": "N7RYPS89NWGT7NR8" } }, "PostgreSQL": { @@ -110352,7 +110256,7 @@ }, "Single-AZ": { "pricePerUnit": 10.36, - "sku": "57U74ZED8A62YFV3" + "sku": "5JM65B253JJAF2WM" } } }, @@ -110364,7 +110268,7 @@ }, "Single-AZ": { "pricePerUnit": 15.54, - "sku": "5DRCH5ZUBYVZ4P7G" + "sku": "YJ4VGWXW5GUNGMW5" } } }, @@ -110376,7 +110280,7 @@ }, "Single-AZ": { "pricePerUnit": 1.295, - "sku": "3GMQZ9UGGNRW59MN" + "sku": "J22R6SY3JB8UKTKF" } } }, @@ -110424,7 +110328,7 @@ }, "Single-AZ": { "pricePerUnit": 2.59, - "sku": "CJYGEWAQ3B59BJ2K" + "sku": "R8JV36VD53JQJBT2" } } }, @@ -110508,7 +110412,7 @@ }, "Single-AZ": { "pricePerUnit": 0.324, - "sku": "E32EN8QBD45FN48U" + "sku": "EQBHKQR7ZJ79443J" } } }, @@ -110532,7 +110436,7 @@ }, "Single-AZ": { "pricePerUnit": 0.648, - "sku": "R2TB2U648A9V9M23" + "sku": "TGFPJRJPYD8QZ5WM" } } }, @@ -111472,7 +111376,7 @@ }, "Single-AZ": { "pricePerUnit": 8.672, - "sku": "S5XKFFTEU2WZKCPV" + "sku": "QUAWFTAVJSQ5QUJ8" } }, "PostgreSQL": { @@ -111620,7 +111524,7 @@ }, "Single-AZ": { "pricePerUnit": 1.084, - "sku": "DJCERF2MT42GVC4R" + "sku": "GY2TZ4ZBBXA84VE8" } }, "PostgreSQL": { @@ -111730,7 +111634,7 @@ }, "Single-AZ": { "pricePerUnit": 17.344, - "sku": "HVNWCFW5N5K5X8UZ" + "sku": "8KE624H66UGPABRG" } }, "PostgreSQL": { @@ -111804,7 +111708,7 @@ }, "Single-AZ": { "pricePerUnit": 2.168, - "sku": "9X5YX2BR3CGKSRCT" + "sku": "E2T8DRFNFJJ5DV25" } }, "PostgreSQL": { @@ -112024,7 +111928,7 @@ }, "Single-AZ": { "pricePerUnit": 0.271, - "sku": "QUK8276ZDPSAM7EQ" + "sku": "2VDZF4UED4ZKW3NH" } }, "PostgreSQL": { @@ -112294,7 +112198,7 @@ }, "Single-AZ": { "pricePerUnit": 0.604, - "sku": "PRCX8UAHYAJRUPNS" + "sku": "DV63BMXS2S3X467K" } }, "PostgreSQL": { @@ -112368,7 +112272,7 @@ }, "Single-AZ": { "pricePerUnit": 0.151, - "sku": "DXSYKTP9MJTKDUR3" + "sku": "N666EMYS5HK97EWV" } }, "PostgreSQL": { @@ -112438,7 +112342,7 @@ }, "Single-AZ": { "pricePerUnit": 0.076, - "sku": "34N4JAJM9UF96JT7" + "sku": "DJ5ZHU7EV7AN49MC" } }, "PostgreSQL": { @@ -113000,7 +112904,7 @@ }, "Single-AZ": { "pricePerUnit": 47.36, - "sku": "UBZMDZYD9E36JXR9" + "sku": "Y2RKUP53C4292DJU" } }, "PostgreSQL": { @@ -113070,7 +112974,7 @@ }, "Single-AZ": { "pricePerUnit": 71.04, - "sku": "XHCWDFZZZDQ3RPTR" + "sku": "Y7EZQPXKG4W8W764" } }, "PostgreSQL": { @@ -113210,7 +113114,7 @@ }, "Single-AZ": { "pricePerUnit": 94.72, - "sku": "R9ZRPYVFYF7CY4TU" + "sku": "NJT9BJ7X3HT8HV2Y" } }, "PostgreSQL": { @@ -113350,7 +113254,7 @@ }, "Single-AZ": { "pricePerUnit": 23.68, - "sku": "TBGKNJST347U7Q6U" + "sku": "M3MUGFBQYJKH5ZC6" } }, "PostgreSQL": { @@ -119520,7 +119424,7 @@ }, "Single-AZ": { "pricePerUnit": 6.048, - "sku": "4F2ZXHKR3ZQ7PA6X" + "sku": "4XJFUWGJWY2Y4Y9N" } }, "PostgreSQL": { @@ -119582,7 +119486,7 @@ }, "Single-AZ": { "pricePerUnit": 9.072, - "sku": "22QMMEEK296FQT7Z" + "sku": "GRQ4K8XYDARHSR3J" } }, "PostgreSQL": { @@ -119768,7 +119672,7 @@ }, "Single-AZ": { "pricePerUnit": 1.512, - "sku": "CP8CV48TCXKMCANG" + "sku": "YHNXTERXZGFH2BBS" } }, "PostgreSQL": { @@ -119892,7 +119796,7 @@ }, "Single-AZ": { "pricePerUnit": 0.189, - "sku": "F84K7DMXB5YGZY6W" + "sku": "A9ZPJ2XM9BAZNP9B" } }, "PostgreSQL": { @@ -122925,8 +122829,8 @@ "sku": "VVZK82FWHC3AAPKP" }, "Single-AZ": { - "pricePerUnit": 14.832, - "sku": "79YGPY98KZBE9D3G" + "pricePerUnit": 14.83, + "sku": "NS3J5CF52C899F5A" } }, "SQL Server": { @@ -122948,7 +122852,7 @@ }, "Single-AZ": { "pricePerUnit": 1.236, - "sku": "QH7QH73S55H6NFAH" + "sku": "A9Z9MTCYQQU7M3EZ" } }, "SQL Server": { @@ -123006,7 +122910,7 @@ }, "Single-AZ": { "pricePerUnit": 2.472, - "sku": "QWMDJPUV5CDDBTRU" + "sku": "QQTEJ6Q3BJ7HHAMX" } }, "SQL Server": { @@ -123110,7 +123014,7 @@ }, "Single-AZ": { "pricePerUnit": 0.309, - "sku": "9T2SCYSHWNSDXTFE" + "sku": "RXU9XQUZD3GG8N84" } }, "SQL Server": { @@ -123144,7 +123048,7 @@ }, "Single-AZ": { "pricePerUnit": 0.618, - "sku": "3V2D38A4FXSFSVCJ" + "sku": "9F8PTZDVEAEJ5AM5" } }, "SQL Server": { @@ -124335,8 +124239,8 @@ "sku": "H6RJ495PMS9PWRMC" }, "Single-AZ": { - "pricePerUnit": 6.192, - "sku": "848JWPE4ZGTCGFJX" + "pricePerUnit": 6.187, + "sku": "UUJJ94EG8EUDCJHM" } }, "PostgreSQL": { @@ -124557,8 +124461,8 @@ "sku": "CTUZRF5KPDEWSNTE" }, "Single-AZ": { - "pricePerUnit": 1.032, - "sku": "TQ6NT4MFCCUWJA5D" + "pricePerUnit": 1.031, + "sku": "WWH7P3C326XEK4C5" } }, "PostgreSQL": { @@ -124668,7 +124572,7 @@ }, "Single-AZ": { "pricePerUnit": 16.512, - "sku": "GF4JBJRW9CFZ2BXB" + "sku": "TNY59QDE5DPT6GW8" } }, "PostgreSQL": { @@ -124741,8 +124645,8 @@ "sku": "SJZGRQFSRQZZK8US" }, "Single-AZ": { - "pricePerUnit": 2.064, - "sku": "KCNSZKYSMQC87GYN" + "pricePerUnit": 4.288, + "sku": "W24QME2WV8WS2K72" } }, "PostgreSQL": { @@ -124961,8 +124865,8 @@ "sku": "GSYDQF57SJYHGTEF" }, "Single-AZ": { - "pricePerUnit": 0.258, - "sku": "B3837M6PA3C4J5VF" + "pricePerUnit": 0.536, + "sku": "3U3QWWQZKVGG6Y36" } }, "PostgreSQL": { @@ -125047,8 +124951,8 @@ "sku": "UBAZQNKXX2YDZCTS" }, "Single-AZ": { - "pricePerUnit": 0.516, - "sku": "QSR3S364QZFRD8J5" + "pricePerUnit": 1.072, + "sku": "NX3F9CNVSMA9Y83H" } }, "PostgreSQL": { @@ -126945,8 +126849,8 @@ "sku": "U73PR3JFHHX62CT4" }, "Single-AZ": { - "pricePerUnit": 0.576, - "sku": "Q8AZ9TGB22ASRMR8" + "pricePerUnit": 1.232, + "sku": "FTR9DAF6W2Y5XD8G" } }, "PostgreSQL": { @@ -128445,8 +128349,8 @@ "sku": "QRUUH7XN2G82XUWM" }, "Single-AZ": { - "pricePerUnit": 11.296, - "sku": "V8DGJ2VKC7Z6C92Q" + "pricePerUnit": 11.28, + "sku": "SYF5XTW7VUNX827R" } }, "PostgreSQL": { @@ -131064,7 +130968,7 @@ }, "Single-AZ": { "pricePerUnit": 0.792, - "sku": "3TUFF3XPVPWWA5NB" + "sku": "YS9ER9K4CV5ARH7P" } }, "PostgreSQL": { @@ -131126,7 +131030,7 @@ }, "Single-AZ": { "pricePerUnit": 12.672, - "sku": "EQ7HB4QWNQV9P58Y" + "sku": "7R7HEHJ37NC3BWN5" } }, "PostgreSQL": { @@ -131188,7 +131092,7 @@ }, "Single-AZ": { "pricePerUnit": 1.584, - "sku": "6ATGC38N96D633UR" + "sku": "YNBRRDDYC2JPPZYG" } }, "PostgreSQL": { @@ -132984,7 +132888,7 @@ }, "Single-AZ": { "pricePerUnit": 1.296, - "sku": "EPKMXEASR3XMGMPH" + "sku": "FGQXXPYQXQJ72YEH" } }, "SQL Server": { @@ -133042,7 +132946,7 @@ }, "Single-AZ": { "pricePerUnit": 2.592, - "sku": "XG4BTCJW8ZCJCY87" + "sku": "2W8VSVHEJN377JH7" } }, "SQL Server": { @@ -133146,7 +133050,7 @@ }, "Single-AZ": { "pricePerUnit": 0.324, - "sku": "59DT6DED9ZGZZYQE" + "sku": "HMGF9C9NZ2APX7BJ" } }, "SQL Server": { @@ -133180,7 +133084,7 @@ }, "Single-AZ": { "pricePerUnit": 0.648, - "sku": "YPMZTYG3CFKNTQMY" + "sku": "J5NAMU9GYK9QSYQV" } }, "SQL Server": { @@ -134104,7 +134008,7 @@ }, "Single-AZ": { "pricePerUnit": 6.528, - "sku": "PV2SAJJYZ3DPKRFQ" + "sku": "GB8AK8S5ECT6RRC3" } }, "PostgreSQL": { @@ -134178,7 +134082,7 @@ }, "Single-AZ": { "pricePerUnit": 8.704, - "sku": "QNHF7SQU83NY8APH" + "sku": "YNKUHBMPDY5SXZBD" } }, "PostgreSQL": { @@ -134252,7 +134156,7 @@ }, "Single-AZ": { "pricePerUnit": 13.056, - "sku": "VXJAY3NV4N8T3MAA" + "sku": "E6BX5NE2FE5QTU69" } }, "PostgreSQL": { @@ -134326,7 +134230,7 @@ }, "Single-AZ": { "pricePerUnit": 1.088, - "sku": "PSHNQMQK3JJ77MTV" + "sku": "VREAAU9JDZWXGVVY" } }, "PostgreSQL": { @@ -134436,7 +134340,7 @@ }, "Single-AZ": { "pricePerUnit": 17.408, - "sku": "CNCK5E6AMRJQYBE5" + "sku": "NPNQ9GKZHWETUS9D" } }, "PostgreSQL": { @@ -134509,8 +134413,8 @@ "sku": "QQT5E346X8Z62TGJ" }, "Single-AZ": { - "pricePerUnit": 2.176, - "sku": "UV9FS8GV6VEXS4AJ" + "pricePerUnit": 4.387, + "sku": "GVRBUBWNQG4GTGQE" } }, "PostgreSQL": { @@ -134632,7 +134536,7 @@ }, "Single-AZ": { "pricePerUnit": 4.352, - "sku": "J5RANTWMBD2NCCFU" + "sku": "FNURJG99TPPCPPTU" } }, "PostgreSQL": { @@ -134729,8 +134633,8 @@ "sku": "CV3R9YRS59XVC8YK" }, "Single-AZ": { - "pricePerUnit": 0.272, - "sku": "9ZBAZQ6U4H7XNR7R" + "pricePerUnit": 0.548, + "sku": "KGHX4V83AEA699BQ" } }, "PostgreSQL": { @@ -134815,8 +134719,8 @@ "sku": "7MF43T5CWRJXNGDU" }, "Single-AZ": { - "pricePerUnit": 0.544, - "sku": "3PGKR95K7NJJ75DY" + "pricePerUnit": 1.097, + "sku": "4EE8GTHSXGNFFA5B" } }, "PostgreSQL": { @@ -135507,8 +135411,8 @@ "sku": "P3W5S6GDWZM92964" }, "Single-AZ": { - "pricePerUnit": 0.608, - "sku": "FB45F46PS7WRS295" + "pricePerUnit": 1.296, + "sku": "98B877TQB3TATRTN" } }, "PostgreSQL": { @@ -135582,7 +135486,7 @@ }, "Single-AZ": { "pricePerUnit": 0.152, - "sku": "9Y4ZPA4Q6SVYGXFA" + "sku": "SVHSP8FHGQJ8BVBE" } }, "PostgreSQL": { @@ -135651,8 +135555,8 @@ "sku": "5RD3KN8FHV77M9XA" }, "Single-AZ": { - "pricePerUnit": 0.076, - "sku": "TFSYZF7SZ6NJJT2E" + "pricePerUnit": 0.162, + "sku": "8JDZVMVZUNEZJ8RA" } }, "PostgreSQL": { @@ -135812,7 +135716,7 @@ }, "Single-AZ": { "pricePerUnit": 0.304, - "sku": "CJVRB237K73C58B8" + "sku": "2K6FZAAJKGA2BYYW" } }, "PostgreSQL": { @@ -136245,8 +136149,8 @@ "sku": "JCZS7HDVA5XAPDBJ" }, "Single-AZ": { - "pricePerUnit": 94.72, - "sku": "3AN5BKPSG5WM7F8S" + "pricePerUnit": 94.786, + "sku": "9NMDA85M6WU8K65A" } }, "SQL Server": { @@ -136277,8 +136181,8 @@ "sku": "8Q5BZT88HMV2EM7J" }, "Single-AZ": { - "pricePerUnit": 11.84, - "sku": "5FVRCMG9F6VBBV77" + "pricePerUnit": 11.848, + "sku": "YRZHK33ZR9ZBAFYC" } }, "SQL Server": { @@ -136309,8 +136213,8 @@ "sku": "4NC6FSYQ7X6DRYFX" }, "Single-AZ": { - "pricePerUnit": 23.68, - "sku": "XG7KREVTPHNYMH22" + "pricePerUnit": 23.697, + "sku": "GKFQYRDN8QAF3YF6" } }, "SQL Server": { @@ -138452,7 +138356,7 @@ }, "Single-AZ": { "pricePerUnit": 6.336, - "sku": "94QWXWV66BJMN7WU" + "sku": "FXASV3CD2QA8DERF" } }, "PostgreSQL": { @@ -138514,7 +138418,7 @@ }, "Single-AZ": { "pricePerUnit": 9.504, - "sku": "947VDYXP9E2UUNNS" + "sku": "3AVFJ9HRYSAR8QQJ" } }, "PostgreSQL": { @@ -138700,7 +138604,7 @@ }, "Single-AZ": { "pricePerUnit": 1.584, - "sku": "ZMG53ZW2Q6CBKPGH" + "sku": "Y52WSTA3EJHERQ2Y" } }, "PostgreSQL": { @@ -138824,7 +138728,7 @@ }, "Single-AZ": { "pricePerUnit": 0.198, - "sku": "EWGKH8JPTBYB62GX" + "sku": "T2N4MQBQD8RSBHZ5" } }, "PostgreSQL": { @@ -138886,7 +138790,7 @@ }, "Single-AZ": { "pricePerUnit": 0.396, - "sku": "NXKEC4A2W5KW5Z57" + "sku": "B2ZSPF4H3BEHCVV6" } }, "PostgreSQL": { @@ -141459,8 +141363,8 @@ "sku": "4JGWPRP7XXR2YAZ9" }, "Single-AZ": { - "pricePerUnit": 13.008, - "sku": "2DFGYY3294MPEGS2" + "pricePerUnit": 12.998, + "sku": "VVHBMXHB2BWPCVPW" } }, "PostgreSQL": { @@ -141534,7 +141438,7 @@ }, "Single-AZ": { "pricePerUnit": 1.084, - "sku": "P359YSWXR4E9773B" + "sku": "WWJJA9YA7D2SR2KX" } }, "PostgreSQL": { @@ -142024,7 +141928,7 @@ }, "Single-AZ": { "pricePerUnit": 0.542, - "sku": "GCTFSEJKP9BQ2NAA" + "sku": "E3S2HBKQG65JZYD6" } }, "PostgreSQL": { @@ -142391,8 +142295,8 @@ "sku": "VAFEXZAST4Y3CGF5" }, "Single-AZ": { - "pricePerUnit": 0.608, - "sku": "Q8DZ5ET574J5DR88" + "pricePerUnit": 1.301, + "sku": "PC5P87RENGJWJ47F" } }, "PostgreSQL": { @@ -142466,7 +142370,7 @@ }, "Single-AZ": { "pricePerUnit": 0.152, - "sku": "N6X2UDAMNMUGJM99" + "sku": "ZKV3ZQQ3FDHDN29R" } }, "PostgreSQL": { @@ -142535,8 +142439,8 @@ "sku": "XP9D6S6WJA2U6QHE" }, "Single-AZ": { - "pricePerUnit": 0.076, - "sku": "VY9RWVY5RTW6YE6Z" + "pricePerUnit": 0.163, + "sku": "HP63EWU6G7WQ7D56" } }, "PostgreSQL": { @@ -142696,7 +142600,7 @@ }, "Single-AZ": { "pricePerUnit": 0.304, - "sku": "WYA7XTX6PQMZQZW2" + "sku": "FD8NJGUX4SUQVJNT" } }, "PostgreSQL": { @@ -142998,7 +142902,7 @@ }, "Single-AZ": { "pricePerUnit": 47.36, - "sku": "X7J32GPFXXT79G5A" + "sku": "TMXZJUDR3WBBQ5HV" } }, "SQL Server": { @@ -143030,7 +142934,7 @@ }, "Single-AZ": { "pricePerUnit": 71.04, - "sku": "T9MVWXVEWDDHD8TH" + "sku": "8KN7SZGCTES4DBMT" } }, "SQL Server": { @@ -143094,7 +142998,7 @@ }, "Single-AZ": { "pricePerUnit": 94.72, - "sku": "H4PHWZ5HCQSKG9VE" + "sku": "3RQXMZBNRDK49Z54" } }, "SQL Server": { @@ -143126,7 +143030,7 @@ }, "Single-AZ": { "pricePerUnit": 11.84, - "sku": "RST7KBU4G4K5Z6BF" + "sku": "237RZP8BSKKMHVA8" } }, "SQL Server": { @@ -143158,7 +143062,7 @@ }, "Single-AZ": { "pricePerUnit": 23.68, - "sku": "D8DCXE68VTKP3F65" + "sku": "3SQJ22M2T2UTGWEW" } }, "SQL Server": { @@ -148458,7 +148362,7 @@ }, "Single-AZ": { "pricePerUnit": 6.656, - "sku": "YKAWZB4CGPJKSRWU" + "sku": "RDSHDBTS5AC74RQG" } }, "SQL Server": { @@ -148480,7 +148384,7 @@ }, "Single-AZ": { "pricePerUnit": 9.984, - "sku": "PDQFG7WAE73VNDH2" + "sku": "GNQBVH8XRA2K5SMM" } }, "SQL Server": { @@ -148502,7 +148406,7 @@ }, "Single-AZ": { "pricePerUnit": 0.832, - "sku": "ZVN5W9DS7DPCDGXV" + "sku": "ACPNJ6TWV56RRBQN" } }, "SQL Server": { @@ -148546,7 +148450,7 @@ }, "Single-AZ": { "pricePerUnit": 1.664, - "sku": "T4UXEXGB2YQ9BGVY" + "sku": "RPWMJNVJRHCAD69X" } }, "SQL Server": { @@ -148590,7 +148494,7 @@ }, "Single-AZ": { "pricePerUnit": 0.208, - "sku": "45KFGH34B9A5W8KF" + "sku": "SHU6HVCD3GX5PC5P" } }, "SQL Server": { @@ -148612,7 +148516,7 @@ }, "Single-AZ": { "pricePerUnit": 0.416, - "sku": "JS5BWKM8CDE8EZP4" + "sku": "EUKVAP9DMJKRT7FM" } }, "SQL Server": { @@ -149716,7 +149620,7 @@ }, "Single-AZ": { "pricePerUnit": 6.816, - "sku": "435SFW8H6Q2SX7FE" + "sku": "AMRFZGHNR36UN62C" } }, "SQL Server": { @@ -149744,7 +149648,7 @@ }, "Single-AZ": { "pricePerUnit": 9.088, - "sku": "T473WZKM6KEKRHGH" + "sku": "TG5J7BWC7HQFEVK3" } }, "SQL Server": { @@ -149800,7 +149704,7 @@ }, "Single-AZ": { "pricePerUnit": 1.136, - "sku": "ZEUPG9UUBZWB3DPG" + "sku": "62U6A3KHN8DWBAUU" } }, "SQL Server": { @@ -149892,7 +149796,7 @@ }, "Single-AZ": { "pricePerUnit": 2.272, - "sku": "92548AQ8G29MG9S8" + "sku": "U4Q4HHNDE45VRFUJ" } }, "SQL Server": { @@ -150060,7 +149964,7 @@ }, "Single-AZ": { "pricePerUnit": 0.568, - "sku": "9NWR8DGT574UWZGM" + "sku": "UMGP5HKQ5CC2XNRK" } }, "SQL Server": { @@ -150135,8 +150039,8 @@ "sku": "CQ4PYBUCAD2K3J7E" }, "Single-AZ": { - "pricePerUnit": 0.632, - "sku": "74TY45DZ8RRXZWKV" + "pricePerUnit": 1.355, + "sku": "MV8Y243XNX6RN2G8" } }, "PostgreSQL": { @@ -150209,8 +150113,8 @@ "sku": "M4WMPCE92QE2SJY2" }, "Single-AZ": { - "pricePerUnit": 0.158, - "sku": "V78U3RY5KWU8XACB" + "pricePerUnit": 0.339, + "sku": "NB2K8J2W42CFXYKX" } }, "PostgreSQL": { @@ -150279,8 +150183,8 @@ "sku": "CBVMCPXF4XCSYK58" }, "Single-AZ": { - "pricePerUnit": 0.079, - "sku": "HZA2HTY7U6GJ68SE" + "pricePerUnit": 0.169, + "sku": "JEC3ZAS2HC8KMF73" } }, "PostgreSQL": { @@ -150439,8 +150343,8 @@ "sku": "ZEC5U8CS825QSYEE" }, "Single-AZ": { - "pricePerUnit": 0.316, - "sku": "VBNKY576CSPQD36X" + "pricePerUnit": 0.678, + "sku": "D2VUPPYTEA99AKHX" } }, "PostgreSQL": { @@ -158118,7 +158022,7 @@ }, "Single-AZ": { "pricePerUnit": 5.544, - "sku": "TUAE449CZAUPPYZM" + "sku": "9N845PCXNJ72EFPD" } }, "PostgreSQL": { @@ -158242,7 +158146,7 @@ }, "Single-AZ": { "pricePerUnit": 11.088, - "sku": "Q7XPNYCNR43AE2M8" + "sku": "RB4BRWGH9CFH2XKW" } }, "PostgreSQL": { @@ -158366,7 +158270,7 @@ }, "Single-AZ": { "pricePerUnit": 14.784, - "sku": "NUPSG9ETSUBSG5CM" + "sku": "4K9XNFECDR5AVRUF" } }, "PostgreSQL": { @@ -158428,7 +158332,7 @@ }, "Single-AZ": { "pricePerUnit": 1.848, - "sku": "XP27MC7HG5VCR68U" + "sku": "MC62NV3EA36R9TGG" } }, "PostgreSQL": { @@ -158490,7 +158394,7 @@ }, "Single-AZ": { "pricePerUnit": 3.696, - "sku": "PVQNEVQRDAQDDQM4" + "sku": "MTVM2NZAXH46PM26" } }, "PostgreSQL": { @@ -158614,7 +158518,7 @@ }, "Single-AZ": { "pricePerUnit": 0.462, - "sku": "F5KJZ59RX3THUF2M" + "sku": "QATDDSYMFFAK4SFW" } }, "PostgreSQL": { @@ -159926,7 +159830,7 @@ }, "Single-AZ": { "pricePerUnit": 14.03, - "sku": "S28FDY5GV7D4T5N2" + "sku": "XQNTQ6YMQ8RR79EN" } }, "SQL Server": { @@ -159948,7 +159852,7 @@ }, "Single-AZ": { "pricePerUnit": 21.046, - "sku": "TKT8VEMPT58B2Y2V" + "sku": "AXKT7ZFJP4KMG62E" } }, "SQL Server": { @@ -160028,7 +159932,7 @@ }, "Single-AZ": { "pricePerUnit": 3.508, - "sku": "XNP72R2FG9TS63N4" + "sku": "R8SXUS2KFRRH9FJV" } }, "SQL Server": { @@ -160098,7 +160002,7 @@ }, "Single-AZ": { "pricePerUnit": 7.015, - "sku": "S28F95HW83K3H2AC" + "sku": "T77GVCSE6TW6H8G9" } }, "SQL Server": { @@ -160132,7 +160036,7 @@ }, "Single-AZ": { "pricePerUnit": 0.438, - "sku": "FUTJVWGMYGYMFHCJ" + "sku": "F3F52CWX3KFCG96Z" } }, "SQL Server": { @@ -160166,7 +160070,7 @@ }, "Single-AZ": { "pricePerUnit": 0.877, - "sku": "AX3RNNUEWEEXSMSQ" + "sku": "7H3Y5JYC2FGQPGMG" } }, "SQL Server": { @@ -161090,7 +160994,7 @@ }, "Single-AZ": { "pricePerUnit": 11.664, - "sku": "78VZ9MRZKSCFY5KW" + "sku": "ABATBX8UCYPSRM86" } }, "PostgreSQL": { @@ -161164,7 +161068,7 @@ }, "Single-AZ": { "pricePerUnit": 15.552, - "sku": "6Q6CUVQ3A4FWDDCD" + "sku": "MKEZHAMAAKW439CU" } }, "PostgreSQL": { @@ -161238,7 +161142,7 @@ }, "Single-AZ": { "pricePerUnit": 23.328, - "sku": "P96N7GEHXMDVE39S" + "sku": "PE6CE263PEMHPQ54" } }, "PostgreSQL": { @@ -161312,7 +161216,7 @@ }, "Single-AZ": { "pricePerUnit": 1.944, - "sku": "9Y4U8DZV8EJWYPKN" + "sku": "6RPAGRPU3M5ZYWVZ" } }, "PostgreSQL": { @@ -161422,7 +161326,7 @@ }, "Single-AZ": { "pricePerUnit": 31.104, - "sku": "GMWTFPH85ER7QQGU" + "sku": "RS9RVQ4W5DJACZH2" } }, "PostgreSQL": { @@ -161496,7 +161400,7 @@ }, "Single-AZ": { "pricePerUnit": 3.888, - "sku": "9KV72PNJP4MXHXZU" + "sku": "3N6EQPP96CQD4ENY" } }, "PostgreSQL": { @@ -161716,7 +161620,7 @@ }, "Single-AZ": { "pricePerUnit": 0.486, - "sku": "JKVBUJPUKFF8SBJ7" + "sku": "FFAYMS9V65XFJS7F" } }, "PostgreSQL": { @@ -161802,7 +161706,7 @@ }, "Single-AZ": { "pricePerUnit": 0.972, - "sku": "VQS7A2UXBBGXU4BT" + "sku": "9NCAAJYN4DJVGU65" } }, "PostgreSQL": { @@ -162370,7 +162274,7 @@ }, "Single-AZ": { "pricePerUnit": 0.28, - "sku": "SMAYQBKV3XA9D4TZ" + "sku": "5CAKKFHSSPMWHXR9" } }, "PostgreSQL": { @@ -162440,7 +162344,7 @@ }, "Single-AZ": { "pricePerUnit": 0.14, - "sku": "8YTZCPHM3Y98PUG8" + "sku": "EEHB7Z2USRD8J9G8" } }, "PostgreSQL": { @@ -162599,8 +162503,8 @@ "sku": "57KN34CMCHFXDCWR" }, "Single-AZ": { - "pricePerUnit": 0.56, - "sku": "MH27BWGTRZVC2C8Z" + "pricePerUnit": 0.864, + "sku": "XV44EH5M47ZTVME7" } }, "PostgreSQL": { @@ -162937,8 +162841,8 @@ "sku": "GAX3Q8UPR7PU66VM" }, "Single-AZ": { - "pricePerUnit": 73.344, - "sku": "JPMZQMEM29T3XQ3R" + "pricePerUnit": 73.365, + "sku": "HYXRV2XF4EX3CD2S" } }, "SQL Server": { @@ -163001,8 +162905,8 @@ "sku": "9KNFXTZB9RDHUNZU" }, "Single-AZ": { - "pricePerUnit": 9.168, - "sku": "Q67E5K7XMH2592QK" + "pricePerUnit": 9.171, + "sku": "A8X8ED68C9G4WBDM" } }, "SQL Server": { @@ -163033,8 +162937,8 @@ "sku": "KZFC4MPPMJH2UKTE" }, "Single-AZ": { - "pricePerUnit": 146.688, - "sku": "EWHRDG3GZZR6BPKH" + "pricePerUnit": 146.73, + "sku": "PZF7RW8MXQY5BWES" } }, "SQL Server": { @@ -163065,8 +162969,8 @@ "sku": "T375A39BU3DVSNKU" }, "Single-AZ": { - "pricePerUnit": 18.336, - "sku": "PF2EBECT5UW8KCSG" + "pricePerUnit": 18.341, + "sku": "W5YYNTQCF82GQP92" } }, "SQL Server": { @@ -163097,8 +163001,8 @@ "sku": "Z498K7KF6Q7EU2T3" }, "Single-AZ": { - "pricePerUnit": 36.672, - "sku": "H2C2KYDWJCEG7F85" + "pricePerUnit": 36.683, + "sku": "8HP5EQSD4Z6H3XB7" } }, "SQL Server": { @@ -165786,7 +165690,7 @@ }, "Single-AZ": { "pricePerUnit": 10.944, - "sku": "W6MP5KN7JEW26J28" + "sku": "W3HQVM437XWNNM6P" } }, "PostgreSQL": { @@ -165848,7 +165752,7 @@ }, "Single-AZ": { "pricePerUnit": 1.368, - "sku": "KUY4EFWK78ACY772" + "sku": "RHQQHDYKP6AMQZBF" } }, "PostgreSQL": { @@ -165910,7 +165814,7 @@ }, "Single-AZ": { "pricePerUnit": 2.736, - "sku": "QW7UM2Y5KZT59T2J" + "sku": "4KGK3A8AQGQHBV6N" } }, "PostgreSQL": { @@ -165972,7 +165876,7 @@ }, "Single-AZ": { "pricePerUnit": 0.171, - "sku": "MSU8JRUKP9NZYPHU" + "sku": "SM8QY9F8VDUXNSWR" } }, "PostgreSQL": { @@ -166034,7 +165938,7 @@ }, "Single-AZ": { "pricePerUnit": 0.342, - "sku": "NSGKD2FYWBZ92C38" + "sku": "855WKCSUGN9H9D8R" } }, "PostgreSQL": { @@ -169141,8 +169045,8 @@ "sku": "BMZTFZ52285JQE9U" }, "Single-AZ": { - "pricePerUnit": 1.104, - "sku": "2BE3R84EYYF2EGWE" + "pricePerUnit": 1.103, + "sku": "FY8AN5GAVHJQV7CM" } }, "PostgreSQL": { @@ -169229,8 +169133,8 @@ "sku": "SS2YHZPT5487TNE7" }, "Single-AZ": { - "pricePerUnit": 2.208, - "sku": "KKNWP4SWFMC8ZNQN" + "pricePerUnit": 2.205, + "sku": "9YNEMT9DNS6DXHB3" } }, "PostgreSQL": { @@ -169457,8 +169361,8 @@ "sku": "GTBKATRBFCSRBGU7" }, "Single-AZ": { - "pricePerUnit": 0.552, - "sku": "3NT53XGW4WEMAQ3A" + "pricePerUnit": 0.551, + "sku": "YM332KR7H5S2TGYH" } }, "PostgreSQL": { @@ -170660,7 +170564,7 @@ }, "Single-AZ": { "pricePerUnit": 5.592, - "sku": "M3G4WYPMGNSJA6ER" + "sku": "CG85BE8BTTXQRVU7" } }, "PostgreSQL": { @@ -170882,7 +170786,7 @@ }, "Single-AZ": { "pricePerUnit": 0.932, - "sku": "VMAYNXTYXAXA46EJ" + "sku": "E767GRNRASUD5SV9" } }, "PostgreSQL": { @@ -170992,7 +170896,7 @@ }, "Single-AZ": { "pricePerUnit": 14.912, - "sku": "SYEJMFUSEHZTW95N" + "sku": "DNMUDVXB9AFUGPP8" } }, "PostgreSQL": { @@ -171066,7 +170970,7 @@ }, "Single-AZ": { "pricePerUnit": 1.864, - "sku": "SRYDJGENHRQHTP9U" + "sku": "62ZYT7CC6H87CDHV" } }, "PostgreSQL": { @@ -171372,7 +171276,7 @@ }, "Single-AZ": { "pricePerUnit": 0.466, - "sku": "XJ378TZBRJ5AT73E" + "sku": "6DJ7SZ3G3CMEKG5N" } }, "PostgreSQL": { @@ -173269,8 +173173,8 @@ "sku": "TPF7X865H2SA3PQM" }, "Single-AZ": { - "pricePerUnit": 0.544, - "sku": "8DZ7C9FGY2WZ7PM9" + "pricePerUnit": 1.2, + "sku": "YRPU89ZN362EV9WW" } }, "PostgreSQL": { @@ -173413,8 +173317,8 @@ "sku": "8CTSMU3V7DR7C43U" }, "Single-AZ": { - "pricePerUnit": 0.068, - "sku": "5PV62KP9CJUS4EVE" + "pricePerUnit": 0.15, + "sku": "K4SGPVDGPSJ8UZVP" } }, "PostgreSQL": { @@ -174445,8 +174349,8 @@ "sku": "9GWR2KHXBPQM5N2J" }, "Single-AZ": { - "pricePerUnit": 56.448, - "sku": "ARJESS4FRC2DRBD3" + "pricePerUnit": 56.445, + "sku": "JAMYNBHKCVH57X7C" } }, "PostgreSQL": { @@ -174832,7 +174736,7 @@ }, "Single-AZ": { "pricePerUnit": 18.215, - "sku": "FXXF9PBCD63E9EQB" + "sku": "9UN3YCSHPFDBHXP9" } } }, @@ -177088,7 +176992,7 @@ }, "Single-AZ": { "pricePerUnit": 4.104, - "sku": "FD9CUK6YGG7NVWPQ" + "sku": "PSMWBCAVKH6NYTUW" } }, "PostgreSQL": { @@ -177212,7 +177116,7 @@ }, "Single-AZ": { "pricePerUnit": 8.208, - "sku": "44PKWXVAAVXSQR8R" + "sku": "YFFJEB3VYF3PUS4V" } }, "PostgreSQL": { @@ -177274,7 +177178,7 @@ }, "Single-AZ": { "pricePerUnit": 0.684, - "sku": "UMEQDWYUJKXZBDFR" + "sku": "FB4K7SF4Y5YQ4MQZ" } }, "PostgreSQL": { @@ -177336,7 +177240,7 @@ }, "Single-AZ": { "pricePerUnit": 10.944, - "sku": "BTB93CVSX3NZAMN8" + "sku": "UB5BWWHDP2U5VYKK" } }, "PostgreSQL": { @@ -177398,7 +177302,7 @@ }, "Single-AZ": { "pricePerUnit": 1.368, - "sku": "DEQKN4DG5JAUJVT2" + "sku": "3SNV66936JYWBCRC" } }, "PostgreSQL": { @@ -177522,7 +177426,7 @@ }, "Single-AZ": { "pricePerUnit": 0.171, - "sku": "DRAENKHWTS3MKNNY" + "sku": "SWVVG82QCUW4NXD3" } }, "PostgreSQL": { @@ -177584,7 +177488,7 @@ }, "Single-AZ": { "pricePerUnit": 0.342, - "sku": "45RK9S4YGDFJ5YCZ" + "sku": "UYT6EB6AQS3F379M" } }, "PostgreSQL": { @@ -180525,8 +180429,8 @@ "sku": "XVS8NAE9HYDUM4S7" }, "Single-AZ": { - "pricePerUnit": 6.624, - "sku": "V7BVUEUJ9C4UBP8A" + "pricePerUnit": 6.615, + "sku": "5UZ5NPRNVYRMUVPT" } }, "PostgreSQL": { @@ -180629,8 +180533,8 @@ "sku": "45YZGNWBDYHZH5CR" }, "Single-AZ": { - "pricePerUnit": 13.248, - "sku": "NKHW39ACNFN7VPHH" + "pricePerUnit": 13.231, + "sku": "2JNNSP7Q5TQQ4H7F" } }, "PostgreSQL": { @@ -180682,7 +180586,7 @@ }, "Single-AZ": { "pricePerUnit": 1.104, - "sku": "ZWAUKFYQXKEG8CK9" + "sku": "6YRJ8TTUZBSSX3W7" } }, "PostgreSQL": { @@ -180770,7 +180674,7 @@ }, "Single-AZ": { "pricePerUnit": 2.208, - "sku": "9PXGQ6PS7ANE6HWN" + "sku": "UJGT8J4JMNYWGH4R" } }, "PostgreSQL": { @@ -180869,8 +180773,8 @@ "sku": "RZW9GWYTZR7D9GJJ" }, "Single-AZ": { - "pricePerUnit": 4.416, - "sku": "QVX8UEMTS8G65KEN" + "pricePerUnit": 4.41, + "sku": "R8JVKBUVNQCU3MRK" } }, "PostgreSQL": { @@ -180934,7 +180838,7 @@ }, "Single-AZ": { "pricePerUnit": 0.276, - "sku": "DN5EWVQ8GJNK6RAM" + "sku": "XDZX6TH8WMY43ZEB" } }, "PostgreSQL": { @@ -180997,8 +180901,8 @@ "sku": "ABF8RHT7D3KMUCJY" }, "Single-AZ": { - "pricePerUnit": 0.552, - "sku": "QC8AYDMF2A4TJ2TG" + "pricePerUnit": 0.551, + "sku": "E9ZXYMHBF6HDXCWZ" } }, "PostgreSQL": { @@ -182274,7 +182178,7 @@ }, "Single-AZ": { "pricePerUnit": 7.456, - "sku": "83GHN9JWGF44HXQ2" + "sku": "5BBPKG4MJTCJDVHK" } }, "PostgreSQL": { @@ -182348,7 +182252,7 @@ }, "Single-AZ": { "pricePerUnit": 11.184, - "sku": "Z9UY49YWGEG3ZPWH" + "sku": "9NEBHKDPQVK64VVQ" } }, "PostgreSQL": { @@ -182422,7 +182326,7 @@ }, "Single-AZ": { "pricePerUnit": 0.932, - "sku": "RS7UMXUMEZSXUK3A" + "sku": "R739FDP7HKFPBX6H" } }, "PostgreSQL": { @@ -182532,7 +182436,7 @@ }, "Single-AZ": { "pricePerUnit": 14.912, - "sku": "4WDGKF2HU44Y9NER" + "sku": "8W24EZ78247XVU79" } }, "PostgreSQL": { @@ -182606,7 +182510,7 @@ }, "Single-AZ": { "pricePerUnit": 1.864, - "sku": "W9SPD3ANPMRW7VH7" + "sku": "EQZ8H5UQ7255P865" } }, "PostgreSQL": { @@ -182826,7 +182730,7 @@ }, "Single-AZ": { "pricePerUnit": 0.233, - "sku": "A4J5885RV7N4VQBX" + "sku": "W82GKPERDBFNRFT4" } }, "PostgreSQL": { @@ -182912,7 +182816,7 @@ }, "Single-AZ": { "pricePerUnit": 0.466, - "sku": "8NR8RBNSD5YAHWS8" + "sku": "C28HEURRG68F3ZBC" } }, "PostgreSQL": { @@ -184862,7 +184766,7 @@ }, "Single-AZ": { "pricePerUnit": 0.136, - "sku": "WGRR9U55R6EQ6TGF" + "sku": "56GTPC25Y6RZ43DQ" } }, "PostgreSQL": { @@ -184932,7 +184836,7 @@ }, "Single-AZ": { "pricePerUnit": 0.068, - "sku": "X74KFQQDQCPQ97RR" + "sku": "YDFT6B9QTGR8UEJ9" } }, "PostgreSQL": { @@ -185869,8 +185773,8 @@ "sku": "5WFPWEUJZ92NAMXJ" }, "Single-AZ": { - "pricePerUnit": 37.632, - "sku": "Q9URN2YP6RQK2932" + "pricePerUnit": 37.63, + "sku": "4PRUV6FPXEBQ3HHM" } }, "SQL Server": { @@ -185934,7 +185838,7 @@ }, "Single-AZ": { "pricePerUnit": 4.704, - "sku": "BD48KJG3BFWXR7HQ" + "sku": "65DHCBDMS4RAGB2D" } }, "PostgreSQL": { @@ -186004,7 +185908,7 @@ }, "Single-AZ": { "pricePerUnit": 9.408, - "sku": "K5KMXD4AWWBBYUY6" + "sku": "C5J3TDAUG3J56HEQ" } }, "SQL Server": { @@ -186035,8 +185939,8 @@ "sku": "2V2B373YRUZUKYRA" }, "Single-AZ": { - "pricePerUnit": 18.816, - "sku": "MYJV4BX94HTYDNEZ" + "pricePerUnit": 18.815, + "sku": "SGB894RJR3YTDGS2" } }, "SQL Server": { @@ -186068,7 +185972,7 @@ }, "Single-AZ": { "pricePerUnit": 2.352, - "sku": "AVH7JPS64BNWCYB6" + "sku": "UBR6636WME8XBR3N" } }, "SQL Server": { @@ -206648,7 +206552,7 @@ }, "Single-AZ": { "pricePerUnit": 0.684, - "sku": "F8P7XAJ8S8KF8YNK" + "sku": "WRV2YU4PT27U4AB4" } }, "PostgreSQL": { @@ -206772,7 +206676,7 @@ }, "Single-AZ": { "pricePerUnit": 1.368, - "sku": "JBFU3JH3AW56Z4N4" + "sku": "DHXQQ3ZDNT6FEDKV" } }, "PostgreSQL": { @@ -206896,7 +206800,7 @@ }, "Single-AZ": { "pricePerUnit": 0.171, - "sku": "PS3RVJ8ZA5TEQNB5" + "sku": "N3MVM7PMSEZ44TMQ" } }, "PostgreSQL": { @@ -206958,7 +206862,7 @@ }, "Single-AZ": { "pricePerUnit": 0.342, - "sku": "PMZNHBN4J7YKMWB2" + "sku": "2RHVD8K7FBRHG843" } }, "PostgreSQL": { @@ -209899,8 +209803,8 @@ "sku": "95SRVNQDHAQMBQ5S" }, "Single-AZ": { - "pricePerUnit": 6.624, - "sku": "NFQAZ6B39WA8CQKT" + "pricePerUnit": 6.615, + "sku": "XXTCHQ6EE4J69233" } }, "PostgreSQL": { @@ -210003,8 +209907,8 @@ "sku": "5894P64RKFA9ZJGU" }, "Single-AZ": { - "pricePerUnit": 13.248, - "sku": "ZWHS9WCCEUY2JDWW" + "pricePerUnit": 13.231, + "sku": "T8KH6NNBSJKAPPMZ" } }, "PostgreSQL": { @@ -210143,8 +210047,8 @@ "sku": "HCFYC8UHUN2P9MXE" }, "Single-AZ": { - "pricePerUnit": 2.208, - "sku": "8Y5TWTDXXNQZCP2A" + "pricePerUnit": 2.205, + "sku": "5F655CAY79R28E4K" } }, "PostgreSQL": { @@ -210243,8 +210147,8 @@ "sku": "SBWZECDEA8KNPRGJ" }, "Single-AZ": { - "pricePerUnit": 4.416, - "sku": "GFSPR5SHEAGR9YQ8" + "pricePerUnit": 4.41, + "sku": "GVQX7K6UCY6HFR3V" } }, "PostgreSQL": { @@ -210371,8 +210275,8 @@ "sku": "ZW2WPKF8MY8A9TWX" }, "Single-AZ": { - "pricePerUnit": 0.552, - "sku": "PEP4HGRF7M49WK4Y" + "pricePerUnit": 0.551, + "sku": "5PSB6B7KV3VY3VD4" } }, "PostgreSQL": { @@ -211648,7 +211552,7 @@ }, "Single-AZ": { "pricePerUnit": 7.456, - "sku": "5P4NDFFK5ME7ZMC3" + "sku": "5FVHD63X2N9BH55G" } }, "PostgreSQL": { @@ -211795,8 +211699,8 @@ "sku": "2T7GN4EG7C3F9G25" }, "Single-AZ": { - "pricePerUnit": 0.932, - "sku": "UGUNVARNCDTTDN6A" + "pricePerUnit": 1.928, + "sku": "P7AXGPZN7QKD7P2S" } }, "PostgreSQL": { @@ -211906,7 +211810,7 @@ }, "Single-AZ": { "pricePerUnit": 14.912, - "sku": "XM5S4P3MYW8GBR94" + "sku": "NCJ4ZW9DRCYMAWJX" } }, "PostgreSQL": { @@ -212102,7 +212006,7 @@ }, "Single-AZ": { "pricePerUnit": 3.728, - "sku": "HNHGET8B34HH5KSJ" + "sku": "GSVDM38J946A9HKB" } }, "PostgreSQL": { @@ -212200,7 +212104,7 @@ }, "Single-AZ": { "pricePerUnit": 0.233, - "sku": "UY3J3X6YEKA7GQNC" + "sku": "7F2GQ6ZQ4TUE8R3N" } }, "PostgreSQL": { @@ -212286,7 +212190,7 @@ }, "Single-AZ": { "pricePerUnit": 0.466, - "sku": "UM4KVTE6MQW5TCY6" + "sku": "E22PJJAT6JJK6J8U" } }, "PostgreSQL": { @@ -214190,7 +214094,7 @@ }, "Single-AZ": { "pricePerUnit": 0.544, - "sku": "NG39AB7SFYF9RE8T" + "sku": "YE5GR9AKMPWUNYA8" } }, "PostgreSQL": { @@ -214264,7 +214168,7 @@ }, "Single-AZ": { "pricePerUnit": 0.136, - "sku": "P5JVU7KANAXZRR4J" + "sku": "RX8AV6CMGWASU2HQ" } }, "PostgreSQL": { @@ -214334,7 +214238,7 @@ }, "Single-AZ": { "pricePerUnit": 0.068, - "sku": "WQ9BZ4ZFFX87FA5V" + "sku": "8849NHVJRT5URTQX" } }, "PostgreSQL": { @@ -214494,7 +214398,7 @@ }, "Single-AZ": { "pricePerUnit": 0.272, - "sku": "D8PF3VXUD97FA9ZC" + "sku": "YBVKG2RURCAYRAJM" } }, "PostgreSQL": { @@ -215295,8 +215199,8 @@ "sku": "37D499NDQ85CXNPF" }, "Single-AZ": { - "pricePerUnit": 37.632, - "sku": "KFGNBTZN3N7PHMXT" + "pricePerUnit": 37.63, + "sku": "FAWE5S93PC6USHNU" } }, "PostgreSQL": { @@ -215436,7 +215340,7 @@ }, "Single-AZ": { "pricePerUnit": 4.704, - "sku": "5UJRQCMKVZMHA69F" + "sku": "JHJ977P48KDYP27K" } }, "PostgreSQL": { @@ -215505,8 +215409,8 @@ "sku": "ZBRJRN28JT8HG3AF" }, "Single-AZ": { - "pricePerUnit": 75.264, - "sku": "YAH89HXBGUYZVSP7" + "pricePerUnit": 75.26, + "sku": "DUFRUH83WS9VEYR7" } }, "PostgreSQL": { @@ -215645,8 +215549,8 @@ "sku": "9UNNWAU2TZ84ZXP4" }, "Single-AZ": { - "pricePerUnit": 18.816, - "sku": "3EESFRH97B4BCJKW" + "pricePerUnit": 18.815, + "sku": "TA7WANCY6WAA74NC" } }, "PostgreSQL": { @@ -215716,7 +215620,7 @@ }, "Single-AZ": { "pricePerUnit": 2.352, - "sku": "UATKY3NWZS96H3CZ" + "sku": "JREUMQCTYCSM5VFJ" } }, "PostgreSQL": { @@ -215752,7 +215656,7 @@ }, "Single-AZ": { "pricePerUnit": 18.215, - "sku": "NSQ6SJ3ZKJ2PXJH6" + "sku": "4NUDPM68E94ZT2ZH" } } }, @@ -215764,7 +215668,7 @@ }, "Single-AZ": { "pricePerUnit": 3.036, - "sku": "GX7VRWEA8KFZTHZ2" + "sku": "4TJYATYRWURNAWC6" } } }, @@ -215776,7 +215680,7 @@ }, "Single-AZ": { "pricePerUnit": 6.072, - "sku": "RR9HATP29XKQAXR3" + "sku": "EY5699VV3X7DHVR8" } } }, @@ -215800,7 +215704,7 @@ }, "Single-AZ": { "pricePerUnit": 12.143, - "sku": "W4J5E7K2BZK8QNAJ" + "sku": "BX8GE7KWCCTJ3U6J" } } }, diff --git a/data/aws/instance_types.json b/data/aws/instance_types.json index 13c9ac4643..260345df8c 100644 --- a/data/aws/instance_types.json +++ b/data/aws/instance_types.json @@ -5790,6 +5790,12 @@ "vcpu": "1", "up": null, "down": null, + "superseded": { + "regular": "db.t3.micro", + "next_gen": "", + "burstable": "", + "amd": "" + }, "nfu": "0.5", "memory": "0.613" }, @@ -5797,6 +5803,12 @@ "vcpu": "1", "up": "db.t2.small", "down": null, + "superseded": { + "regular": "db.t3.micro", + "next_gen": "", + "burstable": "", + "amd": "" + }, "nfu": "0.5", "memory": "1" }, @@ -5804,6 +5816,12 @@ "vcpu": "1", "up": "db.t2.medium", "down": "db.t2.micro", + "superseded": { + "regular": "db.t3.small", + "next_gen": "", + "burstable": "", + "amd": "" + }, "nfu": "1", "memory": "2" }, @@ -5811,6 +5829,12 @@ "vcpu": "2", "up": "db.t2.large", "down": "db.t2.small", + "superseded": { + "regular": "db.t3.medium", + "next_gen": "", + "burstable": "", + "amd": "" + }, "nfu": "2", "memory": "4" }, @@ -5818,6 +5842,12 @@ "vcpu": "2", "up": "db.t2.xlarge", "down": "db.t2.medium", + "superseded": { + "regular": "db.t3.large", + "next_gen": "", + "burstable": "", + "amd": "" + }, "nfu": "4", "memory": "8" }, @@ -5825,6 +5855,12 @@ "vcpu": "4", "up": "db.t2.2xlarge", "down": "db.t2.large", + "superseded": { + "regular": "db.t3.xlarge", + "next_gen": "", + "burstable": "", + "amd": "" + }, "nfu": "8", "memory": "16" }, @@ -5832,6 +5868,12 @@ "vcpu": "8", "up": null, "down": "db.t2.xlarge", + "superseded": { + "regular": "db.t3.2xlarge", + "next_gen": "", + "burstable": "", + "amd": "" + }, "nfu": "16", "memory": "32" }, diff --git a/data/azure/azure_sqlmi_storage_pricing.json b/data/azure/azure_sqlmi_storage_pricing.json new file mode 100644 index 0000000000..4afbf98ead --- /dev/null +++ b/data/azure/azure_sqlmi_storage_pricing.json @@ -0,0 +1,730 @@ +{ + "australiacentral": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000D", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0005", + "unitPrice": 0.138 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000S", + "unitPrice": 0.12 + } + }, + "australiacentral2": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0007", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0001", + "unitPrice": 0.138 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000X", + "unitPrice": 0.12 + } + }, + "australiaeast": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0001", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0008", + "unitPrice": 0.138 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000Q", + "unitPrice": 0.12 + } + }, + "australiasoutheast": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0017", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000F", + "unitPrice": 0.138 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000T", + "unitPrice": 0.12 + } + }, + "brazilsouth": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0008", + "unitPrice": 0.475 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0003", + "unitPrice": 0.2185 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000V", + "unitPrice": 0.19 + } + }, + "brazilsoutheast": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0022", + "unitPrice": 0.6175 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0022", + "unitPrice": 0.28405 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/001D", + "unitPrice": 0.494 + } + }, + "canadacentral": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000Q", + "unitPrice": 0.275 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000S", + "unitPrice": 0.1265 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000R", + "unitPrice": 0.11 + } + }, + "canadaeast": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000K", + "unitPrice": 0.275 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000M", + "unitPrice": 0.1265 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000W", + "unitPrice": 0.11 + } + }, + "centralindia": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000X", + "unitPrice": 0.285 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000B", + "unitPrice": 0.1311 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000K", + "unitPrice": 0.114 + } + }, + "centralus": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000L", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000P", + "unitPrice": 0.138 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/0008", + "unitPrice": 0.12 + } + }, + "eastasia": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0018", + "unitPrice": 0.375 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000X", + "unitPrice": 0.1725 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/0010", + "unitPrice": 0.15 + } + }, + "eastus": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000M", + "unitPrice": 0.25 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0018", + "unitPrice": 0.115 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/0006", + "unitPrice": 0.1 + } + }, + "eastus2": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0002", + "unitPrice": 0.25 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000T", + "unitPrice": 0.115 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/0007", + "unitPrice": 0.1 + } + }, + "francecentral": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000T", + "unitPrice": 0.313 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000J", + "unitPrice": 0.14375 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000M", + "unitPrice": 0.1 + } + }, + "francesouth": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000S", + "unitPrice": 0.406 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000K", + "unitPrice": 0.186875 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000L", + "unitPrice": 0.1 + } + }, + "germanynorth": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/001S", + "unitPrice": 0.387 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/001R", + "unitPrice": 0.178 + } + }, + "germanywestcentral": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/001R", + "unitPrice": 0.2975 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/001S", + "unitPrice": 0.137 + } + }, + "israelcentral": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0050", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0051", + "unitPrice": 0.1518 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/001X", + "unitPrice": 0.1309 + } + }, + "italynorth": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/004Z", + "unitPrice": 0.2975 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0050", + "unitPrice": 0.13685 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/001W", + "unitPrice": 0.119 + } + }, + "japaneast": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0011", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000D", + "unitPrice": 0.138 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000G", + "unitPrice": 0.12 + } + }, + "japanwest": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0016", + "unitPrice": 0.33 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000C", + "unitPrice": 0.1518 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000F", + "unitPrice": 0.132 + } + }, + "jioindiacentral": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0024", + "unitPrice": 0.285 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0024", + "unitPrice": 0.1311 + } + }, + "jioindiawest": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0025", + "unitPrice": 0.285 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0025", + "unitPrice": 0.1311 + } + }, + "koreacentral": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0012", + "unitPrice": 0.295 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000Q", + "unitPrice": 0.1357 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000D", + "unitPrice": 0.118 + } + }, + "koreasouth": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0015", + "unitPrice": 0.295 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0013", + "unitPrice": 0.1357 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000B", + "unitPrice": 0.118 + } + }, + "mexicocentral": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0051", + "unitPrice": 0.275 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0052", + "unitPrice": 0.1265 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/001Z", + "unitPrice": 0.11 + } + }, + "newzealandnorth": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/00D6", + "unitPrice": 0.315 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/00DB", + "unitPrice": 0.1449 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/0024", + "unitPrice": 0.126 + } + }, + "northcentralus": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000N", + "unitPrice": 0.25 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0011", + "unitPrice": 0.115 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/0004", + "unitPrice": 0.1 + } + }, + "northeurope": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0014", + "unitPrice": 0.275 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0012", + "unitPrice": 0.1265 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000P", + "unitPrice": 0.11 + } + }, + "norwayeast": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/001W", + "unitPrice": 0.3272 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/001X", + "unitPrice": 0.151 + } + }, + "norwaywest": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/001X", + "unitPrice": 0.4254 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/001W", + "unitPrice": 0.196 + } + }, + "polandcentral": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/002G", + "unitPrice": 0.32725 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/002G", + "unitPrice": 0.150535 + } + }, + "qatarcentral": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/002F", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/002F", + "unitPrice": 0.1518 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/001S", + "unitPrice": 0.1309 + } + }, + "southafricanorth": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/001L", + "unitPrice": 0.335 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/001N", + "unitPrice": 0.154 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/0018", + "unitPrice": 0.134 + } + }, + "southafricawest": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/001K", + "unitPrice": 0.42 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/001M", + "unitPrice": 0.193 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/0017", + "unitPrice": 0.168 + } + }, + "southcentralus": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0004", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000V", + "unitPrice": 0.138 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/0005", + "unitPrice": 0.12 + } + }, + "southeastasia": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000W", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0007", + "unitPrice": 0.138 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000Z", + "unitPrice": 0.12 + } + }, + "southindia": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0010", + "unitPrice": 0.313 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0016", + "unitPrice": 0.14375 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000J", + "unitPrice": 0.125 + } + }, + "spaincentral": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/00D4", + "unitPrice": 0.2975 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/00D6", + "unitPrice": 0.13685 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/0023", + "unitPrice": 0.119 + } + }, + "swedencentral": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/002B", + "unitPrice": 0.2975 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/002B", + "unitPrice": 0.13685 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/001P", + "unitPrice": 0.119 + } + }, + "swedensouth": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0029", + "unitPrice": 0.38675 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0029", + "unitPrice": 0.177905 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/001N", + "unitPrice": 0.1547 + } + }, + "switzerlandnorth": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/001Q", + "unitPrice": 0.357 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/001P", + "unitPrice": 0.164 + } + }, + "switzerlandwest": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/001P", + "unitPrice": 0.425333 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/001Q", + "unitPrice": 0.195512 + } + }, + "uaecentral": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/001N", + "unitPrice": 0.39 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/001B", + "unitPrice": 0.1932 + } + }, + "uaenorth": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/001M", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0019", + "unitPrice": 0.1518 + } + }, + "uksouth": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000B", + "unitPrice": 0.288 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000N", + "unitPrice": 0.13225 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/0009", + "unitPrice": 0.115 + } + }, + "ukwest": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000C", + "unitPrice": 0.288 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000G", + "unitPrice": 0.13225 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000C", + "unitPrice": 0.115 + } + }, + "usgovarizona": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000H", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0004", + "unitPrice": 0.14375 + } + }, + "usgovtexas": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000J", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0002", + "unitPrice": 0.138 + } + }, + "usgovvirginia": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000G", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0006", + "unitPrice": 0.138 + } + }, + "westcentralus": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0005", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0009", + "unitPrice": 0.138 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/0002", + "unitPrice": 0.12 + } + }, + "westeurope": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0013", + "unitPrice": 0.2975 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0015", + "unitPrice": 0.13685 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000N", + "unitPrice": 0.119 + } + }, + "westindia": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/000Z", + "unitPrice": 0.285 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0010", + "unitPrice": 0.1311 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/000H", + "unitPrice": 0.114 + } + }, + "westus": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0003", + "unitPrice": 0.3 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000Z", + "unitPrice": 0.138 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/0001", + "unitPrice": 0.12 + } + }, + "westus2": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0006", + "unitPrice": 0.25 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/000W", + "unitPrice": 0.115 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/0003", + "unitPrice": 0.1 + } + }, + "westus3": { + "BusinessCritical": { + "sku": "DZH318Z0BQDX/0026", + "unitPrice": 0.25 + }, + "GeneralPurpose": { + "sku": "DZH318Z0BQCS/0026", + "unitPrice": 0.115 + }, + "Hyperscale": { + "sku": "DZH318Z0BXWW/001K", + "unitPrice": 0.1 + } + } +} \ No newline at end of file diff --git a/data/azure/azure_vm_pricing.json b/data/azure/azure_vm_pricing.json index cef5ed582c..975e3503a6 100644 --- a/data/azure/azure_vm_pricing.json +++ b/data/azure/azure_vm_pricing.json @@ -398086,114 +398086,6 @@ "sku": "DZH318Z0D21D" } }, - "Standard D128ns v6": { - "Linux": { - "pricePerUnit": 9.354, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 15.242, - "pricePerUnitAHUB": 9.354, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D16ns v6": { - "Linux": { - "pricePerUnit": 1.169, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 1.905, - "pricePerUnitAHUB": 1.169, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D2ns v6": { - "Linux": { - "pricePerUnit": 0.146, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 0.238, - "pricePerUnitAHUB": 0.146, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D32ns v6": { - "Linux": { - "pricePerUnit": 2.339, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 3.811, - "pricePerUnitAHUB": 2.339, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D48ns v6": { - "Linux": { - "pricePerUnit": 3.508, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 5.716, - "pricePerUnitAHUB": 3.508, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D4ns v6": { - "Linux": { - "pricePerUnit": 0.292, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 0.476, - "pricePerUnitAHUB": 0.292, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D64ns v6": { - "Linux": { - "pricePerUnit": 4.677, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 7.621, - "pricePerUnitAHUB": 4.677, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D8ns v6": { - "Linux": { - "pricePerUnit": 0.585, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 0.953, - "pricePerUnitAHUB": 0.585, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D96ns v6": { - "Linux": { - "pricePerUnit": 7.016, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 11.432, - "pricePerUnitAHUB": 7.016, - "sku": "DZH318Z0M4ZQ" - } - }, "Standard_A0": { "Linux": { "pricePerUnit": 0.02, @@ -398986,6 +398878,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D128ns_v6": { + "Linux": { + "pricePerUnit": 9.354, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 15.242, + "pricePerUnitAHUB": 9.354, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D128s_v6": { "Linux": { "pricePerUnit": 6.451, @@ -399358,6 +399262,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D16ns_v6": { + "Linux": { + "pricePerUnit": 1.169, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 1.905, + "pricePerUnitAHUB": 1.169, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D16pds_v5": { "Linux": { "pricePerUnit": 0.723, @@ -399794,6 +399710,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D2ns_v6": { + "Linux": { + "pricePerUnit": 0.146, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 0.238, + "pricePerUnitAHUB": 0.146, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D2pds_v5": { "Linux": { "pricePerUnit": 0.0904, @@ -400230,6 +400158,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D32ns_v6": { + "Linux": { + "pricePerUnit": 2.339, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 3.811, + "pricePerUnitAHUB": 2.339, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D32pds_v5": { "Linux": { "pricePerUnit": 1.446, @@ -400654,6 +400594,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D48ns_v6": { + "Linux": { + "pricePerUnit": 3.508, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 5.716, + "pricePerUnitAHUB": 3.508, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D48pds_v5": { "Linux": { "pricePerUnit": 2.17, @@ -401066,6 +401018,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D4ns_v6": { + "Linux": { + "pricePerUnit": 0.292, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 0.476, + "pricePerUnitAHUB": 0.292, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D4pds_v5": { "Linux": { "pricePerUnit": 0.181, @@ -401502,6 +401466,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D64ns_v6": { + "Linux": { + "pricePerUnit": 4.677, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 7.621, + "pricePerUnitAHUB": 4.677, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D64pds_v5": { "Linux": { "pricePerUnit": 2.893, @@ -401902,6 +401878,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D8ns_v6": { + "Linux": { + "pricePerUnit": 0.585, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 0.953, + "pricePerUnitAHUB": 0.585, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D8pds_v5": { "Linux": { "pricePerUnit": 0.362, @@ -402254,6 +402242,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D96ns_v6": { + "Linux": { + "pricePerUnit": 7.016, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 11.432, + "pricePerUnitAHUB": 7.016, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D96pds_v6": { "Linux": { "pricePerUnit": 4.406, @@ -412474,114 +412474,6 @@ "sku": "DZH318Z0D21D" } }, - "Standard D128ns v6": { - "Linux": { - "pricePerUnit": 9.354, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 15.242, - "pricePerUnitAHUB": 9.354, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D16ns v6": { - "Linux": { - "pricePerUnit": 1.169, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 1.905, - "pricePerUnitAHUB": 1.169, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D2ns v6": { - "Linux": { - "pricePerUnit": 0.146, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 0.238, - "pricePerUnitAHUB": 0.146, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D32ns v6": { - "Linux": { - "pricePerUnit": 2.339, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 3.811, - "pricePerUnitAHUB": 2.339, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D48ns v6": { - "Linux": { - "pricePerUnit": 3.508, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 5.716, - "pricePerUnitAHUB": 3.508, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D4ns v6": { - "Linux": { - "pricePerUnit": 0.292, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 0.476, - "pricePerUnitAHUB": 0.292, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D64ns v6": { - "Linux": { - "pricePerUnit": 4.677, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 7.621, - "pricePerUnitAHUB": 4.677, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D8ns v6": { - "Linux": { - "pricePerUnit": 0.585, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 0.953, - "pricePerUnitAHUB": 0.585, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D96ns v6": { - "Linux": { - "pricePerUnit": 7.016, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 11.432, - "pricePerUnitAHUB": 7.016, - "sku": "DZH318Z0M4ZQ" - } - }, "Standard_A0": { "Linux": { "pricePerUnit": 0.02, @@ -413374,6 +413266,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D128ns_v6": { + "Linux": { + "pricePerUnit": 9.354, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 15.242, + "pricePerUnitAHUB": 9.354, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D128s_v6": { "Linux": { "pricePerUnit": 6.451, @@ -413746,6 +413650,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D16ns_v6": { + "Linux": { + "pricePerUnit": 1.169, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 1.905, + "pricePerUnitAHUB": 1.169, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D16pds_v5": { "Linux": { "pricePerUnit": 0.723, @@ -414182,6 +414098,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D2ns_v6": { + "Linux": { + "pricePerUnit": 0.146, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 0.238, + "pricePerUnitAHUB": 0.146, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D2pds_v5": { "Linux": { "pricePerUnit": 0.0904, @@ -414618,6 +414546,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D32ns_v6": { + "Linux": { + "pricePerUnit": 2.339, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 3.811, + "pricePerUnitAHUB": 2.339, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D32pds_v5": { "Linux": { "pricePerUnit": 1.446, @@ -415042,6 +414982,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D48ns_v6": { + "Linux": { + "pricePerUnit": 3.508, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 5.716, + "pricePerUnitAHUB": 3.508, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D48pds_v5": { "Linux": { "pricePerUnit": 2.17, @@ -415454,6 +415406,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D4ns_v6": { + "Linux": { + "pricePerUnit": 0.292, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 0.476, + "pricePerUnitAHUB": 0.292, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D4pds_v5": { "Linux": { "pricePerUnit": 0.181, @@ -415890,6 +415854,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D64ns_v6": { + "Linux": { + "pricePerUnit": 4.677, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 7.621, + "pricePerUnitAHUB": 4.677, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D64pds_v5": { "Linux": { "pricePerUnit": 2.893, @@ -416290,6 +416266,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D8ns_v6": { + "Linux": { + "pricePerUnit": 0.585, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 0.953, + "pricePerUnitAHUB": 0.585, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D8pds_v5": { "Linux": { "pricePerUnit": 0.362, @@ -416642,6 +416630,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D96ns_v6": { + "Linux": { + "pricePerUnit": 7.016, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 11.432, + "pricePerUnitAHUB": 7.016, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D96pds_v6": { "Linux": { "pricePerUnit": 4.406, @@ -472785,114 +472785,6 @@ "sku": "DZH318Z0CTQD" } }, - "Standard D128ns v6": { - "Linux": { - "pricePerUnit": 10.913, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 16.801, - "pricePerUnitAHUB": 10.913, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D16ns v6": { - "Linux": { - "pricePerUnit": 1.364, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 2.1, - "pricePerUnitAHUB": 1.364, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D2ns v6": { - "Linux": { - "pricePerUnit": 0.171, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 0.263, - "pricePerUnitAHUB": 0.171, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D32ns v6": { - "Linux": { - "pricePerUnit": 2.728, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 4.2, - "pricePerUnitAHUB": 2.728, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D48ns v6": { - "Linux": { - "pricePerUnit": 4.092, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 6.3, - "pricePerUnitAHUB": 4.092, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D4ns v6": { - "Linux": { - "pricePerUnit": 0.341, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 0.525, - "pricePerUnitAHUB": 0.341, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D64ns v6": { - "Linux": { - "pricePerUnit": 5.457, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 8.401, - "pricePerUnitAHUB": 5.457, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D8ns v6": { - "Linux": { - "pricePerUnit": 0.682, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 1.05, - "pricePerUnitAHUB": 0.682, - "sku": "DZH318Z0M4ZQ" - } - }, - "Standard D96ns v6": { - "Linux": { - "pricePerUnit": 8.185, - "pricePerUnitAHUB": null, - "sku": "DZH318Z0M4ZS" - }, - "Windows": { - "pricePerUnit": 12.601, - "pricePerUnitAHUB": 8.185, - "sku": "DZH318Z0M4ZQ" - } - }, "Standard_A0": { "Linux": { "pricePerUnit": 0.02, @@ -473685,6 +473577,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D128ns_v6": { + "Linux": { + "pricePerUnit": 10.913, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 16.801, + "pricePerUnitAHUB": 10.913, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D128s_v6": { "Linux": { "pricePerUnit": 7.526, @@ -474057,6 +473961,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D16ns_v6": { + "Linux": { + "pricePerUnit": 1.364, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 2.1, + "pricePerUnitAHUB": 1.364, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D16pds_v5": { "Linux": { "pricePerUnit": 0.848, @@ -474493,6 +474409,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D2ns_v6": { + "Linux": { + "pricePerUnit": 0.171, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 0.263, + "pricePerUnitAHUB": 0.171, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D2pds_v5": { "Linux": { "pricePerUnit": 0.106, @@ -474929,6 +474857,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D32ns_v6": { + "Linux": { + "pricePerUnit": 2.728, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 4.2, + "pricePerUnitAHUB": 2.728, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D32pds_v5": { "Linux": { "pricePerUnit": 1.696, @@ -475353,6 +475293,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D48ns_v6": { + "Linux": { + "pricePerUnit": 4.092, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 6.3, + "pricePerUnitAHUB": 4.092, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D48pds_v5": { "Linux": { "pricePerUnit": 2.544, @@ -475765,6 +475717,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D4ns_v6": { + "Linux": { + "pricePerUnit": 0.341, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 0.525, + "pricePerUnitAHUB": 0.341, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D4pds_v5": { "Linux": { "pricePerUnit": 0.212, @@ -476201,6 +476165,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D64ns_v6": { + "Linux": { + "pricePerUnit": 5.457, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 8.401, + "pricePerUnitAHUB": 5.457, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D64pds_v5": { "Linux": { "pricePerUnit": 3.392, @@ -476601,6 +476577,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D8ns_v6": { + "Linux": { + "pricePerUnit": 0.682, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 1.05, + "pricePerUnitAHUB": 0.682, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D8pds_v5": { "Linux": { "pricePerUnit": 0.424, @@ -476953,6 +476941,18 @@ "sku": "DZH318Z0LDQN" } }, + "Standard_D96ns_v6": { + "Linux": { + "pricePerUnit": 8.185, + "pricePerUnitAHUB": null, + "sku": "DZH318Z0M4ZS" + }, + "Windows": { + "pricePerUnit": 12.601, + "pricePerUnitAHUB": 8.185, + "sku": "DZH318Z0M4ZQ" + } + }, "Standard_D96pds_v6": { "Linux": { "pricePerUnit": 5.155, diff --git a/data/change_history/change_history.json b/data/change_history/change_history.json index 8f54356d08..c50fa5b05a 100644 --- a/data/change_history/change_history.json +++ b/data/change_history/change_history.json @@ -1,5 +1,317 @@ { "merged_prs": [ + { + "number": 2616, + "title": "POL-1330 New Policy: AWS Account Credentials", + "description": "### Description\r\n\r\nThis adds a new, unpublished policy template along with a custom meta parent. The purpose of this policy template is to test all of the various cross-account roles implied by an AWS credential to see if they were working as expected or not. Please see the README for more details.\r\n\r\n(A custom meta parent is used because the policy engine does not allow you to ignore_status on a signing error, so the meta parent will compare the aggregated incident results to the status of the child policies to determine if the API request succeeded or failed.)\r\n\r\n### Link to Example Applied Policy\r\n\r\nhttps://app.flexera.com/orgs/27018/automation/applied-policies/projects/119613?policyId=66fab44d7b7d1d58450a795e\r\n\r\n(Only one credential in the incident will say \"Passed\" because equivalent cross-account roles have *not*, in this instance, been created for the other AWS accounts. This result is the expected behavior in that scenario.)\r\n\r\n### Contribution Check List\r\n\r\n- [X] New functionality includes testing.\r\n- [X] New functionality has been documented in the README if applicable\r\n- [X] New functionality has been documented in CHANGELOG.MD\r\n", + "labels": [ + "READY-FOR-REVIEW", + "New Policy" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2616", + "created_at": "2024-09-11 17:47:08 UTC", + "merged_at": "2024-10-11 19:31:30 UTC", + "modified_files": [ + ".spellignore", + "automation/aws/aws_account_credentials/CHANGELOG.md", + "automation/aws/aws_account_credentials/META_README.md", + "automation/aws/aws_account_credentials/README.md", + "automation/aws/aws_account_credentials/aws_account_credentials.pt", + "automation/aws/aws_account_credentials/aws_account_credentials_meta_parent.pt", + "data/policy_permissions_list/master_policy_permissions_list.json", + "data/policy_permissions_list/master_policy_permissions_list.yaml", + "tools/policy_master_permission_generation/validated_policy_templates.yaml" + ] + }, + { + "number": 2746, + "title": "Update Active Policy List", + "description": "Update Active Policy List from GitHub Actions Workflow [Update Active Policy List](https://github.com/flexera-public/policy_templates/actions/runs/11297033895)", + "labels": [ + "automation", + "data" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2746", + "created_at": "2024-10-11 17:58:43 UTC", + "merged_at": "2024-10-11 18:15:10 UTC", + "modified_files": [ + "data/active_policy_list/active_policy_list.json" + ] + }, + { + "number": 2728, + "title": "POL-1379 Azure SQL MI Storage Pricing Automation", + "description": "### Description\r\n\r\nThis adds automation to gather Azure SQL MI Storage Pricing and updates the Azure SQL MI Storage policy template to use this pricing data. In most cases, this will not matter (the generic SQL DB storage pricing is the same in most cases), but this ensures that any deviations in storage pricing specific to SQL MI are accounted for.\r\n", + "labels": [ + "READY-FOR-REVIEW" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2728", + "created_at": "2024-10-08 13:00:27 UTC", + "merged_at": "2024-10-11 17:53:41 UTC", + "modified_files": [ + ".github/workflows/generate-azure-sqlmi-storage-pricing-json", + "cost/azure/rightsize_managed_sql_storage/CHANGELOG.md", + "cost/azure/rightsize_managed_sql_storage/azure_rightsize_managed_sql_storage.pt", + "cost/azure/rightsize_managed_sql_storage/azure_rightsize_managed_sql_storage_meta_parent.pt", + "data/azure/azure_sqlmi_storage_pricing.json", + "data/policy_permissions_list/master_policy_permissions_list.json", + "data/policy_permissions_list/master_policy_permissions_list.yaml", + "tools/cloud_data/azure/azure_sqlmi_storage_pricing.py" + ] + }, + { + "number": 2726, + "title": "POL-1375 Google Label Cardinality Report: BigQuery Fix", + "description": "### Description\r\n\r\nFixes an issue caused by the BigQuery API returning both the project ID and dataset ID in the \"id\" field when listing datasets. This caused errors when attempting to use this id to query for BigQuery tables in the dataset.\r\n\r\n### Link to Example Applied Policy\r\n\r\nhttps://app.flexera.com/orgs/6/automation/applied-policies/projects/7954?policyId=6703fa877b7d1d58450a95d5\r\nAlso tested in client environment where the error was occurring.\r\n\r\n### Contribution Check List\r\n\r\n- [X] New functionality includes testing.\r\n- [X] New functionality has been documented in the README if applicable\r\n- [X] New functionality has been documented in CHANGELOG.MD\r\n", + "labels": [ + "READY-FOR-REVIEW" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2726", + "created_at": "2024-10-07 15:06:41 UTC", + "merged_at": "2024-10-11 17:53:29 UTC", + "modified_files": [ + "data/policy_permissions_list/master_policy_permissions_list.json", + "data/policy_permissions_list/master_policy_permissions_list.yaml", + "operational/google/label_cardinality/CHANGELOG.md", + "operational/google/label_cardinality/google_label_cardinality.pt", + "operational/google/label_cardinality/google_label_cardinality_meta_parent.pt" + ] + }, + { + "number": 2744, + "title": "Update Active Policy List", + "description": "Update Active Policy List from GitHub Actions Workflow [Update Active Policy List](https://github.com/flexera-public/policy_templates/actions/runs/11293119945)", + "labels": [ + "automation", + "data" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2744", + "created_at": "2024-10-11 13:21:51 UTC", + "merged_at": "2024-10-11 13:22:34 UTC", + "modified_files": [ + "data/active_policy_list/active_policy_list.json" + ] + }, + { + "number": 2743, + "title": "POL-1382 Currency Conversion: Multiple Dimension Support", + "description": "### Description\r\n\r\nAdds support for multiple dimension filters for the `Currency Conversion` policy template.\r\n\r\n### Link to Example Applied Policy\r\n\r\nhttps://app.flexera.com/orgs/6/automation/applied-policies/projects/7954?policyId=67091efa98177e765e2c763a\r\n\r\n### Contribution Check List\r\n\r\n- [X] New functionality includes testing.\r\n- [X] New functionality has been documented in the README if applicable\r\n- [X] New functionality has been documented in CHANGELOG.MD\r\n", + "labels": [ + "READY-FOR-REVIEW" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2743", + "created_at": "2024-10-11 12:47:48 UTC", + "merged_at": "2024-10-11 13:18:16 UTC", + "modified_files": [ + "cost/flexera/cco/currency_conversion/CHANGELOG.md", + "cost/flexera/cco/currency_conversion/README.md", + "cost/flexera/cco/currency_conversion/currency_conversion.pt", + "data/policy_permissions_list/master_policy_permissions_list.json", + "data/policy_permissions_list/master_policy_permissions_list.yaml" + ] + }, + { + "number": 2742, + "title": "Update Policy Master Permissions List", + "description": "Update Policy Master Permissions List from GitHub Actions Workflow [Generate Policy Master Permissions JSON](https://github.com/flexera-public/policy_templates/actions/runs/11279629168)", + "labels": [ + "automation" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2742", + "created_at": "2024-10-10 18:12:08 UTC", + "merged_at": "2024-10-10 18:15:21 UTC", + "modified_files": [ + "data/policy_permissions_list/master_policy_permissions_list.json", + "data/policy_permissions_list/master_policy_permissions_list.yaml" + ] + }, + { + "number": 2678, + "title": "POL-1365 Update Policy Permissions Automation - support for crossed-dagger symbol", + "description": "### Description\r\n\r\n\r\nFor policy permissions in the Readme which have more than two different footnotes, we must use another symbol to differentiate them.\r\n\r\nCurrently we are using and asterisk and a dagger, but now we have an example of a readme where the permissions have 3 different types of footnotes and therefore this is a change to add the crossed-dagger footnote symbol.\r\n\r\nAlso, this makes a change to the Dangerfile so that the Pull Request checks also support the new symbol (as well as the existing dagger symbol)\r\n\r\n### Issues Resolved\r\n\r\n\r\n\r\n### Link to Example Applied Policy\r\n\r\n\r\n\r\n\r\n### Contribution Check List\r\n\r\n- [x] New functionality includes testing.\r\n\r\nTested for a policy with AWS, Azure and Google Cloud permissions respectively\r\nTested for each symbol, and if the symbol exist for a permission, whether a footnote also exists\r\nExample:\r\n![image](https://github.com/user-attachments/assets/85cdeb54-b27b-46e9-a361-1c1f4aa85829)\r\n\r\n", + "labels": [ + "READY-FOR-REVIEW", + "automation" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2678", + "created_at": "2024-09-25 16:20:11 UTC", + "merged_at": "2024-10-10 18:11:49 UTC", + "modified_files": [ + ".dangerfile/readme_tests.rb", + "tools/policy_master_permission_generation/generate_policy_master_permissions.rb" + ] + }, + { + "number": 2712, + "title": "POL-1139 New Policy: AWS S3 Usage Type Rule-Based Dimension", + "description": "### Description\r\n\r\nThis new unpublished policy template, `AWS S3 Usage Type Rule-Based Dimension`, creates a single rule-based dimension based on the usage_type values for AWS S3. The intent is to provide a more general and human readable alternative to the built-in dimension, whose values tend to be very specific and not very human readable.\r\n\r\n### Link to Example Applied Policy\r\n\r\nhttps://app.flexera.com/orgs/28010/automation/applied-policies/projects/123559?policyId=66fe9287d1e796bae484f492\r\n\r\n### Contribution Check List\r\n\r\n- [X] New functionality includes testing.\r\n- [X] New functionality has been documented in the README if applicable\r\n- [X] New functionality has been documented in CHANGELOG.MD\r\n", + "labels": [ + "READY-FOR-REVIEW", + "New Policy" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2712", + "created_at": "2024-10-02 19:59:19 UTC", + "merged_at": "2024-10-10 18:09:28 UTC", + "modified_files": [ + ".spellignore", + "automation/aws/aws_s3_usage_type_rbd/CHANGELOG.md", + "automation/aws/aws_s3_usage_type_rbd/README.md", + "automation/aws/aws_s3_usage_type_rbd/aws_s3_usage_type_rbd.pt", + "data/policy_permissions_list/master_policy_permissions_list.json", + "data/policy_permissions_list/master_policy_permissions_list.yaml", + "tools/policy_master_permission_generation/validated_policy_templates.yaml" + ] + }, + { + "number": 2739, + "title": "POL-1381 Update AWS Instance Types JSON to include superseded instances for db.t family", + "description": "### Description\r\n\r\n\r\n- DB instances:\r\n - M family (e.g., db.t2 → db.t3)\r\n\r\n### Issues Resolved\r\n\r\n\r\nPotentially allows for testing the new AWS Superseded RDS Instances policy using RDS resources in existing Flexera One tenants.\r\n\r\n### Link to Example Applied Policy\r\n\r\n\r\n\r\n\r\n### Contribution Check List\r\n", + "labels": [ + "enhancement", + "READY-FOR-REVIEW", + "data" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2739", + "created_at": "2024-10-09 16:14:44 UTC", + "merged_at": "2024-10-10 14:35:44 UTC", + "modified_files": [ + "data/aws/instance_types.json" + ] + }, + { + "number": 2741, + "title": "Update Active Policy List", + "description": "Update Active Policy List from GitHub Actions Workflow [Update Active Policy List](https://github.com/flexera-public/policy_templates/actions/runs/11259804862)", + "labels": [ + "automation", + "data" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2741", + "created_at": "2024-10-09 17:15:03 UTC", + "merged_at": "2024-10-09 17:15:56 UTC", + "modified_files": [ + "data/active_policy_list/active_policy_list.json" + ] + }, + { + "number": 2740, + "title": "Update README Policy Table of Contents", + "description": "Update README Policy Table of Contents from GitHub Actions Workflow [Generate README Policy Table of Contents](https://github.com/flexera-public/policy_templates/actions/runs/11259785333)", + "labels": [ + "documentation", + "automation" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2740", + "created_at": "2024-10-09 17:11:48 UTC", + "merged_at": "2024-10-09 17:15:39 UTC", + "modified_files": [ + "README.md" + ] + }, + { + "number": 2702, + "title": "POL-1355 New Policy: AWS Rightsize ElastiCache", + "description": "### Description\r\n\r\nNew policy template to produce rightsizing recommendations for AWS ElastiCache clusters. See README for more details.\r\n\r\n### Link to Example Applied Policy\r\n\r\nhttps://app.flexera.com/orgs/6/automation/applied-policies/projects/7954?policyId=66fbec91d1e796bae484f05b\r\n(Also tested in client environment with actual results/incident)\r\n\r\n### Contribution Check List\r\n\r\n- [X] New functionality includes testing.\r\n- [X] New functionality has been documented in the README if applicable\r\n- [X] New functionality has been documented in CHANGELOG.MD\r\n", + "labels": [ + "READY-FOR-REVIEW", + "New Policy" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2702", + "created_at": "2024-10-01 12:28:01 UTC", + "merged_at": "2024-10-09 17:11:27 UTC", + "modified_files": [ + ".spellignore", + "cost/aws/rightsize_elasticache/CHANGELOG.md", + "cost/aws/rightsize_elasticache/README.md", + "cost/aws/rightsize_elasticache/aws_rightsize_elasticache.pt", + "cost/aws/rightsize_elasticache/aws_rightsize_elasticache_meta_parent.pt", + "data/policy_permissions_list/master_policy_permissions_list.json", + "data/policy_permissions_list/master_policy_permissions_list.yaml", + "tools/meta_parent_policy_compiler/meta_parent_policy_compiler.rb", + "tools/policy_master_permission_generation/validated_policy_templates.yaml" + ] + }, + { + "number": 2709, + "title": "POL-1374 Email Cost Optimization Recommendations: Added Policy Support", + "description": "### Description\r\n\r\nUpdates to Email Cost Optimization Recommendations. From the CHANGELOG:\r\n\r\n- Added support for additional recommendation policy templates\r\n- Changed \"Disks\" option to \"Storage\" for `Recommendation List` parameter to better reflect functionality\r\n- Added \"PaaS\" option to `Recommendation List` parameter\r\n\r\n### Link to Example Applied Policy\r\n\r\nhttps://app.flexera.com/orgs/6/automation/applied-policies/projects/7954?policyId=66fd8bd0d1e796bae484f33d\r\n\r\n### Contribution Check List\r\n\r\n- [X] New functionality includes testing.\r\n- [X] New functionality has been documented in the README if applicable\r\n- [X] New functionality has been documented in CHANGELOG.MD\r\n", + "labels": [ + "READY-FOR-REVIEW" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2709", + "created_at": "2024-10-02 18:03:06 UTC", + "merged_at": "2024-10-09 17:11:10 UTC", + "modified_files": [ + "cost/flexera/cco/email_recommendations/CHANGELOG.md", + "cost/flexera/cco/email_recommendations/email_recommendations.pt", + "data/policy_permissions_list/master_policy_permissions_list.json", + "data/policy_permissions_list/master_policy_permissions_list.yaml" + ] + }, + { + "number": 2721, + "title": "POL-1377 Cloud Bill Processing Error Notification: Fixes/Improvements", + "description": "### Description\r\n\r\nFixes for `Cloud Bill Processing Error Notification`. From the CHANGELOG:\r\n\r\n- Updated some API requests to use newer internal Flexera API\r\n- Fixed error that sometimes caused functioning bill connections to appear in results\r\n- Fixed error that sometimes caused the policy template to fail\r\n- Modified incident table to include more useful information\r\n\r\n### Link to Example Applied Policy\r\n\r\nhttps://app.flexera.com/orgs/27018/automation/applied-policies/projects/119613?policyId=67003ae77b7d1d58450a90b4\r\n(Also tested in client environment where error was originally reported)\r\n\r\n### Contribution Check List\r\n\r\n- [X] New functionality includes testing.\r\n- [X] New functionality has been documented in the README if applicable\r\n- [X] New functionality has been documented in CHANGELOG.MD\r\n", + "labels": [ + "READY-FOR-REVIEW" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2721", + "created_at": "2024-10-04 18:57:48 UTC", + "merged_at": "2024-10-09 17:10:55 UTC", + "modified_files": [ + "data/policy_permissions_list/master_policy_permissions_list.json", + "data/policy_permissions_list/master_policy_permissions_list.yaml", + "operational/flexera/cco/bill_processing_errors_notification/CHANGELOG.md", + "operational/flexera/cco/bill_processing_errors_notification/bill_processing_errors_notification.pt" + ] + }, + { + "number": 2725, + "title": "Update Azure VM Pricing Data", + "description": "Updated Azure VM Pricing from GitHub Actions Workflow [Generate Azure VM Pricing JSON](https://github.com/flexera-public/policy_templates/actions/runs/11199097360)", + "labels": [ + "automation", + "data", + "azure" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2725", + "created_at": "2024-10-06 05:07:24 UTC", + "merged_at": "2024-10-07 08:42:08 UTC", + "modified_files": [ + "data/azure/azure_vm_pricing.json" + ] + }, + { + "number": 2724, + "title": "Update Azure MD Pricing Data", + "description": "Updated Azure MD Pricing from GitHub Actions Workflow [Generate Azure MD Pricing JSON](https://github.com/flexera-public/policy_templates/actions/runs/11198779928)", + "labels": [ + "automation", + "data", + "azure" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2724", + "created_at": "2024-10-06 04:03:32 UTC", + "merged_at": "2024-10-07 08:41:40 UTC", + "modified_files": [ + "data/azure/azure_md_pricing.json" + ] + }, + { + "number": 2723, + "title": "Update Change History", + "description": "Update Change History from GitHub Actions Workflow [Update Change History](https://github.com/flexera-public/policy_templates/actions/runs/11197851190)", + "labels": [ + "automation" + ], + "href": "https://github.com/flexera-public/policy_templates/pull/2723", + "created_at": "2024-10-06 01:37:37 UTC", + "merged_at": "2024-10-07 08:41:10 UTC", + "modified_files": [ + "HISTORY.md", + "data/change_history/change_history.json" + ] + }, { "number": 2720, "title": "Update Active Policy List", diff --git a/data/policy_permissions_list/master_policy_permissions_list.json b/data/policy_permissions_list/master_policy_permissions_list.json index 5d1d500d8a..e49383c375 100644 --- a/data/policy_permissions_list/master_policy_permissions_list.json +++ b/data/policy_permissions_list/master_policy_permissions_list.json @@ -1,5 +1,32 @@ { "values": [ + { + "id": "./automation/aws/aws_account_credentials/aws_account_credentials.pt", + "name": "AWS Account Credentials", + "version": "0.1.0", + "providers": [ + { + "name": "aws", + "permissions": [ + { + "name": "sts:GetCallerIdentity", + "read_only": true, + "required": true + } + ] + }, + { + "name": "flexera", + "permissions": [ + { + "name": "billing_center_viewer", + "read_only": true, + "required": true + } + ] + } + ] + }, { "id": "./automation/aws/aws_missing_regions/aws_missing_regions.pt", "name": "AWS Missing Regions", @@ -64,6 +91,33 @@ } ] }, + { + "id": "./automation/aws/aws_s3_usage_type_rbd/aws_s3_usage_type_rbd.pt", + "name": "AWS S3 Usage Type Rule-Based Dimension", + "version": "0.1.0", + "providers": [ + { + "name": "flexera", + "permissions": [ + { + "name": "observer", + "read_only": true, + "required": true + }, + { + "name": "billing_center_viewer", + "read_only": true, + "required": true + }, + { + "name": "rule_based_dimensions_manager", + "read_only": true, + "required": true + } + ] + } + ] + }, { "id": "./automation/azure/azure_missing_subscriptions/azure_missing_subscriptions.pt", "name": "Azure Missing Subscriptions", @@ -2638,12 +2692,14 @@ { "name": "kms:CreateGrant", "read_only": true, - "required": true + "required": false, + "description": "Only required if using Customer Managed KMS Key on Volumes mounted by EC2 Instance(s)" }, { "name": "kms:Decrypt", "read_only": true, - "required": true + "required": false, + "description": "Only required if using Customer Managed KMS Key on Volumes mounted by EC2 Instance(s)" }, { "name": "ec2:CreateTags", @@ -3704,7 +3760,7 @@ { "id": "./cost/azure/rightsize_managed_sql_storage/azure_rightsize_managed_sql_storage.pt", "name": "Azure Rightsize SQL Managed Instance Storage", - "version": "0.1.0", + "version": "0.2.0", "providers": [ { "name": "azure_rm", @@ -4700,7 +4756,7 @@ { "id": "./cost/flexera/cco/currency_conversion/currency_conversion.pt", "name": "Currency Conversion", - "version": "4.0.0", + "version": "5.0.0", "providers": [ { "name": "flexera", @@ -6793,7 +6849,7 @@ { "id": "./operational/google/label_cardinality/google_label_cardinality.pt", "name": "Google Label Cardinality Report", - "version": "0.1.0", + "version": "0.1.1", "providers": [ { "name": "gce", diff --git a/data/policy_permissions_list/master_policy_permissions_list.yaml b/data/policy_permissions_list/master_policy_permissions_list.yaml index de2fea3f0e..d29ce2e226 100644 --- a/data/policy_permissions_list/master_policy_permissions_list.yaml +++ b/data/policy_permissions_list/master_policy_permissions_list.yaml @@ -1,5 +1,19 @@ --- :values: +- id: "./automation/aws/aws_account_credentials/aws_account_credentials.pt" + name: AWS Account Credentials + version: 0.1.0 + :providers: + - :name: aws + :permissions: + - name: sts:GetCallerIdentity + read_only: true + required: true + - :name: flexera + :permissions: + - name: billing_center_viewer + read_only: true + required: true - id: "./automation/aws/aws_missing_regions/aws_missing_regions.pt" name: AWS Missing Regions version: 0.2.0 @@ -35,6 +49,21 @@ - name: rule_based_dimensions_manager read_only: true required: true +- id: "./automation/aws/aws_s3_usage_type_rbd/aws_s3_usage_type_rbd.pt" + name: AWS S3 Usage Type Rule-Based Dimension + version: 0.1.0 + :providers: + - :name: flexera + :permissions: + - name: observer + read_only: true + required: true + - name: billing_center_viewer + read_only: true + required: true + - name: rule_based_dimensions_manager + read_only: true + required: true - id: "./automation/azure/azure_missing_subscriptions/azure_missing_subscriptions.pt" name: Azure Missing Subscriptions version: '0.1' @@ -1513,10 +1542,14 @@ required: true - name: kms:CreateGrant read_only: true - required: true + required: false + description: Only required if using Customer Managed KMS Key on Volumes mounted + by EC2 Instance(s) - name: kms:Decrypt read_only: true - required: true + required: false + description: Only required if using Customer Managed KMS Key on Volumes mounted + by EC2 Instance(s) - name: ec2:CreateTags read_only: true required: false @@ -2148,7 +2181,7 @@ required: true - id: "./cost/azure/rightsize_managed_sql_storage/azure_rightsize_managed_sql_storage.pt" name: Azure Rightsize SQL Managed Instance Storage - version: 0.1.0 + version: 0.2.0 :providers: - :name: azure_rm :permissions: @@ -2718,7 +2751,7 @@ required: true - id: "./cost/flexera/cco/currency_conversion/currency_conversion.pt" name: Currency Conversion - version: 4.0.0 + version: 5.0.0 :providers: - :name: flexera :permissions: @@ -3939,7 +3972,7 @@ required: true - id: "./operational/google/label_cardinality/google_label_cardinality.pt" name: Google Label Cardinality Report - version: 0.1.0 + version: 0.1.1 :providers: - :name: gce :permissions: diff --git a/operational/google/label_cardinality/CHANGELOG.md b/operational/google/label_cardinality/CHANGELOG.md index a1ed544621..bef2975fd9 100644 --- a/operational/google/label_cardinality/CHANGELOG.md +++ b/operational/google/label_cardinality/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v0.1.1 + +- Fixed issue where policy template execution would not complete if BigQuery datasets were found + ## v0.1.0 - Initial release diff --git a/operational/google/label_cardinality/google_label_cardinality.pt b/operational/google/label_cardinality/google_label_cardinality.pt index 573fd9832d..c6f2c5b9c6 100644 --- a/operational/google/label_cardinality/google_label_cardinality.pt +++ b/operational/google/label_cardinality/google_label_cardinality.pt @@ -7,7 +7,7 @@ category "Operational" severity "low" default_frequency "weekly" info( - version: "0.1.0", + version: "0.1.1", provider: "Google", service: "Tags", policy_set: "Tag Cardinality" @@ -333,10 +333,10 @@ datasource "ds_google_bigquery_datasets" do result do encoding "json" collect jmes_path(response, "datasets[*]") do - field "id", jmes_path(col_item, "id") - field "name", jmes_path(col_item, "id") + field "id", get(1, split(jmes_path(col_item, "id"), ':')) + field "name", get(1, split(jmes_path(col_item, "id"), ':')) field "labels", jmes_path(col_item, "labels") - field "selfLink", join(["/bigquery/v2/projects/", val(iter_item, "id"), "/datasets/", jmes_path(col_item, "id")]) + field "selfLink", join(["/bigquery/v2/projects/", val(iter_item, "id"), "/datasets/", get(1, split(jmes_path(col_item, "id"), ':'))]) field "type", "bigquery.datasets" field "projectId", val(iter_item, "id") field "projectName", val(iter_item, "name") diff --git a/operational/google/label_cardinality/google_label_cardinality_meta_parent.pt b/operational/google/label_cardinality/google_label_cardinality_meta_parent.pt index 7920585922..3ac980eafb 100644 --- a/operational/google/label_cardinality/google_label_cardinality_meta_parent.pt +++ b/operational/google/label_cardinality/google_label_cardinality_meta_parent.pt @@ -7,7 +7,7 @@ category "Meta" default_frequency "15 minutes" info( provider: "Google", - version: "0.1.0", # This version of the Meta Parent Policy Template should match the version of the Child Policy Template as it appears in the Catalog for best reliability + version: "0.1.1", # This version of the Meta Parent Policy Template should match the version of the Child Policy Template as it appears in the Catalog for best reliability publish: "true", deprecated: "false" ) diff --git a/tools/cloud_data/azure/azure_sqlmi_storage_pricing.py b/tools/cloud_data/azure/azure_sqlmi_storage_pricing.py new file mode 100644 index 0000000000..f85d627b8a --- /dev/null +++ b/tools/cloud_data/azure/azure_sqlmi_storage_pricing.py @@ -0,0 +1,64 @@ +# Instructions for updating the price list: +# (1) Download the flexera-public/policy_templates repository locally. +# (2) Create a new local branch of the repository. +# (3) Run this Python script. It should replace azure_sqlmi_storage_pricing.json with a new updated file. +# Note: Working directory should be the *root* directory of the repository. +# (4) Add and commit the new file, push it to the repository, and then make a pull request. + +import requests +import json +import os + +print("Gathering data from Azure Price API...") + +output_filename = f'data/azure/azure_sqlmi_storage_pricing.json' + +api_url = "https://prices.azure.com/api/retail/prices" +query = "unitOfMeasure eq '1 GB/Month' and serviceName eq 'SQL Managed Instance' and type eq 'Consumption' and (skuName eq 'General Purpose' or skuName eq 'Business Critical' or skuName eq 'Hyperscale')" +response = requests.get(api_url, params={'$filter': query}) +json_data = response.json() + +price_list = json_data['Items'] +nextPage = json_data['NextPageLink'] + +while(nextPage): + response = requests.get(nextPage) + json_data = response.json() + nextPage = json_data['NextPageLink'] + price_list.extend(json_data['Items']) + +final_list = {} + +print("Processing data from Azure Price API...") + +for item in price_list: + region = item['armRegionName'] + skuName = item['skuName'] + skuId = item['skuId'] + unitPrice = item['unitPrice'] + productName = item['productName'] + meterName = item['meterName'] + + # This is so the values match what other Azure APIs return for these sku names + if skuName == "Business Critical": + skuName = "BusinessCritical" + + if skuName == "General Purpose": + skuName = "GeneralPurpose" + + if "Free" not in meterName and unitPrice != 0.0: + if region not in final_list: + final_list[region] = {} + + final_list[region][skuName] = { + "sku": skuId, + "unitPrice": unitPrice + } + +print("Writing results to file...") + +price_file = open(output_filename, "w") +price_file.write(json.dumps(final_list, sort_keys=True, indent=2)) +price_file.close() + +print("DONE!") diff --git a/tools/policy_master_permission_generation/generate_policy_master_permissions.rb b/tools/policy_master_permission_generation/generate_policy_master_permissions.rb index 188c32f30b..84a5d747d2 100644 --- a/tools/policy_master_permission_generation/generate_policy_master_permissions.rb +++ b/tools/policy_master_permission_generation/generate_policy_master_permissions.rb @@ -99,9 +99,8 @@ def extract_permissions_from_readme(readme_content) # Extract the text from this section section_text = readme_content[section_start..-1] - # Find the line starting with '/*' or '†' to get any specific notes around permissions from the README + # Find the line starting with '/*', '†', '‡', '§', '‖' or '¶' to get any specific notes around permissions from the README list_of_notes = [] - # note = "" section_text.each_line do |line| break if line.strip.start_with?( "##", "###", "- [**") && !line.strip.start_with?(section) @@ -111,6 +110,18 @@ def extract_permissions_from_readme(readme_content) elsif line.strip.start_with?("\u2020") dagger_note = line.strip.sub(/^\†\s*/, '') list_of_notes << { symbol: "†", detail: dagger_note } + elsif line.strip.start_with?("\u2021") + cross_dagger_note = line.strip.sub(/^\‡\s*/, '') + list_of_notes << { symbol: "‡", detail: cross_dagger_note } + elsif line.strip.start_with?("\u00a7") + section_note = line.strip.sub(/^\§\s*/, '') + list_of_notes << { symbol: "§", detail: section_note } + elsif line.strip.start_with?("\u2016") + vertical_bar_note = line.strip.sub(/^\‖\s*/, '') + list_of_notes << { symbol: "‖", detail: vertical_bar_note } + elsif line.strip.start_with?("\u00b6") + pilcrow_note = line.strip.sub(/^\¶\s*/, '') + list_of_notes << { symbol: "¶", detail: pilcrow_note } end end diff --git a/tools/policy_master_permission_generation/validated_policy_templates.yaml b/tools/policy_master_permission_generation/validated_policy_templates.yaml index cd9b6e34d4..ae2bae3c95 100644 --- a/tools/policy_master_permission_generation/validated_policy_templates.yaml +++ b/tools/policy_master_permission_generation/validated_policy_templates.yaml @@ -4,8 +4,10 @@ # - The `data/policy_permissions_list/master_policy_permissions_list` datasets contains all permissions from the README.md -- this confirms generate_policy_master_permissions.rb script parses README as expected validated_policy_templates: # AWS +- "./automation/aws/aws_account_credentials/aws_account_credentials.pt" - "./automation/aws/aws_missing_regions/aws_missing_regions.pt" - "./automation/aws/aws_rbd_from_tag/aws_rbd_from_tag.pt" +- "./automation/aws/aws_s3_usage_type_rbd/aws_s3_usage_type_rbd.pt" - "./compliance/aws/disallowed_regions/aws_disallowed_regions.pt" - "./compliance/aws/ecs_unused/aws_unused_ecs_clusters.pt" - "./compliance/aws/iam_role_audit/aws_iam_role_audit.pt"