├── .gitignore ├── README.md ├── argo.jpg ├── v02-argocd-setting-up ├── install-using-helm-nginx-ingress │ ├── note.txt │ └── values-nginx-ingress.yml ├── install-using-helm-nodeport │ ├── note.txt │ └── values-nodePort.yml └── install-using-kubectl │ ├── install-using-kubectl.yml │ └── note.txt ├── v03-argocd-applications ├── application-directory.yml ├── application-helm.yml ├── application-using-terraform │ ├── main.tf │ ├── providers.tf │ └── variables.tf ├── directoryOfmanifests │ ├── deployment.yml │ ├── service.yml │ ├── serviceaccount.yml │ ├── sub-directory │ │ └── service.yml │ └── test-connection.yml └── helm │ └── nginx │ ├── .helmignore │ ├── Chart.yaml │ ├── custom-values.yaml │ ├── templates │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── hpa.yaml │ ├── ingress.yaml │ ├── service.yaml │ ├── serviceaccount.yaml │ └── tests │ │ └── test-connection.yaml │ └── values.yaml ├── v04-argocd-projects ├── project-manifest-examples │ ├── project-destination-restriction.yml │ ├── project-resource-blacklist.yml │ ├── project-resource-whitelist.yml │ ├── project-role.yml │ └── project-source-restriction.yml └── project-using-terraform │ ├── main.tf │ ├── providers.tf │ ├── terraform.tfvars │ └── variables.tf ├── v05-argocd-private-repositories ├── private-repos-manifests-examples │ ├── credential-template-secret.yml │ ├── https-private-repo-secret.yml │ └── ssh-private-repo-secret.yml └── private-repos-using-terraform │ ├── main.tf │ ├── providers.tf │ ├── terraform.tfvars │ └── variables.tf ├── v06-argocd-sync-policies-options ├── sync-options │ ├── application-level │ │ ├── create-namespace.yml │ │ ├── fail-on-shared-resource.yml │ │ ├── namespace-metadata.yml │ │ ├── prune-last.yml │ │ ├── replace.yml │ │ └── selective-sync.yml │ └── resource-level │ │ ├── delete.yml │ │ ├── disable-kubectl-validation.yml │ │ ├── no-prune.yml │ │ ├── prune-last.yml │ │ └── replace.yml ├── sync-policies-options-using-terraform │ ├── .terraform.lock.hcl │ ├── main.tf │ ├── providers.tf │ ├── terraform.tfvars │ └── variables.tf └── sync-policies │ ├── automated-sync.yml │ ├── prune-sync.yml │ └── selfheal-sync.yml ├── v07-argocd-sync-phases-waves ├── python_mattermost_api │ ├── Dockerfile │ ├── mattermost_api.py │ └── requirements.txt └── sync-phases-waves-manifests-examples │ ├── deployment.yml │ ├── fail-job.yml │ ├── post-job.yml │ ├── pre-job.yml │ ├── service.yml │ └── serviceaccount.yml ├── v08-argocd-add-cluster ├── add-cluster │ ├── add-cluster-using-manifest │ │ └── add-cluster.yml │ └── add-cluster-using-terraform │ │ ├── main.tf │ │ ├── providers.tf │ │ ├── terraform.tfvars │ │ └── variables.tf └── tracking-strategies │ ├── git.yml │ └── helm.yml ├── v09-argocd-applicationSet-1 ├── cluster-generator │ ├── cluster-generator-ex1.yml │ ├── cluster-generator-ex2.yml │ ├── cluster-generator-ex3.yml │ └── cluster-generator-ex4.yml ├── git-generator │ ├── cluster-config │ │ ├── pre-staging │ │ │ └── config.json │ │ └── staging │ │ │ └── config.json │ ├── directories-subtype │ │ ├── git-generator-ex1.yml │ │ └── git-generator-ex2.yml │ ├── files-subtype │ │ └── git-generator-ex1.yml │ └── resources │ │ ├── nginx-helm │ │ ├── Chart.yaml │ │ ├── custom-values.yaml │ │ ├── templates │ │ │ ├── NOTES.txt │ │ │ ├── _helpers.tpl │ │ │ ├── deployment.yaml │ │ │ ├── hpa.yaml │ │ │ ├── ingress.yaml │ │ │ ├── service.yaml │ │ │ ├── serviceaccount.yaml │ │ │ └── tests │ │ │ │ └── test-connection.yaml │ │ └── values.yaml │ │ └── nginx-manifests │ │ ├── deployment.yml │ │ ├── service.yml │ │ ├── serviceaccount.yml │ │ ├── sub-directory │ │ └── service.yml │ │ └── test-connection.yml └── list-generator │ ├── list-generator-ex1.yml │ └── list-generator-ex2.yml ├── v10-argocd-applicationSet-2 ├── matrix-generator │ ├── matrix-generator-ex1.yml │ ├── matrix-generator-ex2.yml │ └── matrix-generator-ex3.yml └── merge-generator │ └── merge-generator-ex1.yml ├── v12-argo-rollouts-blue-green ├── blue-green-app │ ├── Dockerfile │ ├── blue-green.py │ ├── requirements.txt │ └── templates │ │ ├── app-v1.html │ │ └── app-v2.html └── blue-green-manifests │ ├── ingress.yml │ └── rollout.yml ├── v13-argo-rollouts-canary ├── rolling-update-ingress.yml ├── rolling-update.yml ├── rollouts-setweight-ingress.yml ├── rollouts-setweight.yml ├── rollouts-traffic-management-ingress.yml └── rollouts-traffic-management.yml ├── v14-argo-rollouts-analysis ├── blue-green-analysis │ ├── Dockerfile │ ├── app-success-rate.sh │ ├── ingress.yml │ ├── post-promotion-analysis.yml │ ├── pre-promotion-analysis.yml │ └── rollout-with-analysis.yml └── canary-analysis │ ├── analysis-app.py │ ├── canary-analysis.yml │ ├── ingress.yml │ └── rollout-with-analysis.yml ├── v15-argo-workflows-getting-started ├── setting-up │ ├── note.txt │ └── values.yml └── template-types │ └── templates.yml ├── v16-argo-workflows-crds-and-artifacts ├── artifacts │ ├── conditional-artifacts.yml │ ├── conditional-parameters.yml │ ├── hardwired-artifacts.yml │ ├── minio-artifact-repo-cm.yml │ ├── workflow-artiafcts.yml │ ├── workflow-input-parameters.yml │ └── workflow-output-parameters.yml └── customResource-kinds │ ├── cluster-workflow-template.yml │ ├── cron-workflow.yml │ ├── workflow-ref.yml │ ├── workflow-template.yml │ └── workflow.yml ├── v17-combining-argo-tools ├── app │ ├── Dockerfile │ └── index.html ├── argo-cd │ └── argo-app.yml ├── argo-rollouts │ ├── nginx-ingress.yml │ └── nginx-rollouts.yml └── argo-workflows │ ├── build-push.yml │ ├── clone-repo.yml │ ├── update-manifest.yml │ └── workflows.yml └── v18-combining-argo-tools-part-2 ├── argo-cd └── argo-app.yml ├── argo-events ├── event-source.yml └── sensor.yml └── argo-rollouts ├── nginx-ingress.yml └── nginx-rollouts.yml /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | 8 | # Crash log files 9 | crash.log 10 | crash.*.log 11 | 12 | 13 | # Ignore override files as they are usually used to override resources locally and so 14 | # are not checked in 15 | override.tf 16 | override.tf.json 17 | *_override.tf 18 | *_override.tf.json 19 | 20 | # Include override files you do wish to add to version control using negated pattern 21 | # !example_override.tf 22 | 23 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 24 | # example: *tfplan* 25 | 26 | # Ignore CLI configuration files 27 | .terraformrc 28 | terraform.rc 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Argoproj 2 |  3 | 4 | ## Tools we are going to learn together 5 | * [Argo CD](https://github.com/argoproj/argo-cd) - Declarative GitOps Continuous Delivery 6 | * [Argo Rollouts](https://github.com/argoproj/argo-rollouts) - Progressive Delivery with support for Canary and Blue Green deployment strategies 7 | * [Argo Workflows](https://github.com/argoproj/argo-workflows) - Container-native Workflow Engine 8 | * [Argo Events](https://github.com/argoproj/argo-events) - Event-based Dependency Manager 9 | 10 | 11 | ## About the Author 12 | - **Mohammad Madanipour** 13 | - [GitHub](https://github.com/mohammadll) 14 | - [Linkedin](https://linkedin.com/in/mohammad-madanipour) 15 | 16 | 17 | ## You can also follow the videos of the Argo-Stack course on YouTube 18 | - **Argo-CD** 19 | - [Argo-CD Core Concepts](https://www.youtube.com/watch?v=T-ERIOb_3z0&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4) 20 | - [Argo-CD Setting-up](https://www.youtube.com/watch?v=pVnk9utUit8&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=2) 21 | - [Argo-CD Applications](https://www.youtube.com/watch?v=3tzMmhvD6p0&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=3) 22 | - [Argo-CD Projects](https://www.youtube.com/watch?v=VT4NTt5rUew&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=4) 23 | - [Argo-CD Private Repos](https://www.youtube.com/watch?v=SsewuwHuA08&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=5) 24 | - [Argo-CD Sync Policies And Sync Options](https://www.youtube.com/watch?v=XU08NQH11-Q&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=6) 25 | - [Argo-CD Sync Phases And Sync Waves](https://www.youtube.com/watch?v=nXx-Y3Vbn_0&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=7) 26 | - [Argo-CD Adding Cluster & Tracking Strategies](https://www.youtube.com/watch?v=dBpauFPL64A&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=8) 27 | - [Argo-CD ApplicationSet Part-1](https://www.youtube.com/watch?v=LoFazAmwWOw&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=9) 28 | - [Argo-CD ApplicationSet Part-2](https://www.youtube.com/watch?v=yT3w2iig9MI&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=10) 29 | - **Argo-Rollouts** 30 | - [Argo-Rollouts Overview & Installation](https://www.youtube.com/watch?v=hgEVcHhBwPw&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=11) 31 | - [Argo-Rollouts Blue-Green Deployment Strategy](https://www.youtube.com/watch?v=q1pMzZE8Ugw&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=12) 32 | - [Argo-Rollouts Canary Deployment Strategy](https://www.youtube.com/watch?v=MY4E8TgQ5Gs&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=13) 33 | - [Argo-Rollouts Analysis](https://www.youtube.com/watch?v=qbHv3riNN0g&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=15) 34 | - **Argo-Workflows** 35 | - [Argo-Workflows Getting-Started](https://www.youtube.com/watch?v=UgpVX5Sn5OI&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=14) 36 | - [Argo-Workflows Custom Resource Kinds & Artifacts](https://www.youtube.com/watch?v=ugB7v5WadGY&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=16) 37 | - **Final Project (Argo-CD + Argo-Rollouts + Argo-Workflows + Argo-Events)** 38 | - [CICD with Argo tools ( Part 1 )](https://www.youtube.com/watch?v=WxLqz9TyRSc&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=17) 39 | - [CICD with Argo tools ( Part 2 )](https://www.youtube.com/watch?v=ex-F_VXNYNA&list=PLYrn63eEqAzYttcyB6On1oH35O5rxgDt4&index=18) 40 | -------------------------------------------------------------------------------- /argo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devopshobbies/argocd-tutorial/9e00b5cb8aa9c164004eb4e2954986b7fc54a232/argo.jpg -------------------------------------------------------------------------------- /v02-argocd-setting-up/install-using-helm-nginx-ingress/note.txt: -------------------------------------------------------------------------------- 1 | ### Installing Argocd Helm Chart by overriding the parameters related to Ingress 2 | ### Please Note that before installing Argo, you must have nginx-ingress-controller installed on the cluster 3 | ### Also make sure to add the host used in the ingress to the /etc/hosts file 4 | 5 | ### Install Argocd Helm Chart as following: 6 | kubectl create ns argocd 7 | helm repo add argo https://argoproj.github.io/argo-helm 8 | helm install argocd argo/argo-cd -n argocd -f values-nginx-ingress.yml 9 | 10 | ### You can also use ingress with cert manager if you want -------------------------------------------------------------------------------- /v02-argocd-setting-up/install-using-helm-nginx-ingress/values-nginx-ingress.yml: -------------------------------------------------------------------------------- 1 | server: 2 | ingress: 3 | enabled: true 4 | annotations: 5 | nginx.ingress.kubernetes.io/force-ssl-redirect: "true" 6 | nginx.ingress.kubernetes.io/ssl-passthrough: "true" 7 | ingressClassName: nginx 8 | hostname: "devops.hobbies" 9 | -------------------------------------------------------------------------------- /v02-argocd-setting-up/install-using-helm-nodeport/note.txt: -------------------------------------------------------------------------------- 1 | ### Installing Argocd Helm Chart by overriding the parameters related to argocd-server service and changing it from ClusterIP type to NodePort 2 | 3 | ### Install Argocd Helm Chart as following: 4 | kubectl create ns argocd 5 | helm repo add argo https://argoproj.github.io/argo-helm 6 | helm install argocd argo/argo-cd -n argocd -f values-nodePort.yml -------------------------------------------------------------------------------- /v02-argocd-setting-up/install-using-helm-nodeport/values-nodePort.yml: -------------------------------------------------------------------------------- 1 | server: 2 | service: 3 | type: NodePort 4 | nodePortHttp: 32073 5 | nodePortHttps: 32074 -------------------------------------------------------------------------------- /v02-argocd-setting-up/install-using-kubectl/note.txt: -------------------------------------------------------------------------------- 1 | ### We have changed the type of the argocd-server service from the ClusterIP to NodePort as following: 2 | 3 | apiVersion: v1 4 | kind: Service 5 | metadata: 6 | labels: 7 | app.kubernetes.io/component: server 8 | app.kubernetes.io/name: argocd-server 9 | app.kubernetes.io/part-of: argocd 10 | name: argocd-server 11 | spec: 12 | ports: 13 | - name: http 14 | nodePort: 32073 15 | port: 80 16 | protocol: TCP 17 | targetPort: 8080 18 | - name: https 19 | nodePort: 32074 20 | port: 443 21 | protocol: TCP 22 | targetPort: 8080 23 | selector: 24 | app.kubernetes.io/name: argocd-server 25 | type: NodePort 26 | 27 | 28 | ### If you want to connect to argocd-server in an insecure manner , add the following DATA block to argocd-cmd-params-cm ConfigMap: 29 | 30 | apiVersion: v1 31 | kind: ConfigMap 32 | data: 33 | server.insecure: "true" 34 | metadata: 35 | labels: 36 | app.kubernetes.io/name: argocd-cmd-params-cm 37 | app.kubernetes.io/part-of: argocd 38 | name: argocd-cmd-params-cm -------------------------------------------------------------------------------- /v03-argocd-applications/application-directory.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: application-directory 5 | spec: 6 | destination: 7 | namespace: directory 8 | server: https://kubernetes.default.svc 9 | project: default 10 | source: 11 | # directory: 12 | # exclude: 'service.yml' 13 | # include: '{serviceaccount.yml,service.yml}' 14 | # recurse: true 15 | path: v03-argocd-applications/directoryOfmanifests 16 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 17 | targetRevision: main 18 | -------------------------------------------------------------------------------- /v03-argocd-applications/application-helm.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: application-from-scratch 5 | spec: 6 | destination: 7 | namespace: default 8 | server: https://kubernetes.default.svc 9 | project: default 10 | source: 11 | # It's possible to override helm values through different ways such as "valueFiles", "values", "valuesObject" and "parameters". 12 | # Values injections have the following order of precedence parameters > valuesObject > values > valueFiles > helm repository values.yaml Or rather 13 | # helm: 14 | # releaseName: application-from-helm 15 | # valueFiles: 16 | # - custom-values.yaml 17 | # values: | 18 | # replicaCount: 3 19 | # valuesObject: 20 | # replicaCount: 5 21 | # parameters: 22 | # - name: "replicaCount" 23 | # value: "1" 24 | path: v03-argocd-applications/helm/nginx 25 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 26 | targetRevision: main 27 | -------------------------------------------------------------------------------- /v03-argocd-applications/application-using-terraform/main.tf: -------------------------------------------------------------------------------- 1 | resource "argocd_application" "helm" { 2 | metadata { 3 | name = "helm-app-using-terraform" 4 | namespace = var.namespace 5 | labels = { 6 | test = "true" 7 | } 8 | } 9 | 10 | spec { 11 | destination { 12 | server = var.destination_server 13 | namespace = var.destination_namespace 14 | } 15 | 16 | source { 17 | repo_url = var.repo_url 18 | path = var.path 19 | target_revision = var.target_revision 20 | helm { 21 | value_files = var.values_files 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /v03-argocd-applications/application-using-terraform/providers.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | argocd = { 4 | source = "oboukili/argocd" 5 | version = "6.0.2" 6 | } 7 | } 8 | } 9 | 10 | provider "argocd" { 11 | server_addr = var.server_addr 12 | username = var.username 13 | password = var.password 14 | insecure = var.insecure 15 | } 16 | -------------------------------------------------------------------------------- /v03-argocd-applications/application-using-terraform/variables.tf: -------------------------------------------------------------------------------- 1 | variable "username" { 2 | type = string 3 | description = "Username Value" 4 | } 5 | 6 | variable "password" { 7 | type = string 8 | description = "Password Value" 9 | } 10 | 11 | variable "namespace" { 12 | type = string 13 | description = "Namespace Value" 14 | } 15 | 16 | variable "destination_namespace" { 17 | type = string 18 | description = "Destination Namespace Value" 19 | } 20 | 21 | variable "destination_server" { 22 | type = string 23 | description = "Destination Server Value" 24 | } 25 | 26 | variable "server_addr" { 27 | type = string 28 | description = "server_addr Value" 29 | } 30 | 31 | variable "repo_url" { 32 | type = string 33 | description = "Repo_url Value" 34 | } 35 | 36 | variable "path" { 37 | type = string 38 | description = "Path Value" 39 | } 40 | 41 | variable "target_revision" { 42 | type = string 43 | description = "Target_revision Value" 44 | } 45 | 46 | variable "values_files" { 47 | type = list(string) 48 | description = "Values_files Value as a list" 49 | } 50 | 51 | variable "insecure" { 52 | type = bool 53 | description = "insecure Value as a boolean" 54 | } 55 | -------------------------------------------------------------------------------- /v03-argocd-applications/directoryOfmanifests/deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nginx 5 | labels: 6 | helm.sh/chart: nginx-0.1.0 7 | app.kubernetes.io/name: nginx 8 | app.kubernetes.io/instance: nginx 9 | app.kubernetes.io/version: "1.16.0" 10 | app.kubernetes.io/managed-by: Helm 11 | spec: 12 | replicas: 1 13 | selector: 14 | matchLabels: 15 | app.kubernetes.io/name: nginx 16 | app.kubernetes.io/instance: nginx 17 | template: 18 | metadata: 19 | labels: 20 | app.kubernetes.io/name: nginx 21 | app.kubernetes.io/instance: nginx 22 | spec: 23 | serviceAccountName: nginx 24 | securityContext: 25 | {} 26 | containers: 27 | - name: nginx 28 | securityContext: 29 | {} 30 | image: "nginx:1.16.0" 31 | imagePullPolicy: IfNotPresent 32 | ports: 33 | - name: http 34 | containerPort: 80 35 | protocol: TCP 36 | livenessProbe: 37 | httpGet: 38 | path: / 39 | port: http 40 | readinessProbe: 41 | httpGet: 42 | path: / 43 | port: http 44 | resources: 45 | {} 46 | -------------------------------------------------------------------------------- /v03-argocd-applications/directoryOfmanifests/service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nginx 5 | annotations: 6 | argocd.argoproj.io/sync-options: Replace=true 7 | labels: 8 | helm.sh/chart: nginx-0.1.0 9 | app.kubernetes.io/name: nginx 10 | app.kubernetes.io/instance: nginx 11 | app.kubernetes.io/version: "1.16.0" 12 | app.kubernetes.io/managed-by: Helm 13 | spec: 14 | type: ClusterIP 15 | ports: 16 | - port: 80 17 | targetPort: http 18 | protocol: TCP 19 | name: http 20 | selector: 21 | app.kubernetes.io/name: nginx 22 | app.kubernetes.io/instance: nginx 23 | -------------------------------------------------------------------------------- /v03-argocd-applications/directoryOfmanifests/serviceaccount.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: nginx 5 | annotations: 6 | argocd.argoproj.io/sync-options: Prune=false 7 | labels: 8 | helm.sh/chart: nginx-0.1.0 9 | app.kubernetes.io/name: nginx 10 | app.kubernetes.io/instance: nginx 11 | app.kubernetes.io/version: "1.16.0" 12 | app.kubernetes.io/managed-by: Helm 13 | -------------------------------------------------------------------------------- /v03-argocd-applications/directoryOfmanifests/sub-directory/service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nginx-sub-directory 5 | # annotations: 6 | # argocd.argoproj.io/sync-options: Prune=false 7 | labels: 8 | helm.sh/chart: nginx-0.1.0 9 | app.kubernetes.io/name: nginx 10 | app.kubernetes.io/instance: nginx 11 | app.kubernetes.io/version: "1.16.0" 12 | app.kubernetes.io/managed-by: Helm 13 | spec: 14 | type: ClusterIP 15 | ports: 16 | - port: 80 17 | targetPort: http 18 | protocol: TCP 19 | name: http 20 | selector: 21 | app.kubernetes.io/name: nginx 22 | app.kubernetes.io/instance: nginx 23 | -------------------------------------------------------------------------------- /v03-argocd-applications/directoryOfmanifests/test-connection.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "nginx-test-connection" 5 | labels: 6 | helm.sh/chart: nginx-0.1.0 7 | app.kubernetes.io/name: nginx 8 | app.kubernetes.io/instance: nginx 9 | app.kubernetes.io/version: "1.16.0" 10 | app.kubernetes.io/managed-by: Helm 11 | annotations: 12 | "helm.sh/hook": test 13 | spec: 14 | containers: 15 | - name: wget 16 | image: busybox 17 | command: ['wget'] 18 | args: ['nginx:80'] 19 | restartPolicy: Never 20 | -------------------------------------------------------------------------------- /v03-argocd-applications/helm/nginx/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /v03-argocd-applications/helm/nginx/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: nginx 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "1.16.0" 25 | -------------------------------------------------------------------------------- /v03-argocd-applications/helm/nginx/custom-values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 4 2 | -------------------------------------------------------------------------------- /v03-argocd-applications/helm/nginx/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range $host := .Values.ingress.hosts }} 4 | {{- range .paths }} 5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} 6 | {{- end }} 7 | {{- end }} 8 | {{- else if contains "NodePort" .Values.service.type }} 9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "nginx.fullname" . }}) 10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 11 | echo http://$NODE_IP:$NODE_PORT 12 | {{- else if contains "LoadBalancer" .Values.service.type }} 13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 14 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "nginx.fullname" . }}' 15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "nginx.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 16 | echo http://$SERVICE_IP:{{ .Values.service.port }} 17 | {{- else if contains "ClusterIP" .Values.service.type }} 18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "nginx.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 19 | export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") 20 | echo "Visit http://127.0.0.1:8080 to use your application" 21 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT 22 | {{- end }} 23 | -------------------------------------------------------------------------------- /v03-argocd-applications/helm/nginx/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "nginx.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "nginx.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "nginx.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "nginx.labels" -}} 37 | helm.sh/chart: {{ include "nginx.chart" . }} 38 | {{ include "nginx.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "nginx.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "nginx.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "nginx.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "nginx.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /v03-argocd-applications/helm/nginx/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "nginx.fullname" . }} 5 | labels: 6 | {{- include "nginx.labels" . | nindent 4 }} 7 | spec: 8 | {{- if not .Values.autoscaling.enabled }} 9 | replicas: {{ .Values.replicaCount }} 10 | {{- end }} 11 | selector: 12 | matchLabels: 13 | {{- include "nginx.selectorLabels" . | nindent 6 }} 14 | template: 15 | metadata: 16 | {{- with .Values.podAnnotations }} 17 | annotations: 18 | {{- toYaml . | nindent 8 }} 19 | {{- end }} 20 | labels: 21 | {{- include "nginx.selectorLabels" . | nindent 8 }} 22 | spec: 23 | {{- with .Values.imagePullSecrets }} 24 | imagePullSecrets: 25 | {{- toYaml . | nindent 8 }} 26 | {{- end }} 27 | serviceAccountName: {{ include "nginx.serviceAccountName" . }} 28 | securityContext: 29 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 30 | containers: 31 | - name: {{ .Chart.Name }} 32 | securityContext: 33 | {{- toYaml .Values.securityContext | nindent 12 }} 34 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 35 | imagePullPolicy: {{ .Values.image.pullPolicy }} 36 | ports: 37 | - name: http 38 | containerPort: {{ .Values.service.port }} 39 | protocol: TCP 40 | livenessProbe: 41 | httpGet: 42 | path: / 43 | port: http 44 | readinessProbe: 45 | httpGet: 46 | path: / 47 | port: http 48 | resources: 49 | {{- toYaml .Values.resources | nindent 12 }} 50 | {{- with .Values.nodeSelector }} 51 | nodeSelector: 52 | {{- toYaml . | nindent 8 }} 53 | {{- end }} 54 | {{- with .Values.affinity }} 55 | affinity: 56 | {{- toYaml . | nindent 8 }} 57 | {{- end }} 58 | {{- with .Values.tolerations }} 59 | tolerations: 60 | {{- toYaml . | nindent 8 }} 61 | {{- end }} 62 | -------------------------------------------------------------------------------- /v03-argocd-applications/helm/nginx/templates/hpa.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.autoscaling.enabled }} 2 | apiVersion: autoscaling/v2 3 | kind: HorizontalPodAutoscaler 4 | metadata: 5 | name: {{ include "nginx.fullname" . }} 6 | labels: 7 | {{- include "nginx.labels" . | nindent 4 }} 8 | spec: 9 | scaleTargetRef: 10 | apiVersion: apps/v1 11 | kind: Deployment 12 | name: {{ include "nginx.fullname" . }} 13 | minReplicas: {{ .Values.autoscaling.minReplicas }} 14 | maxReplicas: {{ .Values.autoscaling.maxReplicas }} 15 | metrics: 16 | {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} 17 | - type: Resource 18 | resource: 19 | name: cpu 20 | target: 21 | type: Utilization 22 | averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} 23 | {{- end }} 24 | {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} 25 | - type: Resource 26 | resource: 27 | name: memory 28 | target: 29 | type: Utilization 30 | averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} 31 | {{- end }} 32 | {{- end }} 33 | -------------------------------------------------------------------------------- /v03-argocd-applications/helm/nginx/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "nginx.fullname" . -}} 3 | {{- $svcPort := .Values.service.port -}} 4 | {{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} 5 | {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} 6 | {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} 7 | {{- end }} 8 | {{- end }} 9 | {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} 10 | apiVersion: networking.k8s.io/v1 11 | {{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} 12 | apiVersion: networking.k8s.io/v1beta1 13 | {{- else -}} 14 | apiVersion: extensions/v1beta1 15 | {{- end }} 16 | kind: Ingress 17 | metadata: 18 | name: {{ $fullName }} 19 | labels: 20 | {{- include "nginx.labels" . | nindent 4 }} 21 | {{- with .Values.ingress.annotations }} 22 | annotations: 23 | {{- toYaml . | nindent 4 }} 24 | {{- end }} 25 | spec: 26 | {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} 27 | ingressClassName: {{ .Values.ingress.className }} 28 | {{- end }} 29 | {{- if .Values.ingress.tls }} 30 | tls: 31 | {{- range .Values.ingress.tls }} 32 | - hosts: 33 | {{- range .hosts }} 34 | - {{ . | quote }} 35 | {{- end }} 36 | secretName: {{ .secretName }} 37 | {{- end }} 38 | {{- end }} 39 | rules: 40 | {{- range .Values.ingress.hosts }} 41 | - host: {{ .host | quote }} 42 | http: 43 | paths: 44 | {{- range .paths }} 45 | - path: {{ .path }} 46 | {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} 47 | pathType: {{ .pathType }} 48 | {{- end }} 49 | backend: 50 | {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} 51 | service: 52 | name: {{ $fullName }} 53 | port: 54 | number: {{ $svcPort }} 55 | {{- else }} 56 | serviceName: {{ $fullName }} 57 | servicePort: {{ $svcPort }} 58 | {{- end }} 59 | {{- end }} 60 | {{- end }} 61 | {{- end }} 62 | -------------------------------------------------------------------------------- /v03-argocd-applications/helm/nginx/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "nginx.fullname" . }} 5 | labels: 6 | {{- include "nginx.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: http 12 | protocol: TCP 13 | name: http 14 | selector: 15 | {{- include "nginx.selectorLabels" . | nindent 4 }} 16 | -------------------------------------------------------------------------------- /v03-argocd-applications/helm/nginx/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "nginx.serviceAccountName" . }} 6 | labels: 7 | {{- include "nginx.labels" . | nindent 4 }} 8 | {{- with .Values.serviceAccount.annotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /v03-argocd-applications/helm/nginx/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "nginx.fullname" . }}-test-connection" 5 | labels: 6 | {{- include "nginx.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox 13 | command: ['wget'] 14 | args: ['{{ include "nginx.fullname" . }}:{{ .Values.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /v03-argocd-applications/helm/nginx/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for nginx. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 2 6 | 7 | image: 8 | repository: nginx 9 | pullPolicy: IfNotPresent 10 | # Overrides the image tag whose default is the chart appVersion. 11 | tag: "" 12 | 13 | imagePullSecrets: [] 14 | nameOverride: "" 15 | fullnameOverride: "" 16 | 17 | serviceAccount: 18 | # Specifies whether a service account should be created 19 | create: true 20 | # Annotations to add to the service account 21 | annotations: {} 22 | # The name of the service account to use. 23 | # If not set and create is true, a name is generated using the fullname template 24 | name: "" 25 | 26 | podAnnotations: {} 27 | 28 | podSecurityContext: {} 29 | # fsGroup: 2000 30 | 31 | securityContext: {} 32 | # capabilities: 33 | # drop: 34 | # - ALL 35 | # readOnlyRootFilesystem: true 36 | # runAsNonRoot: true 37 | # runAsUser: 1000 38 | 39 | service: 40 | type: ClusterIP 41 | port: 80 42 | 43 | ingress: 44 | enabled: false 45 | className: "" 46 | annotations: {} 47 | # kubernetes.io/ingress.class: nginx 48 | # kubernetes.io/tls-acme: "true" 49 | hosts: 50 | - host: chart-example.local 51 | paths: 52 | - path: / 53 | pathType: ImplementationSpecific 54 | tls: [] 55 | # - secretName: chart-example-tls 56 | # hosts: 57 | # - chart-example.local 58 | 59 | resources: {} 60 | # We usually recommend not to specify default resources and to leave this as a conscious 61 | # choice for the user. This also increases chances charts run on environments with little 62 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 63 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 64 | # limits: 65 | # cpu: 100m 66 | # memory: 128Mi 67 | # requests: 68 | # cpu: 100m 69 | # memory: 128Mi 70 | 71 | autoscaling: 72 | enabled: false 73 | minReplicas: 1 74 | maxReplicas: 100 75 | targetCPUUtilizationPercentage: 80 76 | # targetMemoryUtilizationPercentage: 80 77 | 78 | nodeSelector: {} 79 | 80 | tolerations: [] 81 | 82 | affinity: {} 83 | -------------------------------------------------------------------------------- /v04-argocd-projects/project-manifest-examples/project-destination-restriction.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: AppProject 3 | metadata: 4 | name: project-destination-restriction 5 | namespace: argocd 6 | spec: 7 | clusterResourceWhitelist: 8 | - group: '*' 9 | kind: '*' 10 | destinations: 11 | - namespace: '!dev' ## Use '!' to place namespace in BlackList, if we remove '!' the namespace will be placed in WhiteList 12 | server: '*' ## '*' means we are allowed to use any servers 13 | sourceRepos: 14 | - '*' 15 | -------------------------------------------------------------------------------- /v04-argocd-projects/project-manifest-examples/project-resource-blacklist.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: AppProject 3 | metadata: 4 | name: project-resource-blacklist 5 | namespace: argocd 6 | spec: 7 | clusterResourceWhitelist: 8 | - group: '*' ## it means we are allowed to use any kinds of clusterscoped resources 9 | kind: '*' 10 | namespaceResourceBlacklist: 11 | - group: '' 12 | kind: 'ServiceAccount' ## it means we are NOT allowd to use 'serviceaccount' namespacescoped resource 13 | destinations: 14 | - namespace: '*' 15 | server: '*' 16 | sourceRepos: 17 | - '*' 18 | -------------------------------------------------------------------------------- /v04-argocd-projects/project-manifest-examples/project-resource-whitelist.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: AppProject 3 | metadata: 4 | name: project-resource-whitelist 5 | namespace: argocd 6 | spec: 7 | clusterResourceWhitelist: 8 | - group: '*' ## it means we are allowed to use any kinds of clusterscoped resources 9 | kind: '*' 10 | namespaceResourceWhitelist: 11 | - group: '' 12 | kind: 'ServiceAccount' ## it means we are allowd to use 'serviceaccount' namespacescoped resource Only 13 | destinations: 14 | - namespace: '*' 15 | server: '*' 16 | sourceRepos: 17 | - '*' 18 | -------------------------------------------------------------------------------- /v04-argocd-projects/project-manifest-examples/project-role.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: AppProject 3 | metadata: 4 | name: project-role 5 | namespace: argocd 6 | spec: 7 | clusterResourceWhitelist: 8 | - group: '*' 9 | kind: '*' 10 | namespaceResourceWhitelist: 11 | - group: '*' 12 | kind: '*' 13 | destinations: 14 | - namespace: '*' 15 | server: '*' 16 | sourceRepos: 17 | - '*' 18 | roles: 19 | - name: read-sync 20 | description: "this role can be used for reading applications" 21 | policies: 22 | - p, proj:project-role:read-sync, applications, get, project-role/*, allow 23 | - p, proj:project-role:read-sync, applications, sync, project-role/*, allow 24 | -------------------------------------------------------------------------------- /v04-argocd-projects/project-manifest-examples/project-source-restriction.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: AppProject 3 | metadata: 4 | name: project-source-restriction 5 | namespace: argocd 6 | spec: 7 | clusterResourceWhitelist: 8 | - group: '*' 9 | kind: '*' 10 | destinations: 11 | - namespace: '*' 12 | server: '*' 13 | sourceRepos: 14 | - '!https://github.com/devopshobbies/argocd-tutorial.git' ## Use '!' to place repo in BlackList, if we remove '!' the repo will be placed in WhiteList 15 | - '*' ## '*' means we are allowed to use any repos 16 | -------------------------------------------------------------------------------- /v04-argocd-projects/project-using-terraform/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | roles_count = length(var.roles) 3 | } 4 | 5 | resource "argocd_project" "terraform-project" { 6 | metadata { 7 | name = var.project_name 8 | namespace = var.project_namespace 9 | labels = var.project_labels 10 | } 11 | 12 | spec { 13 | description = var.project_description 14 | 15 | source_namespaces = var.source_namespaces 16 | source_repos = var.source_repos 17 | 18 | dynamic "destination" { 19 | for_each = var.destinations 20 | content { 21 | server = destination.value.server 22 | namespace = destination.value.namespace 23 | } 24 | } 25 | 26 | dynamic "cluster_resource_whitelist" { 27 | for_each = var.cluster_resources_whitelist 28 | content { 29 | group = cluster_resource_whitelist.value.group 30 | kind = cluster_resource_whitelist.value.kind 31 | } 32 | } 33 | 34 | dynamic "namespace_resource_whitelist" { 35 | for_each = var.namespace_resources_whitelist 36 | content { 37 | group = namespace_resource_whitelist.value.group 38 | kind = namespace_resource_whitelist.value.kind 39 | } 40 | } 41 | 42 | dynamic "role" { 43 | for_each = var.roles 44 | content { 45 | name = role.value.name 46 | policies = role.value.policies 47 | } 48 | } 49 | } 50 | } 51 | 52 | resource "argocd_project_token" "secret" { 53 | count = local.roles_count 54 | project = var.project_name 55 | role = var.roles[count.index]["name"] 56 | depends_on = [ 57 | argocd_project.terraform-project 58 | ] 59 | } 60 | -------------------------------------------------------------------------------- /v04-argocd-projects/project-using-terraform/providers.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | argocd = { 4 | source = "oboukili/argocd" 5 | version = "6.0.2" 6 | } 7 | } 8 | } 9 | 10 | provider "argocd" { 11 | server_addr = var.server_addr 12 | username = var.username 13 | password = var.password 14 | insecure = var.insecure 15 | } 16 | -------------------------------------------------------------------------------- /v04-argocd-projects/project-using-terraform/terraform.tfvars: -------------------------------------------------------------------------------- 1 | server_addr = "localhost:32073" 2 | username = "admin" 3 | password = "O0Nk42qUhEOMK4q8" 4 | insecure = true 5 | project_name = "terraform-project" 6 | project_namespace = "argocd" 7 | project_labels = { 8 | acceptance = "true" 9 | } 10 | project_description = "this project has been created using terraform" 11 | source_namespaces = ["argocd"] 12 | source_repos = ["*"] 13 | destinations = { 14 | destination_one = { 15 | server = "*", 16 | namespace = "dev" 17 | }, 18 | destination_two = { 19 | server = "*", 20 | namespace = "prod" 21 | } 22 | } 23 | cluster_resources_whitelist = { 24 | resource_one = { 25 | group = "*" 26 | kind = "*" 27 | } 28 | } 29 | namespace_resources_whitelist = { 30 | resource_one = { 31 | group = "apps" 32 | kind = "Deployment" 33 | }, 34 | resource_two = { 35 | group = "" 36 | kind = "Service" 37 | } 38 | } 39 | roles = [ 40 | { 41 | name = "read-only" 42 | policies = [ 43 | "p, proj:terraform-project:read-only, applications, get, terraform-project/*, allow", 44 | ] 45 | } 46 | ] 47 | -------------------------------------------------------------------------------- /v04-argocd-projects/project-using-terraform/variables.tf: -------------------------------------------------------------------------------- 1 | variable "server_addr" { 2 | type = string 3 | description = "The server address" 4 | } 5 | 6 | variable "username" { 7 | type = string 8 | description = "The Username" 9 | } 10 | 11 | variable "password" { 12 | type = string 13 | description = "The Password" 14 | } 15 | 16 | variable "insecure" { 17 | type = bool 18 | description = "The Connection Insecure flag" 19 | } 20 | 21 | variable "project_name" { 22 | type = string 23 | description = "The Name of the Project" 24 | } 25 | 26 | variable "project_namespace" { 27 | type = string 28 | description = "The Namespace of the Project" 29 | } 30 | 31 | variable "project_labels" { 32 | type = map(string) 33 | description = "The Labels of the Project" 34 | } 35 | 36 | variable "project_description" { 37 | type = string 38 | description = "The Description of the Project" 39 | } 40 | 41 | variable "source_namespaces" { 42 | type = list(string) 43 | description = "The Source Namespaces of the Project" 44 | } 45 | 46 | variable "source_repos" { 47 | type = list(string) 48 | description = "The Source Repos of the Project" 49 | } 50 | 51 | variable "destinations" { 52 | type = map(object({ 53 | server = string, 54 | namespace = string 55 | })) 56 | } 57 | 58 | variable "cluster_resources_whitelist" { 59 | type = map(object({ 60 | group = string, 61 | kind = string 62 | })) 63 | } 64 | 65 | variable "namespace_resources_whitelist" { 66 | type = map(object({ 67 | group = string, 68 | kind = string 69 | })) 70 | } 71 | 72 | variable "roles" { 73 | type = list(object({ 74 | name = string, 75 | policies = list(string) 76 | })) 77 | } 78 | -------------------------------------------------------------------------------- /v05-argocd-private-repositories/private-repos-manifests-examples/credential-template-secret.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: credential-template-secret 5 | namespace: argocd 6 | labels: 7 | argocd.argoproj.io/secret-type: repo-creds 8 | stringData: 9 | type: git 10 | url: https://github.com/mohammadll 11 | username: argocd-privare-repo 12 | password: CHANGE_ME_WITH_TOKEN 13 | -------------------------------------------------------------------------------- /v05-argocd-private-repositories/private-repos-manifests-examples/https-private-repo-secret.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: https-private-repo-secret 5 | namespace: argocd 6 | labels: 7 | argocd.argoproj.io/secret-type: repository 8 | stringData: 9 | type: git 10 | url: https://github.com/mohammadll/argo-tutorial.git 11 | username: argocd-privare-repo 12 | password: CHANGE_ME_WITH_TOKEN 13 | -------------------------------------------------------------------------------- /v05-argocd-private-repositories/private-repos-manifests-examples/ssh-private-repo-secret.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: ssh-private-repo-secret 5 | namespace: argocd 6 | labels: 7 | argocd.argoproj.io/secret-type: repository 8 | stringData: 9 | type: git 10 | url: git@github.com:mohammadll/argo-tutorial.git 11 | sshPrivateKey: | 12 | -----BEGIN OPENSSH PRIVATE KEY----- 13 | ......................................... 14 | -----END OPENSSH PRIVATE KEY----- 15 | -------------------------------------------------------------------------------- /v05-argocd-private-repositories/private-repos-using-terraform/main.tf: -------------------------------------------------------------------------------- 1 | # Private Git repository 2 | resource "argocd_repository" "private" { 3 | repo = var.repo_url 4 | username = var.repo_username 5 | password = var.repo_password 6 | } 7 | -------------------------------------------------------------------------------- /v05-argocd-private-repositories/private-repos-using-terraform/providers.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | argocd = { 4 | source = "oboukili/argocd" 5 | version = "6.0.2" 6 | } 7 | } 8 | } 9 | 10 | provider "argocd" { 11 | server_addr = var.server_addr 12 | username = var.username 13 | password = var.password 14 | insecure = var.insecure 15 | } -------------------------------------------------------------------------------- /v05-argocd-private-repositories/private-repos-using-terraform/terraform.tfvars: -------------------------------------------------------------------------------- 1 | server_addr = "localhost:32073" 2 | username = "admin" 3 | password = "-TzDOP0pmtM-reCX" 4 | insecure = true 5 | repo_password = "CHANGE-ME-WITH-TOKEN" 6 | repo_username = "argocd-privare-repo" 7 | repo_url = "https://github.com/mohammadll/argo-tutorial.git" 8 | -------------------------------------------------------------------------------- /v05-argocd-private-repositories/private-repos-using-terraform/variables.tf: -------------------------------------------------------------------------------- 1 | variable "server_addr" { 2 | type = string 3 | description = "The server address" 4 | } 5 | 6 | variable "username" { 7 | type = string 8 | description = "The Username" 9 | } 10 | 11 | variable "password" { 12 | type = string 13 | description = "The Password" 14 | } 15 | 16 | variable "insecure" { 17 | type = bool 18 | description = "The Connection Insecure flag" 19 | } 20 | 21 | variable "repo_password" { 22 | type = string 23 | description = "The Password or the token of my github account" 24 | } 25 | 26 | variable "repo_username" { 27 | type = string 28 | description = "The username or the token name" 29 | } 30 | 31 | variable "repo_url" { 32 | type = string 33 | description = "The Private Repository Url" 34 | } 35 | -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-options/application-level/create-namespace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | namespace: argocd 5 | spec: 6 | destination: 7 | server: https://kubernetes.default.svc 8 | namespace: some-namespace 9 | syncPolicy: 10 | syncOptions: 11 | - CreateNamespace=true -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-options/application-level/fail-on-shared-resource.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | spec: 4 | syncPolicy: 5 | syncOptions: 6 | - FailOnSharedResource=true -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-options/application-level/namespace-metadata.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | namespace: test 5 | spec: 6 | syncPolicy: 7 | managedNamespaceMetadata: 8 | labels: # The labels to set on the application namespace 9 | any: label 10 | you: like 11 | annotations: # The annotations to set on the application namespace 12 | the: same 13 | applies: for 14 | annotations: on-the-namespace 15 | syncOptions: 16 | - CreateNamespace=true -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-options/application-level/prune-last.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | spec: 4 | syncPolicy: 5 | syncOptions: 6 | - PruneLast=true -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-options/application-level/replace.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | spec: 4 | syncPolicy: 5 | syncOptions: 6 | - Replace=true -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-options/application-level/selective-sync.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | spec: 4 | syncPolicy: 5 | syncOptions: 6 | - ApplyOutOfSyncOnly=true -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-options/resource-level/delete.yml: -------------------------------------------------------------------------------- 1 | metadata: 2 | annotations: 3 | argocd.argoproj.io/sync-options: Delete=false 4 | -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-options/resource-level/disable-kubectl-validation.yml: -------------------------------------------------------------------------------- 1 | metadata: 2 | annotations: 3 | argocd.argoproj.io/sync-options: Validate=false -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-options/resource-level/no-prune.yml: -------------------------------------------------------------------------------- 1 | metadata: 2 | annotations: 3 | argocd.argoproj.io/sync-options: Prune=false -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-options/resource-level/prune-last.yml: -------------------------------------------------------------------------------- 1 | metadata: 2 | annotations: 3 | argocd.argoproj.io/sync-options: PruneLast=true -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-options/resource-level/replace.yml: -------------------------------------------------------------------------------- 1 | metadata: 2 | annotations: 3 | argocd.argoproj.io/sync-options: Replace=true -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-policies-options-using-terraform/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "terraform init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.terraform.io/oboukili/argocd" { 5 | version = "6.0.2" 6 | constraints = "6.0.2" 7 | hashes = [ 8 | "h1:wyeXBDZkKqdnj/8luX78jI1DdnCOb3R3FNAx6vHG+6Y=", 9 | "zh:1e9be24a93d1f0739be7dba490c9a12226e68dfcf9f10ac132ef74b28d53f3e6", 10 | "zh:26fb94f3d70bb5b7416863af2eb38867fee04cccbf4b9989e4c45e031e9176e2", 11 | "zh:730dfdf3d671bf94bf6e7c5b7095e02fdd61f37b18cc2efbaec165db31ed9526", 12 | "zh:74bacd85536d5c70b19a2f5e5d9504ce57fd48ac33a89fab0d5ad0b08896f5a3", 13 | "zh:77abd7cf8484cc53942b20ec902e6600b74f4108b76e8aaf6dc5c8e2cfbbae60", 14 | "zh:9784c1cd03d7de8bb8cb9c851fbb5371f7b2db932c9b1438c75fd9e0fe7ae884", 15 | "zh:a430b8974bcfd92f10313a39423b1f5c313082576f2638d2e1c035165d17b086", 16 | "zh:d7189c67872ad6826702806c3a894d5e972659667f1a6c7579fe50afebc3c314", 17 | "zh:fb7ab84c065941297a98aba2b0222e039eeafabf794efc4ef2a18a96d1f7705b", 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-policies-options-using-terraform/main.tf: -------------------------------------------------------------------------------- 1 | resource "argocd_application" "application" { 2 | metadata { 3 | name = "sync-policy-options-using-terraform" 4 | namespace = var.namespace 5 | labels = { 6 | using_sync_policy_options = "true" 7 | } 8 | } 9 | 10 | spec { 11 | destination { 12 | server = var.destination_server 13 | namespace = var.destination_namespace 14 | } 15 | 16 | source { 17 | repo_url = var.repo_url 18 | path = var.path 19 | target_revision = var.target_revision 20 | } 21 | sync_policy { 22 | managed_namespace_metadata { 23 | labels = var.namespace_metadata_labels 24 | } 25 | automated { 26 | prune = var.prune_enabled 27 | self_heal = var.selfheal_enabled 28 | } 29 | sync_options = var.sync_options 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-policies-options-using-terraform/providers.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | argocd = { 4 | source = "oboukili/argocd" 5 | version = "6.0.2" 6 | } 7 | } 8 | } 9 | 10 | provider "argocd" { 11 | server_addr = var.server_addr 12 | username = var.username 13 | password = var.password 14 | insecure = var.insecure 15 | } -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-policies-options-using-terraform/terraform.tfvars: -------------------------------------------------------------------------------- 1 | username = "admin" 2 | password = "GOeR1fjOnQRDFfHp" 3 | namespace = "argocd" 4 | destination_namespace = "sync-policy-options" 5 | destination_server = "https://kubernetes.default.svc" 6 | server_addr = "localhost:32073" 7 | insecure = true 8 | repo_url = "https://github.com/devopshobbies/argocd-tutorial.git" 9 | path = "v03-argocd-applications/directoryOfmanifests" 10 | target_revision = "main" 11 | prune_enabled = true 12 | selfheal_enabled = true 13 | sync_options = ["CreateNamespace=true", "FailOnSharedResource=true"] 14 | namespace_metadata_labels = { 15 | created_by = "Terraform" 16 | Course_creator = "Mohammad" 17 | } -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-policies-options-using-terraform/variables.tf: -------------------------------------------------------------------------------- 1 | variable "username" { 2 | type = string 3 | description = "Username Value" 4 | } 5 | 6 | variable "password" { 7 | type = string 8 | description = "Password Value" 9 | } 10 | 11 | variable "namespace" { 12 | type = string 13 | description = "Namespace Value" 14 | } 15 | 16 | variable "destination_namespace" { 17 | type = string 18 | description = "Destination Namespace Value" 19 | } 20 | 21 | variable "destination_server" { 22 | type = string 23 | description = "Destination Server Value" 24 | } 25 | 26 | variable "server_addr" { 27 | type = string 28 | description = "server_addr Value" 29 | } 30 | 31 | variable "repo_url" { 32 | type = string 33 | description = "Repo_url Value" 34 | } 35 | 36 | variable "path" { 37 | type = string 38 | description = "Path Value" 39 | } 40 | 41 | variable "target_revision" { 42 | type = string 43 | description = "Target_revision Value" 44 | } 45 | 46 | variable "insecure" { 47 | type = bool 48 | description = "insecure Value as a boolean" 49 | } 50 | 51 | variable "prune_enabled" { 52 | type = bool 53 | description = "Auto-prune Value as a boolean" 54 | } 55 | 56 | variable "selfheal_enabled" { 57 | type = bool 58 | description = "Auto-selfheal Value as a boolean" 59 | } 60 | 61 | variable "sync_options" { 62 | type = list(string) 63 | description = "List of sync options as a list of strings" 64 | } 65 | 66 | variable "namespace_metadata_labels" { 67 | type = map(string) 68 | description = "Map of namespace metadata labels as a map of strings" 69 | } -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-policies/automated-sync.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: automated-application 5 | spec: 6 | destination: 7 | namespace: automated-sync 8 | server: https://kubernetes.default.svc 9 | project: default 10 | source: 11 | path: v03-argocd-applications/directoryOfmanifests 12 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 13 | targetRevision: main 14 | syncPolicy: 15 | automated: {} 16 | -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-policies/prune-sync.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: prune-application 5 | spec: 6 | destination: 7 | namespace: prune-sync 8 | server: https://kubernetes.default.svc 9 | project: default 10 | source: 11 | path: v03-argocd-applications/directoryOfmanifests 12 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 13 | targetRevision: main 14 | syncPolicy: 15 | automated: 16 | prune: true 17 | -------------------------------------------------------------------------------- /v06-argocd-sync-policies-options/sync-policies/selfheal-sync.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: selfheal-application 5 | spec: 6 | destination: 7 | namespace: selfheal-sync 8 | server: https://kubernetes.default.svc 9 | project: default 10 | source: 11 | path: v03-argocd-applications/directoryOfmanifests 12 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 13 | targetRevision: main 14 | syncPolicy: 15 | automated: 16 | selfHeal: true 17 | -------------------------------------------------------------------------------- /v07-argocd-sync-phases-waves/python_mattermost_api/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8-slim-buster 2 | WORKDIR /devops-hobbies 3 | COPY requirements.txt . 4 | RUN pip3 install -r requirements.txt 5 | COPY mattermost_api.py . 6 | -------------------------------------------------------------------------------- /v07-argocd-sync-phases-waves/python_mattermost_api/mattermost_api.py: -------------------------------------------------------------------------------- 1 | from mattermostdriver import Driver 2 | from os import environ 3 | import json 4 | 5 | server = Driver({ 6 | 'url': environ['url'], 7 | 'token': environ['token'], 8 | 'scheme': environ['scheme'], 9 | 'port': int(environ['port']) 10 | }) 11 | 12 | server.login() 13 | 14 | channel_name = environ['channel_name'] 15 | team_name = environ['team_name'] 16 | 17 | channel_id = server.channels.get_channel_by_name_and_team_name(team_name, channel_name)['id'] 18 | 19 | server.posts.create_post(options = { 20 | 'channel_id': channel_id, 21 | 'message': environ['message'] 22 | }) 23 | -------------------------------------------------------------------------------- /v07-argocd-sync-phases-waves/python_mattermost_api/requirements.txt: -------------------------------------------------------------------------------- 1 | certifi==2023.7.22 2 | charset-normalizer==3.2.0 3 | idna==3.4 4 | mattermostdriver==7.3.2 5 | requests==2.31.0 6 | urllib3==2.0.4 7 | websockets==11.0.3 -------------------------------------------------------------------------------- /v07-argocd-sync-phases-waves/sync-phases-waves-manifests-examples/deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nginx 5 | labels: 6 | helm.sh/chart: nginx-0.1.0 7 | app.kubernetes.io/name: nginx 8 | app.kubernetes.io/instance: nginx 9 | app.kubernetes.io/version: "1.16.0" 10 | app.kubernetes.io/managed-by: Helm 11 | spec: 12 | replicas: 1 13 | selector: 14 | matchLabels: 15 | app.kubernetes.io/name: nginx 16 | app.kubernetes.io/instance: nginx 17 | template: 18 | metadata: 19 | labels: 20 | app.kubernetes.io/name: nginx 21 | app.kubernetes.io/instance: nginx 22 | spec: 23 | serviceAccountName: nginx 24 | securityContext: 25 | {} 26 | containers: 27 | - name: nginx 28 | securityContext: 29 | {} 30 | image: "nginx:1.16.0" 31 | imagePullPolicy: IfNotPresent 32 | ports: 33 | - name: http 34 | containerPort: 80 35 | protocol: TCP 36 | livenessProbe: 37 | httpGet: 38 | path: / 39 | port: http 40 | readinessProbe: 41 | httpGet: 42 | path: / 43 | port: http 44 | resources: 45 | {} 46 | -------------------------------------------------------------------------------- /v07-argocd-sync-phases-waves/sync-phases-waves-manifests-examples/fail-job.yml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: mattermost-post-job-failure 5 | annotations: 6 | argocd.argoproj.io/hook: SyncFail 7 | spec: 8 | template: 9 | spec: 10 | containers: 11 | - name: mattermost-failure 12 | image: mattermost:final 13 | command: [ "python3", "mattermost_api.py"] 14 | env: 15 | - name: message 16 | value: "MESSAGE FROM ARGOCD: The last sync is: *** Sync Failed ***" 17 | - name: url 18 | value: "mattermost.local" 19 | - name: token 20 | value: "1mh8r35js7dhpcswb4mpnkwpcw" 21 | - name: scheme 22 | value: "http" 23 | - name: port 24 | value: "8065" 25 | - name: channel_name 26 | value: "argocd-course" 27 | - name: team_name 28 | value: "DevOps-Hobbies" 29 | restartPolicy: Never 30 | backoffLimit: 0 31 | -------------------------------------------------------------------------------- /v07-argocd-sync-phases-waves/sync-phases-waves-manifests-examples/post-job.yml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: mattermost-post-job-success 5 | annotations: 6 | argocd.argoproj.io/hook: PostSync 7 | spec: 8 | template: 9 | spec: 10 | containers: 11 | - name: mattermost-success 12 | image: mattermost:final 13 | command: [ "python3", "mattermost_api.py"] 14 | env: 15 | - name: message 16 | value: "MESSAGE FROM ARGOCD: The last sync is: *** Sync OK ***" 17 | - name: url 18 | value: "mattermost.local" 19 | - name: token 20 | value: "1mh8r35js7dhpcswb4mpnkwpcw" 21 | - name: scheme 22 | value: "http" 23 | - name: port 24 | value: "8065" 25 | - name: channel_name 26 | value: "argocd-course" 27 | - name: team_name 28 | value: "DevOps-Hobbies" 29 | restartPolicy: Never 30 | backoffLimit: 0 31 | -------------------------------------------------------------------------------- /v07-argocd-sync-phases-waves/sync-phases-waves-manifests-examples/pre-job.yml: -------------------------------------------------------------------------------- 1 | apiVersion: batch/v1 2 | kind: Job 3 | metadata: 4 | name: health-check-pre-job 5 | annotations: 6 | argocd.argoproj.io/hook: PreSync 7 | argocd.argoproj.io/hook-delete-policy: HookFailed 8 | spec: 9 | template: 10 | spec: 11 | containers: 12 | - name: health-check 13 | image: curlimages/curl 14 | command: ["/bin/sh", "-c"] 15 | args: ["if curl -s http://myapp.local:5000 | grep -qi 'running'; then echo 'Demo Application is up and Running'; exit 0; else echo 'Demo Application is NOT accessible'; exit 1; fi"] 16 | restartPolicy: Never 17 | backoffLimit: 0 18 | -------------------------------------------------------------------------------- /v07-argocd-sync-phases-waves/sync-phases-waves-manifests-examples/service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nginx 5 | annotations: 6 | argocd.argoproj.io/sync-wave: "-2" 7 | labels: 8 | helm.sh/chart: nginx-0.1.0 9 | app.kubernetes.io/name: nginx 10 | app.kubernetes.io/instance: nginx 11 | app.kubernetes.io/version: "1.16.0" 12 | app.kubernetes.io/managed-by: Helm 13 | spec: 14 | type: ClusterIP 15 | ports: 16 | - port: 80 17 | targetPort: http 18 | protocol: TCP 19 | name: http 20 | selector: 21 | app.kubernetes.io/name: nginx 22 | app.kubernetes.io/instance: nginx 23 | -------------------------------------------------------------------------------- /v07-argocd-sync-phases-waves/sync-phases-waves-manifests-examples/serviceaccount.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: nginx 5 | annotations: 6 | argocd.argoproj.io/sync-wave: "-1" 7 | labels: 8 | helm.sh/chart: nginx-0.1.0 9 | app.kubernetes.io/name: nginx 10 | app.kubernetes.io/instance: nginx 11 | app.kubernetes.io/version: "1.16.0" 12 | app.kubernetes.io/managed-by: Helm 13 | -------------------------------------------------------------------------------- /v08-argocd-add-cluster/add-cluster/add-cluster-using-manifest/add-cluster.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: external 5 | labels: 6 | argocd.argoproj.io/secret-type: cluster 7 | type: Opaque 8 | stringData: 9 | name: external 10 | server: API_SERVER_ADDRESS 11 | config: | 12 | { 13 | "bearerToken": "SERVICE_ACCOUNT_TOKEN", 14 | "tlsClientConfig": { 15 | "insecure": false, 16 | "caData": "BASE64 ENCODED CERTIFICATE" 17 | } 18 | } -------------------------------------------------------------------------------- /v08-argocd-add-cluster/add-cluster/add-cluster-using-terraform/main.tf: -------------------------------------------------------------------------------- 1 | resource "kubernetes_service_account" "argocd_manager_sa" { 2 | metadata { 3 | name = var.sa_name 4 | namespace = var.sa_namespace 5 | } 6 | } 7 | 8 | resource "kubernetes_secret" "argocd_manager_secret" { 9 | metadata { 10 | name = var.argocd-manager-secret 11 | annotations = { 12 | "kubernetes.io/service-account.name" = "${kubernetes_service_account.argocd_manager_sa.metadata.0.name}" 13 | } 14 | } 15 | type = "kubernetes.io/service-account-token" 16 | } 17 | 18 | resource "kubernetes_cluster_role_binding" "argocd_manager_binding" { 19 | metadata { 20 | name = var.argocd-manager-binding 21 | } 22 | 23 | role_ref { 24 | api_group = "rbac.authorization.k8s.io" 25 | kind = "ClusterRole" 26 | name = "cluster-admin" 27 | } 28 | 29 | subject { 30 | kind = "ServiceAccount" 31 | name = kubernetes_service_account.argocd_manager_sa.metadata.0.name 32 | namespace = kubernetes_service_account.argocd_manager_sa.metadata.0.namespace 33 | } 34 | } 35 | 36 | data "kubernetes_secret" "argocd_manager_secret" { 37 | metadata { 38 | name = kubernetes_secret.argocd_manager_secret.metadata.0.name 39 | } 40 | } 41 | 42 | resource "argocd_cluster" "new_cluster" { 43 | provider = argocd.argocd_server 44 | server = var.new_cluster_server_addr 45 | 46 | config { 47 | bearer_token = "${lookup(data.kubernetes_secret.argocd_manager_secret.data, "token")}" 48 | 49 | tls_client_config { 50 | ca_data = "${lookup(data.kubernetes_secret.argocd_manager_secret.data, "ca.crt")}" 51 | insecure = false 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /v08-argocd-add-cluster/add-cluster/add-cluster-using-terraform/providers.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | kubernetes = { 4 | source = "hashicorp/kubernetes" 5 | version = "2.23.0" 6 | } 7 | argocd = { 8 | source = "oboukili/argocd" 9 | version = "6.0.3" 10 | } 11 | } 12 | } 13 | 14 | provider "kubernetes" { 15 | config_path = var.config_path 16 | config_context = var.config_context 17 | } 18 | 19 | provider "argocd" { 20 | alias = "argocd_server" 21 | server_addr = var.server_addr 22 | username = var.username 23 | password = var.password 24 | insecure = var.insecure 25 | } -------------------------------------------------------------------------------- /v08-argocd-add-cluster/add-cluster/add-cluster-using-terraform/terraform.tfvars: -------------------------------------------------------------------------------- 1 | server_addr = "localhost:32073" 2 | username = "admin" 3 | password = "vGiZPEnfe9wEToPc" 4 | insecure = true 5 | sa_name = "argocd-manager-sa" 6 | sa_namespace = "default" 7 | config_path = "~/.kube/config" 8 | config_context = "new-cluster-context" 9 | argocd-manager-binding = "argocd-manager-binding" 10 | argocd-manager-secret = "argocd-manager-secret" 11 | argocd_secret_cluster = "argocd-secret-cluster" 12 | secret_labels = { 13 | "argocd.argoproj.io/secret-type" = "cluster" 14 | } 15 | new_cluster = "external" 16 | new_cluster_server_addr = "https://192.168.64.93:6443" -------------------------------------------------------------------------------- /v08-argocd-add-cluster/add-cluster/add-cluster-using-terraform/variables.tf: -------------------------------------------------------------------------------- 1 | variable "server_addr" { 2 | type = string 3 | description = "The server address" 4 | } 5 | 6 | variable "username" { 7 | type = string 8 | description = "The Username" 9 | } 10 | 11 | variable "password" { 12 | type = string 13 | description = "The Password" 14 | } 15 | 16 | variable "insecure" { 17 | type = bool 18 | description = "The Connection Insecure flag" 19 | } 20 | 21 | variable "sa_name" { 22 | type = string 23 | description = "The name of argocd serviceaccount" 24 | } 25 | 26 | variable "sa_namespace" { 27 | type = string 28 | description = "The namespace of argocd serviceaccount" 29 | } 30 | 31 | variable "config_path" { 32 | type = string 33 | description = "The path of kube config" 34 | } 35 | 36 | variable "config_context" { 37 | type = string 38 | description = "The context in kube config" 39 | } 40 | 41 | variable "argocd-manager-binding" { 42 | type = string 43 | description = "The name of argocd manager clusterrole binding" 44 | } 45 | 46 | variable "argocd-manager-secret" { 47 | type = string 48 | description = "The name of argocd manager secret" 49 | } 50 | 51 | variable "argocd_secret_cluster" { 52 | type = string 53 | description = "The name of argocd secret cluster" 54 | } 55 | 56 | variable "secret_labels" { 57 | type = map(string) 58 | description = "The Labels of argocd manager secret" 59 | } 60 | 61 | variable "new_cluster" { 62 | type = string 63 | description = "The name of new cluster" 64 | } 65 | 66 | variable "new_cluster_server_addr" { 67 | type = string 68 | description = "The name of new cluster server address" 69 | } -------------------------------------------------------------------------------- /v08-argocd-add-cluster/tracking-strategies/git.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: git-tracking-strategies 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: git-tracking-strategies 9 | name: in-cluster 10 | project: default 11 | source: 12 | path: v03-argocd-applications/directoryOfmanifests 13 | repoURL: "https://github.com/devopshobbies/argocd-tutorial.git" 14 | targetRevision: # HEAD/Branch tracking ex: HEAD/main || tag tracking ex: v1 || commit pinning ex: 9814933 15 | syncPolicy: 16 | syncOptions: 17 | - CreateNamespace=true 18 | automated: {} 19 | -------------------------------------------------------------------------------- /v08-argocd-add-cluster/tracking-strategies/helm.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: helm-tracking-strategies 5 | namespace: argocd 6 | spec: 7 | project: default 8 | source: 9 | chart: sealed-secrets 10 | repoURL: https://bitnami-labs.github.io/sealed-secrets 11 | targetRevision: # use the version number ex: 1.16.1 || use a range ex: 1.* or 1.2.* or >=1.2.0 <1.3.0 || use the latest version ex: '*' 12 | helm: 13 | releaseName: sealed-secrets 14 | destination: 15 | server: "https://kubernetes.default.svc" 16 | namespace: helm-tracking-strategies 17 | syncPolicy: 18 | syncOptions: 19 | - CreateNamespace=true 20 | automated: {} 21 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/cluster-generator/cluster-generator-ex1.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: cluster-generator-ex1 5 | namespace: argocd 6 | spec: 7 | generators: 8 | - clusters: {} 9 | template: 10 | metadata: 11 | name: '{{name}}-application' 12 | spec: 13 | project: "default" 14 | source: 15 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 16 | targetRevision: main 17 | path: v03-argocd-applications/helm/nginx 18 | destination: 19 | server: '{{server}}' 20 | namespace: cluster-generator 21 | syncPolicy: 22 | automated: {} 23 | syncOptions: 24 | - CreateNamespace=true -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/cluster-generator/cluster-generator-ex2.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: cluster-generator-ex2 5 | namespace: argocd 6 | spec: 7 | generators: 8 | - clusters: 9 | selector: 10 | matchLabels: 11 | argocd.argoproj.io/secret-type: cluster 12 | environment: staging 13 | template: 14 | metadata: 15 | name: '{{name}}-application' 16 | spec: 17 | project: "default" 18 | source: 19 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 20 | targetRevision: main 21 | path: v03-argocd-applications/helm/nginx 22 | destination: 23 | server: '{{server}}' 24 | namespace: cluster-generator 25 | syncPolicy: 26 | automated: {} 27 | syncOptions: 28 | - CreateNamespace=true -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/cluster-generator/cluster-generator-ex3.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: cluster-generator-ex3 5 | namespace: argocd 6 | spec: 7 | generators: 8 | - clusters: 9 | selector: 10 | matchLabels: 11 | environment: staging 12 | values: 13 | path: helm/nginx 14 | namespace: staging-ns 15 | - clusters: 16 | selector: 17 | matchLabels: 18 | environment: pre-staging 19 | values: 20 | path: directoryOfmanifests 21 | namespace: pre-staging-ns 22 | template: 23 | metadata: 24 | name: '{{name}}-application' 25 | spec: 26 | project: "default" 27 | source: 28 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 29 | targetRevision: main 30 | path: v03-argocd-applications/{{values.path}} 31 | destination: 32 | server: '{{server}}' 33 | namespace: '{{values.namespace}}' 34 | syncPolicy: 35 | automated: {} 36 | syncOptions: 37 | - CreateNamespace=true -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/cluster-generator/cluster-generator-ex4.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: cluster-generator 5 | namespace: argocd 6 | spec: 7 | generators: 8 | - clusters: 9 | selector: 10 | matchExpressions: 11 | - key: argocd.argoproj.io/kubernetes-version # the label argocd.argoproj.io/auto-label-cluster-info needs to be set to true on the cluster secret. 12 | operator: In 13 | values: 14 | - "1.28" 15 | - "1.31" 16 | template: 17 | metadata: 18 | name: '{{name}}-application' 19 | spec: 20 | project: "default" 21 | source: 22 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 23 | targetRevision: main 24 | path: v03-argocd-applications/helm/nginx 25 | destination: 26 | server: '{{server}}' 27 | namespace: prod 28 | syncPolicy: 29 | automated: {} 30 | syncOptions: 31 | - CreateNamespace=true 32 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/cluster-config/pre-staging/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "cluster": { 3 | "owner": "mohammad", 4 | "name": "pre-staging", 5 | "path": "v03-argocd-applications/directoryOfmanifests", 6 | "source_type": "directoryOfManifests", 7 | "address": "https://kubernetes.default.svc", 8 | "namespace": "pre-staging-ns" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/cluster-config/staging/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "cluster": { 3 | "owner": "mohammad", 4 | "name": "staging", 5 | "path": "v03-argocd-applications/helm/nginx", 6 | "source_type": "helm", 7 | "address": "https://192.168.226.93:6443", 8 | "namespace": "staging-ns" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/directories-subtype/git-generator-ex1.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: git-directories-generator-ex1 5 | namespace: argocd 6 | spec: 7 | generators: 8 | - git: 9 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 10 | revision: main 11 | directories: 12 | - path: v09-argocd-applicationSet-1/git-generator/resources/* 13 | template: 14 | metadata: 15 | name: '{{path.basename}}-application' 16 | spec: 17 | project: default 18 | source: 19 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 20 | targetRevision: main 21 | path: '{{path}}' 22 | destination: 23 | server: https://kubernetes.default.svc 24 | namespace: '{{path.basename}}-ns' 25 | syncPolicy: 26 | automated: {} 27 | syncOptions: 28 | - CreateNamespace=true 29 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/directories-subtype/git-generator-ex2.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: git-directories-generator-ex2 5 | namespace: argocd 6 | spec: 7 | generators: 8 | - git: 9 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 10 | revision: main 11 | directories: 12 | - path: v09-argocd-applicationSet-1/git-generator/resources/* 13 | - path: v09-argocd-applicationSet-1/git-generator/resources/nginx-manifests 14 | exclude: true 15 | template: 16 | metadata: 17 | name: '{{path.basename}}-application' 18 | spec: 19 | project: default 20 | source: 21 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 22 | targetRevision: main 23 | path: '{{path}}' 24 | destination: 25 | server: https://kubernetes.default.svc 26 | namespace: '{{path.basename}}-ns' 27 | syncPolicy: 28 | automated: {} 29 | syncOptions: 30 | - CreateNamespace=true 31 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/files-subtype/git-generator-ex1.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: git-files-generator-ex1 5 | namespace: argocd 6 | spec: 7 | generators: 8 | - git: 9 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 10 | revision: main 11 | files: 12 | - path: v09-argocd-applicationSet-1/git-generator/cluster-config/**/config.json 13 | template: 14 | metadata: 15 | name: '{{cluster.name}}-application' 16 | spec: 17 | project: default 18 | source: 19 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 20 | targetRevision: main 21 | path: '{{cluster.path}}' 22 | destination: 23 | server: '{{cluster.address}}' 24 | namespace: '{{cluster.namespace}}' 25 | syncPolicy: 26 | automated: {} 27 | syncOptions: 28 | - CreateNamespace=true 29 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-helm/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: nginx 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "1.16.0" 25 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-helm/custom-values.yaml: -------------------------------------------------------------------------------- 1 | replicaCount: 4 2 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-helm/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range $host := .Values.ingress.hosts }} 4 | {{- range .paths }} 5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} 6 | {{- end }} 7 | {{- end }} 8 | {{- else if contains "NodePort" .Values.service.type }} 9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "nginx.fullname" . }}) 10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 11 | echo http://$NODE_IP:$NODE_PORT 12 | {{- else if contains "LoadBalancer" .Values.service.type }} 13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 14 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "nginx.fullname" . }}' 15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "nginx.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 16 | echo http://$SERVICE_IP:{{ .Values.service.port }} 17 | {{- else if contains "ClusterIP" .Values.service.type }} 18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "nginx.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 19 | export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") 20 | echo "Visit http://127.0.0.1:8080 to use your application" 21 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT 22 | {{- end }} 23 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-helm/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "nginx.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "nginx.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "nginx.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "nginx.labels" -}} 37 | helm.sh/chart: {{ include "nginx.chart" . }} 38 | {{ include "nginx.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "nginx.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "nginx.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "nginx.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "nginx.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-helm/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "nginx.fullname" . }} 5 | labels: 6 | {{- include "nginx.labels" . | nindent 4 }} 7 | spec: 8 | {{- if not .Values.autoscaling.enabled }} 9 | replicas: {{ .Values.replicaCount }} 10 | {{- end }} 11 | selector: 12 | matchLabels: 13 | {{- include "nginx.selectorLabels" . | nindent 6 }} 14 | template: 15 | metadata: 16 | {{- with .Values.podAnnotations }} 17 | annotations: 18 | {{- toYaml . | nindent 8 }} 19 | {{- end }} 20 | labels: 21 | {{- include "nginx.selectorLabels" . | nindent 8 }} 22 | spec: 23 | {{- with .Values.imagePullSecrets }} 24 | imagePullSecrets: 25 | {{- toYaml . | nindent 8 }} 26 | {{- end }} 27 | serviceAccountName: {{ include "nginx.serviceAccountName" . }} 28 | securityContext: 29 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 30 | containers: 31 | - name: {{ .Chart.Name }} 32 | securityContext: 33 | {{- toYaml .Values.securityContext | nindent 12 }} 34 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 35 | imagePullPolicy: {{ .Values.image.pullPolicy }} 36 | ports: 37 | - name: http 38 | containerPort: {{ .Values.service.port }} 39 | protocol: TCP 40 | livenessProbe: 41 | httpGet: 42 | path: / 43 | port: http 44 | readinessProbe: 45 | httpGet: 46 | path: / 47 | port: http 48 | resources: 49 | {{- toYaml .Values.resources | nindent 12 }} 50 | {{- with .Values.nodeSelector }} 51 | nodeSelector: 52 | {{- toYaml . | nindent 8 }} 53 | {{- end }} 54 | {{- with .Values.affinity }} 55 | affinity: 56 | {{- toYaml . | nindent 8 }} 57 | {{- end }} 58 | {{- with .Values.tolerations }} 59 | tolerations: 60 | {{- toYaml . | nindent 8 }} 61 | {{- end }} 62 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-helm/templates/hpa.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.autoscaling.enabled }} 2 | apiVersion: autoscaling/v2 3 | kind: HorizontalPodAutoscaler 4 | metadata: 5 | name: {{ include "nginx.fullname" . }} 6 | labels: 7 | {{- include "nginx.labels" . | nindent 4 }} 8 | spec: 9 | scaleTargetRef: 10 | apiVersion: apps/v1 11 | kind: Deployment 12 | name: {{ include "nginx.fullname" . }} 13 | minReplicas: {{ .Values.autoscaling.minReplicas }} 14 | maxReplicas: {{ .Values.autoscaling.maxReplicas }} 15 | metrics: 16 | {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} 17 | - type: Resource 18 | resource: 19 | name: cpu 20 | target: 21 | type: Utilization 22 | averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} 23 | {{- end }} 24 | {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} 25 | - type: Resource 26 | resource: 27 | name: memory 28 | target: 29 | type: Utilization 30 | averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} 31 | {{- end }} 32 | {{- end }} 33 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-helm/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "nginx.fullname" . -}} 3 | {{- $svcPort := .Values.service.port -}} 4 | {{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} 5 | {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} 6 | {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} 7 | {{- end }} 8 | {{- end }} 9 | {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} 10 | apiVersion: networking.k8s.io/v1 11 | {{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} 12 | apiVersion: networking.k8s.io/v1beta1 13 | {{- else -}} 14 | apiVersion: extensions/v1beta1 15 | {{- end }} 16 | kind: Ingress 17 | metadata: 18 | name: {{ $fullName }} 19 | labels: 20 | {{- include "nginx.labels" . | nindent 4 }} 21 | {{- with .Values.ingress.annotations }} 22 | annotations: 23 | {{- toYaml . | nindent 4 }} 24 | {{- end }} 25 | spec: 26 | {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} 27 | ingressClassName: {{ .Values.ingress.className }} 28 | {{- end }} 29 | {{- if .Values.ingress.tls }} 30 | tls: 31 | {{- range .Values.ingress.tls }} 32 | - hosts: 33 | {{- range .hosts }} 34 | - {{ . | quote }} 35 | {{- end }} 36 | secretName: {{ .secretName }} 37 | {{- end }} 38 | {{- end }} 39 | rules: 40 | {{- range .Values.ingress.hosts }} 41 | - host: {{ .host | quote }} 42 | http: 43 | paths: 44 | {{- range .paths }} 45 | - path: {{ .path }} 46 | {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} 47 | pathType: {{ .pathType }} 48 | {{- end }} 49 | backend: 50 | {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} 51 | service: 52 | name: {{ $fullName }} 53 | port: 54 | number: {{ $svcPort }} 55 | {{- else }} 56 | serviceName: {{ $fullName }} 57 | servicePort: {{ $svcPort }} 58 | {{- end }} 59 | {{- end }} 60 | {{- end }} 61 | {{- end }} 62 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-helm/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "nginx.fullname" . }} 5 | labels: 6 | {{- include "nginx.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: http 12 | protocol: TCP 13 | name: http 14 | selector: 15 | {{- include "nginx.selectorLabels" . | nindent 4 }} 16 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-helm/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "nginx.serviceAccountName" . }} 6 | labels: 7 | {{- include "nginx.labels" . | nindent 4 }} 8 | {{- with .Values.serviceAccount.annotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-helm/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "nginx.fullname" . }}-test-connection" 5 | labels: 6 | {{- include "nginx.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox 13 | command: ['wget'] 14 | args: ['{{ include "nginx.fullname" . }}:{{ .Values.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-helm/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for nginx. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 2 6 | 7 | image: 8 | repository: nginx 9 | pullPolicy: IfNotPresent 10 | # Overrides the image tag whose default is the chart appVersion. 11 | tag: "" 12 | 13 | imagePullSecrets: [] 14 | nameOverride: "" 15 | fullnameOverride: "" 16 | 17 | serviceAccount: 18 | # Specifies whether a service account should be created 19 | create: true 20 | # Annotations to add to the service account 21 | annotations: {} 22 | # The name of the service account to use. 23 | # If not set and create is true, a name is generated using the fullname template 24 | name: "" 25 | 26 | podAnnotations: {} 27 | 28 | podSecurityContext: {} 29 | # fsGroup: 2000 30 | 31 | securityContext: {} 32 | # capabilities: 33 | # drop: 34 | # - ALL 35 | # readOnlyRootFilesystem: true 36 | # runAsNonRoot: true 37 | # runAsUser: 1000 38 | 39 | service: 40 | type: ClusterIP 41 | port: 80 42 | 43 | ingress: 44 | enabled: false 45 | className: "" 46 | annotations: {} 47 | # kubernetes.io/ingress.class: nginx 48 | # kubernetes.io/tls-acme: "true" 49 | hosts: 50 | - host: chart-example.local 51 | paths: 52 | - path: / 53 | pathType: ImplementationSpecific 54 | tls: [] 55 | # - secretName: chart-example-tls 56 | # hosts: 57 | # - chart-example.local 58 | 59 | resources: {} 60 | # We usually recommend not to specify default resources and to leave this as a conscious 61 | # choice for the user. This also increases chances charts run on environments with little 62 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 63 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 64 | # limits: 65 | # cpu: 100m 66 | # memory: 128Mi 67 | # requests: 68 | # cpu: 100m 69 | # memory: 128Mi 70 | 71 | autoscaling: 72 | enabled: false 73 | minReplicas: 1 74 | maxReplicas: 100 75 | targetCPUUtilizationPercentage: 80 76 | # targetMemoryUtilizationPercentage: 80 77 | 78 | nodeSelector: {} 79 | 80 | tolerations: [] 81 | 82 | affinity: {} 83 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-manifests/deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: nginx 5 | labels: 6 | helm.sh/chart: nginx-0.1.0 7 | app.kubernetes.io/name: nginx 8 | app.kubernetes.io/instance: nginx 9 | app.kubernetes.io/version: "1.16.0" 10 | app.kubernetes.io/managed-by: Helm 11 | spec: 12 | replicas: 3 13 | selector: 14 | matchLabels: 15 | app.kubernetes.io/name: nginx 16 | app.kubernetes.io/instance: nginx 17 | template: 18 | metadata: 19 | labels: 20 | app.kubernetes.io/name: nginx 21 | app.kubernetes.io/instance: nginx 22 | spec: 23 | serviceAccountName: nginx 24 | securityContext: 25 | {} 26 | containers: 27 | - name: nginx 28 | securityContext: 29 | {} 30 | image: "nginx:1.16.0" 31 | imagePullPolicy: IfNotPresent 32 | ports: 33 | - name: http 34 | containerPort: 80 35 | protocol: TCP 36 | livenessProbe: 37 | httpGet: 38 | path: / 39 | port: http 40 | readinessProbe: 41 | httpGet: 42 | path: / 43 | port: http 44 | resources: 45 | {} 46 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-manifests/service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nginx 5 | annotations: 6 | argocd.argoproj.io/sync-options: Replace=true 7 | labels: 8 | helm.sh/chart: nginx-0.1.0 9 | app.kubernetes.io/name: nginx 10 | app.kubernetes.io/instance: nginx 11 | app.kubernetes.io/version: "1.16.0" 12 | app.kubernetes.io/managed-by: Helm 13 | spec: 14 | type: ClusterIP 15 | ports: 16 | - port: 80 17 | targetPort: http 18 | protocol: TCP 19 | name: http 20 | selector: 21 | app.kubernetes.io/name: nginx 22 | app.kubernetes.io/instance: nginx 23 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-manifests/serviceaccount.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: nginx 5 | annotations: 6 | argocd.argoproj.io/sync-options: Prune=false 7 | labels: 8 | helm.sh/chart: nginx-0.1.0 9 | app.kubernetes.io/name: nginx 10 | app.kubernetes.io/instance: nginx 11 | app.kubernetes.io/version: "1.16.0" 12 | app.kubernetes.io/managed-by: Helm 13 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-manifests/sub-directory/service.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: nginx-sub-directory 5 | # annotations: 6 | # argocd.argoproj.io/sync-options: Prune=false 7 | labels: 8 | helm.sh/chart: nginx-0.1.0 9 | app.kubernetes.io/name: nginx 10 | app.kubernetes.io/instance: nginx 11 | app.kubernetes.io/version: "1.16.0" 12 | app.kubernetes.io/managed-by: Helm 13 | spec: 14 | type: ClusterIP 15 | ports: 16 | - port: 80 17 | targetPort: http 18 | protocol: TCP 19 | name: http 20 | selector: 21 | app.kubernetes.io/name: nginx 22 | app.kubernetes.io/instance: nginx 23 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/git-generator/resources/nginx-manifests/test-connection.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "nginx-test-connection" 5 | labels: 6 | helm.sh/chart: nginx-0.1.0 7 | app.kubernetes.io/name: nginx 8 | app.kubernetes.io/instance: nginx 9 | app.kubernetes.io/version: "1.16.0" 10 | app.kubernetes.io/managed-by: Helm 11 | annotations: 12 | "helm.sh/hook": test 13 | spec: 14 | containers: 15 | - name: wget 16 | image: busybox 17 | command: ['wget'] 18 | args: ['nginx:80'] 19 | restartPolicy: Never 20 | -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/list-generator/list-generator-ex1.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: list-generator-ex1 5 | namespace: argocd 6 | spec: 7 | generators: 8 | - list: 9 | elements: 10 | - cluster: local 11 | url: https://kubernetes.default.svc 12 | path: directoryOfmanifests 13 | - cluster: external 14 | url: https://192.168.64.93:6443 15 | path: helm/nginx 16 | template: 17 | metadata: 18 | name: '{{cluster}}-application' 19 | spec: 20 | project: default 21 | source: 22 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 23 | targetRevision: main 24 | path: v03-argocd-applications/{{path}} 25 | destination: 26 | server: '{{url}}' 27 | namespace: '{{cluster}}' 28 | syncPolicy: 29 | automated: {} 30 | syncOptions: 31 | - CreateNamespace=true -------------------------------------------------------------------------------- /v09-argocd-applicationSet-1/list-generator/list-generator-ex2.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: list-generator-ex2 5 | namespace: argocd 6 | spec: 7 | generators: 8 | - list: 9 | elements: 10 | - environment: pre-staging 11 | server: https://kubernetes.default.svc 12 | path: directoryOfmanifests 13 | - environment: staging 14 | server: https://192.168.64.93:6443 15 | path: helm/nginx 16 | template: 17 | metadata: 18 | name: '{{environment}}-application' 19 | spec: 20 | project: default 21 | source: 22 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 23 | targetRevision: main 24 | path: v03-argocd-applications/{{path}} 25 | destination: 26 | server: '{{server}}' 27 | namespace: '{{environment}}' 28 | syncPolicy: 29 | automated: {} 30 | syncOptions: 31 | - CreateNamespace=true -------------------------------------------------------------------------------- /v10-argocd-applicationSet-2/matrix-generator/matrix-generator-ex1.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: matrix-generator-ex1 5 | spec: 6 | generators: 7 | - matrix: 8 | generators: 9 | - git: 10 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 11 | revision: main 12 | directories: 13 | - path: v09-argocd-applicationSet-1/git-generator/resources/* 14 | - clusters: {} 15 | template: 16 | metadata: 17 | name: '{{path.basename}}-{{name}}' 18 | spec: 19 | project: default 20 | source: 21 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 22 | targetRevision: main 23 | path: '{{path}}' 24 | destination: 25 | server: '{{server}}' 26 | namespace: '{{metadata.labels.environment}}' 27 | syncPolicy: 28 | automated: {} 29 | syncOptions: 30 | - CreateNamespace=true -------------------------------------------------------------------------------- /v10-argocd-applicationSet-2/matrix-generator/matrix-generator-ex2.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: matrix-generator-ex2 5 | spec: 6 | generators: 7 | - matrix: 8 | generators: 9 | - git: 10 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 11 | revision: main 12 | directories: 13 | - path: v09-argocd-applicationSet-1/git-generator/resources/* 14 | - list: 15 | elements: 16 | - environment: pre-staging 17 | server: https://kubernetes.default.svc 18 | - environment: staging 19 | server: https://192.168.226.93:6443 20 | template: 21 | metadata: 22 | name: '{{path.basename}}-{{environment}}' 23 | spec: 24 | project: default 25 | source: 26 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 27 | targetRevision: main 28 | path: '{{path}}' 29 | destination: 30 | server: '{{server}}' 31 | namespace: '{{environment}}' 32 | syncPolicy: 33 | automated: {} 34 | syncOptions: 35 | - CreateNamespace=true -------------------------------------------------------------------------------- /v10-argocd-applicationSet-2/matrix-generator/matrix-generator-ex3.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: matrix-generator-ex3 5 | spec: 6 | generators: 7 | - matrix: 8 | generators: 9 | - git: 10 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 11 | revision: main 12 | files: 13 | - path: v09-argocd-applicationSet-1/git-generator/cluster-config/**/config.json 14 | - clusters: 15 | selector: 16 | matchLabels: 17 | argocd.argoproj.io/secret-type: cluster 18 | environment: '{{cluster.name}}' 19 | template: 20 | metadata: 21 | name: '{{name}}-application' 22 | spec: 23 | project: default 24 | source: 25 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 26 | targetRevision: main 27 | path: '{{cluster.path}}' 28 | destination: 29 | server: '{{server}}' 30 | namespace: '{{metadata.labels.environment}}' 31 | syncPolicy: 32 | automated: {} 33 | syncOptions: 34 | - CreateNamespace=true -------------------------------------------------------------------------------- /v10-argocd-applicationSet-2/merge-generator/merge-generator-ex1.yml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: merge-generator-ex1 5 | spec: 6 | generators: 7 | - merge: 8 | mergeKeys: 9 | - server 10 | generators: 11 | - clusters: 12 | values: 13 | tag: '1.23' 14 | replicas: '1' 15 | - clusters: 16 | selector: 17 | matchLabels: 18 | environment: 'staging' 19 | values: 20 | tag: '1.24' 21 | - list: 22 | elements: 23 | - server: https://kubernetes.default.svc 24 | values.replicas: '3' 25 | template: 26 | metadata: 27 | name: '{{name}}-application' 28 | spec: 29 | project: default 30 | source: 31 | repoURL: https://github.com/devopshobbies/argocd-tutorial.git 32 | targetRevision: main 33 | path: v03-argocd-applications/helm/nginx 34 | helm: 35 | parameters: 36 | - name: "image.tag" 37 | value: '{{values.tag}}' 38 | - name: "replicaCount" 39 | value: '{{values.replicas}}' 40 | destination: 41 | server: '{{server}}' 42 | namespace: '{{metadata.labels.environment}}' 43 | syncPolicy: 44 | automated: {} 45 | syncOptions: 46 | - CreateNamespace=true -------------------------------------------------------------------------------- /v12-argo-rollouts-blue-green/blue-green-app/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.8-slim-buster 2 | WORKDIR /devops-hobbies 3 | ENV FLASK_APP blue-green.py 4 | COPY requirements.txt . 5 | RUN pip3 install -r requirements.txt 6 | COPY blue-green.py . 7 | COPY templates ./templates 8 | CMD ["flask", "run", "--host=0.0.0.0"] -------------------------------------------------------------------------------- /v12-argo-rollouts-blue-green/blue-green-app/blue-green.py: -------------------------------------------------------------------------------- 1 | from os import environ 2 | from flask import Flask, render_template 3 | app = Flask(__name__) 4 | 5 | @app.route('/') 6 | def home(): 7 | return render_template(environ['html_name']) 8 | if __name__ == '__main__': 9 | app.run() -------------------------------------------------------------------------------- /v12-argo-rollouts-blue-green/blue-green-app/requirements.txt: -------------------------------------------------------------------------------- 1 | blinker==1.6.2 2 | click==8.1.7 3 | flask==3.0.0 4 | importlib-metadata==6.8.0 5 | itsdangerous==2.1.2 6 | Jinja2==3.1.2 7 | MarkupSafe==2.1.3 8 | werkzeug==3.0.0 9 | zipp==3.17.0 -------------------------------------------------------------------------------- /v12-argo-rollouts-blue-green/blue-green-app/templates/app-v1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |