Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GitOps Bridge v2 poc #74

Open
wants to merge 90 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
2e5daed
initial poc
csantanapr Jul 19, 2024
129f384
--- split
csantanapr Jul 19, 2024
b00ef2d
update
csantanapr Jul 19, 2024
b518da5
now
csantanapr Jul 19, 2024
d5a6add
update branch
csantanapr Jul 19, 2024
4f72e7e
update detaul
csantanapr Jul 19, 2024
201215b
fix namepsaces
csantanapr Jul 19, 2024
2fef0a6
use selector
csantanapr Jul 19, 2024
4254c5b
csi resources
csantanapr Jul 19, 2024
d1ce66e
add workload
csantanapr Jul 19, 2024
9f69ef3
hardcode the variable for now
csantanapr Jul 19, 2024
6b1617a
push hcnages for karpenter
csantanapr Jul 23, 2024
f617ffe
fix metric server
csantanapr Jul 23, 2024
e485bba
add irsa
csantanapr Jul 23, 2024
440aa61
fix
csantanapr Jul 23, 2024
faff635
fix
csantanapr Jul 23, 2024
e7d9509
push the changes
csantanapr Jul 24, 2024
c24b6fe
update
csantanapr Jul 24, 2024
2ec8a82
update argocd
csantanapr Jul 24, 2024
12629f4
push tolerations
csantanapr Jul 24, 2024
1002927
update
csantanapr Jul 24, 2024
203dd1b
update
csantanapr Jul 24, 2024
6151df8
fix
csantanapr Jul 24, 2024
a505548
fix metric-server
csantanapr Jul 24, 2024
ec13d17
add values for alb
csantanapr Jul 24, 2024
2fcb657
update cluster name
csantanapr Jul 24, 2024
8f4b425
adm64 for now
csantanapr Jul 25, 2024
855ee81
add karpenter node role to cluster
csantanapr Jul 25, 2024
28a34d0
update
csantanapr Jul 25, 2024
c02a32d
add gatekeeper
csantanapr Jul 26, 2024
e43d271
add skipdryrun
csantanapr Jul 26, 2024
168a72d
fix skip
csantanapr Jul 26, 2024
cd37ecf
update argocd
csantanapr Jul 26, 2024
0defea4
netpol
csantanapr Jul 26, 2024
e229d3f
update netpol
csantanapr Jul 26, 2024
96c9f05
fix location
csantanapr Jul 26, 2024
355435d
update argocd
csantanapr Jul 26, 2024
97140f6
update values
csantanapr Jul 27, 2024
a60d7cc
refactor gitops brige directories
csantanapr Jul 27, 2024
047e114
update missing tenant metadata
csantanapr Jul 27, 2024
987eed9
update
csantanapr Jul 27, 2024
afd7f69
comment out tenatns
csantanapr Jul 27, 2024
3adf444
namepsaces from values
csantanapr Jul 27, 2024
5cb4a81
update
csantanapr Jul 27, 2024
3724c7d
update
csantanapr Jul 27, 2024
d5806d4
update argo cd namespace
csantanapr Jul 27, 2024
1ce4e8f
use releasename from helm chart
csantanapr Jul 27, 2024
780ed17
remove release name from stack
csantanapr Jul 27, 2024
22ab650
make stacks optional
csantanapr Jul 27, 2024
955852f
add tenant options
csantanapr Jul 28, 2024
0e43e9b
switch gatekeeper to chart
csantanapr Jul 28, 2024
5c3c4e1
update workloads
csantanapr Jul 28, 2024
bcb8634
fix typo
csantanapr Jul 28, 2024
ec63ec4
update
csantanapr Jul 28, 2024
47fb1f2
fix
csantanapr Jul 28, 2024
0b0cb8e
ugly fix
csantanapr Jul 28, 2024
c4ea145
fix netpol
csantanapr Jul 28, 2024
d1a0359
update teams helm chart and network policies
csantanapr Jul 28, 2024
14d2212
update gitops bridge helm
csantanapr Jul 28, 2024
9890a83
move addons to default
csantanapr Jul 29, 2024
19c0f6e
update node class
csantanapr Jul 29, 2024
8736edc
fix karpenter sg
csantanapr Jul 30, 2024
4e7ea92
add labels and annotations
csantanapr Jul 30, 2024
b78d2d9
chart improvements
csantanapr Jul 31, 2024
ad45c05
chart improvements
csantanapr Jul 31, 2024
3fb0637
add stack assigment
csantanapr Aug 1, 2024
316dd3a
sync gitops-bridge chart
csantanapr Aug 4, 2024
e52d329
update
csantanapr Aug 4, 2024
7aca4ff
new karpenter chart
csantanapr Aug 4, 2024
92aebd4
add license to karpenter community repo
csantanapr Aug 4, 2024
9e517c2
update
csantanapr Aug 4, 2024
eeab017
fix volcano
csantanapr Aug 4, 2024
ec4d618
fix amiselector
csantanapr Aug 4, 2024
b525918
skip argocd
csantanapr Aug 4, 2024
bcf09ac
adjust workload
csantanapr Aug 6, 2024
df38048
enable_addon_selector
csantanapr Aug 6, 2024
59a4099
add dynamic addons template
csantanapr Aug 6, 2024
2845678
update gitops bridge char values
csantanapr Aug 6, 2024
6ca7798
stacks in folder
csantanapr Aug 6, 2024
cbb21c2
remove old files
csantanapr Aug 6, 2024
9749797
add addons
csantanapr Aug 7, 2024
177762e
fix values
csantanapr Aug 7, 2024
6e3937b
update destroy
csantanapr Aug 7, 2024
050367f
update list of addons
csantanapr Aug 7, 2024
69842e9
add monitoring
csantanapr Aug 8, 2024
feff3c9
fix namespace
csantanapr Aug 8, 2024
885445f
fix fluentbit
csantanapr Aug 8, 2024
0f436e8
update fluent
csantanapr Aug 8, 2024
f81e96b
add tolerations
csantanapr Aug 8, 2024
f686cd7
update destroy
csantanapr Aug 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions argocd/iac/terraform/examples/eks/single-cluster-v2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# ArgoCD on Amazon EKS

