├── .github └── workflows │ └── pr.yaml ├── .wokeignore ├── LICENSE ├── SECURITY.md ├── capi ├── charts │ ├── aws │ │ └── eks-cluster-chart │ │ │ ├── Chart.yaml │ │ │ ├── templates │ │ │ ├── cluster.yaml │ │ │ └── sync.yaml │ │ │ └── values.yaml │ └── azure │ │ └── aks-cluster-chart │ │ ├── Chart.yaml │ │ ├── templates │ │ ├── cluster.yaml │ │ └── sync.yaml │ │ └── values.yaml ├── clusters │ ├── east-voyager-aks │ │ └── cluster-helm-release.yaml │ ├── pacific-aks │ │ └── cluster-helm-release.yaml │ ├── secure-aks │ │ └── cluster-helm-release.yaml │ └── west-voyager-aws │ │ └── cluster-helm-release.yaml └── setup │ ├── aws │ ├── bootstrap-config.yaml │ ├── capa_setup.sh │ └── role-binding.yaml │ ├── azure │ └── capz_setup.sh │ └── clusters-sync.yaml ├── clusters ├── base │ └── flux-system │ │ ├── gotk-components.yaml │ │ ├── gotk-sync.yaml │ │ └── kustomization.yaml └── k3d-america │ └── infra.yaml ├── docs ├── capi-capz.md ├── demo │ └── asian-aks │ │ └── cluster-helm-release.yaml └── images │ ├── capi.png │ ├── multi-cluster-diagram.png │ └── src │ ├── capi.drawio │ └── multi-cluster-tenant-layout.drawio ├── infra ├── base │ ├── kustomization.yaml │ ├── nginx │ │ ├── kustomization.yaml │ │ ├── namespace.yaml │ │ └── release.yaml │ ├── secure-aks-baseline │ │ ├── aad-pod-identity.yaml │ │ ├── akv-secrets-store-csi.yaml │ │ ├── container-azm-ms-agentconfig.yaml │ │ ├── kured-1.4.0-dockerhub.yaml │ │ ├── kustomization.yaml │ │ ├── namespace.yaml │ │ ├── network-policy.yaml │ │ └── readme.md │ └── sources │ │ ├── bitnami.yaml │ │ └── kustomization.yaml └── k3d-america │ ├── kustomization.yaml │ └── nginx │ ├── kustomization.yaml │ └── release.yaml ├── readme.md ├── updates └── utils ├── add-cluster.sh ├── attach-acr.sh ├── remove-cluster.sh └── templates ├── clusters └── infra.yaml └── infra └── kustomization.yaml /.github/workflows/pr.yaml: -------------------------------------------------------------------------------- 1 | 2 | name: PR 3 | 4 | on: 5 | pull_request: 6 | branches: [main] 7 | 8 | jobs: 9 | code_quality_checks: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v2 14 | - name: 'woke' 15 | uses: get-woke/woke-action@v0 16 | with: 17 | # Cause the check to fail on any broke rules 18 | fail-on-error: true 19 | # See https://github.com/marketplace/actions/get-all-changed-files for more options 20 | # woke-args: ${{ steps.files.outputs.added_modified }} 21 | -------------------------------------------------------------------------------- /.wokeignore: -------------------------------------------------------------------------------- 1 | *.drawio -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Microsoft Corporation. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** 12 | 13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). 14 | 15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). 16 | 17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). 18 | 19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 20 | 21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 22 | * Full paths of source file(s) related to the manifestation of the issue 23 | * The location of the affected source code (tag/branch/commit or direct URL) 24 | * Any special configuration required to reproduce the issue 25 | * Step-by-step instructions to reproduce the issue 26 | * Proof-of-concept or exploit code (if possible) 27 | * Impact of the issue, including how an attacker might exploit the issue 28 | 29 | This information will help us triage your report more quickly. 30 | 31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. 32 | 33 | ## Preferred Languages 34 | 35 | We prefer all communications to be in English. 36 | 37 | ## Policy 38 | 39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). 40 | 41 | 42 | -------------------------------------------------------------------------------- /capi/charts/aws/eks-cluster-chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: aws-cluster 3 | description: A Helm chart for AWS Cluster 4 | 5 | version: 0.0.3 6 | -------------------------------------------------------------------------------- /capi/charts/aws/eks-cluster-chart/templates/cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cluster.x-k8s.io/v1alpha3 2 | kind: Cluster 3 | metadata: 4 | name: {{ .Values.name }} 5 | spec: 6 | clusterNetwork: 7 | services: 8 | cidrBlocks: 9 | - {{ .Values.servicesCidrBlock }} 10 | serviceDomain: cluster.local 11 | controlPlaneRef: 12 | apiVersion: controlplane.cluster.x-k8s.io/v1alpha3 13 | kind: AWSManagedControlPlane 14 | name: {{ .Values.name }} 15 | infrastructureRef: 16 | apiVersion: controlplane.cluster.x-k8s.io/v1alpha3 17 | kind: AWSManagedControlPlane 18 | name: {{ .Values.name }} 19 | --- 20 | apiVersion: controlplane.cluster.x-k8s.io/v1alpha3 21 | kind: AWSManagedControlPlane 22 | metadata: 23 | name: {{ .Values.name }} 24 | spec: 25 | region: {{ .Values.location }} 26 | sshKeyName: {{ .Values.sshKeyName }} 27 | version: {{ .Values.k8sVersion }} 28 | eksClusterName: {{ .Values.name }} 29 | --- 30 | apiVersion: cluster.x-k8s.io/v1alpha3 31 | kind: MachineDeployment 32 | metadata: 33 | name: {{ .Values.name }} 34 | spec: 35 | clusterName: {{ .Values.name }} 36 | replicas: {{ .Values.workerAgentPoolNodes }} 37 | selector: 38 | matchLabels: null 39 | template: 40 | spec: 41 | bootstrap: 42 | configRef: 43 | apiVersion: bootstrap.cluster.x-k8s.io/v1alpha3 44 | kind: EKSConfigTemplate 45 | name: {{ .Values.name }} 46 | clusterName: {{ .Values.name }} 47 | infrastructureRef: 48 | apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3 49 | kind: AWSMachineTemplate 50 | name: {{ .Values.name }} 51 | version: {{ .Values.k8sVersion }} 52 | --- 53 | apiVersion: infrastructure.cluster.x-k8s.io/v1alpha3 54 | kind: AWSMachineTemplate 55 | metadata: 56 | name: {{ .Values.name }} 57 | spec: 58 | template: 59 | spec: 60 | iamInstanceProfile: nodes.cluster-api-provider-aws.sigs.k8s.io 61 | instanceType: {{ .Values.workerAgentPoolNodeSize }} 62 | sshKeyName: {{ .Values.sshKeyName }} 63 | --- 64 | apiVersion: bootstrap.cluster.x-k8s.io/v1alpha3 65 | kind: EKSConfigTemplate 66 | metadata: 67 | name: {{ .Values.name }} 68 | spec: 69 | template: {} 70 | -------------------------------------------------------------------------------- /capi/charts/aws/eks-cluster-chart/templates/sync.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 2 | kind: Kustomization 3 | metadata: 4 | name: {{ .Values.name }}-flux-system 5 | spec: 6 | interval: 3m0s 7 | sourceRef: 8 | kind: GitRepository 9 | name: flux-system 10 | namespace: flux-system 11 | path: ./clusters/base/flux-system 12 | prune: true 13 | kubeConfig: 14 | secretRef: 15 | name: {{ .Values.name }}-kubeconfig 16 | --- 17 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 18 | kind: Kustomization 19 | metadata: 20 | name: {{ .Values.name }}-infrastructure 21 | spec: 22 | interval: 3m0s 23 | sourceRef: 24 | kind: GitRepository 25 | name: flux-system 26 | namespace: flux-system 27 | path: {{ .Values.infraPath }} # ./infra/base 28 | prune: true 29 | kubeConfig: 30 | secretRef: 31 | name: {{ .Values.name }}-kubeconfig -------------------------------------------------------------------------------- /capi/charts/aws/eks-cluster-chart/values.yaml: -------------------------------------------------------------------------------- 1 | name: 2 | servicesCidrBlock: 192.168.0.0/16 3 | location: 4 | sshKeyName: default 5 | k8sVersion: v1.21.2 6 | additionalTags: voyager 7 | workerAgentPoolNodes: 1 8 | workerAgentPoolNodeSize: t2.medium 9 | infraPath: ./infra/base 10 | 11 | -------------------------------------------------------------------------------- /capi/charts/azure/aks-cluster-chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: aks-cluster 3 | description: A Helm chart for AKS Cluster 4 | 5 | version: 0.0.7 6 | -------------------------------------------------------------------------------- /capi/charts/azure/aks-cluster-chart/templates/cluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cluster.x-k8s.io/v1alpha3 2 | kind: Cluster 3 | metadata: 4 | name: {{ .Values.name }} 5 | spec: 6 | clusterNetwork: 7 | services: 8 | cidrBlocks: 9 | - {{ .Values.servicesCidrBlock }} 10 | serviceDomain: cluster.local 11 | controlPlaneRef: 12 | apiVersion: exp.infrastructure.cluster.x-k8s.io/v1alpha3 13 | kind: AzureManagedControlPlane 14 | name: {{ .Values.name }} 15 | infrastructureRef: 16 | apiVersion: exp.infrastructure.cluster.x-k8s.io/v1alpha3 17 | kind: AzureManagedCluster 18 | name: {{ .Values.name }} 19 | --- 20 | apiVersion: exp.infrastructure.cluster.x-k8s.io/v1alpha3 21 | kind: AzureManagedControlPlane 22 | metadata: 23 | name: {{ .Values.name }} 24 | spec: 25 | defaultPoolRef: 26 | name: {{ .Values.controlAgentPoolName }} 27 | location: {{ .Values.location }} 28 | resourceGroupName: {{ .Values.clusterResourceGroup }} 29 | nodeResourceGroupName: nodepool-{{ .Values.clusterResourceGroup }} 30 | sshPublicKey: "" 31 | subscriptionID: {{ .Values.subscriptionId }} 32 | version: {{ .Values.k8sVersion }} 33 | networkPlugin: {{ .Values.networkPlugin }} 34 | networkPolicy: {{ .Values.networkPolicy }} 35 | virtualNetwork: 36 | name: {{ .Values.virtualNetwork.name }} 37 | cidrBlock: 10.0.0.0/8 38 | 39 | --- 40 | apiVersion: exp.infrastructure.cluster.x-k8s.io/v1alpha3 41 | kind: AzureManagedCluster 42 | metadata: 43 | name: {{ .Values.name }} 44 | --- 45 | apiVersion: exp.cluster.x-k8s.io/v1alpha3 46 | kind: MachinePool 47 | metadata: 48 | name: {{ .Values.controlAgentPoolName }} 49 | spec: 50 | clusterName: {{ .Values.name }} 51 | replicas: {{ .Values.controlAgentPoolNodes }} 52 | template: 53 | spec: 54 | bootstrap: 55 | dataSecretName: "" 56 | clusterName: {{ .Values.name }} 57 | infrastructureRef: 58 | apiVersion: exp.infrastructure.cluster.x-k8s.io/v1alpha3 59 | kind: AzureManagedMachinePool 60 | name: {{ .Values.controlAgentPoolName }} 61 | version: {{ .Values.k8sVersion }} 62 | --- 63 | apiVersion: exp.infrastructure.cluster.x-k8s.io/v1alpha3 64 | kind: AzureManagedMachinePool 65 | metadata: 66 | name: {{ .Values.controlAgentPoolName }} 67 | spec: 68 | sku: {{ .Values.controlAgentPoolNodeSize }} 69 | --- 70 | apiVersion: exp.cluster.x-k8s.io/v1alpha3 71 | kind: MachinePool 72 | metadata: 73 | name: {{ .Values.workerAgentPoolName }} 74 | spec: 75 | clusterName: {{ .Values.name }} 76 | replicas: {{ .Values.workerAgentPoolNodes }} 77 | template: 78 | spec: 79 | bootstrap: 80 | dataSecretName: "" 81 | clusterName: {{ .Values.name }} 82 | infrastructureRef: 83 | apiVersion: exp.infrastructure.cluster.x-k8s.io/v1alpha3 84 | kind: AzureManagedMachinePool 85 | name: {{ .Values.workerAgentPoolName }} 86 | version: {{ .Values.k8sVersion }} 87 | --- 88 | apiVersion: exp.infrastructure.cluster.x-k8s.io/v1alpha3 89 | kind: AzureManagedMachinePool 90 | metadata: 91 | name: {{ .Values.workerAgentPoolName }} 92 | spec: 93 | sku: {{ .Values.workerAgentPoolNodeSize }} -------------------------------------------------------------------------------- /capi/charts/azure/aks-cluster-chart/templates/sync.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 2 | kind: Kustomization 3 | metadata: 4 | name: {{ .Values.name }}-flux-system 5 | spec: 6 | interval: 3m0s 7 | sourceRef: 8 | kind: GitRepository 9 | name: flux-system 10 | namespace: flux-system 11 | path: ./clusters/base/flux-system 12 | prune: true 13 | kubeConfig: 14 | secretRef: 15 | name: {{ .Values.name }}-kubeconfig 16 | --- 17 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 18 | kind: Kustomization 19 | metadata: 20 | name: {{ .Values.name }}-infrastructure 21 | spec: 22 | interval: 3m0s 23 | sourceRef: 24 | kind: GitRepository 25 | name: flux-system 26 | namespace: flux-system 27 | path: {{ .Values.infraPath }} # ./infra/base 28 | prune: true 29 | kubeConfig: 30 | secretRef: 31 | name: {{ .Values.name }}-kubeconfig -------------------------------------------------------------------------------- /capi/charts/azure/aks-cluster-chart/values.yaml: -------------------------------------------------------------------------------- 1 | name: 2 | servicesCidrBlock: 10.0.0.0/16 3 | location: eastus 4 | clusterResourceGroup: 5 | subscriptionId: 0fe1cc35-0cfa-4152-97d7-5dfb45a8d4ba 6 | k8sVersion: v1.20.7 7 | networkPlugin: kubenet 8 | networkPolicy: calico 9 | controlAgentPoolName: clagentpool 10 | controlAgentPoolNodes: 2 11 | controlAgentPoolNodeSize: Standard_D8s_v3 12 | workerAgentPoolName: wragentpool 13 | workerAgentPoolNodes: 1 14 | workerAgentPoolNodeSize: Standard_D8s_v3 15 | infraPath: ./infra/base -------------------------------------------------------------------------------- /capi/clusters/east-voyager-aks/cluster-helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: east-voyager-helm-release 5 | namespace: capi-worker-clusters 6 | spec: 7 | chart: 8 | spec: 9 | chart: ./capi/charts/azure/aks-cluster-chart 10 | sourceRef: 11 | kind: GitRepository 12 | name: flux-system 13 | namespace: flux-system 14 | interval: 10m 15 | values: 16 | name: east-voyager 17 | clusterResourceGroup: voyager-rg 18 | controlAgentPoolName: clevpool 19 | workerAgentPoolName: wrevpool 20 | virtualNetwork: 21 | name: voyager-vnet 22 | 23 | 24 | -------------------------------------------------------------------------------- /capi/clusters/pacific-aks/cluster-helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: pacific-aks-helm-release 5 | namespace: capi-worker-clusters 6 | spec: 7 | chart: 8 | spec: 9 | chart: ./capi/charts/azure/aks-cluster-chart 10 | sourceRef: 11 | kind: GitRepository 12 | name: flux-system 13 | namespace: flux-system 14 | interval: 10m 15 | values: 16 | name: pacific-aks 17 | clusterResourceGroup: pacific-aks-rg 18 | controlAgentPoolName: clpacpool 19 | workerAgentPoolName: wrpacpool 20 | virtualNetwork: 21 | name: pacific-vnet 22 | 23 | 24 | -------------------------------------------------------------------------------- /capi/clusters/secure-aks/cluster-helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: secure-aks-helm-release 5 | namespace: capi-worker-clusters 6 | spec: 7 | chart: 8 | spec: 9 | chart: ./capi/charts/azure/aks-cluster-chart 10 | sourceRef: 11 | kind: GitRepository 12 | name: flux-system 13 | namespace: flux-system 14 | interval: 10m 15 | values: 16 | name: secure-aks 17 | clusterResourceGroup: secure-aks-rg 18 | controlAgentPoolName: clsecpool 19 | workerAgentPoolName: wrsecpool 20 | networkPlugin: azure 21 | networkPolicy: azure 22 | virtualNetwork: 23 | name: secure-vnet 24 | infraPath: ./infra/base/secure-aks-baseline 25 | 26 | -------------------------------------------------------------------------------- /capi/clusters/west-voyager-aws/cluster-helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: west-aws-helm-release 5 | namespace: capi-worker-clusters 6 | spec: 7 | chart: 8 | spec: 9 | chart: ./capi/charts/aws/eks-cluster-chart 10 | sourceRef: 11 | kind: GitRepository 12 | name: flux-system 13 | namespace: flux-system 14 | interval: 10m 15 | values: 16 | name: west-voyager 17 | location: us-west-2 18 | k8sVersion: v1.21.2 19 | workerAgentPoolNodes: 1 20 | workerAgentPoolNodeSize: t2.medium 21 | -------------------------------------------------------------------------------- /capi/setup/aws/bootstrap-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: bootstrap.aws.infrastructure.cluster.x-k8s.io/v1alpha1 2 | kind: AWSIAMConfiguration 3 | spec: 4 | eks: 5 | enable: true 6 | iamRoleCreation: false # Set to true if you plan to use the EKSEnableIAM feature flag to enable automatic creation of IAM roles 7 | defaultControlPlaneRole: 8 | disable: false # Set to false to enable creation of the default control plane role 9 | managedMachinePool: 10 | disable: false # Set to false to enable creation of the default node role for managed machine pools -------------------------------------------------------------------------------- /capi/setup/aws/capa_setup.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Corporation. 2 | # Licensed under the MIT License. 3 | 4 | # Install cluster ctl 5 | # https://cluster-api.sigs.k8s.io/user/quick-start.html#install-clusterctl 6 | 7 | # Download and install clusterawsadm 8 | # https://github.com/kubernetes-sigs/cluster-api-provider-aws/releases 9 | 10 | export AWS_REGION= 11 | export AWS_ACCESS_KEY_ID= 12 | export AWS_SECRET_ACCESS_KEY= 13 | export EXP_EKS=true 14 | export EXP_EKS_IAM=true 15 | export EXP_EKS_ADD_ROLES=true 16 | 17 | clusterawsadm bootstrap iam create-cloudformation-stack --config bootstrap-config.yaml 18 | 19 | export AWS_B64ENCODED_CREDENTIALS=$(clusterawsadm bootstrap credentials encode-as-profile) 20 | 21 | clusterctl init --infrastructure aws --control-plane aws-eks --bootstrap aws-eks 22 | 23 | kubectl apply -f role-binding.yaml 24 | -------------------------------------------------------------------------------- /capi/setup/aws/role-binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: capa-eks-control-plane-manager-rolebinding-role 5 | labels: 6 | cluster.x-k8s.io/provider: infrastructure-aws 7 | clusterctl.cluster.x-k8s.io: '' 8 | subjects: 9 | - kind: ServiceAccount 10 | name: capa-eks-control-plane-controller-manager 11 | namespace: capa-eks-control-plane-system 12 | roleRef: 13 | apiGroup: rbac.authorization.k8s.io 14 | kind: ClusterRole 15 | name: capa-system-capa-manager-role -------------------------------------------------------------------------------- /capi/setup/azure/capz_setup.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Corporation. 2 | # Licensed under the MIT License. 3 | 4 | # Install cluster ctl https://cluster-api.sigs.k8s.io/user/quick-start.html#install-clusterctl 5 | export AZURE_SUBSCRIPTION_ID= 6 | export AZURE_TENANT_ID= 7 | export AZURE_CLIENT_ID= 8 | export AZURE_CLIENT_SECRET= 9 | 10 | export AZURE_ENVIRONMENT="AzurePublicCloud" 11 | 12 | export AZURE_SUBSCRIPTION_ID_B64="$(echo -n "$AZURE_SUBSCRIPTION_ID" | base64 | tr -d '\n')" 13 | export AZURE_TENANT_ID_B64="$(echo -n "$AZURE_TENANT_ID" | base64 | tr -d '\n')" 14 | export AZURE_CLIENT_ID_B64="$(echo -n "$AZURE_CLIENT_ID" | base64 | tr -d '\n')" 15 | export AZURE_CLIENT_SECRET_B64="$(echo -n "$AZURE_CLIENT_SECRET" | base64 | tr -d '\n')" 16 | 17 | export EXP_MACHINE_POOL=true 18 | export EXP_AKS=true 19 | 20 | clusterctl init --infrastructure azure -------------------------------------------------------------------------------- /capi/setup/clusters-sync.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 2 | kind: Kustomization 3 | metadata: 4 | namespace: capi-worker-clusters 5 | name: worker-clusters 6 | spec: 7 | interval: 10m0s 8 | sourceRef: 9 | kind: GitRepository 10 | name: flux-system 11 | namespace: flux-system 12 | path: ./capi/clusters 13 | prune: true -------------------------------------------------------------------------------- /clusters/base/flux-system/gotk-sync.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: source.toolkit.fluxcd.io/v1beta1 3 | kind: GitRepository 4 | metadata: 5 | name: flux-system 6 | namespace: flux-system 7 | spec: 8 | interval: 1m0s 9 | ref: 10 | branch: main 11 | url: https://github.com/kaizentm/multicluster-gitops 12 | --- 13 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 14 | kind: Kustomization 15 | metadata: 16 | name: flux-system 17 | namespace: flux-system 18 | spec: 19 | interval: 10m0s 20 | path: ./clusters/base 21 | prune: true 22 | sourceRef: 23 | kind: GitRepository 24 | name: flux-system 25 | validation: client 26 | -------------------------------------------------------------------------------- /clusters/base/flux-system/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - gotk-components.yaml 5 | - gotk-sync.yaml 6 | -------------------------------------------------------------------------------- /clusters/k3d-america/infra.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 2 | kind: Kustomization 3 | metadata: 4 | name: infrastructure 5 | namespace: flux-system 6 | spec: 7 | interval: 10m0s 8 | sourceRef: 9 | kind: GitRepository 10 | name: flux-system 11 | namespace: flux-system 12 | path: ./infra/k3d-america 13 | prune: true 14 | validation: client -------------------------------------------------------------------------------- /docs/capi-capz.md: -------------------------------------------------------------------------------- 1 | # Provision AKS clusters with Flux and CAPI 2 | 3 | CAPI is an implementation of “K8s operator” pattern (resource + controller) to provision and manage k8s clusters. So we can define a “worker” cluster as a CRD resource and there is a controller running on “managing” cluster which brings the resource to the desired state by actually provisioning/altering the “worker” k8s cluster. That said, it opens a wide door for GitOps when the resource definitions (“worker” cluster descriptors) are delivered to the “managing” K8s cluster from a Git repository by a GitOps operator, e.g. Flux. 4 | 5 | There are a number of various CAPI providers to provision clusters on different clouds (e.g. Azure, AWS, GCP, VMWare, etc.). In this example [Cluster API Provider Azure (CAPZ)](https://capz.sigs.k8s.io/) provisions k8s clusters on Azure. 6 | 7 | The diagram below demonstrates how it actually works: 8 | ![capi.png](images/capi.png) 9 | 10 | Managing cluster can be any K8s cluster (AKS, Kind, k3s, etc.). It’s not supposed to run any workloads. Its purpose is to observe the Fleet repo and provision or update “worker” clusters that run the workloads. Therefore the managing cluster should have a GitOps operator (e.g. Flux) and CAPI/CAPZ installed. 11 | Flux can be installed with the [Flux bootstrap command](https://toolkit.fluxcd.io/guides/installation/). Having done that, we should define a [Flux “clusters” Kustomization](https://github.com/kaizentm/multicluster-gitops/blob/main/capi/mngmt/clusters-sync.yaml) to observe capi/clusters folder in the Fleet repo: 12 | ``` 13 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 14 | kind: Kustomization 15 | metadata: 16 | namespace: capi-worker-clusters 17 | name: worker-clusters 18 | spec: 19 | interval: 10m0s 20 | sourceRef: 21 | kind: GitRepository 22 | name: flux-system 23 | namespace: flux-system 24 | path: ./capi/clusters 25 | prune: true 26 | ``` 27 | CAPI with the Azure provider implementation (CAPZ) can be installed on the managing cluster with the [following script](https://github.com/kaizentm/multicluster-gitops/blob/main/capi/mngmt/capi_setup.sh): 28 | ``` 29 | # Install cluster ctl https://cluster-api.sigs.k8s.io/user/quick-start.html#install-clusterctl 30 | export AZURE_SUBSCRIPTION_ID= 31 | export AZURE_TENANT_ID= 32 | export AZURE_CLIENT_ID= 33 | export AZURE_CLIENT_SECRET= 34 | 35 | export AZURE_ENVIRONMENT="AzurePublicCloud" 36 | 37 | export AZURE_SUBSCRIPTION_ID_B64="$(echo -n "$AZURE_SUBSCRIPTION_ID" | base64 | tr -d '\n')" 38 | export AZURE_TENANT_ID_B64="$(echo -n "$AZURE_TENANT_ID" | base64 | tr -d '\n')" 39 | export AZURE_CLIENT_ID_B64="$(echo -n "$AZURE_CLIENT_ID" | base64 | tr -d '\n')" 40 | export AZURE_CLIENT_SECRET_B64="$(echo -n "$AZURE_CLIENT_SECRET" | base64 | tr -d '\n')" 41 | 42 | export EXP_MACHINE_POOL=true 43 | export EXP_AKS=true 44 | 45 | clusterctl init --infrastructure azure 46 | ``` 47 | 48 | In order to add a cluster to the fleet we need to create a corresponding subfolder (e.g. atlantic-aks) in capi/clusters folder in the Fleet repo. The atlantic-aks subfolder contains a [Flux HelmRelease definition](https://github.com/kaizentm/multicluster-gitops/blob/main/capi/clusters/atlantic-aks/cluster-helm-release.yaml) pointing to a [Hem chart with all necessary CRDs](https://github.com/kaizentm/multicluster-gitops/tree/main/capi/mngmt/aks-cluster-chart) (e.g. Cluster, Control Plane, Agent Pool, etc.) that CAPI/CAPZ will use to provision a cluster in Azure. The HelmRelease also specifies values for the Helm chart such as cluster name, resource group name, agent pools names: 49 | 50 | ``` 51 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 52 | kind: HelmRelease 53 | metadata: 54 | name: atlantic-aks-helm-release 55 | namespace: capi-worker-clusters 56 | spec: 57 | chart: 58 | spec: 59 | chart: ./capi/mngmt/aks-cluster-chart 60 | sourceRef: 61 | kind: GitRepository 62 | name: flux-system 63 | namespace: flux-system 64 | interval: 10m 65 | values: 66 | name: atlantic-aks 67 | clusterResourceGroup: atlantic-aks-rg 68 | controlAgentPoolName: clatlpool 69 | workerAgentPoolName: wratlpool 70 | ``` 71 | 72 | Once a new cluster is defined in the Fleet repo, Flux “clusters” Kustomization reconciles the atlantic-aks HelmRelease and creates the CAPI resources in the cluster. CAPI/CAPZ sees the new resources and brings them to the desired state by provisioning the resources (AKS, node pool, subnet, etc.) in Azure. 73 | 74 | Cluster Helm chart also defines “flux-system” and “infra” Flux Kustomizations. The first one remotely installs Flux on the new provisioned cluster so it can manage its workloads independently. The “infa” Kustomization is responsible for installing all required infrastructure configurations on the new cluster. In this example there is Nginx ingress controller to be set up on all clusters in the fleet. The “infa” Kustomization remotely creates a Flux “nginx” HelmRelease on the new cluster which in its turn will fetch the “nginx” Helm Chart from internet and install it on the cluster. 75 | 76 | To delete or update a cluster, for example to add a new node pool or increase the number of nodes, we just need to make the changes in the Fleet repo. All configurations will be replicated automatically to Azure. 77 | -------------------------------------------------------------------------------- /docs/demo/asian-aks/cluster-helm-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: asian-aks-helm-release 5 | namespace: capi-worker-clusters 6 | spec: 7 | chart: 8 | spec: 9 | chart: ./capi/mngmt/aks-cluster-chart 10 | sourceRef: 11 | kind: GitRepository 12 | name: flux-system 13 | namespace: flux-system 14 | interval: 10m 15 | values: 16 | name: asian-aks 17 | clusterResourceGroup: asian-aks-rg 18 | controlAgentPoolName: claspool 19 | workerAgentPoolName: wraspool 20 | 21 | -------------------------------------------------------------------------------- /docs/images/capi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/multicluster-gitops/bf8f86b01a3ed75ff5c7249daab9a1bb25709d9d/docs/images/capi.png -------------------------------------------------------------------------------- /docs/images/multi-cluster-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/multicluster-gitops/bf8f86b01a3ed75ff5c7249daab9a1bb25709d9d/docs/images/multi-cluster-diagram.png -------------------------------------------------------------------------------- /docs/images/src/capi.drawio: -------------------------------------------------------------------------------- 1 | 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 -------------------------------------------------------------------------------- /infra/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - sources 5 | - nginx 6 | -------------------------------------------------------------------------------- /infra/base/nginx/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | namespace: nginx 4 | resources: 5 | - namespace.yaml 6 | - release.yaml -------------------------------------------------------------------------------- /infra/base/nginx/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: nginx -------------------------------------------------------------------------------- /infra/base/nginx/release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: nginx 5 | spec: 6 | releaseName: nginx-ingress-controller 7 | chart: 8 | spec: 9 | chart: nginx-ingress-controller 10 | sourceRef: 11 | kind: HelmRepository 12 | name: bitnami 13 | namespace: flux-system 14 | version: "5.6.14" 15 | interval: 1h0m0s 16 | install: 17 | remediation: 18 | retries: 3 19 | values: 20 | service: 21 | type: ClusterIP 22 | # Default values 23 | # https://github.com/bitnami/charts/blob/master/bitnami/nginx-ingress-controller/values.yaml 24 | -------------------------------------------------------------------------------- /infra/base/secure-aks-baseline/aad-pod-identity.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1beta1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | name: azureassignedidentities.aadpodidentity.k8s.io 5 | labels: 6 | app.kubernetes.io/name: aad-pod-identity 7 | app.kubernetes.io/instance: aad-pod-identity 8 | spec: 9 | group: aadpodidentity.k8s.io 10 | version: v1 11 | names: 12 | kind: AzureAssignedIdentity 13 | plural: azureassignedidentities 14 | scope: Namespaced 15 | --- 16 | apiVersion: apiextensions.k8s.io/v1beta1 17 | kind: CustomResourceDefinition 18 | metadata: 19 | name: azureidentities.aadpodidentity.k8s.io 20 | labels: 21 | app.kubernetes.io/name: aad-pod-identity 22 | app.kubernetes.io/instance: aad-pod-identity 23 | spec: 24 | group: aadpodidentity.k8s.io 25 | version: v1 26 | names: 27 | kind: AzureIdentity 28 | singular: azureidentity 29 | plural: azureidentities 30 | scope: Namespaced 31 | --- 32 | apiVersion: apiextensions.k8s.io/v1beta1 33 | kind: CustomResourceDefinition 34 | metadata: 35 | name: azureidentitybindings.aadpodidentity.k8s.io 36 | labels: 37 | app.kubernetes.io/name: aad-pod-identity 38 | app.kubernetes.io/instance: aad-pod-identity 39 | spec: 40 | group: aadpodidentity.k8s.io 41 | version: v1 42 | names: 43 | kind: AzureIdentityBinding 44 | plural: azureidentitybindings 45 | scope: Namespaced 46 | --- 47 | apiVersion: apiextensions.k8s.io/v1beta1 48 | kind: CustomResourceDefinition 49 | metadata: 50 | name: azurepodidentityexceptions.aadpodidentity.k8s.io 51 | labels: 52 | app.kubernetes.io/name: aad-pod-identity 53 | app.kubernetes.io/instance: aad-pod-identity 54 | spec: 55 | group: aadpodidentity.k8s.io 56 | version: v1 57 | names: 58 | kind: AzurePodIdentityException 59 | singular: azurepodidentityexception 60 | plural: azurepodidentityexceptions 61 | scope: Namespaced 62 | --- 63 | apiVersion: v1 64 | kind: ServiceAccount 65 | metadata: 66 | name: aad-pod-identity-mic 67 | namespace: cluster-baseline-settings 68 | labels: 69 | app.kubernetes.io/name: aad-pod-identity 70 | app.kubernetes.io/instance: aad-pod-identity 71 | app.kubernetes.io/component: mic 72 | --- 73 | apiVersion: v1 74 | kind: ServiceAccount 75 | metadata: 76 | name: aad-pod-identity-nmi 77 | namespace: cluster-baseline-settings 78 | labels: 79 | app.kubernetes.io/name: aad-pod-identity 80 | app.kubernetes.io/instance: aad-pod-identity 81 | app.kubernetes.io/component: nmi 82 | --- 83 | apiVersion: rbac.authorization.k8s.io/v1 84 | kind: ClusterRole 85 | metadata: 86 | name: aad-pod-identity-mic 87 | labels: 88 | app.kubernetes.io/name: aad-pod-identity 89 | app.kubernetes.io/instance: aad-pod-identity 90 | app.kubernetes.io/component: mic 91 | rules: 92 | - apiGroups: ["apiextensions.k8s.io"] 93 | resources: ["customresourcedefinitions"] 94 | verbs: ["*"] 95 | - apiGroups: [""] 96 | resources: ["pods", "nodes"] 97 | verbs: [ "list", "watch" ] 98 | - apiGroups: [""] 99 | resources: ["events"] 100 | verbs: ["create", "patch"] 101 | - apiGroups: [""] 102 | resources: ["configmaps"] 103 | verbs: ["get", "create", "update"] 104 | - apiGroups: [""] 105 | resources: ["endpoints"] 106 | verbs: [ "create", "get", "update"] 107 | - apiGroups: ["aadpodidentity.k8s.io"] 108 | resources: ["azureidentitybindings", "azureidentities"] 109 | verbs: ["get", "list", "watch", "post", "update"] 110 | - apiGroups: ["aadpodidentity.k8s.io"] 111 | resources: ["azurepodidentityexceptions"] 112 | verbs: ["list", "update"] 113 | - apiGroups: ["aadpodidentity.k8s.io"] 114 | resources: ["azureassignedidentities"] 115 | verbs: ["*"] 116 | --- 117 | apiVersion: rbac.authorization.k8s.io/v1 118 | kind: ClusterRole 119 | metadata: 120 | name: aad-pod-identity-nmi 121 | labels: 122 | app.kubernetes.io/name: aad-pod-identity 123 | app.kubernetes.io/instance: aad-pod-identity 124 | app.kubernetes.io/component: nmi 125 | rules: 126 | - apiGroups: ["apiextensions.k8s.io"] 127 | resources: ["customresourcedefinitions"] 128 | verbs: ["get", "list"] 129 | - apiGroups: [""] 130 | resources: ["pods"] 131 | verbs: ["get", "list", "watch"] 132 | - apiGroups: [""] 133 | resources: ["secrets"] 134 | verbs: ["get"] 135 | - apiGroups: ["aadpodidentity.k8s.io"] 136 | resources: ["azureidentitybindings", "azureidentities", "azurepodidentityexceptions"] 137 | verbs: ["get", "list", "watch"] 138 | - apiGroups: ["aadpodidentity.k8s.io"] 139 | resources: ["azureassignedidentities"] 140 | verbs: ["get", "list", "watch"] 141 | --- 142 | apiVersion: rbac.authorization.k8s.io/v1 143 | kind: ClusterRoleBinding 144 | metadata: 145 | name: aad-pod-identity-mic 146 | labels: 147 | app.kubernetes.io/name: aad-pod-identity 148 | app.kubernetes.io/instance: aad-pod-identity 149 | app.kubernetes.io/component: mic 150 | subjects: 151 | - kind: ServiceAccount 152 | name: aad-pod-identity-mic 153 | namespace: cluster-baseline-settings 154 | roleRef: 155 | kind: ClusterRole 156 | name: aad-pod-identity-mic 157 | apiGroup: rbac.authorization.k8s.io 158 | --- 159 | apiVersion: rbac.authorization.k8s.io/v1 160 | kind: ClusterRoleBinding 161 | metadata: 162 | name: aad-pod-identity-nmi 163 | labels: 164 | app.kubernetes.io/name: aad-pod-identity 165 | app.kubernetes.io/instance: aad-pod-identity 166 | app.kubernetes.io/component: nmi 167 | subjects: 168 | - kind: ServiceAccount 169 | name: aad-pod-identity-nmi 170 | namespace: cluster-baseline-settings 171 | roleRef: 172 | kind: ClusterRole 173 | name: aad-pod-identity-nmi 174 | apiGroup: rbac.authorization.k8s.io 175 | --- 176 | apiVersion: apps/v1 177 | kind: DaemonSet 178 | metadata: 179 | name: aad-pod-identity-nmi 180 | namespace: cluster-baseline-settings 181 | labels: 182 | app.kubernetes.io/name: aad-pod-identity 183 | app.kubernetes.io/instance: aad-pod-identity 184 | app.kubernetes.io/component: nmi 185 | tier: node 186 | annotations: 187 | description: Deploy components for aad-pod-identity 188 | spec: 189 | updateStrategy: 190 | type: RollingUpdate 191 | selector: 192 | matchLabels: 193 | app.kubernetes.io/name: aad-pod-identity 194 | app.kubernetes.io/instance: aad-pod-identity 195 | app.kubernetes.io/component: nmi 196 | tier: node 197 | template: 198 | metadata: 199 | labels: 200 | app.kubernetes.io/name: aad-pod-identity 201 | app.kubernetes.io/instance: aad-pod-identity 202 | app.kubernetes.io/component: nmi 203 | tier: node 204 | spec: 205 | serviceAccountName: aad-pod-identity-nmi 206 | hostNetwork: true 207 | dnsPolicy: ClusterFirstWithHostNet 208 | volumes: 209 | - hostPath: 210 | path: /run/xtables.lock 211 | type: FileOrCreate 212 | name: iptableslock 213 | - hostPath: 214 | path: /etc/default/kubelet 215 | name: kubelet-config 216 | containers: 217 | - name: nmi 218 | image: "mcr.microsoft.com/oss/azure/aad-pod-identity/nmi:v1.7.0" 219 | imagePullPolicy: Always 220 | args: 221 | - "--node=$(NODE_NAME)" 222 | - "--http-probe-port=8085" 223 | env: 224 | - name: NODE_NAME 225 | valueFrom: 226 | fieldRef: 227 | fieldPath: spec.nodeName 228 | securityContext: 229 | runAsUser: 0 230 | capabilities: 231 | add: 232 | - NET_ADMIN 233 | volumeMounts: 234 | - mountPath: /run/xtables.lock 235 | name: iptableslock 236 | - mountPath: /etc/default/kubelet 237 | name: kubelet-config 238 | readOnly: true 239 | livenessProbe: 240 | httpGet: 241 | path: /healthz 242 | port: 8085 243 | initialDelaySeconds: 10 244 | periodSeconds: 5 245 | resources: 246 | limits: 247 | cpu: 200m 248 | memory: 512Mi 249 | requests: 250 | cpu: 100m 251 | memory: 256Mi 252 | nodeSelector: 253 | kubernetes.io/os: linux 254 | --- 255 | apiVersion: apps/v1 256 | kind: Deployment 257 | metadata: 258 | name: aad-pod-identity-mic 259 | namespace: cluster-baseline-settings 260 | labels: 261 | app.kubernetes.io/name: aad-pod-identity 262 | app.kubernetes.io/instance: aad-pod-identity 263 | app.kubernetes.io/component: mic 264 | annotations: 265 | description: Deploy components for aad-pod-identity 266 | spec: 267 | replicas: 2 268 | selector: 269 | matchLabels: 270 | app.kubernetes.io/name: aad-pod-identity 271 | app.kubernetes.io/instance: aad-pod-identity 272 | app.kubernetes.io/component: mic 273 | template: 274 | metadata: 275 | labels: 276 | app.kubernetes.io/name: aad-pod-identity 277 | app.kubernetes.io/instance: aad-pod-identity 278 | app.kubernetes.io/component: mic 279 | spec: 280 | serviceAccountName: aad-pod-identity-mic 281 | containers: 282 | - name: mic 283 | image: "mcr.microsoft.com/oss/azure/aad-pod-identity/mic:v1.7.0" 284 | imagePullPolicy: Always 285 | args: 286 | - "--cloudconfig=/etc/kubernetes/azure.json" 287 | - "--logtostderr" 288 | securityContext: 289 | runAsUser: 0 290 | env: 291 | - name: MIC_POD_NAMESPACE 292 | valueFrom: 293 | fieldRef: 294 | fieldPath: metadata.namespace 295 | volumeMounts: 296 | - name: k8s-azure-file 297 | mountPath: /etc/kubernetes/azure.json 298 | readOnly: true 299 | livenessProbe: 300 | httpGet: 301 | path: /healthz 302 | port: 8080 303 | initialDelaySeconds: 10 304 | periodSeconds: 5 305 | resources: 306 | limits: 307 | cpu: 200m 308 | memory: 1024Mi 309 | requests: 310 | cpu: 100m 311 | memory: 256Mi 312 | volumes: 313 | - name: k8s-azure-file 314 | hostPath: 315 | path: /etc/kubernetes/azure.json 316 | nodeSelector: 317 | kubernetes.io/os: linux 318 | --- 319 | apiVersion: aadpodidentity.k8s.io/v1 320 | kind: AzurePodIdentityException 321 | metadata: 322 | name: aad-pod-identity-mic-exception 323 | namespace: cluster-baseline-settings 324 | spec: 325 | podLabels: 326 | app.kubernetes.io/name: aad-pod-identity 327 | app.kubernetes.io/instance: aad-pod-identity 328 | app.kubernetes.io/component: mic 329 | --- 330 | apiVersion: aadpodidentity.k8s.io/v1 331 | kind: AzurePodIdentityException 332 | metadata: 333 | name: aks-addon-exception 334 | namespace: kube-system 335 | spec: 336 | podLabels: 337 | kubernetes.azure.com/managedby: aks 338 | --- 339 | apiVersion: aadpodidentity.k8s.io/v1 340 | kind: AzurePodIdentityException 341 | metadata: 342 | name: aks-azure-policy-exception 343 | namespace: kube-system 344 | spec: 345 | podLabels: 346 | app: azure-policy 347 | --- 348 | apiVersion: aadpodidentity.k8s.io/v1 349 | kind: AzurePodIdentityException 350 | metadata: 351 | name: oms-agent-exception 352 | namespace: kube-system 353 | spec: 354 | podLabels: 355 | component: oms-agent 356 | --- 357 | apiVersion: aadpodidentity.k8s.io/v1 358 | kind: AzurePodIdentityException 359 | metadata: 360 | name: oms-agent-rs-exception 361 | namespace: kube-system 362 | spec: 363 | podLabels: 364 | rsName: omsagent-rs 365 | -------------------------------------------------------------------------------- /infra/base/secure-aks-baseline/akv-secrets-store-csi.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: secrets-store-csi-driver 5 | namespace: cluster-baseline-settings 6 | labels: 7 | app.kubernetes.io/name: secrets-store-csi-driver 8 | app.kubernetes.io/component: csi-driver 9 | --- 10 | apiVersion: v1 11 | kind: ServiceAccount 12 | metadata: 13 | name: csi-secrets-store-provider-azure 14 | namespace: cluster-baseline-settings 15 | labels: 16 | app.kubernetes.io/name: csi-secrets-store-provider-azure 17 | app.kubernetes.io/component: csi-provider 18 | --- 19 | apiVersion: rbac.authorization.k8s.io/v1 20 | kind: ClusterRole 21 | metadata: 22 | creationTimestamp: null 23 | name: secretproviderclasses-role 24 | labels: 25 | app.kubernetes.io/name: secrets-store-csi-driver 26 | app.kubernetes.io/component: csi-driver 27 | rules: 28 | - apiGroups: 29 | - "" 30 | resources: 31 | - events 32 | verbs: 33 | - create 34 | - patch 35 | - apiGroups: 36 | - "" 37 | resources: 38 | - pods 39 | verbs: 40 | - get 41 | - list 42 | - watch 43 | - apiGroups: 44 | - secrets-store.csi.x-k8s.io 45 | resources: 46 | - secretproviderclasses 47 | verbs: 48 | - get 49 | - list 50 | - watch 51 | - apiGroups: 52 | - secrets-store.csi.x-k8s.io 53 | resources: 54 | - secretproviderclasspodstatuses 55 | verbs: 56 | - create 57 | - delete 58 | - get 59 | - list 60 | - patch 61 | - update 62 | - watch 63 | - apiGroups: 64 | - secrets-store.csi.x-k8s.io 65 | resources: 66 | - secretproviderclasspodstatuses/status 67 | verbs: 68 | - get 69 | - patch 70 | - update 71 | --- 72 | apiVersion: rbac.authorization.k8s.io/v1 73 | kind: ClusterRoleBinding 74 | metadata: 75 | name: secretproviderclasses-rolebinding 76 | labels: 77 | app.kubernetes.io/name: secrets-store-csi-driver 78 | app.kubernetes.io/component: csi-driver 79 | roleRef: 80 | apiGroup: rbac.authorization.k8s.io 81 | kind: ClusterRole 82 | name: secretproviderclasses-role 83 | subjects: 84 | - kind: ServiceAccount 85 | name: secrets-store-csi-driver 86 | namespace: cluster-baseline-settings 87 | --- 88 | apiVersion: rbac.authorization.k8s.io/v1 89 | kind: ClusterRole 90 | metadata: 91 | creationTimestamp: null 92 | name: secretprovidersyncing-role 93 | labels: 94 | app.kubernetes.io/name: secrets-store-csi-driver 95 | app.kubernetes.io/component: csi-driver 96 | rules: 97 | - apiGroups: 98 | - "" 99 | resources: 100 | - secrets 101 | verbs: 102 | - create 103 | - delete 104 | - get 105 | - list 106 | - patch 107 | - update 108 | - watch 109 | --- 110 | apiVersion: rbac.authorization.k8s.io/v1 111 | kind: ClusterRoleBinding 112 | metadata: 113 | name: secretprovidersyncing-rolebinding 114 | labels: 115 | app.kubernetes.io/name: secrets-store-csi-driver 116 | app.kubernetes.io/component: csi-driver 117 | roleRef: 118 | apiGroup: rbac.authorization.k8s.io 119 | kind: ClusterRole 120 | name: secretprovidersyncing-role 121 | subjects: 122 | - kind: ServiceAccount 123 | name: secrets-store-csi-driver 124 | namespace: cluster-baseline-settings 125 | --- 126 | apiVersion: storage.k8s.io/v1 127 | kind: CSIDriver 128 | metadata: 129 | name: secrets-store.csi.k8s.io 130 | labels: 131 | app.kubernetes.io/name: secrets-store-csi-driver 132 | app.kubernetes.io/component: csi-driver 133 | spec: 134 | podInfoOnMount: true 135 | attachRequired: false 136 | volumeLifecycleModes: 137 | - Ephemeral 138 | --- 139 | apiVersion: apiextensions.k8s.io/v1 140 | kind: CustomResourceDefinition 141 | metadata: 142 | annotations: 143 | controller-gen.kubebuilder.io/version: v0.4.0 144 | creationTimestamp: null 145 | name: secretproviderclasses.secrets-store.csi.x-k8s.io 146 | labels: 147 | app.kubernetes.io/name: secrets-store-csi-driver-secretproviderclasses-crd 148 | app.kubernetes.io/component: csi-driver 149 | spec: 150 | group: secrets-store.csi.x-k8s.io 151 | names: 152 | kind: SecretProviderClass 153 | listKind: SecretProviderClassList 154 | plural: secretproviderclasses 155 | singular: secretproviderclass 156 | scope: Namespaced 157 | versions: 158 | - name: v1alpha1 159 | schema: 160 | openAPIV3Schema: 161 | description: SecretProviderClass is the Schema for the secretproviderclasses 162 | API 163 | properties: 164 | apiVersion: 165 | description: 'APIVersion defines the versioned schema of this representation 166 | of an object. Servers should convert recognized schemas to the latest 167 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 168 | type: string 169 | kind: 170 | description: 'Kind is a string value representing the REST resource this 171 | object represents. Servers may infer this from the endpoint the client 172 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 173 | type: string 174 | metadata: 175 | type: object 176 | spec: 177 | description: SecretProviderClassSpec defines the desired state of SecretProviderClass 178 | properties: 179 | parameters: 180 | additionalProperties: 181 | type: string 182 | description: Configuration for specific provider 183 | type: object 184 | provider: 185 | description: Configuration for provider name 186 | type: string 187 | secretObjects: 188 | items: 189 | description: SecretObject defines the desired state of synced K8s 190 | secret objects 191 | properties: 192 | data: 193 | items: 194 | description: SecretObjectData defines the desired state of 195 | synced K8s secret object data 196 | properties: 197 | key: 198 | description: data field to populate 199 | type: string 200 | objectName: 201 | description: name of the object to sync 202 | type: string 203 | type: object 204 | type: array 205 | labels: 206 | additionalProperties: 207 | type: string 208 | description: labels of K8s secret object 209 | type: object 210 | secretName: 211 | description: name of the K8s secret object 212 | type: string 213 | type: 214 | description: type of K8s secret object 215 | type: string 216 | type: object 217 | type: array 218 | type: object 219 | status: 220 | description: SecretProviderClassStatus defines the observed state of SecretProviderClass 221 | properties: 222 | byPod: 223 | items: 224 | description: ByPodStatus defines the state of SecretProviderClass 225 | as seen by an individual controller 226 | properties: 227 | id: 228 | description: id of the pod that wrote the status 229 | type: string 230 | namespace: 231 | description: namespace of the pod that wrote the status 232 | type: string 233 | type: object 234 | type: array 235 | type: object 236 | type: object 237 | served: true 238 | storage: true 239 | status: 240 | acceptedNames: 241 | kind: "" 242 | plural: "" 243 | conditions: [] 244 | storedVersions: [] 245 | --- 246 | apiVersion: apiextensions.k8s.io/v1 247 | kind: CustomResourceDefinition 248 | metadata: 249 | annotations: 250 | controller-gen.kubebuilder.io/version: v0.4.0 251 | creationTimestamp: null 252 | name: secretproviderclasspodstatuses.secrets-store.csi.x-k8s.io 253 | labels: 254 | app.kubernetes.io/name: secrets-store-csi-driver-secretproviderclasspodstatuses-crd 255 | app.kubernetes.io/component: csi-driver 256 | spec: 257 | group: secrets-store.csi.x-k8s.io 258 | names: 259 | kind: SecretProviderClassPodStatus 260 | listKind: SecretProviderClassPodStatusList 261 | plural: secretproviderclasspodstatuses 262 | singular: secretproviderclasspodstatus 263 | scope: Namespaced 264 | versions: 265 | - name: v1alpha1 266 | schema: 267 | openAPIV3Schema: 268 | description: SecretProviderClassPodStatus is the Schema for the secretproviderclassespodstatus 269 | API 270 | properties: 271 | apiVersion: 272 | description: 'APIVersion defines the versioned schema of this representation 273 | of an object. Servers should convert recognized schemas to the latest 274 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 275 | type: string 276 | kind: 277 | description: 'Kind is a string value representing the REST resource this 278 | object represents. Servers may infer this from the endpoint the client 279 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 280 | type: string 281 | metadata: 282 | type: object 283 | status: 284 | description: SecretProviderClassPodStatusStatus defines the observed state 285 | of SecretProviderClassPodStatus 286 | properties: 287 | mounted: 288 | type: boolean 289 | objects: 290 | items: 291 | description: SecretProviderClassObject defines the object fetched 292 | from external secrets store 293 | properties: 294 | id: 295 | type: string 296 | version: 297 | type: string 298 | type: object 299 | type: array 300 | podName: 301 | type: string 302 | secretProviderClassName: 303 | type: string 304 | targetPath: 305 | type: string 306 | type: object 307 | type: object 308 | served: true 309 | storage: true 310 | status: 311 | acceptedNames: 312 | kind: "" 313 | plural: "" 314 | conditions: [] 315 | storedVersions: [] 316 | --- 317 | kind: DaemonSet 318 | apiVersion: apps/v1 319 | metadata: 320 | name: csi-secrets-store 321 | namespace: cluster-baseline-settings 322 | labels: 323 | app: csi-secrets-store 324 | app.kubernetes.io/name: csi-secrets-store 325 | app.kubernetes.io/component: csi-driver 326 | spec: 327 | selector: 328 | matchLabels: 329 | app: csi-secrets-store 330 | template: 331 | metadata: 332 | labels: 333 | app: csi-secrets-store 334 | app.kubernetes.io/name: csi-secrets-store 335 | app.kubernetes.io/component: csi-driver 336 | spec: 337 | nodeSelector: 338 | kubernetes.io/os: linux 339 | serviceAccountName: secrets-store-csi-driver 340 | hostNetwork: true 341 | containers: 342 | - name: node-driver-registrar 343 | image: mcr.microsoft.com/oss/kubernetes-csi/csi-node-driver-registrar:v2.0.1 344 | args: 345 | - --v=5 346 | - --csi-address=/csi/csi.sock 347 | - --kubelet-registration-path=/var/lib/kubelet/plugins/csi-secrets-store/csi.sock 348 | env: 349 | - name: KUBE_NODE_NAME 350 | valueFrom: 351 | fieldRef: 352 | apiVersion: v1 353 | fieldPath: spec.nodeName 354 | imagePullPolicy: Always 355 | volumeMounts: 356 | - name: plugin-dir 357 | mountPath: /csi 358 | - name: registration-dir 359 | mountPath: /registration 360 | resources: 361 | limits: 362 | cpu: 100m 363 | memory: 100Mi 364 | requests: 365 | cpu: 10m 366 | memory: 20Mi 367 | - name: secrets-store 368 | image: mcr.microsoft.com/oss/kubernetes-csi/secrets-store/driver:v0.0.17 369 | args: 370 | - "--debug=false" 371 | - "--endpoint=$(CSI_ENDPOINT)" 372 | - "--nodeid=$(KUBE_NODE_NAME)" 373 | - "--provider-volume=/etc/kubernetes/secrets-store-csi-providers" 374 | - "--metrics-addr=:8095" 375 | - "--enable-secret-rotation=false" # To use this alpha feature, follow guidance at https://github.com/kubernetes-sigs/secrets-store-csi-driver/blob/master/docs/README.rotation.md 376 | - "--rotation-poll-interval=5m" 377 | - "--grpc-supported-providers=azure" 378 | env: 379 | - name: CSI_ENDPOINT 380 | value: unix:///csi/csi.sock 381 | - name: KUBE_NODE_NAME 382 | valueFrom: 383 | fieldRef: 384 | apiVersion: v1 385 | fieldPath: spec.nodeName 386 | imagePullPolicy: Always 387 | securityContext: 388 | privileged: true 389 | ports: 390 | - containerPort: 9808 391 | name: healthz 392 | protocol: TCP 393 | livenessProbe: 394 | failureThreshold: 5 395 | httpGet: 396 | path: /healthz 397 | port: healthz 398 | initialDelaySeconds: 30 399 | timeoutSeconds: 10 400 | periodSeconds: 15 401 | volumeMounts: 402 | - name: plugin-dir 403 | mountPath: /csi 404 | - name: mountpoint-dir 405 | mountPath: /var/lib/kubelet/pods 406 | mountPropagation: Bidirectional 407 | - name: providers-dir 408 | mountPath: /etc/kubernetes/secrets-store-csi-providers 409 | resources: 410 | limits: 411 | cpu: 200m 412 | memory: 200Mi 413 | requests: 414 | cpu: 50m 415 | memory: 100Mi 416 | - name: liveness-probe 417 | image: mcr.microsoft.com/oss/kubernetes-csi/livenessprobe:v2.1.0 418 | imagePullPolicy: Always 419 | args: 420 | - --csi-address=/csi/csi.sock 421 | - --probe-timeout=3s 422 | - --health-port=9808 423 | - -v=2 424 | volumeMounts: 425 | - name: plugin-dir 426 | mountPath: /csi 427 | resources: 428 | limits: 429 | cpu: 100m 430 | memory: 100Mi 431 | requests: 432 | cpu: 10m 433 | memory: 20Mi 434 | volumes: 435 | - name: mountpoint-dir 436 | hostPath: 437 | path: /var/lib/kubelet/pods 438 | type: DirectoryOrCreate 439 | - name: registration-dir 440 | hostPath: 441 | path: /var/lib/kubelet/plugins_registry/ 442 | type: Directory 443 | - name: plugin-dir 444 | hostPath: 445 | path: /var/lib/kubelet/plugins/csi-secrets-store/ 446 | type: DirectoryOrCreate 447 | - name: providers-dir 448 | hostPath: 449 | path: /etc/kubernetes/secrets-store-csi-providers 450 | type: DirectoryOrCreate 451 | --- 452 | apiVersion: apps/v1 453 | kind: DaemonSet 454 | metadata: 455 | name: csi-secrets-store-provider-azure 456 | namespace: cluster-baseline-settings 457 | labels: 458 | app: csi-secrets-store-provider-azure 459 | app.kubernetes.io/name: csi-secrets-store-provider-azure 460 | app.kubernetes.io/component: csi-provider 461 | spec: 462 | updateStrategy: 463 | type: RollingUpdate 464 | selector: 465 | matchLabels: 466 | app: csi-secrets-store-provider-azure 467 | template: 468 | metadata: 469 | labels: 470 | app: csi-secrets-store-provider-azure 471 | app.kubernetes.io/name: csi-secrets-store-provider-azure 472 | app.kubernetes.io/component: csi-provider 473 | spec: 474 | serviceAccountName: csi-secrets-store-provider-azure 475 | hostNetwork: true 476 | containers: 477 | - name: provider-azure-installer 478 | image: mcr.microsoft.com/oss/azure/secrets-store/provider-azure:0.0.10 479 | imagePullPolicy: IfNotPresent 480 | args: 481 | - --endpoint=unix:///provider/azure.sock 482 | lifecycle: 483 | preStop: 484 | exec: 485 | command: 486 | - "rm /provider/azure.sock" 487 | resources: 488 | requests: 489 | cpu: 50m 490 | memory: 100Mi 491 | limits: 492 | cpu: 50m 493 | memory: 100Mi 494 | volumeMounts: 495 | - mountPath: "/provider" 496 | name: providervol 497 | - name: mountpoint-dir 498 | mountPath: /var/lib/kubelet/pods 499 | mountPropagation: HostToContainer 500 | volumes: 501 | - name: providervol 502 | hostPath: 503 | path: "/etc/kubernetes/secrets-store-csi-providers" 504 | - name: mountpoint-dir 505 | hostPath: 506 | path: /var/lib/kubelet/pods 507 | nodeSelector: 508 | kubernetes.io/os: linux -------------------------------------------------------------------------------- /infra/base/secure-aks-baseline/container-azm-ms-agentconfig.yaml: -------------------------------------------------------------------------------- 1 | kind: ConfigMap 2 | apiVersion: v1 3 | data: 4 | # https://raw.githubusercontent.com/microsoft/Docker-Provider/ci_prod/kubernetes/container-azm-ms-agentconfig.yaml 5 | schema-version: v1 6 | config-version: ver1 7 | log-data-collection-settings: |- 8 | [log_collection_settings] 9 | [log_collection_settings.stdout] 10 | enabled = true 11 | exclude_namespaces = ["kube-system"] 12 | [log_collection_settings.stderr] 13 | enabled = true 14 | exclude_namespaces = ["kube-system"] 15 | [log_collection_settings.env_var] 16 | enabled = true 17 | [log_collection_settings.enrich_container_logs] 18 | enabled = false 19 | [log_collection_settings.collect_all_kube_events] 20 | enabled = false 21 | prometheus-data-collection-settings: |- 22 | [prometheus_data_collection_settings.cluster] 23 | interval = "1m" 24 | monitor_kubernetes_pods = true 25 | [prometheus_data_collection_settings.node] 26 | interval = "1m" 27 | urls = ["http://$NODE_IP:9103/metrics"] 28 | metric_collection_settings: |- 29 | [metric_collection_settings.collect_kube_system_pv_metrics] 30 | enabled = true 31 | alertable-metrics-configuration-settings: |- 32 | [alertable_metrics_configuration_settings.container_resource_utilization_thresholds] 33 | container_cpu_threshold_percentage = 90.0 34 | container_memory_rss_threshold_percentage = 90.0 35 | container_memory_working_set_threshold_percentage = 90.0 36 | [alertable_metrics_configuration_settings.pv_utilization_thresholds] 37 | pv_usage_threshold_percentage = 75.0 38 | integrations: |- 39 | [integrations.azure_network_policy_manager] 40 | collect_basic_metrics = true 41 | collect_advanced_metrics = false 42 | metadata: 43 | name: container-azm-ms-agentconfig 44 | namespace: kube-system -------------------------------------------------------------------------------- /infra/base/secure-aks-baseline/kured-1.4.0-dockerhub.yaml: -------------------------------------------------------------------------------- 1 | # https://github.com/weaveworks/kured/releases/download/1.4.0/kured-1.4.0-dockerhub.yaml 2 | --- 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: ClusterRole 5 | metadata: 6 | name: kured 7 | rules: 8 | - apiGroups: [""] 9 | resources: ["nodes"] 10 | verbs: ["get", "patch"] 11 | - apiGroups: [""] 12 | resources: ["pods"] 13 | verbs: ["list", "delete", "get"] 14 | - apiGroups: ["apps"] 15 | resources: ["daemonsets"] 16 | verbs: ["get"] 17 | - apiGroups: [""] 18 | resources: ["pods/eviction"] 19 | verbs: ["create"] 20 | --- 21 | apiVersion: rbac.authorization.k8s.io/v1 22 | kind: ClusterRoleBinding 23 | metadata: 24 | name: kured 25 | roleRef: 26 | apiGroup: rbac.authorization.k8s.io 27 | kind: ClusterRole 28 | name: kured 29 | subjects: 30 | - kind: ServiceAccount 31 | name: kured 32 | namespace: cluster-baseline-settings 33 | --- 34 | apiVersion: rbac.authorization.k8s.io/v1 35 | kind: Role 36 | metadata: 37 | namespace: cluster-baseline-settings 38 | name: kured 39 | rules: 40 | - apiGroups: ["apps"] 41 | resources: ["daemonsets"] 42 | resourceNames: ["kured"] 43 | verbs: ["update"] 44 | --- 45 | apiVersion: rbac.authorization.k8s.io/v1 46 | kind: RoleBinding 47 | metadata: 48 | namespace: cluster-baseline-settings 49 | name: kured 50 | subjects: 51 | - kind: ServiceAccount 52 | namespace: cluster-baseline-settings 53 | name: kured 54 | roleRef: 55 | apiGroup: rbac.authorization.k8s.io 56 | kind: Role 57 | name: kured 58 | --- 59 | apiVersion: v1 60 | kind: ServiceAccount 61 | metadata: 62 | name: kured 63 | namespace: cluster-baseline-settings 64 | --- 65 | apiVersion: apps/v1 66 | kind: DaemonSet 67 | metadata: 68 | name: kured 69 | namespace: cluster-baseline-settings 70 | spec: 71 | selector: 72 | matchLabels: 73 | name: kured 74 | updateStrategy: 75 | type: RollingUpdate 76 | template: 77 | metadata: 78 | labels: 79 | name: kured 80 | annotations: 81 | prometheus.io/scrape: "true" 82 | prometheus.io/port: "8080" 83 | spec: 84 | serviceAccountName: kured 85 | tolerations: 86 | - key: node-role.kubernetes.io/master 87 | effect: NoSchedule 88 | hostPID: true 89 | restartPolicy: Always 90 | containers: 91 | - name: kured 92 | # PRODUCTION READINESS CHANGE REQUIRED 93 | # This image should be sourced from a non-public container registry, such as the 94 | # one deployed along side of this reference implementation. 95 | # az acr import --source docker.io/weaveworks/kured:1.4.0 -n 96 | # and then set this to 97 | # image: .azurecr.io/weaveworks/kured:1.4.0 98 | image: docker.io/weaveworks/kured:1.4.0 99 | imagePullPolicy: IfNotPresent 100 | securityContext: 101 | privileged: true 102 | env: 103 | - name: KURED_NODE_ID 104 | valueFrom: 105 | fieldRef: 106 | fieldPath: spec.nodeName 107 | command: 108 | - /usr/bin/kured 109 | - --ds-namespace=cluster-baseline-settings -------------------------------------------------------------------------------- /infra/base/secure-aks-baseline/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - aad-pod-identity.yaml 5 | - akv-secrets-store-csi.yaml 6 | - container-azm-ms-agentconfig.yaml 7 | - kured-1.4.0-dockerhub.yaml 8 | - namespace.yaml 9 | - network-policy.yaml 10 | -------------------------------------------------------------------------------- /infra/base/secure-aks-baseline/namespace.yaml: -------------------------------------------------------------------------------- 1 | kind: Namespace 2 | apiVersion: v1 3 | metadata: 4 | name: cluster-baseline-settings 5 | -------------------------------------------------------------------------------- /infra/base/secure-aks-baseline/network-policy.yaml: -------------------------------------------------------------------------------- 1 | kind: NetworkPolicy 2 | apiVersion: networking.k8s.io/v1 3 | metadata: 4 | name: allow-only-ingress-to-prod 5 | namespace: cluster-baseline-settings 6 | spec: 7 | podSelector: 8 | matchLabels: 9 | env: prod 10 | ingress: 11 | - from: 12 | - namespaceSelector: {} 13 | podSelector: 14 | matchLabels: 15 | app.kubernetes.io/name: traefik-ingress-ilb 16 | app.kubernetes.io/instance: traefik-ingress-ilb 17 | --- 18 | kind: NetworkPolicy 19 | apiVersion: networking.k8s.io/v1 20 | metadata: 21 | name: deny-egress-from-prod 22 | namespace: cluster-baseline-settings 23 | spec: 24 | podSelector: 25 | matchLabels: 26 | env: prod 27 | policyTypes: 28 | - Egress -------------------------------------------------------------------------------- /infra/base/secure-aks-baseline/readme.md: -------------------------------------------------------------------------------- 1 | ### This folder contains configurations required by [AKS Secure Baseline Architecture](https://github.com/mspnp/aks-secure-baseline) 2 | 3 | - Azure AD Pod Identity 4 | - Azure KeyVault Secret Store CSI Provider 5 | - Azure Monitor Prometheus Scraping 6 | - Kured 7 | - Network policy 8 | 9 | 10 | -------------------------------------------------------------------------------- /infra/base/sources/bitnami.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta1 2 | kind: HelmRepository 3 | metadata: 4 | name: bitnami 5 | spec: 6 | interval: 30m 7 | url: https://charts.bitnami.com/bitnami 8 | -------------------------------------------------------------------------------- /infra/base/sources/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | namespace: flux-system 4 | resources: 5 | - bitnami.yaml 6 | -------------------------------------------------------------------------------- /infra/k3d-america/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - ../base/sources 5 | - nginx 6 | -------------------------------------------------------------------------------- /infra/k3d-america/nginx/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | namespace: nginx 4 | resources: 5 | - ../../base/nginx 6 | patchesStrategicMerge: 7 | - release.yaml -------------------------------------------------------------------------------- /infra/k3d-america/nginx/release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: nginx 5 | spec: 6 | values: 7 | service: 8 | type: ClusterIP 9 | ports: 10 | http: 8080 -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Multi-cluster and multi-tenant environment with Flux v2 2 | 3 | This repository contains a sample of GitOps setup that supports multi-cluster and multi-tenant environments with Flux v2. It used [Flux V2 Multi-Tenancy](https://github.com/fluxcd/flux2-multi-tenancy) repository as a starting point for considerations. 4 | 5 | The repository targets to cover the following use-cases: 6 | 7 | **Use-cases**: 8 | 9 | 1. *An organization has a few K8s clusters across the globe. Let's say a cluster per region (EMEA, Asia, America). There are also a few environments (Dev, Qa, Prod) distributed across these clusters. So each environment is represented on all clusters. There are also 100 teams working on these environments. When a team's application is being deployed to a Dev environment, for example, it's being deployed to all three clusters (in Dev environment). However, on each cluster the application behaves slightly differently (e.g. it communicates to external services hosted in that region). The desire is to have a single GitOps setup of the application, declaring that it should be deployed across all available clusters in the environment with a specific configuration for each cluster (e.g. different DB connection strings in different clusters, different load balancing settings, even different image tags).* 10 | 11 | 2. *There is a fleet of K8s clusters (e.g. 'edge' clusters at each POS location). There is a single GitOps setup of the application declaring that it should be deployed across all clusters defined in the fleet. The desire is to be able to easily add/remove a cluster to the whole setup.* 12 | 13 | To better understand the solution provided in this repository, it would be helpful to follow the whole reconciliation process of a dev environment happening on one of the clusters in a fleet. This process is represented on the following diagram: 14 | 15 | ![multi-cluster-diagram.png](docs/images/multi-cluster-diagram.png) 16 | 17 | The [fleet repository](https://github.com/kaizentm/multicluster-gitops) (this one) represents environments with branches. For example, [Dev branch](https://github.com/kaizentm/multicluster-gitops/tree/dev) describes clusters, infrastructure resources, tenants with their applications, everything that Dev environment consists of. QA branch describes resources for the QA environment and so on. In order to make changes in an environment configurations one needs to create a PR to the corresponding branch. Different branches/environments normally have different reviewing/approving policies. 18 | 19 | The [Main branch](https://github.com/kaizentm/multicluster-gitops) contains resources outside of environments, things that are common and shared by all environments. It might be Flux binary components running in flux-system namespace, any common infrastructure microservices such as Nginx, for example. 20 | 21 | When a new cluster is added to the setup it should be bootstrapped with Flux. The [flux bootstrap](https://toolkit.fluxcd.io/cmd/flux_bootstrap/) command points to [cluster/base/flux-system](cluster/base/flux-system) folder in the Main branch and creates in the new cluster flux-system namespace, GitRepository source, Flux Kustomization, CRDs and all necessary Flux binary components. 22 | 23 | In addition to that [Flux Kustomization "infrastructure"](clusters/k3d-america/infra.yaml) is created to reconcile all common infra resources that should be installed on the cluster. In this case this reconciliation creates Nginx namespace, HelmRepository source and HelmRelease that will fetch Nginx helm chart from Bitnami Helm repository and install it on the cluster. Although Nginx is a common resource, which is supposed to be installed on every cluster, each cluster may have some specific configurations. Here we override ingress service port number in [infra/k3d-america/nginx/release.yaml](infra/k3d-america/nginx/release.yaml). Pay attention, that "cluster" here may represent not a single physical cluster but a group of clusters with the exact same configurations, for example a group of clusters in a region. See [add a cluster](#add-a-cluster) procedure for the details. 24 | 25 | When the new new cluster is added to an environment (e.g. dev), the dev-flux-system namespace, GitRepository source, Flux Kustomizations "infrastructure" and "tenants" are created. See [add a cluster to an environment](#add-a-cluster-to-an-environment) procedure for the details. 26 | 27 | Flux Kustomizations "infrastructure" in the dev-flux-system namespace reconciles all infra resources that are specific for this environment. In this case dev-redis namespace with a corresponding deployment is created. We override specific for the k3d-america cluster deployment parameters in [infra/k3d-america/redis/redis.yaml](https://github.com/kaizentm/multicluster-gitops/blob/dev/infra/k3d-america/redis/redis.yaml). 28 | 29 | Flux Kustomizations "tenants" refers to a list of tenants sharing the Dev environment on this cluster. It creates a namespace for each tenant which is considered as a sandbox for this tenant in this environment on this cluster. Within the namespace it creates GitRepository source pointing to Dev branch of tenant's manifests repository that contains applications manifests to be deployed to the dev environment. Each tenant has a number of applications. For each of them a Flux Kustomization is created to reconcile the application resources. For example, Flux Kustomization "azure-vote" creates Azure Vote application components. Again, since the application on every cluster (even in the same environment) may be deployed with specific configurations, the Kustomization reads application manifests from k3d-america folder. 30 | 31 | A cluster can be added to the fleet as a "remote" cluster. This means it doesn't have any Flux components installed and it's not connected to a Git repository. All deployments to a "remote" cluster are propagated by Flux working on a "management" cluster. For example "k3s-america-south" is a "remote" cluster managed by "k3d-america" "management" cluster. "k3d-america" cluster has Flux Kustomization "k3s-america-south-infrastructure" that replicates resources from infra/k3d-america/clusters/k3s-america-south folder to "k3s-america-south" cluster. In a similar way Flux Kustomization "k3s-america-south-azure-vote" in "dev-kaizentm" namespace replicates "azure-vote" application to 32 | "k3s-america-south" cluster. See [add a remote cluster to an environment](#add-a-remote-cluster-to-an-environment) procedure for adding a remote cluster to an environment. 33 | 34 | Besides managing infrastructure and tenants' workloads on clusters in GitOps way, it's also possible to provision K8s clusters themselves in GitOps fashion. So that we just add a new cluster definition to the fleet repo and, in a while, there is a new cluster provisioned with Flux installed on it and all the required infra setup up and running. Furthermore, the cluster is provisioned in compliance with all the security regulations required in the organization. Follow the [Provision AKS clusters with Flux and CAPI](docs/capi.md) guidance to learn how to provision AKS clusters with CAPI and Flux. 35 | 36 | 37 | ### Add a cluster 38 | To add a cluster to a fleet perform the following: 39 | - Make sure kubectl context is configured to the new cluster 40 | ``` 41 | kubectl config use-context YOUR_CONTEXT 42 | ``` 43 | - Add a cluster to the fleet 44 | ``` 45 | export GITHUB_TOKEN= 46 | export GITHUB_USER= 47 | export GITHUB_REPO= 48 | 49 | ./utils/add-cluster.sh YOUR_CLUSTER_NAME 50 | ``` 51 | This will create flux-system namespace in your cluster and create a few folders in the repo 52 | YOUR_CLUSTER_NAME may be a cluster group name, so every time we are adding a new cluster from the group we are specifying the same group name. 53 | 54 | - Commit and push changes created by add-cluster.sh 55 | - Check that new infra namespaces are created in the cluster, such as "nginx" 56 | ``` 57 | kubectl get namespaces 58 | 59 | NAME STATUS AGE 60 | default Active 28m 61 | kube-system Active 28m 62 | kube-public Active 28m 63 | kube-node-lease Active 28m 64 | nginx Active 7m48s 65 | flux-system Active 24m 66 | ``` 67 | 68 | ### Add a cluster to an environment 69 | To add a cluster to an environment (e.g Dev) switch to dev branch of this repo and perform the following: 70 | - Execute the following command: 71 | ``` 72 | ./utils/add-cluster-environment.sh YOUR_CLUSTER_NAME 73 | ``` 74 | This will create YOUR_CLUSTER_NAME subfolders in "clusters","infra" and "tenants" folders. It will also create dev-flux-system namespace, "infrastructure" and "tenants" Flux Kustomizations in the cluster. 75 | - Commit and push changes created by add-cluster-environment.sh 76 | - Check that new namespaces with environment specific infra (e.g. dev-redis) and tenants namespaces (e.g. dev-kaizentm) are created in the cluster 77 | ``` 78 | kubectl get namespaces 79 | 80 | NAME STATUS AGE 81 | default Active 3h5m 82 | kube-system Active 3h5m 83 | kube-public Active 3h5m 84 | kube-node-lease Active 3h5m 85 | flux-system Active 3h1m 86 | nginx Active 164m 87 | dev-flux-system Active 18m 88 | dev-kaizentm Active 16m 89 | dev-redis Active 16m 90 | ``` 91 | 92 | ### Add a remote cluster to an environment 93 | To add a remote cluster to an environment (e.g Dev) switch to dev branch of this repo and perform the following: 94 | - Execute the following command: 95 | ``` 96 | ./utils/add-remote-cluster-environment.sh MANAGED_CLUSTER_NAME REMOTE_CLUSTER_NAME KUBE_CONFIG_FILE 97 | ``` 98 | for example 99 | ``` 100 | ./utils/add-remote-cluster-environment.sh k3d-america k3s-america-north ./k3s-america-north.conf 101 | ``` 102 | where k3s-america-north.conf is a kubeconfig file to connect to k3s-america-north. 103 | This will create MANAGED_CLUSTER_NAME/REMOTE_CLUSTER_NAME subfolder in "clusters" folder and MANAGED_CLUSTER_NAME/clusters/REMOTE_CLUSTER_NAME subfolders in "infra" and "tenants" folders. 104 | - Commit and push changes created by add-remote-cluster-environment.sh 105 | - Check on the "remote" cluster "k3s-america-north" that new namespaces with environment specific infra (e.g. dev-redis) and tenants namespaces (e.g. dev-kaizentm) are created in the cluster 106 | ``` 107 | kubectl get namespaces 108 | 109 | NAME STATUS AGE 110 | default Active 3h5m 111 | kube-system Active 3h5m 112 | kube-public Active 3h5m 113 | kube-node-lease Active 3h5m 114 | dev-kaizentm Active 16m 115 | dev-redis Active 16m 116 | ``` 117 | 118 | ### Remove a cluster from an environment 119 | To remove a cluster from an environment (e.g Dev) switch to dev branch of this repo and perform the following: 120 | - Execute the following command: 121 | ``` 122 | ./utils/remove-cluster-from-environment.sh YOUR_CLUSTER_NAME 123 | ``` 124 | This will delete YOUR_CLUSTER_NAME subfolders in "clusters","infra" and "tenants" folders. It will also delete dev-flux-system namespace, "infrastructure" and "tenants" Flux Kustomizations in the cluster. 125 | - Commit and push changes created by remove-cluster-from-environment.sh 126 | - Check that environment specific namespaces are deleted 127 | ``` 128 | kubectl get namespaces 129 | 130 | NAME STATUS AGE 131 | default Active 3h5m 132 | kube-system Active 3h5m 133 | kube-public Active 3h5m 134 | kube-node-lease Active 3h5m 135 | flux-system Active 3h1m 136 | nginx Active 164m 137 | ``` 138 | 139 | ### Add a tenant 140 | To add a tenant to an environment switch to the environment branch (e.g. dev) and perform the following: 141 | - Execute the following command 142 | ``` 143 | ./utils/add-tenant.sh TENANT_NAME REPO_URL REPO_BRANCH_NAME 144 | ``` 145 | for example 146 | ``` 147 | ./utils/add-tenant.sh yakuza https://github.com/yakuza/gitops-manifests dev 148 | ``` 149 | This will create corresponding subfolders for each cluster in "tenants" folder. 150 | - Commit and push changes created by add-tenant.sh 151 | - Check that tenant's namespace for this environment (e.g dev-yakuza) is available on the environment clusters 152 | ``` 153 | kubectl get namespaces 154 | 155 | NAME STATUS AGE 156 | default Active 3h5m 157 | kube-system Active 3h5m 158 | kube-public Active 3h5m 159 | kube-node-lease Active 3h5m 160 | flux-system Active 3h1m 161 | nginx Active 164m 162 | dev-flux-system Active 18m 163 | dev-kaizentm Active 16m 164 | dev-redis Active 16m 165 | dev-yakuza Active 16m 166 | ``` 167 | 168 | ### Add tenant'a application 169 | To add tenant's application to an environment switch to the environment branch (e.g. dev) and perform the following: 170 | - Execute the following command 171 | ``` 172 | ./utils/add-app.sh TENANT_NAME APP_NAME 173 | ``` 174 | This will create corresponding subfolders for each cluster in "tenants" folder. 175 | - Commit and push changes created by add-tenant.sh 176 | - Check that application components have been installed on the environment clusters 177 | 178 | 179 | ### Init an environment 180 | To initialize a new environment create a new branch from an existing environment (e.g. dev) 181 | for example 182 | ``` 183 | git checkout -b qa 184 | ``` 185 | and execute the following command: 186 | ``` 187 | ./utils/init-environment.sh qa 188 | ``` 189 | this will clean all clusters, infra and tenants subfolders and leave only initial files. 190 | 191 | 192 | ### Resources 193 | - [Multi-Tenancy Strategies](https://github.com/fluxcd/flux2/discussions/263) 194 | - [Flux V2 Multi-Tenancy](https://github.com/fluxcd/flux2-multi-tenancy) 195 | - [Flux v2 Kustomize-Helm example](https://github.com/fluxcd/flux2-kustomize-helm-example) 196 | - [Multicluster environments discussion](https://github.com/fluxcd/flux2/discussions/766) 197 | 198 | 199 | ## Contributing 200 | 201 | This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit 202 | 203 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. -------------------------------------------------------------------------------- /updates: -------------------------------------------------------------------------------- 1 | - concept of multi-cluster environments (vs one cluster per environment) 2 | - environments are separated with branches and clusters are separated with folders 3 | - central place in the repo for flux-system 4 | - separation of common infra vs env-specific infra 5 | - multiple apps per tenant 6 | - scripts to add cluster/tenant/app/environment -------------------------------------------------------------------------------- /utils/add-cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) Microsoft Corporation. 4 | # Licensed under the MIT License. 5 | 6 | # Usage: 7 | # 8 | # export GITHUB_TOKEN= 9 | # export GITHUB_USER= 10 | # export GITHUB_REPO= 11 | # 12 | # add-cluster.sh CLUSTER_NAME 13 | 14 | CLUSTER_NAME=$1 15 | 16 | mkdir -p ./clusters/$CLUSTER_NAME 17 | cp ./utils/templates/clusters/infra.yaml ./clusters/$CLUSTER_NAME/infra.yaml 18 | sed -i 's/{CLUSTER_NAME}/'$CLUSTER_NAME'/g' ./clusters/$CLUSTER_NAME/infra.yaml 19 | 20 | mkdir -p ./infra/$CLUSTER_NAME 21 | cp ./utils/templates/infra/kustomization.yaml ./infra/$CLUSTER_NAME/kustomization.yaml 22 | 23 | 24 | flux bootstrap github \ 25 | --owner=${GITHUB_USER} \ 26 | --repository=${GITHUB_REPO} \ 27 | --branch=main \ 28 | --path=clusters/base 29 | 30 | kubectl apply -f clusters/$CLUSTER_NAME/infra.yaml 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /utils/attach-acr.sh: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Corporation. 2 | # Licensed under the MIT License. 3 | 4 | ACR_NAME=gitopsflowacr.azurecr.io 5 | ACR_UNAME=$(az acr credential show -n $ACR_NAME --query="username" -o tsv) 6 | ACR_PASSWD=$(az acr credential show -n $ACR_NAME --query="passwords[0].value" -o tsv) 7 | 8 | 9 | kubectl create secret docker-registry acr-secret \ 10 | --docker-server=$ACR_NAME \ 11 | --docker-username=$ACR_UNAME \ 12 | --docker-password=$ACR_PASSWD \ 13 | --docker-email=ignorethis@email.com \ 14 | --namespace dev-kaizentm 15 | 16 | -------------------------------------------------------------------------------- /utils/remove-cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) Microsoft Corporation. 4 | # Licensed under the MIT License. 5 | 6 | # Usage: 7 | # 8 | # remove-cluster.sh CLUSTER_NAME 9 | 10 | CLUSTER_NAME=$1 11 | 12 | rm -r ./clusters/$CLUSTER_NAME 13 | rm -r ./infra/$CLUSTER_NAME 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /utils/templates/clusters/infra.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta1 2 | kind: Kustomization 3 | metadata: 4 | name: infrastructure 5 | namespace: flux-system 6 | spec: 7 | interval: 10m0s 8 | sourceRef: 9 | kind: GitRepository 10 | name: flux-system 11 | namespace: flux-system 12 | path: ./infra/{CLUSTER_NAME} 13 | prune: true 14 | validation: client -------------------------------------------------------------------------------- /utils/templates/infra/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - ../base 5 | --------------------------------------------------------------------------------