Add Dockerfile

This commit is contained in:
2026-07-07 16:57:36 +00:00
parent ab81491143
commit 48e992dd41
+233
View File
@@ -0,0 +1,233 @@
# ───────────────────────────────────────────────────────────
# Ansible Control Node — Alpine-based, QEMU-bootable
#
# Dual-purpose image:
# 1. Run directly: docker run --rm -it ansible-node ansible-playbook ...
# 2. Convert to QEMU disk: scripts/build-qemu.sh extracts this rootfs
# into a bootable qcow2 for pc-q35-10.0
#
# Integrations:
# • Windows — pywinrm + kerberos → WinRM
# • Cisco ASA — cisco.asa + paramiko → SSH/CLI
# • Cisco Catalyst— cisco.ios + paramiko → SSH/CLI
# • Cisco NX-OS — cisco.nxos + paramiko → SSH/NX-API
# • Linux — native SSH (built-in ansible)
# • VMware — pyvmomi → vCenter/ESXi SOAP API
# • MSSQL — pymssql → SQL Server TDS
# ───────────────────────────────────────────────────────────
FROM alpine:3.20
# ── System labels ──────────────────────────────────────────
LABEL org.opencontainers.image.title="Ansible Control Node"
LABEL org.opencontainers.image.description="Minimal Ansible control node for Windows, Cisco, VMware, MSSQL, and Linux targets. QEMU-bootable via build-qemu.sh."
LABEL org.opencontainers.image.authors="ansible_testing"
# ── Kernel + base system ──────────────────────────────
# alpine-base = openrc + busybox + mdev + init scripts (no systemd)
# linux-virt = kernel optimized for VMs (virtio, no firmware)
# docker = container runtime for nested workloads
RUN apk add --no-cache \
alpine-base \
linux-virt \
e2fsprogs \
docker \
docker-openrc \
# ── Networking ────────────────────────────────────────
dhcpcd \
openssh-client \
openssh-server \
curl \
wget \
ca-certificates \
bind-tools \
# ── Kerberos (WinRM Kerberos auth to Windows) ────────
krb5 \
krb5-server \
# ── FreeTDS (pymssql → MSSQL TDS protocol) ───────────
freetds \
freetds-dev \
# ── Ansible + Python + SSH pw provider ───────────────
ansible \
sshpass \
py3-pip \
python3 \
python3-dev \
# ── Build deps for pip packages (purged after) ───────
gcc \
musl-dev \
openssl-dev \
krb5-dev \
libffi-dev \
# ── Quality-of-life ──────────────────────────────────
bash \
bash-completion \
vim \
tmux \
git \
jq \
less \
sudo
# ── Python packages for target integrations ──────────────
RUN pip3 install --no-cache-dir --break-system-packages \
# Windows: WinRM + Kerberos
'pywinrm[kerberos]>=0.4' \
requests-kerberos \
requests-ntlm \
# Cisco: SSH/NETCONF/RESTCONF
paramiko>=2.7 \
ncclient>=0.6 \
netmiko>=4.0 \
scp \
# VMware: vCenter/ESXi SOAP API
pyvmomi>=8.0 \
requests \
# MSSQL: TDS protocol
pymssql>=2.2 \
# General utilities (required by many Ansible modules)
jmespath>=1.0 \
xmltodict>=0.13 \
pyyaml>=6.0 \
cryptography>=41.0 \
packaging
# ── Ansible collections for all target types ──────────────
RUN ansible-galaxy collection install \
# Windows management
ansible.windows \
# Network common (required by Cisco collections)
ansible.netcommon \
ansible.utils \
# Cisco ASA firewalls
cisco.asa \
# Cisco Catalyst / IOS / IOS-XE switches & routers
cisco.ios \
# Cisco Nexus / NX-OS data center switches
cisco.nxos \
# VMware vCenter / ESXi
community.vmware \
# MSSQL Server
community.general \
community.mysql \
microsoft.sql \
# Crypto/certificates (needed for various modules)
community.crypto \
# Generic collection with many useful modules
community.general
# ── OpenRC: enable boot services ──────────────────────────
# sysinit — devices, logging, hardware
RUN rc-update add devfs sysinit && \
rc-update add dmesg sysinit && \
rc-update add mdev sysinit && \
rc-update add hwdrivers sysinit
# boot — modules, networking, hostname (urandom handled by bootmisc)
RUN rc-update add modules boot && \
rc-update add sysctl boot && \
rc-update add bootmisc boot && \
rc-update add hostname boot && \
rc-update add networking boot
# default — SSH, DHCP, Docker daemon
RUN rc-update add sshd default && \
rc-update add dhcpcd default && \
rc-update add docker default
# ── Serial console (ttyS0) for QEMU -nographic ────────────
RUN echo 'ttyS0::respawn:/sbin/agetty -L 115200 ttyS0 xterm-256color' \
>> /etc/inittab
# ── Hostname (hosts managed by init/dhcpcd at boot) ────────
RUN echo 'ansible-node' > /etc/hostname
# ── SSH: allow root + ansible user ────────────────────────
RUN ssh-keygen -A && \
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' \
/etc/ssh/sshd_config && \
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' \
/etc/ssh/sshd_config && \
echo 'UseDNS no' >> /etc/ssh/sshd_config
# ── Users ─────────────────────────────────────────────────
# Root password (change on first boot!)
RUN echo 'root:ansible' | chpasswd
# Ansible service user
RUN adduser -D ansible && \
echo 'ansible:ansible' | chpasswd && \
addgroup ansible wheel && \
echo '%wheel ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
# ── Docker: enable ansible user to run docker ─────────────
RUN addgroup ansible docker
# ── Working directory ─────────────────────────────────────
RUN mkdir -p /ansible/playbooks /ansible/inventory && \
chown -R ansible:ansible /ansible
# ── Ansible config ────────────────────────────────────────
RUN mkdir -p /etc/ansible && \
printf '[defaults]\n\
host_key_checking = False\n\
stdout_callback = yaml\n\
callback_whitelist = profile_tasks\n\
retry_files_enabled = False\n\
\n\
[ssh_connection]\n\
pipelining = True\n\
control_path = /tmp/ansible-%%h-%%p-%%r' \
> /etc/ansible/ansible.cfg
# ── Default inventory (placeholder) ───────────────────────
RUN printf '[windows]\n\
# win-host.example.com\n\
\n\
[cisco_asa]\n\
# asa-firewall.example.com\n\
\n\
[cisco_ios]\n\
# catalyst-switch.example.com\n\
\n\
[cisco_nxos]\n\
# nexus-switch.example.com\n\
\n\
[vmware]\n\
# vcenter.example.com\n\
\n\
[mssql]\n\
# sql-server.example.com\n\
\n\
[linux]\n\
# debian-host.example.com\n\
\n\
[all:vars]\n\
ansible_user=ansible\n' \
> /etc/ansible/hosts
# ── MOTD (friendly boot message) ──────────────────────────
RUN printf '\n\
\e[1;32m╔════════════════════════════════════════════════╗\e[0m\n\
\e[1;32m║ Ansible Control Node — Alpine Linux ║\e[0m\n\
\e[1;32m╠════════════════════════════════════════════════╣\e[0m\n\
\e[1;32m║ Windows • Cisco • VMware • MSSQL • Linux ║\e[0m\n\
\e[1;32m╠════════════════════════════════════════════════╣\e[0m\n\
\e[1;32m║ SSH: ssh ansible@<ip> -p 22 ║\e[0m\n\
\e[1;32m║ Dir: /ansible ║\e[0m\n\
\e[1;32m╚════════════════════════════════════════════════╝\e[0m\n\
' > /etc/motd
# ── First-boot: expand rootfs to fill disk, gen SSH keys ─
RUN printf '#!/bin/sh\n\
# Expand root filesystem to fill the underlying disk\n\
ROOTDEV=$(findmnt -n -o SOURCE / 2>/dev/null || echo /dev/vda)\n\
resize2fs "$ROOTDEV" 2>/dev/null || true\n\
# Re-generate SSH host keys if running from a cloned image\n\
if [ ! -f /etc/ssh/.host-keys-generated ]; then\n\
ssh-keygen -A && touch /etc/ssh/.host-keys-generated\n\
fi\n' \
> /etc/local.d/00-first-boot.start && \
chmod +x /etc/local.d/00-first-boot.start && \
rc-update add local default
WORKDIR /ansible
CMD ["/sbin/init"]