fix: move pxc to role and allow overriding
diff --git a/atmosphere/flows.py b/atmosphere/flows.py
index d05a3e1..73cd25c 100644
--- a/atmosphere/flows.py
+++ b/atmosphere/flows.py
@@ -275,7 +275,6 @@
     flow = graph_flow.Flow("deploy").add(
         # cert-manager
         *cert_manager.issuer_tasks_from_config(config.issuer),
-        openstack_helm.ApplyPerconaXtraDBClusterTask(),
     )
 
     if config.memcached.enabled:
diff --git a/atmosphere/tasks/composite/openstack_helm.py b/atmosphere/tasks/composite/openstack_helm.py
index acd9b89..e47c583 100644
--- a/atmosphere/tasks/composite/openstack_helm.py
+++ b/atmosphere/tasks/composite/openstack_helm.py
@@ -1,14 +1,11 @@
 import textwrap
 
 import mergedeep
-import pykube
 import yaml
 
-from atmosphere import utils
 from atmosphere.models import config
 from atmosphere.models.openstack_helm import values
-from atmosphere.tasks import constants
-from atmosphere.tasks.kubernetes import base, flux, v1
+from atmosphere.tasks.kubernetes import flux, v1
 
 
 class ApplyReleaseSecretTask(v1.ApplySecretTask):
@@ -131,84 +128,3 @@
             },
         ],
     }
-
-
-class PerconaXtraDBCluster(pykube.objects.NamespacedAPIObject):
-    version = "pxc.percona.com/v1-10-0"
-    endpoint = "perconaxtradbclusters"
-    kind = "PerconaXtraDBCluster"
-
-
-class ApplyPerconaXtraDBClusterTask(base.ApplyKubernetesObjectTask):
-    def __init__(self):
-        super().__init__(
-            kind=PerconaXtraDBCluster,
-            namespace=constants.NAMESPACE_OPENSTACK,
-            name="percona-xtradb",
-        )
-
-    def generate_object(self) -> PerconaXtraDBCluster:
-        return PerconaXtraDBCluster(
-            self.api,
-            {
-                "apiVersion": self._obj_kind.version,
-                "kind": self._obj_kind.kind,
-                "metadata": {
-                    "name": self._obj_name,
-                    "namespace": self._obj_namespace,
-                },
-                "spec": {
-                    "crVersion": "1.10.0",
-                    "secretsName": "percona-xtradb",
-                    "pxc": {
-                        "size": 3,
-                        "image": utils.get_image_ref_using_legacy_image_repository(
-                            "percona_xtradb_cluster"
-                        ).string(),
-                        "autoRecovery": True,
-                        "configuration": "[mysqld]\nmax_connections=8192\n",
-                        "sidecars": [
-                            {
-                                "name": "exporter",
-                                "image": utils.get_image_ref_using_legacy_image_repository(
-                                    "prometheus_mysqld_exporter"
-                                ).string(),
-                                "ports": [{"name": "metrics", "containerPort": 9104}],
-                                "livenessProbe": {
-                                    "httpGet": {"path": "/", "port": 9104}
-                                },
-                                "env": [
-                                    {
-                                        "name": "MONITOR_PASSWORD",
-                                        "valueFrom": {
-                                            "secretKeyRef": {
-                                                "name": "percona-xtradb",
-                                                "key": "monitor",
-                                            }
-                                        },
-                                    },
-                                    {
-                                        "name": "DATA_SOURCE_NAME",
-                                        "value": "monitor:$(MONITOR_PASSWORD)@(localhost:3306)/",
-                                    },
-                                ],
-                            }
-                        ],
-                        "nodeSelector": constants.NODE_SELECTOR_CONTROL_PLANE,
-                        "volumeSpec": {
-                            "persistentVolumeClaim": {
-                                "resources": {"requests": {"storage": "160Gi"}}
-                            }
-                        },
-                    },
-                    "haproxy": {
-                        "enabled": True,
-                        "size": 3,
-                        "image": utils.get_image_ref_using_legacy_image_repository(
-                            "percona_xtradb_cluster_haproxy"
-                        ).string(),
-                        "nodeSelector": {"openstack-control-plane": "enabled"},
-                    },
-                },
-            },
-        )
diff --git a/roles/atmosphere/meta/main.yml b/roles/atmosphere/meta/main.yml
index e676cd4..894f7b0 100644
--- a/roles/atmosphere/meta/main.yml
+++ b/roles/atmosphere/meta/main.yml
@@ -24,4 +24,4 @@
         - focal
 
 dependencies:
