DEV Community

Cover image for Deploying Applications with GitHub Actions and ArgoCD to EKS: Best Practices and Techniques

Deploying Applications with GitHub Actions and ArgoCD to EKS: Best Practices and Techniques

In this blog, we'll explore the integration of GitHub Actions and ArgoCD for deploying applications to Amazon Elastic Kubernetes Service (EKS). We'll cover the essential practices and techniques to streamline the CI/CD process.

Introduction

Deploying applications involves multiple stages: building, testing, and deploying code. GitHub Actions and ArgoCD are powerful tools that can streamline this process, especially when used with a Kubernetes environment like Amazon EKS.

Why Use GitHub Actions and ArgoCD for EKS?

GitHub Actions: Provides a flexible and integrated way to define CI/CD workflows directly within your GitHub repository.

ArgoCD: GitOps continuous delivery tool for Kubernetes. It ensures that the desired state of your application defined in a Git repository is deployed to your Kubernetes cluster.

Amazon EKS: A managed Kubernetes service that makes it easy to run Kubernetes on AWS without needing to install and operate your own Kubernetes control plane or nodes.

Prerequisite

To get the most out of this article, you should be familiar with:

  • Creating a repository on GitHub
  • Connecting your local repository with the remote repository
  • How to use Git for version control
  • Prior knowledge on Kubernetes
  • Accessing AWS console

Setting Up Your Environment

Amazon EKS Cluster

Create an EKS Cluster:

  • Use the AWS Management Console, CLI, or Infrastructure as Code (IaC) tools like Terraform to provision your EKS cluster.
  • Ensure the cluster is configured with appropriate node groups and IAM roles.

Install and configure kubectl:

  • Install kubectl and configure it to interact with your EKS cluster.

aws eks update-kubeconfig --name your-cluster-name

ArgoCD Installation

Install ArgoCD on EKS:

  • Create a name space for ArgoCD.

kubectl create namespace argocd

  • Apply the ArgoCD manifests using below

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

  • This command deploys all the necessary components of ArgoCDinto EKS cluster under the argocd namespace

Access the ArgoCD UI:

  • By default, the argoCD api server is not exposed via external IP. You can use port Forwarding to access the ArgoCD UI
  • Port-forward the ArgoCD API server to access the web UI.

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

  • you can now access the ArgoCD by navigating to

https://localhost:8080

Login to ArgoCD:

  • Retrieve the initial admin password and log in.
  • The initial password for the admin account is auto-generated and stored in a Kubernetes secret named argo-cd-initial-admin-secret:

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

  • use this to login to the ArgoCD UI.

Connecting ArgoCD with git repository

  • To connect ArgoCD with git repository from Argo UI we have to add the name of the project, git repo url, username and password. Below are the screenshots from ArgoCD UI to connect with GIT Repo

Image description

Image description

Setting Up ArgoCD Applications

