Kubernetes Deployments with GitHub Actions¶
Overview¶
Sketch a GitHub Actions deploy job that applies a SHA-tagged image with kubectl or Helm, waits for rollout success, documents rollback, and draws a clear boundary between push Continuous Delivery (CD) and GitOps pull controllers.
Pipelines that push manifests need a secure path into the cluster. Prefer short-lived credentials — OpenID Connect (OIDC) to a cloud Identity and Access Management (IAM) role that can call the Kubernetes API, or a narrowly scoped kubeconfig stored as an environment secret — never a cluster-admin key in unprotected repository secrets. Progressive delivery and rollbacks sit on Deployments or Helm releases. GitOps (Flux / Argo CD) inverts the model: the cluster pulls desired state from Git; CI updates Git rather than talking to the API directly.
This is a core tutorial in Module 8 · Kubernetes Deployments of the REBASH Academy GitHub Actions for Cloud & DevOps Engineers series — written for Cloud, DevOps, Platform, and SRE engineers.
Prerequisites¶
Learning Objectives¶
By the end of this tutorial, you will be able to:
- Sketch a
kubectlor Helm deploy job with environment protection - Wait on
rollout status/ Helm hooks as validation - Outline rollback (Helm revision or prior image digest)
- Compare push CD with GitOps pull
- State when CI should stop applying to the cluster
Architecture¶
This topic’s control points and relationships are shown below.
Theory¶
What it is¶
Kubernetes deployment from GitHub Actions means a job updates cluster state after Module 7 builds and (ideally) scans an image. Typical tools:
| Mode | Who applies changes | Fit |
|---|---|---|
Push CD (kubectl / Helm) | Workflow job | Simple apps, controlled envs, demos |
| GitOps pull | Controller (Argo CD / Flux) | Multi-cluster, strong drift control |
| Hybrid | CI updates Git; controller syncs | Common enterprise pattern |
Authenticate with OIDC to Amazon Elastic Kubernetes Service (EKS), Azure Kubernetes Service (AKS), or Google Kubernetes Engine (GKE) (Module 10), or mount a short-lived kubeconfig. Deploy the same digest produced in the Docker pipeline — never latest.
Why it matters¶
Static kubeconfigs in CI are high-value secrets and hard to rotate. Environment protection and required reviewers shrink blast radius for production. Rollouts without validation leave pods CrashLooping while the job reports success. Confusing push CI with GitOps causes double-writes: Actions and Argo CD fight over the same Deployment and drift becomes chronic.
How it works¶
- Gate the workflow on
main(or a release tag) and a GitHub Environment (staging/production) with protection rules. - Authenticate to the cluster (OIDC +
aws eks update-kubeconfig,az aks get-credentials, or a secret kubeconfig). - Run
kubectl set image/kubectl apply -korhelm upgrade --installwith the Module 7 image tag (:<sha>or@sha256:…). - Validate:
kubectl rollout status --timeout=…or Helm wait; fail the job on timeout. Optional smoke checks against the Service or Ingress. - Rollback:
helm rollback <release> <revision>, or redeploy the last known-good digest; under GitOps, revert the Git commit and let the controller sync.
Keep production behind manual approval on the environment. Prefer GitOps when many clusters or strict drift detection matter more than push latency.
Key concepts and comparisons¶
| Pattern | Idea | Rollback |
|---|---|---|
| Rolling update | Default Deployment surge | Prior ReplicaSet / Helm revision |
| Canary | Partial traffic to new version | Shift weight back |
| Blue-green | Two stacks; cut over Service/Ingress | Point traffic at previous stack |
| GitOps | Desired state in Git | Revert commit |
Common pitfalls¶
- Cluster-admin credentials in unprotected repository secrets.
- Deploying
latestinstead of the SHA built in the same pipeline. - Declaring success without
rollout statusor health probes. - Both CI and Argo CD applying the same Deployment (duelling controllers).
- Skipping
helm historyso rollback targets are unclear.
Hands-on Lab¶
Create a workspace for this tutorial.
mkdir -p ~/rebash-github-actions/module-08/{.github/workflows,manifests} && cd ~/rebash-github-actions/module-08/{.github/workflows,manifests}
Focus: kubectl dry-run deploy workflow with environment protection
Step 1 – Manifests + deploy workflow¶
mkdir -p .github/workflows manifests
cat > manifests/deploy.yaml << 'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: demo
namespace: rebash-lab
data:
note: github-actions-k8s-lab
EOF
cat > .github/workflows/k8s.yml << 'EOF'
name: Kubernetes deploy shape
on: [workflow_dispatch]
permissions:
contents: read
id-token: write
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Client dry-run when kubectl exists
run: |
if command -v kubectl >/dev/null; then
kubectl apply --dry-run=client -f manifests/
else
test -f manifests/deploy.yaml
fi
deploy_staging:
needs: validate
runs-on: ubuntu-latest
environment: staging
steps:
- uses: actions/checkout@v4
- run: echo "Wire cloud OIDC + kubectl apply for a real cluster"
EOF
Step 2 – Validate manifests file¶
Final step – Cleanup note¶
Validation¶
- Lab commands run under
~/rebash-github-actions/module-08/{.github/workflows,manifests}/ - You can explain each Theory section in your own words
- You used modern tooling where it applies to this topic
- You can describe one production failure mode for this topic
Code Walkthrough¶
Production practice for Kubernetes Deployments with GitHub Actions always combines:
- Inspect before you change (status, plan, logs, dry-run)
- Prefer reversible, documented changes (Git, IaC, drop-ins, version pins)
- Capture evidence (command output, pipeline logs) for handovers
- Prefer current tools and APIs over legacy shortcuts
- Least privilege — escalate credentials only when required
Keep runbooks short enough to follow under pressure. Automate checks; keep humans for judgement.
Security Considerations¶
- Treat credentials and tokens for github-actions as privileged — never commit them
- Prefer short-lived auth (OIDC, roles, SSO) over long-lived keys
- Validate blast radius before apply/deploy/delete operations
- Restrict who can approve production changes
- Collect audit logs; limit who can read sensitive traces
Common Mistakes¶
Cluster-admin credentials in unprotected repository secrets.
Validate assumptions against the Theory section and official docs before changing production.
Deploying latest instead of the SHA built in the same pipeline.
Lab shortcuts (open security groups, admin roles, skip approvals) must not ship unchanged.
Changing production without a rollback path
Always know how to revert (previous artefact, prior release, state rollback, DNS failback).
Best Practices¶
- Encode Kubernetes Deployments with GitHub Actions changes as code and review them in pull requests
- Pin versions (images, modules, actions, provider plugins)
- Separate environments with clear promotion gates
- Alert on symptoms with runbooks attached
- Destroy lab resources; tag everything with owner and expiry where possible
Troubleshooting¶
| Symptom | Likely cause | Fix |
|---|---|---|
| Auth / permission denied | Wrong identity, policy, or scope | Check caller identity, roles, and least-privilege policies |
| Timeout / no route | Network, DNS, security group, or endpoint | Trace path, DNS, and allow-lists before retrying |
| Drift / unexpected plan | Manual change or wrong state/workspace | Reconcile desired vs actual; avoid click-ops on managed resources |
| Pipeline/job red | Flaky step, cache, or missing secret | Read failing step logs; bisect recent workflow/config changes |
| Cost spike | Idle load balancer, NAT, oversized compute | Inventory billable resources; stop/delete labs promptly |
Summary¶
Kubernetes Deployments with GitHub Actions is essential for Cloud and DevOps engineers working with github-actions. Practise the lab until the inspection and change path is muscle memory, then continue the track.
Interview Questions¶
- How do you authenticate kubectl from GitHub Actions safely?
- Why dry-run before apply in CI?
- What role should a deploy job have in-cluster?
- How do GitHub environments help Kubernetes promotions?
- How do you roll back a bad deploy triggered by Actions?
Sample answer — question 2
Validate kubeconfig/OIDC exchange, namespace context, and client dry-run results before blaming the cluster.
Sample answer — question 4
Prefer short-lived credentials via OIDC, namespace-scoped Roles, and environment reviewers for production.