-  - role: percona_xtradb_cluster_operator
+  - role: percona_xtradb_cluster
diff --git a/roles/openstack_helm_barbican/meta/main.yml b/roles/openstack_helm_barbican/meta/main.yml
index 3f8b4a4..f479c17 100644
--- a/roles/openstack_helm_barbican/meta/main.yml
+++ b/roles/openstack_helm_barbican/meta/main.yml
@@ -25,4 +25,3 @@
 
 dependencies:
   - role: atmosphere
-  - role: wait_for_pxc
diff --git a/roles/openstack_helm_cinder/meta/main.yml b/roles/openstack_helm_cinder/meta/main.yml
index 83f86ce..e44991a 100644
--- a/roles/openstack_helm_cinder/meta/main.yml
+++ b/roles/openstack_helm_cinder/meta/main.yml
@@ -25,4 +25,3 @@
 
 dependencies:
   - role: atmosphere
-  - role: wait_for_pxc
diff --git a/roles/openstack_helm_designate/meta/main.yml b/roles/openstack_helm_designate/meta/main.yml
index 469958a..c0d03fc 100644
--- a/roles/openstack_helm_designate/meta/main.yml
+++ b/roles/openstack_helm_designate/meta/main.yml
@@ -24,4 +24,3 @@
 
 dependencies:
   - role: atmosphere
-  - role: wait_for_pxc
diff --git a/roles/openstack_helm_glance/meta/main.yml b/roles/openstack_helm_glance/meta/main.yml
index baf7a6d..d286883 100644
--- a/roles/openstack_helm_glance/meta/main.yml
+++ b/roles/openstack_helm_glance/meta/main.yml
@@ -25,4 +25,3 @@
 
 dependencies:
   - role: openstacksdk
-  - role: wait_for_pxc
diff --git a/roles/openstack_helm_heat/meta/main.yml b/roles/openstack_helm_heat/meta/main.yml
index 57e2e1c..3a7140b 100644
--- a/roles/openstack_helm_heat/meta/main.yml
+++ b/roles/openstack_helm_heat/meta/main.yml
@@ -25,4 +25,3 @@
 
 dependencies:
   - role: atmosphere
-  - role: wait_for_pxc
diff --git a/roles/openstack_helm_horizon/meta/main.yml b/roles/openstack_helm_horizon/meta/main.yml
index f0271e3..f101c63 100644
--- a/roles/openstack_helm_horizon/meta/main.yml
+++ b/roles/openstack_helm_horizon/meta/main.yml
@@ -25,4 +25,3 @@
 
 dependencies:
   - role: atmosphere
-  - role: wait_for_pxc
diff --git a/roles/openstack_helm_keystone/meta/main.yml b/roles/openstack_helm_keystone/meta/main.yml
index 0fcab44..4929cc5 100644
--- a/roles/openstack_helm_keystone/meta/main.yml
+++ b/roles/openstack_helm_keystone/meta/main.yml
@@ -25,4 +25,3 @@
 
 dependencies:
   - role: atmosphere
-  - role: wait_for_pxc
diff --git a/roles/openstack_helm_magnum/meta/main.yml b/roles/openstack_helm_magnum/meta/main.yml
index 9b7fe68..f2e80be 100644
--- a/roles/openstack_helm_magnum/meta/main.yml
+++ b/roles/openstack_helm_magnum/meta/main.yml
@@ -25,6 +25,5 @@
 dependencies:
   - role: openstacksdk
   - role: openstack_cli
