Git Product home page Git Product logo

azure-cost-mon's Introduction

Build Status Coverage Status PyPI version

ACE azure-costs-exporter

UNMAINTAINED: This repository is no longer maintained. It might no longer be compatible with the latest Azure APIs.

Prometheus exporter for the Microsoft Azure billing API. Check out this blog post for more background about the idea and some nice screenshots.

Description

azure-costs-exporter is a web app, that is intended to be called by Prometheus to export billing information from Azure. It will then return the available metrics in Prometheus compatible format.

The billing API in use is part of the "Enterprise Agreement (EA)" Portal. Hence, it is not available for pay-as-you-go subscriptions. The configuration requires an active EA with Microsoft.

Configuration

You need to create an application.cfg file. This file is essentially a Python file that defines variables in regular Python syntax. The following variables need to be defined in order to record various metrics.

If you do not want to monitor a given metric, just do not define the corresponding XXX_METRIC_NAME option.

Enterprise billing metrics


Add the following variables to the `application.cfg` file:

    ENROLLMENT_NUMBER='123456'
    BILLING_API_ACCESS_KEY='very_secret_key'
    BILLING_METRIC_NAME='azure_costs'

- `ENROLLMENT_NUMBER` is the unique ID that identifies a particular EA.
- The `BILLING_API_ACCESS_KEY` can be created in the [EA portal](https://ea.azure.com/) to gain
access to the billing API. Navigate to "Reports > Download Usage" and generate an API Access Key.
- `BILLING_METRIC_NAME` is the name of the time series that will be generated in Prometheus.


Microsoft AD application settings

For monitoring of reserved or allocated virtual machines, you need to provide additional configuration options in the application.cfg file:

APPLICATION_ID='abcd'
APPLICATION_SECRET='secret'
AD_TENANT_ID='efgh'

The configuration variables contain details on the Microsoft service principal / Azure Active Directory application / app registration. The Microsoft documentation explains what all this means, and how to obtain the values for above configuration options.

  • APPLICATION_ID is the application ID of a Microsoft service principal / Azure Active Directory application / app registration.
  • APPLICATION_SECRET is the application secret that is created during the Azure app registration.
  • AD_TENANT_ID is the ID of your Azure Active Directory instance.

Allocated virtual machine metrics


In addition to the Microsoft AD application settings, add the following variables to the `application.cfg` file:

    SUBSCRIPTION_IDS=['subscription_1', 'subscription_2']
    ALLOCATED_VM_METRIC_NAME='azure_allocated_vms'

- `SUBSCRIPTION_IDS` is a _sequence_ (!) of subscription IDs that shall be monitored.
- `ALLOCATED_VM_METRIC_NAME` is the name of the time series that will be generated for Prometheus

Please note that the application ID requires "Reader" permissions on each subscription that you want to
monitor.


Reserved virtual machine metrics
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In addition to the Microsoft AD application settings, add the following variables to the `application.cfg` file:

    RESERVED_VM_METRIC_NAME='azure_reserved_vms'

- `RESERVED_VM_METRIC_NAME` is the name of the time series that will be generated for Prometheus

Please note that the application requires "Reader" permissions on _each individual_ reservation _order_ to be
able to retrieve the information of the actual reservations within the reservation orders. That's permissions
for you :-D.


Deployment
----------

E.g. via `gunicorn`. In an activated `virtualenv`, you can do:

    pip install azure-costs-exporter gunicorn
    cp /path/to/application.cfg .
    gunicorn azure_costs_exporter:app

Tests
-----

The used python testing tool is [pytest](https://docs.pytest.org/en/latest/).
To run the tests:

```bash
mkvirtualenv billing
pip install -r requirements_dev.txt
pip install -e .
py.test
```

azure-cost-mon's People

Contributors

manuelbahr avatar mathmagique avatar matthias-bach-by avatar snyk-bot avatar stephan-erb-by avatar treebee avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

azure-cost-mon's Issues

Constant costs might decrease due to numerical instabilities

Exported data contains long floating point numbers such as 0.0000032120027740023963. Due to the nature of the floating points numbers, aggregating those can lead to unstable results as the addition is non-commutative. This is problematic as it prevents us from defining meaningful aggregation rules over exported cost data.

Please see prometheus/prometheus#2951 for details.

We don't need full precision here, so we should round the results to 2 or 3 digits before emitting.

Make metric name configurable

The metric name as it appears in prometheus is hardcoded at the moment. This should be made configurable via application.cfg.

Dynamic timeout

Use X-Prometheus-Scrape-Timeout-Seconds header sent by Prometheus instead of a hardcoded network timeout in the request to the Azure API.

Switch to official Prometheus python client

To foster re-use and make the code easier to approach for the Prometheus community, we should switch to the official Prometheus client (https://github.com/prometheus/client_python)

Example how the integration could look like:

from prometheus_client.core import CounterMetricFamily, REGISTRY

class AzureCollector(object):
    def collect(self):
        c = CounterMetricFamily('my_counter_total', 'Help text', labels=['foo'])
        c.add_metric(['bar'], 1.7)
        c.add_metric(['baz'], 3.8)
        yield c

REGISTRY.register(AzureCollector())

We could either use the built-in HTTP server (via start_http_server), built-in WSGI app (via make_wsgi_app) or continue to use Flask by returning output of generate_latest() with content type CONTENT_TYPE_LATEST from a custom /metrics function.

Consistent metric labelling

Currently the labels of different components of this exporter are not aligned.

  • azure_costs_eur labels are written in CamelCase, while azure_vms_allocated et al are written in snake_case.
  • ResourceGroup values are lowercase, resource_group values are UPPERCASE
  • azure_costs_eur has the label SubscriptionName="<literal name>", while azure_vms_allocated has the label subscription="<UUID>"

Be sensitive to token in tests

Currently, the test_token test runs through but actually should fail. The test obviously is not sensitive to the token setting. In practice it works, but the test should represent that behaviour.

Run the application with env variables instead of configuration file

I run applications like these in a docker container. For this I don't want a dependancy to a file with hardcoded variables. It would be nice if there is an option to read the configuration from the environment.

e.g. I would like to see a docker-compose.yml like this

version: '3'

services:
azure-billing-exporter:
    image: blue-yonder/azure-cost-mon
    ports:
    - 8000:8000
    environment:
      PROMETHEUS_METRIC_NAME: "azure_costs_eur"
      ENROLLMENT_NUMBER: "31415"
      BILLING_API_ACCESS_KEY: "3408795poitwiqeotu934t5pqweiut"

My workaround is to use the following Dockerfile

FROM python       

ADD https://github.com/blue-yonder/azure-cost-mon/archive/v0.4.1.tar.gz /tmp

WORKDIR /tmp
RUN tar -zxvf /tmp/v0.4.1.tar.gz \
  &&  mv /tmp/azure-cost-mon-0.4.1 /azure_cost_mon

WORKDIR /azure_cost_mon
RUN pip install -r requirements.txt \
  && pip install azure-costs-exporter gunicorn

ADD startup.py /azure_cost_mon/startup.py
EXPOSE 8000
ENTRYPOINT ["python","/azure_cost_mon/startup.py"]

And the following startup.py

import os

metricName=os.environ['PROMETHEUS_METRIC_NAME']
enrollmentNumber = os.environ['ENROLLMENT_NUMBER']
apiAccessKey= os.environ['BILLING_API_ACCESS_KEY']

file = open('/azure_cost_mon/application.cfg','w') 
file.write('ENROLLMENT_NUMBER=\''+enrollmentNumber+ '\'\n') 
file.write('BILLING_API_ACCESS_KEY=\''+apiAccessKey+ '\'\n') 
file.write('PROMETHEUS_METRIC_NAME=\''+metricName+ '\'\n') 
file.close()

os.system("gunicorn --log-level=info azure_costs_exporter:app -b :8000")

Integration test with Azure API

There seems to be an Azure test enrollment with ID 100 that returns realistic data. It would be useful to perform a real integration test against live data. The API key can be found here.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.