This pattern shows how to use the new stack platform concept

This tutorial guides you through deploying an Amazon EKS cluster with addons configured via ArgoCD, employing the [GitOps Bridge Pattern](https://github.com/gitops-bridge-dev).


## Prerequisites
Before you begin, make sure you have the following command line tools installed:
- git
- terraform
- kubectl
- argocd

## Fork the Git Repositories

### Fork the Addon GitOps Repo
1. Fork the git repository for addons [here](https://github.com/gitops-bridge-dev/gitops-bridge-argocd-control-plane-template).
2. Update the following environment variables to point to your fork by changing the default values:
```shell
export TF_VAR_gitops_addons_org=https://github.com/gitops-bridge-dev
export TF_VAR_gitops_addons_repo=gitops-bridge-argocd-control-plane-template
```

### Fork the Workloads GitOps Repo
1. Fork the git repository for this pattern [here](https://github.com/gitops-bridge-dev/gitops-bridge)
2. Update the following environment variables to point to your fork by changing the default values:
```shell
export TF_VAR_gitops_workload_org=https://github.com/gitops-bridge-dev
export TF_VAR_gitops_workload_repo=gitops-bridge
```

## Deploy the EKS Cluster
Initialize Terraform and deploy the EKS cluster:
```shell
terraform init
terraform apply -auto-approve
```
Retrieve `kubectl` config, then execute the output command:
```shell
terraform output -raw configure_kubectl
```

Terraform will add GitOps Bridge Metadata to the ArgoCD secret.
The annotations contain metadata for the addons' Helm charts and ArgoCD ApplicationSets.
```shell
kubectl get secret -n argocd -l argocd.argoproj.io/secret-type=cluster -o json | jq '.items[0].metadata.annotations'
```
The output looks like the following:
```json
{
"addons_repo_basepath": "",
"addons_repo_path": "bootstrap/control-plane/addons",
"addons_repo_revision": "main",
"addons_repo_url": "https://github.com/gitops-bridge-dev/gitops-bridge-argocd-control-plane-template",
"aws_account_id": "0123456789",
"aws_cluster_name": "getting-started-gitops",
"aws_load_balancer_controller_iam_role_arn": "arn:aws:iam::0123456789:role/alb-controller",
"aws_load_balancer_controller_namespace": "kube-system",
"aws_load_balancer_controller_service_account": "aws-load-balancer-controller-sa",
"aws_region": "us-west-2",
"aws_vpc_id": "vpc-001d3f00151bbb731",
"cluster_name": "in-cluster",
"environment": "dev",
"workload_repo_basepath": "argocd/iac/terraform/examples/eks/",
"workload_repo_path": "getting-started/k8s",
"workload_repo_revision": "main",
"workload_repo_url": "https://github.com/gitops-bridge-dev/gitops-bridge"
}
```
The labels offer a straightforward way to enable or disable an addon in ArgoCD for the cluster.
```shell
kubectl get secret -n argocd -l argocd.argoproj.io/secret-type=cluster -o json | jq '.items[0].metadata.labels'
```
The output looks like the following:
```json
{
"aws_cluster_name": "getting-started-gitops",
"enable_argocd": "true",
"enable_aws_load_balancer_controller": "true",
"enable_metrics_server": "true",
"kubernetes_version": "1.28",
}
```

## Deploy the Addons
Bootstrap the addons using ArgoCD:
```shell
kubectl apply -f bootstrap/addons.yaml
```

### Monitor GitOps Progress for Addons
Wait until all the ArgoCD applications' `HEALTH STATUS` is `Healthy`. Use Crl+C to exit the `watch` command
```shell
watch kubectl get applications -n argocd
```

### Verify the Addons
Verify that the addons are ready:
```shell
kubectl get deployment -n kube-system \
aws-load-balancer-controller \
metrics-server
```

## Access ArgoCD
Access ArgoCD's UI, run the command from the output:
```shell
terraform output -raw access_argocd
```


## Deploy the Workloads
Deploy a sample application located in [k8s/game-2048.yaml](k8s/game-2048.yaml) using ArgoCD:
```shell
kubectl apply -f bootstrap/workloads.yaml
```

### Monitor GitOps Progress for Workloads
Watch until the Workloads ArgoCD Application is `Healthy`
```shell
watch kubectl get -n argocd applications workloads
```
Wait until the ArgoCD Applications `HEALTH STATUS` is `Healthy`. Crl+C to exit the `watch` command

### Verify the Application
Verify that the application configuration is present and the pod is running:
```shell
kubectl get -n game-2048 deployments,service,ep,ingress
```
Wait until the Ingress/game-2048 `MESSAGE` column value is `Successfully reconciled`. Crl+C to exit the `watch` command
```shell
kubectl events -n game-2048 --for ingress/game-2048 --watch
```



### Access the Application using AWS Load Balancer
Verify the application endpoint health using `curl`:
```shell
curl -I $(kubectl get -n game-2048 ingress game-2048 -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
```
The first line of the output should have `HTTP/1.1 200 OK`.

Retrieve the ingress URL for the application, and access in the browser:
```shell
echo "Application URL: http://$(kubectl get -n game-2048 ingress game-2048 -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')"
```


### Container Metrics
Check the application's CPU and memory metrics:
```shell
kubectl top pods -n game-2048
```

## Destroy the EKS Cluster
To tear down all the resources and the EKS cluster, run the following command:
```shell
./destroy.sh
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
global:
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
controller:
env:
- name: ARGOCD_SYNC_WAVE_DELAY
value: '30'
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-addons
namespace: argocd
spec:
syncPolicy:
preserveResourcesOnDeletion: true
goTemplate: true
goTemplateOptions:
- missingkey=error
generators:
- clusters: {}
template:
metadata:
name: cluster-addons
spec:
project: default
source:
repoURL: '{{.metadata.annotations.addons_repo_url}}'
path: '{{.metadata.annotations.addons_repo_basepath}}charts/gitops-bridge'
targetRevision: '{{.metadata.annotations.addons_repo_revision}}'
helm:
valuesObject:
repoURLValuesBasePath: '{{.metadata.annotations.addons_repo_basepath}}'
repoURLValuesRevision: '{{.metadata.annotations.addons_repo_revision}}'
repoURLGitBasePath: '{{.metadata.annotations.addons_repo_basepath}}stacks/'
repoURLGitRevision: '{{.metadata.annotations.addons_repo_revision}}'
useSelector: false
useStack: true
addons:
%{ for key, value in addons ~}
%{ if substr(key, 0, 7) == "enable_" && value == true ~}
${replace(key, "enable_", "")}:
enabled: ${value}
%{ endif ~}
%{ endfor ~}
ignoreMissingValueFiles: true
valueFiles:
- '{{.metadata.annotations.addons_repo_basepath}}default/addons/gitops-bridge/values.yaml'
- '{{.metadata.annotations.addons_repo_basepath}}environments/{{.metadata.labels.environment}}/gitops-bridge/values.yaml'
- '{{.metadata.annotations.addons_repo_basepath}}clusters/{{.nameNormalized}}/addons/values.yaml'
- '{{.metadata.annotations.addons_repo_basepath}}tenants/{{.metadata.labels.tenant}}/default/addons/gitops-bridge/values.yaml'
- '{{.metadata.annotations.addons_repo_basepath}}tenants/{{.metadata.labels.tenant}}/environments/{{.metadata.labels.environment}}/gitops-bridge/values.yaml'
- '{{.metadata.annotations.addons_repo_basepath}}tenants/{{.metadata.labels.tenant}}/clusters/{{.nameNormalized}}/addons/values.yaml'
destination:
namespace: argocd
name: '{{.name}}'
syncPolicy:
automated:
selfHeal: true
allowEmpty: true
prune: false
retry:
limit: 100
syncOptions:
- CreateNamespace=true
- ServerSideApply=true # Big CRDs.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: cluster-addons
namespace: argocd
spec:
syncPolicy:
preserveResourcesOnDeletion: true
goTemplate: true
goTemplateOptions:
- missingkey=error
generators:
- clusters: {}
template:
metadata:
name: cluster-addons
spec:
project: default
source:
repoURL: '{{.metadata.annotations.addons_repo_url}}'
path: '{{.metadata.annotations.addons_repo_basepath}}charts/gitops-bridge'
targetRevision: '{{.metadata.annotations.addons_repo_revision}}'
helm:
valuesObject:
repoURLValuesBasePath: '{{.metadata.annotations.addons_repo_basepath}}'
repoURLValuesRevision: '{{.metadata.annotations.addons_repo_revision}}'
repoURLGitBasePath: '{{.metadata.annotations.addons_repo_basepath}}stacks/'
repoURLGitRevision: '{{.metadata.annotations.addons_repo_revision}}'
useSelector: true
useStack: true
ignoreMissingValueFiles: true
valueFiles:
- '{{.metadata.annotations.addons_repo_basepath}}default/addons/gitops-bridge/values.yaml'
- '{{.metadata.annotations.addons_repo_basepath}}environments/{{.metadata.labels.environment}}/gitops-bridge/values.yaml'
- '{{.metadata.annotations.addons_repo_basepath}}clusters/{{.nameNormalized}}/addons/values.yaml'
- '{{.metadata.annotations.addons_repo_basepath}}tenants/{{.metadata.labels.tenant}}/default/addons/gitops-bridge/values.yaml'
- '{{.metadata.annotations.addons_repo_basepath}}tenants/{{.metadata.labels.tenant}}/environments/{{.metadata.labels.environment}}/gitops-bridge/values.yaml'
- '{{.metadata.annotations.addons_repo_basepath}}tenants/{{.metadata.labels.tenant}}/clusters/{{.nameNormalized}}/addons/values.yaml'
destination:
namespace: argocd
name: '{{.name}}'
syncPolicy:
automated:
selfHeal: true
allowEmpty: true
prune: false
retry:
limit: 100
syncOptions:
- CreateNamespace=true
- ServerSideApply=true # Big CRDs.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: workloads
namespace: argocd
spec:
syncPolicy:
preserveResourcesOnDeletion: false
generators:
- clusters: {}
template:
metadata:
name: workloads
finalizers:
# This finalizer is for demo purposes, in production remove apps using argocd CLI "argocd app delete workload --cascade"
# When you invoke argocd app delete with --cascade, the finalizer is added automatically.
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: '{{metadata.annotations.workload_repo_url}}'
path: '{{metadata.annotations.workload_repo_basepath}}'
targetRevision: '{{metadata.annotations.workload_repo_revision}}'
destination:
name: '{{name}}'
syncPolicy:
automated:
selfHeal: true
allowEmpty: true
prune: false
retry:
limit: 100
syncOptions:
- CreateNamespace=true
- ServerSideApply=true # Big CRDs.
78 changes: 78 additions & 0 deletions argocd/iac/terraform/examples/eks/single-cluster-v2/destroy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/bin/bash

set -uo pipefail

SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
ROOTDIR="$(cd ${SCRIPTDIR}/../..; pwd )"
[[ -n "${DEBUG:-}" ]] && set -x

scale_down_karpenter_nodes() {
# Get all nodes with the label karpenter.sh/registered=true
nodes=$(kubectl get nodes -l karpenter.sh/registered=true -o jsonpath='{.items[*].metadata.name}')

# Iterate over each node
for node in $nodes; do
# Get all pods running on the current node
pods=$(kubectl get pods --all-namespaces --field-selector spec.nodeName=$node -o jsonpath='{range .items[*]}{.metadata.namespace}{" "}{.metadata.name}{"\n"}{end}')

# Iterate over each pod
while IFS= read -r pod; do
namespace=$(echo $pod | awk '{print $1}')
pod_name=$(echo $pod | awk '{print $2}')

# Get the owner references of the pod
owner_refs=$(kubectl get pod $pod_name -n $namespace -o jsonpath='{.metadata.ownerReferences[*]}')

# Check if the owner is a ReplicaSet (which is part of a deployment) or a StatefulSet and scale down
if echo $owner_refs | grep -q "ReplicaSet"; then
replicaset_name=$(kubectl get pod $pod_name -n $namespace -o jsonpath='{.metadata.ownerReferences[?(@.kind=="ReplicaSet")].name}')
deployment_name=$(kubectl get replicaset $replicaset_name -n $namespace -o jsonpath='{.metadata.ownerReferences[?(@.kind=="Deployment")].name}')
if [[ $(kubectl get deployment $deployment_name -n $namespace -o jsonpath='{.spec.replicas}') -gt 0 ]]; then
echo kubectl scale deployment $deployment_name -n $namespace --replicas=0
kubectl scale deployment $deployment_name -n $namespace --replicas=0
fi
elif echo $owner_refs | grep -q "StatefulSet"; then
statefulset_name=$(kubectl get pod $pod_name -n $namespace -o jsonpath='{.metadata.ownerReferences[?(@.kind=="StatefulSet")].name}')
if [[ $(kubectl get statefulset $statefulset_name -n $namespace -o jsonpath='{.spec.replicas}') -gt 0 ]]; then
echo kubectl scale statefulset $statefulset_name -n $namespace --replicas=0
kubectl scale statefulset $statefulset_name -n $namespace --replicas=0
fi
fi
done <<< "$pods"
done

# Loop through each node and delete it
for node in $nodes; do
echo "Deleting node: $node"
kubectl delete node $node
done
# do a final check to make sure the nodes are gone, loop sleep 60 in between checks
nodes=$(kubectl get nodes -l karpenter.sh/registered=true -o jsonpath='{.items[*].metadata.name}')
while [[ ! -z $nodes ]]; do
echo "Waiting for nodes to be deleted: $nodes"
sleep 60
nodes=$(kubectl get nodes -l karpenter.sh/registered=true -o jsonpath='{.items[*].metadata.name}')
done
sleep 60


}

# Delete the Ingress/SVC before removing the addons
TMPFILE=$(mktemp)
terraform -chdir=$SCRIPTDIR output -raw configure_kubectl > "$TMPFILE"
# check if TMPFILE contains the string "No outputs found"
if [[ ! $(cat $TMPFILE) == *"No outputs found"* ]]; then
source "$TMPFILE"
scale_down_karpenter_nodes
kubectl delete ing -A --all
# delete all the kuberneters service of type LoadBalancer, without using jq
kubectl get svc --all-namespaces -o json | grep -E '"type": "LoadBalancer"' | awk '{print "kubectl delete svc " $1 " -n " $2}' | bash
sleep 60
fi

terraform destroy -target="module.gitops_bridge_bootstrap" -auto-approve
terraform destroy -target="module.eks_blueprints_addons" -auto-approve
terraform destroy -target="module.eks" -auto-approve
terraform destroy -target="module.vpc" -auto-approve
terraform destroy -auto-approve
Loading