You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by da...@apache.org on 2019/02/28 15:41:54 UTC

[trafficcontrol] branch master updated: CIAB: Traffic Stats integration (#3337)

This is an automated email from the ASF dual-hosted git repository.

dangogh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new 5da899f  CIAB: Traffic Stats integration (#3337)
5da899f is described below

commit 5da899f28bb74a31b9db9f459b0c8c693f18b482
Author: Shihta Kuan <Sh...@users.noreply.github.com>
AuthorDate: Thu Feb 28 23:41:48 2019 +0800

    CIAB: Traffic Stats integration (#3337)
    
    * CIAB: Traffic Stats integration
    
    This commit add traffic stats, influxdb, and grafana
---
 docs/source/admin/quick_howto/ciab.rst             |  55 ++++-
 docs/source/admin/traffic_stats.rst                |   6 +-
 infrastructure/cdn-in-a-box/Makefile               |   8 +-
 .../cdn-in-a-box/docker-compose.expose-ports.yml   |   3 +
 infrastructure/cdn-in-a-box/docker-compose.yml     |  32 +++
 .../docker-compose.grafana.expose-ports.yml}       |  43 +---
 .../optional/docker-compose.grafana.yml            |  60 ++++++
 .../grafana/Dockerfile}                            |  69 +++---
 .../optional/grafana/datasources.yml.template      |  53 +++++
 .../cdn-in-a-box/optional/grafana/run-grafana.sh   |  58 +++++
 .../cdn-in-a-box/traffic_ops/to-access.sh          |  15 ++
 .../profiles/080-TRAFFIC_STATS.json                | 234 +++++++++++++++++++++
 .../traffic_ops_data/profiles/081-INFLUXDB.json    |   7 +
 .../traffic_ops_data/profiles/082-GRAFANA.json     |   7 +
 .../traffic_ops_data/types/050-GRAFANA.json        |   5 +
 .../traffic_ops_data/users/030-tstats.json         |   9 +
 .../Dockerfile}                                    |  71 +++----
 .../Dockerfile-influxdb}                           |  56 +----
 .../cdn-in-a-box/traffic_stats/run-influxdb.sh     |  50 +++++
 infrastructure/cdn-in-a-box/traffic_stats/run.sh   | 107 ++++++++++
 infrastructure/cdn-in-a-box/variables.env          |  10 +
 21 files changed, 769 insertions(+), 189 deletions(-)

diff --git a/docs/source/admin/quick_howto/ciab.rst b/docs/source/admin/quick_howto/ciab.rst
index 36bc652..2683a8f 100644
--- a/docs/source/admin/quick_howto/ciab.rst
+++ b/docs/source/admin/quick_howto/ciab.rst
@@ -73,6 +73,12 @@ In a typical scenario, if the steps in `Building`_ have been followed, all that'
 	+---------------------------------+--------------------------------------------------------------+---------------------------------------+-------------------------------------------+
 	| Traffic Vault                   | Riak key-value store on port 8010                            | ``TV_ADMIN_USER`` in `variables.env`_ | ``TV_ADMIN_PASSWORD`` in `variables.env`_ |
 	+---------------------------------+--------------------------------------------------------------+---------------------------------------+-------------------------------------------+
+	| Traffic Stats                   | N/A                                                          | N/A                                   | N/A                                       |
+	+---------------------------------+--------------------------------------------------------------+---------------------------------------+-------------------------------------------+
+	| Traffic Stats Influxdb          | Influxdbd connections accepted on port 8086 (database name:  | ``INFLUXDB_ADMIN_USER`` in            | ``INFLUXDB_ADMIN_PASSWORD`` in            |
+	|                                 | ``cache_stats``, ``daily_stats`` and                         | `variables.env`_                      | `variables.env`_                          |
+	|                                 | ``deliveryservice_stats``)                                   |                                       |                                           |
+	+---------------------------------+--------------------------------------------------------------+---------------------------------------+-------------------------------------------+
 
 .. seealso:: :ref:`tr-api` and :ref:`tm-api`
 
@@ -347,14 +353,14 @@ How to use it
 """""""""""""
 #. It is recommended that this be done using a custom bash alias.
 
-    .. code-block:: shell
-        :caption: CIAB Startup with VPN
+	.. code-block:: shell
+		:caption: CIAB Startup with VPN
 
-        # From infrastructure/cdn-in-a-box
-        alias mydc="docker-compose -f $PWD/docker-compose.yml -f $PWD/docker-compose.expose-ports.yml -f $PWD/optional/docker-compose.vpn.yml -f $PWD/optional/docker-compose.vpn.expose-ports.yml"
-        mydc down -v
-        mydc build
-        mydc up
+		# From infrastructure/cdn-in-a-box
+		alias mydc="docker-compose -f $PWD/docker-compose.yml -f $PWD/docker-compose.expose-ports.yml -f $PWD/optional/docker-compose.vpn.yml -f $PWD/optional/docker-compose.vpn.expose-ports.yml"
+		mydc down -v
+		mydc build
+		mydc up
 
 #. All certificates, keys, and client configuration are stored at ``infrastruture/cdn-in-a-box/optional/vpn/vpnca``. You just simply change ``REALHOSTIP`` and ``REALPORT`` of ``client.ovpn`` to fit your environment, and then you can use it to connect to this OpenVPN server.
 
