on
Automating Kubernetes deployments with GitHub Actions and Argo Rollouts
Continuous deployment to Kubernetes is safer when you reduce blast radius and let the system verify a release before promoting it to everyone. A practical, modern pattern is to use GitHub Actions to build and publish images, then drive a progressive delivery controller — like Argo Rollouts — to perform canary or blue/green releases with automated analysis and rollback. This article walks through the core ideas and a compact workflow you can adopt.
Why use Argo Rollouts with GitHub Actions?
- GitHub Actions handles the CI piece: build, test, sign, and publish container images (and update manifests).
- Argo Rollouts runs inside Kubernetes and provides progressive delivery primitives (canary/blue-green), traffic shifting, and metric-driven analysis that can automatically promote or rollback a release.
- Combined, they let you keep Git as the source of truth for desired state and run safe, observable releases in production.
Argo Rollouts provides first-class support for canary updates, traffic weighting, and analysis templates that query observability backends (e.g., Prometheus) to decide success/failure during a rollout. (argoproj.github.io)
High-level workflow
- Developer opens PR → GitHub Actions CI runs tests.
- On merge, Actions builds and pushes a container image (prefer OIDC-based auth instead of long-lived secrets). (docs.github.com)
- Actions updates the image tag in the Kubernetes manifests repository (or a manifests directory) and pushes the change.
- Argo Rollouts (or ArgoCD if you prefer GitOps) notices the manifest change in the repo and applies the new Rollout resource. Argo then performs a canary: gradually shifts traffic, runs analysis checks, and either promotes to 100% or rolls back automatically if metrics fail. (argoproj.github.io)
Minimal GitHub Actions example
This condensed job shows the essential steps: build, authenticate (via OIDC where supported), push, and update manifests. Replace placeholders with your repo/registry details.
name: release
on:
push:
branches: [ main ]
jobs:
build-and-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set image tag
run: echo "IMAGE_TAG=sha-${GITHUB_SHA::8}" >> $GITHUB_ENV
- name: Authenticate to registry (example: Google Artifact Registry)
uses: google-github-actions/auth@v1
with:
workload_identity_provider: projects/123/locations/global/workloadIdentityPools/my-pool/providers/my-provider
service_account: my-sa@project.iam.gserviceaccount.com
- name: Build and push image
run: |
docker build -t us-central1-docker.pkg.dev/myproj/myrepo/myapp:${IMAGE_TAG} .
docker push us-central1-docker.pkg.dev/myproj/myrepo/myapp:${IMAGE_TAG}
- name: Update manifests (simple sed)
run: |
git config user.name "github-actions"
git config user.email "actions@github.com"
sed -i "s|image: .*|image: us-central1-docker.pkg.dev/myproj/myrepo/myapp:${IMAGE_TAG}|" k8s/myapp/rollout.yaml
git add k8s/myapp/rollout.yaml
git commit -m "release: ${IMAGE_TAG}" || echo "no changes"
git push
Notes:
- Use short-lived federated credentials/OIDC where possible — it avoids storing long-lived secrets in the repo. GitHub Actions supports OIDC federation to cloud providers (example: GCP). (docs.github.com)
- If you use a dedicated manifests repo for GitOps, your Action can push there instead of the same repo.
Example Argo Rollout (canary with analysis)
Below is a focused Rollout spec sketch that uses a canary strategy and an analysis step which queries Prometheus to ensure success rate stays high.
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
name: myapp
spec:
replicas: 5
strategy:
canary:
steps:
- setWeight: 10
- pause: {duration: 120s}
- analysis:
templates:
- name: success-rate
templateName: success-rate
- setWeight: 50
- pause: {duration: 120s}
- setWeight: 100
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: us-central1-docker.pkg.dev/myproj/myrepo/myapp:sha-xxxx
Argo Rollouts’ analysis templates can call Prometheus and other metric providers to determine whether a step is healthy, and they drive automatic promotion or rollback. (argoproj.github.io)
Practical tips and considerations
- Observability: Ensure key user-facing metrics (success rate, latency, error budget) are available in Prometheus or another supported backend. Analysis is only as good as the metrics. (argoproj.github.io)
- Traffic management: If you’re not using a service mesh, Argo Rollouts supports a number of ingress/Service configurations for traffic shifting; validate integration with your ingress controller. (argoproj.github.io)
- GitOps vs CI-driven apply: You can have Actions push manifest changes and let ArgoCD/Argo Rollouts pull them (recommended GitOps pattern), or let Actions run kubectl apply directly. Using a GitOps controller centralizes drift detection and auditability. (argoproj.github.io)
- Cloud auth: Prefer OIDC/workload identity to avoid long-lived cloud credentials in your runners; GitHub provides documentation and examples for configuring this with cloud providers. (docs.github.com)
Conclusion
Using GitHub Actions together with Argo Rollouts gives you a clean separation: Actions handles build and manifest updates while Argo Rollouts executes the delivery plan inside the cluster with traffic shifting and metric-driven safeguards. The pattern reduces risk, increases automation, and keeps release decisions visible and auditable. For teams running Kubernetes in cloud providers, combine OIDC-based authentication for secure registry access and cluster operations, and build analysis hooks into Prometheus to make rollouts truly automatic and safe. (docs.github.com)