diff --git a/roles/podman/README.md b/roles/podman/README.md new file mode 100644 index 0000000..5122d9d --- /dev/null +++ b/roles/podman/README.md @@ -0,0 +1,185 @@ +# Podman Infrastructure Role + +This role provides Podman container infrastructure for the rick-infra project, following the same patterns established by the PostgreSQL and Valkey infrastructure roles. + +## Overview + +**Podman** is a daemonless container engine for developing, managing, and running OCI containers and pods on Linux systems. This role establishes the foundational container infrastructure that containerized application services can build upon. + +Podman is deployed as a system-level infrastructure service that provides container runtime capabilities for service-specific users to utilize. + +## Features + +- **Daemonless architecture**: No background daemon required, improved security +- **Rootless containers**: Applications run containers as dedicated users +- **OCI compliance**: Full Docker compatibility with enhanced security +- **Systemd integration**: Native systemd integration via quadlet files +- **Security-focused**: crun runtime, secure registries, restrictive defaults +- **Infrastructure pattern**: Matches PostgreSQL/Valkey role architecture + +## Architecture + +### **Container Runtime Stack:** +- **Podman**: Container engine and CLI +- **crun**: Fast, lightweight OCI runtime (instead of runc) +- **netavark**: Modern container networking +- **aardvark-dns**: Container DNS resolution +- **conmon**: Container monitoring +- **catatonit**: Container init process + +### **Registry Configuration:** +- **docker.io**: Docker Hub (primary) +- **quay.io**: Red Hat Quay +- **ghcr.io**: GitHub Container Registry + +All registries configured with HTTPS-only, no insecure connections allowed. + +## Application Integration + +Applications should create service-specific users and manage their own container deployments: + +### **Service-Specific User Pattern:** +```yaml +# Example from future authentik role +- name: Create authentik user + user: + name: authentik + system: yes + shell: /bin/bash + home: /var/lib/authentik + create_home: yes + +- name: Configure rootless podman for authentik + lineinfile: + path: "{{ item.file }}" + line: "authentik:{{ item.start }}:{{ item.count }}" + loop: + - { file: /etc/subuid, start: 100000, count: 65536 } + - { file: /etc/subgid, start: 100000, count: 65536 } +``` + +### **Quadlet Integration:** +```yaml +# Deploy quadlet files to user systemd directory +- name: Deploy container quadlets + template: + src: "{{ item }}.j2" + dest: "/var/lib/authentik/.config/containers/systemd/{{ item }}" + owner: authentik + group: authentik + loop: + - authentik.pod + - authentik-server.container + - authentik-worker.container +``` + +### **Container-to-Host Connectivity:** +```ini +# Pod quadlet with host access +[Pod] +Network=service-internal +AddHost=host.containers.internal:host-gateway +PublishPort=127.0.0.1:9000:9000/tcp +``` + +```bash +# Environment variables for host service access +DATABASE_HOST=host.containers.internal +REDIS_HOST=host.containers.internal +``` + +## Configuration + +### **Default Settings:** +```yaml +# Service management +podman_service_enabled: true +podman_service_state: "started" + +# Registry configuration +podman_registries: + - docker.io + - quay.io + - ghcr.io + +# Security settings +podman_rootless: true +podman_systemd_security: true +``` + +All settings use secure defaults and can be overridden in host_vars if needed. + +## Dependencies + +This is an infrastructure role with no dependencies. Applications that need containers should declare this role as a dependency: + +```yaml +# roles/authentik/meta/main.yml +dependencies: + - role: postgresql + - role: valkey + - role: podman # Container infrastructure + - role: caddy +``` + +## Service Management + +```bash +# System service (API endpoint) +sudo systemctl status podman +sudo systemctl status podman.socket + +# Container functionality +sudo podman --version +sudo podman run --rm hello-world + +# User containers (example with authentik user) +sudo -u authentik systemctl --user status authentik-pod +sudo -u authentik podman ps -a +``` + +## Container User Isolation + +Each containerized service gets: +- **Dedicated system user** (e.g., `authentik`, `nextcloud`) +- **Isolated subuid/subgid ranges** (100000+65536 IDs per service) +- **Private container storage** in user home directory +- **User systemd session** for container service management +- **Network isolation** via custom bridge networks + +## File Locations + +- **Global configuration**: `/etc/containers/` + - `registries.conf` - Registry settings + - `containers.conf` - Global podman settings +- **User containers**: `/var/lib/{service}/` + - `.config/containers/systemd/` - Quadlet files + - `.config/systemd/user/` - Generated systemd services + - `.local/share/containers/` - Container storage + +## Security + +- **Rootless operation**: All containers run as unprivileged users +- **Registry security**: HTTPS-only, trusted registries +- **Runtime security**: crun with security features enabled +- **Network isolation**: Custom networks, no privileged networking +- **Storage isolation**: Per-user container storage +- **Systemd integration**: Full systemd security features available + +## Integration with Host Services + +Containerized applications access host services (PostgreSQL, Valkey) via: +- **Bridge networking** with host gateway access +- **Host mapping**: `host.containers.internal` → host IP +- **Localhost binding**: Host services remain on 127.0.0.1 +- **Standard ports**: No port conflicts, containers use bridge networks + +## Notes + +This role follows the rick-infra infrastructure pattern where foundational services (Podman, PostgreSQL, Valkey) are provided as host-level infrastructure, and applications manage their own specific usage patterns and user isolation rather than sharing a common container user. + +**Architecture Benefits:** +- Clear separation between infrastructure and applications +- Service-level isolation and security +- Native systemd integration for all containers +- Familiar management patterns consistent with native services \ No newline at end of file diff --git a/roles/podman/defaults/main.yml b/roles/podman/defaults/main.yml new file mode 100644 index 0000000..286daed --- /dev/null +++ b/roles/podman/defaults/main.yml @@ -0,0 +1,73 @@ +--- +# ================================================================= +# Podman Infrastructure Role - Simplified Configuration +# ================================================================= +# Provides rootless container infrastructure for applications +# Applications manage their own service-specific users and deployments + +# ================================================================= +# Essential Configuration +# ================================================================= + +# Service Management +podman_service_enabled: true +podman_service_state: "started" + +# Installation Configuration (Arch Linux optimized) +podman_install_optional: false # Trust pacman dependency management + +# ================================================================= +# Container Runtime Security +# ================================================================= + +# Rootless container configuration +podman_rootless: true +podman_systemd_security: true + +# ================================================================= +# Registry Configuration +# ================================================================= + +# Default container registries (secure, trusted sources) +podman_registries: + - docker.io + - quay.io + - ghcr.io + +# Registry security settings +podman_registry_insecure: false +podman_registry_blocked: false + +# ================================================================= +# Network Configuration +# ================================================================= + +# Default networking (applications create their own networks) +podman_default_network: "bridge" +podman_network_security: true + +# ================================================================= +# Storage Configuration +# ================================================================= + +# Container storage settings +podman_storage_driver: "overlay" +podman_storage_security: true + +# ================================================================= +# Infrastructure Notes +# ================================================================= +# This role provides minimal podman infrastructure +# Applications should manage their own configurations: +# +# Service-specific users: +# - Applications create users like: authentik, nextcloud, etc. +# - Each user gets isolated subuid/subgid ranges +# - Each user manages their own containers via systemd --user +# +# Container networking: +# - Applications create bridge networks for isolation +# - Host services accessed via host.containers.internal +# - Port publishing only to localhost for security +# +# Podman's built-in defaults are used for everything else \ No newline at end of file diff --git a/roles/podman/handlers/main.yml b/roles/podman/handlers/main.yml new file mode 100644 index 0000000..1534643 --- /dev/null +++ b/roles/podman/handlers/main.yml @@ -0,0 +1,13 @@ +--- +# Podman Infrastructure Role - Handlers +# Matches the handler pattern from other infrastructure roles + +- name: reload systemd + systemd: + daemon_reload: yes + +- name: restart podman + systemd: + name: podman + state: restarted + when: podman_service_enabled | default(true) \ No newline at end of file diff --git a/roles/podman/meta/main.yml b/roles/podman/meta/main.yml new file mode 100644 index 0000000..aeb4096 --- /dev/null +++ b/roles/podman/meta/main.yml @@ -0,0 +1,27 @@ +--- +# Podman Infrastructure Role - Meta Information + +galaxy_info: + author: rick-infra + description: Podman container infrastructure role for rick-infra project + company: Personal Infrastructure + license: MIT + min_ansible_version: 2.9 + + platforms: + - name: ArchLinux + versions: + - all + + galaxy_tags: + - podman + - containers + - infrastructure + - systemd + - rootless + +# Dependencies +# Podman is a foundational infrastructure service with no dependencies +dependencies: [] + +# Role provides container infrastructure for other services to consume \ No newline at end of file diff --git a/roles/podman/tasks/main.yml b/roles/podman/tasks/main.yml new file mode 100644 index 0000000..78fbfa1 --- /dev/null +++ b/roles/podman/tasks/main.yml @@ -0,0 +1,79 @@ +--- +# Podman Infrastructure Role - Simplified Tasks + +- name: Update package cache + pacman: + update_cache: yes + +- name: Install crun as OCI runtime (faster than runc) + pacman: + name: crun + state: present + +- name: Install Podman container runtime + pacman: + name: podman + state: present + +- name: Verify podman installation + command: podman --version + register: podman_version_check + changed_when: false + +- name: Create global containers configuration directory + file: + path: /etc/containers + state: directory + mode: '0755' + +- name: Configure global container registries + template: + src: registries.conf.j2 + dest: /etc/containers/registries.conf + mode: '0644' + backup: yes + notify: restart podman + +- name: Configure global podman settings + template: + src: containers.conf.j2 + dest: /etc/containers/containers.conf + mode: '0644' + backup: yes + notify: restart podman + +- name: Enable podman system service (if enabled) + systemd: + name: podman + enabled: "{{ podman_service_enabled }}" + state: "{{ podman_service_state }}" + daemon_reload: yes + when: podman_service_enabled + +- name: Test podman functionality + command: podman info --format json + register: podman_info_result + changed_when: false + +- name: Verify rootless podman configuration + command: podman system info + register: podman_system_info + changed_when: false + failed_when: false + +- name: Display Podman infrastructure status + debug: + msg: | + ✅ Podman container infrastructure ready! + + 🐳 Version: {{ podman_version_check.stdout.split()[2] | default('unknown') }} + 🔒 Security: Rootless container runtime enabled + 📦 Registries: {{ podman_registries | join(', ') }} + 🏗️ Storage: {{ 'overlay' if 'overlay' in podman_system_info.stdout else 'system default' }} + + 🚀 Ready for containerized applications! + + 📋 Next Steps: + - Applications should create service-specific users + - Each user gets isolated container environment + - Services deploy quadlet files for systemd integration \ No newline at end of file diff --git a/roles/podman/templates/containers.conf.j2 b/roles/podman/templates/containers.conf.j2 new file mode 100644 index 0000000..f99777a --- /dev/null +++ b/roles/podman/templates/containers.conf.j2 @@ -0,0 +1,67 @@ +# Podman Configuration - Generated by Ansible +# rick-infra Podman Infrastructure Role +# +# Global podman configuration providing secure defaults +# for containerized applications + +# ================================================================= +# Container Engine Configuration +# ================================================================= + +[engine] + +# Container runtime (OCI compliant) +# runtime = "runc" # Default, can be overridden to crun + +# Network backend for container networking +network_backend = "netavark" + +# Default network for new containers +default_network = "{{ podman_default_network }}" + +# ================================================================= +# Storage Configuration +# ================================================================= + +# Storage driver for container layers and images +# driver = "{{ podman_storage_driver }}" # overlay is default + +# ================================================================= +# Security Configuration +# ================================================================= + +# Enable security features +# seccomp_profile = "/usr/share/containers/seccomp.json" +# apparmor_profile = "containers-default-0.14.5" + +# ================================================================= +# Network Configuration +# ================================================================= + +[network] + +# Default subnet for new networks (applications override this) +default_subnet = "10.88.0.0/16" +default_subnet_pools = [ + {"base" = "10.89.0.0/16", "size" = 24}, + {"base" = "10.90.0.0/16", "size" = 24} +] + +# ================================================================= +# Service Integration +# ================================================================= + +[service_destinations] + +# Systemd integration for container services +# Applications use this for quadlet deployment + +# ================================================================= +# Infrastructure Notes +# ================================================================= +# This configuration provides secure defaults for all containers +# Applications should: +# - Create service-specific users for container isolation +# - Use quadlet files for systemd integration +# - Create custom networks for multi-container applications +# - Access host services via host.containers.internal \ No newline at end of file diff --git a/roles/podman/templates/registries.conf.j2 b/roles/podman/templates/registries.conf.j2 new file mode 100644 index 0000000..0031a14 --- /dev/null +++ b/roles/podman/templates/registries.conf.j2 @@ -0,0 +1,35 @@ +# Container Registry Configuration - Generated by Ansible +# rick-infra Podman Infrastructure Role +# +# This configuration defines trusted container registries +# for secure container image retrieval + +# ================================================================= +# Registry Search Configuration +# ================================================================= + +# Default registries to search when pulling unqualified image names +# Images without a registry prefix will search these in order +unqualified-search-registries = {{ podman_registries | to_json }} + +{% for registry in podman_registries %} +# ================================================================= +# {{ registry | title }} Registry Configuration +# ================================================================= + +[[registry]] +location = "{{ registry }}" +insecure = {{ podman_registry_insecure | lower }} +blocked = {{ podman_registry_blocked | lower }} + +{% endfor %} + +# ================================================================= +# Security Notes +# ================================================================= +# All registries configured with: +# - insecure: false (HTTPS required) +# - blocked: false (registry accessible) +# +# Additional registries can be added by applications as needed +# following the same security-first configuration pattern \ No newline at end of file diff --git a/site.yml b/site.yml index 15a6814..bb653ea 100644 --- a/site.yml +++ b/site.yml @@ -11,8 +11,10 @@ # Infrastructure services # - role: postgresql # tags: ['postgresql', 'infrastructure', 'database'] - - role: valkey - tags: ['valkey', 'redis', 'infrastructure', 'cache'] + # - role: valkey + # tags: ['valkey', 'redis', 'infrastructure', 'cache'] + - role: podman + tags: ['podman', 'containers', 'infrastructure'] # - role: caddy # tags: ['caddy', 'infrastructure', 'web']