fix: use offline deploy for magnum
diff --git a/atmosphere/cmd/operator.py b/atmosphere/cmd/operator.py
index ca8aeb1..65ab3b3 100644
--- a/atmosphere/cmd/operator.py
+++ b/atmosphere/cmd/operator.py
@@ -1,45 +1 @@
-import kopf
-
-from atmosphere import clients
 from atmosphere.operator import constants, controllers, utils  # noqa: F401
-from atmosphere.operator.api import objects, types
-
-
-@kopf.on.create(
-    constants.API_VERSION_ATMOSPHERE,
-    constants.KIND_OPENSTACK_HELM_RABBITMQ_CLUSTER,
-)
-@kopf.on.resume(
-    constants.API_VERSION_ATMOSPHERE,
-    constants.KIND_OPENSTACK_HELM_RABBITMQ_CLUSTER,
-)
-def create_openstack_helm_rabbitmq_cluster(
-    namespace: str, name: str, annotations: dict, labels: dict, spec: dict, **_
-):
-    api = clients.get_pykube_api()
-    objects.OpenstackHelmRabbitmqCluster(
-        api=api,
-        metadata=types.NamespacedObjectMeta(
-            name=name,
-            namespace=namespace,
-            annotations=utils.filter_annotations(annotations),
-            labels=labels,
-        ),
-        spec=types.OpenstackHelmRabbitmqClusterSpec(**spec),
-    ).apply_rabbitmq_cluster()
-
-
-@kopf.on.delete(
-    constants.API_VERSION_ATMOSPHERE,
-    constants.KIND_OPENSTACK_HELM_RABBITMQ_CLUSTER,
-)
-def delete_openstack_helm_rabbitmq_cluster(namespace: str, name: str, spec: dict, **_):
-    api = clients.get_pykube_api()
-    objects.OpenstackHelmRabbitmqCluster(
-        api=api,
-        metadata=types.NamespacedObjectMeta(
-            name=name,
-            namespace=namespace,
-        ),
-        spec=types.OpenstackHelmRabbitmqClusterSpec(**spec),
-    ).delete_rabbitmq_cluster()
diff --git a/atmosphere/operator/api/objects.py b/atmosphere/operator/api/objects.py
index 0ef37b0..b16223c 100644
--- a/atmosphere/operator/api/objects.py
+++ b/atmosphere/operator/api/objects.py
@@ -3,7 +3,6 @@
 import pykube
 from pydantic import Field
 
-from atmosphere.operator import constants
 from atmosphere.operator.api import mixins, types
 
 # Kubernetes API
@@ -38,69 +37,3 @@
     )
     kind: str = Field("HelmRelease", const=True)
     spec: types.HelmReleaseSpec
-
-
-class RabbitmqCluster(pykube.objects.NamespacedAPIObject, mixins.ServerSideApplyMixin):
-    version = "rabbitmq.com/v1beta1"
-    endpoint = "rabbitmqclusters"
-    kind = "RabbitmqCluster"
-
-
-# Atmosphere
-
-
-class OpenstackHelmRabbitmqCluster(types.NamespacedKubernetesObject):
-    endpoint: ClassVar[str] = "openstackhelmrabbitmqclusters"
-
-    kind: str = Field(constants.KIND_OPENSTACK_HELM_RABBITMQ_CLUSTER, const=True)
-    spec: types.OpenstackHelmRabbitmqClusterSpec
-
-    def apply_rabbitmq_cluster(self):
-        return RabbitmqCluster(
-            self.api,
-            {
-                "apiVersion": RabbitmqCluster.version,
-                "kind": RabbitmqCluster.kind,
-                "metadata": {
-                    "name": f"rabbitmq-{self.metadata.name}",
-                    "namespace": self.metadata.namespace,
-                    "annotations": self.metadata.annotations,
-                    "labels": self.metadata.labels,
-                },
-                "spec": {
-                    "image": self.spec.image,
-                    "affinity": {
-                        "nodeAffinity": {
-                            "requiredDuringSchedulingIgnoredDuringExecution": {
-                                "nodeSelectorTerms": [
-                                    {
-                                        "matchExpressions": [
-                                            {
-                                                "key": "openstack-control-plane",
-                                                "operator": "In",
-                                                "values": ["enabled"],
-                                            }
-                                        ]
-                                    }
-                                ]
-                            }
-                        }
-                    },
-                    "rabbitmq": {
-                        "additionalConfig": "vm_memory_high_watermark.relative = 0.9\n"
-                    },
-                    "resources": {
-                        "requests": {"cpu": "500m", "memory": "1Gi"},
-                        "limits": {"cpu": "1", "memory": "2Gi"},
-                    },
-                    "terminationGracePeriodSeconds": 15,
-                },
-            },
-        ).apply()
-
-    def delete_rabbitmq_cluster(self):
-        rabbitmq_cluster = RabbitmqCluster.objects(
-            self.api, namespace=self.metadata.namespace
-        ).get_or_none(name=f"rabbitmq-{self.metadata.name}")
-        if rabbitmq_cluster:
-            rabbitmq_cluster.delete()
diff --git a/atmosphere/operator/api/types.py b/atmosphere/operator/api/types.py
index 1df4516..5aa7e84 100644
--- a/atmosphere/operator/api/types.py
+++ b/atmosphere/operator/api/types.py
@@ -170,10 +170,3 @@
 
     class Config:
         allow_population_by_field_name = True
-
-
-# Atmosphere
-
-
-class OpenstackHelmRabbitmqClusterSpec(pydantic.BaseModel):
-    image: pydantic.constr(min_length=1)
diff --git a/atmosphere/operator/constants.py b/atmosphere/operator/constants.py
index 1766d9f..ba69c97 100644
--- a/atmosphere/operator/constants.py
+++ b/atmosphere/operator/constants.py
@@ -1,7 +1,5 @@
 API_VERSION_ATMOSPHERE = "atmosphere.vexxhost.com/v1alpha1"
 
-KIND_OPENSTACK_HELM_RABBITMQ_CLUSTER = "OpenstackHelmRabbitmqCluster"
-
 IMAGE_LIST = {
     "alertmanager": "quay.io/prometheus/alertmanager:v0.24.0",
     "atmosphere": "quay.io/vexxhost/atmosphere:0.13.0",  # x-release-please-version
diff --git a/atmosphere/operator/controllers/cloud.py b/atmosphere/operator/controllers/cloud.py
index a5f06ec..9181897 100644
--- a/atmosphere/operator/controllers/cloud.py
+++ b/atmosphere/operator/controllers/cloud.py
@@ -7,8 +7,8 @@
 
 from atmosphere import clients, flows
 from atmosphere.models import config
-from atmosphere.operator import tasks, utils
-from atmosphere.operator.api import Cloud, objects, types
+from atmosphere.operator import tasks
+from atmosphere.operator.api import Cloud
 
 
 @kopf.on.resume(Cloud.version, Cloud.kind)
@@ -21,178 +21,13 @@
     engine = flows.get_engine(cfg)
     engine.run()
 
-    flow = graph_flow.Flow("deploy").add(
-        tasks.GenerateImageTagsConfigMap(provides="image_tags"),
-        tasks.GenerateSecrets(provides="secrets"),
-    )
+    flow = graph_flow.Flow("deploy")
 
     if spec["magnum"].get("enabled", True):
-        objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="magnum",
-                namespace=namespace,
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image=utils.get_image_ref(
-                    "rabbitmq_server", override_registry=spec["imageRepository"]
-                ).string()
-            ),
-        ).apply()
         flow.add(
             tasks.InstallClusterApiTask(),
-            tasks.GetChartValues(
-                inject={
-                    "helm_repository": "openstack-helm",
-                    "helm_repository_url": "https://tarballs.opendev.org/openstack/openstack-helm/",
-                    "chart_name": "magnum",
-                    "chart_version": "0.2.8",
-                },
-                provides="magnum_chart_values",
-            ),
-            tasks.GenerateReleaseValues(
-                inject={"chart_name": "magnum"},
-                provides="magnum_release_values",
-            ),
-            tasks.GenerateMagnumChartValuesFrom(
-                inject={"chart_name": "magnum"},
-                provides="magnum_values_from",
-            ),
-            tasks.ApplyHelmReleaseTask(
-                inject={
-                    "helm_repository": "openstack-helm",
-                    "chart_name": "magnum",
-                    "chart_version": "0.2.8",
-                    "release_name": "magnum",
-                },
-                rebind={
-                    "values": "magnum_release_values",
-                    "values_from": "magnum_values_from",
-                },
-            ),
         )
 
