diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml
index 31db08125b..b1a84f7e10 100644
--- a/ansible/group_vars/all.yml
+++ b/ansible/group_vars/all.yml
@@ -110,6 +110,7 @@ ironic_api_port: "6385"
 
 magnum_api_port: "9511"
 
+rgw_port: "6780"
 
 ####################
 # Openstack options
@@ -155,6 +156,7 @@ enable_rabbitmq: "yes"
 
 # Additional optional OpenStack services are specified here
 enable_ceph: "no"
+enable_ceph_rgw: "no"
 enable_cinder: "no"
 enable_heat: "yes"
 enable_horizon: "yes"
diff --git a/ansible/inventory/all-in-one b/ansible/inventory/all-in-one
index 458ea36f24..fcf28a8c09 100644
--- a/ansible/inventory/all-in-one
+++ b/ansible/inventory/all-in-one
@@ -57,6 +57,9 @@ control
 [ceph-mon:children]
 control
 
+[ceph-rgw:children]
+control
+
 [ceph-osd:children]
 storage
 
diff --git a/ansible/roles/ceph/defaults/main.yml b/ansible/roles/ceph/defaults/main.yml
index 08fffde130..74d13c69e6 100644
--- a/ansible/roles/ceph/defaults/main.yml
+++ b/ansible/roles/ceph/defaults/main.yml
@@ -17,6 +17,9 @@ ceph_data_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docke
 ceph_data_tag: "{{ openstack_release }}"
 ceph_data_image_full: "{{ ceph_data_image }}:{{ ceph_data_tag }}"
 
+ceph_rgw_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ kolla_install_type }}-ceph-rgw"
+ceph_rgw_tag: "{{ openstack_release }}"
+ceph_rgw_image_full: "{{ ceph_rgw_image }}:{{ ceph_rgw_tag }}"
 
 ####################
 # Ceph
diff --git a/ansible/roles/ceph/tasks/config.yml b/ansible/roles/ceph/tasks/config.yml
index 891a0e7ef8..21ae654b9d 100644
--- a/ansible/roles/ceph/tasks/config.yml
+++ b/ansible/roles/ceph/tasks/config.yml
@@ -7,6 +7,7 @@
   with_items:
     - "ceph-mon"
     - "ceph-osd"
+    - "ceph-rgw"
 
 - name: Copying over config.json files for services
   template:
@@ -15,6 +16,7 @@
   with_items:
     - "ceph-mon"
     - "ceph-osd"
+    - "ceph-rgw"
 
 - name: Copying over ceph.conf
   merge_configs:
@@ -27,3 +29,4 @@
   with_items:
     - "ceph-mon"
     - "ceph-osd"
+    - "ceph-rgw"
diff --git a/ansible/roles/ceph/tasks/distribute_keyrings.yml b/ansible/roles/ceph/tasks/distribute_keyrings.yml
index 10ec0a8ddf..95658e455b 100644
--- a/ansible/roles/ceph/tasks/distribute_keyrings.yml
+++ b/ansible/roles/ceph/tasks/distribute_keyrings.yml
@@ -32,3 +32,14 @@
     - "{{ ceph_files['ceph.client.mon.keyring'] }}"
     - "{{ ceph_files['ceph.monmap'] }}"
   when: inventory_hostname in groups['ceph-mon']
+
+- name: Pushing Ceph keyrings for RGWs
+  bslurp:
+    src: "{{ item.content }}"
+    dest: "{{ node_config_directory }}/ceph-rgw/{{ item.filename }}"
+    mode: 0600
+    sha1: "{{ item.sha1 }}"
+  with_items:
+    - "{{ ceph_files['ceph.client.admin.keyring'] }}"
+    - "{{ ceph_files['ceph.client.radosgw.keyring'] }}"
+  when: inventory_hostname in groups['ceph-rgw']
diff --git a/ansible/roles/ceph/tasks/main.yml b/ansible/roles/ceph/tasks/main.yml
index 63dca3460f..403265af74 100644
--- a/ansible/roles/ceph/tasks/main.yml
+++ b/ansible/roles/ceph/tasks/main.yml
@@ -14,3 +14,8 @@
 
 - include: start_osds.yml
   when: inventory_hostname in groups['ceph-osd']
