diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml
index 5155d11867..a07819b53a 100644
--- a/ansible/group_vars/all.yml
+++ b/ansible/group_vars/all.yml
@@ -232,6 +232,9 @@ rabbitmq_management_port: "15672"
 rabbitmq_cluster_port: "25672"
 rabbitmq_epmd_port: "4369"
 
+redis_port: "6379"
+redis_sentinel_port: "26379"
+
 rdp_port: "8001"
 
 rgw_port: "6780"
@@ -397,6 +400,7 @@ enable_osprofiler: "no"
 enable_panko: "no"
 enable_qdrouterd: "no"
 enable_rally: "no"
+enable_redis: "no"
 enable_sahara: "no"
 enable_searchlight: "no"
 enable_senlin: "no"
diff --git a/ansible/inventory/all-in-one b/ansible/inventory/all-in-one
index 58ee74b831..efdb2bfce3 100644
--- a/ansible/inventory/all-in-one
+++ b/ansible/inventory/all-in-one
@@ -215,6 +215,9 @@ control
 [skydive:children]
 monitoring
 
+[redis:children]
+control
+
 # Additional control implemented here. These groups allow you to control which
 # services run on which hosts at a per-service level.
 #
diff --git a/ansible/inventory/multinode b/ansible/inventory/multinode
index 6bb1a49b2c..3c26989595 100644
--- a/ansible/inventory/multinode
+++ b/ansible/inventory/multinode
@@ -233,6 +233,9 @@ control
 [skydive:children]
 monitoring
 
+[redis:children]
+control
+
 # Additional control implemented here. These groups allow you to control which
 # services run on which hosts at a per-service level.
 #