-        objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="keystone",
-                namespace=namespace,
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image=utils.get_image_ref(
-                    "rabbitmq_server", override_registry=spec["imageRepository"]
-                ).string()
-            ),
-        ).apply()
-        objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="barbican",
-                namespace=namespace,
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image=utils.get_image_ref(
-                    "rabbitmq_server", override_registry=spec["imageRepository"]
-                ).string()
-            ),
-        ).apply()
-        objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="glance",
-                namespace=namespace,
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image=utils.get_image_ref(
-                    "rabbitmq_server", override_registry=spec["imageRepository"]
-                ).string()
-            ),
-        ).apply()
-        objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="cinder",
-                namespace=namespace,
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image=utils.get_image_ref(
-                    "rabbitmq_server", override_registry=spec["imageRepository"]
-                ).string()
-            ),
-        ).apply()
-        objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="neutron",
-                namespace=namespace,
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image=utils.get_image_ref(
-                    "rabbitmq_server", override_registry=spec["imageRepository"]
-                ).string()
-            ),
-        ).apply()
-        objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="nova",
-                namespace=namespace,
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image=utils.get_image_ref(
-                    "rabbitmq_server", override_registry=spec["imageRepository"]
-                ).string()
-            ),
-        ).apply()
-        objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="octavia",
-                namespace=namespace,
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image=utils.get_image_ref(
-                    "rabbitmq_server", override_registry=spec["imageRepository"]
-                ).string()
-            ),
-        ).apply()
-        objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="senlin",
-                namespace=namespace,
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image=utils.get_image_ref(
-                    "rabbitmq_server", override_registry=spec["imageRepository"]
-                ).string()
-            ),
-        ).apply()
-        objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="designate",
-                namespace=namespace,
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image=utils.get_image_ref(
-                    "rabbitmq_server", override_registry=spec["imageRepository"]
-                ).string()
-            ),
-        ).apply()
-        objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="heat",
-                namespace=namespace,
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image=utils.get_image_ref(
-                    "rabbitmq_server", override_registry=spec["imageRepository"]
-                ).string()
-            ),
-        ).apply()
-
     engine = engines.load(
         flow,
         store={
diff --git a/atmosphere/operator/tasks.py b/atmosphere/operator/tasks.py
index c089e63..2c46dd0 100644
--- a/atmosphere/operator/tasks.py
+++ b/atmosphere/operator/tasks.py
@@ -1,48 +1,12 @@
 import glob
-import json
-import logging
 import os
 import subprocess
 
-import mergedeep
 import pkg_resources
-import pykube
-import yaml
-from oslo_utils import strutils
 from taskflow import task
-from tenacity import retry, retry_if_result, stop_after_delay, wait_fixed
 
 from atmosphere.operator import constants, utils
 
-LOG = logging.getLogger(__name__)
-
-
-class ApplyKubernetesObjectTask(task.Task):
-    def generate_object(self, *args, **kwargs) -> pykube.objects.APIObject:
-        raise NotImplementedError
-
-    def wait_for_resource(self, resource: pykube.objects.APIObject):
-        return resource
-
-    def _apply(self, resource: pykube.objects.APIObject) -> pykube.objects.APIObject:
-        resp = resource.api.patch(
-            **resource.api_kwargs(
-                headers={
-                    "Content-Type": "application/apply-patch+yaml",
-                },
-                params={
-                    "fieldManager": "atmosphere-operator",
-                    "force": True,
-                },
-                data=json.dumps(resource.obj),
-            )
-        )
-
-        resource.api.raise_for_status(resp)
-        resource.set_obj(resp.json())
-
-        return self.wait_for_resource(resource)
-
 
 class InstallClusterApiTask(task.Task):
     def execute(self, spec: dict):
@@ -76,437 +40,3 @@
                 stdout=subprocess.DEVNULL,
                 stderr=subprocess.DEVNULL,
             )
-
-
-class HelmRelease(pykube.objects.NamespacedAPIObject):
-    version = "helm.toolkit.fluxcd.io/v2beta1"
-    endpoint = "helmreleases"
-    kind = "HelmRelease"
-
-
-class ApplyHelmReleaseTask(ApplyKubernetesObjectTask):
-    def execute(
-        self,
-        api: pykube.HTTPClient,
-        namespace: str,
-        release_name: str,
-        helm_repository: str,
-        chart_name: str,
-        chart_version: str,
-        values: dict,
-        values_from: list,
-    ) -> HelmRelease:
-        resource = HelmRelease(
-            api,
-            {
-                "apiVersion": HelmRelease.version,
-                "kind": HelmRelease.kind,
-                "metadata": {
-                    "name": release_name,
-                    "namespace": namespace,
-                },
-                "spec": {
-                    "interval": "60s",
-                    "chart": {
-                        "spec": {
-                            "chart": chart_name,
-                            "version": chart_version,
-                            "sourceRef": {
-                                "kind": "HelmRepository",
-                                "name": helm_repository,
-                            },
-                        }
-                    },
-                    "install": {
-                        "crds": "CreateReplace",
-                        "disableWait": True,
-                        "remediation": {
-                            "retries": 3,
-                        },
-                    },
-                    "upgrade": {
-                        "crds": "CreateReplace",
-                        "disableWait": True,
-                        "remediation": {
-                            "retries": 3,
-                        },
-                    },
-                    "values": values,
-                    "valuesFrom": values_from,
-                },
-            },
-        )
-
-        return self._apply(resource)
-
-    @retry(
-        retry=retry_if_result(lambda f: f is False),
-        stop=stop_after_delay(300),
-        wait=wait_fixed(1),
-    )
-    def wait_for_resource(self, resource: HelmRelease, *args, **kwargs) -> bool:
-        # TODO(mnaser): detect potential changes and wait
-        resource.reload()
-
-        conditions = {
-            condition["type"]: strutils.bool_from_string(condition["status"])
-            for condition in resource.obj["status"].get("conditions", [])
-        }
-
-        if not conditions.get("Ready", False) and conditions.get("Released", False):
-            return False
-        return resource
-
-
-class GenerateSecrets(ApplyKubernetesObjectTask):
-    def execute(
-        self, api: pykube.HTTPClient, namespace: str, name: str
-    ) -> pykube.Secret:
-        # TODO(mnaser): We should generate this if it's missing, but for now
-        #               assume that it exists.
-        secret_name = f"{name}-secrets"
-        return pykube.Secret.objects(api, namespace=namespace).get(name=secret_name)
-
-
-class GenerateImageTagsConfigMap(ApplyKubernetesObjectTask):
-    def execute(
-        self, api: pykube.HTTPClient, namespace: str, name: str, spec: dict
-    ) -> pykube.ConfigMap:
-        resource = pykube.ConfigMap(
-            api,
-            {
-                "apiVersion": pykube.ConfigMap.version,
-                "kind": pykube.ConfigMap.kind,
-                "metadata": {
-                    "name": f"{name}-images",
-                    "namespace": namespace,
-                },
-                "data": {
-                    "values.yaml": yaml.dump(
-                        {
-                            "images": {
-                                "tags": {
-                                    image_name: utils.get_image_ref(
-                                        image_name,
-                                        override_registry=spec["imageRepository"],
-                                    ).string()
-                                    for image_name in constants.IMAGE_LIST.keys()
-                                }
-                            }
-                        }
-                    )
-                },
-            },
-        )
-
-        return self._apply(resource)
-
-
-class GetChartValues(task.Task):
-    def execute(
-        self,
-        helm_repository: str,
-        helm_repository_url: str,
-        chart_name: str,
-        chart_version: str,
-    ) -> dict:
-        # TODO(mnaser): Once we move towards air-gapped deployments, we should
-        #               refactor this to pull from local OCI registry instead.
-        subprocess.check_call(
-            f"helm repo add --force-update {helm_repository} {helm_repository_url}",
-            shell=True,
-            stdout=subprocess.DEVNULL,
-            stderr=subprocess.DEVNULL,
-        )
-        subprocess.check_call(
-            "helm repo update",
-            shell=True,
-            stdout=subprocess.DEVNULL,
-            stderr=subprocess.DEVNULL,
-        )
-        data = subprocess.check_output(
-            f"helm show values {helm_repository}/{chart_name} --version {chart_version}",
-            shell=True,
-        )
-        return yaml.safe_load(data)
-
-
-class GenerateReleaseValues(task.Task):
-    def _generate_base(self, rabbitmq: str, spec: dict) -> dict:
-        return {
-            "endpoints": {
-                "identity": {
-                    "auth": {
-                        "admin": {
-                            "username": f"admin-{spec['regionName']}",
-                            "region_name": spec["regionName"],
-                        },
-                    },
-                },
-                "oslo_db": {
-                    "hosts": {
-                        # TODO(mnaser): Move this into a dependency
-                        "default": "percona-xtradb-haproxy",
-                    },
-                },
-                "oslo_messaging": {
-                    "statefulset": None,
-                    "hosts": {
-                        # TODO(mnaser): handle scenario when those don't exist
-                        "default": rabbitmq,
-                    },
-                },
-            },
-        }
-
-    def _generate_magnum(self, spec: dict) -> dict:
-        return {
-            "endpoints": {
-                "container_infra": {
-                    "host_fqdn_override": {
-                        "public": {"host": spec["magnum"]["endpoint"]}
-                    },
-                    "port": {"api": {"public": 443}},
-                    "scheme": {"public": "https"},
-                },
-                "identity": {
-                    "auth": {
-                        "magnum": {
-                            "username": f"magnum-{spec['regionName']}",
-                            "region_name": spec["regionName"],
-                        },
-                        "magnum_stack_user": {
-                            "username": f"magnum-domain-{spec['regionName']}",
-                            "region_name": spec["regionName"],
-                        },
-                    },
-                },
-            },
-            "conf": {
-                "magnum": {
-                    "DEFAULT": {"log_config_append": None},
-                    "barbican_client": {
-                        "endpoint_type": "internalURL",
-                        "region_name": spec["regionName"],
-                    },
-                    "cinder_client": {
-                        "endpoint_type": "internalURL",
-                        "region_name": spec["regionName"],
-                    },
-                    "cluster_template": {
-                        "kubernetes_allowed_network_drivers": "calico",
-                        "kubernetes_default_network_driver": "calico",
-                    },
-                    "conductor": {"workers": 4},
-                    "drivers": {
-                        "verify_ca": False,
-                    },
-                    "glance_client": {
-                        "endpoint_type": "internalURL",
-                        "region_name": spec["regionName"],
-                    },
-                    "heat_client": {
-                        "endpoint_type": "internalURL",
-                        "region_name": spec["regionName"],
-                    },
-                    "keystone_auth": {
-                        "auth_url": "http://keystone-api.openstack.svc.cluster.local:5000/v3",
-                        "user_domain_name": "service",
-                        "username": f"magnum-{spec['regionName']}",
-                        # NOTE(mnaser): Magnum does not allow changing the interface to internal
-                        #               so we workaround with this for now.
-                        "insecure": True,
-                    },
-                    "keystone_authtoken": {
-                        # NOTE(mnaser): Magnum does not allow changing the interface to internal
-                        #               so we workaround with this for now.
-                        "insecure": True,
-                    },
-                    "magnum_client": {"region_name": spec["regionName"]},
-                    "neutron_client": {
-                        "endpoint_type": "internalURL",
-                        "region_name": spec["regionName"],
-                    },
-                    "nova_client": {
-                        "endpoint_type": "internalURL",
-                        "region_name": spec["regionName"],
-                    },
-                    "octavia_client": {
-                        "endpoint_type": "internalURL",
-                        "region_name": spec["regionName"],
-                    },
-                }
-            },
-            "pod": {
-                "replicas": {
-                    "api": 3,
-                    "conductor": 3,
-                },
-            },
-            "manifests": {
-                "ingress_api": False,
-                "service_ingress_api": False,
-            },
-        }
-
-    def execute(self, chart_name: str, spec: dict) -> dict:
-        return mergedeep.merge(
-            {},
-            self._generate_base(f"rabbitmq-{chart_name}", spec),
-            getattr(self, f"_generate_{chart_name}")(spec),
-            spec[chart_name].get("overrides", {}),
-        )
-
-
-class GenerateMagnumChartValuesFrom(task.Task):
-    def execute(
-        self,
-        chart_name: str,
-        image_tags: pykube.ConfigMap,
-        secrets: pykube.Secret,
-    ) -> dict:
-        return [
-            {
-                "kind": pykube.ConfigMap.kind,
-                "name": image_tags.name,
-            },
-            {
-                "kind": pykube.Secret.kind,
-                "name": secrets.name,
-                "targetPath": "conf.magnum.keystone_auth.password",
-                "valuesKey": "magnum-keystone-password",
-            },
-            {
-                "kind": pykube.Secret.kind,
-                "name": secrets.name,
-                "targetPath": "endpoints.oslo_cache.auth.memcache_secret_key",
-                "valuesKey": "memcache-secret-key",
-            },
-            {
-                "kind": pykube.Secret.kind,
-                "name": secrets.name,
-                "targetPath": "endpoints.identity.auth.admin.password",
-                "valuesKey": "keystone-admin-password",
-            },
-            {
-                "kind": pykube.Secret.kind,
-                "name": secrets.name,
-                "targetPath": "endpoints.identity.auth.magnum.password",
-                "valuesKey": "magnum-keystone-password",
-            },
-            {
-                "kind": pykube.Secret.kind,
-                "name": secrets.name,
-                "targetPath": "endpoints.identity.auth.magnum_stack_user.password",
-                "valuesKey": "magnum-keystone-password",
-            },
-            {
-                "kind": pykube.Secret.kind,
-                "name": "percona-xtradb",
-                "targetPath": "endpoints.oslo_db.auth.admin.password",
-                "valuesKey": "root",
-            },
-            {
-                "kind": pykube.Secret.kind,
-                "name": secrets.name,
-                "targetPath": "endpoints.oslo_db.auth.magnum.password",
-                "valuesKey": "magnum-database-password",
-            },
-            {
-                "kind": pykube.Secret.kind,
-                "name": f"rabbitmq-{chart_name}-default-user",
-                "targetPath": "endpoints.oslo_messaging.auth.admin.username",
-                "valuesKey": "username",
-            },
-            {
-                "kind": pykube.Secret.kind,
-                "name": f"rabbitmq-{chart_name}-default-user",
-                "targetPath": "endpoints.oslo_messaging.auth.admin.password",
-                "valuesKey": "password",
-            },
-            {
-                "kind": pykube.Secret.kind,
-                "name": secrets.name,
-                "targetPath": "endpoints.oslo_messaging.auth.magnum.password",
-                "valuesKey": "magnum-rabbitmq-password",
-            },
-        ]
-
-
-class GenerateOpenStackHelmEndpoints(task.Task):
-    SKIPPED_ENDPOINTS = (
-        "cluster_domain_suffix",
-        "local_image_registry",
-        "oci_image_registry",
-        "fluentd",
-    )
-
-    def __init__(
-        self,
-        repository_name: str,
-        repository_url: str,
-        chart_name: str,
-        chart_version: str,
-        *args,
-        **kwargs,
-    ):
-        self._repository_name = repository_name
-        self._repository_url = repository_url
-        self._chart_name = chart_name
-        self._chart_version = chart_version
-
-        super().__init__(*args, **kwargs)
-
-    def _get_values(self):
-        # TODO(mnaser): Once we move towards air-gapped deployments, we should
-        #               refactor this to pull from local OCI registry instead.
-        subprocess.check_call(
-            f"helm repo add --force-update {self._repository_name} {self._repository_url}",
-            shell=True,
-            stdout=subprocess.DEVNULL,
-            stderr=subprocess.DEVNULL,
-        )
-        subprocess.check_call(
-            "helm repo update",
-            shell=True,
-            stdout=subprocess.DEVNULL,
-            stderr=subprocess.DEVNULL,
-        )
-        data = subprocess.check_output(
-            f"helm show values {self._repository_name}/{self._chart_name} --version {self._chart_version}",
-            shell=True,
-        )
-        return yaml.safe_load(data)
-
-    def _generate_oslo_messaging(self):
-        return {
-            "statefulset": None,
-            "hosts": {
-                "default": f"rabbitmq-{self._chart_name}",
-            },
-        }
-
-    def _generate_orchestration(self):
-        return {}
-
-    def _generate_key_manager(self):
-        return {}
-
-    def _generate_oslo_db(self):
-        return {"hosts": {"default": "percona-xtradb-haproxy"}}
-
-    def _generate_identity(self):
-        return {}
-
-    def _generate_oslo_cache(self):
-        # TODO: only generate if we're getting endpoints for memcached chart
-        return {}
-
-    def _generate_container_infra(self):
-        return {}
-
-    def execute(self, *args, **kwargs):
-        endpoints = (
-            self._get_values().get("endpoints", {}).keys() - self.SKIPPED_ENDPOINTS
-        )
-        return {"endpoints": {k: getattr(self, "_generate_" + k)() for k in endpoints}}
diff --git a/atmosphere/tests/unit/operator/test_objects.py b/atmosphere/tests/unit/operator/test_objects.py
index ad682e7..5434138 100644
--- a/atmosphere/tests/unit/operator/test_objects.py
+++ b/atmosphere/tests/unit/operator/test_objects.py
@@ -217,192 +217,3 @@
                     ],
                 },
             }
