Skip to content

Commit 598cb27

Browse files
authoredMar 10, 2025··
Merge pull request #278 from stakater/SA-7086-AWS-Opencost-docs
AWS Cloud Cost Pricing docs [SA-7086]
2 parents b038e67 + d3a1f67 commit 598cb27

File tree

6 files changed

+223
-83
lines changed

6 files changed

+223
-83
lines changed
 

‎content/changelog.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#### Features
88

9-
- Added [Azure Pricing](./integrations/azure-pricing.md) support for Opencost via [Integration Config](./kubernetes-resources/integration-config.md#azure-pricing-model).
9+
- Added [Azure Pricing](./integrations/azure-pricing.md) support for Opencost via [Integration Config](./kubernetes-resources/integration-config.md#azure-pricing).
1010
- Added option to disable `Intra-tenant Networking` via [Integration Config](./kubernetes-resources/integration-config.md#tenantpolicies).
1111
- Added [Storage class per tenant](./kubernetes-resources/tenant/tenant-overview.md#storage) support via Tenant CR.
1212
- Added option to override component images.

‎content/installation/azure-aks.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# On AKS
22

3-
This document covers how to deploy Multi Tenant Operator with an [AKS (Azure Kubernetes Service)](https://azure.microsoft.com/en-us/products/kubernetes-service/) cluster.
3+
This document covers how to deploy Multi Tenant Operator with an AKS (Azure Kubernetes Service) cluster.
44

55
## Prerequisites
66

‎content/integrations/aws-pricing.md

+185
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# AWS Pricing
2+
3+
MTO supports AWS pricing model via the `integrationConfig.components.showbackOpts.cloudIntegrationSecretRef` field. Following 3 types of pricing are supported:
4+
5+
- [`AWS Standard Pricing`](#aws-standard-pricing)
6+
- [`AWS Spot Instance Datafeed`](#aws-spot-instance-pricing)
7+
8+
## AWS Standard Pricing
9+
10+
OpenCost will automatically read the node information `node.spec.providerID` to determine the cloud service provider (CSP) in use. If it detects the CSP is AWS, it will attempt to pull the AWS on-demand pricing from the configured public API URL with no further configuration required.
11+
12+
OpenCost will request pricing data from the `us-east-1` region for your `node_region` using the template:
13+
14+
```url
15+
https://pricing.us-east-1.amazonaws.com/offers/v1.0/aws/AmazonEC2/current/${node_region}/index.json
16+
```
17+
18+
## AWS Spot Instance Pricing
19+
20+
To enable the AWS Spot Instance pricing, subscribe to AWS Spot Instance Data Feed with the following command
21+
22+
```sh
23+
aws ec2 create-spot-datafeed-subscription \
24+
--bucket <BUCKET_NAME> \
25+
[--prefix <BUCKET_PREFIX>]
26+
```
27+
28+
- `<BUCKET_NAME>` — Name of the bucket Amazon S3 bucket to store the data feed files
29+
- `<BUCKET_PREFIX>` — Optional prefix directory in which data feed files will be stored
30+
31+
### Amazon S3 bucket requirements
32+
33+
When you subscribe to the data feed, you must specify an Amazon S3 bucket to store the data feed files.
34+
35+
Before you choose an Amazon S3 bucket for the data feed, consider the following:
36+
37+
- You must have `FULL_CONTROL` permission to the bucket. If you're the bucket owner, you have this permission by default. Otherwise, the bucket owner must grant your AWS account this permission.
38+
39+
- When you subscribe to a data feed, these permissions are used to update the bucket ACL to give the AWS data feed account `FULL_CONTROL` permission. The AWS data feed account writes data feed files to the bucket. If your account doesn't have the required permissions, the data feed files cannot be written to the bucket. For more information, see Logs sent to Amazon S3 in the Amazon CloudWatch Logs User Guide.
40+
41+
- If you update the ACL and remove the permissions for the AWS data feed account, the data feed files cannot be written to the bucket. You must resubscribe to the data feed to receive the data feed files.
42+
43+
- Each data feed file has its own ACL (separate from the ACL for the bucket). The bucket owner has `FULL_CONTROL` permission to the data files. The AWS data feed account has read and write permissions.
44+
45+
- If you delete your data feed subscription, Amazon EC2 doesn't remove the read and write permissions for the AWS data feed account on either the bucket or the data files. You must remove these permissions yourself.
46+
47+
- If you encrypt your Amazon S3 bucket using server-side encryption with an AWS KMS key stored in AWS Key Management Service (SSE-KMS), you must use a customer managed key. For more information, see Amazon S3 bucket server-side encryption in the Amazon CloudWatch Logs User Guide.
48+
49+
### Configure an IAM Policy
50+
51+
- Create a user or role for OpenCost with access to the spot feed bucket. Attach the policy below to the role/user and replace `<BUCKET_NAME>` with your spot bucket name
52+
53+
```json
54+
{
55+
"Version": "2012-10-17",
56+
"Statement": [
57+
{
58+
"Action": [
59+
"s3:ListAllMyBuckets",
60+
"s3:ListBucket",
61+
"s3:HeadBucket",
62+
"s3:HeadObject",
63+
"s3:List*",
64+
"s3:Get*"
65+
],
66+
"Resource": [
67+
"arn:aws:s3:::<BUCKET_NAME>"
68+
],
69+
"Effect": "Allow",
70+
"Sid": "SpotDataAccess"
71+
}
72+
]
73+
}
74+
```
75+
76+
### Option 1: Service Keys
77+
78+
Generate Access Keys with following steps
79+
80+
1. Navigate to the AWS IAM Console.
81+
1. Select Access Management > Users from the left navigation.
82+
1. Find the OpenCost User and select Security credentials > Create access key.
83+
1. Follow along to receive the Access Key ID and Secret Access Key (AWS will not provide you the Secret Access Key in the future, so make sure you save this value).
84+
85+
Create a `service-key.json` and replace the values with the user access keys
86+
87+
```json
88+
{
89+
"aws_access_key_id": "<ACCESS_KEY_ID>",
90+
"aws_secret_access_key": "<SECRET_ACCESS_KEY>"
91+
}
92+
```
93+
94+
Create a Kubernetes secret with the following command
95+
96+
```sh
97+
kubectl create secret generic <SECRET_NAME> --from-file=service-key.json --namespace multi-tenant-operator
98+
```
99+
100+
!!! note
101+
When managing the service account key as a Kubernetes secret, the secret must reference the service account key JSON file, and that file must be named `service-key.json`.
102+
103+
The data feed will provide specific pricing information about any Spot instances in your account on an hourly basis. After setting this up, the bucket information can be provided through options in the IntegrationConfig via `integrationConfig.components.showbackOpts.custom` object.
104+
105+
- `awsSpotDataBucket` - The name of the S3 bucket Spot Instance Data Feed is publishing to.
106+
- `awsSpotDataRegion` - The region configured for Spot Instance Data Feed
107+
- `awsSpotDataPrefix` - The prefix (if any) configured for Spot Instance Data Feed
108+
- `projectID` - The AWS Account ID
109+
- `<SECRET_NAME>` - Name of the service key secret created in previous step
110+
111+
Example:
112+
113+
```yaml
114+
components:
115+
showback: true # should be enabled
116+
showbackOpts:
117+
custom:
118+
provider: aws
119+
description: "AWS Provider Configuration. Provides default values used if instance type or spot information is not found."
120+
CPU: "0.031611"
121+
spotCPU: "0.006655"
122+
RAM: "0.004237"
123+
GPU: "0.95"
124+
spotRAM: "0.000892"
125+
storage: "0.000138888889"
126+
zoneNetworkEgress: "0.01"
127+
regionNetworkEgress: "0.01"
128+
internetNetworkEgress: "0.143"
129+
spotLabel: "kops.k8s.io/instancegroup"
130+
spotLabelValue: "spotinstance-nodes"
131+
awsSpotDataRegion: "us-east-2"
132+
awsSpotDataBucket: "my-spot-bucket"
133+
awsSpotDataPrefix: "spot_pricing_prefix"
134+
projectID: "012345678901"
135+
136+
cloudPricingSecretRef:
137+
name: <SECRET_NAME>
138+
namespace: multi-tenant-operator
139+
```
140+
141+
### Option 2: IRSA (IAM Roles for Service Accounts)
142+
143+
After creating the role and policy, attach the role ARN as an annotation to the opencost gateway account via following command
144+
145+
```sh
146+
kubectl annotate serviceaccounts -n multi-tenant-operator tenant-operator-opencost-gateway eks.amazonaws.com/role-arn=<ROLE_ARN>
147+
```
148+
149+
Apply the IntegrationConfig with current spot bucket data feed information
150+
151+
Example:
152+
153+
```yaml
154+
components:
155+
showback: true # should be enabled
156+
showbackOpts:
157+
custom:
158+
provider: aws
159+
description: "AWS Provider Configuration. Provides default values used if instance type or spot information is not found."
160+
CPU: "0.031611"
161+
spotCPU: "0.006655"
162+
RAM: "0.004237"
163+
GPU: "0.95"
164+
spotRAM: "0.000892"
165+
storage: "0.000138888889"
166+
zoneNetworkEgress: "0.01"
167+
regionNetworkEgress: "0.01"
168+
internetNetworkEgress: "0.143"
169+
spotLabel: "kops.k8s.io/instancegroup"
170+
spotLabelValue: "spotinstance-nodes"
171+
awsSpotDataRegion: "us-east-2"
172+
awsSpotDataBucket: "my-spot-bucket"
173+
awsSpotDataPrefix: "spot_pricing_prefix"
174+
projectID: "012345678901"
175+
```
176+
177+
## References
178+
179+
For more information, refer to the following resources
180+
181+
- [`OpenCost documentation`](https://www.opencost.io/docs/configuration/aws)
182+
- [`Kubecost documentation`](https://docs.kubecost.com/install-and-configure/install/cloud-integration/aws-cloud-integrations)
183+
- [`Assign IAM roles to Kubernetes service accounts`](https://docs.aws.amazon.com/eks/latest/userguide/associate-service-account-role.html)
184+
- [`Track your Spot Instance costs using the Spot Instance data feed`](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-data-feeds.html)
185+
- [`Manage access keys from IAM users`](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html)

‎content/integrations/azure-pricing.md

+7-72
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
# Azure Pricing
22

3-
MTO supports Azure pricing model via the `integrationConfig.components.showbackOpts.azurePricingSecretRef` field. Following 3 types of pricing are supported:
3+
MTO supports Azure pricing model via the `integrationConfig.components.showbackOpts.cloudPricingSecretRef` field. Following 3 types of pricing are supported:
44

5-
- [`Azure Pricing Configuration`](https://www.opencost.io/docs/configuration/azure#azure-pricing-configuration)
6-
- [`Customer-specific pricing`](https://www.opencost.io/docs/configuration/azure#customer-specific-pricing)
7-
- [`Azure Cloud Costs`](https://www.opencost.io/docs/configuration/azure#azure-cloud-costs)
5+
- [`Azure Standard Pricing`](#azure-standard-pricing)
6+
- [`Customer-specific pricing`](#customer-specific-pricing)
87

9-
## Azure Pricing Configuration
8+
## Azure Standard Pricing
109

1110
For Azure pricing configuration, OpenCost needs access to the Microsoft Azure Billing Rate Card API to access accurate pricing data for your Kubernetes resources.
1211

@@ -86,7 +85,7 @@ components:
8685
console: true # should be enabled
8786
showback: true # should be enabled
8887
showbackOpts:
89-
azurePricingSecretRef:
88+
cloudPricingSecretRef:
9089
name: azure-service-key
9190
namespace: multi-tenant-operator
9291
```
@@ -140,7 +139,7 @@ components:
140139
console: true # should be enabled
141140
showback: true # should be enabled
142141
showbackOpts:
143-
azurePricingSecretRef:
142+
cloudPricingSecretRef:
144143
name: customer-specific-pricing
145144
namespace: multi-tenant-operator
146145
```
@@ -195,70 +194,6 @@ RESPONSE="$(curl --silent --show-error -X PUT "${URL}" \
195194
echo "Response: ${RESPONSE}"
196195
```
197196

198-
## Azure Cloud Costs
199-
200-
The following values can be found in the Azure Portal under *Cost Management > Exports*, or Storage accounts:
201-
202-
- `<SUBSCRIPTION_ID>` is the Subscription ID belonging to the Storage account which stores your exported Azure cost report data.
203-
- `<STORAGE_ACCOUNT>` is the name of the Storage account where the exported Azure cost report data is being stored.
204-
- `<STORAGE_ACCESS_KEY>` can be found by selecting Access Keys from the navigation sidebar then selecting Show keys. Using either of the two keys will work.
205-
- `<STORAGE_CONTAINER>` is the name that you chose for the exported cost report when you set it up. This is the name of the container where the CSV cost reports are saved in your Storage account.
206-
- `<CONTAINER_PATH>` should be used if there is more than one billing report that is exported to the configured container. The path provided should have only one billing export because OpenCost will retrieve the most recent billing report for a given month found within the path. If this configuration is not used, it should be set to an empty string "".
207-
- `<CLOUD>` is the value which denotes the cloud where the storage account exists. Possible values are public and gov. The default is public if an empty string is provided.
208-
209-
Set these values to the Azure array in the `cloud-integration.json` file:
210-
211-
```json
212-
{
213-
"azure": {
214-
"storage": [
215-
{
216-
"subscriptionID": "<SUBSCRIPTON_ID>",
217-
"account": "<STORAGE_ACCOUNT>",
218-
"container": "<STORAGE_CONTAINER>",
219-
"path": "<CONTAINER_PATH>",
220-
"cloud": "<CLOUD>",
221-
"authorizer": {
222-
"accessKey": "<STORAGE_ACCESS_KEY>",
223-
"account": "<STORAGE_ACCOUNT>",
224-
"authorizerType": "AzureAccessKey"
225-
}
226-
},
227-
{
228-
"subscriptionID": "<SUBSCRIPTION_ID>",
229-
"account": "<STORAGE_ACCOUNT>",
230-
"container": "<EXPORT_CONTAINER>",
231-
"path": "",
232-
"cloud": "<CLOUD>",
233-
"authorizer": {
234-
"accessKey": "<ACCOUNT_ACCESS_KEY>",
235-
"account": "<STORAGE_ACCOUNT>",
236-
"authorizerType": "AzureAccessKey"
237-
}
238-
}
239-
]
240-
}
241-
}
242-
```
243-
244-
Load the `cloud-integration.json` into a Kubernetes secret in your opencost namespace.
245-
246-
```bash
247-
kubectl create secret generic cloud-costs --from-file=./cloud-integration.json --namespace opencost
248-
```
249-
250-
Update your IntegrationConfig to use the Cloud Costs pricing model:
251-
252-
```yaml
253-
components:
254-
console: true # should be enabled
255-
showback: true # should be enabled
256-
showbackOpts:
257-
azurePricingSecretRef:
258-
name: cloud-costs
259-
namespace: multi-tenant-operator
260-
```
261-
262197
## Conclusion
263198

264199
In this guide, we have seen how to configure OpenCost to use Azure pricing model. We have seen how to configure Azure Pricing Configuration, Customer-specific pricing, and Azure Cloud Costs. To enable all three pricing models, you can create a single secret with all the required values and update the IntegrationConfig to use the secret.
@@ -276,7 +211,7 @@ components:
276211
console: true # should be enabled
277212
showback: true # should be enabled
278213
showbackOpts:
279-
azurePricingSecretRef:
214+
cloudPricingSecretRef:
280215
name: azure-pricing
281216
namespace: multi-tenant-operator
282217
```

‎content/kubernetes-resources/integration-config.md

+28-9
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,19 @@ spec:
2323
zoneNetworkEgress: "0.01"
2424
regionNetworkEgress: "0.01"
2525
internetNetworkEgress: "0.12"
26-
azurePricingSecretRef:
27-
name: azure-pricing
26+
spotLabel: "kops.k8s.io/instancegroup"
27+
spotLabelValue: "spotinstance-nodes"
28+
awsSpotDataRegion: "us-east-2"
29+
awsSpotDataBucket: "my-spot-bucket"
30+
awsSpotDataPrefix: "spot_pricing_prefix"
31+
projectID: "012345678901"
32+
33+
cloudPricingSecretRef:
34+
name: secret-name
2835
namespace: multi-tenant-operator
36+
37+
opencostServiceRoleArn: arn:aws:iam::123456789012:role/S3Access
38+
2939
ingress:
3040
ingressClassName: 'nginx'
3141
keycloak:
@@ -153,7 +163,7 @@ Following are the different components that can be used to configure multi-tenan
153163
zoneNetworkEgress: "0.01"
154164
regionNetworkEgress: "0.01"
155165
internetNetworkEgress: "0.12"
156-
azurePricingSecretRef:
166+
cloudPricingSecretRef:
157167
name: azure-pricing
158168
namespace: multi-tenant-operator
159169
ingress:
@@ -184,7 +194,8 @@ Following are the different components that can be used to configure multi-tenan
184194
- `tlsSecretName:` Name of the secret containing the TLS certificate and key for the Keycloak's ingress.
185195
- `components.showbackOpts:` Configures the showback feature with the following options:
186196
- `custom:` Custom pricing model for showback.
187-
- `azurePricingSecretRef:` Secret reference for Azure pricing model.
197+
- `cloudPricingSecretRef:` Secret reference for AWS / Azure Pricing model.
198+
- `opencostServiceRoleArn`: Role ARN to be used by OpenCost gateway's service account
188199

189200
Here's an example of how to generate the secrets required to configure MTO:
190201

@@ -231,16 +242,24 @@ components:
231242

232243
After modifying your default IntegrationConfig in `multi-tenant-operator` namespace, a configmap named `opencost-custom-pricing` will be updated. You will be able to see updated pricing info in `mto-console`.
233244

234-
### Azure Pricing Model
245+
### Azure Pricing
235246

236-
MTO supports Azure pricing model via the `showbackOpts.azurePricingSecretRef` field. Following 3 types of pricing are supported:
247+
MTO supports Azure pricing model via the `showbackOpts.cloudIntegrationSecretRef` field. Following 2 types of pricing are supported:
237248

238-
- [`Azure Pricing Configuration`](https://www.opencost.io/docs/configuration/azure#azure-pricing-configuration)
239-
- [`Customer-specific pricing`](https://www.opencost.io/docs/configuration/azure#customer-specific-pricing)
240-
- [`Azure Cloud Costs`](https://www.opencost.io/docs/configuration/azure#azure-cloud-costs)
249+
- [`Azure Standard Pricing`](../integrations/azure-pricing.md#azure-standard-pricing)
250+
- [`Customer-specific pricing`](../integrations/azure-pricing.md#customer-specific-pricing)
241251

242252
More details on Azure pricing can be found [here](../integrations/azure-pricing.md).
243253

254+
### AWS Pricing
255+
256+
MTO supports AWS pricing model via the `integrationConfig.components.showbackOpts.cloudIntegrationSecretRef` field. Following 2 types of pricing are supported:
257+
258+
- [`AWS Standard Pricing`](../integrations/aws-pricing.md#aws-standard-pricing)
259+
- [`AWS Spot Instance Pricing`](../integrations/aws-pricing.md#aws-spot-instance-pricing)
260+
261+
More details on AWS pricing can be found [here](../integrations/aws-pricing.md).
262+
244263
## Access Control
245264

246265
```yaml

‎theme_override/mkdocs.yml

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ nav:
9292
- integrations/mattermost.md
9393
- integrations/keycloak.md
9494
- integrations/azure-pricing.md
95+
- integrations/aws-pricing.md
9596
- pricing.md
9697
- changelog.md
9798
- eula.md

0 commit comments

Comments
 (0)
Please sign in to comment.