@@ -363,16 +369,16 @@ The proposed VPN client
 On Linux, we suggest ``openvpn``. On most Linux distributions, this will also be the name of the package that provides it.
 
 .. code-block:: shell
-    :caption: Install openvpn on ubuntu/debian
+	:caption: Install openvpn on ubuntu/debian
 
-    apt-get update && apt-get install -y openvpn
+	apt-get update && apt-get install -y openvpn
 
 On OSX, it only works with brew installed openvpn client, not the *OpenVPN GUI client*.
 
 .. code-block:: shell
-    :caption: Install openvpn on OSX
+	:caption: Install openvpn on OSX
 
-    brew install openvpn
+	brew install openvpn
 
 If you want a GUI version of VPN client, we recommend `Tunnelblick <https://tunnelblick.net/>`_.
 
@@ -395,3 +401,30 @@ Pushed settings are shown as follows:
 * A routing rule for the ``CIAB`` subnet
 
 .. note:: It will not change your default gateway. That means apart from CDN in a Box traffic and DNS requests, all other traffic will use the standard interface bound to the default gateway.
+
+Grafana
+-------
+This container provides a Grafana service. It's an open platform for analytics and monitoring. This container has prepared necessary *datasources* and *scripted dashboards*. Please refer to :ref:`grafana-config` for detailed Settings.
+
+How to start it
+"""""""""""""""
+It is recommended that this be done using a custom bash alias.
+
+.. code-block:: shell
+	:caption: CIAB Startup with Grafana
+
+	# From infrastructure/cdn-in-a-box
+	alias mydc="docker-compose -f $PWD/docker-compose.yml -f $PWD/optional/docker-compose.grafana.yml -f $PWD/optional/docker-compose.grafana.expose-ports.yml"
+	mydc down -v
+	mydc build
+	mydc up
+
+Apart from start Grafana, the above commands also expose port 3000 for it.
+
+Check the charts
+""""""""""""""""
+There are some *scripted dashboards* can show beautiful charts. You can display different charts by passing in different *query string*
+
+* ``https://<grafanaHost>/dashboard/script/traffic_ops_cachegroup.js?which=``. The query parameter `which` in this particular URL should be the **cachegroup**. Take CIAB as an example, it can be filled in with **CDN_in_a_Box_Edge** or **CDN_in_a_Box_Edge**.
+* ``https://<grafanaHost>/dashboard/script/traffic_ops_deliveryservice.js?which=``. The query parameter `which` in this particular URL should be the **xml_id** of the desired Delivery Service.
+* ``https://<grafanaHost>/dashboard/script/traffic_ops_server.js?which=``. The query parameter `which` in this particular URL should be the **hostname** (not **FQDN**). It can be filled in with **edge** or **mid** in CIAB.
diff --git a/docs/source/admin/traffic_stats.rst b/docs/source/admin/traffic_stats.rst
index 4695139..1dd2d60 100644
--- a/docs/source/admin/traffic_stats.rst
+++ b/docs/source/admin/traffic_stats.rst
@@ -82,6 +82,8 @@ Once InfluxDB is installed and configured, databases and retention policies need
 
 To easily create databases, retention policies, and continuous queries, run :program:`create_ts_databases` from the :file:`/opt/traffic_stats/influxdb_tools` directory on your Traffic Stats server. See the `InfluxDB Tools`_ section for more information.
 
+.. _grafana-config:
+
 Configuring Grafana
 -------------------
 In Traffic Portal the :menuselection:`Other --> Grafana` menu item can be configured to display Grafana graphs using InfluxDB data. In order for this to work correctly, you will need two things:
@@ -129,11 +131,11 @@ To configure Traffic Portal to use Grafana Dashboards, you need to enter the fol
 	+---------------------------+----------------------------------------------------------------------------------------------------+
 	|       parameter name      |                                        parameter value                                             |
 	+===========================+====================================================================================================+
-	| all_graph_url             | ``https://<grafana_url>/dashboard/db/deliveryservice-stats``                                       |
+	| all_graph_url             | ``https://<grafanaHost>/dashboard/db/deliveryservice-stats``                                       |
 	+---------------------------+----------------------------------------------------------------------------------------------------+
 	| cachegroup_graph_url      | ``https://<grafanaHost>/dashboard/script/traffic_ops_cachegroup.js?which=``                        |
 	+---------------------------+----------------------------------------------------------------------------------------------------+
-	| deliveryservice_graph_url | ``https://<grafanaHost>/dashboard/script/traffic_ops_devliveryservice.js?which=``                  |
+	| deliveryservice_graph_url | ``https://<grafanaHost>/dashboard/script/traffic_ops_deliveryservice.js?which=``                   |
 	+---------------------------+----------------------------------------------------------------------------------------------------+
 	| server_graph_url          | ``https://<grafanaHost>/dashboard/script/traffic_ops_server.js?which=``                            |
 	+---------------------------+----------------------------------------------------------------------------------------------------+