-
-
-class TestOpenstackHelmRabbitmqCluster:
-    @given(st.builds(objects.OpenstackHelmRabbitmqCluster))
-    def test_property(self, instance):
-        assert isinstance(instance, objects.OpenstackHelmRabbitmqCluster)
-        assert isinstance(instance.metadata, types.NamespacedObjectMeta)
-        assert isinstance(instance.spec, types.OpenstackHelmRabbitmqClusterSpec)
-
-    def test_apply(self, api, requests_mock):
-        instance = objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="neutron",
-                namespace="default",
-                annotations={
-                    "annotate": "this",
-                },
-                labels={
-                    "foo": "bar",
-                },
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image="rabbitmq:3.8.9",
-            ),
-        )
-
-        with requests_mock as rsps:
-            rsps.add(
-                responses.PATCH,
-                "https://localhost:9443/apis/atmosphere.vexxhost.com/v1alpha1/namespaces/default/openstackhelmrabbitmqclusters/neutron?fieldManager=atmosphere-operator&force=True",  # noqa E501
-                json={},
-            )
-
-            instance.apply()
-
-            assert len(rsps.calls) == 1
-            assert json.loads(rsps.calls[0].request.body) == {
-                "apiVersion": "atmosphere.vexxhost.com/v1alpha1",
-                "kind": "OpenstackHelmRabbitmqCluster",
-                "metadata": {
-                    "name": "neutron",
-                    "namespace": "default",
-                    "labels": {
-                        "foo": "bar",
-                    },
-                    "annotations": {
-                        "annotate": "this",
-                    },
-                },
-                "spec": {
-                    "image": "rabbitmq:3.8.9",
-                },
-            }
-
-    def test_apply_rabbitmq_cluster(self, api, requests_mock):
-        instance = objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="neutron",
-                namespace="default",
-                annotations={
-                    "annotate": "this",
-                },
-                labels={
-                    "foo": "bar",
-                },
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image="rabbitmq:3.8.9",
-            ),
-        )
-
-        with requests_mock as rsps:
-            rsps.add(
-                responses.PATCH,
-                "https://localhost:9443/apis/rabbitmq.com/v1beta1/namespaces/default/rabbitmqclusters/rabbitmq-neutron?fieldManager=atmosphere-operator&force=True",  # noqa E501
-                json={},
-            )
-
-            instance.apply_rabbitmq_cluster()
-
-            assert len(rsps.calls) == 1
-            assert json.loads(rsps.calls[0].request.body) == {
-                "apiVersion": "rabbitmq.com/v1beta1",
-                "kind": "RabbitmqCluster",
-                "metadata": {
-                    "name": "rabbitmq-neutron",
-                    "namespace": "default",
-                    "annotations": {
-                        "annotate": "this",
-                    },
-                    "labels": {
-                        "foo": "bar",
-                    },
-                },
-                "spec": {
-                    "image": "rabbitmq:3.8.9",
-                    "affinity": {
-                        "nodeAffinity": {
-                            "requiredDuringSchedulingIgnoredDuringExecution": {
-                                "nodeSelectorTerms": [
-                                    {
-                                        "matchExpressions": [
-                                            {
-                                                "key": "openstack-control-plane",
-                                                "operator": "In",
-                                                "values": ["enabled"],
-                                            }
-                                        ]
-                                    }
-                                ]
-                            }
-                        }
-                    },
-                    "rabbitmq": {
-                        "additionalConfig": "vm_memory_high_watermark.relative = 0.9\n"
-                    },
-                    "resources": {
-                        "requests": {"cpu": "500m", "memory": "1Gi"},
-                        "limits": {"cpu": "1", "memory": "2Gi"},
-                    },
-                    "terminationGracePeriodSeconds": 15,
-                },
-            }
-
-    def test_delete_rabbitmq_cluster(self, api, requests_mock):
-        instance = objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="neutron",
-                namespace="default",
-                annotations={
-                    "annotate": "this",
-                },
-                labels={
-                    "foo": "bar",
-                },
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image="rabbitmq:3.8.9",
-            ),
-        )
-
-        with requests_mock as rsps:
-            rsps.add(
-                responses.GET,
-                "https://localhost:9443/apis/rabbitmq.com/v1beta1/namespaces/default/rabbitmqclusters/rabbitmq-neutron",
-                json={
-                    "metadata": {
-                        "name": "rabbitmq-neutron",
-                    },
-                },
-            )
-            rsps.add(
-                responses.DELETE,
-                "https://localhost:9443/apis/rabbitmq.com/v1beta1/namespaces/default/rabbitmqclusters/rabbitmq-neutron",
-            )
-
-            instance.delete_rabbitmq_cluster()
-            assert len(rsps.calls) == 2
-
-    def test_delete_missing_rabbitmq_cluster(self, api, requests_mock):
-        instance = objects.OpenstackHelmRabbitmqCluster(
-            api=api,
-            metadata=types.NamespacedObjectMeta(
-                name="neutron",
-                namespace="default",
-                annotations={
-                    "annotate": "this",
-                },
-                labels={
-                    "foo": "bar",
-                },
-            ),
-            spec=types.OpenstackHelmRabbitmqClusterSpec(
-                image="rabbitmq:3.8.9",
-            ),
-        )
-
-        with requests_mock as rsps:
-            rsps.add(
-                responses.GET,
-                "https://localhost:9443/apis/rabbitmq.com/v1beta1/namespaces/default/rabbitmqclusters/rabbitmq-neutron",
-                status=404,
-            )
-
-            instance.delete_rabbitmq_cluster()
-            assert len(rsps.calls) == 1
diff --git a/atmosphere/tests/unit/operator/test_types.py b/atmosphere/tests/unit/operator/test_types.py
index 246dc69..164ca6d 100644
--- a/atmosphere/tests/unit/operator/test_types.py
+++ b/atmosphere/tests/unit/operator/test_types.py
@@ -149,11 +149,3 @@
         assert isinstance(instance.upgrade, types.HelmReleaseActionSpec)
         assert isinstance(instance.values, dict)
         assert isinstance(instance.values_from, list)
