Argo CD "App of Apps" on EKS

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MyrinNew
    Senior Member
    • Feb 2024
    • 5168

    #1

    Argo CD "App of Apps" on EKS

    In our previous article we saw how to set up an Istio service mesh and monitor it using Kiali. Now we'll configure and use Argo CD on our EKS cluster with the "App of Apps" GitOps pattern, and automatically deploy sample frontend (nginx) and backend (http-echo) applications.


    The "App of Apps" pattern is essential when you're bootstrapping clusters with many components, whether they're add-ons (like Istio and Kiali) or application workloads.


    Prerequisites

    1. You have a Kubernetes cluster running
    2. kubectl is configured to talk to your Kubernetes cluster
    3. You have a basic understanding of GitOps
    4. You have a Git repository. I'll be using GitHub for this demo
    5. You have a basic understanding of Helm


    Step 1 - Installing Argo CD

    Before installing Argo CD in our cluster, we'll first create an "argocd" namespace for better isolation and management of Argo CD components (pods, deployments, services, etc).






    kubectl create namespace argocd







    There are primarily two options for installing Argo CD in a Kubernetes cluster: kubectl or helm.

    For our demo, we'll install Argo CD using helm.


    We'll start by adding the Argo CD Helm chart repository:






    helm repo add argo https://argoproj.github.io/argo-helm







    Then we update the Helm repository list to ensure we have the latest chart information:






    helm repo update







    And finally, we install the Argo CD Helm chart with the command below. This will install all necessary Argo CD components into the argocd namespace (that we just created). You can customize the installation by using a values.yaml file with the --values flag.






    helm install argocd argo/argo-cd --namespace argocd







    We can verify the installation with the following command, making sure that all pods are running:






    kubectl -n argocd get pods







    With Argo CD now installed, the simplest way to access the UI is via port forwarding (depending on your EKS cluster's network).

    So, we'll port-forward the argocd-server service, making it available on http://localhost:8080:






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







    We should now retrieve the initial admin password (the default username is admin). The initial password is auto-generated and stored as a Kubernetes secret:






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







    You can access the Argo CD UI on http://localhost:8080





    Step 2 - Prepare Git Repository

    Your GitOps repository should look like this:






    gitops-eks/
    ├── apps/
    │ ├── frontend-app.yaml
    │ └── backend-app.yaml

    ├── app-of-apps/
    │ └── parent-app.yaml

    ├── frontend/
    │ ├── namespace.yaml
    │ ├── deployment.yaml
    │ └── service.yaml

    └── backend/
    ├── namespace.yaml
    ├── deployment.yaml
    └── service.yaml
    • app-of-apps/ -> App of Apps
    • apps/ -> Argo CD applications
    • frontend/ -> Kubernetes manifests for frontend application
    • backend/ -> Kubernetes manifests for backend application


    Content of Manifests

    app-of-apps/parent-app.yaml





    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
    name: platform-apps
    namespace: argocd
    spec:
    project: default

    source:
    repoURL: https://github.com/YOUR_ORG/gitops-eks.git
    targetRevision: HEAD
    path: apps

    destination:
    server: https://kubernetes.default.svc
    namespace: argocd

    syncPolicy:
    automated:
    prune: true
    selfHeal: true
    • This parent Argo CD application (App of Apps) reads all manifests in the apps directory (as indicated by the line path: apps)
    • It then creates the child Argo CD applications (frontend and backend in this case)
    • Then it automatically syncs drift (as indicated by the syncPolicy)


    apps/frontend-app.yaml





    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
    name: frontend
    namespace: argocd
    spec:
    project: default

    source:
    repoURL: https://github.com/YOUR_ORG/gitops-eks.git
    targetRevision: HEAD
    path: frontend

    destination:
    server: https://kubernetes.default.svc
    namespace: frontend

    syncPolicy:
    automated:
    prune: true
    selfHeal: true
    syncOptions:
    - CreateNamespace=true
    • This frontend Argo CD application deploys the frontend application using the Kubernetes manifests in the frontend directory (as indicated by the line path: frontend)
    • It also automatically creates this application's namespace if it doesn't exist already


    apps/backend-app.yaml





    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
    name: backend
    namespace: argocd
    spec:
    project: default

    source:
    repoURL: https://github.com/YOUR_ORG/gitops-eks.git
    targetRevision: HEAD
    path: backend

    destination:
    server: https://kubernetes.default.svc
    namespace: frontend

    syncPolicy:
    automated:
    prune: true
    selfHeal: true
    syncOptions:
    - CreateNamespace=true
    • This frontend Argo CD application deploys the backend application using the Kubernetes manifests in the backend directory (as indicated by the line path: backend)
    • It also automatically creates this application's namespace if it doesn't exist already


    frontend/namespace.yaml





    apiVersion: v1
    kind: Namespace
    metadata:
    name: frontend
    • This manifest creates the namespace for the frontend application


    frontend/deployment.yaml





    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: frontend
    spec:
    replicas: 2
    selector:
    matchLabels:
    app: frontend
    template:
    metadata:
    labels:
    app: frontend
    spec:
    containers:
    - name: nginx
    image: nginx:1.25
    ports:
    - containerPort: 80
    resources:
    requests:
    memory: "64Mi"
    cpu: "250m"
    limits:
    memory: "128Mi"
    cpu: "500m"
    • This manifest creates an Nginx deployment for the frontend application that listens on port 80


    frontend/service.yaml





    apiVersion: v1
    kind: Service
    metadata:
    name: frontend
    spec:
    type: ClusterIP
    selector:
    app: frontend
    ports:
    - protocol: TCP
    port: 80
    targetPort: 80
    • This manifest creates a service for the frontend application's deployment that listens on port 80


    backend/namespace.yaml





    apiVersion: v1
    kind: Namespace
    metadata:
    name: backend
    • This manifest creates the namespace for the backend application


    backend/deployment.yaml





    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: backend
    spec:
    replicas: 2
    selector:
    matchLabels:
    app: backend
    template:
    metadata:
    labels:
    app: backend
    spec:
    containers:
    - name: api
    image: hashicorp/http-echo
    args:
    - "-text=Hello from backend"
    - "-listen=:5678"
    ports:
    - containerPort: 5678
    resources:
    requests:
    memory: "64Mi"
    cpu: "250m"
    limits:
    memory: "128Mi"
    cpu: "500m"
    • This manifest creates an http-echo deployment for the backend application that listens on port 5678


    backend/service.yaml





    apiVersion: v1
    kind: Service
    metadata:
    name: backend
    spec:
    type: ClusterIP
    selector:
    app: backend
    ports:
    - protocol: TCP
    port: 80
    targetPort: 5678
    • This manifest creates a service for the backend application's deployment that listens on port 80 and redirects traffic to the deployment's pods on port 5678


    Step 3 - Bootstrap the App of Apps

    With the Git repository configured and the manifest files pushed to it, we can now apply the parent YAML once:






    kubectl apply -f app-of-apps/parent-app.yaml







    Argo CD will then:

    1. Create all Argo CD applications (App of Apps, frontend, and backend)
    2. Create the Kubernetes namespaces for the frontend and backend applications
    3. Create the deployments for the frontend and backend applications
    4. Create the services for the frontend and backend applications


    You should see a similar output after executing the previous command:





    From your terminal, enter the following commands to verify that the applications were successfully deployed:






    kubectl -n argocd get applications
    kubectl -n frontend get service,deployment
    kubeclt -n backend get service,deployment







    You should have outputs similar to these:





    You could also verify this using the Argo CD UI.

    Below is the page displaying the three Argo CD applications that were created:





    Clicking on each of the applications should show you similar pages:


    parent app




    frontend app




    backend app




    Step 4 - GitOps in Action

    To see the power of GitOps, we will update the backend deployment manifest so it now has 3 replicas instead of the initial 2.

    After making this change and pushing it to the Git repository, we should see our backend application update automatically (you may need to refresh your apps in the UI).


    As you can see from the image below, the backend application no longer has 2 replicas, but now has 3:





    Conclusion

    By implementing Argo CD on your EKS clusters with the App of Apps pattern, you move from imperative cluster management to a true GitOps operating model, thereby leading to faster, reproducible deliveries, with auditable changes.




    More...
Working...