diff --git a/magnum/api/app.py b/magnum/api/app.py
index ddbcaae94e..6f1c8166fc 100644
--- a/magnum/api/app.py
+++ b/magnum/api/app.py
@@ -36,7 +36,17 @@ API_SERVICE_OPTS = [
     cfg.StrOpt('api_paste_config',
                default="api-paste.ini",
                help="Configuration file for WSGI definition of API."
-               )
+               ),
+    cfg.StrOpt('ssl_cert_file',
+               help="This option allows setting path to the SSL certificate "
+                    "of API server. "),
+    cfg.StrOpt('ssl_key_file',
+               help="This option specifies the path to the file where SSL "
+                    "private key of API server is stored when SSL is in "
+                    "effect. "),
+    cfg.BoolOpt('enabled_ssl',
+                default=False,
+                help='Enable SSL Magnum API service')
 ]
 
 CONF = cfg.CONF
diff --git a/magnum/cmd/api.py b/magnum/cmd/api.py
index f9968c25fd..af81e41648 100644
--- a/magnum/cmd/api.py
+++ b/magnum/cmd/api.py
@@ -16,22 +16,41 @@
 
 import os
 import sys
-from wsgiref import simple_server
 
 from oslo_config import cfg
 from oslo_log import log as logging
 from oslo_reports import guru_meditation_report as gmr
+from werkzeug import serving
 
 from magnum.api import app as api_app
 from magnum.common import service
+from magnum.i18n import _
 from magnum.i18n import _LI
 from magnum.objects import base
 from magnum import version
 
-
+CONF = cfg.CONF
 LOG = logging.getLogger(__name__)
 
 
+def _get_ssl_configs(use_ssl):
+    if use_ssl:
+        cert_file = CONF.api.ssl_cert_file
+        key_file = CONF.api.ssl_key_file
+
+        if cert_file and not os.path.exists(cert_file):
+            raise RuntimeError(
+                _("Unable to find cert_file : %s") % cert_file)
+
+        if key_file and not os.path.exists(key_file):
+            raise RuntimeError(
+                _("Unable to find key_file : %s") % key_file)
+
+        return cert_file, key_file
+    else:
+        return None
+
+
 def main():
     service.prepare_service(sys.argv)
 
@@ -42,15 +61,18 @@ def main():
 
     app = api_app.load_app()
 
+    # SSL configuration
+    use_ssl = CONF.api.enabled_ssl
+
     # Create the WSGI server and start it
     host, port = cfg.CONF.api.host, cfg.CONF.api.port
-    srv = simple_server.make_server(host, port, app)
 
     LOG.info(_LI('Starting server in PID %s'), os.getpid())
     LOG.debug("Configuration:")
     cfg.CONF.log_opt_values(LOG, logging.DEBUG)
 
-    LOG.info(_LI('serving on http://%(host)s:%(port)s'),
-             dict(host=host, port=port))
+    LOG.info(_LI('Serving on %(proto)s://%(host)s:%(port)s'),
+             dict(proto="https" if use_ssl else "http", host=host, port=port))
 
-    srv.serve_forever()
+    serving.run_simple(host, port, app,
+                       ssl_context=_get_ssl_configs(use_ssl))
diff --git a/magnum/tests/unit/cmd/test_api.py b/magnum/tests/unit/cmd/test_api.py
index a7fa8b0085..e6ce096902 100644
--- a/magnum/tests/unit/cmd/test_api.py
+++ b/magnum/tests/unit/cmd/test_api.py
@@ -18,21 +18,79 @@ from magnum.cmd import api
 from magnum.tests import base
 
 
+# NOTE(hieulq): need to mock MagnumObject, otherwise other test cases
+# will be failed because of setting wrong ovo indirection api
+@mock.patch('magnum.objects.base.MagnumObject')
 class TestMagnumAPI(base.TestCase):
 
-    # NOTE(hieulq): need to mock MagnumObject, otherwise other test cases
-    # will be failed because of setting wrong ovo indirection api
-    @mock.patch('magnum.objects.base.MagnumObject')
-    @mock.patch('wsgiref.simple_server.make_server')
+    @mock.patch('werkzeug.serving.run_simple')
     @mock.patch.object(api, 'api_app')
     @mock.patch('magnum.common.service.prepare_service')
-    def test_api(self, mock_prep, mock_app, mock_make, mock_base):
+    def test_api_http(self, mock_prep, mock_app, mock_run, mock_base):
         api.main()
 
         app = mock_app.load_app.return_value