-
-
-class TestOpenstackHelmRabbitmqClusterSpec:
-    @given(st.builds(types.OpenstackHelmRabbitmqClusterSpec))
-    def test_property(self, instance):
-        assert isinstance(instance, types.OpenstackHelmRabbitmqClusterSpec)
-        assert isinstance(instance.image, str)
-        assert instance.image != ""
diff --git a/molecule/default/group_vars/all/molecule.yml b/molecule/default/group_vars/all/molecule.yml
index 6fecc77..e1341f1 100644
--- a/molecule/default/group_vars/all/molecule.yml
+++ b/molecule/default/group_vars/all/molecule.yml
@@ -1,7 +1,8 @@
 atmosphere_image: "{{ lookup('file', lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') + '/image') }}"

 

 atmosphere_issuer_config:

-  type: self-signed

+  # type: self-signed

+  email: mnaser@vexxhost.com

 

 openstack_helm_glance_images:

   - name: cirros

diff --git a/rabbitmq/README.md b/rabbitmq/README.md
new file mode 100644
index 0000000..4a53859
--- /dev/null
+++ b/rabbitmq/README.md
@@ -0,0 +1 @@
+# `rabbitmq`
diff --git a/rabbitmq/meta/main.yml b/rabbitmq/meta/main.yml
new file mode 100644
index 0000000..37118dc
--- /dev/null
+++ b/rabbitmq/meta/main.yml
@@ -0,0 +1,23 @@
+# Copyright (c) 2022 VEXXHOST, Inc.
+#
+# 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.
+
+galaxy_info:
+  author: VEXXHOST, Inc.
+  description: Ansible role for RabbitMQ
+  license: Apache-2.0
+  min_ansible_version: 5.5.0
+  platforms:
+    - name: Ubuntu
+      versions:
+        - focal
diff --git a/rabbitmq/tasks/main.yml b/rabbitmq/tasks/main.yml
new file mode 100644
index 0000000..aed2e62
--- /dev/null
+++ b/rabbitmq/tasks/main.yml
@@ -0,0 +1,50 @@
+# Copyright (c) 2022 VEXXHOST, Inc.
+#
+# 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.
+
+- name: Deploy cluster
+  kubernetes.core.k8s:
+    state: present
+    definition:
+      apiVersion: rabbitmq.com/v1beta1
+      kind: RabbitmqCluster
+      metadata:
+        name: "rabbitmq-{{ rabbitmq_cluster_name }}"
+        namespace: openstack
+      spec:
+        image: "{{ atmosphere_images['rabbitmq_server'] | docker_image('ref') }}"
+        affinity:
+          nodeAffinity:
+            requiredDuringSchedulingIgnoredDuringExecution:
+              nodeSelectorTerms:
+                - matchExpressions:
+                    - key: openstack-control-plane
+                      operator: In
+                      values:
+                        - enabled
+        rabbitmq:
+          additionalConfig: |
+            vm_memory_high_watermark.relative = 0.9
+        resources:
+          limits:
+            cpu: "1"
+            memory: 2Gi
+          requests:
+            cpu: 500m
+            memory: 1Gi
+        terminationGracePeriodSeconds: 15
+    wait: true
+    wait_timeout: 600
+    wait_condition:
+      type: ClusterAvailable
+      status: "True"
diff --git a/roles/atmosphere/templates/crds.yml b/roles/atmosphere/templates/crds.yml
index edc7e9f..2a31263 100644
--- a/roles/atmosphere/templates/crds.yml
+++ b/roles/atmosphere/templates/crds.yml
@@ -2,32 +2,6 @@
 apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
