diff --git a/functional/tests/common/test_availability_zone.py b/functional/tests/common/test_availability_zone.py
new file mode 100644
index 0000000000..9296db23d7
--- /dev/null
+++ b/functional/tests/common/test_availability_zone.py
@@ -0,0 +1,25 @@
+#    Licensed 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.
+
+from functional.common import test
+
+
+class AvailabilityZoneTests(test.TestCase):
+    """Functional tests for availability zone. """
+    HEADERS = ["'Zone Name'"]
+    # So far, all components have the same default availability zone name.
+    DEFAULT_AZ_NAME = 'nova'
+
+    def test_availability_zone_list(self):
+        opts = self.get_list_opts(self.HEADERS)
+        raw_output = self.openstack('availability zone list' + opts)
+        self.assertIn(self.DEFAULT_AZ_NAME, raw_output)
diff --git a/openstackclient/compute/v2/availability_zone.py b/openstackclient/common/availability_zone.py
similarity index 100%
rename from openstackclient/compute/v2/availability_zone.py
rename to openstackclient/common/availability_zone.py
diff --git a/openstackclient/tests/common/test_availability_zone.py b/openstackclient/tests/common/test_availability_zone.py
new file mode 100644
index 0000000000..35089d0623
--- /dev/null
+++ b/openstackclient/tests/common/test_availability_zone.py
@@ -0,0 +1,113 @@
+#   Licensed 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.
+#
+
+import six
+
+from openstackclient.common import availability_zone
+from openstackclient.tests.compute.v2 import fakes as compute_fakes
+from openstackclient.tests import fakes
+from openstackclient.tests import utils
+
+
+def _build_compute_az_datalist(compute_az, long_datalist=False):
+    datalist = ()
+    if not long_datalist:
+        datalist = (
+            compute_az.zoneName,
+            'available',
+        )
+    else:
+        for host, services in six.iteritems(compute_az.hosts):
+            for service, state in six.iteritems(services):
+                datalist += (
+                    compute_az.zoneName,
+                    'available',
+                    host,
+                    service,
+                    'enabled :-) ' + state['updated_at'],
+                )
+    return (datalist,)
+
+
+class TestAvailabilityZone(utils.TestCommand):
+
+    def setUp(self):
+        super(TestAvailabilityZone, self).setUp()
+
+        compute_client = compute_fakes.FakeComputev2Client(
+            endpoint=fakes.AUTH_URL,
+            token=fakes.AUTH_TOKEN,
+        )
+        self.app.client_manager.compute = compute_client
+
+        self.compute_azs_mock = compute_client.availability_zones
+        self.compute_azs_mock.reset_mock()
+
+
+class TestAvailabilityZoneList(TestAvailabilityZone):
+
+    compute_azs = \
+        compute_fakes.FakeAvailabilityZone.create_availability_zones()
+
+    def setUp(self):
+        super(TestAvailabilityZoneList, self).setUp()
+
+        self.compute_azs_mock.list.return_value = self.compute_azs
+
+        # Get the command object to test
+        self.cmd = availability_zone.ListAvailabilityZone(self.app, None)
+
+    def test_availability_zone_list_no_options(self):
+        arglist = []
+        verifylist = []
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        # DisplayCommandBase.take_action() returns two tuples
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.compute_azs_mock.list.assert_called_with()
+
+        columnslist = ('Zone Name', 'Zone Status')
+        self.assertEqual(columnslist, columns)
+        datalist = ()
+        for compute_az in self.compute_azs:
+            datalist += _build_compute_az_datalist(compute_az)
+        self.assertEqual(datalist, tuple(data))
+
+    def test_availability_zone_list_long(self):
+        arglist = [
+            '--long',
+        ]
+        verifylist = [
+            ('long', True),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        # DisplayCommandBase.take_action() returns two tuples
+        columns, data = self.cmd.take_action(parsed_args)
+
+        self.compute_azs_mock.list.assert_called_with()
+
+        columnslist = (
+            'Zone Name',
+            'Zone Status',
+            'Host Name',
+            'Service Name',
+            'Service Status',
+        )
+        self.assertEqual(columnslist, columns)
+        datalist = ()
+        for compute_az in self.compute_azs:
+            datalist += _build_compute_az_datalist(compute_az,
+                                                   long_datalist=True)
+        self.assertEqual(datalist, tuple(data))
diff --git a/openstackclient/tests/compute/v2/fakes.py b/openstackclient/tests/compute/v2/fakes.py
index ecf7f599ba..a90c9ee71a 100644
--- a/openstackclient/tests/compute/v2/fakes.py
+++ b/openstackclient/tests/compute/v2/fakes.py
@@ -88,6 +88,8 @@ SERVICE = {
 
 class FakeComputev2Client(object):
     def __init__(self, **kwargs):
+        self.availability_zones = mock.Mock()
+        self.availability_zones.resource_class = fakes.FakeResource(None, {})
         self.images = mock.Mock()
         self.images.resource_class = fakes.FakeResource(None, {})
         self.servers = mock.Mock()
@@ -289,3 +291,63 @@ class FakeFlavor(object):
         if flavors is None:
             flavors = FakeServer.create_flavors(count)
         return mock.MagicMock(side_effect=flavors)
+
+
+class FakeAvailabilityZone(object):
+    """Fake one or more compute availability zones (AZs)."""
+
+    @staticmethod
+    def create_one_availability_zone(attrs={}, methods={}):
+        """Create a fake AZ.
+
+        :param Dictionary attrs:
+            A dictionary with all attributes
+        :param Dictionary methods:
+            A dictionary with all methods
+        :return:
+            A FakeResource object with zoneName, zoneState, etc.
+        """
+        # Set default attributes.
+        host_name = uuid.uuid4().hex
+        service_name = uuid.uuid4().hex
+        service_updated_at = uuid.uuid4().hex
+        availability_zone = {
+            'zoneName': uuid.uuid4().hex,
+            'zoneState': {'available': True},
+            'hosts': {host_name: {service_name: {
+                'available': True,
+                'active': True,
+                'updated_at': service_updated_at,
+            }}},
+        }
+
+        # Overwrite default attributes.
+        availability_zone.update(attrs)
+
+        availability_zone = fakes.FakeResource(
+            info=copy.deepcopy(availability_zone),
+            methods=methods,
+            loaded=True)
+        return availability_zone
+
+    @staticmethod
+    def create_availability_zones(attrs={}, methods={}, count=2):
+        """Create multiple fake AZs.
+
+        :param Dictionary attrs:
+            A dictionary with all attributes
+        :param Dictionary methods:
+            A dictionary with all methods
+        :param int count:
+            The number of AZs to fake
+        :return:
+            A list of FakeResource objects faking the AZs
+        """
+        availability_zones = []
+        for i in range(0, count):
+            availability_zone = \
+                FakeAvailabilityZone.create_one_availability_zone(
+                    attrs, methods)
+            availability_zones.append(availability_zone)
+
+        return availability_zones
diff --git a/setup.cfg b/setup.cfg
index 7e0f0b4c8e..2c48baa558 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -43,6 +43,7 @@ openstack.cli.base =
     volume = openstackclient.volume.client
 
 openstack.common =
+    availability_zone_list = openstackclient.common.availability_zone:ListAvailabilityZone
     configuration_show = openstackclient.common.configuration:ShowConfiguration
     extension_list = openstackclient.common.extension:ListExtension
     limits_show = openstackclient.common.limits:ShowLimits
@@ -50,8 +51,6 @@ openstack.common =
     quota_show = openstackclient.common.quota:ShowQuota
 
 openstack.compute.v2 =
-    availability_zone_list = openstackclient.compute.v2.availability_zone:ListAvailabilityZone
-
     compute_agent_create = openstackclient.compute.v2.agent:CreateAgent
     compute_agent_delete = openstackclient.compute.v2.agent:DeleteAgent
     compute_agent_list = openstackclient.compute.v2.agent:ListAgent