7.9 KiB
| project | type | status | path | tags | created | updated | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| ansible-container-deploy | project-plan | active | Tech/Projects |
|
2026-04-25 | 2026-04-25 |
Ansible Container Deploy
Tag-based per-container Ansible deployment, CLI wizard enhancements, and GitHub clone integration for the PBS Docker stack.
Background
The wordpress-install repo (pbs-production/) has been refactored from a
loop-based all-or-nothing Docker deployment to a tag-based import_tasks
pattern. Each container has its own task wrapper under tasks/containers/
that calls common/deploy.yml with container-specific variables. The
docker-container repo (pbs-workshop/) houses a CLI wizard that scaffolds
new container files (compose template, task wrapper, env template) but
currently only generates simple-tier containers.
The tag-based refactor is coded but untested. The wizard needs enhancements to support medium and complex tier containers. A separate GitHub deploy refactor (github-deploy-refactor, status: complete) established the pbsdeploybot machine user pattern for repo cloning — that logic needs to be absorbed into the dockers role.
Repos
- wordpress-install (pbs-production/) — production deployment repo, tag-based structure in place
- docker-container (pbs-workshop/) — tooling repo, CLI wizard and scaffolding
- claude-code-scaffolding-skill — separate project, consumes the patterns defined here (see Phase 5)
Architecture
common/deploy.yml Variable Contract
Required:
container_name(str) — directory name underfiles/and deploy path at{{ dockers_path }}//
Optional:
container_has_env(bool, default false) — templatesfiles//.env.j2→.envcontainer_extra_dirs(list of str) — additional directories to createcontainer_extra_files(list of {src, dest, mode}) — static files to copycontainer_extra_templates(list of {src, dest, mode}) — Jinja templates to render
Global vars (from vars/main.yml and inventory):
dockers_path— base directory (/opt/docker)user— system user for file ownershipdockers_lan_name— Docker network namedockers_domain_name— primary domain
Container Complexity Tiers
Simple (redis, portainer, uptime-kuma): container_name only
Medium (pbs-api): adds container_extra_dirs, container_extra_files,
container_extra_templates
Complex (wordpress): medium plus post-deploy tasks
common/github.yml (planned)
Will sit alongside common/deploy.yml. Containers that build from a cloned
repo import github.yml first (clone/pull via pbsdeploybot), then
deploy.yml (compose up). Uses the same SSH host alias pattern established
in github-deploy-refactor.
Phases
Phase 1: Validate Tag-Based Deployment
Test the existing tag-based refactor on staging.
- Run
--tags traefikagainst staging, verify only traefik deploys - Run
--tags wordpressagainst staging, verify only wordpress deploys - Run
--tags "traefik,wordpress"to verify multi-tag targeting - Run
--skip-tags n8nto verify exclusion works - Run full playbook (no tags) to verify all-container deployment still works
- Document any issues or adjustments needed
Phase 2: Absorb GitHub Clone Logic
Migrate the github role's clone logic into the dockers role as
common/github.yml.
- Create
tasks/common/github.ymlin the dockers role - Accept per-invocation vars:
repo_url,repo_dest,repo_version - Use
become_user: "{{ ansible_user }}"for SSH config access - Default
repo_versiontomain - Update container task wrappers that need repo clones (e.g., pbs-hub)
to import
github.ymlbeforedeploy.yml - Test on staging with an existing repo-based container
- Decide whether standalone github role is kept for non-container use cases or retired entirely
Phase 3: Wizard Enhancements
Extend the CLI wizard to support medium-tier containers and repo-based builds.
3a: Dockerfile Support
- Add wizard prompt: "Does this container need a custom Dockerfile?"
- If yes, generate a Dockerfile template in the container's files directory
- Add Dockerfile to
container_extra_filesin the generated task wrapper
3b: Git Repo Support
- Add wizard prompt: "Is this container built from a git repo?"
- If yes, prompt for
repo_urlandrepo_version - Generate task wrapper that imports
common/github.ymlbeforecommon/deploy.yml
3c: Extra Files/Dirs/Templates
- Add wizard prompts for additional directories, static files, and templates
- Generate
container_extra_dirs,container_extra_files,container_extra_templatesentries in the task wrapper
3d: Vault Secret References
- When the wizard detects vars that need secrets (db passwords, API
keys, etc.), generate placeholder references in compose templates using
{{ vault_ }}syntax - Output a post-scaffold checklist reminding the user which vault vars need to be manually added to encrypted group vars
3e: Repo-Context Awareness
- When the wizard is run inside the production repo, it should read
existing
vars/main.yml, network configs, and Traefik patterns to inform prompts and output - Wizard should auto-detect available networks, domain name, and base path from existing config
- Wizard should append generated vars entries to
vars/main.yml(or output them for manual paste) - Implementation details deferred to Claude Code — requirement is stated, approach is flexible
Phase 4: Production Rollout
- Deploy tag-based structure to production (after staging validation)
- Test selective deployment on production with a low-risk container
- Update any runbooks or deployment docs
Phase 5: Scaffolding Skill Integration
Separate project (claude-code-scaffolding-skill), documented here for dependency tracking.
Three new scaffold types to add:
ansible-docker-container— scaffolds the project structure for a tag-based Docker container deployment (folder tree, template files, vars skeleton). The wizard then fills in the details.ansible-role— reusable Galaxy-style role (defaults, handlers, meta, tasks, templates, Molecule testing)ansible— full playbook project (ansible.cfg, inventory, group_vars, host_vars, playbooks, roles, requirements.yml, vault setup)
The scaffold creates project structure; the wizard populates container-specific content. Scaffold = one-time project start, wizard = repeated container additions.
This project provides the reference patterns. The scaffolding skill project owns implementation.
Decisions Made
- Wizard vs scaffold split: Scaffold generates project structure, wizard fills in container details. Different tools, same conventions.
- Vault secrets stay manual: Wizard generates
{{ vault_* }}placeholder references and a reminder checklist. Actual vault entries are hand-added. - Context-aware wizard implementation deferred to Claude Code: Requirement is that the wizard reads existing repo config when run in-place. How it does that is an implementation detail.
- Scaffolding skill: start inside existing skill, separate if it doesn't fit. Build assuming merge into claude-code-scaffolding-skill. If infrastructure types feel forced next to dev tooling types, split into standalone skill.
- common/github.yml pattern: Clone logic absorbed into dockers role, not kept as a standalone role for container use cases. Matches the common/deploy.yml pattern.
Dependencies
- github-deploy-refactor (complete) — provides pbsdeploybot auth pattern
- claude-code-scaffolding-skill (separate project) — consumes patterns from Phase 3+
Open Questions
- Should the standalone github role be kept for non-container clone use cases, or is pbsdeploybot + common/github.yml sufficient for everything?
- Final call on scaffolding skill merge vs standalone — deferred until implementation reveals fit
...sent from Jenny & Travis