Skip to content

Commit 23be419

Browse files
authored
Publish Azure SIG images via GitHub Action (#1944)
* Publish Azure VHDs via GitHub Action * Remove obsolete Azure ADO build pipeline * Make REPLICATED_REGIONS an overridable input variable * Extract duplicate sed commands into a composite action * Quote var references in command statements * Check for Windows kube-proxy image via HEAD request
1 parent 2ff67f1 commit 23be419

10 files changed

Lines changed: 817 additions & 519 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Configure Kubernetes version
2+
description: Update kubernetes.json with the specified Kubernetes version
3+
4+
inputs:
5+
kubernetes_version:
6+
description: 'Kubernetes version (e.g., 1.31.1)'
7+
required: true
8+
9+
runs:
10+
using: composite
11+
steps:
12+
- name: Configure Kubernetes version
13+
working-directory: images/capi/packer/config
14+
shell: bash
15+
env:
16+
KUBERNETES_VERSION: ${{ inputs.kubernetes_version }}
17+
run: |
18+
set -euo pipefail
19+
KUBERNETES_RELEASE=$(echo "${KUBERNETES_VERSION}" | cut -d "." -f -2)
20+
sed -i "s/^ \"kubernetes_series\".*/ \"kubernetes_series\": \"v${KUBERNETES_RELEASE}\",/g" kubernetes.json
21+
sed -i "s/^ \"kubernetes_semver\".*/ \"kubernetes_semver\": \"v${KUBERNETES_VERSION}\",/g" kubernetes.json
22+
sed -i "s/^ \"kubernetes_rpm_version\".*/ \"kubernetes_rpm_version\": \"${KUBERNETES_VERSION}\",/g" kubernetes.json
23+
sed -i "s/^ \"kubernetes_deb_version\".*/ \"kubernetes_deb_version\": \"${KUBERNETES_VERSION}-1.1\",/g" kubernetes.json
24+
grep -q "v${KUBERNETES_VERSION}" kubernetes.json || { echo 'ERROR: kubernetes version not set in kubernetes.json'; exit 1; }
25+
cat kubernetes.json

.github/workflows/README.md

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# Azure SIG Image Builder - GitHub Actions Workflows
2+
3+
This directory contains GitHub Actions workflows for building and publishing Azure Shared Image Gallery (SIG) images using the image-builder project. These workflows are the GitHub Actions equivalent of the Azure DevOps pipelines in `images/capi/packer/azure/.pipelines/`.
4+
5+
## Workflow Overview
6+
7+
The entire pipeline is defined in a single workflow file, `build-azure-sig.yaml`, which contains all stages as separate jobs:
8+
9+
## Pipeline Stages
10+
11+
```
12+
┌─────────┐ ┌──────────┐ ┌─────────────┐ ┌─────────┐
13+
│ Build │───▶│ Test │───▶│ Promote │───▶│ Clean │
14+
└─────────┘ └──────────┘ └─────────────┘ └─────────┘
15+
(optional) (requires approval) (if build succeeded)
16+
```
17+
18+
1. **Build**: Builds the Kubernetes node image using Packer and publishes it to a staging Azure Compute Gallery
19+
2. **Test**: (Optional) Creates a test CAPI cluster using the built image to validate it works correctly
20+
3. **Promote**: (Requires approval) Promotes the image from staging to the community gallery for public access
21+
4. **Clean**: Cleans up staging resources (managed image and staging gallery version) — only runs if the build succeeded
22+
23+
## Usage
24+
25+
### Triggering the Workflow
26+
27+
1. Go to the **Actions** tab in the GitHub repository
28+
2. Select **Build Azure SIG Image** from the workflows list
29+
3. Click **Run workflow**
30+
4. Fill in the required inputs:
31+
32+
| Input | Required | Description | Example |
33+
|-------|----------|-------------|---------|
34+
| `kubernetes_version` | Yes | Kubernetes version to build | `1.31.1` |
35+
| `os` | Yes | Operating system | `Ubuntu`, `AzureLinux`, or `Windows` |
36+
| `os_version` | Yes | OS version | `24.04`, `22.04`, `2022-containerd` |
37+
| `resource_group` | No | Azure resource group | `cluster-api-gallery` |
38+
| `staging_gallery_name` | No | Staging gallery name | `staging_gallery` |
39+
| `gallery_name` | No | Community gallery name | `community_gallery` |
40+
| `packer_flags` | No | Additional Packer flags | `--on-error=abort` |
41+
| `tags` | No | Custom tags for the image | `env=prod team=infra` |
42+
| `skip_test` | No | Skip the test stage | `true` (default) |
43+
| `skip_promote` | No | Skip the promote stage | `false` |
44+
45+
### Supported OS and Version Combinations
46+
47+
| OS | Versions |
48+
|----|----------|
49+
| Ubuntu | `22.04`, `24.04` |
50+
| AzureLinux | `3` |
51+
| Windows | `2022-containerd`, `2025-containerd` |
52+
53+
## Setup Requirements
54+
55+
### 1. Azure OIDC Authentication
56+
57+
Configure Azure OIDC (OpenID Connect) authentication for passwordless authentication from GitHub Actions:
58+
59+
1. Create an Azure AD application and service principal
60+
2. Configure federated credentials for the GitHub repository
61+
3. Grant the service principal necessary permissions on your Azure subscription
62+
63+
Add the following secrets to your GitHub repository or organization:
64+
65+
| Secret | Description |
66+
|--------|-------------|
67+
| `AZURE_CLIENT_ID` | Azure AD application (client) ID |
68+
| `AZURE_TENANT_ID` | Azure AD tenant ID |
69+
| `AZURE_SUBSCRIPTION_ID` | Azure subscription ID |
70+
71+
For detailed instructions, see: [Azure Login with OIDC](https://github.com/azure/login#login-with-openid-connect-oidc-recommended)
72+
73+
### 2. GitHub Environment for Approvals
74+
75+
Create a GitHub Environment for the promotion approval gate:
76+
77+
1. Go to **Settings****Environments**
78+
2. Create a new environment named `image-promotion-approval`
79+
3. Enable **Required reviewers** and add the appropriate team members
80+
4. Optionally configure deployment branches and wait timer
81+
82+
### 3. Repository/Organization Variables
83+
84+
Set the following variables in your repository or organization settings for the promotion stage:
85+
86+
| Variable | Description | Example |
87+
|----------|-------------|---------|
88+
| `EULA_LINK` | URL to the EULA for the image | `https://example.com/eula` |
89+
| `PUBLISHER_EMAIL` | Email for the image publisher | `team@example.com` |
90+
| `PUBLISHER_URI` | URI for the image publisher | `https://example.com` |
91+
| `SIG_PUBLISHER` | Publisher name for image definitions | `MyOrganization` |
92+
93+
### 4. Azure Resources
94+
95+
Ensure the following Azure resources are set up:
96+
97+
- **Resource Group**: A resource group for the compute galleries (default: `cluster-api-gallery`)
98+
- **Staging Gallery**: An Azure Compute Gallery for initial image publishing
99+
- **Community Gallery**: An Azure Compute Gallery with community permissions for public access
100+
101+
The workflows will create these resources if they don't exist, provided the service principal has sufficient permissions.
102+
103+
### Required Azure RBAC Permissions
104+
105+
The service principal needs the following permissions:
106+
107+
- `Contributor` on the resource group (or subscription)
108+
- `User Access Administrator` if creating new resource groups
109+
- For community galleries: permissions to create and manage Shared Image Galleries
110+
111+
## Artifacts
112+
113+
The workflows produce the following artifacts:
114+
115+
| Artifact | Description | Retention |
116+
|----------|-------------|-----------|
117+
| `publishing-info` | JSON file with image metadata from the build stage | 7 days |
118+
| `sig-publishing` | JSON file with community gallery publishing details | 30 days |
119+
120+
## Differences from Azure DevOps Pipelines
121+
122+
| Feature | Azure DevOps | GitHub Actions |
123+
|---------|--------------|----------------|
124+
| Authentication | Service Connection | Azure OIDC via `azure/login@v2` |
125+
| Approvals | ADO Environments | GitHub Environments |
126+
| Artifacts | Pipeline Artifacts | GitHub Actions Artifacts |
127+
| Variables | Pipeline Variables | Workflow Inputs + Repository Variables |
128+
| Templates | YAML Templates | Jobs within a single workflow |
129+
130+
## Troubleshooting
131+
132+
### Common Issues
133+
134+
1. **Authentication failures**
135+
- Verify OIDC credentials are correctly configured
136+
- Check that the federated credential matches the repository and branch
137+
138+
2. **Permission denied errors**
139+
- Ensure the service principal has sufficient Azure RBAC permissions
140+
- Verify the subscription ID is correct
141+
142+
3. **Packer build failures**
143+
- Check the Packer output in the build logs
144+
- Verify the OS/version combination is supported
145+
- Ensure the Kubernetes version exists
146+
147+
4. **Test stage failures**
148+
- The test stage requires the Azure CAPI CLI extension
149+
- Ensure sufficient quota for VMs in the target region
150+
151+
### Debug Mode
152+
153+
To enable debug output, add `--on-error=abort` to the `packer_flags` input to preserve the Packer VM on failure for investigation.
154+
155+
> **Warning:** Do **not** use `--on-error=ask` — it will cause the workflow to hang indefinitely waiting for interactive input, consuming the entire job timeout.
156+
157+
For more verbose logging, you can enable GitHub Actions debug logging by setting the `ACTIONS_STEP_DEBUG` secret to `true`.
158+
159+
## Related Documentation
160+
161+
- [Image Builder Documentation](../../docs/book/src/capi/capi.md)
162+
- [Azure Provider Documentation](../../images/capi/packer/azure/README.md)
163+
- [Azure DevOps Pipelines](../../images/capi/packer/azure/.pipelines/)
164+
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
165+
- [Azure Login Action](https://github.com/azure/login)

0 commit comments

Comments
 (0)