-        server = mock_make.return_value
         mock_prep.assert_called_once_with(mock.ANY)
         mock_app.load_app.assert_called_once_with()
-        mock_make.assert_called_once_with(base.CONF.api.host,
-                                          base.CONF.api.port, app)
-        server.serve_forever.assert_called_once_with()
+        mock_run.assert_called_once_with(base.CONF.api.host,
+                                         base.CONF.api.port,
+                                         app, ssl_context=None)
+
+    @mock.patch('os.path.exists')
+    @mock.patch('werkzeug.serving.run_simple')
+    @mock.patch.object(api, 'api_app')
+    @mock.patch('magnum.common.service.prepare_service')
+    def test_api_https_no_cert(self, mock_prep, mock_app, mock_run,
+                               mock_exist, mock_base):
+        self.config(enabled_ssl=True,
+                    ssl_cert_file='tmp_crt',
+                    group='api')
+        mock_exist.return_value = False
+
+        self.assertRaises(RuntimeError, api.main)
+        mock_prep.assert_called_once_with(mock.ANY)
+        mock_app.load_app.assert_called_once_with()
+        mock_run.assert_not_called()
+        mock_exist.assert_called_once_with('tmp_crt')
+
+    @mock.patch('os.path.exists')
+    @mock.patch('werkzeug.serving.run_simple')
+    @mock.patch.object(api, 'api_app')
+    @mock.patch('magnum.common.service.prepare_service')
+    def test_api_https_no_key(self, mock_prep, mock_app, mock_run,
+                              mock_exist, mock_base):
+        self.config(enabled_ssl=True,
+                    ssl_cert_file='tmp_crt',
+                    ssl_key_file='tmp_key',
+                    group='api')
+        mock_exist.side_effect = [True, False]
+
+        self.assertRaises(RuntimeError, api.main)
+        mock_prep.assert_called_once_with(mock.ANY)
+        mock_app.load_app.assert_called_once_with()
+        mock_run.assert_not_called()
+        mock_exist.assert_has_calls([mock.call('tmp_crt'),
+                                     mock.call('tmp_key')])
+
+    @mock.patch('os.path.exists')
+    @mock.patch('werkzeug.serving.run_simple')
+    @mock.patch.object(api, 'api_app')
+    @mock.patch('magnum.common.service.prepare_service')
+    def test_api_https(self, mock_prep, mock_app, mock_run,
+                       mock_exist, mock_base):
+        self.config(enabled_ssl=True,
+                    ssl_cert_file='tmp_crt',
+                    ssl_key_file='tmp_key',
+                    group='api')
+        mock_exist.side_effect = [True, True]
+
+        api.main()
+
+        app = mock_app.load_app.return_value
+        mock_prep.assert_called_once_with(mock.ANY)
+        mock_app.load_app.assert_called_once_with()
+        mock_exist.assert_has_calls([mock.call('tmp_crt'),
+                                     mock.call('tmp_key')])
+        mock_run.assert_called_once_with(base.CONF.api.host,
+                                         base.CONF.api.port, app,
+                                         ssl_context=('tmp_crt', 'tmp_key'))
diff --git a/releasenotes/notes/bug-1614596-support-ssl-magnum-api-e4896928c6562e03.yaml b/releasenotes/notes/bug-1614596-support-ssl-magnum-api-e4896928c6562e03.yaml
new file mode 100644
index 0000000000..456f2ba57f
--- /dev/null
+++ b/releasenotes/notes/bug-1614596-support-ssl-magnum-api-e4896928c6562e03.yaml
@@ -0,0 +1,6 @@
+---
+upgrade:
+  - Magnum now support SSL for API service. User can enable SSL for API
+    via new 3 config options 'enabled_ssl', 'ssl_cert_file' and 'ssl_key_file'.
+  - Change default API development service from wsgiref simple_server to
+    werkzeug for better supporting SSL.
diff --git a/requirements.txt b/requirements.txt
index eb5a8b18e8..48920ce655 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -55,3 +55,4 @@ stevedore>=1.16.0 # Apache-2.0
 taskflow>=1.26.0 # Apache-2.0
 cryptography!=1.3.0,>=1.0 # BSD/Apache-2.0
 urllib3>=1.15.1 # MIT
+Werkzeug>=0.7 # BSD License