-  name: openstackhelmrabbitmqclusters.atmosphere.vexxhost.com
-spec:
-  scope: Namespaced
-  group: atmosphere.vexxhost.com
-  names:
-    kind: OpenstackHelmRabbitmqCluster
-    plural: openstackhelmrabbitmqclusters
-    singular: openstackhelmrabbitmqcluster
-  versions:
-    - name: v1alpha1
-      served: true
-      storage: true
-      schema:
-        openAPIV3Schema:
-          type: object
-          properties:
-            spec:
-              type: object
-              x-kubernetes-preserve-unknown-fields: true
-            status:
-              type: object
-              x-kubernetes-preserve-unknown-fields: true
----
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
   name: clouds.atmosphere.vexxhost.com
 spec:
   scope: Namespaced
diff --git a/roles/atmosphere/templates/resources.yml b/roles/atmosphere/templates/resources.yml
index bce31b0..c52dbc1 100644
--- a/roles/atmosphere/templates/resources.yml
+++ b/roles/atmosphere/templates/resources.yml
@@ -24,18 +24,6 @@
   impliedRoleRef:
     name: load-balancer-member
 ---
-apiVersion: v1
-kind: Secret
-metadata:
-  name: atmosphere-secrets
-  namespace: openstack
-stringData:
-  keystone-admin-password: "{{ openstack_helm_endpoints_keystone_admin_password }}"
-  magnum-database-password: "{{ openstack_helm_endpoints_magnum_mariadb_password }}"
-  magnum-keystone-password: "{{ openstack_helm_endpoints_magnum_keystone_password }}"
-  magnum-rabbitmq-password: "{{ openstack_helm_endpoints_magnum_rabbitmq_password }}"
-  memcache-secret-key: "{{ openstack_helm_endpoints_memcached_secret_key }}"
----
 apiVersion: atmosphere.vexxhost.com/v1alpha1
 kind: Cloud
 metadata:
diff --git a/roles/atmosphere/vars/main.yml b/roles/atmosphere/vars/main.yml
index 31b9832..85f1809 100644
--- a/roles/atmosphere/vars/main.yml
+++ b/roles/atmosphere/vars/main.yml
@@ -3,5 +3,3 @@
   ingressClassName: "{{ openstack_helm_ingress_class_name | default('openstack') }}"
   certManagerClusterIssuer: "{{ openstack_helm_ingress_cluster_issuer | default('atmosphere') }}"
   regionName: "{{ openstack_helm_endpoints_region_name }}"
-  magnum:
-    endpoint: "{{ openstack_helm_endpoints_magnum_api_host }}"
diff --git a/roles/openstack_helm_barbican/tasks/main.yml b/roles/openstack_helm_barbican/tasks/main.yml
index a671853..0987b04 100644
--- a/roles/openstack_helm_barbican/tasks/main.yml
+++ b/roles/openstack_helm_barbican/tasks/main.yml
@@ -52,18 +52,6 @@
           valuesFrom:
             - kind: Secret
               name: atmosphere-barbican
-            - kind: Secret
-              name: percona-xtradb
-              valuesKey: root
-              targetPath: endpoints.oslo_db.auth.admin.password
-            - kind: Secret
-              name: rabbitmq-barbican-default-user
-              valuesKey: username
-              targetPath: endpoints.oslo_messaging.auth.admin.username
-            - kind: Secret
-              name: rabbitmq-barbican-default-user
-              valuesKey: password
-              targetPath: endpoints.oslo_messaging.auth.admin.password
 
 - name: Create Ingress
   ansible.builtin.include_role:
