Take the headache out of deploying apps on k8s via ArgoCD with some templating and magic.
To make the most out of this code, you'll need a Kubernetes cluster running ArgoCD. Not sure how to install ArgoCD on your cluster? Check out this handy-dandy tutorial here.
You also need to be running Python >=3.8 if you want to run the code locally. Alternatively, you can run the code from within Docker. Image provided. Obviously, if you go that route, you'll need to have Docker installed.
You can check out our other ArgoCD-themed tutorials:
- Using Tekton and ArgoCD to Set Up a Kubernetes-Native Build & Release Pipeline
- Configuring SSO with Azure Active Directory on ArgoCD
- Turbocharge ArgoCD with App of Apps Pattern and Kustomized Helm
NOTE: I am using Fish as my default shell. You'll need to make adjustments in some spots if you're using Bash.
To keep things neat, I like to use Python virtual environments. Set up your virtual environment by running the commands below:
pip install venv
virtualenv venv
source venv/bin/activate.fish
python -m pip install --upgrade pip
pip install --upgrade --force-reinstall -r requirements.txt
I use pre-commit
to format my Python code so that it's consistent across the board. It's installed as part of requirements.txt
Once pre-commit
is installed, run the commands below to set up the tool.
pre-commit install
pre-commit run --all-files
Since the ArgoCD CLI installation instructions don't seem to work when building a Dockerfile, I've downloaded a copy of the binary to this repo, which then I copy when building the Dockerfile. Since it's a big file, you need git-lfs
when adding to the repo.
To install git-lfs
:
brew install git-lfs
git lfs install
git lfs track argocd-linux-amd64
NOTE: If you've figured out how to build a Dockerfile with the ArgoCD CLI that's less convoluted than my process, please, SHARE YOUR KNOWLEDGE!!
Fun fact: you can install the ArgoCD CLI from your ArgoCD cluster, rather than from ArgoCD's GitHub repo.
One reason why you might choose this route is that it ensures parity between your CLI version and the version running on your k8s cluster.
Reference: ArgoCD Docs
- Mac:
http://<argocd_server>/argo-cd/download/argocd-darwin-amd64
- Windows:
http://<argocd_server>/argo-cd/download/argocd-windows-amd64.exe
- Linux:
http://<argocd_server>/argo-cd/download/argocd-linux-amd64
To run the code locally using Python Invoke:
NOTE: I'm using Fish as my default shell. Please update accordingly for Bash.
set -x GIT_USERNAME
set -x GIT_TOKEN <git_token>
set -x GIT_REPO_URL <git_repo_url>
set -x ARGOCD_USERNAME admin
set -x ARGOCD_PASSWORD <argocd_password>
set -x ENV development
set -x TARGET_ENVIRONMENT "DEV"
# Set up App of Apps YAML
invoke --collection=argocd_app_bootstrap argo-setup.setup-app-of-apps
# Deploy App Bundle to ArgoCD
invoke --collection=argocd_app_bootstrap argo-run.deploy-app-bundle
# Cascade delete the ArgoCD App Bundle
invoke --collection=argocd_app_bootstrap argo-run.remove-app-bundle
# Removes all registered repos and projects from ArgoCD defined in argo_proj.yml
invoke --collection=argocd_app_bootstrap argo-run.remove-project argo-run.remove-repos
# Kubernetes deployment scaffolding (creates kustomized helm folder and some templated YAMLs)
invoke --collection=argocd_app_bootstrap deploy-setup.bootstrap-k8s-deployment
To run code within the Docker container, let's first build the Dockerfile:.
Before running the Docker build, you'll have to do the following:
- Modify
Line 45
in the Dockerfile to point to your own gcloud service account credentials JSON file. If you're not on gcloud, please modify the dockerfile accordingly. - Modify
Line 26
in docker_build.sh to point to your own gcloud service account credentials JSON file. If you're not on gcloud, please modify the script accordingly.
NOTE: You should check out this blog post on Medium if you want to impersonate a service account instead. Honestly, it's a better idea. I just haven't gotten to it myself.
Now run the build.
# Build
./docker/docker_build.sh <tag_name>
Run the image:
# Run
docker run -it --rm \
--network host \
--name argocd-bootstrap \
-e ENV="development_docker" \
-e GIT_USERNAME="" \
-e GIT_TOKEN="<git_token>" \
-e GIT_REPO_URL="<git_repo_url>" \
-e ARGOCD_USERNAME="admin" \
-e ARGOCD_PASSWORD="<argocd_admin_password>" \
-e TARGET_ENVIRONMENT="DEV" \
argocdapp-bootstrap:1.0.0 "/bin/bash"
Once you're inside the container, play around by running the commands below:
# gcloud login, sets up kube config
./startup.sh
# Set up App of Apps YAML
argo-bootstrap argo-setup.setup-app-of-apps
# Deploy App Bundle to ArgoCD
argo-bootstrap argo-run.deploy-app-bundle
# Cascade delete the ArgoCD App Bundle
argo-bootstrap argo-run.remove-app-bundle
# Removes all registered repos and projects from ArgoCD defined in argo_proj.yml
argo-bootstrap argo-run.remove-project argo-run.remove-repos
# Kubernetes deployment scaffolding (creates kustomized helm folder and some templated YAMLs)
argo-bootstrap deploy-setup.bootstrap-k8s-deployment
NOTE:
startup.sh
assumes that you're usinggcloud
. If you're on a different cloud provider, you'll need to modify accordingly.
We're into the good stuff now.
The purpose of this tool is to allow for making it easier to implement ArgoCD's App of Apps pattern. It generates the necessary files and folder structure described in our blog post about the App of Apps Pattern.
First, have a quick refresher on some useful terms.
An App Bundle is a group of related microservices.
An App Manifest refers to all of the YAML definitions that make your microservices run on Kubernetes. For example, a
Service
resource definition and aDeployment
resource definition.
This tool reads a file called argo_proj.yml
to create an AppProject
YAML and all of the Application
YAMLs for the microservices being grouped together for a particular App Bundle. Keeping in mind that applications are often deployed to different environments, these files are created for DEV
, QA
, and PROD
environments.
The argo_proj.yml
looks something like this:
argocd:
project:
name: appbundle-project
description: The app bundle POC project
parent_app:
name: appbundle
repo_url: https://github.com/d0-labs/argocd-app-of-apps-parent
version: 1.0
child_apps:
destination_cluster: in-cluster
app:
- name: helm-guestbook
repo_url: https://github.com/d0-labs/argocd-app-of-apps-child-guestbook
namespace: helm-guestbook
manifest_path: kustomized_helm/overlays/dev
deploy_plugin: kustomized-helm
- name: 2048-game
repo_url: https://github.com/d0-labs/argocd-app-of-apps-child-2048-game
namespace: 2048-game
manifest_path: kustomized_helm/overlays/dev
deploy_plugin: kustomized-helm
parent_app.repo_url
: The App Bundle repo. This is the repo in which theApplication
andAppProject
YAML files will be created. This repo would be typically managed by an SRE team.child_apps.destination_cluster
: The cluster to which the microservices apps will be deployedapp.repo_url
: The application repo in which the application code resides. This is typically managed by application developers.app.manifest_path
: The location of the Kubernetes app manifests (i.e. Helm Charts, Kustomizations,Service
definitions,Deployment
definitions, etc.)app.deploy_plugin
: The name of the ArgoCD plugin to use, as configured in the argocd-cm.yml file. We are assuming the use of a kustomized-helm plugin. If this field is ommitted, then ArgoCD will look for either Helm Charts, Kustomizations, or plain old YAML in the specified manifest path.
So you've seen the main commands of the tool in the quickstart guide above. Here's a more detailed view of what they do.
Please note that I am assuming that you've got your ArgoCD up and running and configured, and have registered your clusters using argocd cluster add
. For more on ArgoCD setup, please check out this blog post.
This action creates the Application
and AppProject
YAML files for the parent and child applications defined in the App Bundle repo. The files are created in the App Bundle repo (like this one), and have a file structure like this one:
Note how we're creating app bundles for 3 different k8s clusters (DEV
, QA
, PROD
).
This action will:
- Register the repos associated with the parent and child apps defined in
argo_proj.yml
. - Create the
AppProject
in ArgoCD for the target environment (i.e. eitherDEV
,QA
, orPROD
). Remember thatTARGET_ENVIRONMENT
environment variable that you set in the Quickstart above? :) - Create the parent and child
Application
in ArgoCD - Deploy the applications to the target cluster for the given target environment (defined by
TARGET_ENVIRONMENT
)
This action will perform a cascade delete of all parent and child resources, including app manifests, namespaces, and ArgoCD Application
definitions. It does NOT delete the project or repo registrations.
This action is actually 2 chained actions. The first action deletes the AppProject
from ArgoCD. The second action unregisters the repos configured in argo_proj.yml
.
You could technically create a single invoke
task which chains them together without having to "manually" chain them as above.
This action will scaffold a folder structure for deploying applications to Kubernetes using Kustomized Helm. The folder structure looks like this:
Helm is used to template base variables (i.e. .Release.Name
).
Kustomize is used to:
- Apply common namespace and labels to all YAML resources being Kustomized
- Handle environment-specific configuratoins (i.e. DEV, QA, PROD). This includes:
- Number of replicas for the
Deployment
(viapatchesJson6902
in thekustomization.yml
) - Number of seconds for the livenessProbe for the
Deployment
(viapatchesJson6902
in thekustomization.yml
) - Image name and tag (via
images
in thekustomization.yml
)
- Number of replicas for the