├── .gitignore ├── README.md ├── TODO.md ├── applications ├── argocd-istio-app │ ├── Chart.yaml │ ├── templates │ │ └── istio-resources.yaml │ └── values.yaml ├── istio │ ├── Chart.yaml │ ├── templates │ │ └── istio.yaml │ └── values.yaml ├── master-app-empty │ ├── Chart.yaml │ ├── templates │ │ └── namespace.yaml │ └── values.yaml ├── master-app │ ├── Chart.yaml │ ├── templates │ │ ├── argocd-istio.yaml │ │ ├── istio-operator.yaml │ │ ├── istio.yaml │ │ ├── namespace.yaml │ │ └── rollout-canary-app.yaml │ ├── values-playground.yaml │ └── values.yaml └── rollout-canary-app │ ├── Chart.yaml │ ├── templates │ ├── 00-rollout-canary.yaml │ ├── 01-service.yaml │ └── 02-istio-resources.yaml │ └── values.yaml ├── argocd-bootstrap ├── argocd-istio-bootstrap │ ├── argocd-server.yaml │ └── kustomization.yaml └── base │ ├── argocd-cm.yaml │ ├── argocd-namespace.yaml │ ├── kustomization.yaml │ └── master-app.yaml └── blueprint └── playground.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eks-argocd-bootstrap 2 | 3 | [![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/R5R51LJWE) 4 | 5 | In this project you will find an example of how to create and bootstrap and EKS cluster with ArgoCD. 6 | 7 | Leveraging the ArgoCD concept of [App of Apps](https://argoproj.github.io/argo-cd/operator-manual/declarative-setup/#app-of-apps), 8 | you will be able to install a number of kubernetes manifests quickly, safely and repeatedly. 9 | 10 | Read more on my blog: [Bootstrap a kubernetes cluster with ArgoCD and Istio](https://nemo83.dev/posts/argocd-istio-operator-bootstrap/) 11 | 12 | ## Project structure 13 | 14 | The project structure should be similar to this: 15 | 16 | ```bash 17 | . 18 | ├── README.md 19 | ├── applications 20 | │   ├── istio-app 21 | │   ├── istio-operator-app 22 | │   └── master-app 23 | ├── argocd-bootstrap 24 | │   ├── kustomization.yaml 25 | │   ├── master-app.yaml 26 | │   ├── repositories 27 | │   └── resource.customizations 28 | └── blueprint 29 | └── playground.yaml 30 | ``` 31 | 32 | The `blueprint` folder contains the specifications for an Eks Cluster. 33 | The `argocd-bootstrap` folder contains the `kustomization` required to install ArgoCD and bootstrap the cluster. It also 34 | contains the `master-app.yaml` file that is nothing else than the app-of-apps responsible for installing all the _other_ kubernetes manifests. 35 | `applications` is the folder that contains the `master-app` itself plus all the other apps that you might want to install on your cluster. 36 | 37 | ## Creating the cluster 38 | 39 | In order to create the cluster run: 40 | 41 | `eksctl create cluster -f blueprint/playground.yaml` 42 | 43 | ## Bootstrap the cluster 44 | 45 | `kubectl apply -k argocd-bootstrap` 46 | 47 | If you then want to access ArgoCD via a load balancer you have to then issue: 48 | 49 | `kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'` 50 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | * provide example on how to customise the master app depending on cluster (use a different value-files) 4 | * this could be one install for istio only 5 | * one install for istio and argo rollout 6 | * all of them 7 | * cluster autoscaler 8 | * docker for desktop 9 | * aws 10 | * split apps in helm apps and kustomize apps 11 | * PoC for secrets. 12 | * localhost docker-for-desktop config DNS: https://passingcuriosity.com/2013/dnsmasq-dev-osx/ 13 | -------------------------------------------------------------------------------- /applications/argocd-istio-app/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: argocd-istio-app 2 | -------------------------------------------------------------------------------- /applications/argocd-istio-app/templates/istio-resources.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: networking.istio.io/v1alpha3 3 | kind: Gateway 4 | metadata: 5 | name: argocd-gateway 6 | spec: 7 | selector: 8 | istio: ingressgateway 9 | servers: 10 | - port: 11 | number: 80 12 | name: http 13 | protocol: HTTP 14 | hosts: 15 | - "argocd.kube" 16 | # Uncomment below to enable HTTPS 17 | # tls: 18 | # httpsRedirect: true 19 | # - port: 20 | # number: 443 21 | # name: https 22 | # protocol: HTTPS 23 | # hosts: 24 | # - "argocd.kube" 25 | # tls: 26 | # mode: PASSTHROUGH 27 | --- 28 | apiVersion: networking.istio.io/v1alpha3 29 | kind: VirtualService 30 | metadata: 31 | name: argocd-server 32 | spec: 33 | hosts: 34 | - argocd.kube 35 | gateways: 36 | - argocd-gateway 37 | http: 38 | - route: 39 | - destination: 40 | host: argocd-server.argocd.svc.cluster.local 41 | port: 42 | number: 80 -------------------------------------------------------------------------------- /applications/argocd-istio-app/values.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/speedwing/eks-argocd-bootstrap/31a15b919ded8433486000ec49a8b9ee9eac623f/applications/argocd-istio-app/values.yaml -------------------------------------------------------------------------------- /applications/istio/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: istio 2 | -------------------------------------------------------------------------------- /applications/istio/templates/istio.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: install.istio.io/v1alpha1 2 | kind: IstioOperator 3 | metadata: 4 | name: istio-control-plane 5 | namespace: istio-system 6 | spec: 7 | profile: default 8 | addonComponents: 9 | prometheus: 10 | enabled: false 11 | # This one below technically is useless: 12 | # values: 13 | # global: 14 | # k8sIngress: 15 | # enabled: false 16 | -------------------------------------------------------------------------------- /applications/istio/values.yaml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/speedwing/eks-argocd-bootstrap/31a15b919ded8433486000ec49a8b9ee9eac623f/applications/istio/values.yaml -------------------------------------------------------------------------------- /applications/master-app-empty/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: master-app-empty 2 | -------------------------------------------------------------------------------- /applications/master-app-empty/templates/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: production 6 | -------------------------------------------------------------------------------- /applications/master-app-empty/values.yaml: -------------------------------------------------------------------------------- 1 | spec: 2 | destination: 3 | server: https://kubernetes.default.svc 4 | -------------------------------------------------------------------------------- /applications/master-app/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: master-application 2 | -------------------------------------------------------------------------------- /applications/master-app/templates/argocd-istio.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: argocd-istio-app 5 | namespace: argocd 6 | finalizers: 7 | - resources-finalizer.argocd.argoproj.io 8 | spec: 9 | project: default 10 | source: 11 | repoURL: https://github.com/speedwing/eks-argocd-bootstrap.git 12 | targetRevision: HEAD 13 | path: applications/argocd-istio-app 14 | 15 | destination: 16 | namespace: production 17 | server: {{ .Values.spec.destination.server }} 18 | 19 | syncPolicy: 20 | automated: 21 | prune: true 22 | selfHeal: true 23 | validate: true 24 | -------------------------------------------------------------------------------- /applications/master-app/templates/istio-operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: istio-operator 5 | namespace: argocd 6 | annotations: 7 | argocd.argoproj.io/sync-wave: "-2" 8 | finalizers: 9 | - resources-finalizer.argocd.argoproj.io 10 | spec: 11 | project: default 12 | source: 13 | repoURL: https://github.com/istio/istio.git 14 | targetRevision: "1.6.0" 15 | path: manifests/charts/istio-operator 16 | 17 | helm: 18 | parameters: 19 | - name: "hub" 20 | value: "docker.io/istio" 21 | - name: "tag" 22 | value: "1.6.0" 23 | - name: "operatorNamespace" 24 | value: "istio-operator" 25 | - name: "istioNamespace" 26 | value: "istio-system" 27 | 28 | destination: 29 | namespace: istio-operator 30 | server: {{ .Values.spec.destination.server }} 31 | 32 | syncPolicy: 33 | automated: 34 | prune: true 35 | -------------------------------------------------------------------------------- /applications/master-app/templates/istio.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: istio 5 | namespace: argocd 6 | annotations: 7 | argocd.argoproj.io/sync-wave: "-1" 8 | finalizers: 9 | - resources-finalizer.argocd.argoproj.io 10 | spec: 11 | project: default 12 | source: 13 | repoURL: https://github.com/speedwing/eks-argocd-bootstrap.git 14 | targetRevision: HEAD 15 | path: applications/istio 16 | 17 | destination: 18 | namespace: istio-system 19 | server: {{ .Values.spec.destination.server }} 20 | 21 | syncPolicy: 22 | automated: 23 | prune: true 24 | -------------------------------------------------------------------------------- /applications/master-app/templates/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: production 6 | labels: 7 | name: "production" 8 | istio-injection: "enabled" 9 | --- 10 | apiVersion: v1 11 | kind: Namespace 12 | metadata: 13 | name: istio-system 14 | annotations: 15 | argocd.argoproj.io/sync-wave: "-10" 16 | -------------------------------------------------------------------------------- /applications/master-app/templates/rollout-canary-app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: rollout-canary-app 5 | namespace: argocd 6 | finalizers: 7 | - resources-finalizer.argocd.argoproj.io 8 | spec: 9 | project: default 10 | source: 11 | repoURL: https://github.com/speedwing/eks-argocd-bootstrap.git 12 | targetRevision: HEAD 13 | path: applications/rollout-canary-app 14 | 15 | destination: 16 | namespace: production 17 | server: {{ .Values.spec.destination.server }} 18 | 19 | syncPolicy: 20 | automated: 21 | prune: true 22 | selfHeal: true 23 | validate: true 24 | -------------------------------------------------------------------------------- /applications/master-app/values-playground.yaml: -------------------------------------------------------------------------------- 1 | cluster: 2 | name: "eks-playground" 3 | awsRegion: "eu-west-1" 4 | clusterAutoscaler: 5 | namespace: "kube-system" 6 | -------------------------------------------------------------------------------- /applications/master-app/values.yaml: -------------------------------------------------------------------------------- 1 | spec: 2 | destination: 3 | server: https://kubernetes.default.svc 4 | 5 | cluster: 6 | name: "no-name" 7 | awsRegion: "us-east-1" 8 | -------------------------------------------------------------------------------- /applications/rollout-canary-app/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: rollout-canary 2 | -------------------------------------------------------------------------------- /applications/rollout-canary-app/templates/00-rollout-canary.yaml: -------------------------------------------------------------------------------- 1 | # This example demonstrates a Rollout using the canary update strategy with a customized rollout 2 | # plan. The prescribed steps initially sets a canary weight of 20%, then pauses indefinitely. Once 3 | # resumed, the rollout performs a gradual, automated 20% weight increase until it reaches 100%. 4 | apiVersion: argoproj.io/v1alpha1 5 | kind: Rollout 6 | metadata: 7 | name: rollout-canary 8 | spec: 9 | replicas: 2 10 | revisionHistoryLimit: 2 11 | selector: 12 | matchLabels: 13 | app: rollout-canary 14 | template: 15 | metadata: 16 | labels: 17 | app: rollout-canary 18 | spec: 19 | containers: 20 | - name: rollouts-demo 21 | image: {{ .Values.image }} 22 | imagePullPolicy: Always 23 | ports: 24 | - containerPort: 8080 25 | strategy: 26 | canary: 27 | steps: 28 | - setWeight: 5 29 | - pause: {} 30 | - setWeight: 50 31 | - pause: 32 | duration: 60 33 | canaryService: rollout-canary # required 34 | stableService: rollout-canary-stable # required 35 | trafficRouting: 36 | istio: 37 | virtualService: 38 | name: rollout-canary-vs # required 39 | routes: 40 | - primary # At least one route is required 41 | -------------------------------------------------------------------------------- /applications/rollout-canary-app/templates/01-service.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: rollout-canary-stable 6 | spec: 7 | ports: 8 | - name: http 9 | port: 80 10 | protocol: TCP 11 | targetPort: 8080 12 | selector: 13 | app: rollout-canary 14 | --- 15 | apiVersion: v1 16 | kind: Service 17 | metadata: 18 | name: rollout-canary 19 | spec: 20 | ports: 21 | - name: http 22 | port: 80 23 | protocol: TCP 24 | targetPort: 8080 25 | selector: 26 | app: rollout-canary 27 | -------------------------------------------------------------------------------- /applications/rollout-canary-app/templates/02-istio-resources.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: networking.istio.io/v1alpha3 3 | kind: Gateway 4 | metadata: 5 | name: rollout-canary-kube 6 | labels: 7 | app.kubernetes.io/name: applications.argoproj.io 8 | app.kubernetes.io/part-of: argocd 9 | app.kubernetes.io/instance: argocd 10 | app.kubernetes.io/managed-by: Tiller 11 | annotations: 12 | kubernetes.io/ingress.class: "ingressgateway" 13 | kubernetes.io/ingress.tld: "flo.pub" 14 | spec: 15 | selector: 16 | istio: ingressgateway 17 | servers: 18 | - port: 19 | number: 80 20 | name: http 21 | protocol: HTTP 22 | hosts: 23 | - "rollout-canary.kube" 24 | --- 25 | apiVersion: networking.istio.io/v1alpha3 26 | kind: VirtualService 27 | metadata: 28 | name: rollout-canary-vs 29 | labels: 30 | app.kubernetes.io/name: applications.argoproj.io 31 | app.kubernetes.io/part-of: argocd 32 | app.kubernetes.io/instance: argocd 33 | app.kubernetes.io/managed-by: Tiller 34 | spec: 35 | hosts: 36 | - rollout-canary.kube 37 | gateways: 38 | - rollout-canary-kube 39 | http: 40 | - name: primary 41 | route: 42 | - destination: 43 | host: rollout-canary-stable 44 | weight: 100 45 | - destination: 46 | host: rollout-canary 47 | weight: 0 48 | 49 | -------------------------------------------------------------------------------- /applications/rollout-canary-app/values.yaml: -------------------------------------------------------------------------------- 1 | image: argoproj/rollouts-demo:red -------------------------------------------------------------------------------- /argocd-bootstrap/argocd-istio-bootstrap/argocd-server.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: argocd-server 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: argocd-server 11 | command: 12 | - argocd-server 13 | - --staticassets 14 | - /shared/app 15 | - --repo-server 16 | - argocd-repo-server:8081 17 | - --insecure 18 | -------------------------------------------------------------------------------- /argocd-bootstrap/argocd-istio-bootstrap/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | namespace: argocd 4 | bases: 5 | - ../base 6 | patchesStrategicMerge: 7 | - argocd-server.yaml 8 | -------------------------------------------------------------------------------- /argocd-bootstrap/base/argocd-cm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: argocd-cm 5 | data: 6 | repositories: | 7 | - url: https://github.com/helm/charts.git 8 | - url: https://github.com/speedwing/eks-argocd-bootstrap.git 9 | - url: https://github.com/argoproj/argo-rollouts.git 10 | - url: https://github.com/istio/istio.git 11 | resource.customizations: | 12 | admissionregistration.k8s.io/MutatingWebhookConfiguration: 13 | ignoreDifferences: | 14 | jsonPointers: 15 | - /webhooks/0/clientConfig/caBundle 16 | install.istio.io/IstioOperator: 17 | health.lua: | 18 | hs = {} 19 | if obj.status ~= nil then 20 | if obj.status.status == "HEALTHY" then 21 | hs.status = "Healthy" 22 | hs.message = "IstioOperator Ready" 23 | return hs 24 | end 25 | end 26 | 27 | hs.status = "Progressing" 28 | hs.message = "Waiting for IstioOperator" 29 | return hs 30 | -------------------------------------------------------------------------------- /argocd-bootstrap/base/argocd-namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: argocd 5 | -------------------------------------------------------------------------------- /argocd-bootstrap/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | namespace: argocd 4 | bases: 5 | - github.com/argoproj/argo-cd/manifests/cluster-install?ref=v1.5.5 6 | - github.com/argoproj/argo-rollouts/manifests/cluster-install?ref=v0.8.2 7 | resources: 8 | - argocd-namespace.yaml 9 | - master-app.yaml 10 | patchesStrategicMerge: 11 | - argocd-cm.yaml 12 | -------------------------------------------------------------------------------- /argocd-bootstrap/base/master-app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: master-app 5 | finalizers: 6 | - resources-finalizer.argocd.argoproj.io 7 | spec: 8 | project: default 9 | source: 10 | repoURL: https://github.com/speedwing/eks-argocd-bootstrap.git 11 | targetRevision: HEAD 12 | path: applications/master-app 13 | helm: 14 | valueFiles: 15 | - values-playground.yaml 16 | destination: 17 | namespace: argocd 18 | server: https://kubernetes.default.svc 19 | 20 | syncPolicy: 21 | automated: 22 | prune: true 23 | validate: true 24 | -------------------------------------------------------------------------------- /blueprint/playground.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: eksctl.io/v1alpha5 3 | kind: ClusterConfig 4 | 5 | metadata: 6 | name: eks-playground 7 | region: eu-west-1 8 | version: "1.14" 9 | 10 | 11 | iam: 12 | withOIDC: true 13 | serviceAccounts: 14 | - metadata: 15 | name: cluster-autoscaler-aws-cluster-autoscaler 16 | namespace: kube-system 17 | labels: {aws-usage: "cluster-ops"} 18 | attachPolicy: # inline policy can be defined along with `attachPolicyARNs` 19 | Version: "2012-10-17" 20 | Statement: 21 | - Effect: Allow 22 | Action: 23 | - "autoscaling:DescribeAutoScalingGroups" 24 | - "autoscaling:DescribeAutoScalingInstances" 25 | - "autoscaling:DescribeLaunchConfigurations" 26 | - "autoscaling:DescribeTags" 27 | - "autoscaling:SetDesiredCapacity" 28 | - "autoscaling:TerminateInstanceInAutoScalingGroup" 29 | - "ec2:DescribeLaunchTemplateVersions" 30 | Resource: '*' 31 | 32 | nodeGroups: 33 | - name: workers 34 | labels: 35 | role: workers 36 | tags: 37 | k8s.io/cluster-autoscaler/enabled: "1" 38 | k8s.io/cluster-autoscaler/eks-playground: "1" 39 | instanceType: m5.xlarge 40 | minSize: 1 41 | maxSize: 5 42 | # privateNetworking: true 43 | --------------------------------------------------------------------------------