├── .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 | 
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 | 
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 |
--------------------------------------------------------------------------------