diff --git a/ansible/roles/redis/defaults/main.yml b/ansible/roles/redis/defaults/main.yml
new file mode 100644
index 0000000000..3ff30a8c3c
--- /dev/null
+++ b/ansible/roles/redis/defaults/main.yml
@@ -0,0 +1,34 @@
+---
+project_name: "redis"
+
+redis_services:
+  redis:
+    container_name: redis
+    group: redis
+    enabled: true
+    image: "{{ redis_image_full }}"
+    volumes:
+      - "{{ node_config_directory }}/redis/:{{ container_config_directory }}/:ro"
+      - "/etc/localtime:/etc/localtime:ro"
+      - "{{ project_name }}:/var/lib/redis/"
+      - "kolla_logs:/var/log/kolla/"
+  redis-sentinel:
+    container_name: redis_sentinel
+    group: redis
+    enabled: true
+    image: "{{ redis_sentinel_image_full }}"
+    volumes:
+      - "{{ node_config_directory }}/redis-sentinel/:{{ container_config_directory }}/:ro"
+      - "/etc/localtime:/etc/localtime:ro"
+      - "kolla_logs:/var/log/kolla/"
+
+####################
+# Docker
+####################
+redis_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ kolla_install_type }}-redis"
+redis_tag: "{{ openstack_release }}"
+redis_image_full: "{{ redis_image }}:{{ redis_tag }}"
+
+redis_sentinel_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ kolla_install_type }}-redis-sentinel"
+redis_sentinel_tag: "{{ openstack_release }}"
+redis_sentinel_image_full: "{{ redis_sentinel_image }}:{{ redis_tag }}"
diff --git a/ansible/roles/redis/handlers/main.yml b/ansible/roles/redis/handlers/main.yml
new file mode 100644
index 0000000000..a2dbf0a9c1
--- /dev/null
+++ b/ansible/roles/redis/handlers/main.yml
@@ -0,0 +1,42 @@
+---
+- name: Restart redis container
+  vars:
+    service_name: "redis"
+    service: "{{ redis_services[service_name] }}"
+    config_json: "{{ redis_config_jsons.results|selectattr('item.key', 'equalto', service_name)|first }}"
+    redis_conf: "{{ redis_confs.results|selectattr('item.key', 'equalto', service_name)|first }}"
+    redis_container: "{{ check_redis_containers.results|selectattr('item.key', 'equalto', service_name)|first }}"
+  kolla_docker:
+    action: "recreate_or_restart_container"
+    common_options: "{{ docker_common_options }}"
+    name: "{{ service.container_name }}"
+    image: "{{ service.image }}"
+    volumes: "{{ service.volumes }}"
+  when:
+    - action != "config"
+    - inventory_hostname in groups[service.group]
+    - service.enabled | bool
+    - config_json.changed | bool
+      or redis_confs.changed |bool
+      or redis_container.changed | bool
+
+- name: Restart redis-sentinel container
+  vars:
+    service_name: "redis-sentinel"
+    service: "{{ redis_services[service_name] }}"
+    config_json: "{{ redis_config_jsons.results|selectattr('item.key', 'equalto', service_name)|first }}"
+    redis_conf: "{{ redis_confs.results|selectattr('item.key', 'equalto', service_name)|first }}"
+    redis_container: "{{ check_redis_containers.results|selectattr('item.key', 'equalto', service_name)|first }}"
+  kolla_docker:
+    action: "recreate_or_restart_container"
+    common_options: "{{ docker_common_options }}"
+    name: "{{ service.container_name }}"
+    image: "{{ service.image }}"
+    volumes: "{{ service.volumes }}"
+  when:
+    - action != "config"
+    - inventory_hostname in groups[service.group]
+    - service.enabled | bool
+    - config_json.changed | bool
+      or redis_confs.changed |bool
+      or redis_container.changed | bool
diff --git a/ansible/roles/redis/meta/main.yml b/ansible/roles/redis/meta/main.yml
new file mode 100644
index 0000000000..6b4fff8fef
--- /dev/null
+++ b/ansible/roles/redis/meta/main.yml
@@ -0,0 +1,3 @@
+---
+dependencies:
+  - { role: common }
diff --git a/ansible/roles/redis/tasks/config.yml b/ansible/roles/redis/tasks/config.yml
new file mode 100644
index 0000000000..7ae888ba31
--- /dev/null
+++ b/ansible/roles/redis/tasks/config.yml
@@ -0,0 +1,50 @@
+---
+- name: Ensuring config directories exist
+  file:
+    path: "{{ node_config_directory }}/{{ item.key }}"
+    state: "directory"
+    recurse: yes
+  when:
+    - inventory_hostname in groups[item.value.group]
+    - item.value.enabled | bool
+  with_dict: "{{ redis_services }}"
+
+- name: Copying over default config.json files
+  template:
+    src: "{{ item.key }}.json.j2"
+    dest: "{{ node_config_directory }}/{{ item.key }}/config.json"
+  register: redis_config_jsons
+  when:
+    - inventory_hostname in groups[item.value.group]
+    - item.value.enabled | bool
+  with_dict: "{{ redis_services }}"
+  notify:
+    - Restart {{ item.key }} container
+
+- name: Copying over redis config files
+  template:
+    src: "{{ item.key }}.conf.j2"
+    dest: "{{ node_config_directory }}/{{ item.key }}/redis.conf"
+  register: redis_confs
+  when:
+    - inventory_hostname in groups[item.value.group]
+    - item.value.enabled | bool
+  with_dict: "{{ redis_services }}"
+  notify:
+    - Restart {{ item.key }} container
+
+- name: Check redis containers
+  kolla_docker:
+    action: "compare_container"
+    common_options: "{{ docker_common_options }}"
+    name: "{{ item.value.container_name }}"
+    image: "{{ item.value.image }}"
+    volumes: "{{ item.value.volumes }}"
+  register: check_redis_containers
+  when:
+    - action != "config"
+    - inventory_hostname in groups[item.value.group]
+    - item.value.enabled | bool
+  with_dict: "{{ redis_services }}"
+  notify:
+    - Restart {{ item.key }} container
diff --git a/ansible/roles/redis/tasks/deploy.yml b/ansible/roles/redis/tasks/deploy.yml
new file mode 100644
index 0000000000..dd26ecc34d
--- /dev/null
+++ b/ansible/roles/redis/tasks/deploy.yml
@@ -0,0 +1,5 @@
+---
+- include: config.yml
+
+- name: Flush handlers
+  meta: flush_handlers
diff --git a/ansible/roles/redis/tasks/main.yml b/ansible/roles/redis/tasks/main.yml
new file mode 100644
index 0000000000..b017e8b4ad
--- /dev/null
+++ b/ansible/roles/redis/tasks/main.yml
@@ -0,0 +1,2 @@
+---
+- include: "{{ action }}.yml"
diff --git a/ansible/roles/redis/tasks/precheck.yml b/ansible/roles/redis/tasks/precheck.yml
new file mode 100644
index 0000000000..ec94321cdb
--- /dev/null
+++ b/ansible/roles/redis/tasks/precheck.yml
@@ -0,0 +1,20 @@
+---
+- name: Get container facts
+  kolla_container_facts:
+    name:
+      - redis
+  register: container_facts
+
+- name: Checking free port for Redis
+  vars:
+    redis: "{{ redis_services['redis'] }}"
+  wait_for:
+    host: "{{ api_interface_address }}"
+    port: "{{ redis_port }}"
+    connect_timeout: 1
+    timeout: 1
+    state: stopped
+  when:
+    - container_facts['redis'] is not defined
+    - inventory_hostname in groups[redis.group]
+    - redis.enabled | bool
diff --git a/ansible/roles/redis/tasks/pull.yml b/ansible/roles/redis/tasks/pull.yml
new file mode 100644
index 0000000000..6fefbdbf2c
--- /dev/null
+++ b/ansible/roles/redis/tasks/pull.yml
@@ -0,0 +1,10 @@
+---
+- name: Pulling redis images
+  kolla_docker:
+    action: "pull_image"
+    common_options: "{{ docker_common_options }}"
+    image: "{{ item.value.image }}"
+  when:
+    - inventory_hostname in groups[item.value.group]
+    - item.value.enabled | bool
+  with_dict: "{{ redis_services }}"
diff --git a/ansible/roles/redis/tasks/reconfigure.yml b/ansible/roles/redis/tasks/reconfigure.yml
new file mode 100644
index 0000000000..56169f9727
--- /dev/null
+++ b/ansible/roles/redis/tasks/reconfigure.yml
@@ -0,0 +1,2 @@
+---
+- include: "deploy.yml"
diff --git a/ansible/roles/redis/tasks/upgrade.yml b/ansible/roles/redis/tasks/upgrade.yml
new file mode 100644
index 0000000000..dd26ecc34d
--- /dev/null
+++ b/ansible/roles/redis/tasks/upgrade.yml
@@ -0,0 +1,5 @@
+---
+- include: config.yml
+
+- name: Flush handlers
+  meta: flush_handlers
diff --git a/ansible/roles/redis/templates/redis-sentinel.conf.j2 b/ansible/roles/redis/templates/redis-sentinel.conf.j2
new file mode 100644
index 0000000000..0e034e9a33
--- /dev/null
+++ b/ansible/roles/redis/templates/redis-sentinel.conf.j2
@@ -0,0 +1,11 @@
+{% set redis_master_address = hostvars[groups['redis'][0]]['ansible_' + hostvars[groups['redis'][0]]['api_interface']]['ipv4']['address'] %}
+daemonize no
+pidfile "/var/run/redis/redis-sentinel.pid"
+logfile "/var/log/kolla/redis/redis-sentinel.log"
+bind {{ api_interface_address }}
+port {{ redis_sentinel_port }}
+sentinel monitor kolla {{ redis_master_address }} {{ redis_port }} 2
+sentinel auth-pass kolla {{ redis_master_password }}
+sentinel down-after-milliseconds kolla 5000
+sentinel failover-timeout kolla 60000
+sentinel parallel-syncs kolla 1
diff --git a/ansible/roles/redis/templates/redis-sentinel.json.j2 b/ansible/roles/redis/templates/redis-sentinel.json.j2
new file mode 100644
index 0000000000..b8df171bb0
--- /dev/null
+++ b/ansible/roles/redis/templates/redis-sentinel.json.j2
@@ -0,0 +1,18 @@
+{
+    "command": "redis-sentinel /etc/redis/redis.conf",
+    "config_files": [
+        {
+            "source": "{{ container_config_directory }}/redis.conf",
+            "dest": "/etc/redis/redis.conf",
+            "owner": "redis",
+            "perm": "0600"
+        }
+    ],
+    "permissions": [
+        {
+            "path": "/var/log/kolla/redis",
+            "owner": "redis:redis",
+            "recurse": true
+        }
+    ]
+}
diff --git a/ansible/roles/redis/templates/redis.conf.j2 b/ansible/roles/redis/templates/redis.conf.j2
new file mode 100644
index 0000000000..e96f359d59
--- /dev/null
+++ b/ansible/roles/redis/templates/redis.conf.j2
@@ -0,0 +1,55 @@
+bind {{ api_interface_address }}
+port {{ redis_port }}
+tcp-backlog 511
+timeout 0
+tcp-keepalive 300
+daemonize no
+pidfile /var/run/redis/redis-server.pid
+loglevel notice
+logfile /var/log/kolla/redis/redis.log
+databases 16
+save 900 1
+save 300 10
+save 60 10000
+stop-writes-on-bgsave-error yes
+rdbcompression yes
+rdbchecksum yes
+dbfilename dump.rdb
+dir /var/lib/redis
+slave-serve-stale-data yes
+slave-read-only yes
+repl-diskless-sync no
+repl-diskless-sync-delay 5
+repl-disable-tcp-nodelay no
+slave-priority 100
+appendonly yes
+appendfilename "redis-staging-ao.aof"
+appendfsync everysec
+no-appendfsync-on-rewrite no
+auto-aof-rewrite-percentage 100
+auto-aof-rewrite-min-size 64mb
+aof-load-truncated yes
+lua-time-limit 5000
+slowlog-log-slower-than 10000
+slowlog-max-len 128
+latency-monitor-threshold 0
+notify-keyspace-events ""
+hash-max-ziplist-entries 512
+hash-max-ziplist-value 64
+set-max-intset-entries 512
+zset-max-ziplist-entries 128
+zset-max-ziplist-value 64
+hll-sparse-max-bytes 3000
+activerehashing yes
+client-output-buffer-limit normal 0 0 0
+client-output-buffer-limit slave 256mb 64mb 60
+client-output-buffer-limit pubsub 32mb 8mb 60
+hz 10
+aof-rewrite-incremental-fsync yes
+requirepass {{ redis_master_password }}
+masterauth {{ redis_master_password }}
+
+{% if inventory_hostname != groups['redis'][0] %}
+{% set redis_master_address = hostvars[groups['redis'][0]]['ansible_' + hostvars[groups['redis'][0]]['api_interface']]['ipv4']['address'] %}
+slaveof {{ redis_master_address }} 6379
+{% endif %}
diff --git a/ansible/roles/redis/templates/redis.json.j2 b/ansible/roles/redis/templates/redis.json.j2
new file mode 100644
index 0000000000..063c2ad69f
--- /dev/null
+++ b/ansible/roles/redis/templates/redis.json.j2
@@ -0,0 +1,18 @@
+{
+    "command": "redis-server /etc/redis/redis.conf",
+    "config_files": [
+        {
+            "source": "{{ container_config_directory }}/redis.conf",
+            "dest": "/etc/redis/redis.conf",
+            "owner": "redis",
+            "perm": "0600"
+        }
+    ],
+    "permissions": [
+        {
+            "path": "/var/log/kolla/redis",
+            "owner": "redis:redis",
+            "recurse": true
+        }
+    ]
+}
diff --git a/ansible/site.yml b/ansible/site.yml
index da683b1d0d..261667d5c5 100644
--- a/ansible/site.yml
+++ b/ansible/site.yml
@@ -103,6 +103,16 @@
         tags: telegraf,
         when: enable_telegraf | bool }
 
+- name: Apply role redis
+  gather_facts: false
+  hosts:
+    - redis
+  serial: '{{ serial|default("0") }}'
+  roles:
+    - { role: redis,
+        tags: redis,
+        when: enable_redis | bool }
+
 - name: Apply role haproxy
   gather_facts: false
   hosts:
diff --git a/etc/kolla/globals.yml b/etc/kolla/globals.yml
index 1cf7e0aaa8..0699b313e4 100644
--- a/etc/kolla/globals.yml
+++ b/etc/kolla/globals.yml
@@ -197,6 +197,7 @@ kolla_internal_vip_address: "10.10.10.254"
 #enable_panko: "no"
 #enable_qdrouterd: "no"
 #enable_rally: "no"
+#enable_redis: "no"
 #enable_sahara: "no"
 #enable_searchlight: "no"
 #enable_senlin: "no"
diff --git a/etc/kolla/passwords.yml b/etc/kolla/passwords.yml
index b126c5a131..f376e31f09 100644
--- a/etc/kolla/passwords.yml
+++ b/etc/kolla/passwords.yml
@@ -209,3 +209,8 @@ kibana_password:
 # etcd options
 ####################
 etcd_cluster_token:
+
+####################
+# redis options
+####################
+redis_master_password: