GitHub Actions Tutorial — Deploy to Kubernetes

1 minute read

Deploy to Kubernetes

GitHub Actions can deploy to any Kubernetes cluster — EKS, GKE, AKS, or self-managed. The pattern is always: authenticate → set context → apply manifests (or run Helm).


kubectl Apply

With kubeconfig Secret


name: Deploy to Kubernetes

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4

      - name: Set kubeconfig
        run: |
          mkdir -p $HOME/.kube
          echo "${{ secrets.KUBECONFIG }}" | base64 -d > $HOME/.kube/config

      - name: Deploy
        run: |
          kubectl apply -f k8s/
          kubectl rollout status deployment/my-app -n default --timeout=300s

With EKS


steps:
  - uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
      aws-region: us-east-1

  - name: Update kubeconfig
    run: aws eks update-kubeconfig --name my-cluster --region us-east-1

  - run: kubectl apply -f k8s/

With AKS


steps:
  - uses: azure/login@v2
    with:
      client-id: ${{ secrets.AZURE_CLIENT_ID }}
      tenant-id: ${{ secrets.AZURE_TENANT_ID }}
      subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

  - uses: azure/aks-set-context@v4
    with:
      resource-group: my-rg
      cluster-name: my-cluster

  - run: kubectl apply -f k8s/


Helm Deployments


name: Helm Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4

      - name: Set kubeconfig
        run: |
          mkdir -p $HOME/.kube
          echo "${{ secrets.KUBECONFIG }}" | base64 -d > $HOME/.kube/config

      - name: Helm upgrade
        run: |
          helm upgrade --install my-app ./charts/my-app \
            --namespace production \
            --set image.tag=${{ github.sha }} \
            --set replicas=3 \
            --wait --timeout 5m


Kustomize


steps:
  - uses: actions/checkout@v4

  - name: Set image tag
    run: |
      cd k8s/overlays/production
      kustomize edit set image my-app=my-registry/my-app:${{ github.sha }}

  - name: Apply
    run: kubectl apply -k k8s/overlays/production


Rolling Update Pattern


steps:
  - name: Deploy
    run: |
      kubectl set image deployment/my-app \
        my-app=my-registry/my-app:${{ github.sha }} \
        -n production

  - name: Wait for rollout
    run: |
      kubectl rollout status deployment/my-app \
        -n production --timeout=300s

  - name: Verify
    run: |
      kubectl get pods -n production -l app=my-app


Common Mistakes

Mistake Fix
KUBECONFIG secret not base64 Encode: cat kubeconfig \| base64 -w0
Rollout timeout Increase --timeout or check pod events
Wrong namespace Always specify -n namespace in kubectl commands
Helm values not updated Use --set image.tag= to pass the commit SHA

Quick Reference

Tool Command
kubectl kubectl apply -f k8s/
Helm helm upgrade --install ... --wait
Kustomize kubectl apply -k overlays/prod
EKS auth aws eks update-kubeconfig
AKS auth azure/aks-set-context@v4
Rollout check kubectl rollout status deployment/...

← Previous: Deploy to Azure

Next: Deploy Docker Images →

Updated: