GitOps Workflow with ArgoCD and GitHub Actions

In this article we are going to cover How to Create GitOps Workflow with ArgoCD and GitHub Actions.

Prerequisites:

  • AWS Account(Ubuntu EC2 configured)
  • Install Git
  • Install Docker
  • Install Minikube
  • Install kubectl
  • Install Helm
  • Install ArgoCD

Step #1:Install ArgoCD on Minikube

Follow these steps to install Argo CD

We are using driver as docker

minikube start --driver=docker

Just like other Kubernetes tools, ArgoCD requires a namespace with its name. Therefore, we will create a namespace for argocd.

kubectl create ns argocd

ArgoCD can be installed using its manifests. First, you’ll need to download these manifests and apply them to your Minikube cluster.

kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Step #2:Install Helm on Minikube

Helm simplifies deploying and managing applications on Kubernetes. Let’s configure Helm and add the necessary repositories:

Install Helm

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

Add the official Helm repository:

helm repo add stable https://charts.helm.sh/stable

Update the Helm repositories:

helm repo update

Step #3:Create Dockerfile for Go App

Lets create dockerfile using below command:

sudo nano Dockerfile
# Use a lightweight base image
FROM golang:1.21 as builder

# Set the working directory
WORKDIR /app

# Copy your Go source code to the container
COPY . .

# Build your Go application
RUN CGO_ENABLED=0 GOOS=linux go build -o server

# Use a minimal base image for the final image
FROM alpine:latest

# Set the working directory
WORKDIR /app

# Copy the binary from the builder stage
COPY --from=builder /app/server .

# Expose the port your application will run on
EXPOSE 8081

# Start your Go application
CMD ["./server"]

Lets create Go Application -main.go file using below command:

sudo nano main.go
package main

import (
	"fmt"
	"net/http"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
	// Write the response to the client
	fmt.Fprint(w, "Hello, World!")
}

func main() {
	// Register the handler function for the root ("/") route
	http.HandleFunc("/", helloHandler)

	// Start the HTTP server on port 8080
	if err := http.ListenAndServe(":8081", nil); err != nil {
		fmt.Printf("Server error: %v\n", err)
	}
}

Step #4:Create Helm Chart for Go application and modify helm chart file

Initialize a new Helm chart:

helm create chart

This will create a new directory named chart with the basic structure of a Helm chart.

Modify the Helm chart files according to our application’s requirements.

Update chart/templates/deployment.yaml: Replace the content of the file with the following code:

sudo nano deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-app
spec:
  replicas: 2 
  selector:
    matchLabels:
      app: go-app # Add this label
  template:
    metadata:
      labels:
        app: go-app
    spec:
      containers:
        - name: go-app
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 
          ports:
            - containerPort: 8081
sudo nano service.yaml
apiVersion: v1
kind: Service
metadata:
  name: go-app
spec:
  selector:
    app: go-app
  ports:
    - protocol: TCP
      port: 8081
      targetPort: 8081 # Match the port where your Go application is running
sudo nano values.yaml
image:
  repository: devopshint/go-app
  tag: f04b9b3f230b1e4c5eb2bc0da7b14f93809560ad
sudo nano chart.yaml
apiVersion: v2
name: go-app
description: A Go Application
type: application
version: 0.1.0
appVersion: 1.0.0

Step #5:Create ArgoCD workflow to deploy application in ArgoCD

create new folder apps and create new file in apps folder go-app-deploy-minikube.yaml

sudo nano go-app-deploy-minikube.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: 'go-app'
spec:
  destination:
    name: 'in-cluster'
    namespace: 'default'
  source:
    path: 'chart'
    repoURL: 'https://github.com/devopshint/gitops-workflow-deploy-goapp-minikube-using-argocd'
    targetRevision: HEAD
    helm:
      valueFiles:
      - values.yaml
  project: 'default'
  syncPolicy:
    syncOptions:
      - CreateNamespace=false

Step #6:Push Go App code and Dockerfile to GitHub Repo

  • Create new repo in GitHub
  • Click on the “New” button to create a new repository.
  • Provide a name for your repository.
  • Optionally, add a description and choose the repository visibility settings.
  • Click on the “Create repository” button to create the repository.