diff --git a/roles/openstack_helm_cinder/tasks/main.yml b/roles/openstack_helm_cinder/tasks/main.yml
index 695987d..ab17686 100644
--- a/roles/openstack_helm_cinder/tasks/main.yml
+++ b/roles/openstack_helm_cinder/tasks/main.yml
@@ -52,18 +52,6 @@
           valuesFrom:
             - kind: Secret
               name: atmosphere-cinder
-            - kind: Secret
-              name: percona-xtradb
-              valuesKey: root
-              targetPath: endpoints.oslo_db.auth.admin.password
-            - kind: Secret
-              name: rabbitmq-cinder-default-user
-              valuesKey: username
-              targetPath: endpoints.oslo_messaging.auth.admin.username
-            - kind: Secret
-              name: rabbitmq-cinder-default-user
-              valuesKey: password
-              targetPath: endpoints.oslo_messaging.auth.admin.password
 
 - name: Create Ingress
   ansible.builtin.include_role:
diff --git a/roles/openstack_helm_designate/tasks/main.yml b/roles/openstack_helm_designate/tasks/main.yml
index f189ede..fd2a06f 100644
--- a/roles/openstack_helm_designate/tasks/main.yml
+++ b/roles/openstack_helm_designate/tasks/main.yml
@@ -52,18 +52,6 @@
           valuesFrom:
             - kind: Secret
               name: atmosphere-designate
-            - kind: Secret
-              name: percona-xtradb
-              valuesKey: root
-              targetPath: endpoints.oslo_db.auth.admin.password
-            - kind: Secret
-              name: rabbitmq-designate-default-user
-              valuesKey: username
-              targetPath: endpoints.oslo_messaging.auth.admin.username
-            - kind: Secret
-              name: rabbitmq-designate-default-user
-              valuesKey: password
-              targetPath: endpoints.oslo_messaging.auth.admin.password
 
 - name: Create Ingress
   ansible.builtin.include_role:
diff --git a/roles/openstack_helm_endpoints/tasks/main.yml b/roles/openstack_helm_endpoints/tasks/main.yml
index c8dc0b4..60cdfc7 100644
--- a/roles/openstack_helm_endpoints/tasks/main.yml
+++ b/roles/openstack_helm_endpoints/tasks/main.yml
@@ -19,6 +19,54 @@
   when:
     - openstack_helm_endpoints_list is not defined or openstack_helm_endpoints_list == None
 
+# NOTE(mnaser): Since we manage one-RabbitMQ per service, we create the RabbitMQ
+#               cluster here and then append the necessary values to be used
+#               inside the `oslo_messaging` section.
+- name: Configure "oslo.messaging"
+  when:
+    - '"oslo_messaging" in openstack_helm_endpoints_list'
+  block:
+    - name: Create RabbitMQ cluster
+      ansible.builtin.include_role:
+        name: rabbitmq
+      vars:
+        rabbitmq_cluster_name: "{{ openstack_helm_endpoints_chart }}"
+
+    - name: Grab RabbitMQ cluster secret
+      kubernetes.core.k8s_info:
+        api_version: v1
+        kind: Secret
+        name: "rabbitmq-{{ openstack_helm_endpoints_chart }}-default-user"
+        namespace: openstack
+      register: _openstack_helm_endpoints_rabbitmq_cluster_secret
+
+    - name: Cache fact with RabbitMQ cluster credentials
+      ansible.builtin.set_fact:
+        _openstack_helm_endpoints_rabbitmq_cluster_username: |-
+          {{ _openstack_helm_endpoints_rabbitmq_cluster_secret.resources[0]['data']['username'] | b64decode }}
+        _openstack_helm_endpoints_rabbitmq_cluster_password: |-
+          {{ _openstack_helm_endpoints_rabbitmq_cluster_secret.resources[0]['data']['password'] | b64decode }}
+
+# NOTE(mnaser): Since we deploy the database using the operator and we let it
+#               generate the root password, we look it up if the fact has not
+#               been cached from a previous run.
+- name: Configure "oslo.db"
+  when:
+    - '"oslo_db" in openstack_helm_endpoints_list'
+    - openstack_helm_endpoints_mariadb_admin_password is not defined
+  block:
+    - name: Grab Percona XtraDB cluster secret
+      kubernetes.core.k8s_info:
+        api_version: v1
+        kind: Secret
+        name: percona-xtradb
+        namespace: openstack
+      register: _openstack_helm_endpoints_oslo_db_secret
+
+    - name: Cache fact with Percona XtraDB password
+      ansible.builtin.set_fact:
+        openstack_helm_endpoints_mariadb_admin_password: "{{ _openstack_helm_endpoints_oslo_db_secret.resources[0]['data']['root'] | b64decode }}"
+
 - name: Reset value for OpenStack_Helm endpoints
   ansible.builtin.set_fact:
     openstack_helm_endpoints: "{{ openstack_helm_endpoints_config }}"
diff --git a/roles/openstack_helm_endpoints/vars/main.yml b/roles/openstack_helm_endpoints/vars/main.yml
index 98bb122..391cdec 100644
--- a/roles/openstack_helm_endpoints/vars/main.yml
+++ b/roles/openstack_helm_endpoints/vars/main.yml
@@ -30,11 +30,24 @@
 
 _openstack_helm_endpoints_oslo_db:
   oslo_db:
+    auth:
+      admin:
+        password: "{{ openstack_helm_endpoints_mariadb_admin_password }}"
     hosts:
       default: percona-xtradb-haproxy
 
 _openstack_helm_endpoints_oslo_messaging:
   oslo_messaging:
+    auth:
+      user:
+        username: "{{ _openstack_helm_endpoints_rabbitmq_cluster_username }}"
+        password: "{{ _openstack_helm_endpoints_rabbitmq_cluster_password }}"
+      # NOTE(mnaser): The following is not actually used by the chart, however,
+      #               since we are actually doing dynamic lookups to generate
+      #               endpoints, we add it here.
+      admin:
+        username: "{{ _openstack_helm_endpoints_rabbitmq_cluster_username }}"
+        password: "{{ _openstack_helm_endpoints_rabbitmq_cluster_password }}"
     statefulset: null
     hosts:
       default: "rabbitmq-{{ openstack_helm_endpoints_chart }}"
@@ -216,6 +229,8 @@
 _openstack_helm_endpoints_oslo_db_api:
   oslo_db_api:
     auth:
+      admin:
+        password: "{{ openstack_helm_endpoints_mariadb_admin_password }}"
       nova:
         password: "{{ openstack_helm_endpoints_nova_mariadb_password }}"
     hosts:
@@ -224,6 +239,8 @@
 _openstack_helm_endpoints_oslo_db_cell0:
   oslo_db_cell0:
     auth:
+      admin:
+        password: "{{ openstack_helm_endpoints_mariadb_admin_password }}"
       nova:
         password: "{{ openstack_helm_endpoints_nova_mariadb_password }}"
     hosts:
@@ -446,6 +463,10 @@
         region_name: "{{ openstack_helm_endpoints_magnum_region_name }}"
         username: "magnum-{{ openstack_helm_endpoints_magnum_region_name }}"
         password: "{{ openstack_helm_endpoints_magnum_keystone_password }}"
+      magnum_stack_user:
+        region_name: "{{ openstack_helm_endpoints_magnum_region_name }}"
+        username: "magnum-domain-{{ openstack_helm_endpoints_magnum_region_name }}"
+        password: "{{ openstack_helm_endpoints_magnum_keystone_password }}"
   container_infra:
     scheme:
       public: https
diff --git a/roles/openstack_helm_glance/tasks/main.yml b/roles/openstack_helm_glance/tasks/main.yml
index 6743778..9b2041c 100644
--- a/roles/openstack_helm_glance/tasks/main.yml
+++ b/roles/openstack_helm_glance/tasks/main.yml
@@ -77,18 +77,6 @@
           valuesFrom:
             - kind: Secret
               name: atmosphere-glance
-            - kind: Secret
-              name: percona-xtradb
-              valuesKey: root
-              targetPath: endpoints.oslo_db.auth.admin.password
-            - kind: Secret
-              name: rabbitmq-glance-default-user
-              valuesKey: username
-              targetPath: endpoints.oslo_messaging.auth.admin.username
-            - kind: Secret
-              name: rabbitmq-glance-default-user
-              valuesKey: password
-              targetPath: endpoints.oslo_messaging.auth.admin.password
 
 - name: Create Ingress
   ansible.builtin.include_role:
diff --git a/roles/openstack_helm_heat/tasks/main.yml b/roles/openstack_helm_heat/tasks/main.yml
index d9ec7bd..ccb0ef7 100644
--- a/roles/openstack_helm_heat/tasks/main.yml
+++ b/roles/openstack_helm_heat/tasks/main.yml
@@ -52,18 +52,6 @@
           valuesFrom:
             - kind: Secret
               name: atmosphere-heat
-            - kind: Secret
-              name: percona-xtradb
-              valuesKey: root
-              targetPath: endpoints.oslo_db.auth.admin.password
-            - kind: Secret
-              name: rabbitmq-heat-default-user
-              valuesKey: username
-              targetPath: endpoints.oslo_messaging.auth.admin.username
-            - kind: Secret
-              name: rabbitmq-heat-default-user
-              valuesKey: password
-              targetPath: endpoints.oslo_messaging.auth.admin.password
 
 - name: Create Ingress
   ansible.builtin.include_role:
diff --git a/roles/openstack_helm_horizon/tasks/main.yml b/roles/openstack_helm_horizon/tasks/main.yml
index 189099d..e10a794 100644
--- a/roles/openstack_helm_horizon/tasks/main.yml
+++ b/roles/openstack_helm_horizon/tasks/main.yml
@@ -52,10 +52,6 @@
           valuesFrom:
             - kind: Secret
               name: atmosphere-horizon
-            - kind: Secret
-              name: percona-xtradb
-              valuesKey: root
-              targetPath: endpoints.oslo_db.auth.admin.password
 
 - name: Create Ingress
   ansible.builtin.include_role:
diff --git a/roles/openstack_helm_keystone/tasks/main.yml b/roles/openstack_helm_keystone/tasks/main.yml
index 684399c..44d866f 100644
--- a/roles/openstack_helm_keystone/tasks/main.yml
+++ b/roles/openstack_helm_keystone/tasks/main.yml
@@ -52,18 +52,6 @@
           valuesFrom:
             - kind: Secret
               name: atmosphere-keystone
-            - kind: Secret
-              name: percona-xtradb
-              valuesKey: root
-              targetPath: endpoints.oslo_db.auth.admin.password
-            - kind: Secret
-              name: rabbitmq-keystone-default-user
-              valuesKey: username
-              targetPath: endpoints.oslo_messaging.auth.admin.username
-            - kind: Secret
-              name: rabbitmq-keystone-default-user
-              valuesKey: password
-              targetPath: endpoints.oslo_messaging.auth.admin.password
 
 - name: Create Ingress
   ansible.builtin.include_role:
diff --git a/roles/openstack_helm_magnum/README.md b/roles/openstack_helm_magnum/README.md
new file mode 100644
index 0000000..d4cf7d3
--- /dev/null
+++ b/roles/openstack_helm_magnum/README.md
@@ -0,0 +1 @@
+# `openstack_helm_magnum`
diff --git a/roles/openstack_helm_magnum/defaults/main.yml b/roles/openstack_helm_magnum/defaults/main.yml
index d291f86..21650de 100644
--- a/roles/openstack_helm_magnum/defaults/main.yml
+++ b/roles/openstack_helm_magnum/defaults/main.yml
@@ -1,19 +1,25 @@
----
-# .. vim: foldmarker=[[[,]]]:foldmethod=marker
-
-# .. Copyright (C) 2022 VEXXHOST, Inc.
-# .. SPDX-License-Identifier: Apache-2.0
-
-# Default variables
-# =================
-
-# .. contents:: Sections
-#    :local:
-
-
-# .. envvar:: openstack_helm_magnum_images [[[
+# Copyright (c) 2023 VEXXHOST, Inc.
 #
-# List of images for magnum clusters
+# 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.
+
+openstack_helm_magnum_helm_release_name: magnum
+openstack_helm_magnum_helm_chart_path: "{{ role_path }}/../../charts/magnum/"
+openstack_helm_magnum_helm_chart_ref: /usr/local/src/magnum
+
+openstack_helm_magnum_helm_release_namespace: openstack
+openstack_helm_magnum_helm_values: {}
+
+# List of images to load into OpenStack for Magnum
 openstack_helm_magnum_images:
   - name: ubuntu-2004-v1.23.13
     source_url: https://object-storage.public.mtl1.vexxhost.net/swift/v1/a91f106f55e64246babde7402c21b87a/magnum-capi/
@@ -31,7 +37,5 @@
     disk_format: qcow2
     container_format: bare
 
-                                                                   # ]]]
-
 # List of annotations to apply to the Ingress
 openstack_helm_magnum_ingress_annotations: {}
diff --git a/roles/openstack_helm_magnum/meta/main.yml b/roles/openstack_helm_magnum/meta/main.yml
index f639330..73d42b6 100644
--- a/roles/openstack_helm_magnum/meta/main.yml
+++ b/roles/openstack_helm_magnum/meta/main.yml
@@ -24,7 +24,11 @@
 
 dependencies:
   - role: defaults
-  - role: openstacksdk
-  - role: openstack_cli
-  - role: openstack_helm_barbican
-  - role: openstack_helm_octavia
+  - role: openstack_helm_endpoints
+    vars:
+      openstack_helm_endpoints_repo_name: openstack-helm
+      openstack_helm_endpoints_chart: magnum
+  - role: upload_helm_chart
+    vars:
+      upload_helm_chart_src: "{{ openstack_helm_magnum_helm_chart_path }}"
+      upload_helm_chart_dest: "{{ openstack_helm_magnum_helm_chart_ref }}"
diff --git a/roles/openstack_helm_magnum/tasks/main.yml b/roles/openstack_helm_magnum/tasks/main.yml
index 0d4204c..31df009 100644
--- a/roles/openstack_helm_magnum/tasks/main.yml
+++ b/roles/openstack_helm_magnum/tasks/main.yml
@@ -12,12 +12,40 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-- name: Generate OpenStack-Helm endpoints
-  ansible.builtin.include_role:
-    name: openstack_helm_endpoints
-  vars:
-    openstack_helm_endpoints_repo_name: openstack-helm
-    openstack_helm_endpoints_chart: magnum
+# NOTE(mnaser): We should get rid of this task eventually as it is suspending
+#               the old HelmRelease and removing it to avoid uninstalling the
+#               Helm chart.
+- name: Uninstall the legacy HelmRelease
+  run_once: true
+  block:
+    - name: Suspend the existing HelmRelease
+      kubernetes.core.k8s:
+        state: patched
+        api_version: helm.toolkit.fluxcd.io/v2beta1
+        kind: HelmRelease
+        name: "{{ openstack_helm_magnum_helm_release_name }}"
+        namespace: "{{ openstack_helm_magnum_helm_release_namespace }}"
+        definition:
+          spec:
+            suspend: true
+
+    - name: Remove the existing HelmRelease
+      kubernetes.core.k8s:
+        state: absent
+        api_version: helm.toolkit.fluxcd.io/v2beta1
+        kind: HelmRelease
+        name: "{{ openstack_helm_magnum_helm_release_name }}"
+        namespace: "{{ openstack_helm_magnum_helm_release_namespace }}"
+
+- name: Deploy Helm chart
+  run_once: true
+  kubernetes.core.helm:
+    name: "{{ openstack_helm_magnum_helm_release_name }}"
+    chart_ref: "{{ openstack_helm_magnum_helm_chart_ref }}"
+    release_namespace: "{{ openstack_helm_magnum_helm_release_namespace }}"
+    create_namespace: true
+    kubeconfig: /etc/kubernetes/admin.conf
+    values: "{{ _openstack_helm_magnum_helm_values | combine(openstack_helm_magnum_helm_values, recursive=True) }}"
 
 - name: Deploy Helm chart
   kubernetes.core.k8s:
