Skip to content

Commit

Permalink
add Kubecost Proactive Cost Control (#893)
Browse files Browse the repository at this point in the history
Signed-off-by: chipzoller <chipzoller@gmail.com>
  • Loading branch information
chipzoller authored Jan 23, 2024
1 parent b5bac67 commit 7f44dc8
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
21 changes: 21 additions & 0 deletions kubecost/kubecost-proactive-cost-control/artifacthub-pkg.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: kubecost-proactive-cost-control
version: 1.0.0
displayName: Kubecost Proactive Cost Control
createdAt: "2024-01-23T00:00:00.000Z"
description: >-
Kubecost Enterprise allows users to define budgets for Namespaces and clusters as well as predict the cost of new Deployments based on historical cost data. By combining these abilities, users can achieve proactive cost controls for clusters with Kubecost installed by denying Deployments which would exceed the remaining configured monthly budget, if applicable. This policy checks for the creation of Deployments and compares the predicted cost of the Deployment to the remaining amount in the monthly budget, if one is found. If the predicted cost is greater than the remaining budget, the Deployment is denied. This policy requires Kubecost Enterprise at a version of 1.108 or greater.
install: |-
```shell
kubectl apply -f https://raw.githubusercontent.com/kyverno/policies/main/kubecost/kubecost-proactive-cost-control/kubecost-proactive-cost-control.yaml
```
keywords:
- kyverno
- Kubecost
readme: |
Kubecost Enterprise allows users to define budgets for Namespaces and clusters as well as predict the cost of new Deployments based on historical cost data. By combining these abilities, users can achieve proactive cost controls for clusters with Kubecost installed by denying Deployments which would exceed the remaining configured monthly budget, if applicable. This policy checks for the creation of Deployments and compares the predicted cost of the Deployment to the remaining amount in the monthly budget, if one is found. If the predicted cost is greater than the remaining budget, the Deployment is denied. This policy requires Kubecost Enterprise at a version of 1.108 or greater.
Refer to the documentation for more details on Kyverno annotations: https://artifacthub.io/docs/topics/annotations/kyverno/
annotations:
kyverno/category: "Kubecost"
kyverno/subject: "Deployment"
digest: 383e8d5e2c7eecaab112316bd915fd4e0d976d579ddc07543c1540fbe59aa704
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: kubecost-proactive-cost-control
annotations:
policies.kyverno.io/title: Kubecost Proactive Cost Control
policies.kyverno.io/category: Kubecost
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Deployment
policies.kyverno.io/minversion: 1.11.0
kyverno.io/kyverno-version: 1.11.4
kyverno.io/kubernetes-version: "1.26"
policies.kyverno.io/description: >-
Kubecost Enterprise allows users to define budgets for Namespaces and clusters
as well as predict the cost of new Deployments based on historical cost data.
By combining these abilities, users can achieve proactive cost controls for
clusters with Kubecost installed by denying Deployments which would exceed the
remaining configured monthly budget, if applicable. This policy checks for the creation of
Deployments and compares the predicted cost of the Deployment to the remaining amount
in the monthly budget, if one is found. If the predicted cost is greater than the remaining
budget, the Deployment is denied. This policy requires Kubecost Enterprise
at a version of 1.108 or greater.
spec:
validationFailureAction: Audit
rules:
- name: enforce-monthly-namespace-budget
match:
any:
- resources:
kinds:
- Deployment
operations:
- CREATE
# First, check if this Namespace is subject to a budget.
# If it is not, always allow the Deployment.
preconditions:
all:
- key: "{{ budget }}"
operator: NotEquals
value: nobudget
context:
# Get the budget of the destination Namespace. Select the first budget returned which matches the Namespace.
# If no budget is found, set budget to "nobudget".
- name: budget
apiCall:
method: GET
service:
url: http://kubecost-cost-analyzer.kubecost:9090/model/budgets
jmesPath: "data[?values.namespace[?contains(@,'{{ request.namespace }}')]] | [0] || 'nobudget'"
# Call the prediction API and pass it the Deployment from the admission request. Extract the totalMonthlyRate.
- name: predictedMonthlyCost
apiCall:
method: POST
data:
- key: apiVersion
value: "{{ request.object.apiVersion }}"
- key: kind
value: "{{ request.object.kind }}"
- key: spec
value: "{{ request.object.spec }}"
service:
url: http://kubecost-cost-analyzer.kubecost:9090/model/prediction/speccost?clusterID=cluster-one&defaultNamespace=default
jmesPath: "[0].costChange.totalMonthlyRate"
# Calculate the budget that remains from the window by subtracting the currentSpend from the spendLimit.
- name: remainingBudget
variable:
jmesPath: subtract(budget.spendLimit,budget.currentSpend)
validate:
message: >-
This Deployment, which costs ${{ round(predictedMonthlyCost, `2`) }} to run for a month,
will overrun the remaining budget of ${{ round(remainingBudget,`2`) }}. Please seek approval or request
a Policy Exception.
# Deny the request if the predictedMonthlyCost is greater than the remainingBudget.
deny:
conditions:
all:
- key: "{{ predictedMonthlyCost }}"
operator: GreaterThan
value: "{{ remainingBudget }}"

0 comments on commit 7f44dc8

Please sign in to comment.