diff --git a/manifests/site/test-site/ephemeral/initinfra/kustomization.yaml b/manifests/site/test-site/ephemeral/initinfra/kustomization.yaml
index 5566fa80d..7493021a0 100644
--- a/manifests/site/test-site/ephemeral/initinfra/kustomization.yaml
+++ b/manifests/site/test-site/ephemeral/initinfra/kustomization.yaml
@@ -1,4 +1,7 @@
 resources:
+  - ../../shared/clusterctl
   - ../../../../function/baremetal-operator
+patchesStrategicMerge:
+  - patch_bmo_config.yaml
 commonLabels:
   airshipit.org/stage: initinfra
diff --git a/manifests/site/test-site/ephemeral/initinfra/patch_bmo_config.yaml b/manifests/site/test-site/ephemeral/initinfra/patch_bmo_config.yaml
new file mode 100644
index 000000000..fe1e595ad
--- /dev/null
+++ b/manifests/site/test-site/ephemeral/initinfra/patch_bmo_config.yaml
@@ -0,0 +1,10 @@
+---
+kind: ConfigMap
+apiVersion: v1
+metadata:
+  labels:
+  name: ironic-vars
+data:
+  PROVISIONING_IP: "10.23.24.101"
+  DHCP_RANGE: "10.23.24.200,10.23.24.250"
+  PROVISIONING_INTERFACE: "enp0s4"
diff --git a/manifests/site/test-site/shared/clusterctl/clusterctl.yaml b/manifests/site/test-site/shared/clusterctl/clusterctl.yaml
new file mode 100644
index 000000000..5873ff506
--- /dev/null
+++ b/manifests/site/test-site/shared/clusterctl/clusterctl.yaml
@@ -0,0 +1,31 @@
+apiVersion: airshipit.org/v1alpha1
+kind: Clusterctl
+metadata:
+  labels:
+    airshipit.org/deploy-k8s: "false"
+  name: clusterctl-v1
+init-options:
+  core-provider: "cluster-api:v0.3.3"
+  bootstrap-providers:
+    - "kubeadm:v0.3.3"
+  infrastructure-providers:
+    - "metal3:v0.3.1"
+  control-plane-providers:
+    - "kubeadm:v0.3.3"
+providers:
+  - name: "metal3"
+    type: "InfrastructureProvider"
+    versions:
+      v0.3.1: manifests/function/capm3/v0.3.1
+  - name: "kubeadm"
+    type: "BootstrapProvider"
+    versions:
+      v0.3.3: manifests/function/cabpk/v0.3.3
+  - name: "cluster-api"
+    type: "CoreProvider"
+    versions:
+      v0.3.3: manifests/function/capi/v0.3.3
+  - name: "kubeadm"
+    type: "ControlPlaneProvider"
+    versions:
+      v0.3.3: manifests/function/cacpk/v0.3.3
diff --git a/manifests/site/test-site/shared/clusterctl/kustomization.yaml b/manifests/site/test-site/shared/clusterctl/kustomization.yaml
new file mode 100644
index 000000000..4bc44013e
--- /dev/null
+++ b/manifests/site/test-site/shared/clusterctl/kustomization.yaml
@@ -0,0 +1,2 @@
+resources:
+  - clusterctl.yaml
diff --git a/playbooks/airship-airshipctl-test-runner.yaml b/playbooks/airship-airshipctl-test-runner.yaml
index d86c30b8c..68e483ce2 100644
--- a/playbooks/airship-airshipctl-test-runner.yaml
+++ b/playbooks/airship-airshipctl-test-runner.yaml
@@ -22,6 +22,7 @@
           - airshipctl-build-ephemeral-iso
           - install-kubectl
           - airshipctl-deploy-ephemeral-node
+          - airshipctl-cluster-init-ephemeral
           - airshipctl-phase-apply-initinfra
         var_files_default:
           - local-dev.yaml