diff --git a/roles/openstack_helm_magnum/vars/main.yml b/roles/openstack_helm_magnum/vars/main.yml
new file mode 100644
index 0000000..b29e430
--- /dev/null
+++ b/roles/openstack_helm_magnum/vars/main.yml
@@ -0,0 +1,73 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# 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.
+
+_openstack_helm_magnum_helm_values:
+  endpoints: "{{ openstack_helm_endpoints }}"
+  images:
+    pull_policy: Always
+    tags: "{{ atmosphere_images | openstack_helm_image_tags('magnum') }}"
+  conf:
+    magnum:
+      DEFAULT:
+        log_config_append: null
+      barbican_client:
+        endpoint_type: internalURL
+        region_name: "{{ openstack_helm_endpoints_barbican_region_name }}"
+      cinder_client:
+        endpoint_type: internalURL
+        region_name: "{{ openstack_helm_endpoints_cinder_region_name }}"
+      cluster_template:
+        kubernetes_allowed_network_drivers: calico
+        kubernetes_default_network_driver: calico
+      conductor:
+        workers: 4
+      drivers:
+        verify_ca: false
+      glance_client:
+        endpoint_type: internalURL
+        region_name: "{{ openstack_helm_endpoints_glance_region_name }}"
+      heat_client:
+        endpoint_type: internalURL
+        region_name: "{{ openstack_helm_endpoints_heat_region_name }}"
+      keystone_auth:
+        auth_url: http://keystone-api.openstack.svc.cluster.local:5000/v3
+        user_domain_name: service
+        username: "magnum-{{ openstack_helm_endpoints_magnum_region_name }}"
+        password: "{{ openstack_helm_endpoints_magnum_keystone_password }}"
+        # NOTE(mnaser): Magnum does not allow changing the interface to internal
+        #               so we workaround with this for now.
+        insecure: true
+      keystone_authtoken:
+        # NOTE(mnaser): Magnum does not allow changing the interface to internal
+        #               so we workaround with this for now.
+        insecure: true
+      magnum_client:
+        endpoint_type: internalURL
+        region_name: "{{ openstack_helm_endpoints_magnum_region_name }}"
+      neutron_client:
+        endpoint_type: internalURL
+        region_name: "{{ openstack_helm_endpoints_neutron_region_name }}"
+      nova_client:
+        endpoint_type: internalURL
+        region_name: "{{ openstack_helm_endpoints_nova_region_name }}"
+      octavia_client:
+        endpoint_type: internalURL
+        region_name: "{{ openstack_helm_endpoints_octavia_region_name }}"
+  pod:
+    replicas:
+      api: 3
+      conductor: 3
+  manifests:
+    ingress_api: false
+    service_ingress_api: false
diff --git a/roles/openstack_helm_neutron/tasks/main.yml b/roles/openstack_helm_neutron/tasks/main.yml
index 61d27be..47c1783 100644
--- a/roles/openstack_helm_neutron/tasks/main.yml
+++ b/roles/openstack_helm_neutron/tasks/main.yml
@@ -77,18 +77,6 @@
           valuesFrom:
             - kind: Secret
               name: atmosphere-neutron
-            - kind: Secret
-              name: percona-xtradb
-              valuesKey: root
-              targetPath: endpoints.oslo_db.auth.admin.password
-            - kind: Secret
-              name: rabbitmq-neutron-default-user
-              valuesKey: username
-              targetPath: endpoints.oslo_messaging.auth.admin.username
-            - kind: Secret
-              name: rabbitmq-neutron-default-user
-              valuesKey: password
-              targetPath: endpoints.oslo_messaging.auth.admin.password
 
 - name: Create Ingress
   ansible.builtin.include_role:
diff --git a/roles/openstack_helm_nova/tasks/main.yml b/roles/openstack_helm_nova/tasks/main.yml
index 335b589..090fcf7 100644
--- a/roles/openstack_helm_nova/tasks/main.yml
+++ b/roles/openstack_helm_nova/tasks/main.yml
@@ -83,26 +83,6 @@
           valuesFrom:
             - kind: Secret
               name: atmosphere-nova
-            - kind: Secret
-              name: percona-xtradb
-              valuesKey: root
-              targetPath: endpoints.oslo_db.auth.admin.password
-            - kind: Secret
-              name: percona-xtradb
-              valuesKey: root
-              targetPath: endpoints.oslo_db_api.auth.admin.password
-            - kind: Secret
-              name: percona-xtradb
-              valuesKey: root
-              targetPath: endpoints.oslo_db_cell0.auth.admin.password
-            - kind: Secret
-              name: rabbitmq-nova-default-user
-              valuesKey: username
-              targetPath: endpoints.oslo_messaging.auth.admin.username
-            - kind: Secret
-              name: rabbitmq-nova-default-user
-              valuesKey: password
-              targetPath: endpoints.oslo_messaging.auth.admin.password
 
 - name: Create Ingress
   ansible.builtin.include_role:
diff --git a/roles/openstack_helm_octavia/tasks/main.yml b/roles/openstack_helm_octavia/tasks/main.yml
index 0d5f677..2047c27 100644
--- a/roles/openstack_helm_octavia/tasks/main.yml
+++ b/roles/openstack_helm_octavia/tasks/main.yml
@@ -233,18 +233,6 @@
           valuesFrom:
             - kind: Secret
               name: atmosphere-octavia
-            - kind: Secret
-              name: percona-xtradb
-              valuesKey: root
-              targetPath: endpoints.oslo_db.auth.admin.password
-            - kind: Secret
-              name: rabbitmq-octavia-default-user
-              valuesKey: username
-              targetPath: endpoints.oslo_messaging.auth.admin.username
-            - kind: Secret
-              name: rabbitmq-octavia-default-user
-              valuesKey: password
-              targetPath: endpoints.oslo_messaging.auth.admin.password
 
 - name: Create Ingress
   ansible.builtin.include_role:
diff --git a/roles/openstack_helm_placement/tasks/main.yml b/roles/openstack_helm_placement/tasks/main.yml
index 020eb49..2407329 100644
--- a/roles/openstack_helm_placement/tasks/main.yml
+++ b/roles/openstack_helm_placement/tasks/main.yml
@@ -52,10 +52,6 @@
           valuesFrom:
             - kind: Secret
               name: atmosphere-placement
-            - kind: Secret
-              name: percona-xtradb
-              valuesKey: root
-              targetPath: endpoints.oslo_db.auth.admin.password
 
 - name: Create Ingress
   ansible.builtin.include_role:
diff --git a/roles/openstack_helm_senlin/tasks/main.yml b/roles/openstack_helm_senlin/tasks/main.yml
index 963fe2d..97b11d7 100644
--- a/roles/openstack_helm_senlin/tasks/main.yml
+++ b/roles/openstack_helm_senlin/tasks/main.yml
@@ -52,18 +52,6 @@
           valuesFrom:
             - kind: Secret
               name: atmosphere-senlin
-            - kind: Secret
-              name: percona-xtradb
-              valuesKey: root
-              targetPath: endpoints.oslo_db.auth.admin.password
-            - kind: Secret
-              name: rabbitmq-senlin-default-user
-              valuesKey: username
-              targetPath: endpoints.oslo_messaging.auth.admin.username
-            - kind: Secret
-              name: rabbitmq-senlin-default-user
-              valuesKey: password
-              targetPath: endpoints.oslo_messaging.auth.admin.password
 
 - name: Create Ingress
   ansible.builtin.include_role: