diff --git a/infra/image/build.sh b/infra/image/build.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1e31cbb0accb5acfa910db925826c06eeb02a884
--- /dev/null
+++ b/infra/image/build.sh
@@ -0,0 +1,66 @@
+#!/bin/bash -eu
+
+BASEDIR="$(readlink -f "$(dirname "$0")")"
+TOPDIR="$(readlink -f "${BASEDIR}/../..")"
+
+scenario=${1:-}
+name="ansible-test"
+hostname="ipaserver.test.local"
+cpus="2"
+memory="4g"
+quayname="quay.io/ansible-freeipa/upstream-tests"
+
+if [ -z "${scenario}" ]; then
+    echo "ERROR: Image needs to be given"
+    exit 1
+fi
+if [ ! -f "${BASEDIR}/dockerfile/${scenario}" ]; then
+    echo "ERROR: ${scenario} is not a valid image"
+    exit 1
+fi
+
+echo "= Cleanup existing ${scenario} ="
+podman image rm "${scenario}" --force
+echo
+
+echo "= Building ${scenario} ="
+podman build -t "${scenario}" -f "${BASEDIR}/dockerfile/${scenario}" \
+       "${BASEDIR}"
+echo
+
+echo "= Creating ${name} ="
+podman create --privileged --name "${name}" --hostname "${hostname}" \
+       --network bridge:interface_name=eth0 --systemd true \
+       --cpus "${cpus}" --memory "${memory}" --memory-swap -1 --no-hosts \
+       --replace "${scenario}"
+echo
+
+echo "= Starting ${name} ="
+podman start "${name}"
+echo
+
+echo "= Installing IPA ="
+ansible-playbook -i "${BASEDIR}/inventory" \
+       "${TOPDIR}/playbooks/install-server.yml"
+echo
+
+echo "= Enabling additional services ="
+podman exec "${name}" systemctl enable fixnet
+podman exec "${name}" systemctl enable fixipaip
+echo
+
+echo "= Stopping ${name} ="
+podman stop "${name}"
+echo
+
+echo "= Committing \"${quayname}:${scenario}\" ="
+podman commit "${name}" "${quayname}:${scenario}"
+echo
+
+echo "= DONE ="
+
+# For tests:
+# podman start "${name}"
+# while [ -n "$(podman exec ansible-test systemctl list-jobs | grep -vi "no jobs running")" ]; do echo "waiting.."; sleep 5; done
+# # Run tests
+# podman stop "${name}"
diff --git a/infra/image/dockerfile/c10s b/infra/image/dockerfile/c10s
new file mode 100644
index 0000000000000000000000000000000000000000..622098f36b7cb84b2772ba6dfa17810c6720bf01
--- /dev/null
+++ b/infra/image/dockerfile/c10s
@@ -0,0 +1,26 @@
+FROM quay.io/centos/centos:stream10-development
+ENV container=podman
+
+RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
+dnf makecache; \
+dnf --assumeyes install \
+    /usr/bin/python3 \
+    /usr/bin/dnf-3 \
+    sudo \
+    bash \
+    systemd \
+    procps-ng \
+    iproute; \
+rm -rf /var/cache/dnf/;
+
+COPY system-service/fixnet.sh /root/
+COPY system-service/fixipaip.sh /root/
+COPY system-service/fixnet.service /etc/systemd/system/
+COPY system-service/fixipaip.service /etc/systemd/system/
+RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
+
+STOPSIGNAL RTMIN+3
+
+VOLUME ["/sys/fs/cgroup"]
+
+CMD ["/usr/sbin/init"]
diff --git a/infra/image/dockerfile/c8s b/infra/image/dockerfile/c8s
new file mode 100644
index 0000000000000000000000000000000000000000..87a5b82e685258dab30c53ebbd5283adab7b7adc
--- /dev/null
+++ b/infra/image/dockerfile/c8s
@@ -0,0 +1,32 @@
+FROM quay.io/centos/centos:stream8
+ENV container=podman
+
+RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
+sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo; \
+sed -i s/^#.*baseurl=http/baseurl=http/g /etc/yum.repos.d/*.repo; \
+sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo; \
+dnf makecache; \
+dnf --assumeyes install \
+    /usr/bin/python3 \
+    /usr/bin/python3-config \
+    /usr/bin/dnf-3 \
+    sudo \
+    bash \
+    systemd \
+    procps-ng \
+    iproute; \
+dnf clean all; \
+rm -rf /var/cache/dnf/;
+
+COPY system-service/fixnet.sh /root/
+COPY system-service/fixipaip.sh /root/
+COPY system-service/fixnet.service /etc/systemd/system/
+COPY system-service/fixipaip.service /etc/systemd/system/
+RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
+
+STOPSIGNAL RTMIN+3
+
+VOLUME ["/sys/fs/cgroup"]
+
+CMD ["/usr/sbin/init"]
+
diff --git a/infra/image/dockerfile/c9s b/infra/image/dockerfile/c9s
new file mode 100644
index 0000000000000000000000000000000000000000..5fe77d926732c871a71e134cf0adfa3fb8883c14
--- /dev/null
+++ b/infra/image/dockerfile/c9s
@@ -0,0 +1,26 @@
+FROM quay.io/centos/centos:stream9
+ENV container=podman
+
+RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
+dnf makecache; \
+dnf --assumeyes install \
+    /usr/bin/python3 \
+    /usr/bin/dnf-3 \
+    sudo \
+    bash \
+    systemd \
+    procps-ng \
+    iproute; \
+rm -rf /var/cache/dnf/;
+
+COPY system-service/fixnet.sh /root/
+COPY system-service/fixipaip.sh /root/
+COPY system-service/fixnet.service /etc/systemd/system/
+COPY system-service/fixipaip.service /etc/systemd/system/
+RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
+
+STOPSIGNAL RTMIN+3
+
+VOLUME ["/sys/fs/cgroup"]
+
+CMD ["/usr/sbin/init"]
diff --git a/infra/image/dockerfile/fedora-latest b/infra/image/dockerfile/fedora-latest
new file mode 100644
index 0000000000000000000000000000000000000000..aadcffb7506c1edac65f7ae3a3db5d3e5c8d391d
--- /dev/null
+++ b/infra/image/dockerfile/fedora-latest
@@ -0,0 +1,28 @@
+FROM fedora:latest
+ENV container=podman
+
+RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
+dnf makecache; \
+dnf --assumeyes install \
+    /usr/bin/python3 \
+    /usr/bin/python3-config \
+    /usr/bin/dnf-3 \
+    sudo \
+    bash \
+    systemd \
+    procps-ng \
+    iproute; \
+dnf clean all; \
+rm -rf /var/cache/dnf/;
+
+COPY system-service/fixnet.sh /root/
+COPY system-service/fixipaip.sh /root/
+COPY system-service/fixnet.service /etc/systemd/system/
+COPY system-service/fixipaip.service /etc/systemd/system/
+RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
+
+STOPSIGNAL RTMIN+3
+
+VOLUME ["/sys/fs/cgroup"]
+
+CMD ["/usr/sbin/init"]
diff --git a/infra/image/dockerfile/fedora-rawhide b/infra/image/dockerfile/fedora-rawhide
new file mode 100644
index 0000000000000000000000000000000000000000..5a1aa005cdfa4f19bdcc176fb96a02f24667da54
--- /dev/null
+++ b/infra/image/dockerfile/fedora-rawhide
@@ -0,0 +1,29 @@
+FROM fedora:rawhide
+ENV container=podman
+
+RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
+dnf makecache; \
+dnf --assumeyes install \
+    /usr/bin/python3 \
+    /usr/bin/python3-config \
+    /usr/bin/dnf-3 \
+    python3-libdnf5 \
+    sudo \
+    bash \
+    systemd \
+    procps-ng \
+    iproute; \
+dnf clean all; \
+rm -rf /var/cache/dnf/;
+
+COPY system-service/fixnet.sh /root/
+COPY system-service/fixipaip.sh /root/
+COPY system-service/fixnet.service /etc/systemd/system/
+COPY system-service/fixipaip.service /etc/systemd/system/
+RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
+
+STOPSIGNAL RTMIN+3
+
+VOLUME ["/sys/fs/cgroup"]
+
+CMD ["/usr/sbin/init"]
diff --git a/infra/image/inventory b/infra/image/inventory
new file mode 100644
index 0000000000000000000000000000000000000000..7ee5e709113492ee97d0f4042db7ba9e69eefa3c
--- /dev/null
+++ b/infra/image/inventory
@@ -0,0 +1,15 @@
+[ipaserver]
+ansible-test ansible_connection=podman ansible_python_interpreter=/usr/bin/python3
+
+[ipaserver:vars]
+ipaadmin_password=SomeADMINpassword
+ipadm_password=SomeDMpassword
+ipaserver_domain=test.local
+ipaserver_realm=TEST.LOCAL
+ipaserver_setup_dns=true
+ipaserver_auto_forwarders=true
+ipaserver_no_dnssec_validation=true
+ipaserver_auto_reverse=true
+ipaserver_setup_kra=true
+ipaserver_setup_firewalld=false
+ipaclient_no_ntp=true
diff --git a/infra/image/system-service/fixipaip.service b/infra/image/system-service/fixipaip.service
new file mode 100644
index 0000000000000000000000000000000000000000..6dde6ae8403abaac251c05060d1cc31e9d741b00
--- /dev/null
+++ b/infra/image/system-service/fixipaip.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Fix IPA server IP in IPA Server
+After=multi-user.target
+
+[Service]
+Type=oneshot
+ExecStart=/root/fixipaip.sh
+
+[Install]
+WantedBy=default.target
diff --git a/infra/image/system-service/fixipaip.sh b/infra/image/system-service/fixipaip.sh
new file mode 100755
index 0000000000000000000000000000000000000000..dd638fa029eb6b958de06beb557153ddd1300413
--- /dev/null
+++ b/infra/image/system-service/fixipaip.sh
@@ -0,0 +1,26 @@
+#!/bin/bash -eu
+
+HOSTNAME=$(hostname)
+IP=$(hostname -I | cut -d " " -f 1)
+
+if [ -z "${HOSTNAME}" ]; then
+    echo "ERROR: Failed to retrieve hostname."
+    exit 1
+fi
+if [ -z "${IP}" ]; then
+    echo "ERROR: Failed to retrieve IP address."
+    exit 1
+fi
+
+if ! echo "SomeADMINpassword" | kinit -c ansible_freeipa_cache admin
+then
+    echo "ERROR: Failed to obtain Kerberos ticket"
+    exit 1
+fi
+KRB5CCNAME=ansible_freeipa_cache \
+    ipa dnsrecord-mod test.local "${HOSTNAME%%.*}" --a-rec="$IP"
+KRB5CCNAME=ansible_freeipa_cache \
+    ipa dnsrecord-mod test.local ipa-ca --a-rec="$IP"
+kdestroy -c ansible_freeipa_cache -A
+
+exit 0
diff --git a/infra/image/system-service/fixnet.service b/infra/image/system-service/fixnet.service
new file mode 100644
index 0000000000000000000000000000000000000000..c481b19ee496c1076d1895f40d1ea9616e6acaa3
--- /dev/null
+++ b/infra/image/system-service/fixnet.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Fix server IP in IPA Server
+Wants=network.target
+After=network.target
+Before=ipa.service
+
+[Service]
+Type=oneshot
+ExecStart=/root/fixnet.sh
+
+[Install]
+WantedBy=ipa.service
diff --git a/infra/image/system-service/fixnet.sh b/infra/image/system-service/fixnet.sh
new file mode 100755
index 0000000000000000000000000000000000000000..3fc05b515c2e0c79f4b16c182d02bf8f67ad4dd6
--- /dev/null
+++ b/infra/image/system-service/fixnet.sh
@@ -0,0 +1,24 @@
+#!/bin/bash -eu
+
+HOSTNAME=$(hostname)
+IP=$(hostname -I | cut -d " " -f 1)
+
+if [ -z "${HOSTNAME}" ]; then
+    echo "ERROR: Failed to retrieve hostname."
+    exit 1
+fi
+if [ -z "${IP}" ]; then
+    echo "ERROR: Failed to retrieve IP address."
+    exit 1
+fi
+
+# shellcheck disable=SC2143
+if [ -n "$(grep -P "[[:space:]]${HOSTNAME}" /etc/hosts)" ]; then
+    sed -ie "s/.*${HOSTNAME}/${IP}\t${HOSTNAME}/" /etc/hosts
+else
+    echo -e "$IP\t${HOSTNAME}" >> /etc/hosts
+fi
+
+echo "nameserver 127.0.0.1" > /etc/resolv.conf
+
+exit 0