diff --git a/playbooks/hosts/grafana.cloud.fedoraproject.org.yml b/playbooks/hosts/grafana.cloud.fedoraproject.org.yml
index 75b5d2a070..7dad697d4d 100644
--- a/playbooks/hosts/grafana.cloud.fedoraproject.org.yml
+++ b/playbooks/hosts/grafana.cloud.fedoraproject.org.yml
@@ -25,12 +25,26 @@
- /srv/private/ansible/files/openstack/passwords.yml
- /srv/web/infra/ansible/vars/{{ ansible_distribution }}.yml
+ roles:
+ - base
+ - rkhunter
+ - { role: denyhosts, when: ansible_distribution_major_version|int != 7 }
+ - apache
+ - graphite/graphite
+ - graphite/statsd
+ - graphite/fedmsg2statsd
+ - graphite/grafana
+
+ tasks:
+ - include: "{{ tasks }}/yumrepos.yml"
+ - include: "{{ tasks }}/2fa_client.yml"
+ - include: "{{ tasks }}/motd.yml"
+ - include: "{{ tasks }}/mod_wsgi.yml"
+
+ handlers:
+ - include: "{{ handlers }}/restart_services.yml"
+
pre_tasks:
- include: "{{ tasks }}/cloud_setup_basic.yml"
- name: set hostname (required by some services, at least postfix need it)
shell: "hostname {{inventory_hostname}}"
-
- # TODO -- we don't actually have these yet
- #roles:
- #- graphite
- #- grapfana
diff --git a/roles/graphite/fedmsg2statsd/files/fedmsg2statsd.service b/roles/graphite/fedmsg2statsd/files/fedmsg2statsd.service
new file mode 100644
index 0000000000..d0ecf9c36f
--- /dev/null
+++ b/roles/graphite/fedmsg2statsd/files/fedmsg2statsd.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=fedmsg to statsd proxy
+After=network.target
+Documentation=https://github.com/fedora-infra/fedmsg2statsd/
+
+[Service]
+ExecStart=/opt/fedmsg2statsd/.cabal-sandbox/bin/fedmsg2statsd localhost 2003 tcp://hub.fedoraproject.org:9940
+Type=simple
+User=nobody
+Group=nobody
+LimitNOFILE=160000
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
diff --git a/roles/graphite/fedmsg2statsd/tasks/main.yml b/roles/graphite/fedmsg2statsd/tasks/main.yml
new file mode 100644
index 0000000000..6787b1dd54
--- /dev/null
+++ b/roles/graphite/fedmsg2statsd/tasks/main.yml
@@ -0,0 +1,47 @@
+---
+- name: install needed packages
+ yum: pkg={{ item }} state=present
+ with_items:
+ - ghc
+ - ghc-devel
+ - git
+ - cabal-install
+ tags:
+ - packages
+ - fedmsg2statsd
+
+- name: Clone fedmsg2statsd repo (this needs to be packaged at some point)
+ git: accept_hostkey=yes clone=yes repo=https://github.com/fedora-infra/fedmsg2statsd.git update=yes dest=/opt/fedmsg2statsd
+ tags:
+ - fedmsg2statsd
+
+- name: Update cabal metadata
+ shell: cabal update
+ tags:
+ - fedmsg2statsd
+
+- name: Start a cabal sandbox
+ shell: cwd=/opt/fedmsg2statsd cabal sandbox init
+ tags:
+ - fedmsg2statsd
+
+- name: Install fedmsg2statsd in the sandbox
+ shell: cwd=/opt/fedmsg2statsd cabal install
+ tags:
+ - fedmsg2statsd
+
+- name: Installing systemd service file
+ copy: >
+ src=fedmsg2statsd.service
+ dest=/usr/lib/systemd/system/fedmsg2statsd.service
+ tags:
+ - config
+ - fedmsg2statsd
+ notify:
+ - restart fedmsg2statsd
+
+- name: Set fedmsg2statsd to run on boot
+ service: name=fedmsg2statsd enabled=yes state=running
+ tags:
+ - service
+ - fedmsg2statsd
diff --git a/roles/graphite/grafana/files/grafana.conf b/roles/graphite/grafana/files/grafana.conf
new file mode 100644
index 0000000000..4c25da333f
--- /dev/null
+++ b/roles/graphite/grafana/files/grafana.conf
@@ -0,0 +1,7 @@
+
+ ServerName grafana.cloud.fedoraproject.org
+ ErrorLog /var/log/httpd/grafana-error.log
+ CustomLog /var/log/httpd/grafana-access.log common
+ ProxyPass / http://localhost:3000/
+ ProxyPassReverse / http://localhost:3000/
+
diff --git a/roles/graphite/grafana/files/grafana.repo b/roles/graphite/grafana/files/grafana.repo
new file mode 100644
index 0000000000..2b637d53be
--- /dev/null
+++ b/roles/graphite/grafana/files/grafana.repo
@@ -0,0 +1,9 @@
+[grafana]
+name=grafana
+baseurl=https://packagecloud.io/grafana/stable/el/6/$basearch
+repo_gpgcheck=1
+enabled=1
+gpgcheck=1
+gpgkey=https://packagecloud.io/gpg.key https://grafanarel.s3.amazonaws.com/RPM-GPG-KEY-grafana
+sslverify=1
+sslcacert=/etc/pki/tls/certs/ca-bundle.crt
diff --git a/roles/graphite/grafana/tasks/main.yml b/roles/graphite/grafana/tasks/main.yml
new file mode 100644
index 0000000000..5eb82cbaec
--- /dev/null
+++ b/roles/graphite/grafana/tasks/main.yml
@@ -0,0 +1,26 @@
+---
+- name: add repo
+ action: copy src=grafana.repo dest=/etc/yum.repos.d/grafana.repo
+ tags:
+ - grafana
+ - packages
+ - repo
+
+- name: install grafana
+ yum: pkg=grafana state=present
+ tags:
+ - grafana
+ - packages
+
+- name: Set grafana to run on boot
+ service: name=grafana enabled=yes state=running
+ tags:
+ - service
+ - grafana
+
+- name: grafana apache proxy config file
+ copy: src=grafana.conf dest=/etc/httpd/conf.d/grafana.conf owner=root group=root mode=644
+ notify:
+ - restart apache
+ tags:
+ - grafana
diff --git a/roles/graphite/graphite/tasks/main.yml b/roles/graphite/graphite/tasks/main.yml
new file mode 100644
index 0000000000..2276fb3627
--- /dev/null
+++ b/roles/graphite/graphite/tasks/main.yml
@@ -0,0 +1,40 @@
+---
+- name: install needed packages
+ yum: pkg={{ item }} state=present
+ with_items:
+ - graphite-web
+ - python-carbon
+ - libsemanage-python
+ - mod_ssl
+ tags:
+ - graphite
+ - carbon
+ - packages
+
+- name: graphite-web config file
+ template: src=local_settings.py dest=/etc/graphite-web/local_settings.py owner=root group=root mode=644
+ notify:
+ - restart apache
+ tags:
+ - graphite
+
+- name: graphite-web apache config
+ template: src=graphite-web.conf dest=/etc/httpd/conf.d/graphite-web.conf owner=root group=root mode=644
+ notify:
+ - restart apache
+ tags:
+ - graphite
+
+- name: Set carbon-aggregator to run on boot
+ service: name=carbon-aggregator enabled=yes state=running
+ tags:
+ - service
+ - graphite
+ - carbon
+
+- name: Set carbon-cache to run on boot
+ service: name=carbon-cache enabled=yes state=running
+ tags:
+ - service
+ - graphite
+ - carbon
diff --git a/roles/graphite/graphite/templates/graphite-web.conf b/roles/graphite/graphite/templates/graphite-web.conf
new file mode 100644
index 0000000000..8263705128
--- /dev/null
+++ b/roles/graphite/graphite/templates/graphite-web.conf
@@ -0,0 +1,39 @@
+
+ ServerName graphite.cloud.fedoraproject.org
+ DocumentRoot "/usr/share/graphite/webapp"
+ ErrorLog /var/log/httpd/graphite-web-error.log
+ CustomLog /var/log/httpd/graphite-web-access.log common
+
+ Header set Access-Control-Allow-Origin "*"
+ # Header set Access-Control-Allow-Methods "GET, OPTIONS"
+ # Header set Access-Control-Allow-Headers "origin, authorization, accept"
+ # Header set Access-Control-Allow-Credentials true
+
+ WSGIScriptAlias / /usr/share/graphite/graphite-web.wsgi
+ WSGIImportScript /usr/share/graphite/graphite-web.wsgi process-group=%{GLOBAL} application-group=%{GLOBAL}
+
+
+ SetHandler None
+
+
+ Alias /media/ "/usr/lib/python2.7/site-packages/django/contrib/admin/media/"
+
+ SetHandler None
+
+
+
+
diff --git a/roles/graphite/graphite/templates/local_settings.py b/roles/graphite/graphite/templates/local_settings.py
new file mode 100644
index 0000000000..60eb86c0c4
--- /dev/null
+++ b/roles/graphite/graphite/templates/local_settings.py
@@ -0,0 +1,212 @@
+## Graphite local_settings.py
+# Edit this file to customize the default Graphite webapp settings
+#
+# Additional customizations to Django settings can be added to this file as well
+
+#####################################
+# General Configuration #
+#####################################
+# Set this to a long, random unique string to use as a secret key for this
+# install. This key is used for salting of hashes used in auth tokens,
+# CRSF middleware, cookie storage, etc. This should be set identically among
+# instances if used behind a load balancer.
+SECRET_KEY = '{{ graphite_secret_csrf_key }}'
+
+# In Django 1.5+ set this to the list of hosts your graphite instances is
+# accessible as. See:
+# https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-ALLOWED_HOSTS
+#ALLOWED_HOSTS = [ '*' ]
+
+# Set your local timezone (Django's default is America/Chicago)
+# If your graphs appear to be offset by a couple hours then this probably
+# needs to be explicitly set to your local timezone.
+#TIME_ZONE = 'America/Los_Angeles'
+
+# Override this to provide documentation specific to your Graphite deployment
+#DOCUMENTATION_URL = "http://graphite.readthedocs.org/"
+
+# Logging
+#LOG_RENDERING_PERFORMANCE = True
+#LOG_CACHE_PERFORMANCE = True
+#LOG_METRIC_ACCESS = True
+
+# Enable full debug page display on exceptions (Internal Server Error pages)
+#DEBUG = True
+
+# If using RRD files and rrdcached, set to the address or socket of the daemon
+#FLUSHRRDCACHED = 'unix:/var/run/rrdcached.sock'
+
+# This lists the memcached servers that will be used by this webapp.
+# If you have a cluster of webapps you should ensure all of them
+# have the *exact* same value for this setting. That will maximize cache
+# efficiency. Setting MEMCACHE_HOSTS to be empty will turn off use of
+# memcached entirely.
+#
+# You should not use the loopback address (127.0.0.1) here if using clustering
+# as every webapp in the cluster should use the exact same values to prevent
+# unneeded cache misses. Set to [] to disable caching of images and fetched data
+#MEMCACHE_HOSTS = ['10.10.10.10:11211', '10.10.10.11:11211', '10.10.10.12:11211']
+#DEFAULT_CACHE_DURATION = 60 # Cache images and data for 1 minute
+
+
+#####################################
+# Filesystem Paths #
+#####################################
+# Change only GRAPHITE_ROOT if your install is merely shifted from /opt/graphite
+# to somewhere else
+#GRAPHITE_ROOT = '/opt/graphite'
+GRAPHITE_ROOT = '/usr/share/graphite'
+
+# Most installs done outside of a separate tree such as /opt/graphite will only
+# need to change these three settings. Note that the default settings for each
+# of these is relative to GRAPHITE_ROOT
+#CONF_DIR = '/opt/graphite/conf'
+#STORAGE_DIR = '/opt/graphite/storage'
+#CONTENT_DIR = '/opt/graphite/webapp/content'
+CONF_DIR = '/etc/graphite-web'
+STORAGE_DIR = '/var/lib/graphite-web'
+CONTENT_DIR = '/usr/share/graphite/webapp/content'
+
+# To further or fully customize the paths, modify the following. Note that the
+# default settings for each of these are relative to CONF_DIR and STORAGE_DIR
+#
+## Webapp config files
+#DASHBOARD_CONF = '/etc/graphite-web/dashboard.conf'
+#GRAPHTEMPLATES_CONF = '/etc/graphite-web/graphTemplates.conf'
+
+## Data directories
+# NOTE: If any directory is unreadable in DATA_DIRS it will break metric browsing
+#WHISPER_DIR = '/opt/graphite/storage/whisper'
+#RRD_DIR = '/opt/graphite/storage/rrd'
+#DATA_DIRS = [WHISPER_DIR, RRD_DIR] # Default: set from the above variables
+#LOG_DIR = '/opt/graphite/storage/log/webapp'
+#INDEX_FILE = '/opt/graphite/storage/index' # Search index file
+WHISPER_DIR = '/var/lib/carbon/whisper/'
+RRD_DIR = '/var/lib/carbon/rrd'
+DATA_DIRS = [WHISPER_DIR, RRD_DIR] # Default: set from the above variables
+LOG_DIR = '/var/log/graphite-web/'
+INDEX_FILE = '/var/lib/graphite-web/index' # Search index file
+
+
+#####################################
+# Email Configuration #
+#####################################
+# This is used for emailing rendered Graphs
+# Default backend is SMTP
+#EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
+#EMAIL_HOST = 'localhost'
+#EMAIL_PORT = 25
+#EMAIL_HOST_USER = ''
+#EMAIL_HOST_PASSWORD = ''
+#EMAIL_USE_TLS = False
+# To drop emails on the floor, enable the Dummy backend:
+#EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
+
+
+#####################################
+# Authentication Configuration #
+#####################################
+## LDAP / ActiveDirectory authentication setup
+#USE_LDAP_AUTH = True
+#LDAP_SERVER = "ldap.mycompany.com"
+#LDAP_PORT = 389
+# OR
+#LDAP_URI = "ldaps://ldap.mycompany.com:636"
+#LDAP_SEARCH_BASE = "OU=users,DC=mycompany,DC=com"
+#LDAP_BASE_USER = "CN=some_readonly_account,DC=mycompany,DC=com"
+#LDAP_BASE_PASS = "readonly_account_password"
+#LDAP_USER_QUERY = "(username=%s)" #For Active Directory use "(sAMAccountName=%s)"
+#
+# If you want to further customize the ldap connection options you should
+# directly use ldap.set_option to set the ldap module's global options.
+# For example:
+#
+#import ldap
+#ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW)
+#ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, "/etc/ssl/ca")
+#ldap.set_option(ldap.OPT_X_TLS_CERTFILE, "/etc/ssl/mycert.pem")
+#ldap.set_option(ldap.OPT_X_TLS_KEYFILE, "/etc/ssl/mykey.pem")
+# See http://www.python-ldap.org/ for further details on these options.
+
+## REMOTE_USER authentication. See: https://docs.djangoproject.com/en/dev/howto/auth-remote-user/
+#USE_REMOTE_USER_AUTHENTICATION = True
+
+# Override the URL for the login link (e.g. for django_openid_auth)
+#LOGIN_URL = '/account/login'
+
+
+##########################
+# Database Configuration #
+##########################
+# By default sqlite is used. If you cluster multiple webapps you will need
+# to setup an external database (such as MySQL) and configure all of the webapp
+# instances to use the same database. Note that this database is only used to store
+# Django models such as saved graphs, dashboards, user preferences, etc.
+# Metric data is not stored here.
+#
+# DO NOT FORGET TO RUN 'manage.py syncdb' AFTER SETTING UP A NEW DATABASE
+#
+# The following built-in database engines are available:
+# django.db.backends.postgresql # Removed in Django 1.4
+# django.db.backends.postgresql_psycopg2
+# django.db.backends.mysql
+# django.db.backends.sqlite3
+# django.db.backends.oracle
+#
+# The default is 'django.db.backends.sqlite3' with file 'graphite.db'
+# located in STORAGE_DIR
+#
+
+DATABASES = {
+ 'default': {
+ 'NAME': '/var/lib/graphite-web/graphite.db',
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'USER': '',
+ 'PASSWORD': '',
+ 'HOST': '',
+ 'PORT': ''
+ }
+}
+
+
+#########################
+# Cluster Configuration #
+#########################
+# (To avoid excessive DNS lookups you want to stick to using IP addresses only in this entire section)
+#
+# This should list the IP address (and optionally port) of the webapp on each
+# remote server in the cluster. These servers must each have local access to
+# metric data. Note that the first server to return a match for a query will be
+# used.
+#CLUSTER_SERVERS = ["10.0.2.2:80", "10.0.2.3:80"]
+
+## These are timeout values (in seconds) for requests to remote webapps
+#REMOTE_STORE_FETCH_TIMEOUT = 6 # Timeout to fetch series data
+#REMOTE_STORE_FIND_TIMEOUT = 2.5 # Timeout for metric find requests
+#REMOTE_STORE_RETRY_DELAY = 60 # Time before retrying a failed remote webapp
+#REMOTE_FIND_CACHE_DURATION = 300 # Time to cache remote metric find results
+
+## Remote rendering settings
+# Set to True to enable rendering of Graphs on a remote webapp
+#REMOTE_RENDERING = True
+# List of IP (and optionally port) of the webapp on each remote server that
+# will be used for rendering. Note that each rendering host should have local
+# access to metric data or should have CLUSTER_SERVERS configured
+#RENDERING_HOSTS = []
+#REMOTE_RENDER_CONNECT_TIMEOUT = 1.0
+
+# If you are running multiple carbon-caches on this machine (typically behind a relay using
+# consistent hashing), you'll need to list the ip address, cache query port, and instance name of each carbon-cache
+# instance on the local machine (NOT every carbon-cache in the entire cluster). The default cache query port is 7002
+# and a common scheme is to use 7102 for instance b, 7202 for instance c, etc.
+#
+# You *should* use 127.0.0.1 here in most cases
+#CARBONLINK_HOSTS = ["127.0.0.1:7002:a", "127.0.0.1:7102:b", "127.0.0.1:7202:c"]
+#CARBONLINK_TIMEOUT = 1.0
+
+#####################################
+# Additional Django Settings #
+#####################################
+# Uncomment the following line for direct access to Django settings such as
+# MIDDLEWARE_CLASSES or APPS
+#from graphite.app_settings import *
diff --git a/roles/graphite/statsd/tasks/main.yml b/roles/graphite/statsd/tasks/main.yml
new file mode 100644
index 0000000000..9ed76a67ef
--- /dev/null
+++ b/roles/graphite/statsd/tasks/main.yml
@@ -0,0 +1,14 @@
+---
+- name: install needed packages
+ yum: pkg={{ item }} state=present
+ with_items:
+ - statsd
+ tags:
+ - packages
+ - statsd
+
+- name: Set statsd to run on boot
+ service: name=statsd enabled=yes state=running
+ tags:
+ - service
+ - statsd