Deploy Your ArgoCD Application:

  • Now that ArgoCD is set up and connected with Github, you can deploy your first application. Create an application manifest in a YAML file. Example YAML file: ```

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: your-app-name
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/your-org/your-repo
path: manifests
targetRevision: HEAD
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
ignoreDifferences:

Apply the ArgoCD Application  

- Deploy the application resource to your cluster.

    `kubectl apply -f  your-application.yaml`

**Setting Up Your CI/CD Pipeline**

Create and Configure Your GitHub Repository
Create a new repository: 
- Store your application code and configuration files.
Store Kubernetes manifests:
- Ensure your Kubernetes deployment files (e.g., deployment.yaml, service.yaml,values.yaml) are in the repository.

**Define GitHub Actions Workflows**

 Workflows are defined in YAML files stored in the .github/workflows directory  of your repository. create a new workflow file.

 Example workflow:

Enter fullscreen mode Exit fullscreen mode

name: CI/CD Pipeline
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
- name: Build application
run: npm run build
- name: docker build
run: docker build -t .
- name: docker push
run: docker push ecr.aws.amazonaws.com/your-repo-name:latest
Pushtoargorepo:
runs-on: ubuntu-latest
steps:
- name: Checkout helm repo
uses: actions/checkout@v2
- name: update values.yaml
run: |
echo "image: ecr.aws.amazonaws.com/your-repo-name:latest" >> helm/values.yaml

- name: push to argo repo
run: |
git commands to commit and push the changes to the helmrepo

Application code reside in one repository where the daily code checks happen from the dev’s and helm charts will be in the GitOps repo. The above workflow builds the application and updates the helm values for the deployment with ArgoCD.
ArgoCD is integrated with helm repo so whenever there is an update in the helm files ArgoCD will sync the changes with Kubernetes.


**GitOps flow for EKS Deployment**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i9q5yq3jn55fzazbkt6c.png)


## Why GitHub Actions and ArgoCD compared to other CI/CD tools

**GitHub Actions**


- GitHub Actions provides a platform to automate, customize, and execute your software development workflows right in your repository. It allows you to
- Automate the entire CI/CD process 
- Create custom workflows for a different stages of development
- Integrate with other tools and services through a vast marketplace of prebuild actions

**ArgoCD**


- Multi-Cluster support: ArgoCD can manage multiple Kubernetes Clusters, making it ideal for enterprises with complex, multi-cloud or hybrid cloud environments.

- Self-Healing: With automated synchronization, ArgoCD can detect drift between the desired state and the actual state and correct it automatically, enhancing the reliability and reducing downtime.


## Security Reasons to choose GitHub Actions and ArgoCD

**Github Actions**

- Encrypted Storage: Secrets are encrypted both at rest and in transit, ensuring that sensitive information is protected against unauthorized access

- Scoped Access: Secrets can be scoped to the repository, organization, or environment, providing granular control over who and what can access them.

**ArgoCD** 

- This continuous delivery tool pulls changes from a remote Git repo. Therefore, you don’t need to define firewall rules and VPC peering connections to get deployment servers to connect with the cluster, which is one less entry point. It significantly reduces the attack surface area for dev/QA/prod servers.

- TLS Encryption: All communication between the ArgoCD server and its component is encryption using TLS.

- Continuous Monitoring: Detects and correct drift from the desired state, reducing the risk of unauthorized changes persisting in the cluster.


## Best Practices

- Version Control Everything: Keep all configuration files and Kubernetes manifests under version control to track changes and maintain consistency.
- Modularize Workflows: Break down your workflows into smaller, reusable components to improve maintainability and readability.
- Resource Management: Define resource limits and requests in your Kubernetes manifests to ensure optimal use of cluster resources.
- Secure Secrets and Credentials: Store sensitive information such as AWS credentials and ArgoCD passwords securely in GitHub Secrets. Avoid hardcoding secrets in your configuration files. 


## Techniques for Enhanced CI/CD

- Parallel Job Execution: Utilize parallel jobs in GitHub Actions to speed up the CI process.
- Conditional Workflows: Implement conditional logic to run specific workflows based on branch names, tags, or other criteria.
- Notification Integration: Integrate notifications with Slack or other communication tools to stay informed about the status of your CI/CD pipelines.
- Rollback Mechanisms: Implement rollback strategies to revert to a stable state in case of deployment failures.

## Overcoming Challenges

**Challenge**: Sending Notifications to a Slack Channel from ArgoCD

**Story**: During our CI/CD pipeline implementation, we realized the importance of keeping the team informed about the deployment status. Initially, we faced difficulties in sending notifications to our Slack channel once the pods were up and running with the latest code.

**Solution**: To address this, we integrated ArgoCD with Slack using webhook notifications. We configured ArgoCD to send a notification to a designated Slack channel upon successful synchronization of the application, indicating that the pods were updated with the latest code.

**Steps to Implement Slack Notifications:**

Create a Slack App:

- Go to the Slack API website and create a new Slack App.
- Add a webhook to your Slack app and configure the webhook URL.

Configure ArgoCD Notifications:

- Install the ArgoCD Notifications controller in your Kubernetes cluster.
- Create a ConfigMap to define the notification template and Slack webhook.

Example ConfigMap:

Enter fullscreen mode Exit fullscreen mode

apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
namespace: argocd
data:
notifications.yaml: |
triggers:
- name: on-sync-succeeded
condition: app.status.operationState.phase == 'Succeeded'
template: app-sync-succeeded

templates:
  - name: app-sync-succeeded
    title: Application {{.app.metadata.name}} sync succeeded
    body: |
      Application {{.app.metadata.name}} in namespace {{.app.metadata.namespace}} was successfully synced.

subscriptions:
  - recipients:
      - slack:your-slack-webhook-url
Enter fullscreen mode Exit fullscreen mode

Apply the ConfigMap:

- Apply the ConfigMap to your Kubernetes cluster using kubectl.
- Save the above YAML data in a file (filename.yaml)then run the below command in the terminal in your argocd namespace in the cluster.

`kubectl apply -f filename.yaml`

Test the Notification:

- Trigger a deployment and verify that a notification is sent to your Slack channel upon successful synchronization.

## Conclusion

By leveraging GitHub Actions and ArgoCD, you can create a robust CI/CD pipeline for deploying applications to Amazon EKS. Following best practices and utilizing advanced techniques will ensure efficient, reliable, and secure application deployments.

Further Reading

• https://docs.github.com/en/actions
• https://helm.sh/docs/
• https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html
















Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
burninmedia profile image
Stephen Lester

How do you bumb container image version? As a commit to the helm chart repo or as a API call to ArgoCD to increment container version? One of the things the API method helps is to reduce the number of PRs in a git repo. But you loose that version of the container as it's state is stored in ArgoCD now. I hate the extra PR history but think having the container image version in the helm chart values get updated via the repo PR so all the state is in version control. What are others thoughts?

Collapse
 
apedrotti profile image
Andre Pedrotti

Looking forward to get insights about that.
I've been struggling myself to define this strategy in an ongoing project.
Thanks in advance