├── handlers ├── main.yml ├── nginx.yml └── grafana.yml ├── tasks ├── grafana_config.yml ├── main.yml ├── nginx.yml ├── grafana_git.yml └── grafana_release.yml ├── meta └── main.yml ├── defaults └── main.yml ├── templates ├── nginx.conf.j2 └── grafana.js.j2 └── README.md /handlers/main.yml: -------------------------------------------------------------------------------- 1 | - include: nginx.yml 2 | - include: grafana.yml 3 | -------------------------------------------------------------------------------- /handlers/nginx.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: reload nginx 3 | service: name=nginx state=reloaded 4 | -------------------------------------------------------------------------------- /tasks/grafana_config.yml: -------------------------------------------------------------------------------- 1 | - name: make config for grafana 2 | template: src=grafana.js.j2 dest={{ grafana_root_path }}/dist/config.js owner={{ grafana_owner }} 3 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - include: grafana_git.yml 3 | when: grafana_version is not defined 4 | - include: grafana_release.yml 5 | when: grafana_version is defined 6 | - include: grafana_config.yml 7 | - include: nginx.yml 8 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: Ian Babrou 4 | description: Grafana role for ansible 5 | license: MIT 6 | min_ansible_version: 1.4 7 | categories: 8 | - monitoring 9 | - web 10 | dependencies: [] 11 | -------------------------------------------------------------------------------- /tasks/nginx.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: make config for nginx 3 | template: src=nginx.conf.j2 4 | dest={{ grafana_nginx_config_path }}/{{ grafana_nginx_config_name }} 5 | owner={{ grafana_owner }} 6 | mode=0644 7 | notify: 8 | - reload nginx 9 | -------------------------------------------------------------------------------- /tasks/grafana_git.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: checkout grafana from git 3 | git: repo={{ grafana_git_url }} 4 | dest={{ grafana_root_path }} 5 | version={{ grafana_git_branch }} 6 | force=yes 7 | update=yes 8 | notify: 9 | - rebuild grafana {{ grafana_root_path }} 10 | - name: make dist dir 11 | file: path={{ grafana_root_path }}/dist state=directory owner={{ grafana_owner }} 12 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | grafana_owner: www-data 3 | 4 | grafana_git_url: https://github.com/torkelo/grafana.git 5 | grafana_git_branch: master 6 | grafana_root_path: /var/www/grafana 7 | grafana_default_route: /dashboard/file/default.json 8 | grafana_index: grafana-dash 9 | 10 | grafana_elasticsearch_url: http://127.0.0.1:9200 11 | grafana_graphite_url: http://127.0.0.1:8080 12 | 13 | grafana_nginx_config_name: grafana.conf 14 | grafana_nginx_config_path: /etc/nginx/sites-enabled 15 | grafana_nginx_listen: 127.0.0.1 16 | grafana_nginx_server_name: 127.0.0.1 17 | grafana_nginx_access_log: false 18 | grafana_nginx_error_log: false 19 | grafana_nginx_enable_ssl: false 20 | grafana_nginx_ssl_cert_path: "" 21 | grafana_nginx_ssl_key_path: "" 22 | grafana_nginx_http_auth_file: false 23 | -------------------------------------------------------------------------------- /tasks/grafana_release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: make grafana dir 3 | file: path={{ grafana_root_path }} state=directory owner={{ grafana_owner }} recurse=yes 4 | - name: download grafana 5 | get_url: dest={{ grafana_root_path }}/grafana-{{ grafana_version }}.tar.gz url=http://grafanarel.s3.amazonaws.com/grafana-{{ grafana_version }}.tar.gz 6 | - name: make version dir 7 | file: path={{ grafana_root_path }}/grafana-{{ grafana_version }} state=directory owner={{ grafana_owner }} recurse=yes 8 | - name: extract grafana tarball 9 | unarchive: src={{ grafana_root_path}}/grafana-{{ grafana_version }}.tar.gz dest={{ grafana_root_path }} copy=false creates={{ grafana_root_path }}/grafana-{{ grafana_version }}/README.md 10 | notify: 11 | - chown grafana dir {{ grafana_root_path }} 12 | - name: link grafana version 13 | file: path={{ grafana_root_path }}/dist src={{ grafana_root_path }}/grafana-{{ grafana_version }} state=link owner={{ grafana_owner }} 14 | -------------------------------------------------------------------------------- /handlers/grafana.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # just trigger actual build process 3 | - name: rebuild grafana {{ grafana_root_path }} 4 | command: /bin/true 5 | notify: 6 | - install npm modules {{ grafana_root_path }} 7 | - install grunt-cli {{ grafana_root_path }} 8 | - update npm modules {{ grafana_root_path }} 9 | - grunt build {{ grafana_root_path }} 10 | - chown grafana dir {{ grafana_root_path }} 11 | - make config for grafana {{ grafana_root_path }} 12 | 13 | 14 | - name: install npm modules {{ grafana_root_path }} 15 | command: chdir={{ grafana_root_path }} npm install 16 | - name: install grunt-cli {{ grafana_root_path }} 17 | command: chdir={{ grafana_root_path }} npm install grunt-cli 18 | - name: update npm modules {{ grafana_root_path }} 19 | command: chdir={{ grafana_root_path }} npm update 20 | - name: grunt build {{ grafana_root_path }} 21 | command: chdir={{ grafana_root_path }} ./node_modules/.bin/grunt build 22 | - name: make config for grafana {{ grafana_root_path }} 23 | template: src=grafana.js.j2 dest={{ grafana_root_path }}/dist/config.js owner={{ grafana_owner }} 24 | - name: chown grafana dir {{ grafana_root_path }} 25 | file: path={{ grafana_root_path }} state=directory owner={{ grafana_owner }} recurse=yes 26 | -------------------------------------------------------------------------------- /templates/nginx.conf.j2: -------------------------------------------------------------------------------- 1 | ## WARNING ## 2 | # This file is automatically generated 3 | # by bobrik.grafana role for ansible. 4 | # Do not mess with it with your hands. 5 | 6 | {% if grafana_nginx_enable_ssl %} 7 | server { 8 | listen {{ grafana_nginx_listen }}; 9 | server_name {{ grafana_nginx_server_name }}; 10 | 11 | return 301 https://{{ grafana_nginx_server_name }}$request_uri; 12 | } 13 | {% endif %} 14 | 15 | server { 16 | {% if grafana_nginx_enable_ssl %} 17 | listen {{ grafana_nginx_listen }}:443 ssl; 18 | {% else %} 19 | listen {{ grafana_nginx_listen }}; 20 | {% endif %} 21 | 22 | server_name {{ grafana_nginx_server_name }}; 23 | 24 | {% if grafana_nginx_enable_ssl %} 25 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 26 | ssl_certificate {{ grafana_nginx_ssl_cert_path }}; 27 | ssl_certificate_key {{ grafana_nginx_ssl_key_path }}; 28 | ssl_ciphers ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM; 29 | ssl_session_cache shared:SSL:10m; 30 | {% endif %} 31 | 32 | proxy_read_timeout 120s; # slow queries happen 33 | 34 | {% if grafana_nginx_access_log %} 35 | access_log {{ grafana_nginx_access_log }}; 36 | {% endif %} 37 | 38 | {% if grafana_nginx_error_log %} 39 | error_log {{ grafana_nginx_error_log }}; 40 | {% endif %} 41 | 42 | {% if grafana_nginx_http_auth_file %} 43 | auth_basic "Beep boop, password please!"; 44 | auth_basic_user_file {{ grafana_nginx_http_auth_file }}; 45 | {% endif %} 46 | 47 | expires -1; 48 | 49 | location / { 50 | root {{ grafana_root_path }}/dist; 51 | } 52 | 53 | location /es/{{ grafana_index }}/ { 54 | rewrite ^/es/({{ grafana_index }}/.*)$ /$1 break; 55 | proxy_pass {{ grafana_elasticsearch_url }}; 56 | } 57 | 58 | location /graphite/ { 59 | rewrite ^/graphite/(.*)$ /$1 break; 60 | proxy_pass {{ grafana_graphite_url }}; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /templates/grafana.js.j2: -------------------------------------------------------------------------------- 1 | ///// @scratch /configuration/config.js/1 2 | // == Configuration 3 | // config.js is where you will find the core Grafana configuration. This file contains parameter that 4 | // must be set before Grafana is run for the first time. 5 | /// 6 | define(['settings'], 7 | function (Settings) { 8 | "use strict"; 9 | 10 | return new Settings({ 11 | 12 | // datasources, you can add multiple 13 | datasources: { 14 | graphite: { 15 | type: 'graphite', 16 | {% if grafana_nginx_enable_ssl %} 17 | url: "https://{{ grafana_nginx_server_name }}/graphite", 18 | {% else %} 19 | url: "http://{{ grafana_nginx_server_name }}/graphite", 20 | {% endif %} 21 | default: true 22 | }, 23 | // influxdb: { 24 | // type: 'influxdb', 25 | // url: "http://my_influxdb_server:8086/db/database_name", 26 | // username: 'admin', 27 | // password: 'admin' 28 | // }, 29 | }, 30 | 31 | // elasticsearch url 32 | // used for storing and loading dashboards, optional 33 | // For Basic authentication use: http://username:password@domain.com:9200 34 | {% if grafana_nginx_enable_ssl %} 35 | elasticsearch: "https://{{ grafana_nginx_server_name }}/es", 36 | {% else %} 37 | elasticsearch: "http://{{ grafana_nginx_server_name }}/es", 38 | {% endif %} 39 | 40 | // default start dashboard 41 | default_route: '{{ grafana_default_route }}', 42 | 43 | // Elasticsearch index for storing dashboards 44 | grafana_index: "{{ grafana_index }}", 45 | 46 | // timezoneOFfset: 47 | // If you experiance problems with zoom, it is probably caused by timezone diff between 48 | // your browser and the graphite-web application. timezoneOffset setting can be used to have Grafana 49 | // translate absolute time ranges to the graphite-web timezone. 50 | // Example: 51 | // If TIME_ZONE in graphite-web config file local_settings.py is set to America/New_York, then set 52 | // timezoneOffset to "-0500" (for UTC - 5 hours) 53 | // Example: 54 | // If TIME_ZONE is set to UTC, set this to "0000" 55 | // 56 | timezoneOffset: null, 57 | 58 | // set to false to disable unsaved changes warning 59 | unsaved_changes_warning: true, 60 | 61 | // set the default timespan for the playlist feature 62 | // Example: "1m", "1h" 63 | playlist_timespan: "1m", 64 | 65 | // Add your own custom pannels 66 | plugins: { 67 | panels: [] 68 | } 69 | 70 | }); 71 | }); 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | grafana 2 | ======== 3 | 4 | [grafana](https://github.com/torkelo/grafana) role for ansible. 5 | 6 | Features 7 | ------------ 8 | 9 | * Protected with nginx and http basic auth 10 | * Read-only access for data and read-write for dashboards 11 | * Many instances per server could be deployed 12 | * SSL ready, https is forced if enabled 13 | 14 | Role Variables 15 | -------------- 16 | 17 | * `grafana_owner` basically nginx user, `www-data` by default 18 | * `grafana_version` if defined, install this version via binary rather than building from git 19 | * `grafana_git_url` git url for grafana, set to upstream by default 20 | * `grafana_git_branch` git branch to track, set to master by default 21 | * `grafana_root_path` path to clone grafana, `/var/www/grafana` by default 22 | * `grafana_default_route` default dashboard url, `/dashboard/file/default.json` by default 23 | * `grafana_index` grafana index to store dashboards, `grafana-dash` by default 24 | * `grafana_elasticsearch_url` elasticsearch url *for nginx*, http://127.0.0.1:9200 by default 25 | * `grafana_graphite_url` graphite-web url *for nginx*, http://127.0.0.1:8080 by default 26 | * `grafana_nginx_config_name` nginx config name, `grafana.conf` by default 27 | * `grafana_nginx_config_path` nginx configs dir, `/etc/nginx/sites-enabled` by default 28 | * `grafana_nginx_listen` nginx listen address, `127.0.0.1` by default 29 | * `grafana_nginx_server_name` nginx server_name (hostname), `127.0.0.1` by default 30 | * `grafana_nginx_access_log` path to nginx access_log, `false` by default 31 | * `grafana_nginx_error_log` path to nginx error_log, `false` by default 32 | * `grafana_nginx_enable_ssl` whether or not ssl should be enabled, `false` by default 33 | * `grafana_nginx_ssl_cert_path` nginx ssl certificate path, `""` by default 34 | * `grafana_nginx_ssl_key_path` nginx ssl key path, `""` by default 35 | * `grafana_nginx_http_auth_file` path to nginx http auth file, `false` by default 36 | 37 | Minimal installation on ubuntu requires none of variables to be set, it will work on `http://127.0.0.1/`. 38 | 39 | Dependencies 40 | ------------ 41 | 42 | * nginx 43 | * elasticsearch 44 | * (optional) node.js, required if `grafana_version` is not set. 45 | 46 | Notes 47 | ----- 48 | 49 | ## Basic Authentication 50 | 51 | Basic authentication may be set up with 52 | 53 | ``` 54 | apt: pkg=apache2-utils 55 | command: htpasswd -bc {{ grafana_nginx_http_auth_file }} username password 56 | ``` 57 | 58 | ## Self-Signed Certificate 59 | 60 | You can create a self-signed certificate to use for SSL: 61 | 62 | ``` 63 | - command: openssl genrsa -out {{ grafana_nginx_ssl_key_path }} 2048 creates={{ grafana_nginx_ssl_key_path }} 64 | - command: openssl req -new -key {{ grafana_nginx_ssl_key_path }} -out {{ grafana_nginx_ssl_csr_path }} -subj "/C={{ country_code }}/ST={{ state }}/L={{ location }}/O={{ organication }}/OU={{ organizational_unit }}/CN={{ cname }}" creates={{ grafana_nginx_ssl_csr_path }} 65 | - command: openssl x509 -req -days 365 -in {{ grafana_nginx_ssl_csr_path }} -signkey {{ grafana_nginx_ssl_key_path }} -out {{ grafana_nginx_ssl_cert_path }} creates={{ grafana_nginx_ssl_cert_path }} 66 | ``` 67 | 68 | ## Listen Address 69 | 70 | The default installation only listens on 127.0.0.1, so is not externally accessible. To make your server publicly accessible, set `grafana_nginx_listen` to `0.0.0.0`. If you do this, it's strongly recommended that you also set `grafana_nginx_enable_ssl` and `grafana_nginx_http_auth_file` to password protect the site and ensure that the password is not sent in the clear. 71 | 72 | License 73 | ------- 74 | 75 | MIT 76 | 77 | Author Information 78 | ------------------ 79 | 80 | * Ian Babrou, ibobrik@gmail.com 81 | * Bryan Larsen, bryan@larsen.st 82 | --------------------------------------------------------------------------------