+
+- include: start_rgws.yml
+  when:
+    - inventory_hostname in groups['ceph-rgw']
+    - enable_ceph_rgw | bool
diff --git a/ansible/roles/ceph/tasks/start_rgws.yml b/ansible/roles/ceph/tasks/start_rgws.yml
new file mode 100644
index 0000000000..68d5516ba0
--- /dev/null
+++ b/ansible/roles/ceph/tasks/start_rgws.yml
@@ -0,0 +1,19 @@
+---
+- name: Starting ceph-rgw container
+  docker:
+    tty: True
+    net: host
+    pull: "{{ docker_pull_policy }}"
+    restart_policy: "{{ docker_restart_policy }}"
+    restart_policy_retry: "{{ docker_restart_policy_retry }}"
+    state: reloaded
+    registry: "{{ docker_registry }}"
+    username: "{{ docker_registry_username }}"
+    password: "{{ docker_registry_password }}"
+    insecure_registry: "{{ docker_insecure_registry }}"
+    name: ceph_rgw
+    image: "{{ ceph_rgw_image_full }}"
+    volumes: "{{ node_config_directory }}/ceph-rgw/:{{ container_config_directory }}/:ro"
+    env:
+      KOLLA_CONFIG_STRATEGY: "{{ config_strategy }}"
+  when: inventory_hostname in groups['ceph-rgw']
diff --git a/ansible/roles/ceph/templates/ceph-rgw.json.j2 b/ansible/roles/ceph/templates/ceph-rgw.json.j2
new file mode 100644
index 0000000000..5a0b043f4d
--- /dev/null
+++ b/ansible/roles/ceph/templates/ceph-rgw.json.j2
@@ -0,0 +1,25 @@
+{
+    "command": "/usr/bin/radosgw -c /etc/ceph/ceph.conf -n client.radosgw.gateway -d",
+    "config_files": [
+        {
+            "source": "{{ container_config_directory }}/ceph.conf",
+            "dest": "/etc/ceph/ceph.conf",
+            "owner": "ceph",
+            "perm": "0600"
+        },
+        {
+            "source": "{{ container_config_directory }}/ceph.client.admin.keyring",
+            "dest": "/etc/ceph/ceph.client.admin.keyring",
+            "owner": "ceph",
+            "perm": "0600",
+            "optional": "True"
+        },
+        {
+            "source": "{{ container_config_directory }}/ceph.client.radosgw.keyring",
+            "dest": "/etc/ceph/ceph.client.radosgw.keyring",
+            "owner": "ceph",
+            "perm": "0600",
+            "optional": "True"
+        }
+    ]
+}
diff --git a/ansible/roles/ceph/templates/ceph.conf.j2 b/ansible/roles/ceph/templates/ceph.conf.j2
index 1c3136c45e..a91435a79e 100644
--- a/ansible/roles/ceph/templates/ceph.conf.j2
+++ b/ansible/roles/ceph/templates/ceph.conf.j2
@@ -7,3 +7,11 @@ mon host = {% for host in groups['ceph-mon'] %}{{ hostvars[host]['ansible_' + ho
 auth cluster required = cephx
 auth service required = cephx
 auth client required = cephx
+
+{% if service_name is defined and service_name == 'ceph-rgw' %}
+[client.radosgw.gateway]
+host = {{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}
+keyring = /etc/ceph/ceph.client.radosgw.keyring
+log file = /var/log/radosgw/client.radosgw.gateway.log
+rgw frontends = civetweb port={{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}:{{ rgw_port }}
+{% endif %}
diff --git a/ansible/roles/haproxy/templates/haproxy.cfg.j2 b/ansible/roles/haproxy/templates/haproxy.cfg.j2
index beac9c2962..fd520d6edd 100644
--- a/ansible/roles/haproxy/templates/haproxy.cfg.j2
+++ b/ansible/roles/haproxy/templates/haproxy.cfg.j2
@@ -173,3 +173,11 @@ listen magnum_api
   server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ magnum_api_port }} check inter 2000 rise 2 fall 5
 {% endfor %}
 {% endif %}
+
+{% if enable_ceph | bool and enable_ceph_rgw | bool %}
+listen radosgw
+  bind {{ kolla_internal_address}}:{{ rgw_port }}
+{% for host in groups['ceph-rgw'] %}
+  server {{ hostvars[host]['ansible_hostname'] }} {{ hostvars[host]['ansible_' + hostvars[host]['api_interface']]['ipv4']['address'] }}:{{ rgw_port }} check inter 2000 rise 2 fall 5
+{% endfor %}
+{% endif %}
diff --git a/ansible/roles/prechecks/tasks/port_checks.yml b/ansible/roles/prechecks/tasks/port_checks.yml
index 0df4a2e716..d62ba6ed31 100644
--- a/ansible/roles/prechecks/tasks/port_checks.yml
+++ b/ansible/roles/prechecks/tasks/port_checks.yml
@@ -406,3 +406,19 @@
     connect_timeout: 1
     state: stopped
   when: inventory_hostname in groups['haproxy']
+
+- name: Checking free port for RadosGW
+  wait_for:
+    host: "{{ hostvars[inventory_hostname]['ansible_' + api_interface]['ipv4']['address'] }}"
+    port: "{{ rgw_port }}"
+    connect_timeout: 1
+    state: stopped
+  when: inventory_hostname in groups['ceph-rgw']
+
+- name: Checking free port for RadosGW HAProxy
+  wait_for:
+    host: "{{ kolla_internal_address }}"
+    port: "{{ rgw_port }}"
+    connect_timeout: 1
+    state: stopped
+  when: inventory_hostname in groups['haproxy']
diff --git a/ansible/site.yml b/ansible/site.yml
index 3b43fd4974..49b2b135a0 100644
--- a/ansible/site.yml
+++ b/ansible/site.yml
@@ -2,6 +2,7 @@
 - hosts:
     - ceph-mon
     - ceph-osd
+    - ceph-rgw
   roles:
     - { role: ceph,
         tags: ceph,
diff --git a/docker/ceph/ceph-base/Dockerfile.j2 b/docker/ceph/ceph-base/Dockerfile.j2
index 32288f7dd8..c51cad8196 100644
--- a/docker/ceph/ceph-base/Dockerfile.j2
+++ b/docker/ceph/ceph-base/Dockerfile.j2
@@ -5,6 +5,7 @@ MAINTAINER {{ maintainer }}
 
 RUN yum -y install \
         ceph \
+        ceph-radosgw \
         parted \
         hdparm \
     && yum clean all
@@ -13,6 +14,7 @@ RUN yum -y install \
 
 RUN apt-get install -y --no-install-recommends \
         ceph \
+        radosgw \
         parted \
         hdparm \
     && apt-get clean
diff --git a/docker/ceph/ceph-mon/Dockerfile.j2 b/docker/ceph/ceph-mon/Dockerfile.j2
index 6fdaff6ee3..38c8d26f6f 100644
--- a/docker/ceph/ceph-mon/Dockerfile.j2
+++ b/docker/ceph/ceph-mon/Dockerfile.j2
@@ -5,3 +5,5 @@ COPY fetch_ceph_keys.py /usr/bin/
 
 COPY extend_start.sh /usr/local/bin/kolla_extend_start
 RUN chmod 755 /usr/local/bin/kolla_extend_start /usr/bin/fetch_ceph_keys.py
+
+{{ include_footer }}
diff --git a/docker/ceph/ceph-mon/extend_start.sh b/docker/ceph/ceph-mon/extend_start.sh
index dce6749b31..3b8246e373 100644
--- a/docker/ceph/ceph-mon/extend_start.sh
+++ b/docker/ceph/ceph-mon/extend_start.sh
@@ -3,6 +3,7 @@
 # Setup common paths
 KEYRING_ADMIN="/etc/ceph/ceph.client.admin.keyring"
 KEYRING_MON="/etc/ceph/ceph.client.mon.keyring"
+KEYRING_RGW="/etc/ceph/ceph.client.radosgw.keyring"
 MONMAP="/etc/ceph/ceph.monmap"
 MON_DIR="/var/lib/ceph/mon/ceph-$(hostname)"
 
@@ -15,7 +16,9 @@ if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then
     # Generating initial keyrings and monmap
     ceph-authtool --create-keyring "${KEYRING_MON}" --gen-key -n mon. --cap mon 'allow *'
     ceph-authtool --create-keyring "${KEYRING_ADMIN}" --gen-key -n client.admin --set-uid=0 --cap mon 'allow *' --cap osd 'allow *' --cap mds 'allow'
+    ceph-authtool --create-keyring "${KEYRING_RGW}" --gen-key -n client.radosgw.gateway --set-uid=0 --cap osd 'allow rwx' --cap mon 'allow rwx'
     ceph-authtool "${KEYRING_MON}" --import-keyring "${KEYRING_ADMIN}"
+    ceph-authtool "${KEYRING_MON}" --import-keyring "${KEYRING_RGW}"
     monmaptool --create --add "$(hostname)" "${MON_IP}" --fsid "${FSID}" "${MONMAP}"
 
     echo "Sleeping until keys are fetched"
diff --git a/docker/ceph/ceph-mon/fetch_ceph_keys.py b/docker/ceph/ceph-mon/fetch_ceph_keys.py
index ab2be9c16f..3303bdf5c0 100644
--- a/docker/ceph/ceph-mon/fetch_ceph_keys.py
+++ b/docker/ceph/ceph-mon/fetch_ceph_keys.py
@@ -57,9 +57,10 @@ def read_file(filename):
 def main():
     admin_keyring = 'ceph.client.admin.keyring'
     mon_keyring = 'ceph.client.mon.keyring'
+    rgw_keyring = 'ceph.client.radosgw.keyring'
     monmap = 'ceph.monmap'
 
-    files = [admin_keyring, mon_keyring, monmap]
+    files = [admin_keyring, mon_keyring, rgw_keyring, monmap]
     json_exit({filename: read_file(filename) for filename in files})
 
 
diff --git a/docker/ceph/ceph-osd/Dockerfile.j2 b/docker/ceph/ceph-osd/Dockerfile.j2
index 9026907dea..03e4dceda5 100644
--- a/docker/ceph/ceph-osd/Dockerfile.j2
+++ b/docker/ceph/ceph-osd/Dockerfile.j2
@@ -3,3 +3,5 @@ MAINTAINER {{ maintainer }}
 
 COPY extend_start.sh /usr/local/bin/kolla_extend_start
 RUN chmod 755 /usr/local/bin/kolla_extend_start
+
+{{ include_footer }}
diff --git a/docker/ceph/ceph-rgw/Dockerfile.j2 b/docker/ceph/ceph-rgw/Dockerfile.j2
new file mode 100644
index 0000000000..cf60009064
--- /dev/null
+++ b/docker/ceph/ceph-rgw/Dockerfile.j2
@@ -0,0 +1,4 @@
+FROM {{ namespace }}/{{ image_prefix }}ceph-base:{{ tag }}
+MAINTAINER {{ maintainer }}
+
+{{ include_footer }}