diff --git a/infrastructure/cdn-in-a-box/Makefile b/infrastructure/cdn-in-a-box/Makefile
index d2a899b..7c2036e 100644
--- a/infrastructure/cdn-in-a-box/Makefile
+++ b/infrastructure/cdn-in-a-box/Makefile
@@ -45,11 +45,12 @@ TO_SOURCE += $(wildcard ../../traffic_ops_db/**/*)
 TM_SOURCE := $(wildcard ../../traffic_monitor/**/*)
 TP_SOURCE := $(wildcard ../../traffic_portal/**/*)
 TR_SOURCE := $(wildcard ../../traffic_router/**/*)
+TS_SOURCE := $(wildcard ../../traffic_stats/**/*)
 
 .PHONY: clean very-clean all nearly-all
 
 # Default target; builds all pre-requisite rpms from source trees
-all: traffic_monitor/traffic_monitor.rpm traffic_portal/traffic_portal.rpm traffic_ops/traffic_ops.rpm traffic_router/traffic_router.rpm traffic_router/tomcat.rpm
+all: traffic_monitor/traffic_monitor.rpm traffic_portal/traffic_portal.rpm traffic_ops/traffic_ops.rpm traffic_router/traffic_router.rpm traffic_router/tomcat.rpm traffic_stats/traffic_stats.rpm
 
 # Actual output rpm recipies
 traffic_monitor/traffic_monitor.rpm: ../../dist/traffic_monitor-$(SPECIAL_SAUCE)
@@ -64,6 +65,8 @@ traffic_router/traffic_router.rpm: ../../dist/traffic_router-$(SPECIAL_SAUCE)
 	cp -f $? $@
 traffic_router/tomcat.rpm: ../../dist/tomcat-$(SPECIAL_SEASONING)
 	cp -f $? $@
+traffic_stats/traffic_stats.rpm: ../../dist/traffic_stats-$(SPECIAL_SAUCE)
+	cp -f $? $@
 
 # Dist rpms
 ../../dist/traffic_monitor-$(SPECIAL_SAUCE): $(TM_SOURCE)
@@ -81,6 +84,9 @@ traffic_router/tomcat.rpm: ../../dist/tomcat-$(SPECIAL_SEASONING)
 ../../dist/traffic_router-$(SPECIAL_SAUCE) ../../dist/tomcat-$(SPECIAL_SEASONING): $(TR_SOURCE)
 	sudo ../../pkg -v traffic_router_build
 
+../../dist/traffic_stats-$(SPECIAL_SAUCE): $(TS_SOURCE)
+	sudo ../../pkg -v traffic_stats_build
+
 clean:
 	$(RM) traffic_ops/traffic_ops.rpm traffic_monitor/traffic_monitor.rpm traffic_portal/traffic_portal.rpm traffic_router/traffic_router.rpm traffic_router/tomcat.rpm edge/traffic_ops_ort.rpm mid/traffic_ops_ort.rpm
 
diff --git a/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml b/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
index be0da42..044cfa7 100644
--- a/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
+++ b/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
@@ -45,6 +45,9 @@ services:
       - "3080:80"
       - "3443:443"
       - "3333:3333"
+  influxdb:
+    ports:
+      - "8086:8086"
   trafficvault:
     ports:
       - "8087:8087"
diff --git a/infrastructure/cdn-in-a-box/docker-compose.yml b/infrastructure/cdn-in-a-box/docker-compose.yml
index bff0d1f..0486e41 100644
--- a/infrastructure/cdn-in-a-box/docker-compose.yml
+++ b/infrastructure/cdn-in-a-box/docker-compose.yml
@@ -156,6 +156,38 @@ services:
       - ./dns/insert-self-into-dns.sh:/usr/local/sbin/insert-self-into-dns.sh
       - shared:/shared
 
+  # trafficstats collect traffic information
+  trafficstats:
+    build:
+      context: .
+      dockerfile: traffic_stats/Dockerfile
+    depends_on:
+      - enroller
+      - influxdb
+    domainname: infra.ciab.test
+    env_file:
+      - variables.env
+    hostname: trafficstats
+    volumes:
+      - ./dns/set-dns.sh:/usr/local/sbin/set-dns.sh
+      - ./dns/insert-self-into-dns.sh:/usr/local/sbin/insert-self-into-dns.sh
+      - shared:/shared
+
+  influxdb:
+    build:
+      context: .
+      dockerfile: traffic_stats/Dockerfile-influxdb
+    hostname: influxdb
+    domainname: infra.ciab.test
+    depends_on:
+      - dns
+    env_file:
+      - variables.env
+    volumes:
+      - ./dns/set-dns.sh:/usr/local/sbin/set-dns.sh
+      - ./dns/insert-self-into-dns.sh:/usr/local/sbin/insert-self-into-dns.sh
+      - shared:/shared
+
   # trafficvault runs a riak container to store private keys
   trafficvault:
     build:
diff --git a/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml b/infrastructure/cdn-in-a-box/optional/docker-compose.grafana.expose-ports.yml
similarity index 54%
copy from infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
copy to infrastructure/cdn-in-a-box/optional/docker-compose.grafana.expose-ports.yml
index be0da42..d750ab9 100644
--- a/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
+++ b/infrastructure/cdn-in-a-box/optional/docker-compose.grafana.expose-ports.yml
@@ -15,49 +15,12 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-# This compose file will expose the ports of each service on the host.
-#
-#      docker-compose -f docker-compose.yml -f docker-compose.expose-ports.yml up
-#
+# Expose the Grafana container on the host on port 3000
 
 ---
 version: '2.1'
 
 services:
-  db:
-    ports:
-      - "5432:5432"
-  trafficops:
-    ports:
-      - "6443:443"
-  trafficops-perl:
-    ports:
-      - "60443:443"
-  trafficportal:
-    ports:
-      - "443:443"
-  trafficmonitor:
-    ports:
-      - "80:80"
-  trafficrouter:
-    ports:
-      - "3053:53"
-      - "3080:80"
-      - "3443:443"
-      - "3333:3333"
-  trafficvault:
-    ports:
-      - "8087:8087"
-      - "8098:8098"
-  edge:
-    ports:
-      - "9000:80"
-  mid:
-    ports:
-      - "9100:80"
-  origin:
-    ports:
-      - "9200:80"
-  dns:
+  grafana:
     ports:
-      - "9353:53"
+      - "3000:443"
diff --git a/infrastructure/cdn-in-a-box/optional/docker-compose.grafana.yml b/infrastructure/cdn-in-a-box/optional/docker-compose.grafana.yml
new file mode 100644
index 0000000..f9b3b1f
--- /dev/null
+++ b/infrastructure/cdn-in-a-box/optional/docker-compose.grafana.yml
@@ -0,0 +1,60 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# This container provide a Grafana service.
+# To start up CiaB with optional Grafana container:
+#
+# alias mydc="docker-compose "` \
+#   `"-f $PWD/docker-compose.yml "` \
+#   `"-f $PWD/optional/docker-compose.grafana.yml "`
+#
+# mydc rm -fv
+# mydc up
+#
+# Here are some links can be used to check grafana:
+#
+#  https://grafana.infra.ciab.test/dashboard/script/traffic_ops_cachegroup.js?which=CDN_in_a_Box_Edge
+#  https://grafana.infra.ciab.test/dashboard/script/traffic_ops_cachegroup.js?which=CDN_in_a_Box_Mid
+#  https://grafana.infra.ciab.test/dashboard/script/traffic_ops_deliveryservice.js?which=demo1
+#  https://grafana.infra.ciab.test/dashboard/script/traffic_ops_server.js?which=edge
+#  https://grafana.infra.ciab.test/dashboard/script/traffic_ops_server.js?which=mid
+
+
+---
+version: '2.1'
+
+services:
+  grafana:
+    build:
+      context: .
+      dockerfile: optional/grafana/Dockerfile
+    hostname: grafana
+    domainname: infra.ciab.test
+    depends_on:
+      - influxdb
+    env_file:
+      - variables.env
+    volumes:
+      - ./dns/set-dns.sh:/usr/local/sbin/set-dns.sh
+      - ./dns/insert-self-into-dns.sh:/usr/local/sbin/insert-self-into-dns.sh
+      - shared:/shared
+
+volumes:
+  schemas:
+    external: false
+  shared:
+    external: false
diff --git a/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml b/infrastructure/cdn-in-a-box/optional/grafana/Dockerfile
similarity index 51%
copy from infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
copy to infrastructure/cdn-in-a-box/optional/grafana/Dockerfile
index be0da42..a7fc121 100644
--- a/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
+++ b/infrastructure/cdn-in-a-box/optional/grafana/Dockerfile
@@ -14,50 +14,29 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-#
-# This compose file will expose the ports of each service on the host.
-#
-#      docker-compose -f docker-compose.yml -f docker-compose.expose-ports.yml up
-#
 
----
-version: '2.1'
+FROM grafana/grafana:5.4.3
+
+USER root
+ARG TRAFFIC_TS_RPM=traffic_stats/traffic_stats.rpm
+
+RUN apt-get update && \
+    apt-get install -y dnsutils net-tools gettext-base p7zip-full netcat && \
+    rm -rf /var/lib/apt/lists/*
+
+ADD enroller/server_template.json \
+    traffic_ops/to-access.sh \
+    optional/grafana/run-grafana.sh \
+    optional/grafana/datasources.yml.template \
+    $TRAFFIC_TS_RPM \
+    /
+
+RUN cd ~ \
+    && 7z x /traffic_stats.rpm \
+    && 7z e traffic_stats-*.cpio *.js -r \
+    && mv *.js /usr/share/grafana/public/dashboards \
+    && rm /traffic_stats.rpm \
+    && rm ~/traffic_stats-*.cpio
 
-services:
-  db:
-    ports:
-      - "5432:5432"
-  trafficops:
-    ports:
-      - "6443:443"
-  trafficops-perl:
-    ports:
-      - "60443:443"
-  trafficportal:
-    ports:
-      - "443:443"
-  trafficmonitor:
-    ports:
-      - "80:80"
-  trafficrouter:
-    ports:
-      - "3053:53"
-      - "3080:80"
-      - "3443:443"
-      - "3333:3333"
-  trafficvault:
-    ports:
-      - "8087:8087"
-      - "8098:8098"
-  edge:
-    ports:
-      - "9000:80"
-  mid:
-    ports:
-      - "9100:80"
-  origin:
-    ports:
-      - "9200:80"
-  dns:
-    ports:
-      - "9353:53"
+ENTRYPOINT [ "/run-grafana.sh" ]
+EXPOSE 443
diff --git a/infrastructure/cdn-in-a-box/optional/grafana/datasources.yml.template b/infrastructure/cdn-in-a-box/optional/grafana/datasources.yml.template
new file mode 100644
index 0000000..21536c3
--- /dev/null
+++ b/infrastructure/cdn-in-a-box/optional/grafana/datasources.yml.template
@@ -0,0 +1,53 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# Refer to "http://docs.grafana.org/administration/provisioning/#example-datasource-config-file"
+# for the variables usages
+
+datasources:
+- name: cache_stats
+  type: influxdb
+  access: proxy
+  orgId: 1
+  url: http://$INFLUXDB_HOST:$INFLUXDB_PORT
+  password: $INFLUXDB_ADMIN_PASSWORD
+  user: $INFLUXDB_ADMIN_USER
+  database: cache_stats
+  basicAuth: false
+  isDefault: true
+
+- name: daily_stats
+  type: influxdb
+  access: proxy
+  orgId: 1
+  url: http://$INFLUXDB_HOST:$INFLUXDB_PORT
+  password: $INFLUXDB_ADMIN_PASSWORD
+  user: $INFLUXDB_ADMIN_USER
+  database: daily_stats
+  basicAuth: false
+  isDefault: false
+
+- name: deliveryservice_stats
+  type: influxdb
+  access: proxy
+  orgId: 1
+  url: http://$INFLUXDB_HOST:$INFLUXDB_PORT
+  password: $INFLUXDB_ADMIN_PASSWORD
+  user: $INFLUXDB_ADMIN_USER
+  database: deliveryservice_stats
+  basicAuth: false
+  isDefault: false
diff --git a/infrastructure/cdn-in-a-box/optional/grafana/run-grafana.sh b/infrastructure/cdn-in-a-box/optional/grafana/run-grafana.sh
new file mode 100755
index 0000000..8a69a6d
--- /dev/null
+++ b/infrastructure/cdn-in-a-box/optional/grafana/run-grafana.sh
@@ -0,0 +1,58 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+set -e
+set -x
+set -m
+
+set-dns.sh
+insert-self-into-dns.sh
+
+source /to-access.sh
+
+# Wait on SSL certificate generation
+until [ -f "$X509_CA_DONE_FILE" ]
+do
+  echo "Waiting on Shared SSL certificate generation"
+  sleep 3
+done
+
+# Source the CIAB-CA shared SSL environment
+source "$X509_CA_ENV_FILE"
+
+# Copy the CIAB-CA certificate to here so it can be added to the trust store
+cp "$X509_CA_CERT_FULL_CHAIN_FILE" /usr/local/share/ca-certificates
+update-ca-certificates
+
+# Traffic Ops must be accepting connections before enroller can start
+until nc -z $TO_FQDN $TO_PORT </dev/null >/dev/null && to-ping; do
+  echo "Waiting for $TO_URL"
+  sleep 5
+done
+
+to-enroll grafana ALL "" "$GRAFANA_PORT" "$GRAFANA_PORT" || (while true; do echo "enroll failed."; sleep 3 ; done)
+
+export GF_SECURITY_ADMIN_USER=$GRAFANA_ADMIN_USER
+export GF_SECURITY_ADMIN_PASSWORD=$GRAFANA_ADMIN_PASSWORD
+export GF_SERVER_PROTOCOL="https"
+export GF_SERVER_HTTP_PORT=$GRAFANA_PORT
+export GF_SERVER_CERT_FILE=$X509_INFRA_CERT_FILE
+export GF_SERVER_CERT_KEY=$X509_INFRA_KEY_FILE
+envsubst < "/datasources.yml.template" > "$GF_PATHS_PROVISIONING/datasources/datasources.yml"
+
+/run.sh
diff --git a/infrastructure/cdn-in-a-box/traffic_ops/to-access.sh b/infrastructure/cdn-in-a-box/traffic_ops/to-access.sh
index 44e0d53..79d1a16 100644
--- a/infrastructure/cdn-in-a-box/traffic_ops/to-access.sh
+++ b/infrastructure/cdn-in-a-box/traffic_ops/to-access.sh
@@ -230,11 +230,26 @@ to-enroll() {
 			export MY_PROFILE="TRAFFIC_PORTAL"
 			export MY_STATUS="ONLINE"
 			;;
+		"ts" )
+			export MY_TYPE="TRAFFIC_STATS"
+			export MY_PROFILE="TRAFFIC_STATS"
+			export MY_STATUS="ONLINE"
+			;;
 		"tv" )
 			export MY_TYPE="RIAK"
 			export MY_PROFILE="RIAK_ALL"
 			export MY_STATUS="ONLINE"
 			;;
+		"influxdb" )
+			export MY_TYPE="INFLUXDB"
+			export MY_PROFILE="INFLUXDB"
+			export MY_STATUS="ONLINE"
+			;;
+		"grafana" )
+			export MY_TYPE="GRAFANA"
+			export MY_PROFILE="GRAFANA"
+			export MY_STATUS="ONLINE"
+			;;
 		* )
 			echo "Usage: to-enroll SERVER_TYPE" >&2
 			echo "(SERVER_TYPE must be a recognized server type)" >&2
diff --git a/infrastructure/cdn-in-a-box/traffic_ops_data/profiles/080-TRAFFIC_STATS.json b/infrastructure/cdn-in-a-box/traffic_ops_data/profiles/080-TRAFFIC_STATS.json
new file mode 100644
index 0000000..e9ef2ee
--- /dev/null
+++ b/infrastructure/cdn-in-a-box/traffic_ops_data/profiles/080-TRAFFIC_STATS.json
@@ -0,0 +1,234 @@
+{
+  "cdnName": "ALL",
+  "description": "Traffic_Stats profile",
+  "name": "TRAFFIC_STATS",
+  "routingDisabled": false,
+  "type": "TS_PROFILE",
+  "params": [
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "bandwidth"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "maxKbps"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.http.current_client_connections"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "DsStats",
+      "value": "kbps"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "DsStats",
+      "value": "tps_2xx"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "DsStats",
+      "value": "status_4xx"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "DsStats",
+      "value": "status_5xx"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "DsStats",
+      "value": "tps_3xx"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "DsStats",
+      "value": "tps_4xx"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "DsStats",
+      "value": "tps_5xx"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "DsStats",
+      "value": "tps_total"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.volume_1.wrap_count"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.volume_2.wrap_count"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.volume_1.write.failure"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.volume_1.write.success"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.ssl.cipher.user_agent.ECDHE-RSA-AES128-GCM-SHA256"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.ssl.cipher.user_agent.RC4-SHA"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.ssl.cipher.user_agent.RC4-MD5"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.ssl.cipher.user_agent.DES-CBC3-SHA"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.bytes_total"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.bytes_used"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.direntries.total"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.direntries.used"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.directory_collision"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.evacuate.active"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.evacuate.failure"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.evacuate.success"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.frags_per_doc.1"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.frags_per_doc.2"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.frags_per_doc.3+"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.gc_bytes_evacuated"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.gc_frags_evacuated"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.hdr_marshal_bytes"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.hdr_marshals"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.lookup.active"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.lookup.failure"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.lookup.success"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.ram_cache.bytes_used"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.ram_cache.total_bytes"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.ram_cache.hits"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.cache.ram_cache.misses"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.http.background_fill_bytes_aborted_stat"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.http.background_fill_bytes_completed_stat"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.process.http.background_fill_current_count"
+    },
+    {
+      "configFile": "traffic_stats.config",
+      "name": "CacheStats",
+      "value": "ats.proxy.node.cache.bytes_free"
+    }
+  ]
+}
diff --git a/infrastructure/cdn-in-a-box/traffic_ops_data/profiles/081-INFLUXDB.json b/infrastructure/cdn-in-a-box/traffic_ops_data/profiles/081-INFLUXDB.json
new file mode 100644
index 0000000..ea10c9f
--- /dev/null
+++ b/infrastructure/cdn-in-a-box/traffic_ops_data/profiles/081-INFLUXDB.json
@@ -0,0 +1,7 @@
+{
+  "cdnName": "ALL",
+  "description": "InfluxDB profile",
+  "name": "INFLUXDB",
+  "routingDisabled": false,
+  "type": "INFLUXDB_PROFILE"
+}
diff --git a/infrastructure/cdn-in-a-box/traffic_ops_data/profiles/082-GRAFANA.json b/infrastructure/cdn-in-a-box/traffic_ops_data/profiles/082-GRAFANA.json
new file mode 100644
index 0000000..054da91
--- /dev/null
+++ b/infrastructure/cdn-in-a-box/traffic_ops_data/profiles/082-GRAFANA.json
@@ -0,0 +1,7 @@
+{
+  "cdnName": "ALL",
+  "description": "Grafana profile",
+  "name": "GRAFANA",
+  "routingDisabled": false,
+  "type": "UNK_PROFILE"
+}
diff --git a/infrastructure/cdn-in-a-box/traffic_ops_data/types/050-GRAFANA.json b/infrastructure/cdn-in-a-box/traffic_ops_data/types/050-GRAFANA.json
new file mode 100644
index 0000000..6868b4f
--- /dev/null
+++ b/infrastructure/cdn-in-a-box/traffic_ops_data/types/050-GRAFANA.json
@@ -0,0 +1,5 @@
+{
+  "description": "Grafana Service",
+  "name": "GRAFANA",
+  "useInTable": "server"
+}
diff --git a/infrastructure/cdn-in-a-box/traffic_ops_data/users/030-tstats.json b/infrastructure/cdn-in-a-box/traffic_ops_data/users/030-tstats.json
new file mode 100644
index 0000000..dda460e
--- /dev/null
+++ b/infrastructure/cdn-in-a-box/traffic_ops_data/users/030-tstats.json
@@ -0,0 +1,9 @@
+{
+  "email": "$TS_EMAIL",
+  "fullName": "Traffic Stats",
+  "localPasswd": "$TS_PASSWORD",
+  "confirmLocalPasswd": "$TS_PASSWORD",
+  "rolename": "operations",
+  "tenant": "root",
+  "username": "$TS_USER"
+}
diff --git a/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml b/infrastructure/cdn-in-a-box/traffic_stats/Dockerfile
similarity index 51%
copy from infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
copy to infrastructure/cdn-in-a-box/traffic_stats/Dockerfile
index be0da42..952ddca 100644
--- a/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
+++ b/infrastructure/cdn-in-a-box/traffic_stats/Dockerfile
@@ -14,50 +14,31 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-#
-# This compose file will expose the ports of each service on the host.
-#
-#      docker-compose -f docker-compose.yml -f docker-compose.expose-ports.yml up
-#
+############################################################
+# Dockerfile to build Traffic Stats container images
+# Based on CentOS
+############################################################
+
+FROM centos:7
+
+# Default values for RPM -- override with `docker build --build-arg RPM=...'
+ARG TRAFFIC_TS_RPM=traffic_stats/traffic_stats.rpm
+ADD $TRAFFIC_TS_RPM /
+
+RUN yum install -y epel-release && \
+    yum install -y /$(basename $TRAFFIC_TS_RPM) \
+        jq \
+        nmap-ncat \
+        net-tools \
+        gettext \
+        bind-utils \
+        openssl && \
+    rm /$(basename $TRAFFIC_TS_RPM) && \
+    yum clean all
 
----
-version: '2.1'
+ADD enroller/server_template.json \
+    traffic_ops/to-access.sh \
+    traffic_stats/run.sh \
+    /
 
-services:
-  db:
-    ports:
-      - "5432:5432"
-  trafficops:
-    ports:
-      - "6443:443"
-  trafficops-perl:
-    ports:
-      - "60443:443"
-  trafficportal:
-    ports:
-      - "443:443"
-  trafficmonitor:
-    ports:
-      - "80:80"
-  trafficrouter:
-    ports:
-      - "3053:53"
-      - "3080:80"
-      - "3443:443"
-      - "3333:3333"
-  trafficvault:
-    ports:
-      - "8087:8087"
-      - "8098:8098"
-  edge:
-    ports:
-      - "9000:80"
-  mid:
-    ports:
-      - "9100:80"
-  origin:
-    ports:
-      - "9200:80"
-  dns:
-    ports:
-      - "9353:53"
+ENTRYPOINT /run.sh
diff --git a/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml b/infrastructure/cdn-in-a-box/traffic_stats/Dockerfile-influxdb
similarity index 51%
copy from infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
copy to infrastructure/cdn-in-a-box/traffic_stats/Dockerfile-influxdb
index be0da42..17cc208 100644
--- a/infrastructure/cdn-in-a-box/docker-compose.expose-ports.yml
+++ b/infrastructure/cdn-in-a-box/traffic_stats/Dockerfile-influxdb
@@ -14,50 +14,16 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-#
-# This compose file will expose the ports of each service on the host.
-#
-#      docker-compose -f docker-compose.yml -f docker-compose.expose-ports.yml up
-#
 
----
-version: '2.1'
+FROM influxdb:1.7.3
+
+RUN apt-get update && \
+    apt-get install -y dnsutils net-tools gettext-base netcat && \
+    rm -rf /var/lib/apt/lists/*
+
+ADD enroller/server_template.json \
+    traffic_ops/to-access.sh \
+    traffic_stats/run-influxdb.sh \
+    /
 
-services:
-  db:
-    ports:
-      - "5432:5432"
-  trafficops:
-    ports:
-      - "6443:443"
-  trafficops-perl:
-    ports:
-      - "60443:443"
-  trafficportal:
-    ports:
-      - "443:443"
-  trafficmonitor:
-    ports:
-      - "80:80"
-  trafficrouter:
-    ports:
-      - "3053:53"
-      - "3080:80"
-      - "3443:443"
-      - "3333:3333"
-  trafficvault:
-    ports:
-      - "8087:8087"
-      - "8098:8098"
-  edge:
-    ports:
-      - "9000:80"
-  mid:
-    ports:
-      - "9100:80"
-  origin:
-    ports:
-      - "9200:80"
-  dns:
-    ports:
-      - "9353:53"
+ENTRYPOINT ["/run-influxdb.sh"]
diff --git a/infrastructure/cdn-in-a-box/traffic_stats/run-influxdb.sh b/infrastructure/cdn-in-a-box/traffic_stats/run-influxdb.sh
new file mode 100755
index 0000000..c35f776
--- /dev/null
+++ b/infrastructure/cdn-in-a-box/traffic_stats/run-influxdb.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+set -e
+set -x
+set -m
+
+set-dns.sh
+insert-self-into-dns.sh
+
+source /to-access.sh
+
+# Wait on SSL certificate generation
+until [ -f "$X509_CA_DONE_FILE" ]
+do
+  echo "Waiting on Shared SSL certificate generation"
+  sleep 3
+done
+
+# Source the CIAB-CA shared SSL environment
+source "$X509_CA_ENV_FILE"
+
+# Copy the CIAB-CA certificate to here so it can be added to the trust store
+cp "$X509_CA_CERT_FULL_CHAIN_FILE" /usr/local/share/ca-certificates
+update-ca-certificates
+
+# Traffic Ops must be accepting connections before enroller can start
+until nc -z $TO_FQDN $TO_PORT </dev/null >/dev/null && to-ping; do
+  echo "Waiting for $TO_URL"
+  sleep 5
+done
+
+to-enroll influxdb ALL "" "$INFLUXDB_PORT" "$INFLUXDB_PORT" || (while true; do echo "enroll failed."; sleep 3 ; done)
+
+exec /entrypoint.sh influxd
diff --git a/infrastructure/cdn-in-a-box/traffic_stats/run.sh b/infrastructure/cdn-in-a-box/traffic_stats/run.sh
new file mode 100755
index 0000000..d5cb6dd
--- /dev/null
+++ b/infrastructure/cdn-in-a-box/traffic_stats/run.sh
@@ -0,0 +1,107 @@
+#!/usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Script for running the Dockerfile for Traffic Stats.
+# The Dockerfile sets up a Docker image which can be used for any new container;
+# This script, which should be run when the container is run (it's the ENTRYPOINT), will configure the container.
+#
+# The following environment variables must be set (ordinarily by `docker run -e` arguments):
+# TO_HOST
+# TO_PORT
+# INFLUXDB_HOST
+
+# Check that env vars are set
+
+set -e
+set -x
+set -m
+
+envvars=( TO_HOST TO_PORT INFLUXDB_HOST)
+for v in $envvars
+do
+  if [[ -z $$v ]]; then echo "$v is unset"; exit 1; fi
+done
+
+set-dns.sh
+insert-self-into-dns.sh
+
+source /to-access.sh
+
+# Wait on SSL certificate generation
+until [ -f "$X509_CA_DONE_FILE" ]
+do
+  echo "Waiting on Shared SSL certificate generation"
+  sleep 3
+done
+
+# Source the CIAB-CA shared SSL environment
+source $X509_CA_ENV_FILE
+
+# Trust the CIAB-CA at the System level
+cp $X509_CA_CERT_FULL_CHAIN_FILE /etc/pki/ca-trust/source/anchors
+update-ca-trust extract
+
+# Enroll with traffic ops
+TSCONF=/opt/traffic_stats/conf/traffic_stats.cfg
+to-enroll ts ALL || (while true; do echo "enroll failed."; sleep 3 ; done)
+
+while ! to-ping 2>/dev/null; do
+  echo "waiting for trafficops ($TO_URL)..."
+  sleep 3
+done
+
+cat <<-EOF >$TSCONF
+{
+	"toUser": "$TO_ADMIN_USER",
+	"toPasswd": "$TO_ADMIN_PASSWORD",
+	"toUrl": "$TO_URL",
+	"influxUser": "$INFLUXDB_ADMIN_USER",
+	"influxPassword": "$INFLUXDB_ADMIN_PASSWORD",
+	"pollingInterval": 10,
+	"publishingInterval": 30,
+	"maxPublishSize": 10000,
+	"statusToMon": "ONLINE",
+	"seelogConfig": "/opt/traffic_stats/conf/traffic_stats_seelog.xml",
+	"dailySummaryPollingInterval": 300,
+	"cacheRetentionPolicy": "daily",
+	"dsRetentionPolicy": "daily",
+	"dailySummaryRetentionPolicy": "indefinite",
+    "influxUrls": ["http://$INFLUXDB_HOST:$INFLUXDB_PORT"]
+}
+EOF
+
+touch /opt/traffic_stats/var/log/traffic_stats/traffic_stats.log
+
+# Wait for influxdb
+until nc $INFLUXDB_HOST $INFLUXDB_PORT </dev/null >/dev/null 2>&1; do
+  echo "Waiting for influxdb to start..."
+  sleep 3
+done
+
+/opt/traffic_stats/influxdb_tools/create_ts_databases -user $INFLUXDB_ADMIN_USER -password $INFLUXDB_ADMIN_PASSWORD -url http://$INFLUXDB_HOST:$INFLUXDB_PORT -replication 1
+
+# Wait for traffic monitor
+until nc $TM_FQDN $TM_PORT </dev/null >/dev/null 2>&1; do
+  echo "Waiting for Traffic Monitor to start..."
+  sleep 3
+done
+
+/opt/traffic_stats/bin/traffic_stats -cfg $TSCONF &
+
+exec tail -f /opt/traffic_stats/var/log/traffic_stats/traffic_stats.log
+
diff --git a/infrastructure/cdn-in-a-box/variables.env b/infrastructure/cdn-in-a-box/variables.env
index 7965779..9c20baf 100644
--- a/infrastructure/cdn-in-a-box/variables.env
+++ b/infrastructure/cdn-in-a-box/variables.env
@@ -47,6 +47,13 @@ ENROLLER_HOST=enroller
 PGPASSWORD=twelve
 POSTGRES_PASSWORD=twelve
 EDGE_HOST=edge
+INFLUXDB_HOST=influxdb
+INFLUXDB_PORT=8086
+INFLUXDB_ADMIN_USER=influxadmin
+INFLUXDB_ADMIN_PASSWORD=influxadminpassword
+GRAFANA_ADMIN_USER=grafanaadmin
+GRAFANA_ADMIN_PASSWORD=grafanaadminpassword
+GRAFANA_PORT=443
 MID_HOST=mid
 ORIGIN_HOST=origin
 TM_HOST=trafficmonitor
@@ -70,7 +77,10 @@ TR_HTTP_PORT=80
 TR_HTTPS_PORT=443
 TR_API_PORT=3333
 TP_PORT=443
+TS_EMAIL=tstats@cdn.example.com
 TS_HOST=trafficstats
+TS_PASSWORD=trafficstatspassword
+TS_USER=tstats
 TV_HOST=trafficvault
 TV_USER=tvault
 TV_PASSWORD=mwL5GP6Ghu_uJpkfjfiBmii3l9vfgLl0