-  - role: wait_for_pxc
   - role: openstack_helm_barbican
   - role: openstack_helm_octavia
diff --git a/roles/openstack_helm_neutron/meta/main.yml b/roles/openstack_helm_neutron/meta/main.yml
index b56ee77..ba41c29 100644
--- a/roles/openstack_helm_neutron/meta/main.yml
+++ b/roles/openstack_helm_neutron/meta/main.yml
@@ -26,4 +26,3 @@
 dependencies:
   - role: atmosphere
   - role: openstacksdk
-  - role: wait_for_pxc
diff --git a/roles/openstack_helm_nova/meta/main.yml b/roles/openstack_helm_nova/meta/main.yml
index 2812822..ad12692 100644
--- a/roles/openstack_helm_nova/meta/main.yml
+++ b/roles/openstack_helm_nova/meta/main.yml
@@ -26,4 +26,3 @@
 dependencies:
   - role: atmosphere
   - role: openstacksdk
-  - role: wait_for_pxc
diff --git a/roles/openstack_helm_octavia/meta/main.yml b/roles/openstack_helm_octavia/meta/main.yml
index 96b62d3..181e9ad 100644
--- a/roles/openstack_helm_octavia/meta/main.yml
+++ b/roles/openstack_helm_octavia/meta/main.yml
@@ -25,4 +25,3 @@
 dependencies:
   - role: openstacksdk
   - role: openstack_cli
-  - role: wait_for_pxc
diff --git a/roles/openstack_helm_placement/meta/main.yml b/roles/openstack_helm_placement/meta/main.yml
index 37a83d9..c83011a 100644
--- a/roles/openstack_helm_placement/meta/main.yml
+++ b/roles/openstack_helm_placement/meta/main.yml
@@ -25,4 +25,3 @@
 
 dependencies:
   - role: atmosphere
-  - role: wait_for_pxc
diff --git a/roles/openstack_helm_senlin/meta/main.yml b/roles/openstack_helm_senlin/meta/main.yml
index 73308ad..4c25fbe 100644
--- a/roles/openstack_helm_senlin/meta/main.yml
+++ b/roles/openstack_helm_senlin/meta/main.yml
@@ -25,4 +25,3 @@
 
 dependencies:
   - role: atmosphere
-  - role: wait_for_pxc
diff --git a/roles/wait_for_pxc/README.md b/roles/percona_xtradb_cluster/README.md
similarity index 85%
rename from roles/wait_for_pxc/README.md
rename to roles/percona_xtradb_cluster/README.md
index 918f313..e039257 100644
--- a/roles/wait_for_pxc/README.md
+++ b/roles/percona_xtradb_cluster/README.md
@@ -1,4 +1,4 @@
-# wait_for_pxc
+# percona_xtradb_cluster
 
 This is a meta-role which should be used as a dependency for now to allow the
 Ansible roles to wait for the PXC cluster to be ready before proceeding.
diff --git a/roles/percona_xtradb_cluster/defaults/main.yml b/roles/percona_xtradb_cluster/defaults/main.yml
new file mode 100644
index 0000000..53583c4
--- /dev/null
+++ b/roles/percona_xtradb_cluster/defaults/main.yml
@@ -0,0 +1,4 @@
+# This variable allows you to add configuration options to `spec` field on the
+# PerconaXtraDBCluster object in Kubernetes.  It can be used to enable features
+# such as backups.
+percona_xtradb_cluster_spec: {}
diff --git a/roles/percona_xtradb_cluster/meta/main.yml b/roles/percona_xtradb_cluster/meta/main.yml
new file mode 100644
index 0000000..9c28d2f
--- /dev/null
+++ b/roles/percona_xtradb_cluster/meta/main.yml
@@ -0,0 +1,27 @@
+# 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 Percona XtraDB cluster
+  license: Apache-2.0
+  min_ansible_version: 5.5.0
+  standalone: false
+  platforms:
+    - name: Ubuntu
+      versions:
+        - focal
+
+dependencies:
+  - role: percona_xtradb_cluster_operator
diff --git a/roles/percona_xtradb_cluster/tasks/main.yml b/roles/percona_xtradb_cluster/tasks/main.yml
new file mode 100644
index 0000000..5cae3e8
--- /dev/null
+++ b/roles/percona_xtradb_cluster/tasks/main.yml
@@ -0,0 +1,17 @@
+- name: Create Percona XtraDB cluster
+  run_once: true
+  kubernetes.core.k8s:
+    state: present
+    definition:
+      apiVersion: pxc.percona.com/v1-10-0
+      kind: PerconaXtraDBCluster
+      metadata:
+        name: percona-xtradb
+        namespace: openstack
+      spec: "{{ _percona_xtradb_cluster_spec | combine(percona_xtradb_cluster_spec, recursive=True) }}"
+    wait_sleep: 1
+    wait_timeout: 600
+    wait: true
+    wait_condition:
+      type: ready
+      status: true
diff --git a/roles/percona_xtradb_cluster/vars/main.yml b/roles/percona_xtradb_cluster/vars/main.yml
new file mode 100644
index 0000000..cd6a5b5
--- /dev/null
+++ b/roles/percona_xtradb_cluster/vars/main.yml
@@ -0,0 +1,41 @@
+_percona_xtradb_cluster_spec:
+  crVersion: "1.10.0"
+  secretsName: percona-xtradb
+  pxc:
+    size: 3
+    image: "{{ lookup('vexxhost.atmosphere.image_ref', 'percona_xtradb_cluster', output='ref') }}"
+    autoRecovery: true
+    configuration: |
+      [mysqld]
+      max_connections=8192
+    sidecars:
+      - name: exporter
+        image: "{{ lookup('vexxhost.atmosphere.image_ref', 'prometheus_mysqld_exporter', output='ref') }}"
+        env:
+          - name: MONITOR_PASSWORD
+            valueFrom:
+              secretKeyRef:
+                name: percona-xtradb
+                key: monitor
+          - name: DATA_SOURCE_NAME
+            value: "monitor:$(MONITOR_PASSWORD)@(localhost:3306)/"
+        ports:
+          - name: metrics
+            containerPort: 9104
+        livenessProbe:
+          httpGet:
+            port: metrics
+            path: /
+    nodeSelector:
+      openstack-control-plane: enabled
+    volumeSpec:
+      persistentVolumeClaim:
+        resources:
+          requests:
+            storage: 160Gi
+  haproxy:
+    enabled: true
+    size: 3
+    image: "{{ lookup('vexxhost.atmosphere.image_ref', 'percona_xtradb_cluster_haproxy', output='ref') }}"
+    nodeSelector:
+      openstack-control-plane: enabled
diff --git a/roles/percona_xtradb_cluster_operator/meta/main.yml b/roles/percona_xtradb_cluster_operator/meta/main.yml
new file mode 100644
index 0000000..c523acb
--- /dev/null
+++ b/roles/percona_xtradb_cluster_operator/meta/main.yml
@@ -0,0 +1,24 @@
+# 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 Percona XtraDB cluster operator
+  license: Apache-2.0
+  min_ansible_version: 5.5.0
+  standalone: false
+  platforms:
+    - name: Ubuntu
+      versions:
+        - focal
diff --git a/roles/wait_for_pxc/tasks/main.yml b/roles/wait_for_pxc/tasks/main.yml
deleted file mode 100644
index 5fa3637..0000000
--- a/roles/wait_for_pxc/tasks/main.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-- name: Wait until Percona XtraDB Cluster is ready
-  kubernetes.core.k8s_info:
-    api_version: pxc.percona.com/v1
-    kind: PerconaXtraDBCluster
-    name: percona-xtradb
-    namespace: openstack
-    wait_sleep: 1
-    wait_timeout: 600
-    wait: true
-    wait_condition:
-      type: ready
-      status: true