A project for building and managing golden (pre-configured) operating system images using Packer and Ansible, with automated deployment to Azure.
This project automates the creation of golden Ubuntu images with hardened security configurations and monitoring setup. The built images are stored as Azure Managed Images in your resource group.
├── ansible/ # Ansible playbooks and roles for image provisioning
│ ├── playbooks/ # Main playbooks
│ │ └── configure.yml # Image configuration playbook
│ └── roles/ # Reusable Ansible roles
│ ├── base/ # Base OS configuration
│ ├── hardening/ # Security hardening
│ └── monitoring/ # Monitoring setup
├── packer/ # Packer configurations
│ └── ubuntu/ # Ubuntu image builder
│ ├── ubuntu.pkr.hcl # Main Packer configuration
│ ├── variables.pkr.hcl # Packer variables
│ └── version.json # Version information
├── scripts/ # Utility scripts
│ ├── generate-metadata.sh # Generate image metadata
│ └── validate.sh # Validation scripts
└── .github/workflows/ # CI/CD pipelines
└── build-image.yml # Automated build workflow
- Packer >= 1.8.0
- Ansible >= 2.9
- Azure CLI for authentication and image management
- Azure Subscription with appropriate permissions
- GitHub Secrets configured (see Configuration section)
Set the following secret in your GitHub repository:
AZURE_CREDENTIALS- Azure service principal credentials (JSON format)
To build the image locally:
cd packer/ubuntu
packer build -var-file="variables.pkr.hcl" ubuntu.pkr.hclPush to the main branch to trigger the automated build workflow:
git push origin mainThe workflow will:
- Check out the code
- Authenticate with Azure
- Build the golden image with Packer
- Run Ansible provisioning (base, hardening, monitoring)
- Upload the image to Azure Storage (if configured)
- base: Installs and configures base OS components
- hardening: Applies security hardening policies (SSH configuration, firewall, etc.)
- monitoring: Sets up monitoring agents and logging
Customize these roles by editing the corresponding tasks/main.yml and defaults/main.yml files.
Edit packer/ubuntu/variables.pkr.hcl to customize:
image_name- Base image namelocation- Azure regionresource_group- Target resource groupimage_sku- Ubuntu version
packer build packer/ubuntubash scripts/validate.shbash scripts/generate-metadata.sh- Azure Managed Image: Stored in the specified resource group, named with format:
{image_name}-golden-{date} - Azure Storage (optional): VHD file uploaded with timestamp for archival and sharing
The GitHub Actions workflow automates the entire process:
-
Triggers on push to
mainbranch -
Builds image with Packer
-
Provisions with Ansible
-
Uploads to storage (optional)
-
Packer Build Fails: Check Azure credentials and ensure the service principal has necessary permissions
-
Ansible Provisioning Fails: Verify Ansible syntax with
ansible-playbook --syntax-check -
Upload Fails: Ensure storage account name and container name are correctly set in GitHub secrets
- Create a feature branch:
git checkout -b feature/your-feature - Make changes and test locally
- Push and create a pull request
- Merge to
mainto trigger the build pipeline