├── .github └── CODEOWNERS ├── .gitignore ├── README.md ├── argo-events ├── base │ ├── calendar-eventsource.yaml │ ├── log-sensor.yaml │ ├── operate-wf-rbac.yaml │ ├── operate-workflow-sa.yaml │ └── workflow-sensor.yaml └── kustomization.yaml ├── argo-rollouts └── kustomization.yaml ├── argo-workflows ├── README.md ├── kustomization.yaml ├── overlays │ ├── argo-role.yaml │ ├── argo-rolebinding.yaml │ ├── argo-server-deploy.yaml │ ├── argo-server-role.yaml │ ├── argo-server-rolebinding.yaml │ ├── argo-server-sa.yaml │ ├── workflow-controller-configmap.yaml │ └── workflow-controller-deploy.yaml └── resources │ ├── .gitignore │ ├── argo-ns.yaml │ ├── argo-rolebinding.yaml │ ├── argo-server-ingress.yaml │ ├── argo-server-rolebinding.yaml │ ├── argo-workflows-certificate.yaml │ ├── argo-workflows-issuer.yaml │ ├── rbac │ ├── read-only-clusterrole.yaml │ ├── read-only-namespaced-clusterrole.yaml │ └── read-write-namespaced-clusterrole.yaml │ └── workflow-count-resourcequota.yaml ├── argocd-image-updater └── kustomization.yaml ├── argocd ├── .gitignore ├── base │ ├── argo-cd-certificate.yaml │ ├── argo-cd-issuer.yaml │ ├── argo-cd-ui-ingress.yaml │ └── rollouts-extension.yaml ├── kustomization.yaml └── overlays │ └── production │ ├── argo-cd-cm.yaml │ ├── argocd-cmd-params-cm.yaml │ ├── argocd-notifications-cm.yaml │ ├── argocd-notifications-controller-deploy.yaml │ ├── argocd-rbac-cm.yaml │ └── argocd-server-service.yaml ├── argoproj ├── base │ ├── argo-cd.yaml │ ├── argo-events.yaml │ ├── argo-rollouts.yaml │ ├── argo-workflows.yaml │ ├── argocd-image-updater.yaml │ ├── cert-manager.yaml │ ├── dex.yaml │ ├── external-dns.yaml │ ├── governor.yaml │ ├── ingress-nginx.yaml │ ├── istio-addons.yaml │ ├── istio-controlplane.yaml │ ├── istio-operator.yaml │ ├── prometheus-operator.yaml │ └── workflow-examples.yaml └── kustomization.yaml ├── cert-manager ├── kustomization.yaml └── overlays │ └── cert-manager-namespace.yaml ├── dex ├── .gitignore ├── Chart.lock ├── Chart.yaml ├── README.md ├── templates │ ├── certificate.yaml │ └── issuer.yaml └── values.yaml ├── external-dns ├── .gitignore ├── Chart.lock ├── Chart.yaml └── values.yaml ├── governor ├── kustomization.yaml ├── pod-reaper-cr.yaml └── pod-reaper-job-patch.yaml ├── infrastructure └── terraform │ ├── .gitignore │ └── gcp │ ├── README.md │ ├── gke │ ├── .terraform.lock.hcl │ ├── Makefile │ ├── README.md │ ├── main.tf │ ├── network.tf │ ├── outputs.tf │ ├── providers.tf │ ├── terraform.tf │ ├── variables.tf │ ├── vars │ │ └── argo-demo-apps.tfvars │ └── workload_identity.tf │ ├── network │ ├── .terraform.lock.hcl │ ├── Makefile │ ├── README.md │ ├── default.auto.tfvars │ ├── main.tf │ ├── outputs.tf │ ├── providers.tf │ ├── terraform.tf │ └── variables.tf │ ├── remote-state │ ├── .terraform.lock.hcl │ ├── Makefile │ ├── README.md │ ├── default.auto.tfvars │ ├── main.tf │ ├── outputs.tf │ ├── providers.tf │ ├── terraform.tf │ └── variables.tf │ └── user-access │ ├── .terraform.lock.hcl │ ├── Makefile │ ├── README.md │ ├── main.tf │ ├── providers.tf │ ├── terraform.tf │ ├── variables.tf │ └── vars │ └── .gitignore ├── istio-controlplane └── istio-controlplane.yaml ├── prometheus-operator ├── README.md ├── dashboard.json ├── kustomization.yaml ├── overlays │ ├── prometheus-crds-annotations.yaml │ ├── prometheus-operator-grafana-cm.yaml │ └── prometheus-operator-grafana-secret.yaml ├── resources │ ├── argocd-metrics-servicemonitor.yaml │ ├── argocd-notifications-controller-metrics-servicemonitor.yaml │ ├── argocd-repo-server-metrics-servicemonitor.yaml │ ├── argocd-server-metrics-servicemonitor.yaml │ ├── grafana-certificate.yaml │ ├── grafana-ingress.yaml │ ├── grafana-issuer.yaml │ └── upstream.yaml ├── upstream.sh └── upstream │ ├── .gitignore │ └── Chart.yaml └── workflow-examples ├── kustomization.yaml └── resources ├── auth ├── read-write-sa-secret.yaml ├── read-write-sa.yaml ├── user-default-login-sa-secret.yaml └── user-default-login-sa.yaml ├── rbac ├── github.com-rolebinding.yaml ├── github.com-sa.yaml ├── read-only-clusterrolebinding.yaml ├── read-only-rolebinding.yaml ├── read-write-rolebinding.yaml ├── submit-workflow-template-role.yaml ├── workflow-role.yaml ├── workflow-rolebinding.yaml └── workflow-sa.yaml └── workflows ├── artifacts-cronworkflow.yaml ├── ci-cronworkflow.yaml ├── coinflip-cronworkflow.yaml ├── coinflip-workflowtemplate.yaml ├── event-consumer-workfloweventbinding.yaml └── github-event-workflowtemplate.yaml /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # # Infrastructure 2 | # /infrastructure/ @agaudreault @leoluz 3 | # /argocd/overlays/production/argocd-rbac-cm.yaml @agaudreault @leoluz 4 | # /external-dns/values.yaml @agaudreault @leoluz 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # argoproj-deployments 2 | 3 | This repository contains definition of Argoproj CI/CD infrastructure: 4 | 5 | - argo-workflows - [![App Status](https://cd.apps.argoproj.io/api/badge?name=argo-workflows)](https://cd.apps.argoproj.io/applications/argo-workflows) 6 | - argocd - includes Argo CD components. [![App Status](https://cd.apps.argoproj.io/api/badge?name=argo-cd)](https://cd.apps.argoproj.io/applications/argo-cd) 7 | - cert-manager - cert-manager components. [![App Status](https://cd.apps.argoproj.io/api/badge?name=cert-manager)](https://cd.apps.argoproj.io/applications/cert-manager) 8 | - argocd-image-updater - argocd-image-updater components. [![App Status](https://cd.apps.argoproj.io/api/badge?name=argocd-image-updater)](https://cd.apps.argoproj.io/applications/argocd-image-updater) 9 | - argoproj - packages all together: includes namespaces and argocd applications definitions. [![App Status](https://cd.apps.argoproj.io/api/badge?name=argoproj)](https://cd.apps.argoproj.io/applications/argoproj) 10 | - dex [![App Status](https://cd.apps.argoproj.io/api/badge?name=dex)](https://cd.apps.argoproj.io/applications/dex) 11 | 12 | 13 | * [Argo Workflows GitHub Webhook](https://github.com/argoproj/argo/settings/hooks/263222342) 14 | * [DEX OpenID](https://dex.apps.argoproj.io/dex/.well-known/openid-configuration) 15 | -------------------------------------------------------------------------------- /argo-events/base/calendar-eventsource.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: EventSource 3 | metadata: 4 | name: calendar 5 | spec: 6 | calendar: 7 | example-with-interval: 8 | interval: 120s 9 | -------------------------------------------------------------------------------- /argo-events/base/log-sensor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Sensor 3 | metadata: 4 | name: log 5 | spec: 6 | dependencies: 7 | - name: test-dep 8 | eventSourceName: calendar 9 | eventName: example-with-interval 10 | triggers: 11 | - template: 12 | name: log-trigger 13 | log: 14 | intervalSeconds: 1 15 | -------------------------------------------------------------------------------- /argo-events/base/operate-wf-rbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: operate-workflow-role 5 | rules: 6 | - apiGroups: 7 | - argoproj.io 8 | verbs: 9 | - "*" 10 | resources: 11 | - workflows 12 | - workflowtemplates 13 | - cronworkflows 14 | - clusterworkflowtemplates 15 | --- 16 | apiVersion: rbac.authorization.k8s.io/v1 17 | kind: RoleBinding 18 | metadata: 19 | name: operate-workflow-role-binding 20 | roleRef: 21 | apiGroup: rbac.authorization.k8s.io 22 | kind: Role 23 | name: operate-workflow-role 24 | subjects: 25 | - kind: ServiceAccount 26 | name: operate-workflow-sa 27 | -------------------------------------------------------------------------------- /argo-events/base/operate-workflow-sa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: operate-workflow-sa 5 | -------------------------------------------------------------------------------- /argo-events/base/workflow-sensor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Sensor 3 | metadata: 4 | name: workflow 5 | spec: 6 | template: 7 | serviceAccountName: operate-workflow-sa 8 | dependencies: 9 | - name: test-dep 10 | eventSourceName: calendar 11 | eventName: example-with-interval 12 | triggers: 13 | - template: 14 | name: argo-workflow-trigger 15 | argoWorkflow: 16 | group: argoproj.io 17 | version: v1alpha1 18 | resource: workflows 19 | operation: submit 20 | source: 21 | resource: 22 | apiVersion: argoproj.io/v1alpha1 23 | kind: Workflow 24 | metadata: 25 | generateName: calendar- 26 | spec: 27 | entrypoint: main 28 | arguments: 29 | parameters: 30 | - name: message 31 | # the value will get overridden by event payload from test-dep 32 | value: hello world 33 | templates: 34 | - name: main 35 | serviceAccountName: workflow 36 | inputs: 37 | parameters: 38 | - name: message 39 | container: 40 | image: docker/whalesay:latest 41 | command: [cowsay] 42 | args: ["{{inputs.parameters.message}}"] 43 | parameters: 44 | - src: 45 | dependencyName: test-dep 46 | dest: spec.arguments.parameters.0.value 47 | -------------------------------------------------------------------------------- /argo-events/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - https://github.com/argoproj/argo-events/manifests/namespace-install 6 | - https://raw.githubusercontent.com/argoproj/argo-events/master/examples/eventbus/native.yaml 7 | - base/operate-workflow-sa.yaml 8 | - base/operate-wf-rbac.yaml 9 | - base/calendar-eventsource.yaml 10 | - base/workflow-sensor.yaml 11 | - base/log-sensor.yaml 12 | 13 | namespace: workflow-playground 14 | -------------------------------------------------------------------------------- /argo-rollouts/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - https://github.com/argoproj/argo-rollouts/releases/download/v1.7.2/install.yaml 6 | -------------------------------------------------------------------------------- /argo-workflows/README.md: -------------------------------------------------------------------------------- 1 | # Argo Workflows 2 | 3 | ### Initial deployment 4 | 5 | You currently have to create secrets manually 6 | 7 | ``` 8 | kubectl apply -n argo -f resources/argo-server-sso-secret.yaml 9 | kubectl apply -n argo -f resources/argo-workflows-webhook-clients-secret.yaml 10 | ``` 11 | -------------------------------------------------------------------------------- /argo-workflows/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - https://github.com/argoproj/argo-workflows/releases/download/v3.6.5/namespace-install.yaml 6 | - resources/argo-ns.yaml 7 | - resources/argo-rolebinding.yaml 8 | - resources/argo-server-ingress.yaml 9 | - resources/argo-server-rolebinding.yaml 10 | - resources/argo-workflows-certificate.yaml 11 | - resources/argo-workflows-issuer.yaml 12 | - resources/workflow-count-resourcequota.yaml 13 | - resources/rbac/read-only-clusterrole.yaml 14 | - resources/rbac/read-only-namespaced-clusterrole.yaml 15 | - resources/rbac/read-write-namespaced-clusterrole.yaml 16 | 17 | patches: 18 | - path: overlays/argo-server-deploy.yaml 19 | - path: overlays/argo-server-sa.yaml 20 | - path: overlays/workflow-controller-configmap.yaml 21 | - path: overlays/workflow-controller-deploy.yaml 22 | - path: overlays/argo-role.yaml 23 | options: 24 | allowKindChange: true 25 | allowNameChange: true 26 | target: 27 | group: rbac.authorization.k8s.io 28 | kind: Role 29 | name: argo-role 30 | - path: overlays/argo-rolebinding.yaml 31 | target: 32 | group: rbac.authorization.k8s.io 33 | kind: RoleBinding 34 | name: argo-binding 35 | - path: overlays/argo-server-role.yaml 36 | options: 37 | allowKindChange: true 38 | allowNameChange: true 39 | target: 40 | group: rbac.authorization.k8s.io 41 | kind: Role 42 | name: argo-server-role 43 | - path: overlays/argo-server-rolebinding.yaml 44 | target: 45 | group: rbac.authorization.k8s.io 46 | kind: RoleBinding 47 | name: argo-server-binding 48 | -------------------------------------------------------------------------------- /argo-workflows/overlays/argo-role.yaml: -------------------------------------------------------------------------------- 1 | - op: replace 2 | path: /kind 3 | value: ClusterRole 4 | - op: replace 5 | path: /metadata/name 6 | value: argo-workflows-argo-role 7 | -------------------------------------------------------------------------------- /argo-workflows/overlays/argo-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | - op: replace 2 | path: /roleRef/kind 3 | value: ClusterRole 4 | - op: replace 5 | path: /roleRef/name 6 | value: argo-workflows-argo-role 7 | -------------------------------------------------------------------------------- /argo-workflows/overlays/argo-server-deploy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: argo-server 5 | spec: 6 | replicas: 2 7 | template: 8 | spec: 9 | serviceAccountName: argo-server 10 | containers: 11 | - name: argo-server 12 | args: 13 | - server 14 | - --namespaced 15 | - --managed-namespace 16 | - workflow-playground 17 | - --auth-mode=sso 18 | - --auth-mode=client 19 | - --x-frame-options=SAMEORIGIN 20 | -------------------------------------------------------------------------------- /argo-workflows/overlays/argo-server-role.yaml: -------------------------------------------------------------------------------- 1 | - op: replace 2 | path: /kind 3 | value: ClusterRole 4 | - op: replace 5 | path: /metadata/name 6 | value: argo-workflows-argo-server-role 7 | - op: add 8 | path: /rules/5/resources/7 9 | value: clusterworkflowtemplates 10 | -------------------------------------------------------------------------------- /argo-workflows/overlays/argo-server-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | - op: replace 2 | path: /roleRef/kind 3 | value: ClusterRole 4 | - op: replace 5 | path: /roleRef/name 6 | value: argo-workflows-argo-server-role 7 | -------------------------------------------------------------------------------- /argo-workflows/overlays/argo-server-sa.yaml: -------------------------------------------------------------------------------- 1 | kind: ServiceAccount 2 | apiVersion: v1 3 | metadata: 4 | name: argo-server 5 | -------------------------------------------------------------------------------- /argo-workflows/overlays/workflow-controller-configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | # https://github.com/settings/applications/1416526 4 | config: | 5 | sso: 6 | issuer: https://dex.apps.argoproj.io/dex 7 | clientId: 8 | name: argo-server-sso 9 | key: clientID 10 | clientSecret: 11 | name: argo-server-sso 12 | key: clientSecret 13 | redirectUrl: https://workflows.apps.argoproj.io/oauth2/callback 14 | scopes: 15 | - groups 16 | rbac: 17 | enabled: true 18 | workflowDefaults: 19 | spec: 20 | activeDeadlineSeconds: 600 21 | retentionPolicy: 22 | completed: 20 23 | failed: 3 24 | errored: 3 25 | kind: ConfigMap 26 | metadata: 27 | name: workflow-controller-configmap 28 | -------------------------------------------------------------------------------- /argo-workflows/overlays/workflow-controller-deploy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: workflow-controller 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - name: workflow-controller 10 | args: 11 | - --namespaced 12 | - --managed-namespace 13 | - workflow-playground 14 | -------------------------------------------------------------------------------- /argo-workflows/resources/.gitignore: -------------------------------------------------------------------------------- 1 | argo-server-sso-secret.yaml 2 | argo-workflows-webhook-clients-secret.yaml -------------------------------------------------------------------------------- /argo-workflows/resources/argo-ns.yaml: -------------------------------------------------------------------------------- 1 | kind: Namespace 2 | apiVersion: v1 3 | metadata: 4 | name: argo -------------------------------------------------------------------------------- /argo-workflows/resources/argo-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: argo 5 | namespace: workflow-playground # Gives permission in the managed namespace 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: argo-workflows-argo-role 10 | subjects: 11 | - kind: ServiceAccount 12 | name: argo 13 | namespace: argo 14 | -------------------------------------------------------------------------------- /argo-workflows/resources/argo-server-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: argo-server 5 | annotations: 6 | # https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/ 7 | ingress.kubernetes.io/proxy-body-size: 100M 8 | ingress.kubernetes.io/app-root: "/" 9 | nginx.ingress.kubernetes.io/backend-protocol: HTTPS 10 | spec: 11 | ingressClassName: nginx 12 | tls: 13 | - hosts: 14 | - workflows.apps.argoproj.io 15 | secretName: argo-workflows-secret 16 | rules: 17 | - host: workflows.apps.argoproj.io 18 | http: 19 | paths: 20 | - path: / 21 | pathType: ImplementationSpecific 22 | backend: 23 | service: 24 | name: argo-server 25 | port: 26 | number: 2746 -------------------------------------------------------------------------------- /argo-workflows/resources/argo-server-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: argo-server-binding 5 | namespace: workflow-playground # Gives permission in the managed namespace 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: argo-workflows-argo-server-role 10 | subjects: 11 | - kind: ServiceAccount 12 | name: argo-server 13 | namespace: argo 14 | -------------------------------------------------------------------------------- /argo-workflows/resources/argo-workflows-certificate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Certificate 3 | metadata: 4 | name: argo-workflows-cert 5 | spec: 6 | secretName: argo-workflows-secret 7 | issuerRef: 8 | name: argo-workflows-issuer 9 | kind: Issuer 10 | commonName: workflows.apps.argoproj.io 11 | dnsNames: 12 | - workflows.apps.argoproj.io 13 | -------------------------------------------------------------------------------- /argo-workflows/resources/argo-workflows-issuer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Issuer 3 | metadata: 4 | name: argo-workflows-issuer 5 | spec: 6 | acme: 7 | server: https://acme-v02.api.letsencrypt.org/directory 8 | email: argoproj@gmail.com 9 | privateKeySecretRef: 10 | name: letsencrypt 11 | solvers: 12 | # An empty 'selector' means that this solver matches all domains 13 | - selector: {} 14 | http01: 15 | ingress: 16 | class: nginx 17 | -------------------------------------------------------------------------------- /argo-workflows/resources/rbac/read-only-clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: argo-workflows-read-only 5 | rules: 6 | - apiGroups: 7 | - argoproj.io 8 | resources: 9 | - clusterworkflowtemplates 10 | - clusteranalysistemplates 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | -------------------------------------------------------------------------------- /argo-workflows/resources/rbac/read-only-namespaced-clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: argo-workflows-read-only-namespaced 5 | rules: 6 | - apiGroups: 7 | - '' 8 | resources: 9 | - pods 10 | - pods/log 11 | verbs: 12 | - get 13 | - list 14 | - apiGroups: 15 | - '' 16 | resources: 17 | - events 18 | verbs: 19 | - watch 20 | - apiGroups: 21 | - argoproj.io 22 | resources: 23 | - eventsources 24 | - sensors 25 | - workflows 26 | - workfloweventbindings 27 | - workflowtemplates 28 | - cronworkflows 29 | verbs: 30 | - get 31 | - list 32 | - watch 33 | -------------------------------------------------------------------------------- /argo-workflows/resources/rbac/read-write-namespaced-clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: argo-workflows-read-write-namespaced 5 | rules: 6 | - apiGroups: 7 | - '' 8 | resources: 9 | - configmaps 10 | verbs: 11 | - get 12 | - watch 13 | - list 14 | - apiGroups: 15 | - '' 16 | resources: 17 | - secrets 18 | verbs: 19 | - get 20 | - apiGroups: 21 | - '' 22 | resources: 23 | - pods 24 | - pods/exec 25 | - pods/log 26 | verbs: 27 | - get 28 | - list 29 | - watch 30 | - apiGroups: 31 | - '' 32 | resources: 33 | - events 34 | verbs: 35 | - watch 36 | - apiGroups: 37 | - '' 38 | resources: 39 | - serviceaccounts 40 | verbs: 41 | - get 42 | - list 43 | - apiGroups: 44 | - argoproj.io 45 | resources: 46 | - eventsources 47 | - sensors 48 | - workflows 49 | - workfloweventbindings 50 | - workflowtemplates 51 | - cronworkflows 52 | - cronworkflows/finalizers 53 | verbs: 54 | - get 55 | - list 56 | - watch 57 | - patch 58 | - create 59 | - update 60 | - delete 61 | - deletecollection 62 | -------------------------------------------------------------------------------- /argo-workflows/resources/workflow-count-resourcequota.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ResourceQuota 3 | metadata: 4 | name: workflow-count 5 | annotations: 6 | workflows.argoproj.io/description: | 7 | This resource quota prevents creation of more than a certain number of workflows being created in a namespace. 8 | The user will get an error when they try to create more. As the count includes both completed and incomplete 9 | workflows, and complete workflows do not make any significant demands of your cluster, you probably want to use it 10 | with a workflow GC strategy, so that a build up of completed workflows does not prevent you from creating and 11 | running new workflows. 12 | Argo Workflowws has feature called "parallelism" that limits the number of running workflows, ignoring completed 13 | workflows. 14 | <= v3.1 you can configure a global limit to the total number of running workflows in the cluster. This is suitable 15 | for single-tenancy set-up. 16 | For multi-tenancy set-up, where each tenant own a single namespace, then in >= v3.1 you can globaly configure a 17 | limit for the total number of running workflows within each namespace. 18 | spec: 19 | hard: 20 | count/workflows.argoproj.io: "100" 21 | -------------------------------------------------------------------------------- /argocd-image-updater/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/master/manifests/install.yaml 6 | -------------------------------------------------------------------------------- /argocd/.gitignore: -------------------------------------------------------------------------------- 1 | /argo-cd-auth-secret.yaml 2 | -------------------------------------------------------------------------------- /argocd/base/argo-cd-certificate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Certificate 3 | metadata: 4 | name: argo-cd-cert 5 | spec: 6 | secretName: argocd-secret 7 | issuerRef: 8 | name: argo-cd-issuer 9 | kind: Issuer 10 | commonName: cd.apps.argoproj.io 11 | dnsNames: 12 | - cd.apps.argoproj.io 13 | -------------------------------------------------------------------------------- /argocd/base/argo-cd-issuer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Issuer 3 | metadata: 4 | name: argo-cd-issuer 5 | spec: 6 | acme: 7 | server: https://acme-v02.api.letsencrypt.org/directory 8 | email: argoproj@gmail.com 9 | privateKeySecretRef: 10 | name: letsencrypt 11 | solvers: 12 | # An empty 'selector' means that this solver matches all domains 13 | - selector: {} 14 | http01: 15 | ingress: 16 | class: nginx 17 | -------------------------------------------------------------------------------- /argocd/base/argo-cd-ui-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: argo-cd-ui 5 | annotations: 6 | ingress.kubernetes.io/proxy-body-size: 100M 7 | ingress.kubernetes.io/app-root: "/" 8 | spec: 9 | ingressClassName: nginx 10 | tls: 11 | - hosts: 12 | - cd.apps.argoproj.io 13 | secretName: argocd-secret 14 | rules: 15 | - host: cd.apps.argoproj.io 16 | http: 17 | paths: 18 | - path: / 19 | pathType: ImplementationSpecific 20 | backend: 21 | service: 22 | name: argocd-server 23 | port: 24 | name: http 25 | -------------------------------------------------------------------------------- /argocd/base/rollouts-extension.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ArgoCDExtension 3 | metadata: 4 | finalizers: 5 | - extensions-finalizer.argocd.argoproj.io 6 | name: argo-rollouts 7 | spec: 8 | sources: 9 | - web: 10 | url: https://github.com/argoproj-labs/rollout-extension/releases/download/v0.1.0/extension.tar 11 | -------------------------------------------------------------------------------- /argocd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | namespace: argocd 5 | 6 | resources: 7 | - base/argo-cd-issuer.yaml 8 | - base/argo-cd-certificate.yaml 9 | - base/argo-cd-ui-ingress.yaml 10 | - base/rollouts-extension.yaml 11 | - https://raw.githubusercontent.com/argoproj/argo-cd/master/manifests/ha/install.yaml 12 | 13 | components: 14 | - https://github.com/argoproj-labs/argocd-extensions/manifests 15 | 16 | patches: 17 | - path: overlays/production/argo-cd-cm.yaml 18 | - path: overlays/production/argocd-server-service.yaml 19 | - path: overlays/production/argocd-notifications-controller-deploy.yaml 20 | - path: overlays/production/argocd-notifications-cm.yaml 21 | - path: overlays/production/argocd-cmd-params-cm.yaml 22 | - path: overlays/production/argocd-rbac-cm.yaml 23 | - path: https://raw.githubusercontent.com/argoproj/argo-cd/master/notifications_catalog/install.yaml 24 | 25 | images: 26 | - name: quay.io/argoproj/argocd 27 | newName: ghcr.io/argoproj/argo-cd/argocd 28 | newTag: 3.1.0-1ecc561d 29 | -------------------------------------------------------------------------------- /argocd/overlays/production/argo-cd-cm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | application.resourceTrackingMethod: annotation 4 | admin.enabled: 'false' 5 | statusbadge.enabled: 'true' 6 | users.anonymous.enabled: 'true' 7 | ga.trackingid: 'UA-105170809-6' 8 | url: https://cd.apps.argoproj.io 9 | configManagementPlugins: | 10 | - name: flux 11 | generate: 12 | command: [sh, -c] 13 | args: ["argocd-flux-plugin . --path $GIT_PATH"] 14 | dex.config: | 15 | connectors: 16 | - type: github 17 | id: github 18 | name: GitHub 19 | config: 20 | clientID: fb563b3a8dd7ea52f683 21 | clientSecret: $argocd-auth:dex.github.clientSecret 22 | orgs: 23 | - name: argoproj 24 | teams: 25 | - argo-rollouts-approvers 26 | - argo-workflows-approvers 27 | - argocd-approvers 28 | kind: ConfigMap 29 | metadata: 30 | name: argocd-cm 31 | -------------------------------------------------------------------------------- /argocd/overlays/production/argocd-cmd-params-cm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: argocd-cmd-params-cm 5 | data: 6 | server.insecure: "true" 7 | -------------------------------------------------------------------------------- /argocd/overlays/production/argocd-notifications-cm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: argocd-notifications-cm 5 | data: 6 | context: | 7 | argocdUrl: https://cd.apps.argoproj.io 8 | 9 | trigger.sync-operation-change: | 10 | - when: app.status.operationState.phase in ['Succeeded'] 11 | send: [github-commit-status, app-sync-succeeded] 12 | - when: app.status.operationState.phase in ['Running'] 13 | send: [github-commit-status, app-sync-running] 14 | - when: app.status.operationState.phase in ['Error', 'Failed'] 15 | send: [github-commit-status, app-sync-failed] 16 | 17 | template.github-commit-status: | 18 | description: Generates Github webhook payload 19 | webhook: 20 | github: 21 | method: POST 22 | path: /repos/{{call .repo.FullNameByRepoURL .app.spec.source.repoURL}}/statuses/{{.app.status.operationState.operation.sync.revision}} 23 | body: | 24 | { 25 | {{if eq .app.status.operationState.phase "Running"}} "state": "pending"{{end}} 26 | {{if eq .app.status.operationState.phase "Succeeded"}} "state": "success"{{end}} 27 | {{if eq .app.status.operationState.phase "Error"}} "state": "error"{{end}} 28 | {{if eq .app.status.operationState.phase "Failed"}} "state": "error"{{end}}, 29 | "description": "ArgoCD", 30 | "target_url": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", 31 | "context": "continuous-delivery/{{.app.metadata.name}}" 32 | } 33 | 34 | service.slack: | 35 | token: $slack-token 36 | signingSecret: $slack-signing-secret 37 | 38 | service.grafana: | 39 | apiUrl: https://grafana.apps.argoproj.io/api 40 | apiKey: $grafana-token 41 | 42 | service.webhook.github: | 43 | url: https://api.github.com 44 | headers: #optional headers 45 | - name: Authorization 46 | value: token $github-token 47 | -------------------------------------------------------------------------------- /argocd/overlays/production/argocd-notifications-controller-deploy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: argocd-notifications-controller 5 | spec: 6 | template: 7 | spec: 8 | containers: 9 | - name: argocd-notifications-controller 10 | command: 11 | - argocd-notifications 12 | - --app-label-selector=!testing 13 | -------------------------------------------------------------------------------- /argocd/overlays/production/argocd-rbac-cm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: argocd-rbac-cm 5 | data: 6 | policy.csv: | 7 | g, argoproj:argo-rollouts-approvers, role:admin 8 | g, argoproj:argo-workflows-approvers, role:admin 9 | g, argoproj:argocd-approvers, role:admin 10 | policy.default: role:readonly 11 | -------------------------------------------------------------------------------- /argocd/overlays/production/argocd-server-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: argocd-server 5 | spec: 6 | type: ClusterIP 7 | -------------------------------------------------------------------------------- /argoproj/base/argo-cd.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: argo-cd 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: argocd 9 | server: https://kubernetes.default.svc 10 | project: default 11 | source: 12 | path: argocd 13 | repoURL: https://github.com/argoproj/argoproj-deployments 14 | targetRevision: HEAD 15 | -------------------------------------------------------------------------------- /argoproj/base/argo-events.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: argo-events 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: workflow-playground 9 | server: https://kubernetes.default.svc 10 | project: default 11 | source: 12 | path: argo-events 13 | repoURL: https://github.com/argoproj/argoproj-deployments 14 | targetRevision: HEAD 15 | syncPolicy: 16 | syncOptions: 17 | - CreateNamespace=true 18 | automated: 19 | prune: true 20 | selfHeal: true 21 | -------------------------------------------------------------------------------- /argoproj/base/argo-rollouts.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: argo-rollouts 5 | namespace: argocd 6 | spec: 7 | project: default 8 | source: 9 | path: argo-rollouts 10 | repoURL: https://github.com/argoproj/argoproj-deployments 11 | targetRevision: HEAD 12 | destination: 13 | server: https://kubernetes.default.svc 14 | namespace: argo-rollouts 15 | syncPolicy: 16 | syncOptions: 17 | - CreateNamespace=true 18 | automated: 19 | prune: true 20 | selfHeal: true 21 | -------------------------------------------------------------------------------- /argoproj/base/argo-workflows.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: argo-workflows 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: argo 9 | server: https://kubernetes.default.svc 10 | project: default 11 | source: 12 | path: argo-workflows 13 | repoURL: https://github.com/argoproj/argoproj-deployments 14 | targetRevision: HEAD 15 | syncPolicy: 16 | syncOptions: 17 | - CreateNamespace=true 18 | automated: 19 | prune: true 20 | selfHeal: true 21 | -------------------------------------------------------------------------------- /argoproj/base/argocd-image-updater.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: argocd-image-updater 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: argocd 9 | server: https://kubernetes.default.svc 10 | project: default 11 | source: 12 | path: argocd-image-updater 13 | repoURL: https://github.com/argoproj/argoproj-deployments 14 | targetRevision: HEAD 15 | syncPolicy: 16 | syncOptions: 17 | - CreateNamespace=true 18 | automated: 19 | prune: true 20 | selfHeal: true 21 | -------------------------------------------------------------------------------- /argoproj/base/cert-manager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: cert-manager 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: cert-manager 9 | server: https://kubernetes.default.svc 10 | project: default 11 | source: 12 | path: cert-manager 13 | repoURL: https://github.com/argoproj/argoproj-deployments 14 | targetRevision: HEAD 15 | syncPolicy: 16 | syncOptions: 17 | - CreateNamespace=true 18 | automated: 19 | prune: true 20 | selfHeal: true 21 | -------------------------------------------------------------------------------- /argoproj/base/dex.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: dex 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: dex 9 | server: https://kubernetes.default.svc 10 | project: default 11 | source: 12 | path: dex 13 | repoURL: https://github.com/argoproj/argoproj-deployments 14 | targetRevision: HEAD 15 | syncPolicy: 16 | syncOptions: 17 | - CreateNamespace=true 18 | automated: 19 | prune: true 20 | selfHeal: true 21 | -------------------------------------------------------------------------------- /argoproj/base/external-dns.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: external-dns 5 | namespace: argocd 6 | spec: 7 | source: 8 | path: external-dns 9 | repoURL: https://github.com/argoproj/argoproj-deployments 10 | targetRevision: HEAD 11 | destination: 12 | server: 'https://kubernetes.default.svc' 13 | namespace: external-dns 14 | project: default 15 | syncPolicy: 16 | syncOptions: 17 | - CreateNamespace=true 18 | automated: 19 | prune: true 20 | selfHeal: true 21 | -------------------------------------------------------------------------------- /argoproj/base/governor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: governor 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: governor 9 | server: https://kubernetes.default.svc 10 | project: default 11 | source: 12 | path: governor 13 | repoURL: https://github.com/argoproj/argoproj-deployments 14 | targetRevision: HEAD 15 | syncPolicy: 16 | syncOptions: 17 | - CreateNamespace=true 18 | automated: 19 | prune: true 20 | selfHeal: true 21 | -------------------------------------------------------------------------------- /argoproj/base/ingress-nginx.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: ingress-nginx 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: ingress-nginx 9 | server: https://kubernetes.default.svc 10 | project: default 11 | source: 12 | repoURL: https://kubernetes.github.io/ingress-nginx 13 | chart: ingress-nginx 14 | targetRevision: 4.9.1 15 | syncPolicy: 16 | syncOptions: 17 | - CreateNamespace=true 18 | automated: 19 | prune: true 20 | selfHeal: true 21 | -------------------------------------------------------------------------------- /argoproj/base/istio-addons.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: istio-addons 5 | namespace: argocd 6 | spec: 7 | source: 8 | path: samples/addons 9 | repoURL: https://github.com/istio/istio 10 | targetRevision: release-1.20 11 | destination: 12 | server: https://kubernetes.default.svc 13 | namespace: istio-system 14 | project: default 15 | syncPolicy: 16 | syncOptions: 17 | - CreateNamespace=true 18 | automated: 19 | prune: true 20 | selfHeal: true 21 | -------------------------------------------------------------------------------- /argoproj/base/istio-controlplane.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: istio-controlplane 5 | namespace: argocd 6 | spec: 7 | source: 8 | path: istio-controlplane 9 | repoURL: https://github.com/argoproj/argoproj-deployments 10 | targetRevision: HEAD 11 | destination: 12 | server: https://kubernetes.default.svc 13 | namespace: istio-system 14 | project: default 15 | syncPolicy: 16 | syncOptions: 17 | - CreateNamespace=true 18 | automated: 19 | prune: true 20 | selfHeal: true 21 | -------------------------------------------------------------------------------- /argoproj/base/istio-operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: istio-operator 5 | namespace: argocd 6 | spec: 7 | source: 8 | repoURL: https://github.com/istio/istio 9 | path: manifests/charts/istio-operator 10 | targetRevision: release-1.20 11 | helm: 12 | parameters: 13 | - name: enableCRDTemplates 14 | value: 'true' 15 | destination: 16 | server: https://kubernetes.default.svc 17 | namespace: istio-operator 18 | project: default 19 | syncPolicy: 20 | syncOptions: 21 | - CreateNamespace=true 22 | automated: 23 | prune: true 24 | selfHeal: true 25 | -------------------------------------------------------------------------------- /argoproj/base/prometheus-operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: prometheus-operator 5 | namespace: argocd 6 | spec: 7 | project: default 8 | source: 9 | path: prometheus-operator 10 | repoURL: https://github.com/argoproj/argoproj-deployments 11 | targetRevision: HEAD 12 | destination: 13 | server: 'https://kubernetes.default.svc' 14 | namespace: prometheus-operator 15 | ignoreDifferences: 16 | - group: apiextensions.k8s.io 17 | jsonPointers: 18 | - /metadata/annotations 19 | - /metadata/labels 20 | - /spec/validation 21 | kind: CustomResourceDefinition 22 | - group: admissionregistration.k8s.io 23 | kind: MutatingWebhookConfiguration 24 | jsonPointers: 25 | - /webhooks 26 | - group: admissionregistration.k8s.io 27 | kind: ValidatingWebhookConfiguration 28 | jsonPointers: 29 | - /webhooks 30 | syncPolicy: 31 | syncOptions: 32 | - CreateNamespace=true 33 | automated: 34 | prune: true 35 | selfHeal: true 36 | -------------------------------------------------------------------------------- /argoproj/base/workflow-examples.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: workflow-examples 5 | namespace: argocd 6 | spec: 7 | destination: 8 | namespace: workflow-playground 9 | server: https://kubernetes.default.svc 10 | project: default 11 | source: 12 | path: workflow-examples 13 | repoURL: https://github.com/argoproj/argoproj-deployments 14 | targetRevision: HEAD 15 | syncPolicy: 16 | syncOptions: 17 | - CreateNamespace=true 18 | automated: 19 | prune: true 20 | selfHeal: true 21 | -------------------------------------------------------------------------------- /argoproj/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - base/argo-cd.yaml 6 | - base/argo-events.yaml 7 | - base/argo-rollouts.yaml 8 | - base/argo-workflows.yaml 9 | - base/argocd-image-updater.yaml 10 | - base/cert-manager.yaml 11 | - base/dex.yaml 12 | - base/external-dns.yaml 13 | - base/governor.yaml 14 | - base/ingress-nginx.yaml 15 | - base/istio-addons.yaml 16 | - base/istio-controlplane.yaml 17 | - base/istio-operator.yaml 18 | - base/prometheus-operator.yaml 19 | - base/workflow-examples.yaml 20 | -------------------------------------------------------------------------------- /cert-manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - https://github.com/cert-manager/cert-manager/releases/download/v1.14.2/cert-manager.yaml 6 | 7 | patches: 8 | - path: overlays/cert-manager-namespace.yaml 9 | -------------------------------------------------------------------------------- /cert-manager/overlays/cert-manager-namespace.yaml: -------------------------------------------------------------------------------- 1 | $patch: delete 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: cert-manager 6 | -------------------------------------------------------------------------------- /dex/.gitignore: -------------------------------------------------------------------------------- 1 | charts 2 | 3 | dex-secret.yaml 4 | -------------------------------------------------------------------------------- /dex/Chart.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: dex 3 | repository: https://charts.dexidp.io 4 | version: 0.16.0 5 | digest: sha256:9b108094ab73cf6a6cb83c07d814c142144f7359a009e04188d7233694c6f972 6 | generated: "2024-02-23T16:50:10.176841-05:00" 7 | -------------------------------------------------------------------------------- /dex/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: dex 3 | version: '1.0.0' 4 | 5 | dependencies: 6 | - name: dex 7 | version: 0.16.0 8 | repository: https://charts.dexidp.io 9 | -------------------------------------------------------------------------------- /dex/README.md: -------------------------------------------------------------------------------- 1 | # Dex 2 | 3 | ## Deployment 4 | 5 | ### Configs 6 | 7 | Dex configs are managed by a Secret deployed manually after the initial deployment. 8 | -------------------------------------------------------------------------------- /dex/templates/certificate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Certificate 3 | metadata: 4 | name: dex-cert 5 | spec: 6 | secretName: dex-secret 7 | issuerRef: 8 | name: dex-issuer 9 | kind: Issuer 10 | commonName: dex.apps.argoproj.io 11 | dnsNames: 12 | - dex.apps.argoproj.io 13 | -------------------------------------------------------------------------------- /dex/templates/issuer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Issuer 3 | metadata: 4 | name: dex-issuer 5 | spec: 6 | acme: 7 | server: https://acme-v02.api.letsencrypt.org/directory 8 | email: argoproj@gmail.com 9 | privateKeySecretRef: 10 | name: letsencrypt 11 | solvers: 12 | # An empty 'selector' means that this solver matches all domains 13 | - selector: {} 14 | http01: 15 | ingress: 16 | class: nginx 17 | -------------------------------------------------------------------------------- /dex/values.yaml: -------------------------------------------------------------------------------- 1 | dex: 2 | replicaCount: 1 3 | 4 | configSecret: 5 | # TODO: need to manually create configs as a Secret 6 | create: false 7 | name: 'dex' 8 | 9 | rbac: 10 | create: true 11 | createClusterScoped: false 12 | 13 | ingress: 14 | enabled: true 15 | className: nginx 16 | annotations: 17 | ingress.kubernetes.io/proxy-body-size: 100M 18 | ingress.kubernetes.io/app-root: '/' 19 | hosts: 20 | - host: dex.apps.argoproj.io 21 | paths: 22 | - path: / 23 | pathType: ImplementationSpecific 24 | tls: 25 | - secretName: dex-secret 26 | hosts: 27 | - dex.apps.argoproj.io 28 | 29 | serviceMonitor: 30 | enabled: true 31 | -------------------------------------------------------------------------------- /external-dns/.gitignore: -------------------------------------------------------------------------------- 1 | charts 2 | -------------------------------------------------------------------------------- /external-dns/Chart.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: external-dns 3 | repository: https://kubernetes-sigs.github.io/external-dns/ 4 | version: 1.14.3 5 | digest: sha256:5e83a573eb35414266e0206767c9a6374055dfe3c665e7df015538452b3184d7 6 | generated: "2024-02-22T15:28:18.480843-05:00" 7 | -------------------------------------------------------------------------------- /external-dns/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: external-dns 3 | version: "1.0.0" 4 | 5 | dependencies: 6 | - name: external-dns 7 | version: 1.14.3 8 | repository: https://kubernetes-sigs.github.io/external-dns/ 9 | -------------------------------------------------------------------------------- /external-dns/values.yaml: -------------------------------------------------------------------------------- 1 | external-dns: 2 | provider: google 3 | policy: sync 4 | sources: 5 | - ingress 6 | txtOwnerId: argo-demo-apps 7 | domainFilters: 8 | - argo-demo-apps.cluster 9 | - apps.argoproj.io 10 | extraArgs: 11 | - --google-project=argo-demo-apps 12 | 13 | logFormat: json 14 | logLevel: info 15 | serviceMonitor: 16 | enabled: false 17 | serviceAccount: 18 | annotations: 19 | iam.gke.io/gcp-service-account: external-dns@argo-demo-apps.iam.gserviceaccount.com 20 | automountServiceAccountToken: true 21 | -------------------------------------------------------------------------------- /governor/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - https://raw.githubusercontent.com/keikoproj/governor/master/examples/pod-reaper.yaml 6 | 7 | images: 8 | - name: governor 9 | newName: keikoproj/governor 10 | newTag: v0.4.1 11 | 12 | patchesStrategicMerge: 13 | - pod-reaper-cr.yaml 14 | 15 | patches: 16 | - path: pod-reaper-job-patch.yaml 17 | target: 18 | group: batch 19 | kind: CronJob 20 | name: pod-reaper 21 | -------------------------------------------------------------------------------- /governor/pod-reaper-cr.yaml: -------------------------------------------------------------------------------- 1 | kind: ClusterRole 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | metadata: 4 | name: pod-reaper 5 | rules: 6 | - apiGroups: [""] 7 | resources: ["pods", ] 8 | verbs: ["get", "delete", "list"] 9 | - apiGroups: [""] 10 | resources: ["namespaces"] 11 | verbs: ["list"] -------------------------------------------------------------------------------- /governor/pod-reaper-job-patch.yaml: -------------------------------------------------------------------------------- 1 | - op: remove 2 | path: /spec/backoffLimit 3 | -------------------------------------------------------------------------------- /infrastructure/terraform/.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 | # Ignore override files as they are usually used to override resources locally and so 13 | # are not checked in 14 | override.tf 15 | override.tf.json 16 | *_override.tf 17 | *_override.tf.json 18 | 19 | # Include override files you do wish to add to version control using negated pattern 20 | # !example_override.tf 21 | 22 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 23 | *.tfplan 24 | 25 | # Ignore CLI configuration files 26 | .terraformrc 27 | terraform.rc 28 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/README.md: -------------------------------------------------------------------------------- 1 | # OpenTofu deployment 2 | 3 | This sections contains multiple OpenTofu modules used to provision a Google Cloud Platform Project. 4 | 5 | ## Requirements 6 | 7 | - OpenTofu (>= 1.6) 8 | - GCloud CLI (>= 464.0.0) 9 | - A GCP Project 10 | 11 | ## Deployment 12 | 13 | This project contains multiples modules that can be applied indenpendely to provision a GKE cluster. 14 | 15 | In a new account, the modules can be deployed in the following order: 16 | 17 | 1. User Access (requires update after the Remote State deployment) 18 | 2. Remote State 19 | 3. Network 20 | 4. GKE 21 | 22 | Once a cluster has been provisioned, ArgoCD is used to deploy applications into it. 23 | 24 | ### [User access](./user-access/README.md) 25 | 26 | The user access module manages users permissions to the GCP project. 27 | To allow a user to execute the GKE terraform, add it to the [user-access module](./user-access/README.md). 28 | 29 | **WARNING:** This gives a lot of permission in the account that are not only restricted to the GKE cluster. 30 | 31 | ### [Remote state](./remote-state/README.md) 32 | 33 | The remote state module creates a remote state storage that can be used as a state backend. 34 | 35 | ### [Network](./network/README.md) 36 | 37 | The network module create the necessary VPC and DNS Zones that will be used by the GKE clusters. 38 | 39 | ### [GKE](./gke/README.md) 40 | 41 | The GKE module provision one or more GKE clusters. 42 | 43 | ## Argo CD deployment 44 | 45 | After the GKE cluster is deployed, you can deploy ArgoCD on it and use Applications resources to provision other 46 | components. Some componenets that are dependencies for ArgoCD to work properly, such as Certificate Manager, will 47 | need to be deployed manually first. 48 | 49 | ``` 50 | kubectl apply -k cert-manager -n cert-manager 51 | kubectl apply -k argocd -n argocd 52 | // If the apply for argocd fails, run it again. It might fail the first time due to missing CRDs 53 | 54 | // Before applying the Applications, you might need to update the repoURL and targetRevision 55 | // if you are working on custom branch 56 | kubectl apply -k argoproj -n argocd 57 | ``` 58 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/gke/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "tofu init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.opentofu.org/hashicorp/external" { 5 | version = "2.3.3" 6 | constraints = ">= 2.2.2" 7 | hashes = [ 8 | "h1:bPQCwpSGRyqu3wpKkMqg9WVNTCTXGFup6QS84JgJydM=", 9 | "zh:1ec36864a1872abdfd1c53ba3c6837407564ac0d86ab80bf4fdc87b41106fe68", 10 | "zh:2117e0edbdc88f0d22fe02fe6b2cfbbbc5d5ce40f8f58e484d8d77d64dd7340f", 11 | "zh:4bcfdacd8e2508c16e131de9072cecd359e0ade3b8c6798a049883f37a5872ea", 12 | "zh:4da71bc601a37bf8b7413c142d43f5f28e97e531d4836ee8624f41b9fb62e250", 13 | "zh:55b9eebac79a46f88db5615f1ee0ac4c3f9351caa4eb8542171ef5d87de60338", 14 | "zh:74d64afaef190321f8ddf1c4a9c6489d6cf51098704a2456c1553406e8306328", 15 | "zh:8a357e51a0ec69872fafc64da3c6a1039277d325255ef5a264b727d83995d18b", 16 | "zh:aacd2e6c13fe19115d51cd28a40a28da017bb48c2e18dec4460d1c37506b1495", 17 | "zh:e19c8bdf0e059341d008a50f9138c44009e9ebb3a8047a300e6bc63ed8af8ea0", 18 | "zh:fafa9639d8b8402e35f3864c6cfb0762ec57cc365a8f383e2acf81105b1b9eea", 19 | ] 20 | } 21 | 22 | provider "registry.opentofu.org/hashicorp/google" { 23 | version = "5.17.0" 24 | constraints = ">= 3.33.0, >= 3.83.0, >= 4.25.0, >= 4.64.0, >= 5.9.0, >= 5.16.0, < 6.0.0" 25 | hashes = [ 26 | "h1:Qog6FCod/79le0BIw8wbbSIiLkJRKRaDaq2y3SgmXaM=", 27 | "zh:01648f0218256309be4e90e00a788f3b28972b96cfb42081d22074494a9b555c", 28 | "zh:07a7da07600fef779f6b89734094ce849bf7eb700d78c815144230350f8466fb", 29 | "zh:246a3759b099ae75869b2ced86a5d7f7b72e3085236ddde8c191d69cc0c078f1", 30 | "zh:98d5ce0c1f3bdb1cca5aa35f56fb5ea0879b57c6a75b1ac687913d23b37f64ff", 31 | "zh:a1ac61c63d7f6afc78653004875d156c818c5955cd60305bb2c4a89199c339ee", 32 | "zh:aa5e6b3d17c286e3b4810863e758eaf8a9c229c4630111ff39a830b5de52643b", 33 | "zh:b96f87cfed04427db6bd06db44dfe0738bc78cdcba3b5e2377b3a3e1796e57b3", 34 | "zh:db3cefe4151a9e2b220ae4491c8326b729300f5377e5f56fa51c5ad82f6d185e", 35 | "zh:e4df08febc025fdc37642e2cb70966bfe4082b34a677bc4b87055a3cfd8502c3", 36 | "zh:f7e35377c0d55d7799c1ee930bd54876d807a1db3a741ba41b87ab764810765f", 37 | ] 38 | } 39 | 40 | provider "registry.opentofu.org/hashicorp/google-beta" { 41 | version = "5.17.0" 42 | constraints = ">= 5.9.0, < 6.0.0" 43 | hashes = [ 44 | "h1:Z5djt7USYVKOPS9+hVGHpET4/xOgkeUUUo3ASiQ79bI=", 45 | "zh:2e0a389f20df8aac5236128c829de41665b8b3b844d0e47b6f5d971db3fad475", 46 | "zh:363cf32da9398f6ea1dff884414916df752aa186f2269c674a941dd5c3926e31", 47 | "zh:53f2545f53221ea672acd1037adfa9d8a0bf859a1d96c832b8beeafcb421f14f", 48 | "zh:56e9e0467dace033749904d0a6b57da09e90cf3eb4bc805d3657a21d243fed1f", 49 | "zh:59198327ee2e83ff31318151669361268908290406966f38f6110d2c34d0662c", 50 | "zh:973c711ff71fb233d4282ccacf99957d2538a6bd5bbd1a32622280792e103c51", 51 | "zh:9e272107fdbef8ebc05c11c45a3624deba996a878b252cbf20e9aba3372cd643", 52 | "zh:a34cbe3be8602c1b730def85516592fbe515c7db99c683ecd41310a1a622a98f", 53 | "zh:a421a63f2c6865e8b05c8b6acdc453d101ec949fd41184bf1e5f781d39756cf7", 54 | "zh:d9c797e8f7aafff8d92f1c84a9778caba42994df840cae0e97e1424bb926ba11", 55 | ] 56 | } 57 | 58 | provider "registry.opentofu.org/hashicorp/kubernetes" { 59 | version = "2.26.0" 60 | constraints = "~> 2.10" 61 | hashes = [ 62 | "h1:Mkxq9x2IY9gfu/i5CrgA9R7zIBTZnmHDrXfzhIJO76k=", 63 | "zh:34272a04ff826a53d2e5efcddd91b723b09a259c4e6155a53d080b49e4a6e8a8", 64 | "zh:3a79055eb0459604d21951529017928ac53fe978d98eaecae305969133e38728", 65 | "zh:7a498aee860606d861183928ac7de0b4d2185b119a65375b1144fda51312ed1c", 66 | "zh:8b1c8411994fb3e9e52ae785b697d1c15d343f348d09b0c3ba0bc49f9c3678a1", 67 | "zh:8c6f21064aa40a66520fb514c405e8a5837ca0fd476070f8df5f08da49eeaf78", 68 | "zh:b7770d11dc1328e1113993a7f03e45eb342aead05c7cb19edb647b1e147c8645", 69 | "zh:eb5b7ce9aece743e2e24035e82b9e4e4acc28ba1f0305dbf06042fa27003d3a7", 70 | "zh:f87665d082064c76c9656d2117919ad2265ff9f4031dbdd65a479b86599d1bb2", 71 | "zh:f94c9fe622b80345289aad832340ef4a4e43aefd3a1ced2be0075cd8ee55b555", 72 | "zh:fa8051dc468a6d524ca5f86b1555b42d5b999c901f65eba989a1654bd89a9907", 73 | ] 74 | } 75 | 76 | provider "registry.opentofu.org/hashicorp/null" { 77 | version = "3.2.2" 78 | constraints = ">= 2.1.0" 79 | hashes = [ 80 | "h1:sU0t6ANQ4IfEwZbbBmcNeOCg2CDCViVb7L7QVfIHrCs=", 81 | "zh:00e5877d19fb1c1d8c4b3536334a46a5c86f57146fd115c7b7b4b5d2bf2de86d", 82 | "zh:1755c2999e73e4d73f9de670c145c9a0dc5a373802799dff06a0e9c161354163", 83 | "zh:2b29d706353bc9c4edda6a2946af3322abe94372ffb421d81fa176f1e57e33be", 84 | "zh:34f65259c6d2bd51582b6da536e782b181b23725782b181193b965f519fbbacd", 85 | "zh:370f6eb744475926a1fa7464d82d46ad83c2e1148b4b21681b4cec4d75b97969", 86 | "zh:5950bdb23b4fcc6431562d7eba3dea37844aa4220c4da2eb898ae3e4d1b64ec4", 87 | "zh:8f3d5c8d4b9d497fec36953a227f80c76d37fc8431b683a23fb1c42b9cccbf8a", 88 | "zh:8f6eb5e65c047bf490ad3891efecefc488503b65898d4ee106f474697ba257d7", 89 | "zh:a7040eed688316fe00379574c72bb8c47dbe2638b038bb705647cbf224de8f72", 90 | "zh:e561f28df04d9e51b75f33004b7767a53c45ad96e3375d86181ba1363bffbc77", 91 | ] 92 | } 93 | 94 | provider "registry.opentofu.org/hashicorp/random" { 95 | version = "3.6.0" 96 | constraints = ">= 2.1.0" 97 | hashes = [ 98 | "h1:6QMZ6JACl+V2t8daN5GTlw22EtG7nhc3BbkbJDw2a5M=", 99 | "zh:486a1c921eab5c51a480f2eb0ad85173f207c9b7bb215f3893e58bc38d3b7c75", 100 | "zh:6901b3afa4607d1e31934ba91ed2625215ada42b3518c3a9adeeac7a5f656dc3", 101 | "zh:7e93752c9de710e417191353ad1a41b5a60432ab7ef4f8b556bf248297ec5e23", 102 | "zh:c795d3d319e8ee7be972746b935963b7e772a6a14080261a35c03915c1f9ccb2", 103 | "zh:cd4f8bcaf332828d1736c73874549c25e427737f136173c7b61e2df3db50e5d9", 104 | "zh:e0103eb2e280989c3d9ffda5d6b413e8f583be21bc1d5754c6e9ca87ecc1c44a", 105 | "zh:f4fbec2510322d5b7ad584a92436b5dbd0f2e897a3ec538932af59e245a4c8e4", 106 | "zh:f5418842afd4aa7676e2456e425e8f573cb2b9bffd29bd7de09d91845644ab24", 107 | "zh:f572a26f93d00ec42461ce478678366e570fa4497e2273f9d47f24cdfc4b42b4", 108 | "zh:ff1f07c561a3f7f219b6fee1647a559933b5dd6181753e164c3978fd47a11685", 109 | ] 110 | } 111 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/gke/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: help 2 | 3 | help: ## Show help 4 | @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) 5 | 6 | .DEFAULT_GOAL := help 7 | 8 | CLUSTER?=default 9 | VAR_FILE=vars/$(CLUSTER).tfvars 10 | 11 | validate-cluster: 12 | @if [ ! -f "$(VAR_FILE)" ]; then echo "File '$(VAR_FILE)' does not exist. Use CLUSTER= make $(MAKECMDGOALS)"; exit 1; fi 13 | 14 | login: ## Helper to authenticate to Google Cloud Platform 15 | gcloud auth application-default login 16 | 17 | init: ## Upgrade the terraform modules 18 | @tofu init -upgrade 19 | # Add private_cluster_config to ignore_changes because of https://github.com/terraform-google-modules/terraform-google-kubernetes-engine/issues/1876 20 | @sed -i '' 's|ignore_changes = \[node_pool, initial_node_count, resource_labels\["asmv"\]\]|ignore_changes = [node_pool, initial_node_count, resource_labels["asmv"], private_cluster_config]|' ./.terraform/modules/gke/modules/beta-private-cluster-update-variant/cluster.tf 21 | 22 | plan: init plan-fast ## Plan with latest modules available 23 | 24 | plan-fast: validate-cluster ## Plan 25 | @tofu workspace select -or-create=true "$(CLUSTER)" 26 | tofu plan -var-file="$(VAR_FILE)" -out "$(CLUSTER).tfplan" 27 | 28 | apply: ## Apply 29 | tofu apply "$(CLUSTER).tfplan" 30 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/gke/README.md: -------------------------------------------------------------------------------- 1 | # GKE Cluster module 2 | 3 | Create GKE clusters 4 | 5 | ## Known Issues 6 | 7 | - The cluster cannot be updated it's `private_cluster_config` after creation due to https://github.com/terraform-google-modules/terraform-google-kubernetes-engine/issues/1876 8 | 9 | ## Usage 10 | 11 | This modules assume you have the required permissions and an existing VPC (created by [network module](../network/README.md)). 12 | 13 | To create a new clusters, add a file under the `vars/` folder and use the cluster name as the file name. 14 | The cluster can be deployed by specifying the `CLUSTER` variable to the Make commands. 15 | 16 | ### Deploy changes 17 | 18 | To apply changes to the module, log in with a user that has been added as an admin in the [user-access module](../user-access/README.md) and run the following commands 19 | 20 | ``` 21 | CLUSTER=argo-demo-apps make plan 22 | CLUSTER=argo-demo-apps make apply 23 | ``` 24 | 25 | ## Connecting to the cluster 26 | 27 | To connect to the cluster, you can run the following command to update you Kubeconfig 28 | 29 | ``` 30 | gcloud container clusters get-credentials argo-demo-apps --region us-central1 --project argo-demo-apps 31 | ``` 32 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/gke/main.tf: -------------------------------------------------------------------------------- 1 | data "google_client_config" "default" {} 2 | 3 | data "google_project" "project" {} 4 | 5 | provider "kubernetes" { 6 | host = "https://${module.gke.endpoint}" 7 | token = data.google_client_config.default.access_token 8 | cluster_ca_certificate = base64decode(module.gke.ca_certificate) 9 | } 10 | 11 | module "gke" { 12 | source = "terraform-google-modules/kubernetes-engine/google//modules/beta-private-cluster-update-variant" 13 | version = "~> 30.0" 14 | 15 | project_id = data.google_project.project.project_id 16 | name = var.name 17 | description = var.description 18 | 19 | kubernetes_version = var.kubernetes_version 20 | release_channel = var.release_channel 21 | 22 | // Network 23 | region = var.region 24 | network = var.vpc 25 | subnetwork = local.subnet_name 26 | ip_range_pods = local.subnet_pod_range_name 27 | ip_range_services = local.subnet_service_range_name 28 | 29 | // General 30 | initial_node_count = 3 31 | datapath_provider = "ADVANCED_DATAPATH" 32 | network_policy = false 33 | remove_default_node_pool = true 34 | create_service_account = true 35 | issue_client_certificate = false 36 | 37 | 38 | // Security 39 | master_ipv4_cidr_block = var.master_range 40 | enable_private_endpoint = false // Not realy clear, but set this to true to disable the public endpoint 41 | deploy_using_private_endpoint = true 42 | enable_private_nodes = true 43 | master_global_access_enabled = false 44 | 45 | // Set to false if you need to delete/recreate the cluster 46 | deletion_protection = true 47 | 48 | depends_on = [ 49 | module.subnet 50 | ] 51 | 52 | } 53 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/gke/network.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | subnet_name = "${var.name}-gke" 3 | subnet_pod_range_name = "${local.subnet_name}-pods" 4 | subnet_service_range_name = "${local.subnet_name}-services" 5 | } 6 | 7 | data "google_compute_network" "vpc" { 8 | name = var.vpc 9 | } 10 | 11 | data "google_compute_router" "router" { 12 | name = var.vpc 13 | network = data.google_compute_network.vpc.name 14 | } 15 | 16 | module "subnet" { 17 | source = "terraform-google-modules/network/google//modules/subnets" 18 | version = "~> 9.0" 19 | 20 | project_id = data.google_project.project.project_id 21 | network_name = data.google_compute_network.vpc.name 22 | 23 | subnets = [ 24 | { 25 | subnet_name = local.subnet_name 26 | description = "Subnet for the GKE cluster ${var.name}" 27 | subnet_ip = var.subnet_range 28 | subnet_region = var.region 29 | subnet_private_access = true 30 | }, 31 | ] 32 | secondary_ranges = { 33 | "${local.subnet_name}" = [ 34 | { 35 | range_name = local.subnet_pod_range_name 36 | ip_cidr_range = var.pod_range 37 | }, 38 | { 39 | range_name = local.subnet_service_range_name 40 | ip_cidr_range = var.service_range 41 | } 42 | ] 43 | } 44 | } 45 | 46 | module "cloud-nat" { 47 | source = "terraform-google-modules/cloud-nat/google" 48 | version = "~> 5.0" 49 | 50 | project_id = data.google_project.project.project_id 51 | region = var.region 52 | router = data.google_compute_router.router.name 53 | name = "${var.name}-gke" 54 | 55 | source_subnetwork_ip_ranges_to_nat = "LIST_OF_SUBNETWORKS" 56 | subnetworks = [ 57 | { 58 | name = module.subnet.subnets["${var.region}/${local.subnet_name}"].id 59 | source_ip_ranges_to_nat = ["PRIMARY_IP_RANGE", "LIST_OF_SECONDARY_IP_RANGES"] 60 | secondary_ip_range_names = module.subnet.subnets["${var.region}/${local.subnet_name}"].secondary_ip_range[*].range_name 61 | } 62 | ] 63 | 64 | } 65 | 66 | 67 | module "cluster-dns" { 68 | source = "terraform-google-modules/cloud-dns/google" 69 | version = "~> 5.0" 70 | 71 | project_id = data.google_project.project.project_id 72 | type = "private" 73 | name = var.name 74 | domain = "${var.name}.cluster." 75 | 76 | private_visibility_config_networks = [data.google_compute_network.vpc.self_link] 77 | 78 | recordsets = [ 79 | { 80 | name = "ns" 81 | type = "A" 82 | ttl = 300 83 | records = [ 84 | "127.0.0.1", 85 | ] 86 | }, 87 | { 88 | name = "" 89 | type = "NS" 90 | ttl = 300 91 | records = [ 92 | "ns.${var.name}.cluster.", 93 | ] 94 | }, 95 | { 96 | name = "localhost" 97 | type = "A" 98 | ttl = 300 99 | records = [ 100 | "127.0.0.1", 101 | ] 102 | }, 103 | { 104 | name = "" 105 | type = "MX" 106 | ttl = 300 107 | records = [ 108 | "1 localhost.", 109 | ] 110 | }, 111 | { 112 | name = "" 113 | type = "TXT" 114 | ttl = 300 115 | records = [ 116 | "\"v=spf1 -all\"", 117 | ] 118 | }, 119 | ] 120 | } 121 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/gke/outputs.tf: -------------------------------------------------------------------------------- 1 | output "name" { 2 | description = "Cluster name" 3 | value = module.gke.name 4 | } 5 | 6 | output "location" { 7 | description = "Cluster location (region if regional cluster, zone if zonal cluster)" 8 | value = module.gke.location 9 | } 10 | 11 | output "zones" { 12 | description = "List of zones in which the cluster resides" 13 | value = module.gke.zones 14 | } 15 | 16 | output "endpoint" { 17 | sensitive = true 18 | description = "Cluster endpoint" 19 | value = module.gke.endpoint 20 | } 21 | 22 | output "master_version" { 23 | description = "Current master kubernetes version" 24 | value = module.gke.master_version 25 | } 26 | 27 | output "ca_certificate" { 28 | sensitive = true 29 | description = "Cluster ca certificate (base64 encoded)" 30 | value = module.gke.ca_certificate 31 | } 32 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/gke/providers.tf: -------------------------------------------------------------------------------- 1 | provider "google" { 2 | project = "argo-demo-apps" 3 | region = "us-central1" 4 | 5 | default_labels = { 6 | "managed-by" = "terraform" 7 | "github-org" = "argoproj" 8 | "github-repo" = "argoproj-deployments" 9 | "module" = "gke" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/gke/terraform.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | backend "gcs" { 5 | bucket = "7612a8-argoproj-bucket-tfstate" 6 | prefix = "tf/gke" 7 | } 8 | 9 | required_providers { 10 | google = { 11 | source = "hashicorp/google" 12 | version = ">= 5.16" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/gke/variables.tf: -------------------------------------------------------------------------------- 1 | variable "name" { 2 | type = string 3 | description = "The name of the cluster (required)" 4 | } 5 | 6 | variable "description" { 7 | type = string 8 | description = "The description of the cluster" 9 | default = "" 10 | } 11 | 12 | variable "region" { 13 | type = string 14 | description = "The region to host the cluster in (optional if zonal cluster / required if regional)" 15 | default = null 16 | } 17 | 18 | variable "kubernetes_version" { 19 | type = string 20 | description = "The Kubernetes version of the masters. If set to 'latest' it will pull latest available version in the selected region." 21 | default = "latest" 22 | } 23 | 24 | variable "release_channel" { 25 | type = string 26 | description = "The release channel of this cluster. Accepted values are `UNSPECIFIED`, `RAPID`, `REGULAR` and `STABLE`. Defaults to `REGULAR`." 27 | default = "REGULAR" 28 | } 29 | 30 | variable "vpc" { 31 | type = string 32 | description = "The VPC network name" 33 | } 34 | 35 | variable "subnet_range" { 36 | type = string 37 | description = "Subnet CIDR" 38 | } 39 | 40 | variable "pod_range" { 41 | type = string 42 | description = "Subnet secondary CIDR for pods" 43 | } 44 | 45 | variable "service_range" { 46 | type = string 47 | description = "Subnet secondary CIDR for services" 48 | } 49 | 50 | variable "master_range" { 51 | type = string 52 | description = "The IP range in CIDR notation to use for the hosted master network" 53 | } 54 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/gke/vars/argo-demo-apps.tfvars: -------------------------------------------------------------------------------- 1 | name = "argo-demo-apps" 2 | description = "Cluster for deploying https://github.com/argoproj/argoproj-deployments" 3 | region = "us-central1" 4 | kubernetes_version = "1.29" 5 | release_channel = "RAPID" 6 | 7 | vpc = "gke-vpc" 8 | subnet_range = "10.0.0.0/22" 9 | pod_range = "10.192.0.0/14" 10 | service_range = "10.196.0.0/16" 11 | master_range = "172.16.0.0/28" 12 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/gke/workload_identity.tf: -------------------------------------------------------------------------------- 1 | module "external-dns-identity" { 2 | source = "terraform-google-modules/kubernetes-engine/google//modules/workload-identity" 3 | version = "~> 30.0" 4 | 5 | project_id = data.google_project.project.project_id 6 | use_existing_k8s_sa = true 7 | annotate_k8s_sa = false 8 | cluster_name = var.name 9 | location = var.region 10 | name = "external-dns" 11 | namespace = "external-dns" 12 | roles = ["roles/dns.admin"] 13 | } 14 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/network/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "tofu init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.opentofu.org/hashicorp/google" { 5 | version = "5.18.0" 6 | constraints = ">= 3.33.0, >= 3.83.0, >= 4.25.0, >= 4.40.0, >= 4.51.0, >= 4.64.0, >= 5.16.0, < 6.0.0" 7 | hashes = [ 8 | "h1:lVcM4pwE6U3r6HM8n2DMHDdIElflFh6ZqVqaGOk36Dg=", 9 | "zh:02e755030e5ea87eefda0f8bb3e6b53df2d2578144c92b4daa21d42336386b83", 10 | "zh:25c3eb7ec7654f4955abcc700d91e9bc7f0ef196508702194351a97dabc087b9", 11 | "zh:6dc9014d91bcbb21546e561fe465aed9c8a69b4d465414f8723026b4b47abaea", 12 | "zh:876fcb3c32a72b21e61fcfac34cc6749edb7247628165eda2e2a3f0282f8e6a0", 13 | "zh:ac6d119350be3a4463cff3f7b6c7d86abeaee279d01c9c344571eff7d945180a", 14 | "zh:c28036b74c81007770fe97aae594e2d797eeff51a4807bb37be3891df3109194", 15 | "zh:d06bac750620247344ea2d57196bdd8e1daed68fe0005a028d059e89116dfe31", 16 | "zh:d4dbeddfe7bb80e0df8d26ff706d8c897e3e82698f3402b2659050704c0789e0", 17 | "zh:d604b24b5001da7743f4ce5036e4ef17f7cc54478f7cb327144cef3760e05bf3", 18 | "zh:e1b8a575928c5bbaa7afa7267474a1bc52da4e9ac526343dfbcc3ef95584fe61", 19 | ] 20 | } 21 | 22 | provider "registry.opentofu.org/hashicorp/google-beta" { 23 | version = "5.18.0" 24 | constraints = ">= 4.40.0, >= 4.64.0, < 6.0.0" 25 | hashes = [ 26 | "h1:RH3haZP/GWtzE0dF3YzGBVucMPceZWmsF6iAG2cXS+o=", 27 | "zh:23d18afe875de1724e734f15fa9bf82db43de212358d7983b3204602e9bea256", 28 | "zh:4cfbc49c5823d7f2f99cb45b6ae16bed02b35f9127c6fd5f15e00565cd93b90d", 29 | "zh:65de3376e6ba4adac31ce6e8f68721f0fb596c63010ed3284a15882f1201dddd", 30 | "zh:b1b7e746f8625246f86dc2751eca7f3a6b6ee625f830c7d7d5cee0fb05bf3baa", 31 | "zh:c5e28345b957a833edd68f5ce4a43a357598fa32f83e236042c74df84a91e408", 32 | "zh:c94a1c61ffb915926c45c7b2d50bdc8ad0441065557c177437c25887aa6ae2da", 33 | "zh:dfaab0ddc5be49db46a943d9802a317fbf29cf413af1d979d34e939a7356a40d", 34 | "zh:ec22f31a10d7b73ae8f442689d032c0e10ac3b412e97c965a8eb79f0c446a6a6", 35 | "zh:f11a24a6cd4244aa8dff60dd59fb7c31d84c327a2947d79bc827e46fbbae6b1c", 36 | "zh:fff507cc871736378f8788a53d179b06ebcfe1f025a2636d414526408c52bb74", 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/network/Makefile: -------------------------------------------------------------------------------- 1 | 2 | login: 3 | gcloud auth application-default login 4 | 5 | plan: 6 | tofu init -upgrade && tofu plan -out default.tfplan 7 | 8 | apply: 9 | tofu apply default.tfplan 10 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/network/README.md: -------------------------------------------------------------------------------- 1 | # Remote state module 2 | 3 | This module creates a VPC and DNS zone that can be used by GKE clusters. 4 | 5 | ## Requirements 6 | 7 | - OpenTofu (>= 1.6) 8 | - GCloud CLI (>= 464.0.0) 9 | 10 | ## Usage 11 | 12 | ### Deploy changes 13 | 14 | To apply changes to the module, log in with a user that has been added as an admin in the [user-access module](../user-access/README.md) and run the following commands 15 | 16 | ``` 17 | make plan 18 | 19 | make apply 20 | ``` 21 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/network/default.auto.tfvars: -------------------------------------------------------------------------------- 1 | vpc_name = "gke-vpc" 2 | regions = ["us-central1"] 3 | zones = ["apps", "demo", "dev"] 4 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/network/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | argoproj_domain = "argoproj.io." 3 | } 4 | 5 | data "google_project" "project" {} 6 | 7 | module "vpc" { 8 | source = "terraform-google-modules/network/google" 9 | version = "~> 9.0" 10 | 11 | project_id = data.google_project.project.project_id 12 | network_name = var.vpc_name 13 | subnets = [] 14 | 15 | routing_mode = "REGIONAL" 16 | } 17 | 18 | resource "google_compute_firewall" "rules" { 19 | project = data.google_project.project.project_id 20 | name = "allow-ssh" 21 | network = module.vpc.network_name 22 | allow { 23 | protocol = "tcp" 24 | ports = ["22"] 25 | } 26 | source_ranges = ["35.235.240.0/20"] 27 | } 28 | 29 | module "cloud_router" { 30 | for_each = var.regions 31 | 32 | source = "terraform-google-modules/cloud-router/google" 33 | version = "~> 6.0" 34 | 35 | name = var.vpc_name 36 | project = data.google_project.project.project_id 37 | network = module.vpc.network_name 38 | region = each.value 39 | } 40 | 41 | # module "argoproj-dns-root" { 42 | # source = "terraform-google-modules/cloud-dns/google" 43 | # version = "~> 5.0" 44 | 45 | # project_id = data.google_project.project.project_id 46 | # type = "public" 47 | # name = "argoproj-io" 48 | # domain = local.argoproj_domain 49 | 50 | # enable_logging = false 51 | 52 | # private_visibility_config_networks = [module.vpc.network_self_link] 53 | 54 | # recordsets = [for key, dns in module.argoproj-dns : 55 | # { 56 | # name = key 57 | # records = dns.name_servers 58 | # ttl = 300 59 | # type = "NS" 60 | # } 61 | # ] 62 | # } 63 | 64 | module "argoproj-dns" { 65 | for_each = var.zones 66 | source = "terraform-google-modules/cloud-dns/google" 67 | version = "~> 5.0" 68 | 69 | project_id = data.google_project.project.project_id 70 | type = "public" 71 | name = replace(trimsuffix("${each.value}.${local.argoproj_domain}", "."), ".", "-") 72 | domain = "${each.value}.${local.argoproj_domain}" 73 | 74 | force_destroy = false // Set to true to delete the zones with records 75 | 76 | private_visibility_config_networks = [module.vpc.network_self_link] 77 | } 78 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/network/outputs.tf: -------------------------------------------------------------------------------- 1 | output "name" { 2 | description = "VPC Name" 3 | value = module.vpc.network_name 4 | } 5 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/network/providers.tf: -------------------------------------------------------------------------------- 1 | provider "google" { 2 | project = "argo-demo-apps" 3 | region = "us-central1" 4 | 5 | default_labels = { 6 | "managed-by" = "terraform" 7 | "github-org" = "argoproj" 8 | "github-repo" = "argoproj-deployments" 9 | "module" = "network" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/network/terraform.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | backend "gcs" { 5 | bucket = "7612a8-argoproj-bucket-tfstate" 6 | prefix = "tf/network" 7 | } 8 | 9 | required_providers { 10 | google = { 11 | source = "hashicorp/google" 12 | version = ">= 5.16" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/network/variables.tf: -------------------------------------------------------------------------------- 1 | variable "vpc_name" { 2 | type = string 3 | description = "The named used by the VPC" 4 | } 5 | 6 | variable "regions" { 7 | type = set(string) 8 | description = "The regions that will host clusters" 9 | default = [] 10 | } 11 | 12 | variable "zones" { 13 | type = set(string) 14 | description = "Zones under the argoproj.io domain" 15 | default = [] 16 | } 17 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/remote-state/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "tofu init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.opentofu.org/hashicorp/google" { 5 | version = "5.16.0" 6 | constraints = ">= 5.16.0" 7 | hashes = [ 8 | "h1:+GSiA1YWYgTrLxhY2rzO/P+1goOsXLt4zJ4UrLCjIDU=", 9 | "zh:541efb51efe68e42c43f95955f689dc7eee8de8a21a0725acf92b54947b4cefa", 10 | "zh:57c4304425d48beea3297360d006ce8b86d24f21bbbcdf211c60876c5225f0a2", 11 | "zh:648e8fd180f7e82fbd8ba089e576fffb43c15a5bb7f5bb130f1a05e645d01a20", 12 | "zh:69eb44111086304146fad59302aba43ffe7d7747e17626ad3c0aea4b2297a200", 13 | "zh:921aa243f986288223b70787a07dc2b24792ad3037f211e014d4f021873ac804", 14 | "zh:a03787e5605b1dec236771d2a84e27941bd598711ea80c618716b0cbd74daa0d", 15 | "zh:bbe6f6e32818af2b9c0367423d8965d60ab3875f572d84b48c5ed9d18e4dd046", 16 | "zh:bfd29dd65735efa60e52c2e0e13ff37f1aa7c3ee9fc30762b27e5e7938a0b43a", 17 | "zh:d3a95df117047cbf3fb18fda6da92dfbd2148e1db126976324f04bfc562fb2ae", 18 | "zh:f27bbccfff36a0dd0857dea2920bdcff1e55b97f11ac8513fb859f744db02b1e", 19 | ] 20 | } 21 | 22 | provider "registry.opentofu.org/hashicorp/random" { 23 | version = "3.6.0" 24 | hashes = [ 25 | "h1:6QMZ6JACl+V2t8daN5GTlw22EtG7nhc3BbkbJDw2a5M=", 26 | "zh:486a1c921eab5c51a480f2eb0ad85173f207c9b7bb215f3893e58bc38d3b7c75", 27 | "zh:6901b3afa4607d1e31934ba91ed2625215ada42b3518c3a9adeeac7a5f656dc3", 28 | "zh:7e93752c9de710e417191353ad1a41b5a60432ab7ef4f8b556bf248297ec5e23", 29 | "zh:c795d3d319e8ee7be972746b935963b7e772a6a14080261a35c03915c1f9ccb2", 30 | "zh:cd4f8bcaf332828d1736c73874549c25e427737f136173c7b61e2df3db50e5d9", 31 | "zh:e0103eb2e280989c3d9ffda5d6b413e8f583be21bc1d5754c6e9ca87ecc1c44a", 32 | "zh:f4fbec2510322d5b7ad584a92436b5dbd0f2e897a3ec538932af59e245a4c8e4", 33 | "zh:f5418842afd4aa7676e2456e425e8f573cb2b9bffd29bd7de09d91845644ab24", 34 | "zh:f572a26f93d00ec42461ce478678366e570fa4497e2273f9d47f24cdfc4b42b4", 35 | "zh:ff1f07c561a3f7f219b6fee1647a559933b5dd6181753e164c3978fd47a11685", 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/remote-state/Makefile: -------------------------------------------------------------------------------- 1 | 2 | login: 3 | gcloud auth application-default login 4 | 5 | plan: 6 | tofu init -upgrade && tofu plan -out default.tfplan 7 | 8 | apply: 9 | tofu apply default.tfplan 10 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/remote-state/README.md: -------------------------------------------------------------------------------- 1 | # Remote state module 2 | 3 | This module creates a bucket that will store the Terraform remote state used by different modules. 4 | 5 | ## Requirements 6 | 7 | - OpenTofu (>= 1.6) 8 | - GCloud CLI (>= 464.0.0) 9 | 10 | ## Usage 11 | 12 | ### Initialization 13 | 14 | **These steps are only required the first time this module is initialized in a GCP project.** 15 | 16 | To initialize the module, it needs to be deployed locally, then imported in the remote state. 17 | 18 | 1. First, run the `./user-access` module. Follow the instructions in the [user-access module](../user-access/README.md). 19 | 2. Run this module with `make plan && make apply` to create the remote storage. 20 | 3. When the remote storage is created, add the `backend` configuration to the `terraform.tf` file. 21 | 4. Finally, run `make plan` again. It will ask you if you want to migrate your local state file to the remote state. Enter `yes`. Delete the local state files on success. 22 | 23 | ### Deploy changes 24 | 25 | 26 | To apply changes to the module, log in with a user that has been added as an admin in the [user-access module](../user-access/README.md) and run the following commands 27 | 28 | ``` 29 | make plan 30 | 31 | make apply 32 | ``` 33 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/remote-state/default.auto.tfvars: -------------------------------------------------------------------------------- 1 | bucket_name = "argoproj" 2 | location = "US" 3 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/remote-state/main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | bucket_name = "${random_id.bucket_prefix.hex}-${var.bucket_name}-bucket-tfstate" 3 | } 4 | 5 | data "google_project" "project" { 6 | } 7 | 8 | resource "google_project_iam_member" "default" { 9 | project = data.google_project.project.project_id 10 | role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" 11 | member = "serviceAccount:service-${data.google_project.project.number}@gs-project-accounts.iam.gserviceaccount.com" 12 | } 13 | 14 | resource "random_id" "bucket_prefix" { 15 | byte_length = 3 16 | } 17 | 18 | resource "google_storage_bucket" "state" { 19 | name = "${random_id.bucket_prefix.hex}-${var.bucket_name}-bucket-tfstate" 20 | force_destroy = false 21 | location = upper(var.location) 22 | storage_class = "STANDARD" 23 | public_access_prevention = "enforced" 24 | 25 | versioning { 26 | enabled = true 27 | } 28 | 29 | lifecycle { 30 | prevent_destroy = true 31 | } 32 | 33 | encryption { 34 | default_kms_key_name = google_kms_crypto_key.state_bucket.id 35 | } 36 | 37 | depends_on = [ 38 | google_project_iam_member.default 39 | ] 40 | } 41 | 42 | resource "google_kms_key_ring" "state" { 43 | name = local.bucket_name 44 | location = lower(var.location) 45 | } 46 | 47 | resource "google_kms_crypto_key" "state_bucket" { 48 | name = "tf-state-bucket" 49 | key_ring = google_kms_key_ring.state.id 50 | rotation_period = "86400s" 51 | 52 | lifecycle { 53 | prevent_destroy = false 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/remote-state/outputs.tf: -------------------------------------------------------------------------------- 1 | output "name" { 2 | description = "Bucket name" 3 | value = google_storage_bucket.state.name 4 | } 5 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/remote-state/providers.tf: -------------------------------------------------------------------------------- 1 | provider "google" { 2 | project = "argo-demo-apps" 3 | region = "us-central1" 4 | 5 | default_labels = { 6 | "managed-by" = "terraform" 7 | "github-org" = "argoproj" 8 | "github-repo" = "argoproj-deployments" 9 | "module" = "remote-state" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/remote-state/terraform.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | backend "gcs" { 5 | bucket = "7612a8-argoproj-bucket-tfstate" 6 | prefix = "tf/remote-state" 7 | } 8 | 9 | required_providers { 10 | google = { 11 | source = "hashicorp/google" 12 | version = ">= 5.16" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/remote-state/variables.tf: -------------------------------------------------------------------------------- 1 | variable "bucket_name" { 2 | type = string 3 | description = "A name that will be used to create the full bucket name" 4 | } 5 | 6 | variable "location" { 7 | description = "The location of the bucket" 8 | type = string 9 | default = "us" 10 | } 11 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/user-access/.terraform.lock.hcl: -------------------------------------------------------------------------------- 1 | # This file is maintained automatically by "tofu init". 2 | # Manual edits may be lost in future updates. 3 | 4 | provider "registry.opentofu.org/hashicorp/google" { 5 | version = "5.17.0" 6 | constraints = ">= 5.16.0" 7 | hashes = [ 8 | "h1:Qog6FCod/79le0BIw8wbbSIiLkJRKRaDaq2y3SgmXaM=", 9 | "zh:01648f0218256309be4e90e00a788f3b28972b96cfb42081d22074494a9b555c", 10 | "zh:07a7da07600fef779f6b89734094ce849bf7eb700d78c815144230350f8466fb", 11 | "zh:246a3759b099ae75869b2ced86a5d7f7b72e3085236ddde8c191d69cc0c078f1", 12 | "zh:98d5ce0c1f3bdb1cca5aa35f56fb5ea0879b57c6a75b1ac687913d23b37f64ff", 13 | "zh:a1ac61c63d7f6afc78653004875d156c818c5955cd60305bb2c4a89199c339ee", 14 | "zh:aa5e6b3d17c286e3b4810863e758eaf8a9c229c4630111ff39a830b5de52643b", 15 | "zh:b96f87cfed04427db6bd06db44dfe0738bc78cdcba3b5e2377b3a3e1796e57b3", 16 | "zh:db3cefe4151a9e2b220ae4491c8326b729300f5377e5f56fa51c5ad82f6d185e", 17 | "zh:e4df08febc025fdc37642e2cb70966bfe4082b34a677bc4b87055a3cfd8502c3", 18 | "zh:f7e35377c0d55d7799c1ee930bd54876d807a1db3a741ba41b87ab764810765f", 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/user-access/Makefile: -------------------------------------------------------------------------------- 1 | 2 | login: 3 | gcloud auth application-default login 4 | 5 | plan: 6 | tofu init -upgrade && tofu plan -var-file=vars/default.tfvars -out default.tfplan 7 | 8 | apply: 9 | tofu apply default.tfplan 10 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/user-access/README.md: -------------------------------------------------------------------------------- 1 | # User Access module 2 | 3 | Manages IAM permissions in the GCP project. 4 | 5 | ## Requirements 6 | 7 | - OpenTofu (>= 1.6) 8 | - GCloud CLI (>= 464.0.0) 9 | 10 | ## Usage 11 | 12 | In this module, you can use the `users` and `admins` variables to give the necessary permissions in the GCP project to deploy the different terraform modules for Argo. 13 | 14 | ### Initialization 15 | 16 | **These steps are only required the first time this module is initialized in a GCP project.** 17 | 18 | To initialize the permission, the module needs to be deployed locally, then imported in the remote state. 19 | 20 | 1. First, run the `./user-access` module without specifying a `state_bucket`. Add your user as part of the `admins` list. This requires at least the permissions from the roles `roles/iam.roleAdmin` and `roles/resourcemanager.projectIamAdmin` to be already given to the current user in the project. 21 | 2. After the module is applied, you need to create the remote state. Follow the instructions in the [remote-state module](../remote-state/README.md). 22 | 3. When the remote state is created, update the variable `state_bucket`, and add the `backend` configuration to the `terraform.tf` file. 23 | 4. Finally, run `make plan`. It will ask you if you want to migrate your local state file to the remote state. Enter `yes`. Delete the local state files on success. 24 | 25 | ### Deploy changes 26 | 27 | To apply changes to the module, log in with a user that is currently an admin and run the following commands 28 | 29 | ``` 30 | make plan 31 | 32 | make apply 33 | ``` 34 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/user-access/main.tf: -------------------------------------------------------------------------------- 1 | # https://cloud.google.com/iam/docs/permissions-reference 2 | 3 | locals { 4 | users = distinct(concat(var.admins, var.users)) 5 | user_roles = [ 6 | "iam.roleViewer", 7 | "container.viewer", 8 | ] 9 | admin_roles = [ 10 | "viewer", 11 | "cloudkms.admin", // Create remote-state bucket 12 | "compute.networkAdmin", // Create VPC 13 | "iam.serviceAccountAdmin", // Create Cluster 14 | "iam.serviceAccountUser", // Create Cluster 15 | "container.admin", // Create Cluster 16 | "iap.tunnelResourceAccessor", // SSH to nodes 17 | "compute.admin", // SSH to nodes 18 | "dns.admin" // Create cluster DNS zone 19 | ] 20 | } 21 | 22 | data "google_project" "project" {} 23 | 24 | # This group should be given to terraform deployer with elevated permissions because it allows to give 25 | resource "google_project_iam_custom_role" "terraform-deployer-iam" { 26 | role_id = "terraformDeployerIAM" 27 | title = "Terraform Deployer IAM" 28 | description = "Role used to deploy terraform IAM resources" 29 | permissions = [ 30 | // roles/iam.roleAdmin 31 | "iam.roles.create", 32 | "iam.roles.delete", 33 | "iam.roles.get", 34 | "iam.roles.list", 35 | "iam.roles.undelete", 36 | "iam.roles.update", 37 | "resourcemanager.projects.get", 38 | "resourcemanager.projects.getIamPolicy", 39 | 40 | // roles/resourcemanager.projectIamAdmin 41 | "resourcemanager.projects.setIamPolicy", 42 | 43 | // Allow to create s3 bucket (everything but delete) 44 | "storage.buckets.create", 45 | "storage.buckets.createTagBinding", 46 | "storage.buckets.deleteTagBinding", 47 | "storage.buckets.enableObjectRetention", 48 | "storage.buckets.get", 49 | "storage.buckets.getIamPolicy", 50 | "storage.buckets.getObjectInsights", 51 | "storage.buckets.list", 52 | "storage.buckets.listEffectiveTags", 53 | "storage.buckets.listTagBindings", 54 | "storage.buckets.setIamPolicy", 55 | "storage.buckets.update", 56 | ] 57 | } 58 | 59 | resource "google_project_iam_custom_role" "terraform-deployer" { 60 | role_id = "terraformDeployer" 61 | title = "Terraform Deployer" 62 | description = "Role used to deploy terraform locally" 63 | permissions = [ 64 | // roles/iam.roleViewer 65 | "iam.roles.list", 66 | "iam.roles.get", 67 | "resourcemanager.projects.get", 68 | "resourcemanager.projects.getIamPolicy", 69 | 70 | // Create GKE modules 71 | 72 | ] 73 | } 74 | 75 | resource "google_project_iam_binding" "terraform-deployer-iam" { 76 | project = data.google_project.project.project_id 77 | role = google_project_iam_custom_role.terraform-deployer-iam.name 78 | 79 | members = var.admins 80 | } 81 | 82 | resource "google_project_iam_binding" "terraform-deployer" { 83 | project = data.google_project.project.project_id 84 | role = google_project_iam_custom_role.terraform-deployer.name 85 | 86 | members = local.users 87 | } 88 | 89 | resource "google_project_iam_binding" "users" { 90 | for_each = toset(local.user_roles) 91 | 92 | project = data.google_project.project.project_id 93 | role = "roles/${each.key}" 94 | members = local.users 95 | } 96 | 97 | resource "google_project_iam_binding" "admins" { 98 | for_each = toset(local.admin_roles) 99 | 100 | project = data.google_project.project.project_id 101 | role = "roles/${each.key}" 102 | members = var.admins 103 | } 104 | 105 | resource "google_storage_bucket_iam_binding" "binding" { 106 | count = var.state_bucket != "" ? 1 : 0 107 | 108 | bucket = var.state_bucket 109 | role = "roles/storage.objectUser" 110 | members = local.users 111 | } 112 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/user-access/providers.tf: -------------------------------------------------------------------------------- 1 | provider "google" { 2 | project = "argo-demo-apps" 3 | region = "us-central1" 4 | 5 | default_labels = { 6 | "managed-by" = "terraform" 7 | "github-org" = "argoproj" 8 | "github-repo" = "argoproj-deployments" 9 | "module" = "user-access" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/user-access/terraform.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = ">= 1.6" 3 | 4 | backend "gcs" { 5 | bucket = "7612a8-argoproj-bucket-tfstate" 6 | prefix = "tf/user-access" 7 | } 8 | 9 | required_providers { 10 | google = { 11 | source = "hashicorp/google" 12 | version = ">= 5.16" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/user-access/variables.tf: -------------------------------------------------------------------------------- 1 | variable "admins" { 2 | type = list(string) 3 | description = "List of principal that have the permission to manage IAM and remotate state for the project" 4 | default = [] 5 | } 6 | 7 | variable "users" { 8 | description = "List of principal that have the permission to manage the project" 9 | type = list(string) 10 | default = [] 11 | } 12 | 13 | variable "state_bucket" { 14 | description = "The terraform remote state bucket. When specified, it will give permission to users to use the remote state" 15 | type = string 16 | default = "" 17 | } 18 | -------------------------------------------------------------------------------- /infrastructure/terraform/gcp/user-access/vars/.gitignore: -------------------------------------------------------------------------------- 1 | ### Currently, personal gmails are in the variable file. 2 | ### Exclude it for now to not expose them until a data source 3 | ### is decided to store them. 4 | *.tfvars 5 | -------------------------------------------------------------------------------- /istio-controlplane/istio-controlplane.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: install.istio.io/v1alpha1 2 | kind: IstioOperator 3 | metadata: 4 | namespace: istio-system 5 | name: istio-controlplane 6 | spec: 7 | profile: demo 8 | -------------------------------------------------------------------------------- /prometheus-operator/README.md: -------------------------------------------------------------------------------- 1 | # Prometheus Operator 2 | 3 | ## Deployment 4 | 5 | ### Initial 6 | 7 | The prometheus-operator deployment hydrate the manifests in the source code. 8 | This will cause the generated secrets to be in plain text in the source control. 9 | Kustomize is configured to ignore the secrets in code. Instead, an initial secret 10 | will need to be configured manually. 11 | 12 | Add the `admin-password` key to the secret with a base64 encoded value 13 | 14 | ``` 15 | kubectl edit secret prometheus-operator-grafana 16 | ``` 17 | 18 | ### Update chart 19 | 20 | Update the version in the `upstream/Chart.yaml` and run `./upstream.sh` locally to download the manifest, 21 | then commit or apply manually with kustomize. 22 | -------------------------------------------------------------------------------- /prometheus-operator/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - ./resources/upstream.yaml 3 | - ./resources/argocd-metrics-servicemonitor.yaml 4 | - ./resources/argocd-server-metrics-servicemonitor.yaml 5 | - ./resources/argocd-repo-server-metrics-servicemonitor.yaml 6 | - ./resources/argocd-notifications-controller-metrics-servicemonitor.yaml 7 | - ./resources/grafana-certificate.yaml 8 | - ./resources/grafana-ingress.yaml 9 | - ./resources/grafana-issuer.yaml 10 | 11 | generatorOptions: 12 | disableNameSuffixHash: true 13 | labels: 14 | grafana_dashboard: argocd 15 | 16 | configMapGenerator: 17 | - name: argocd-dashboard-cm 18 | files: 19 | - dashboard.json 20 | 21 | patchesJson6902: 22 | - target: 23 | name: prometheus-operator-grafana 24 | namespace: prometheus-operator 25 | version: v1 26 | kind: Secret 27 | path: overlays/prometheus-operator-grafana-secret.yaml 28 | - target: 29 | name: .* 30 | version: v1 31 | group: apiextensions.k8s.io 32 | kind: CustomResourceDefinition 33 | path: overlays/prometheus-crds-annotations.yaml 34 | 35 | patchesStrategicMerge: 36 | - overlays/prometheus-operator-grafana-cm.yaml 37 | -------------------------------------------------------------------------------- /prometheus-operator/overlays/prometheus-crds-annotations.yaml: -------------------------------------------------------------------------------- 1 | - op: add 2 | path: '/metadata/annotations/argocd.argoproj.io~1sync-options' 3 | value: ServerSideApply=true 4 | -------------------------------------------------------------------------------- /prometheus-operator/overlays/prometheus-operator-grafana-cm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | grafana.ini: | 4 | [analytics] 5 | check_for_updates = true 6 | [grafana_net] 7 | url = https://grafana.net 8 | [log] 9 | mode = console 10 | [paths] 11 | data = /var/lib/grafana/data 12 | logs = /var/log/grafana 13 | plugins = /var/lib/grafana/plugins 14 | provisioning = /etc/grafana/provisioning 15 | [auth.anonymous] 16 | enabled = true 17 | kind: ConfigMap 18 | metadata: 19 | name: prometheus-operator-grafana 20 | namespace: prometheus-operator 21 | -------------------------------------------------------------------------------- /prometheus-operator/overlays/prometheus-operator-grafana-secret.yaml: -------------------------------------------------------------------------------- 1 | - op: remove 2 | path: /data/admin-password 3 | -------------------------------------------------------------------------------- /prometheus-operator/resources/argocd-metrics-servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: ServiceMonitor 3 | metadata: 4 | name: argocd-metrics 5 | labels: 6 | release: prometheus-operator 7 | spec: 8 | selector: 9 | matchLabels: 10 | app.kubernetes.io/name: argocd-metrics 11 | endpoints: 12 | - port: metrics 13 | namespaceSelector: 14 | any: true -------------------------------------------------------------------------------- /prometheus-operator/resources/argocd-notifications-controller-metrics-servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: ServiceMonitor 3 | metadata: 4 | name: argocd-notifications-controller-metrics 5 | labels: 6 | release: prometheus-operator 7 | spec: 8 | selector: 9 | matchLabels: 10 | app.kubernetes.io/name: argocd-notifications-controller-metrics 11 | endpoints: 12 | - port: metrics 13 | namespaceSelector: 14 | any: true -------------------------------------------------------------------------------- /prometheus-operator/resources/argocd-repo-server-metrics-servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: ServiceMonitor 3 | metadata: 4 | name: argocd-repo-server-metrics 5 | labels: 6 | release: prometheus-operator 7 | spec: 8 | selector: 9 | matchLabels: 10 | app.kubernetes.io/name: argocd-repo-server 11 | endpoints: 12 | - port: metrics 13 | namespaceSelector: 14 | any: true 15 | -------------------------------------------------------------------------------- /prometheus-operator/resources/argocd-server-metrics-servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: ServiceMonitor 3 | metadata: 4 | name: argocd-server-metrics 5 | labels: 6 | release: prometheus-operator 7 | spec: 8 | selector: 9 | matchLabels: 10 | app.kubernetes.io/name: argocd-server-metrics 11 | endpoints: 12 | - port: metrics 13 | namespaceSelector: 14 | any: true -------------------------------------------------------------------------------- /prometheus-operator/resources/grafana-certificate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Certificate 3 | metadata: 4 | name: grafana-cert 5 | spec: 6 | secretName: grafana-tls 7 | issuerRef: 8 | name: grafana-issuer 9 | kind: Issuer 10 | commonName: grafana.apps.argoproj.io 11 | dnsNames: 12 | - grafana.apps.argoproj.io 13 | -------------------------------------------------------------------------------- /prometheus-operator/resources/grafana-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: grafana-ingress 5 | annotations: 6 | ingress.kubernetes.io/proxy-body-size: 100M 7 | ingress.kubernetes.io/app-root: "/" 8 | spec: 9 | ingressClassName: nginx 10 | tls: 11 | - hosts: 12 | - grafana.apps.argoproj.io 13 | secretName: grafana-tls 14 | rules: 15 | - host: grafana.apps.argoproj.io 16 | http: 17 | paths: 18 | - path: / 19 | pathType: ImplementationSpecific 20 | backend: 21 | service: 22 | name: prometheus-operator-grafana 23 | port: 24 | number: 80 -------------------------------------------------------------------------------- /prometheus-operator/resources/grafana-issuer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Issuer 3 | metadata: 4 | name: grafana-issuer 5 | spec: 6 | acme: 7 | server: https://acme-v02.api.letsencrypt.org/directory 8 | email: argoproj@gmail.com 9 | privateKeySecretRef: 10 | name: letsencrypt 11 | solvers: 12 | # An empty 'selector' means that this solver matches all domains 13 | - selector: {} 14 | http01: 15 | ingress: 16 | class: nginx 17 | -------------------------------------------------------------------------------- /prometheus-operator/upstream.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | helm dependency update upstream 3 | helm template \ 4 | --include-crds \ 5 | --namespace prometheus-operator \ 6 | prometheus-operator \ 7 | ./upstream > resources/upstream.yaml 8 | -------------------------------------------------------------------------------- /prometheus-operator/upstream/.gitignore: -------------------------------------------------------------------------------- 1 | charts/* 2 | Chart.lock -------------------------------------------------------------------------------- /prometheus-operator/upstream/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: prometheus-operator 3 | version: 0.1.0 4 | 5 | dependencies: 6 | - name: kube-prometheus-stack 7 | version: 56.9.0 8 | repository: https://prometheus-community.github.io/helm-charts 9 | -------------------------------------------------------------------------------- /workflow-examples/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | namespace: workflow-playground 5 | 6 | resources: 7 | - https://github.com/argoproj/argo-workflows/manifests/quick-start/base/minio 8 | - https://raw.githubusercontent.com/argoproj/argo-workflows/master/manifests/quick-start/base/artifact-repositories-configmap.yaml 9 | - resources/auth/read-write-sa-secret.yaml 10 | - resources/auth/read-write-sa.yaml 11 | - resources/auth/user-default-login-sa-secret.yaml 12 | - resources/auth/user-default-login-sa.yaml 13 | - resources/rbac/github.com-rolebinding.yaml 14 | - resources/rbac/github.com-sa.yaml 15 | - resources/rbac/read-only-clusterrolebinding.yaml 16 | - resources/rbac/read-only-rolebinding.yaml 17 | - resources/rbac/read-write-rolebinding.yaml 18 | - resources/rbac/submit-workflow-template-role.yaml 19 | - resources/rbac/workflow-role.yaml 20 | - resources/rbac/workflow-rolebinding.yaml 21 | - resources/rbac/workflow-sa.yaml 22 | - https://raw.githubusercontent.com/argoproj-labs/argo-workflows-catalog/master/templates/buildkit/manifests.yaml 23 | - https://raw.githubusercontent.com/argoproj-labs/argo-workflows-catalog/master/templates/slack/manifests.yaml 24 | - https://raw.githubusercontent.com/argoproj-labs/argo-workflows-catalog/master/templates/sendmail/manifests.yaml 25 | - https://raw.githubusercontent.com/argoproj-labs/argo-workflows-catalog/master/templates/distro/manifests.yaml 26 | - https://raw.githubusercontent.com/argoproj/argo-workflows/master/examples/artifacts-workflowtemplate.yaml 27 | - https://raw.githubusercontent.com/argoproj/argo-workflows/master/examples/ci-workflowtemplate.yaml 28 | - resources/workflows/artifacts-cronworkflow.yaml 29 | - resources/workflows/ci-cronworkflow.yaml 30 | - resources/workflows/coinflip-cronworkflow.yaml 31 | - resources/workflows/coinflip-workflowtemplate.yaml 32 | - resources/workflows/event-consumer-workfloweventbinding.yaml 33 | - resources/workflows/github-event-workflowtemplate.yaml 34 | -------------------------------------------------------------------------------- /workflow-examples/resources/auth/read-write-sa-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: read-write.service-account-token 5 | annotations: 6 | kubernetes.io/service-account.name: read-write 7 | type: kubernetes.io/service-account-token 8 | -------------------------------------------------------------------------------- /workflow-examples/resources/auth/read-write-sa.yaml: -------------------------------------------------------------------------------- 1 | kind: ServiceAccount 2 | apiVersion: v1 3 | metadata: 4 | name: read-write 5 | annotations: 6 | workflows.argoproj.io/rbac-rule: "'argoproj:argo-workflows-approvers' in groups" 7 | workflows.argoproj.io/rbac-rule-precedence: "1" 8 | -------------------------------------------------------------------------------- /workflow-examples/resources/auth/user-default-login-sa-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: user-default-login.service-account-token 5 | annotations: 6 | kubernetes.io/service-account.name: user-default-login 7 | type: kubernetes.io/service-account-token 8 | -------------------------------------------------------------------------------- /workflow-examples/resources/auth/user-default-login-sa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: user-default-login 5 | annotations: 6 | workflows.argoproj.io/rbac-rule: 'true' 7 | workflows.argoproj.io/rbac-rule-precedence: '0' 8 | -------------------------------------------------------------------------------- /workflow-examples/resources/rbac/github.com-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: github.com 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: Role 8 | name: submit-workflow-template 9 | subjects: 10 | - kind: ServiceAccount 11 | name: github.com 12 | -------------------------------------------------------------------------------- /workflow-examples/resources/rbac/github.com-sa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: github.com -------------------------------------------------------------------------------- /workflow-examples/resources/rbac/read-only-clusterrolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: argo-workflows-read-only 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: argo-workflows-read-only 9 | subjects: 10 | - kind: ServiceAccount 11 | name: user-default-login 12 | namespace: workflow-playground 13 | -------------------------------------------------------------------------------- /workflow-examples/resources/rbac/read-only-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: read-only 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: argo-workflows-read-only-namespaced 9 | subjects: 10 | - kind: ServiceAccount 11 | name: user-default-login 12 | -------------------------------------------------------------------------------- /workflow-examples/resources/rbac/read-write-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: read-write 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: argo-workflows-read-write-namespaced 9 | subjects: 10 | - kind: ServiceAccount 11 | name: read-write 12 | -------------------------------------------------------------------------------- /workflow-examples/resources/rbac/submit-workflow-template-role.yaml: -------------------------------------------------------------------------------- 1 | # Just enough permissions to submit a workflow template. 2 | # You could tighten this further (but perhaps impractically) by using `resourceNames` 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: Role 5 | metadata: 6 | name: submit-workflow-template 7 | rules: 8 | - apiGroups: 9 | - argoproj.io 10 | resources: 11 | - workfloweventbindings 12 | verbs: 13 | - list 14 | - apiGroups: 15 | - argoproj.io 16 | resources: 17 | - workflowtemplates 18 | verbs: 19 | - get 20 | - apiGroups: 21 | - argoproj.io 22 | resources: 23 | - workflows 24 | verbs: 25 | - create -------------------------------------------------------------------------------- /workflow-examples/resources/rbac/workflow-role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: workflow 5 | rules: 6 | # WFT is used to pass information back to the controller 7 | - apiGroups: 8 | - argoproj.io 9 | resources: 10 | - workflowtaskresults 11 | verbs: 12 | - create 13 | - patch 14 | -------------------------------------------------------------------------------- /workflow-examples/resources/rbac/workflow-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: workflow 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: Role 8 | name: workflow 9 | subjects: 10 | - kind: ServiceAccount 11 | name: workflow 12 | -------------------------------------------------------------------------------- /workflow-examples/resources/rbac/workflow-sa.yaml: -------------------------------------------------------------------------------- 1 | kind: ServiceAccount 2 | apiVersion: v1 3 | metadata: 4 | name: workflow -------------------------------------------------------------------------------- /workflow-examples/resources/workflows/artifacts-cronworkflow.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: CronWorkflow 3 | metadata: 4 | name: artifacts 5 | spec: 6 | schedule: '*/5 * * * *' 7 | workflowSpec: 8 | serviceAccountName: workflow 9 | workflowTemplateRef: 10 | name: artifacts -------------------------------------------------------------------------------- /workflow-examples/resources/workflows/ci-cronworkflow.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: CronWorkflow 3 | metadata: 4 | name: ci 5 | spec: 6 | schedule: '*/5 * * * *' 7 | workflowSpec: 8 | serviceAccountName: workflow 9 | workflowTemplateRef: 10 | name: ci -------------------------------------------------------------------------------- /workflow-examples/resources/workflows/coinflip-cronworkflow.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: CronWorkflow 3 | metadata: 4 | name: coinflip 5 | spec: 6 | schedule: '*/5 * * * *' 7 | workflowSpec: 8 | serviceAccountName: workflow 9 | workflowTemplateRef: 10 | name: coinflip -------------------------------------------------------------------------------- /workflow-examples/resources/workflows/coinflip-workflowtemplate.yaml: -------------------------------------------------------------------------------- 1 | # The coinflip example combines the use of a script result, 2 | # along with conditionals, to take a dynamic path in the 3 | # workflow. In this example, depending on the result of the 4 | # first step, 'flip-coin', the template will either run the 5 | # 'heads' step or the 'tails' step. 6 | apiVersion: argoproj.io/v1alpha1 7 | kind: WorkflowTemplate 8 | metadata: 9 | name: coinflip 10 | spec: 11 | entrypoint: coinflip 12 | serviceAccountName: workflow 13 | templates: 14 | - name: coinflip 15 | steps: 16 | - - name: flip-coin 17 | template: flip-coin 18 | - - name: heads 19 | template: heads 20 | when: "{{steps.flip-coin.outputs.result}} == heads" 21 | - name: tails 22 | template: tails 23 | when: "{{steps.flip-coin.outputs.result}} == tails" 24 | 25 | - name: flip-coin 26 | script: 27 | image: python:alpine3.6 28 | command: [ python ] 29 | source: | 30 | import random 31 | result = "heads" if random.randint(0,1) == 0 else "tails" 32 | print(result) 33 | 34 | - name: heads 35 | container: 36 | image: alpine:3.6 37 | command: [ sh, -c ] 38 | args: [ "echo \"it was heads\"" ] 39 | 40 | - name: tails 41 | container: 42 | image: alpine:3.6 43 | command: [ sh, -c ] 44 | args: [ "echo \"it was tails\"" ] 45 | -------------------------------------------------------------------------------- /workflow-examples/resources/workflows/event-consumer-workfloweventbinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: WorkflowEventBinding 3 | metadata: 4 | name: event-consumer 5 | spec: 6 | event: 7 | selector: metadata["x-github-event"] != nil 8 | submit: 9 | workflowTemplateRef: 10 | name: github-event 11 | arguments: 12 | parameters: 13 | - name: message 14 | valueFrom: 15 | event: payload.message -------------------------------------------------------------------------------- /workflow-examples/resources/workflows/github-event-workflowtemplate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: WorkflowTemplate 3 | metadata: 4 | name: github-event 5 | spec: 6 | entrypoint: main 7 | serviceAccountName: workflow 8 | arguments: 9 | parameters: 10 | - name: message 11 | templates: 12 | - name: main 13 | inputs: 14 | parameters: 15 | - name: message 16 | value: "{{workflow.parameters.message}}" 17 | container: 18 | image: alpine:3.6 19 | command: [ sh, -c ] 20 | args: [ "echo", "{{inputs.parameters.message}}" ] 21 | --------------------------------------------------------------------------------