Initialize Git and link the repository:

  • Open a terminal or command prompt.
  • Navigate to the root directory of your application.
  • Commit and push the application code

Stage the changes by running the following command:

git add .

Commit the changes with a meaningful message by running the following command:

git commit -m "Initial commit"

Push the code to the remote repository by running the following command:

git push -u origin main

Step #7:Access the Argo CD UI

Run the following command to port forward the Argo CD UI to your local machine:

kubectl port-forward svc/argocd-server -n argocd --address 0.0.0.0 8080:443

Open your browser and navigate to http://localhost:8080 to access the Argo CD UI.

Retrieve the Argo CD admin password by running the following command:

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

Step #8:GitHub Actions workflow to build Docker Image and push to DockerHub

  • In your GitHub repository, create the directory.github/workflows
  • Create a new file named cd.yaml and open it for editing.
name: Argo CD GitOps CI/CD
on:
  push:
    branches:
    - main
  
jobs:
  build:
    name: Build and Push the image
    runs-on: ubuntu-latest
    
    steps:
    - name: Check out code
      uses: actions/checkout@v2

    - name: Login to Docker Hub
      uses: docker/login-action@v3
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}
    
    - name: Build and push
      uses: docker/build-push-action@v5
      with:
        push: true
        tags: devopshint/go-app:${{ github.sha }} , devopshint/go-app:latest

  update:
    name: Update Helm Manifests
    runs-on: ubuntu-latest
    needs: build

    steps:
    - name: Check out code
      uses: actions/checkout@v2

    - name: Update Image Tag Values
      run: |
        chart_dir="chart"
        new_image_tag=${{ github.sha }}

        # Update the values.yaml file with the new image tag
        sed -i "s/^  tag: .*/  tag: $new_image_tag/" "$chart_dir/values.yaml"
    
    - name: Commit the changes made
      run: | 
        git config --global user.name 'devopshint'
        git config --global user.email '[email protected]'
        git commit -am "updating image tag"
        git push

Configure Docker Hub and GitHub secrets

  • In your GitHub repository, go to the “Settings” tab.
  • In the left sidebar, click on “Secrets”.
  • Click on the “New repository secret” button.
  • Add the following secrets:
  • Name: DOCKER_USERNAME, Value: [Your Docker Hub username]
  • Name: DOCKER_KEY, Value: [Your Docker Hub access token or password]
  • Click on the “Add secret” button to save the secrets.

Update GitHub Actions permissions:

  • In your GitHub repository, go to the “Settings” tab.
  • In the left sidebar, click on “Actions”.
  • Under the “Permissions” section, make sure that the following permissions are enabled:
  • Write, Read, Run workflows, Manage workflows
  • If any permissions are not enabled, click on the “Enable” button next to each permission to grant access.

Step #9:Deploy Go Application on Minikube using GitOps Workflow

  • Click on the “Applications” tab in the top navigation bar.
  • Click on the “New Application” button.
  •  then click “Edit as YAML”
  • Paste the below yaml file
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: 'go-app'
spec:
  destination:
    name: 'in-cluster'
    namespace: 'default'
  source:
    path: 'chart'
    repoURL: 'https://github.com/devopshint/gitops-workflow-deploy-goapp-minikube-using-argocd'
    targetRevision: HEAD
    helm:
      valueFiles:
      - values.yaml
  project: 'default'
  syncPolicy:
    syncOptions:
      - CreateNamespace=false
GitOps Workflow with ArgoCD and GitHub Actions 1
GitOps Workflow with ArgoCD and GitHub Actions 2

Lets Forward the port to access our image in browser

kubectl port-forward svc/go-app --address 0.0.0.0 8081:8081

Access Go application on browser using Minikube IP and port Number

GitOps Workflow with ArgoCD and GitHub Actions 3

Conclusion:

In this article we have covered How to Create GitOps Workflow with ArgoCD and GitHub Actions.

GitHub Repo for above code

Related Articles:

Deploy NodeJS App Helm Chart on Minikube using GitHub Actions and ArgoCD

Shweta Mamidwar

I am Shweta Mamidwar working as a Intern in Product Company. Likes to share knowledge.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Share via
Copy link
Powered by Social Snap