Decoding ArgoCD: A Step-by-Step Approach
Setting Up ArgoCD in harmony with GitHub Action for Continuous Deployments
Hey there! I'm Shwetabh and I am an Engineering Manager at Fyle. Recently, I've been tasked with the exciting challenge of infusing our team with top-notch engineering practices. Join me on this journey as we understand how to set up and utilize ArgoCD for Continuous Deployments!
ArgoCD is a declarative, GitOps continuous delivery tool for Kubernetes. In this guide, we'll walk through the steps to set up ArgoCD in a Kubernetes cluster, integrate it with a GitHub repository for continuous deployment, and define ArgoCD projects and applications.
Prerequisites
A Kubernetes cluster.
kubectl
the command-line tool installed.Admin/Owner access to your GitHub account.
A bit of experience with Kubernetes and Kustomize
Installation
1. Create the argocd
namespace:
kubectl create namespace argocd
2. Install ArgoCD:
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Wait for the ArgoCD services to be up and running.
Accessing ArgoCD
Local Machine:
Retrieve the default admin password:
kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo
Forward the ArgoCD server port:
kubectl -n argocd port-forward svc/argocd-server 8080:443
Access ArgoCD on your browser at
https://localhost:8080
You can also expose ArgoCD via ingress or other tools to a valid domain such as
https://argocd.example.com
This step will be important for setting up webhooks on GitHub for ArgoCD to observe real-time changes.
Defining ArgoCD Projects and Applications
Add a Kustomize file
This file will maintain all the versions that ArgoCD is going to deploy. Any changes to this file will be auto-detected by ArgoCD and applied.
Suppose you have this kind of structure in your deployment repository, create a kustomization.yaml file.
├── manifests
│ ├── acme-app.yaml
│ ├── acme-api.yaml
├── kustomization.yaml
├── namespace.yaml
└── secrets.yaml
You can initiate the file in this way
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./manifests/acme-app.yaml
- ./manifests/acme-api.yaml
images:
- name: docker.io/my-images/acme-app
newName: docker.io/my-images/acme-app
newTag: v27she12
- name: docker.io/my-images/acme-api
newName: docker.io/my-images/acme-api
newTag: v64d7zs1
Setting Up an ArgoCD Project:
If ArgoCD is installed in the same Kubernetes cluster where your deployments are, the server address will be
https://kubernetes.default.svc
If you are running ArgoCD on a different Kubernetes cluster, you can get the cluster server address from AWS/Google Cloud, etc.
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: project-name
namespace: argocd
spec:
description: "Project description"
sourceRepos:
- "*"
destinations:
- namespace: target-namespace
server: https://kubernetes.default.svc
namespaceResourceWhitelist:
- group: "*"
kind: "*"
Setting Up an ArgoCD Application:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: acme-app
namespace: argocd
spec:
project: project-name
destination:
server: https://kubernetes.default.svc
namespace: target-namespace
source:
repoURL: git@github.com:acme/deployments.git
path: mainfests
targetRevision: main
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true # create namespace if it doesn't exist
Automating Deployment Updates with GitHub Actions
1. Push to DockerHub:
Before updating the deployment, we need to ensure that our application's Docker image is built and pushed to DockerHub. Here's how you can automate this step:
- name: Get the latest short commit hash
id: commit
run: echo "::set-output name=sha::$(git rev-parse --short HEAD)"
- name: Build and push to DockerHub
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: docker.io/my-images/acme-app:${{ steps.commit.outputs.sha }}
username: my-images
password: ${{ secrets.DOCKERHUB_TOKEN }}
2. Install Kustomize:
- name: Install kustomize
run: |
curl -s "<https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh>" | bash
sudo mv kustomize /usr/local/bin/
3. Clone the Deployment Repository:
In this setup, we are assuming that all the deployment files are available in 1 deployment repository.
- name: Clone deployment repository
uses: actions/checkout@v2
with:
repository: acme/deployments
ref: main
path: deployments/
persist-credentials: false
token: ${{ secrets.DEPLOY_GIT_ACCESS_TOKEN }}
4. Update Image Tag:
In this example, we are using kustomize to update the current version of the image to the latest GitHub SHA
- name: Update Image Tag
run: |
NEW_TAG="v$(git rev-parse --short HEAD)"
cd deployments/mainfests
kustomize edit set image docker.io/my-images/acme-app=docker.io/my-images/acme-app:$NEW_TAG
5. Commit and Push Changes:
Finally, we are pushing the latest version from the Service repository to our deploy repository. This is where ArgoCD gets to do its magic!
- name: Commit and push changes
run: |
cd deployments
git config --global user.email "your-email@example.com"
git config --global user.name "GitHub Actions"
git add .
git commit -m "Update image tag"
git remote set-url origin <https://x-access-token>:${{ secrets.DEPLOY_GIT_ACCESS_TOKEN }}@github.com/acme/deployments
git push origin main
Setting Up GitHub Webhooks for ArgoCD
Navigate to Your GitHub Repository: Go to the main page of your GitHub repository.
Access Repository Settings: Click on the "Settings" tab.
Webhooks Menu: On the left sidebar, click on "Webhooks."
Add Webhook: Click on the "Add Webhook" button.
Webhook Settings:
Payload URL: Enter the URL of your ArgoCD server's API endpoint, typically
https://<argocd-server-url>/api/webhook
.Content type: Choose
application/json
.Secret: Enter the webhook secret (if you've set one in ArgoCD).
Which events would you like to trigger this webhook? Choose "Just the push event."
Ensure the "Active" checkbox is checked.
Save Webhook: Click on the "Add webhook" button.
Conclusion
With ArgoCD set up, integrated with GitHub, configured with webhooks, and defined with specific projects and applications, you now have a robust GitOps-based continuous deployment workflow. Every change to your repository can trigger a deployment, ensuring your cluster always runs the latest version of your application.