diff --git a/roles/airshipctl-cluster-init-ephemeral/tasks/main.yaml b/roles/airshipctl-cluster-init-ephemeral/tasks/main.yaml
new file mode 100644
index 000000000..0ffcfcb6e
--- /dev/null
+++ b/roles/airshipctl-cluster-init-ephemeral/tasks/main.yaml
@@ -0,0 +1,55 @@
+# 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: initialize CAPI components
+  command: >-
+    airshipctl --debug cluster init
+
+- name: verify CAPI deployments are created
+  command: >-
+    timeout 20 kubectl \
+    --kubeconfig {{ airshipctl_config_dir_default | default(ansible_env.HOME) }}/.airship/kubeconfig \
+    get deploy -n {{ item.namespace }} {{ item.name }}
+  register: deploy_status
+  until: item.name in deploy_status.stdout
+  with_items:
+    - namespace: capi-kubeadm-bootstrap-system
+      name: capi-kubeadm-bootstrap-controller-manager
+    - namespace: capi-kubeadm-control-plane-system
+      name: capi-kubeadm-control-plane-controller-manager
+    - namespace: capi-system
+      name: capi-controller-manager
+    - namespace: capi-webhook-system
+      name: capi-controller-manager
+    - namespace: capi-webhook-system
+      name: capi-kubeadm-bootstrap-controller-manager
+    - namespace: capi-webhook-system
+      name: capi-kubeadm-control-plane-controller-manager
+    - namespace: capi-webhook-system
+      name: capm3-controller-manager
+    - namespace: capm3-system
+      name: capm3-controller-manager
+    - namespace: cert-manager
+      name: cert-manager
+    - namespace: cert-manager
+      name: cert-manager-cainjector
+    - namespace: cert-manager
+      name: cert-manager-webhook
+  retries: 50
+  delay: 20
+
+# TODO: As soon as issue #127 is complete, this check for deployments
+# should be removed and initinfra command should check for resource status.
+- name: verify all deployments are up
+  command: >-
+    kubectl --kubeconfig {{ airshipctl_config_dir_default | default(ansible_env.HOME) }}/.airship/kubeconfig \
+    wait --for=condition=available deploy --all --timeout=1000s -A
diff --git a/tools/gate/29_cluster_init.sh b/tools/gate/29_cluster_init.sh
new file mode 100755
index 000000000..a7b10e85f
--- /dev/null
+++ b/tools/gate/29_cluster_init.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+set -xe
+
+TMP_DIR=${TMP_DIR:-"$(dirname $(mktemp -u))"}
+ANSIBLE_HOSTS=${ANSIBLE_HOSTS:-"${TMP_DIR}/ansible_hosts"}
+PLAYBOOK_CONFIG=${PLAYBOOK_CONFIG:-"${TMP_DIR}/config.yaml"}
+
+sudo ansible-playbook -i "$ANSIBLE_HOSTS" \
+	playbooks/airship-airshipctl-test-runner.yaml \
+	-e @tools/gate/config_cluster_init.yaml \
+	-e @"$PLAYBOOK_CONFIG"
diff --git a/tools/gate/config_cluster_init.yaml b/tools/gate/config_cluster_init.yaml
new file mode 100644
index 000000000..a8e0814f3
--- /dev/null
+++ b/tools/gate/config_cluster_init.yaml
@@ -0,0 +1,15 @@
+# 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.
+
+---
+test_roles:
+  - airshipctl-cluster-init-ephemeral
diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml
index aa4c97f7c..2d48a8b1e 100644
--- a/zuul.d/jobs.yaml
+++ b/zuul.d/jobs.yaml
@@ -79,6 +79,7 @@
         - install-kubectl
         - airshipctl-deploy-ephemeral-node
         - airshipctl-phase-apply-initinfra
+        - airshipctl-cluster-init-ephemeral
       serve_dir: /srv/iso
       serve_port: 8099
 
@@ -103,6 +104,7 @@
         - install-kubectl
         - airshipctl-deploy-ephemeral-node
         - airshipctl-phase-apply-initinfra
+        - airshipctl-cluster-init-ephemeral
       serve_dir: /srv/iso
       serve_port: 8099
     voting: false