Skip to content

Git Integration and CI/CD for Devbox/Ansible Projects

After setting up your development environment with Devbox and configuring Ansible, the next steps involve integrating your project with Git for version control and setting up a basic CI/CD workflow.

Setting Up Git Integration

Version control is essential for any infrastructure-as-code project.

  1. Initialize a Git Repository: If you haven't already, initialize Git in your project directory:

    # Ensure you are in your project root (e.g., ansible-devenv)
    git init
    

  2. Create a .gitignore File: This file tells Git which files and directories to ignore. It's crucial to exclude sensitive files (like vault passwords) and temporary files generated by tools. Create a .gitignore file in the project root:

    # Devbox / Nix related
    .devbox/
    .direnv/
    result*
    
    # Python virtual environment
    .venv/
    __pycache__/
    *.py[cod]
    *$py.class
    
    # Ansible Vault passwords - CRITICAL
    .vault_pass*
    
    # Ansible temporary files
    *.retry
    
    # Molecule (if used for testing)
    .molecule/
    .cache/
    
    # Common Editor/OS files
    .vscode/
    .idea/
    *.swp
    *~
    .DS_Store
    
    Customize this based on the tools and operating systems used by your team.

  3. Make Your First Commit: Add your project files and commit them.

    git add .
    git commit -m "Initial setup of Ansible project with Devbox environment"
    
    Remember to connect this local repository to a remote repository (like GitHub, GitLab, etc.) to collaborate and back up your code.

Sharing Your Environment with Your Team

One of the major benefits of Devbox is how easily it allows sharing the development environment. Your teammates simply need to:

  1. Install Devbox on their systems.
  2. Clone your Git repository.
  3. Navigate into the cloned project directory in their terminal.
  4. Run devbox shell.

Devbox will automatically read the devbox.json file, install the exact package versions specified, and run the init_hook (e.g., setting up the Python virtual environment and installing requirements.txt). This ensures everyone has an identical and isolated development setup.

Handy Aliases for Productivity

To streamline common commands, you can add aliases. These can be added to your personal shell configuration (.bashrc, .zshrc, etc.) or, more portably, to the init_hook within your devbox.json so they are available whenever someone enters the devbox shell.

Example aliases for the devbox.json init_hook:

    // Inside devbox.json shell.init_hook array:
    "alias avault='ansible-vault'",
    "alias aplay='ansible-playbook'",
    "alias alint='ansible-lint'",
    "echo 'Ansible aliases (avault, aplay, alint) are set.'"
Modify the init_hook in devbox.json and run devbox shell again to apply.

Troubleshooting Common Issues

Integration with CI/CD

Using your Devbox-managed environment in a CI/CD pipeline (like GitLab CI, GitHub Actions) requires installing Devbox and running your commands within its context. A common pattern is to use the Python virtual environment created by the init_hook.

Example ci.sh script (adapt for your specific CI/CD platform):

#!/bin/bash
set -e # Exit immediately if a command exits with a non-zero status.

echo "--- Setting up Environment ---"
# Assuming Devbox is installed on the CI runner
# Activate the environment and install dependencies (init_hook should handle this)
# We source the venv directly for explicitness in CI
if [ ! -d .venv ]; then
  echo "Virtual environment not found. Running init_hook via devbox shell..."
  # This is slower but ensures init_hook runs fully
  devbox shell -- 'echo "Environment initialized."'
fi

echo "Activating virtual environment..."
source .venv/bin/activate

echo "--- Linting ---"
ansible-lint playbooks/*.yml # Lint playbooks

echo "--- Syntax Check ---"
# Check syntax of a specific playbook (e.g., deploy.yml)
ansible-playbook playbooks/deploy.yml --syntax-check

# Example: Only run deployment on the main branch
if [ "$CI_COMMIT_BRANCH" = "main" ]; then
  echo "--- Deploying (Main Branch) ---"
  # Securely provide the vault password (e.g., via CI/CD secrets)
  if [ -z "$VAULT_PASSWORD" ]; then
    echo "Error: VAULT_PASSWORD environment variable not set."
    exit 1
  fi
  echo "$VAULT_PASSWORD" > .vault_pass.txt
  chmod 600 .vault_pass.txt

  # Run the actual deployment playbook
  ansible-playbook playbooks/deploy.yml

  # Clean up the password file immediately
  rm .vault_pass.txt
  echo "Deployment playbook executed."
else
  echo "Skipping deployment for non-main branch ($CI_COMMIT_BRANCH)."
fi

echo "--- CI Check Complete ---"

Key considerations for CI/CD:

  • Devbox Installation: Ensure Devbox is installed on your CI runners.
  • Caching: Cache the Nix store (/nix/store) and potentially the .venv directory (though recreating .venv is often safer) to speed up builds.
  • Secrets Management: Use your CI/CD platform's secrets management to securely provide the VAULT_PASSWORD. Never hardcode it.
  • Non-interactive: Ensure your scripts run non-interactively.