├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── NOTICE.md ├── README.md ├── bin ├── README.md ├── add-app-cluster-overlay.sh ├── add-cluster-app.sh ├── add-cluster.sh ├── connect-to-cluster.sh ├── remove-cluster-app.sh ├── remove-cluster.sh └── update-cluster-app.sh ├── clean-up └── README.md ├── doc └── img │ └── architecture.png ├── initial-setup ├── README.md ├── auto │ └── cfn.yaml ├── config │ ├── cloud9-role-permission-policy-template.json │ ├── crossplane-role-permission-policy-template.json │ ├── crossplane-role-trust-policy-template.json │ └── mgmt-cluster-eksctl.yaml ├── doc │ └── repos │ │ ├── AWSCodeCommit-Bootstrap.md │ │ ├── AWSCodeCommit.md │ │ ├── GitHub-Bootstrap.md │ │ ├── GitHub-PAT.png │ │ └── GitHub.md ├── img │ ├── c9-modify-role.png │ ├── c9instancerole.png │ ├── cloud9-role.png │ ├── iam-create-policy-json.png │ ├── iam-create-policy.png │ └── iam-create-role.png └── secrets-template │ └── git-credentials.yaml ├── repos ├── apps-manifests │ ├── product-catalog-api-manifests │ │ ├── v1 │ │ │ └── kubernetes │ │ │ │ ├── base │ │ │ │ ├── deployment.yaml │ │ │ │ ├── kustomization.yaml │ │ │ │ └── service.yaml │ │ │ │ └── overlays │ │ │ │ ├── prod │ │ │ │ ├── deployment.yaml │ │ │ │ └── kustomization.yaml │ │ │ │ └── staging │ │ │ │ ├── deployment.yaml │ │ │ │ └── kustomization.yaml │ │ └── v2-staging │ │ │ └── kubernetes │ │ │ └── overlays │ │ │ └── staging │ │ │ ├── deployment.yaml │ │ │ ├── infra.yaml │ │ │ └── kustomization.yaml │ └── product-catalog-fe-manifests │ │ └── kubernetes │ │ ├── base │ │ ├── deployment.yaml │ │ ├── kustomization.yaml │ │ └── service.yaml │ │ └── overlays │ │ ├── prod │ │ ├── deployment.yaml │ │ └── kustomization.yaml │ │ └── staging │ │ ├── deployment.yaml │ │ └── kustomization.yaml ├── apps │ ├── .DS_Store │ ├── product-catalog-api │ │ ├── .gitignore │ │ ├── v1 │ │ │ ├── .dockerignore │ │ │ ├── Dockerfile │ │ │ ├── app.py │ │ │ ├── bootstrap.sh │ │ │ └── requirements.txt │ │ └── v2 │ │ │ ├── .dockerignore │ │ │ ├── Dockerfile │ │ │ ├── app.py │ │ │ ├── bootstrap.sh │ │ │ └── requirements.txt │ └── product-catalog-fe │ │ ├── .dockerignore │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── index.html │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── public │ │ └── .gitkeep │ │ ├── server.js │ │ └── views │ │ └── index.ejs ├── gitops-system │ ├── .gitignore │ ├── README.md │ ├── clusters-config │ │ ├── kustomization.yaml │ │ └── template │ │ │ ├── crossplane-iam.yaml │ │ │ ├── def │ │ │ ├── eks-cluster.yaml │ │ │ └── kustomization.yaml │ │ │ ├── eks-cluster.yaml │ │ │ ├── external-secrets-config.yaml │ │ │ ├── external-secrets-iam.yaml │ │ │ ├── external-secrets.yaml │ │ │ ├── flux.yaml │ │ │ ├── kustomization.yaml │ │ │ ├── sealed-secrets.yaml │ │ │ ├── secrets.yaml │ │ │ └── secrets │ │ │ ├── git-secret.yaml │ │ │ ├── kustomization.yaml │ │ │ └── namespace.yaml │ ├── clusters │ │ ├── mgmt │ │ │ ├── clusters-config.yaml │ │ │ ├── crossplane-eks-composition.yaml │ │ │ ├── crossplane.yaml │ │ │ ├── flux-system │ │ │ │ ├── gotk-components.yaml │ │ │ │ ├── gotk-sync.yaml │ │ │ │ └── kustomization.yaml │ │ │ ├── karpenter-config.yaml │ │ │ ├── karpenter-iam.yaml │ │ │ ├── karpenter.yaml │ │ │ └── kustomization.yaml │ │ └── template │ │ │ ├── aws-auth.yaml │ │ │ ├── aws-ebs-csi-iam.yaml │ │ │ ├── aws-ebs-csi.yaml │ │ │ ├── aws-load-balancer-controller-iam.yaml │ │ │ ├── aws-load-balancer-controller.yaml │ │ │ ├── crossplane.yaml │ │ │ ├── flux-system │ │ │ ├── gotk-components.yaml │ │ │ ├── gotk-sync.yaml │ │ │ └── kustomization.yaml │ │ │ ├── karpenter-config.yaml │ │ │ ├── karpenter-iam.yaml │ │ │ ├── karpenter.yaml │ │ │ ├── kubecost.yaml │ │ │ ├── kustomization.yaml │ │ │ └── workloads.yaml │ ├── tools-config │ │ ├── aws-auth │ │ │ ├── aws-auth-cm.yaml │ │ │ ├── kustomization.yaml │ │ │ ├── role-binding.yaml │ │ │ └── role.yaml │ │ ├── aws-ebs-csi-iam │ │ │ ├── kustomization.yaml │ │ │ ├── role.yaml │ │ │ └── sa.yaml │ │ ├── aws-load-balancer-controller-iam │ │ │ ├── kustomization.yaml │ │ │ ├── policy.yaml │ │ │ ├── role.yaml │ │ │ └── sa.yaml │ │ ├── crossplane-eks-composition │ │ │ ├── compositeresourcedefinition.yaml │ │ │ ├── composition.yaml │ │ │ ├── kustomization.yaml │ │ │ └── roles.yaml │ │ ├── crossplane-iam │ │ │ └── crossplane-iam.yaml │ │ ├── external-secrets-iam │ │ │ └── external-secrets-iam.yaml │ │ ├── external-secrets │ │ │ └── sealed-secrets-key.yaml │ │ ├── karpenter-config │ │ │ ├── kustomization.yaml │ │ │ ├── node-pool.yaml │ │ │ └── role.yaml │ │ └── karpenter-iam │ │ │ ├── kustomization.yaml │ │ │ ├── policy.yaml │ │ │ ├── role.yaml │ │ │ └── sa.yaml │ ├── tools │ │ ├── aws-ebs-csi │ │ │ ├── aws-ebs-csi-release.yaml │ │ │ ├── aws-ebs-csi-repo.yaml │ │ │ └── kustomization.yaml │ │ ├── aws-load-balancer-controller │ │ │ ├── aws-lb-controller-release.yaml │ │ │ ├── aws-lb-controller-repo.yaml │ │ │ └── kustomization.yaml │ │ ├── crossplane │ │ │ ├── crossplane-aws-provider-config.yaml │ │ │ ├── crossplane-aws-provider-config │ │ │ │ ├── aws-providerconfig.yaml │ │ │ │ └── kustomization.yaml │ │ │ ├── crossplane-aws-provider.yaml │ │ │ ├── crossplane-aws-provider │ │ │ │ ├── aws-provider.yaml │ │ │ │ └── kustomization.yaml │ │ │ ├── crossplane-core.yaml │ │ │ ├── crossplane-core │ │ │ │ ├── crossplane-release.yaml │ │ │ │ ├── crossplane-repository.yaml │ │ │ │ ├── crossplane-system-namespace.yaml │ │ │ │ └── kustomization.yaml │ │ │ ├── crossplane-k8s-provider-config.yaml │ │ │ ├── crossplane-k8s-provider-config │ │ │ │ ├── k8s-providerconfig.yaml │ │ │ │ └── kustomization.yaml │ │ │ ├── crossplane-k8s-provider.yaml │ │ │ ├── crossplane-k8s-provider │ │ │ │ ├── k8s-provider.yaml │ │ │ │ └── kustomization.yaml │ │ │ └── kustomization.yaml │ │ ├── external-secrets │ │ │ ├── external-secrets-release.yaml │ │ │ ├── external-secrets-repository.yaml │ │ │ └── kustomization.yaml │ │ ├── karpenter │ │ │ ├── karpenter-release.yaml │ │ │ ├── karpenter-repo.yaml │ │ │ └── kustomization.yaml │ │ ├── kubecost │ │ │ ├── kubecost-release.yaml │ │ │ ├── kubecost-repository.yaml │ │ │ └── kustomization.yaml │ │ └── sealed-secrets │ │ │ ├── kustomization.yaml │ │ │ ├── sealed-secrets-release.yaml │ │ │ └── sealed-secrets-repository.yaml │ └── workloads │ │ └── template │ │ ├── flux-kustomization.yaml │ │ ├── git-repo.yaml │ │ ├── git-secret.yaml │ │ └── kustomization.yaml └── gitops-workloads │ └── template │ ├── app-template │ ├── app-iam.yaml │ ├── app-sa.yaml │ ├── flux-kustomization.yaml │ ├── git-repo.yaml │ ├── git-secret.yaml │ ├── kustomization.yaml │ ├── ns.yaml │ ├── role-binding.yaml │ ├── role.yaml │ └── sa.yaml │ └── kustomization.yaml ├── resources └── reinvent-2022-slides.pdf └── scenarios.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .project 3 | .vscode 4 | wl-kube.conf -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /bin/README.md: -------------------------------------------------------------------------------- 1 | # Multi-cluster GitOps Scripts 2 | 3 | Note: these scripts operate on local repos and do not commit changes or push to remotes. 4 | Commits and pushes must be done separately. 5 | 6 | ## Workload cluster management 7 | 8 | ### add-cluster.sh 9 | 10 | Usage: 11 | ``` 12 | add-cluster.sh 13 | ``` 14 | 15 | Updates the local repo for `gitops-system` to add a new workload cluster. 16 | 17 | This is achieved by copying the required template folders into new folders for the cluster to be added, and updating the cluster name. The `kustomization.yaml` file in `clusters-config` is also updated to add the new cluster. 18 | 19 | ### remove-cluster.sh 20 | 21 | Usage: 22 | ``` 23 | remove-cluster.sh 24 | ``` 25 | 26 | This removes the specified cluster from `cluster-configs/kustomization.yaml`, which triggers crossplane to remove the cluster. 27 | 28 | It also removes all cluster configuration files from the local 29 | repos for `gitops-system` and `gitops-workloads`. 30 | 31 | ## Application management 32 | 33 | ### add-cluster-app.sh 34 | 35 | Usage: 36 | ``` 37 | add-cluster-app.sh 38 | 39 | 40 | 41 | 42 | 43 | 44 | ``` 45 | 46 | Adds the application `app-name` to the cluster `cluster-name`, using the following steps: 47 | - creates a new folder for the app under the correct workloads cluster folder and copies the app template 48 | - updates the folder content with the correct cluster name and app name 49 | - creates a sealed secret `gitops-secret.yaml` using the supplied template, keys, and known_hosts string 50 | - updates `kustomization.yaml` in the workloads cluster folder. 51 | 52 | It is assumed that a repo called `app-name-manifests` exists. 53 | 54 | ### remove-cluster-app.sh 55 | 56 | ``` 57 | remove-cluster-app.sh 58 | ``` 59 | 60 | Removes the application from `kustomization.yaml` and deletes the application folder from the workloads cluster folder. 61 | 62 | ### add-app-cluster-overlay 63 | 64 | Usage: 65 | ``` 66 | add-app-cluster-overlay cluster_name 67 | ``` 68 | 69 | 70 | ## Example sequence 71 | 72 | Create a `commercial-staging` cluster: 73 | ``` 74 | add-cluster.sh ./gitops-system commercial-staging 75 | ``` 76 | 77 | Commit and push: 78 | ``` 79 | cd gitops-system 80 | git add . 81 | git commit -m "Added cluster" 82 | git push 83 | ``` 84 | 85 | Create an application manifests repo: 86 | ``` 87 | cd ~/environment 88 | gh repo create --private --clone product-catalog-fe-manifests 89 | cp -r multi-cluster-gitops/repos/apps-manifests/product-catalog-fe-manifests/* product-catalog-fe-manifests/ 90 | cd product-catalog-fe-manifests 91 | git add . 92 | git commit -m "baseline version" 93 | git branch -M main 94 | git push --set-upstream origin main 95 | ``` 96 | 97 | Add the app `product-catalog-fe` to the `commercial-staging` cluster: 98 | ``` 99 | add-cluster-app.sh \ 100 | ./gitops-workloads \ 101 | commercial-staging product-catalog-fe \ 102 | multi-cluster-gitops/initial-setup/secrets-template/git-credentials.yaml \ 103 | ~/.ssh/gitops ~/.ssh/gitops.pub \ 104 | "github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=" \ 105 | ./sealed-secrets-keypair-public.pem 106 | ``` 107 | 108 | Commit and push: 109 | ``` 110 | cd gitops-workloads 111 | git add . 112 | git commit -m "Added pc-fe to staging" 113 | git push 114 | ``` -------------------------------------------------------------------------------- /bin/add-app-cluster-overlay.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # $1 = location of app manifests local repo 3 | # $2 = cluster name 4 | # $3 = app name 5 | # $4 = name suffix 6 | 7 | app_manifests=$(realpath "$1") 8 | cluster_name=$2 9 | app_name=$3 10 | name_suffix=$4 11 | 12 | mkdir $app_manifests/kubernetes/overlays/$cluster_name 13 | 14 | cat <$app_manifests/kubernetes/overlays/$cluster_name/kustomization.yaml 15 | apiVersion: kustomize.config.k8s.io/v1beta1 16 | kind: Kustomization 17 | resources: 18 | - ../../base 19 | namespace: $app_name 20 | nameSuffix: $name_suffix 21 | patchesStrategicMerge: 22 | EoF -------------------------------------------------------------------------------- /bin/add-cluster-app.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # $1 = location of gitops-workloads 3 | # $2 = cluster name 4 | # $3 = app name 5 | # $4 = overlay directory name 6 | # $5 = git branch name 7 | # $6 = location of git-credentials template file 8 | # $7 = private key file 9 | # $8 = public key 10 | # $9 = known hosts 11 | # $10 = Sealed secrets public key .pem file 12 | 13 | gitops_workloads=$(realpath "$1") 14 | cluster_name=$2 15 | app_name=$3 16 | overlay_dir_name=$4 17 | branch_name=$5 18 | git_creds_file=$(realpath "$6") 19 | private_key_file=$(realpath "$7") 20 | public_key_file=$(realpath "$8") 21 | known_hosts=$9 22 | pem_file=$(realpath "${10}") 23 | 24 | # check if the add is already added to the cluster 25 | if [ -d "$gitops_workloads/$cluster_name/$app_name" ] 26 | then 27 | echo "Error: The app $app_name is already added to the cluster $cluster_name" 28 | exit 1 29 | fi 30 | 31 | mkdir -p $gitops_workloads/$cluster_name/$app_name 32 | if [[ ! -f $gitops_workloads/$cluster_name/kustomization.yaml ]] 33 | then 34 | cp $gitops_workloads/template/kustomization.yaml $gitops_workloads/$cluster_name 35 | fi 36 | cp -R $gitops_workloads/template/app-template/* $gitops_workloads/$cluster_name/$app_name 37 | grep -RiIl 'cluster-name' $gitops_workloads/$cluster_name/$app_name | xargs sed -i "s/cluster-name/$cluster_name/g" 38 | grep -RiIl 'overlay-dir-name' $gitops_workloads/$cluster_name/$app_name | xargs sed -i "s/overlay-dir-name/$overlay_dir_name/g" 39 | grep -RiIl 'app-name' $gitops_workloads/$cluster_name/$app_name | xargs sed -i "s/app-name/$app_name/g" 40 | grep -RiIl 'branch-name' $gitops_workloads/$cluster_name/$app_name | xargs sed -i "s/branch-name/$branch_name/g" 41 | 42 | 43 | # Prep the sealed secret 44 | 45 | tmp_git_creds=$(mktemp /tmp/git-creds.yaml.XXXXXXXXX) 46 | cp $git_creds_file $tmp_git_creds 47 | APP_NAME=$app_name yq e '.metadata.name=strenv(APP_NAME)' -i $tmp_git_creds 48 | KEY=$(cat $private_key_file | base64 -w 0) yq -i '.data.identity = strenv(KEY)' $tmp_git_creds 49 | CERT=$(cat $public_key_file | base64 -w 0) yq -i '.data."identity.pub" = strenv(CERT)' $tmp_git_creds 50 | HOSTS=$(echo $known_hosts | base64 -w 0) yq -i '.data.known_hosts = strenv(HOSTS)' $tmp_git_creds 51 | kubeseal --cert $pem_file --format yaml <$tmp_git_creds >$gitops_workloads/$cluster_name/$app_name/git-secret.yaml 52 | rm $tmp_git_creds 53 | 54 | # Add to kustomization.yaml 55 | 56 | yq -i e ".resources += [\"$app_name\"]" $gitops_workloads/$cluster_name/kustomization.yaml -------------------------------------------------------------------------------- /bin/add-cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # $1 = location of gitops-system 3 | # $2 = cluster name 4 | 5 | gitops_system=$(realpath "$1") 6 | cluster_name=$2 7 | 8 | # check if the cluster is already added 9 | if [ -d "$gitops_system/clusters-config/$cluster_name" ] 10 | then 11 | echo "Error: The cluster $cluster_name already exists." 12 | exit 1 13 | fi 14 | 15 | # gitops-system clusters-config template 16 | 17 | mkdir -p $gitops_system/clusters-config/$cluster_name 18 | cp -R $gitops_system/clusters-config/template/* $gitops_system/clusters-config/$cluster_name 19 | grep -RiIl 'cluster-name' $gitops_system/clusters-config/$cluster_name | xargs sed -i "s/cluster-name/$cluster_name/g" 20 | 21 | # gitops-system clusters template 22 | 23 | mkdir -p $gitops_system/clusters/$cluster_name 24 | cp -R $gitops_system/clusters/template/* $gitops_system/clusters/$cluster_name 25 | grep -RiIl 'cluster-name' $gitops_system/clusters/$cluster_name | xargs sed -i "s/cluster-name/$cluster_name/g" 26 | 27 | # gitops-system workloads template 28 | 29 | mkdir -p $gitops_system/workloads/$cluster_name 30 | cp -R $gitops_system/workloads/template/* $gitops_system/workloads/$cluster_name 31 | grep -RiIl 'cluster-name' $gitops_system/workloads/$cluster_name | xargs sed -i "s/cluster-name/$cluster_name/g" 32 | 33 | # Add $cluster_name to clusters-config/kustomization.yaml file 34 | 35 | yq -i e ".resources += [\"$cluster_name\"]" $gitops_system/clusters-config/kustomization.yaml -------------------------------------------------------------------------------- /bin/connect-to-cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # $1 = cluster name 3 | 4 | # Creates kubeconfig file and sources KUBECONFIG environment variable 5 | # to connect to cluster. 6 | # 7 | # To use the script use the source command at the terminal to make sure 8 | # the KUBECONFIG environment variable is exported. 9 | # Example: source ~/environment/eks-multi-cluster-gitops/bin/connect-to-cluster.sh 10 | 11 | WORKLOAD_CLUSTER_NAME=$1 12 | KUBECONFIG_DEFAULT_DIR=~/.kube 13 | unset KUBECONFIG 14 | if [ ! -d $KUBECONFIG_DEFAULT_DIR ]; then 15 | echo "Directory $KUBECONFIG_DEFAULT_DIR does not exist" 16 | echo "Creating directory..." 17 | mkdir -p $KUBECONFIG_DEFAULT_DIR 18 | fi 19 | pushd $KUBECONFIG_DEFAULT_DIR 20 | echo "Generating kubeconfig file..." 21 | kubectl -n flux-system get secret $WORKLOAD_CLUSTER_NAME-eks-connection -n flux-system -o jsonpath="{.data.value}" | base64 -d > wl-kube.conf 22 | export KUBECONFIG=$KUBECONFIG_DEFAULT_DIR/wl-kube.conf 23 | kubectl config current-context 24 | popd -------------------------------------------------------------------------------- /bin/remove-cluster-app.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # $1 = location of gitops-workloads 3 | # $2 = cluster name 4 | # $3 = app_name 5 | 6 | 7 | gitops_workloads=$(realpath "$1") 8 | cluster_name=$2 9 | app_name=$3 10 | 11 | # Remove $cluster_name from clusters-config/kustomization.yaml file 12 | yq -i e "del ( .resources[] | select (. == \"$app_name\" ))" $gitops_workloads/$cluster_name/kustomization.yaml 13 | 14 | # Remove app folder from cluster folder 15 | 16 | rm -rf $gitops_workloads/$cluster_name/$app_name -------------------------------------------------------------------------------- /bin/remove-cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # $1 = location of gitops-system 3 | # $2 = location of gitops-workloads 4 | # $3 = cluster name 5 | 6 | gitops_system=$(realpath "$1") 7 | gitops_workloads=$(realpath "$2") 8 | cluster_name=$3 9 | 10 | # Remove $cluster_name from clusters-config/kustomization.yaml file 11 | yq -i e "del ( .resources[] | select (. == \"$cluster_name\" ))" $gitops_system/clusters-config/kustomization.yaml 12 | 13 | rm -rf $gitops_system/clusters-config/$cluster_name 14 | rm -rf $gitops_system/clusters/$cluster_name 15 | rm -rf $gitops_system/workloads/$cluster_name 16 | rm -rf $gitops_workloads/$cluster_name -------------------------------------------------------------------------------- /bin/update-cluster-app.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # $1 = location of gitops-workloads 3 | # $2 = cluster name 4 | # $3 = app name 5 | # $4 = git release tag 6 | 7 | gitops_workloads=$(realpath "$1") 8 | cluster_name=$2 9 | app_name=$3 10 | release_tag=$4 11 | 12 | yq -i e ".spec.ref.tag = \"$release_tag\"" $gitops_workloads/$cluster_name/$app_name/git-repo.yaml -------------------------------------------------------------------------------- /clean-up/README.md: -------------------------------------------------------------------------------- 1 | # Clean-up 2 | 1. Un-deploy the applications/microservices on the workload clusters by removing the resources listed in `gitops-workloads//kustomization.yaml` 3 | 2. Un-deploy the tools installed in the workload clusters by removing the resources listed in `gitops-system/clusters//kustomization.yaml`. Wait for the tools to be uninstalled before you proceed to the next step. 4 | 3. Un-deploy the workload clusters by removing the resources listed in `gitops-system/clusters-config/kustomization.yaml`. Wait for all workload clusters to be fully deleted (including corresponding VPC) before you proceed to the next step. 5 | 4. Un-deploy the tools installed in the management cluster by removing the resources listed in `gitops-system/clusters/mgmt/kustomization.yaml` (except `./flux-system`). Wait for the tools to be uninstalled before you proceed to the next step. 6 | 5. Un-deploy the management cluster. 7 | ``` 8 | eksctl delete cluster --name mgmt --region $AWS_REGION 9 | ``` 10 | Note that `eksctl delete cluster` does not delete the hosting VPC; please delete it manually. 11 | 6. Remove the GitHub repos or AWS CodeCommit repos you created. 12 | - For GitHub you can use: 13 | ``` 14 | gh repo delete --confirm product-catalog-api-manifests 15 | gh repo delete --confirm product-catalog-fe-manifests 16 | gh repo delete --confirm gitops-workloads 17 | gh repo delete --confirm gitops-system 18 | ``` 19 | - If you performed the initial setup using CloudFormation, you can skip this step - the AWS CodeCommit repos will be deleted as part of the CloudFormation stack deletion. 20 | 7. Remove the secret in Secrets Manager. 21 | ``` 22 | aws secretsmanager delete-secret --secret-id sealed-secrets --force-delete-without-recovery 23 | ``` 24 | 25 | 8. Remove the crossplane role 26 | ``` 27 | POLICY_ARN=$(aws iam list-attached-role-policies --role-name crossplane-role --query AttachedPolicies[0].PolicyArn --output text) 28 | aws iam detach-role-policy --role-name crossplane-role --policy-arn $POLICY_ARN 29 | aws iam delete-policy --policy-arn $POLICY_ARN 30 | aws iam delete-role --role-name crossplane-role 31 | ``` 32 | 33 | 9. Remove DynamoDB tables created by the `product-catalog-api` application. You can list tables 34 | starting with "product-" using: 35 | ``` 36 | aws dynamodb list-tables --query "TableNames[?starts_with(@, 'prod') == \`true\`]" 37 | ``` 38 | Then delete individual tables using: 39 | ``` 40 | aws dynamodb delete-table --table-name 41 | ``` 42 | 10. Delete the IAM user that was used to interact with the CodeCommit repos from the Cloud9 environment, and from the EKS clusters by the Flux source controller. Also, delete the associated IAM policy. Skip this step if you used CloudFormation to perform the initial setup. 43 | 44 | 11. If you used CloudFormation to perform the initial setup, delete the corresponding CloudFormation stack: 45 | ``` 46 | aws cloudformation delete-stack --stack-name gitops-initial-setup 47 | ``` 48 | -------------------------------------------------------------------------------- /doc/img/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/eks-multi-cluster-gitops/910fe7fd48015dfaf08b610f6acb3c2512d3b92c/doc/img/architecture.png -------------------------------------------------------------------------------- /initial-setup/config/cloud9-role-permission-policy-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Action": "ec2:*", 6 | "Effect": "Allow", 7 | "Resource": "*" 8 | }, 9 | { 10 | "Effect": "Allow", 11 | "Action": "elasticloadbalancing:*", 12 | "Resource": "*" 13 | }, 14 | { 15 | "Effect": "Allow", 16 | "Action": "cloudwatch:*", 17 | "Resource": "*" 18 | }, 19 | { 20 | "Effect": "Allow", 21 | "Action": "autoscaling:*", 22 | "Resource": "*" 23 | }, 24 | { 25 | "Effect": "Allow", 26 | "Action": "iam:CreateServiceLinkedRole", 27 | "Resource": "*", 28 | "Condition": { 29 | "StringEquals": { 30 | "iam:AWSServiceName": [ 31 | "autoscaling.amazonaws.com", 32 | "ec2scheduled.amazonaws.com", 33 | "elasticloadbalancing.amazonaws.com", 34 | "spot.amazonaws.com", 35 | "spotfleet.amazonaws.com", 36 | "transitgateway.amazonaws.com" 37 | ] 38 | } 39 | } 40 | }, 41 | { 42 | "Effect": "Allow", 43 | "Action": [ 44 | "cloudformation:*" 45 | ], 46 | "Resource": "*" 47 | }, 48 | { 49 | "Effect": "Allow", 50 | "Action": "eks:*", 51 | "Resource": "*" 52 | }, 53 | { 54 | "Action": [ 55 | "ssm:GetParameter", 56 | "ssm:GetParameters" 57 | ], 58 | "Resource": [ 59 | "arn:aws:ssm:*:${ACCOUNT_ID}:parameter/aws/*", 60 | "arn:aws:ssm:*::parameter/aws/*" 61 | ], 62 | "Effect": "Allow" 63 | }, 64 | { 65 | "Action": [ 66 | "kms:CreateGrant", 67 | "kms:DescribeKey" 68 | ], 69 | "Resource": "*", 70 | "Effect": "Allow" 71 | }, 72 | { 73 | "Action": [ 74 | "logs:PutRetentionPolicy" 75 | ], 76 | "Resource": "*", 77 | "Effect": "Allow" 78 | }, 79 | { 80 | "Sid": "Stmt1658116958078", 81 | "Action": [ 82 | "iam:AddRoleToInstanceProfile", 83 | "iam:AttachRolePolicy", 84 | "iam:AttachUserPolicy", 85 | "iam:CreateInstanceProfile", 86 | "iam:CreateOpenIDConnectProvider", 87 | "iam:CreatePolicy", 88 | "iam:CreatePolicyVersion", 89 | "iam:CreateRole", 90 | "iam:CreateServiceLinkedRole", 91 | "iam:CreateUser", 92 | "iam:DeleteInstanceProfile", 93 | "iam:DeleteOpenIDConnectProvider", 94 | "iam:DeletePolicy", 95 | "iam:DeletePolicyVersion", 96 | "iam:DeleteRole", 97 | "iam:DeleteRolePermissionsBoundary", 98 | "iam:DeleteRolePolicy", 99 | "iam:DetachRolePolicy", 100 | "iam:GetInstanceProfile", 101 | "iam:GetOpenIDConnectProvider", 102 | "iam:GetPolicy", 103 | "iam:GetPolicyVersion", 104 | "iam:GetRole", 105 | "iam:GetRolePolicy", 106 | "iam:GetUserPolicy", 107 | "iam:ListAttachedRolePolicies", 108 | "iam:ListInstanceProfiles", 109 | "iam:ListInstanceProfilesForRole", 110 | "iam:ListPolicies", 111 | "iam:ListPolicyTags", 112 | "iam:ListPolicyVersions", 113 | "iam:ListRolePolicies", 114 | "iam:ListRoleTags", 115 | "iam:PassRole", 116 | "iam:PutRolePermissionsBoundary", 117 | "iam:PutRolePolicy", 118 | "iam:RemoveRoleFromInstanceProfile", 119 | "iam:TagOpenIDConnectProvider", 120 | "iam:TagPolicy", 121 | "iam:TagRole", 122 | "iam:UpdateAssumeRolePolicy", 123 | "iam:UploadSSHPublicKey", 124 | "iam:UntagPolicy", 125 | "iam:UntagRole", 126 | "iam:UpdateRole", 127 | "iam:UpdateRoleDescription" 128 | ], 129 | "Effect": "Allow", 130 | "Resource": "*" 131 | }, 132 | { 133 | "Effect": "Allow", 134 | "Action": [ 135 | "secretsmanager:CreateSecret" 136 | ], 137 | "Resource": "*" 138 | }, 139 | { 140 | "Effect": "Allow", 141 | "Action": [ 142 | "secretsmanager:PutSecretValue", 143 | "secretsmanager:UpdateSecret", 144 | "secretsmanager:DeleteSecret" 145 | ], 146 | "Resource": "arn:aws:secretsmanager:${AWS_REGION}:${ACCOUNT_ID}:secret:sealed-secrets*" 147 | }, 148 | { 149 | "Effect": "Allow", 150 | "Action": "sts:GetCallerIdentity", 151 | "Resource": "*" 152 | }, 153 | { 154 | "Effect": "Allow", 155 | "Action": [ 156 | "codecommit:CreateRepository" 157 | ], 158 | "Resource": "*" 159 | }, 160 | { 161 | "Effect": "Allow", 162 | "Action": [ 163 | "dynamodb:ListTables" 164 | ], 165 | "Resource": "*" 166 | }, 167 | { 168 | "Effect": "Allow", 169 | "Action": [ 170 | "dynamodb:DeleteTable" 171 | ], 172 | "Resource": "arn:aws:dynamodb:${AWS_REGION}:${ACCOUNT_ID}:table/products-*" 173 | } 174 | ] 175 | } -------------------------------------------------------------------------------- /initial-setup/config/crossplane-role-permission-policy-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Action": "ec2:*", 6 | "Effect": "Allow", 7 | "Resource": "*" 8 | }, 9 | { 10 | "Effect": "Allow", 11 | "Action": "elasticloadbalancing:*", 12 | "Resource": "*" 13 | }, 14 | { 15 | "Effect": "Allow", 16 | "Action": "cloudwatch:*", 17 | "Resource": "*" 18 | }, 19 | { 20 | "Effect": "Allow", 21 | "Action": "autoscaling:*", 22 | "Resource": "*" 23 | }, 24 | { 25 | "Effect": "Allow", 26 | "Action": "iam:CreateServiceLinkedRole", 27 | "Resource": "*", 28 | "Condition": { 29 | "StringEquals": { 30 | "iam:AWSServiceName": [ 31 | "autoscaling.amazonaws.com", 32 | "ec2scheduled.amazonaws.com", 33 | "elasticloadbalancing.amazonaws.com", 34 | "spot.amazonaws.com", 35 | "spotfleet.amazonaws.com", 36 | "transitgateway.amazonaws.com" 37 | ] 38 | } 39 | } 40 | }, 41 | { 42 | "Effect": "Allow", 43 | "Action": "eks:*", 44 | "Resource": "*" 45 | }, 46 | { 47 | "Action": [ 48 | "ssm:GetParameter", 49 | "ssm:GetParameters" 50 | ], 51 | "Resource": [ 52 | "arn:aws:ssm:*:${ACCOUNT_ID}:parameter/aws/*", 53 | "arn:aws:ssm:*::parameter/aws/*" 54 | ], 55 | "Effect": "Allow" 56 | }, 57 | { 58 | "Action": [ 59 | "kms:CreateGrant", 60 | "kms:DescribeKey" 61 | ], 62 | "Resource": "*", 63 | "Effect": "Allow" 64 | }, 65 | { 66 | "Action": [ 67 | "logs:PutRetentionPolicy" 68 | ], 69 | "Resource": "*", 70 | "Effect": "Allow" 71 | }, 72 | { 73 | "Sid": "Stmt1658116958078", 74 | "Action": [ 75 | "iam:AddRoleToInstanceProfile", 76 | "iam:AttachRolePolicy", 77 | "iam:CreateInstanceProfile", 78 | "iam:CreateOpenIDConnectProvider", 79 | "iam:CreatePolicy", 80 | "iam:CreatePolicyVersion", 81 | "iam:CreateRole", 82 | "iam:CreateServiceLinkedRole", 83 | "iam:DeleteInstanceProfile", 84 | "iam:DeleteOpenIDConnectProvider", 85 | "iam:DeletePolicy", 86 | "iam:DeletePolicyVersion", 87 | "iam:DeleteRole", 88 | "iam:DeleteRolePermissionsBoundary", 89 | "iam:DeleteRolePolicy", 90 | "iam:DetachRolePolicy", 91 | "iam:GetInstanceProfile", 92 | "iam:GetOpenIDConnectProvider", 93 | "iam:GetPolicy", 94 | "iam:GetPolicyVersion", 95 | "iam:GetRole", 96 | "iam:GetRolePolicy", 97 | "iam:GetUserPolicy", 98 | "iam:ListAttachedRolePolicies", 99 | "iam:ListInstanceProfiles", 100 | "iam:ListInstanceProfilesForRole", 101 | "iam:ListPolicies", 102 | "iam:ListPolicyTags", 103 | "iam:ListPolicyVersions", 104 | "iam:ListRolePolicies", 105 | "iam:ListRoleTags", 106 | "iam:PassRole", 107 | "iam:PutRolePermissionsBoundary", 108 | "iam:PutRolePolicy", 109 | "iam:RemoveRoleFromInstanceProfile", 110 | "iam:TagOpenIDConnectProvider", 111 | "iam:TagPolicy", 112 | "iam:TagRole", 113 | "iam:UpdateAssumeRolePolicy", 114 | "iam:UntagPolicy", 115 | "iam:UntagRole", 116 | "iam:UpdateRole", 117 | "iam:UpdateRoleDescription", 118 | "iam:ListOpenIDConnectProviders", 119 | "iam:ListOpenIDConnectProviderTags", 120 | "iam:TagOpenIDConnectProvider", 121 | "iam:UntagOpenIDConnectProvider" 122 | ], 123 | "Effect": "Allow", 124 | "Resource": "*" 125 | } 126 | ] 127 | } -------------------------------------------------------------------------------- /initial-setup/config/crossplane-role-trust-policy-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Principal": { 7 | "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}" 8 | }, 9 | "Action": "sts:AssumeRoleWithWebIdentity", 10 | "Condition": { 11 | "StringEquals": { 12 | "${OIDC_PROVIDER}:aud": "sts.amazonaws.com" 13 | }, 14 | "StringLike": { 15 | "${OIDC_PROVIDER}:sub": "system:serviceaccount:crossplane-system:provider-aws-*" 16 | } 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /initial-setup/config/mgmt-cluster-eksctl.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: eksctl.io/v1alpha5 3 | kind: ClusterConfig 4 | 5 | metadata: 6 | name: mgmt 7 | region: AWS_REGION 8 | version: "1.29" 9 | 10 | iam: 11 | withOIDC: true 12 | 13 | vpc: 14 | nat: 15 | gateway: Single 16 | 17 | managedNodeGroups: 18 | - name: nodegroup 19 | privateNetworking: true 20 | iam: 21 | attachPolicyARNs: 22 | - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy 23 | - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy 24 | - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly 25 | - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore 26 | desiredCapacity: 3 27 | instanceType: m5.large 28 | -------------------------------------------------------------------------------- /initial-setup/doc/repos/AWSCodeCommit-Bootstrap.md: -------------------------------------------------------------------------------- 1 | 2 | ## Bootstrap the management cluster (using AWS CodeCommit repos) 3 | 4 | 1. Bootstrap Flux on the management cluster with the `mgmt` cluster config path. The bootstrap process is customized to support AWS CodeCommit integration. 5 | 6 | ```bash 7 | export CLUSTER_NAME=mgmt 8 | 9 | cd ~/environment/gitops-system 10 | 11 | kubectl apply -f ./clusters/${CLUSTER_NAME}/flux-system/gotk-components.yaml 12 | 13 | kubectl create secret generic flux-system -n flux-system \ 14 | --from-file=identity=${HOME}/.ssh/gitops \ 15 | --from-file=identity.pub=${HOME}/.ssh/gitops.pub \ 16 | --from-file=known_hosts=${HOME}/.ssh/codecommit_known_hosts 17 | 18 | kubectl apply -f ./clusters/${CLUSTER_NAME}/flux-system/gotk-sync.yaml 19 | ``` 20 | 21 | 3. Track the progress of the Flux 22 | deployments using the Flux CLI. This may take >30 minutes due to exponential 23 | backoff, however this is only a one-time process. 24 | ```bash 25 | flux get all 26 | ``` 27 | You can watch this to see once it's ready by using: 28 | ```bash 29 | watch -n 30 -d flux get all 30 | ``` -------------------------------------------------------------------------------- /initial-setup/doc/repos/AWSCodeCommit.md: -------------------------------------------------------------------------------- 1 | ## Create and prepare the Git repositories 2 | ### Create Git SSH keys 3 | 1. Create a new IAM user that will be used to interact with the CodeCommit repos from the Cloud9 environment, and from the EKS clusters by the Flux source controller. While the same IAM user is used for all the 4 | repositories in these instructions, the structure supports using 5 | different users for different repos. 6 | 7 | ```bash 8 | cd ~/environment 9 | aws iam create-user \ 10 | --user-name gitops 11 | 12 | cat >gitops-policy.json <" -f gitops 47 | ``` 48 | (Replace the `` with your company domain). 49 | 50 | 3. Add the public part of the keys generated above to the respective IAM users in your AWS account to 51 | grant access. Note down the SSH key ids printed in the terminal. 52 | 53 | ```bash 54 | cd ~/.ssh 55 | SSH_KEY_ID_GITOPS=$(aws iam upload-ssh-public-key \ 56 | --user-name gitops \ 57 | --ssh-public-key-body file://gitops.pub \ 58 | --query 'SSHPublicKey.SSHPublicKeyId' \ 59 | --output text) 60 | echo "SSH key id of user gitops: ${SSH_KEY_ID_GITOPS}" 61 | ``` 62 | 63 | 4. Create/edit `config` in `~/.ssh` to use the SSH key in `gitops` for 64 | the Git commands executed on the Cloud9 environment. 65 | ```bash 66 | cat >~/.ssh/config < ~/.ssh/codecommit_known_hosts 2>/dev/null 114 | ``` 115 | 116 | 2. Generate a Kubernetes secret file with git ssh credentials for gitops user. 117 | 118 | ```bash 119 | cd ~/environment 120 | kubectl create secret generic flux-system -n flux-system \ 121 | --from-file=identity=${HOME}/.ssh/gitops \ 122 | --from-file=identity.pub=${HOME}/.ssh/gitops.pub \ 123 | --from-file=known_hosts=${HOME}/.ssh/codecommit_known_hosts \ 124 | --dry-run=client \ 125 | --output=yaml \ 126 | >git-creds-system.yaml 127 | ``` 128 | 129 | 130 | When done, continue with the setup process [here](../../README.md#populate-and-update-the-repositories) 131 | -------------------------------------------------------------------------------- /initial-setup/doc/repos/GitHub-Bootstrap.md: -------------------------------------------------------------------------------- 1 | ## Bootstrap the management cluster (using GitHub repos) 2 | 3 | 1. Create a GitHub personal access token. Using the GitHub console, navigate to **Settings->Developer Settings->Personal Access Tokens**. 4 | Use the **Generate new token** button to create a new token, selecting the `repo` scopes (these are 5 | the only ones required for the token used by Flux). 6 | 7 | ![](GitHub-PAT.png) 8 | 9 | 2. Export GitHub access token and username to be used by Flux bootstrap command. 10 | ```bash 11 | export CLUSTER_NAME=mgmt 12 | export GITHUB_TOKEN=XXXX 13 | export GITHUB_USER= 14 | ``` 15 | 16 | 3. Bootstrap Flux on the management cluster with the `mgmt` cluster config path. 17 | ```bash 18 | flux bootstrap github \ 19 | --components-extra=image-reflector-controller,image-automation-controller \ 20 | --owner=$GITHUB_USER \ 21 | --namespace=flux-system \ 22 | --repository=gitops-system \ 23 | --branch=main \ 24 | --path=clusters/$CLUSTER_NAME \ 25 | --personal 26 | ``` 27 | 28 | 4. Track the progress of the Flux 29 | deployments using the Flux CLI. This may take >30 minutes due to exponential 30 | backoff, however this is only a one-time process. 31 | ```bash 32 | flux get all 33 | ``` 34 | You can watch this to see once it's ready by using: 35 | ```bash 36 | watch -n 30 -d flux get all 37 | ``` 38 | 39 | 40 | Once done, continue to follow setup instructions [here](../../README.md#connect-to-cluster). 41 | -------------------------------------------------------------------------------- /initial-setup/doc/repos/GitHub-PAT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/eks-multi-cluster-gitops/910fe7fd48015dfaf08b610f6acb3c2512d3b92c/initial-setup/doc/repos/GitHub-PAT.png -------------------------------------------------------------------------------- /initial-setup/doc/repos/GitHub.md: -------------------------------------------------------------------------------- 1 | ## Create and prepare the Git repositories 2 | 3 | ### Create SSH key for Cloud9 access to GitHub repo 4 | 5 | 1. Create the SSH key that will be used for interacting with the repos in your 6 | GitHub account from the Cloud9 environment. 7 | ```bash 8 | cd ~/.ssh 9 | ssh-keygen -t ed25519 -C "" -f gitops-cloud9 10 | ``` 11 | (Replace `` with your email address). 12 | This generates two files: `gitops-cloud9` contains a private key, and `gitops-cloud9.pub` contains the corresponding public key. 13 | 14 | 15 | 2. Create/edit `config` in `~/.ssh` to use the SSH key in `gitops-cloud9` for 16 | the Git commands executed in the Cloud9 environment. 17 | ```bash 18 | cat << EOF > ~/.ssh/config 19 | Host github.com 20 | AddKeysToAgent yes 21 | IdentityFile ~/.ssh/gitops-cloud9 22 | EOF 23 | ``` 24 | 25 | 3. Log in with the Github CLI using: 26 | ```bash 27 | gh auth login -p ssh -h github.com 28 | ``` 29 | 30 | - In response to **Upload your SSH public key to your GitHub account?**, choose **/home/ubuntu/.ssh/gitops-cloud9.pub**. 31 | - For **Title for your SSH key**, enter **gitops-cloud9**. 32 | - In response to **How would you like to authenticate GitHub CLI?**, choose **Login with a web browser**. 33 | - Note the one-time code. 34 | - Pressing Enter will result in an error message as you cannot open a browser from your Cloud9 environment. 35 | - Use a separate tab on your browser to navigate to https://github.com/login/device and enter the code. 36 | - Choose **Authorize github**. 37 | - Return to your Cloud9 terminal to continue. You are now logged in to your GitHub account from Cloud9. You can test this by running commands like `gh auth status` and `gh repo list`. 38 | 39 | ### Create SSH key for Flux access to GitHub repo 40 | 41 | 1. Create the SSH key that will be used by Flux for interacting 42 | with the repos in your GitHub account. Ensure that you do not use a 43 | passphrase to protect the key, as this will prevent Flux from being able to use 44 | the key. 45 | 46 | **Note:** In order to keep this walkthrough as short as possible, the same SSH 47 | key is used for all GitHub repositories. However, the architecture does support 48 | use of different SSH keys for different repos. 49 | ```bash 50 | cd ~/.ssh 51 | ssh-keygen -t ed25519 -C "gitops@" -f gitops 52 | ``` 53 | (Replace the `` with your company domain or a fictitious domain). 54 | This generates two files: `gitops` contains a private key, and `gitops.pub` contains the corresponding public key. 55 | 56 | 2. Copy the contents of the public key file `gitops.pub` generated above to your GitHub account as follows: 57 | ``` 58 | gh ssh-key add -t gitops ~/.ssh/gitops.pub 59 | ``` 60 | 61 | 3. Verify that the key has been added: 62 | ``` 63 | gh ssh-key list 64 | ``` 65 | 66 | 67 | ### Create GitHub repos 68 | 69 | Create empty repos `gitops-system` and `gitops-workloads` in your GitHub account, and clone them 70 | into the Cloud9 environment. 71 | ``` 72 | cd ~/environment 73 | git config --global init.defaultBranch main 74 | gh repo create --private --clone gitops-system 75 | gh repo create --private --clone gitops-workloads 76 | ``` 77 | 78 | ### Set the `REPO_PREFIX` variable to point at your GitHub account 79 | 80 | 1. Set the variable `GITHUB_ACCOUNT` to your GitHub user name. 81 | ``` 82 | GITHUB_ACCOUNT= 83 | ``` 84 | 2. Set the variable `REPO_PREFIX` as follows: 85 | ``` 86 | export REPO_PREFIX="ssh:\/\/git@github.com\/$GITHUB_ACCOUNT" 87 | ``` 88 | 89 | 90 | ### Create a `Secret` resource that contains the Git Credentials for `gitops-system` 91 | 92 | 1. Copy the content of 93 | `multi-cluster-gitops/initial-setup/secrets-template/git-credentials.yaml` to 94 | `~/environment/git-creds-system.yaml`. 95 | ``` 96 | cd ~/environment 97 | cp multi-cluster-gitops/initial-setup/secrets-template/git-credentials.yaml git-creds-system.yaml 98 | ``` 99 | 100 | 2. Replace the value for the field `identity` with the base64 101 | encoding of the content in `~/.ssh/gitops` 102 | ```bash 103 | KEY=$(cat ~/.ssh/gitops | base64 -w 0) yq -i '.data.identity = strenv(KEY)' git-creds-system.yaml 104 | ``` 105 | 106 | 3. Replace the value for the field `identity.pub` with the base64 encoding of 107 | the content in `~/.ssh/gitops.pub`. 108 | ``` 109 | CERT=$(cat ~/.ssh/gitops.pub | base64 -w 0) yq -i '.data."identity.pub" = strenv(CERT)' git-creds-system.yaml 110 | ``` 111 | 112 | 4. Replace the value for the field `known_hosts` with the base64 encoding of the 113 | following: "github.com " + the value of the `ssh_keys` starting with 114 | `ecdsa-sha2-nistp256` returned from https://api.github.com/meta. 115 | 116 | ```bash 117 | HOST=$(echo "github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=" | base64 -w 0) yq -i '.data.known_hosts = strenv(HOST)' git-creds-system.yaml 118 | ``` 119 | 120 | When done, continue with the setup process [here](../../README.md#populate-and-update-the-repositories) 121 | -------------------------------------------------------------------------------- /initial-setup/img/c9-modify-role.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/eks-multi-cluster-gitops/910fe7fd48015dfaf08b610f6acb3c2512d3b92c/initial-setup/img/c9-modify-role.png -------------------------------------------------------------------------------- /initial-setup/img/c9instancerole.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/eks-multi-cluster-gitops/910fe7fd48015dfaf08b610f6acb3c2512d3b92c/initial-setup/img/c9instancerole.png -------------------------------------------------------------------------------- /initial-setup/img/cloud9-role.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/eks-multi-cluster-gitops/910fe7fd48015dfaf08b610f6acb3c2512d3b92c/initial-setup/img/cloud9-role.png -------------------------------------------------------------------------------- /initial-setup/img/iam-create-policy-json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/eks-multi-cluster-gitops/910fe7fd48015dfaf08b610f6acb3c2512d3b92c/initial-setup/img/iam-create-policy-json.png -------------------------------------------------------------------------------- /initial-setup/img/iam-create-policy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/eks-multi-cluster-gitops/910fe7fd48015dfaf08b610f6acb3c2512d3b92c/initial-setup/img/iam-create-policy.png -------------------------------------------------------------------------------- /initial-setup/img/iam-create-role.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/eks-multi-cluster-gitops/910fe7fd48015dfaf08b610f6acb3c2512d3b92c/initial-setup/img/iam-create-role.png -------------------------------------------------------------------------------- /initial-setup/secrets-template/git-credentials.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | data: 3 | identity: XXXX 4 | identity.pub: XXXX 5 | known_hosts: Z2l0aHViLmNvbSBlY2RzYS1zaGEyLW5pc3RwMjU2IEFBQUFFMlZqWkhOaExYTm9ZVEl0Ym1semRIQXlOVFlBQUFBSWJtbHpkSEF5TlRZQUFBQkJCRW1LU0VOalFFZXpPbXhrWk15N29wS2d3RkI5bmt0NVlScllNak51RzVOODd1UmdnNkNMcmJvNXdBZFQveTZ2MG1LVjBVMncwV1oyWUIvKytUcG9ja2c9 6 | kind: Secret 7 | metadata: 8 | name: flux-system 9 | namespace: flux-system 10 | type: Opaque -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-api-manifests/v1/kubernetes/base/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: product-catalog-api 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: product-catalog-api 10 | strategy: 11 | rollingUpdate: 12 | maxSurge: 25% 13 | maxUnavailable: 25% 14 | type: RollingUpdate 15 | template: 16 | metadata: 17 | labels: 18 | app: product-catalog-api 19 | spec: 20 | serviceAccountName: product-catalog-api-sa 21 | containers: 22 | - name: product-catalog-api 23 | ports: 24 | - containerPort: 5000 25 | name: http 26 | protocol: TCP 27 | livenessProbe: 28 | failureThreshold: 3 29 | httpGet: 30 | path: /products/ping 31 | port: 5000 32 | scheme: HTTP 33 | initialDelaySeconds: 5 34 | periodSeconds: 5 35 | successThreshold: 1 36 | timeoutSeconds: 1 37 | readinessProbe: 38 | failureThreshold: 3 39 | httpGet: 40 | path: /products/ping 41 | port: 5000 42 | scheme: HTTP 43 | initialDelaySeconds: 5 44 | periodSeconds: 3 45 | successThreshold: 1 46 | timeoutSeconds: 1 47 | -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-api-manifests/v1/kubernetes/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - deployment.yaml 5 | - service.yaml 6 | -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-api-manifests/v1/kubernetes/base/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: product-catalog-api 5 | spec: 6 | ports: 7 | - name: http 8 | port: 80 9 | protocol: TCP 10 | targetPort: 5000 11 | selector: 12 | app: product-catalog-api 13 | 14 | -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-api-manifests/v1/kubernetes/overlays/prod/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: product-catalog-api 5 | spec: 6 | replicas: 3 7 | template: 8 | spec: 9 | containers: 10 | - image: public.ecr.aws/h2c3y9h0/multi-cluster-gitops/product-catalog-api:v1 11 | name: product-catalog-api 12 | -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-api-manifests/v1/kubernetes/overlays/prod/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - ../../base 5 | namespace: product-catalog-api 6 | nameSuffix: -prod 7 | patchesStrategicMerge: 8 | - deployment.yaml 9 | -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-api-manifests/v1/kubernetes/overlays/staging/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: product-catalog-api 5 | spec: 6 | replicas: 2 7 | template: 8 | spec: 9 | containers: 10 | - image: public.ecr.aws/h2c3y9h0/multi-cluster-gitops/product-catalog-api:v1 11 | name: product-catalog-api -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-api-manifests/v1/kubernetes/overlays/staging/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - ../../base 5 | namespace: product-catalog-api 6 | nameSuffix: -staging 7 | patchesStrategicMerge: 8 | - deployment.yaml 9 | -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-api-manifests/v2-staging/kubernetes/overlays/staging/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: product-catalog-api 5 | spec: 6 | replicas: 2 7 | template: 8 | spec: 9 | containers: 10 | - name: product-catalog-api 11 | image: public.ecr.aws/h2c3y9h0/multi-cluster-gitops/product-catalog-api:v2 12 | env: 13 | - name: PRODUCTS_TABLE_REGION 14 | value: ${AWS_REGION} 15 | - name: PRODUCTS_TABLE_NAME 16 | value: products-staging -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-api-manifests/v2-staging/kubernetes/overlays/staging/infra.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: dynamodb.aws.crossplane.io/v1alpha1 2 | kind: Table 3 | metadata: 4 | name: products 5 | spec: 6 | forProvider: 7 | region: ${AWS_REGION} 8 | attributeDefinitions: 9 | - attributeName: id 10 | attributeType: S 11 | keySchema: 12 | - attributeName: id 13 | keyType: HASH 14 | billingMode: PROVISIONED 15 | provisionedThroughput: 16 | readCapacityUnits: 1 17 | writeCapacityUnits: 1 18 | providerConfigRef: 19 | name: default -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-api-manifests/v2-staging/kubernetes/overlays/staging/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - ../../base 5 | - infra.yaml 6 | namespace: product-catalog-api 7 | nameSuffix: -staging 8 | patchesStrategicMerge: 9 | - deployment.yaml 10 | -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-fe-manifests/kubernetes/base/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: product-catalog-fe 5 | spec: 6 | replicas: 1 7 | selector: 8 | matchLabels: 9 | app: product-catalog-fe 10 | strategy: 11 | rollingUpdate: 12 | maxSurge: 25% 13 | maxUnavailable: 25% 14 | type: RollingUpdate 15 | template: 16 | metadata: 17 | labels: 18 | app: product-catalog-fe 19 | spec: 20 | containers: 21 | - env: 22 | - name: BASE_URL 23 | value: "http://product-catalog-api.product-catalog-api/products/" 24 | name: product-catalog-fe 25 | ports: 26 | - containerPort: 9000 27 | name: http 28 | protocol: TCP 29 | livenessProbe: 30 | failureThreshold: 3 31 | httpGet: 32 | path: /ping 33 | port: 9000 34 | scheme: HTTP 35 | initialDelaySeconds: 5 36 | periodSeconds: 5 37 | successThreshold: 1 38 | timeoutSeconds: 1 39 | readinessProbe: 40 | failureThreshold: 3 41 | httpGet: 42 | path: /ping 43 | port: 9000 44 | scheme: HTTP 45 | initialDelaySeconds: 5 46 | periodSeconds: 3 47 | successThreshold: 1 48 | timeoutSeconds: 1 49 | -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-fe-manifests/kubernetes/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - deployment.yaml 5 | - service.yaml 6 | -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-fe-manifests/kubernetes/base/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: product-catalog-fe 5 | spec: 6 | ports: 7 | - name: http 8 | port: 80 9 | protocol: TCP 10 | targetPort: 9000 11 | selector: 12 | app: product-catalog-fe 13 | type: LoadBalancer 14 | -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-fe-manifests/kubernetes/overlays/prod/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: product-catalog-fe 5 | spec: 6 | replicas: 3 7 | template: 8 | spec: 9 | containers: 10 | - name: product-catalog-fe 11 | image: public.ecr.aws/h2c3y9h0/multi-cluster-gitops/product-catalog-fe:latest 12 | env: 13 | - name: BASE_URL 14 | value: "http://product-catalog-api-prod.product-catalog-api/products/" 15 | -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-fe-manifests/kubernetes/overlays/prod/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - ../../base 5 | namespace: product-catalog-fe 6 | nameSuffix: -prod 7 | patchesStrategicMerge: 8 | - deployment.yaml 9 | -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-fe-manifests/kubernetes/overlays/staging/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: product-catalog-fe 5 | spec: 6 | replicas: 2 7 | template: 8 | spec: 9 | containers: 10 | - name: product-catalog-fe 11 | image: public.ecr.aws/h2c3y9h0/multi-cluster-gitops/product-catalog-fe:latest 12 | env: 13 | - name: BASE_URL 14 | value: "http://product-catalog-api-staging.product-catalog-api/products/" 15 | -------------------------------------------------------------------------------- /repos/apps-manifests/product-catalog-fe-manifests/kubernetes/overlays/staging/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - ../../base 5 | namespace: product-catalog-fe 6 | nameSuffix: -staging 7 | patchesStrategicMerge: 8 | - deployment.yaml 9 | -------------------------------------------------------------------------------- /repos/apps/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/eks-multi-cluster-gitops/910fe7fd48015dfaf08b610f6acb3c2512d3b92c/repos/apps/.DS_Store -------------------------------------------------------------------------------- /repos/apps/product-catalog-api/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | *.py[cod] 3 | *$py.class -------------------------------------------------------------------------------- /repos/apps/product-catalog-api/v1/.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | node_modules 3 | npm-debug.log -------------------------------------------------------------------------------- /repos/apps/product-catalog-api/v1/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | # Use an official Python runtime as an image 4 | FROM python:3.9-slim 5 | 6 | RUN apt-get update \ 7 | && apt-get install curl -y \ 8 | && rm -rf /var/lib/apt/lists/* 9 | 10 | RUN mkdir /app 11 | WORKDIR /app 12 | 13 | # We copy just the requirements.txt first to leverage Docker cache 14 | COPY requirements.txt /app 15 | RUN pip install -r requirements.txt 16 | 17 | COPY . /app 18 | 19 | # ENV AGG_APP_URL='http://prodinfo.octank-mesh-ns.svc.cluster.local:3000/productAgreement' 20 | 21 | #WORKDIR /docker_app 22 | EXPOSE 8080 23 | ENTRYPOINT ["/app/bootstrap.sh"] 24 | -------------------------------------------------------------------------------- /repos/apps/product-catalog-api/v1/app.py: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | import werkzeug 4 | werkzeug.cached_property = werkzeug.utils.cached_property 5 | from flask import Flask, request, url_for 6 | from flask_restx import Api, Resource, fields 7 | from flask_cors import CORS 8 | import requests 9 | import os 10 | import logging 11 | 12 | flask_app = Flask(__name__) 13 | flask_app.debug = True 14 | log_level = logging.INFO 15 | flask_app.logger.setLevel(log_level) 16 | # enable CORS 17 | CORS(flask_app, resources={r'/*': {'origins': '*'}}) 18 | 19 | # Fix of returning swagger.json on HTTP 20 | @property 21 | def specs_url(self): 22 | """ 23 | The Swagger specifications absolute url (ie. `swagger.json`) 24 | 25 | :rtype: str 26 | """ 27 | return url_for(self.endpoint('specs'), _external=False) 28 | 29 | Api.specs_url = specs_url 30 | app = Api(app = flask_app, 31 | version = "1.0", 32 | title = "Product Catalog", 33 | description = "Complete dictionary of Products available in the Product Catalog") 34 | 35 | name_space = app.namespace('products', description='Products from Product Catalog') 36 | 37 | model = app.model('Name Model', 38 | {'name': fields.String(required = True, 39 | description="Name of the Product", 40 | help="Product Name cannot be blank.")}) 41 | 42 | list_of_names = {} 43 | 44 | @name_space.route('/') 45 | class Products(Resource): 46 | """ 47 | Manipulations with products. 48 | """ 49 | def get(self): 50 | """ 51 | List of products. 52 | Returns a list of products 53 | """ 54 | try: 55 | flask_app.logger.info('Get-All Request succeeded') 56 | return { 57 | "products": list_of_names 58 | } 59 | except Exception as e: 60 | flask_app.logger.error('Error 500 Could not retrieve information ' + e.__doc__ ) 61 | name_space.abort(500, e.__doc__, status = "Could not retrieve information", statusCode = "500") 62 | 63 | @name_space.route('/ping') 64 | class Ping(Resource): 65 | def get(self): 66 | return "healthy" 67 | 68 | @name_space.route("/") 69 | @name_space.param('id', 'Specify the ProductId') 70 | class MainClass(Resource): 71 | 72 | @app.doc(responses={ 200: 'OK', 400: 'Invalid Argument', 500: 'General Error' }) 73 | def get(self, id=None): 74 | try: 75 | name = list_of_names[id] 76 | flask_app.logger.info('Get Request succeeded ' + list_of_names[id]) 77 | return { 78 | "status": "Product Details retrieved", 79 | "name" : list_of_names[id] 80 | } 81 | except Exception as e: 82 | flask_app.logger.error('Error 500 Could not retrieve information ' + e.__doc__ ) 83 | name_space.abort(500, e.__doc__, status = "Could not retrieve information", statusCode = "500") 84 | 85 | 86 | @app.doc(responses={ 200: 'OK', 400: 'Invalid Argument', 500: 'General Error' }) 87 | @app.expect(model) 88 | def post(self, id): 89 | try: 90 | list_of_names[id] = request.json['name'] 91 | flask_app.logger.info('Post Request succeeded ' + list_of_names[id]) 92 | return { 93 | "status": "New Product added to Product Catalog", 94 | "name": list_of_names[id] 95 | } 96 | except Exception as e: 97 | flask_app.logger.error('Error 500 Could not save information ' + e.__doc__ ) 98 | name_space.abort(500, e.__doc__, status = "Could not save information", statusCode = "500") 99 | 100 | if __name__ == '__main__': 101 | app.run(host="0.0.0.0", debug=True) -------------------------------------------------------------------------------- /repos/apps/product-catalog-api/v1/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export FLASK_APP=./app.py 3 | export FLASK_DEBUG=1 4 | flask run -h 0.0.0.0 -------------------------------------------------------------------------------- /repos/apps/product-catalog-api/v1/requirements.txt: -------------------------------------------------------------------------------- 1 | flask-restx==1.3.0 2 | Flask==3.0.3 3 | werkzeug==3.0.4 4 | gunicorn==23.0.0 5 | requests==v2.32.3 6 | flask-cors==4.0.2 7 | boto3==1.35.39 8 | markupsafe==2.1.5 -------------------------------------------------------------------------------- /repos/apps/product-catalog-api/v2/.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | node_modules 3 | npm-debug.log -------------------------------------------------------------------------------- /repos/apps/product-catalog-api/v2/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | # Use an official Python runtime as an image 4 | FROM python:3.9-slim 5 | 6 | RUN apt-get update \ 7 | && apt-get install curl -y \ 8 | && rm -rf /var/lib/apt/lists/* 9 | 10 | RUN mkdir /app 11 | WORKDIR /app 12 | 13 | # We copy just the requirements.txt first to leverage Docker cache 14 | COPY requirements.txt /app 15 | RUN pip install -r requirements.txt 16 | 17 | COPY . /app 18 | 19 | # ENV AGG_APP_URL='http://prodinfo.octank-mesh-ns.svc.cluster.local:3000/productAgreement' 20 | 21 | #WORKDIR /docker_app 22 | EXPOSE 8080 23 | ENTRYPOINT ["/app/bootstrap.sh"] 24 | -------------------------------------------------------------------------------- /repos/apps/product-catalog-api/v2/app.py: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | import boto3 4 | import os 5 | import logging 6 | import werkzeug 7 | 8 | werkzeug.cached_property = werkzeug.utils.cached_property 9 | 10 | from flask import Flask, request, url_for 11 | from flask_restx import Api, Resource, fields 12 | from flask_cors import CORS 13 | 14 | 15 | flask_app = Flask(__name__) 16 | flask_app.debug = True 17 | log_level = logging.INFO 18 | flask_app.logger.setLevel(log_level) 19 | # enable CORS 20 | CORS(flask_app, resources={r"/*": {"origins": "*"}}) 21 | 22 | session = boto3.Session() 23 | dynamodb = session.resource( 24 | "dynamodb", region_name=os.getenv("PRODUCTS_TABLE_REGION", "eu-west-1") 25 | ) 26 | table_name = os.getenv("PRODUCTS_TABLE_NAME", "products") 27 | table = dynamodb.Table(table_name) 28 | 29 | # Fix of returning swagger.json on HTTP 30 | @property 31 | def specs_url(self): 32 | """ 33 | The Swagger specifications absolute url (ie. `swagger.json`) 34 | 35 | :rtype: str 36 | """ 37 | return url_for(self.endpoint("specs"), _external=False) 38 | 39 | 40 | Api.specs_url = specs_url 41 | app = Api( 42 | app=flask_app, 43 | version="1.0", 44 | title="Product Catalog", 45 | description="Complete dictionary of Products available in the Product Catalog", 46 | ) 47 | 48 | name_space = app.namespace("products", description="Products from Product Catalog") 49 | 50 | model = app.model( 51 | "Name Model", 52 | { 53 | "name": fields.String( 54 | required=True, 55 | description="Name of the Product", 56 | help="Product Name cannot be blank.", 57 | ) 58 | }, 59 | ) 60 | 61 | 62 | @name_space.route("/") 63 | class Products(Resource): 64 | """ 65 | Manipulations with products. 66 | """ 67 | 68 | def get(self): 69 | """ 70 | List of products. 71 | Returns a list of products 72 | """ 73 | try: 74 | 75 | flask_app.logger.info("Get all.....") 76 | 77 | resp = table.scan(AttributesToGet=["id", "name"]) 78 | 79 | products = {} 80 | for item in resp["Items"]: 81 | products[item["id"]] = item["name"] 82 | 83 | flask_app.logger.info("Get-All Request succeeded") 84 | return {"products": products} 85 | except Exception as e: 86 | flask_app.logger.error( 87 | "Error 500 Could not retrieve information " + e.__doc__ 88 | ) 89 | name_space.abort( 90 | 500, 91 | e.__doc__, 92 | status="Could not retrieve information", 93 | statusCode="500", 94 | ) 95 | 96 | 97 | @name_space.route("/ping") 98 | class Ping(Resource): 99 | def get(self): 100 | return "healthy" 101 | 102 | 103 | @name_space.route("/") 104 | @name_space.param("id", "Specify the ProductId") 105 | class MainClass(Resource): 106 | @app.doc(responses={200: "OK", 400: "Invalid Argument", 500: "General Error"}) 107 | def get(self, id=None): 108 | try: 109 | resp = table.get_item(Key={"id": str(id)}) 110 | 111 | flask_app.logger.info("Get Request succeeded " + resp["Item"]["name"]) 112 | return {"status": "Product Details retrieved", "name": resp["Item"]["name"]} 113 | except Exception as e: 114 | flask_app.logger.error( 115 | "Error 500 Could not retrieve information " + e.__doc__ 116 | ) 117 | name_space.abort( 118 | 500, 119 | e.__doc__, 120 | status="Could not retrieve information", 121 | statusCode="500", 122 | ) 123 | 124 | @app.doc(responses={200: "OK", 400: "Invalid Argument", 500: "General Error"}) 125 | @app.expect(model) 126 | def post(self, id): 127 | try: 128 | product_item = {"id": str(id), "name": request.json["name"]} 129 | 130 | table.put_item(Item=product_item) 131 | 132 | flask_app.logger.info("Post Request succeeded " + request.json["name"]) 133 | 134 | return { 135 | "status": "New Product added to Product Catalog", 136 | "name": request.json["name"], 137 | } 138 | except Exception as e: 139 | flask_app.logger.error("Error 500 Could not save information " + e.__doc__) 140 | name_space.abort( 141 | 500, e.__doc__, status="Could not save information", statusCode="500" 142 | ) 143 | 144 | 145 | if __name__ == "__main__": 146 | app.run(host="0.0.0.0", debug=True) 147 | -------------------------------------------------------------------------------- /repos/apps/product-catalog-api/v2/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export FLASK_APP=./app.py 3 | export FLASK_DEBUG=1 4 | flask run -h 0.0.0.0 -------------------------------------------------------------------------------- /repos/apps/product-catalog-api/v2/requirements.txt: -------------------------------------------------------------------------------- 1 | flask-restx==1.3.0 2 | Flask==3.0.3 3 | werkzeug==3.0.4 4 | gunicorn==23.0.0 5 | requests==v2.32.3 6 | flask-cors==4.0.2 7 | boto3==1.35.39 8 | markupsafe==2.1.5 -------------------------------------------------------------------------------- /repos/apps/product-catalog-fe/.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | node_modules 3 | npm-debug.log -------------------------------------------------------------------------------- /repos/apps/product-catalog-fe/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /repos/apps/product-catalog-fe/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | # SPDX-License-Identifier: MIT-0 3 | FROM node:14 4 | 5 | # Create app directory 6 | WORKDIR /usr/src/app 7 | 8 | # Install app dependencies 9 | # A wildcard is used to ensure both package.json AND package-lock.json are copied 10 | # where available (npm@5+) 11 | COPY package.json package-lock.json ./ 12 | 13 | # RUN npm install 14 | # If you are building your code for production 15 | RUN npm ci --only=production 16 | 17 | # Bundle app source 18 | COPY . . 19 | 20 | EXPOSE 9000 21 | CMD [ "node", "server.js" ] -------------------------------------------------------------------------------- /repos/apps/product-catalog-fe/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Product Catalog 6 | 7 | 8 |

Product Catalog

9 | 10 |
11 | 12 | 13 | 14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /repos/apps/product-catalog-fe/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend-node", 3 | "version": "1.0.0", 4 | "description": "front end application for microservices in app mesh", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "nodemon server.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "Praseeda Sathaye", 11 | "license": "MIT-0", 12 | "dependencies": { 13 | "axios": "^1.7.4", 14 | "body-parser": "^1.20.3", 15 | "ejs": "^3.1.10", 16 | "express": "^4.21.1", 17 | "prom-client": "^14.0.1" 18 | }, 19 | "devDependencies": { 20 | "nodemon": "^2.0.18" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /repos/apps/product-catalog-fe/public/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/eks-multi-cluster-gitops/910fe7fd48015dfaf08b610f6acb3c2512d3b92c/repos/apps/product-catalog-fe/public/.gitkeep -------------------------------------------------------------------------------- /repos/apps/product-catalog-fe/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const bodyParser= require('body-parser'); 3 | const axios = require('axios'); 4 | const path = require("path"); 5 | const Prometheus = require('prom-client'); 6 | 7 | Prometheus.collectDefaultMetrics(); 8 | 9 | const port = process.env.PORT || 9000; 10 | 11 | var baseProductUrl = process.env.BASE_URL; 12 | 13 | if(baseProductUrl === undefined) { 14 | baseProductUrl = 'http://localhost:5000/products/'; 15 | } 16 | 17 | const app = express(); 18 | 19 | app.set('view engine', 'ejs') 20 | app.use(express.static(path.join(__dirname, "public"))); 21 | 22 | app.use(bodyParser.urlencoded({extended: true})) 23 | 24 | app.get('/', (_, res) => { 25 | const requestOne = axios.get(baseProductUrl); 26 | axios.all([requestOne]).then(axios.spread((...responses) => { 27 | const responseOne = responses[0] 28 | 29 | res.render('index.ejs', {products: responseOne.data.products}) 30 | console.log("Product Catalog get call was Successful from frontend"); 31 | })).catch(errors => { 32 | 33 | console.log(errors); 34 | console.log("There was error in Product Catalog get call from frontend"); 35 | }) 36 | }) 37 | 38 | app.post('/products', (req, res) => { 39 | var headers = { 40 | 'Content-Type': 'application/json' 41 | } 42 | 43 | axios 44 | .post(`${baseProductUrl}${req.body.id}`, JSON.stringify({ name: `${req.body.name}` }), {"headers" : headers}) 45 | .then(() => { 46 | res.redirect(req.get('referer')); 47 | console.log("Product Catalog post call was Successful from frontend"); 48 | }) 49 | .catch(error => { 50 | console.error(error) 51 | }) 52 | }) 53 | 54 | app.get("/ping", (req, res, _) => { 55 | res.json("Healthy"); 56 | }); 57 | 58 | // Export Prometheus metrics from /stats/prometheus endpoint 59 | app.get('/stats/prometheus', (req, res, _) => { 60 | res.set('Content-Type', Prometheus.register.contentType); 61 | res.end(Prometheus.register.metrics()); 62 | }) 63 | 64 | app.listen(parseInt(port), function() { 65 | console.log(`Listening on ${port}`); 66 | console.log(`Using product catalog at ${baseProductUrl}`); 67 | }) -------------------------------------------------------------------------------- /repos/apps/product-catalog-fe/views/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Product Catalog 10 | 11 | 27 | 28 | 29 | 30 |
31 |

Product Catalog

32 |

Add new products and view all existing products

33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | 41 |
42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | 51 |
52 | 53 |
54 |
55 |
56 |
57 |
58 | 59 |
60 |
61 |
62 | 63 |
64 |
65 | 66 | 67 | 68 | 71 | 74 | 75 | 76 | 77 | <% for(var i = 0; i < Object.keys(products).length; i++) { %> 78 | 79 | 82 | 85 | 86 | <% }; %> 87 | 88 |
69 | ID 70 | 72 | Product Name 73 |
80 | <%= Object.keys(products)[i] %> 81 | 83 | <%= Object.values(products)[i] %> 84 |
89 |
90 |
91 |
92 | 93 | -------------------------------------------------------------------------------- /repos/gitops-system/.gitignore: -------------------------------------------------------------------------------- 1 | /.DS_Store 2 | wl-kube.conf -------------------------------------------------------------------------------- /repos/gitops-system/README.md: -------------------------------------------------------------------------------- 1 | # GitOps System 2 | 3 | This directory contains all of the manifests which define the GitOps systems for 4 | the management cluster and each of the workload clusters. 5 | 6 | ## Structure 7 | 8 | ### `clusters` 9 | 10 | Stores the Flux entrypoint definitions for each of the clusters (including the 11 | management cluster). Each of the subdirectories corresponds 1:1 with a cluster. 12 | The `mgmt` cluster represents the management cluster, whereas all other clusters 13 | are represented by their name. Within their respective subdirectory, each 14 | cluster has a `flux-system` directory to store the Flux CD configuration 15 | manifests (CRDs, Deployments, etc.) and also a reference to the `gitops-system` 16 | manifest Git repository and a Kustomization for its own resources (which points 17 | to the cluster subdirectory). You can think of this subdirectory as the 18 | entrypoint for all of the other Flux CD Kustomizations and Helm Releases to be 19 | deployed into the environment. 20 | 21 | ### `clusters-config` 22 | 23 | Stores the cluster and tool configuration for each of the workload clusters. The 24 | `def` subdirectory contains the EKS cluster definition, as represented by a 25 | Crossplane custom resource (the XRD defined in `tools`). The `external-secrets` 26 | subdirectory installs the External Secrets Helm chart. The `initialization` 27 | subdirectory contains the `flux-system` namespace. This is required so that the 28 | `Kustomization` which installs the tools into the cluster (External Secrets, 29 | Flux CD) can depend on it to ensure that the Namespace exists. The `secrets` 30 | subdirectory contains the secrets required by the local Flux CD installation to 31 | connect to its workload and manifest Git repositories (sealed with the common 32 | Sealed Secrets certificate). The other files in this directory install the tools 33 | required by the cluster - [External Secrets][external-secrets], Flux, [Sealed 34 | Secrets][sealed-secrets] - and their respective configurations. 35 | 36 | [external-secrets]: https://github.com/external-secrets/external-secrets 37 | [sealed-secrets]: https://github.com/bitnami-labs/sealed-secrets 38 | 39 | ### `tools` 40 | 41 | Stores the configuration for any tools required by workload clusters. The 42 | `crossplane` subdirectory contains the core [Crossplane][crossplane] 43 | installation, configuration for the [Crossplane AWS Provider][crossplane-aws], 44 | configuration for authenticating the AWS provider with credentials and 45 | Crossplane composite resource definitions and compositions for an EKS cluster. 46 | The `external-secrets` subdirectory contains a `HelmRelease` for installing the 47 | External Secrets operator (used only by the management cluster). 48 | 49 | [crossplane]: https://github.com/crossplane/crossplane 50 | [crossplane-aws]: https://github.com/crossplane/provider-aws 51 | 52 | ### `tools-config` 53 | 54 | Stores optional configuration for any tools required by the workload cluster. 55 | Currently this directory only contains configuration for the common signing key 56 | required by Sealed Secrets to decrypt each of the secrets. 57 | 58 | ### `workloads` 59 | 60 | Stores the workload configuration manifests for each of the clusters. Each of 61 | the subdirectories corresponds 1:1 with a workload cluster. Within their 62 | respective subdirectory, each cluster has references to Git repositories and 63 | Kustomizations for any of the workloads that should be installed into the 64 | cluster. -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/template/crossplane-iam.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 2 | kind: Kustomization 3 | metadata: 4 | name: cluster-name-crossplane-iam 5 | namespace: flux-system 6 | spec: 7 | dependsOn: 8 | - name: cluster-name-eks-cluster 9 | interval: 1m0s 10 | path: ./tools-config/crossplane-iam 11 | prune: true 12 | sourceRef: 13 | kind: GitRepository 14 | name: flux-system 15 | healthChecks: 16 | - kind: Role 17 | apiVersion: iam.aws.crossplane.io/v1beta1 18 | name: crossplane-role-cluster-name 19 | - kind: RolePolicyAttachment 20 | apiVersion: iam.aws.crossplane.io/v1beta1 21 | name: crossplane-rolepolicyattachment-cluster-name 22 | timeout: 2m 23 | patches: 24 | - target: 25 | group: iam.aws.crossplane.io 26 | kind: Role 27 | version: v1beta1 28 | name: crossplane-role 29 | patch: |- 30 | - op: replace 31 | path: /metadata/name 32 | value: crossplane-role-cluster-name 33 | - target: 34 | group: iam.aws.crossplane.io 35 | kind: RolePolicyAttachment 36 | version: v1beta1 37 | name: crossplane-rolepolicyattachment 38 | patch: |- 39 | - op: replace 40 | path: /metadata/name 41 | value: crossplane-rolepolicyattachment-cluster-name 42 | - op: replace 43 | path: /spec/forProvider/policyArnRef/name 44 | value: crossplane-policy-cluster-name 45 | - op: replace 46 | path: /spec/forProvider/roleNameRef/name 47 | value: crossplane-role-cluster-name 48 | - target: 49 | group: iam.aws.crossplane.io 50 | kind: Policy 51 | version: v1beta1 52 | name: crossplane-policy 53 | patch: |- 54 | - op: replace 55 | path: /metadata/name 56 | value: crossplane-policy-cluster-name 57 | - op: replace 58 | path: /spec/forProvider/name 59 | value: crossplane-policy-cluster-name 60 | postBuild: 61 | substituteFrom: 62 | - kind: ConfigMap 63 | name: cluster-info-cluster-name 64 | optional: false -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/template/def/eks-cluster.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: gitops.k8s.aws/v1beta1 3 | kind: EKSCluster 4 | metadata: 5 | name: cluster-name 6 | spec: 7 | parameters: 8 | region: AWS_REGION 9 | vpc-name: 'cluster-name-eks-vpc' 10 | vpc-cidrBlock: '10.20.0.0/16' 11 | 12 | subnet1-public-name: 'public-worker-1' 13 | subnet1-public-cidrBlock: '10.20.1.0/24' 14 | subnet1-public-availabilityZone: 'AWS_REGIONa' 15 | 16 | subnet2-public-name: 'public-worker-2' 17 | subnet2-public-cidrBlock: '10.20.2.0/24' 18 | subnet2-public-availabilityZone: 'AWS_REGIONb' 19 | 20 | subnet1-private-name: 'private-worker-1' 21 | subnet1-private-cidrBlock: '10.20.11.0/24' 22 | subnet1-private-availabilityZone: 'AWS_REGIONa' 23 | 24 | subnet2-private-name: 'private-worker-2' 25 | subnet2-private-cidrBlock: '10.20.12.0/24' 26 | subnet2-private-availabilityZone: 'AWS_REGIONb' 27 | 28 | eks-k8s-version: '1.28' 29 | mng-k8s-version: '1.28' 30 | workload-type: 'non-gpu' 31 | workers-size: 2 32 | 33 | compositionRef: 34 | name: amazon-eks-cluster 35 | 36 | writeConnectionSecretToRef: 37 | namespace: flux-system 38 | name: cluster-name-eks-connection 39 | -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/template/def/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - eks-cluster.yaml -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/template/eks-cluster.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: cluster-name-eks-cluster 6 | namespace: flux-system 7 | spec: 8 | interval: 30s 9 | path: ./clusters-config/cluster-name/def 10 | prune: true 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | healthChecks: 15 | - kind: Secret 16 | apiVersion: v1 17 | name: cluster-name-eks-connection 18 | namespace: flux-system 19 | - kind: OpenIDConnectProvider 20 | apiVersion: iam.aws.crossplane.io/v1beta1 21 | name: cluster-oidc-idp-cluster-name 22 | timeout: 2m 23 | -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/template/external-secrets-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: cluster-name-external-secrets-config 6 | namespace: flux-system 7 | spec: 8 | dependsOn: 9 | - name: cluster-name-external-secrets 10 | interval: 30s 11 | path: ./tools-config/external-secrets 12 | prune: true 13 | sourceRef: 14 | kind: GitRepository 15 | name: flux-system 16 | healthChecks: 17 | - kind: Secret 18 | apiVersion: v1 19 | name: sealed-secrets 20 | namespace: sealed-secrets 21 | - kind: ServiceAccount 22 | apiVersion: v1 23 | name: aws-secrets-manager 24 | namespace: sealed-secrets 25 | kubeConfig: 26 | secretRef: 27 | name: cluster-name-eks-connection 28 | timeout: 2m 29 | patches: 30 | - target: 31 | group: "" 32 | kind: ServiceAccount 33 | version: v1 34 | name: aws-secrets-manager 35 | namespace: sealed-secrets 36 | patch: |- 37 | - op: replace 38 | path: /metadata/annotations 39 | value: 40 | eks.amazonaws.com/role-arn: arn:aws:iam::${ACCOUNT_ID}:role/external-secrets-role-cluster-name 41 | postBuild: 42 | substituteFrom: 43 | - kind: ConfigMap 44 | name: cluster-info-cluster-name 45 | optional: false 46 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/template/external-secrets-iam.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 2 | kind: Kustomization 3 | metadata: 4 | name: cluster-name-external-secrets-iam 5 | namespace: flux-system 6 | spec: 7 | dependsOn: 8 | - name: cluster-name-crossplane-iam 9 | interval: 1m0s 10 | path: ./tools-config/external-secrets-iam 11 | prune: true 12 | sourceRef: 13 | kind: GitRepository 14 | name: flux-system 15 | healthChecks: 16 | - kind: Role 17 | apiVersion: iam.aws.crossplane.io/v1beta1 18 | name: external-secrets-role-cluster-name 19 | - kind: Policy 20 | apiVersion: iam.aws.crossplane.io/v1beta1 21 | name: external-secrets-policy-cluster-name 22 | - kind: RolePolicyAttachment 23 | apiVersion: iam.aws.crossplane.io/v1beta1 24 | name: external-secrets-attachment-cluster-name 25 | timeout: 2m 26 | patches: 27 | - target: 28 | group: iam.aws.crossplane.io 29 | kind: Role 30 | version: v1beta1 31 | name: external-secrets-role 32 | patch: |- 33 | - op: replace 34 | path: /metadata/name 35 | value: external-secrets-role-cluster-name 36 | - target: 37 | group: iam.aws.crossplane.io 38 | kind: Policy 39 | version: v1beta1 40 | name: external-secrets-policy 41 | patch: |- 42 | - op: replace 43 | path: /metadata/name 44 | value: external-secrets-policy-cluster-name 45 | - op: replace 46 | path: /spec/forProvider/name 47 | value: external-secrets-policy-cluster-name 48 | - target: 49 | group: iam.aws.crossplane.io 50 | kind: RolePolicyAttachment 51 | version: v1beta1 52 | name: external-secrets-attachment 53 | patch: |- 54 | - op: replace 55 | path: /metadata/name 56 | value: external-secrets-attachment-cluster-name 57 | - op: replace 58 | path: /spec/forProvider/policyArnRef/name 59 | value: external-secrets-policy-cluster-name 60 | - op: replace 61 | path: /spec/forProvider/roleNameRef/name 62 | value: external-secrets-role-cluster-name 63 | postBuild: 64 | substituteFrom: 65 | - kind: ConfigMap 66 | name: cluster-info-cluster-name 67 | optional: false -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/template/external-secrets.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: cluster-name-external-secrets 6 | namespace: flux-system 7 | spec: 8 | dependsOn: 9 | - name: cluster-name-external-secrets-iam 10 | interval: 1m0s 11 | path: ./tools/external-secrets 12 | prune: true 13 | sourceRef: 14 | kind: GitRepository 15 | name: flux-system 16 | timeout: 2m 17 | healthChecks: 18 | - apiVersion: helm.toolkit.fluxcd.io/v2beta1 19 | kind: HelmRelease 20 | name: cluster-name-external-secrets 21 | namespace: flux-system 22 | patches: 23 | - target: 24 | group: helm.toolkit.fluxcd.io 25 | kind: HelmRelease 26 | name: external-secrets 27 | namespace: flux-system 28 | patch: |- 29 | - op: add 30 | path: /spec/kubeConfig 31 | value: 32 | secretRef: 33 | name: cluster-name-eks-connection 34 | - op: replace 35 | path: /metadata/name 36 | value: cluster-name-external-secrets 37 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/template/flux.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: cluster-name-flux 6 | namespace: flux-system 7 | spec: 8 | dependsOn: 9 | - name: cluster-name-secrets 10 | interval: 30s 11 | path: ./clusters/cluster-name/flux-system 12 | prune: true 13 | sourceRef: 14 | kind: GitRepository 15 | name: flux-system 16 | kubeConfig: 17 | secretRef: 18 | name: cluster-name-eks-connection 19 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/template/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - eks-cluster.yaml 6 | - crossplane-iam.yaml 7 | - external-secrets-iam.yaml 8 | - external-secrets.yaml 9 | - external-secrets-config.yaml 10 | - sealed-secrets.yaml 11 | - secrets.yaml 12 | - flux.yaml 13 | -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/template/sealed-secrets.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: cluster-name-sealed-secrets 6 | namespace: flux-system 7 | spec: 8 | dependsOn: 9 | - name: cluster-name-external-secrets-config 10 | interval: 30s 11 | path: ./tools/sealed-secrets 12 | prune: true 13 | sourceRef: 14 | kind: GitRepository 15 | name: flux-system 16 | healthChecks: 17 | - apiVersion: helm.toolkit.fluxcd.io/v2beta1 18 | kind: HelmRelease 19 | name: cluster-name-sealed-secrets 20 | namespace: flux-system 21 | timeout: 2m 22 | patches: 23 | - target: 24 | group: helm.toolkit.fluxcd.io 25 | kind: HelmRelease 26 | name: sealed-secrets 27 | namespace: flux-system 28 | patch: |- 29 | - op: add 30 | path: /spec/kubeConfig 31 | value: 32 | secretRef: 33 | name: cluster-name-eks-connection 34 | - op: replace 35 | path: /metadata/name 36 | value: cluster-name-sealed-secrets 37 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/template/secrets.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: cluster-name-secrets 6 | namespace: flux-system 7 | spec: 8 | dependsOn: 9 | - name: cluster-name-sealed-secrets 10 | interval: 30s 11 | path: ./clusters-config/cluster-name/secrets 12 | prune: true 13 | sourceRef: 14 | kind: GitRepository 15 | name: flux-system 16 | healthChecks: 17 | - kind: Secret 18 | apiVersion: v1 19 | name: flux-system 20 | namespace: flux-system 21 | kubeConfig: 22 | secretRef: 23 | name: cluster-name-eks-connection 24 | timeout: 2m 25 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/template/secrets/git-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: bitnami.com/v1alpha1 2 | kind: SealedSecret 3 | metadata: 4 | creationTimestamp: null 5 | name: flux-system 6 | namespace: flux-system 7 | spec: 8 | encryptedData: 9 | identity: AgBlfgnmNVH6UwFeoPi1VsFYTu+fwdai4J2G8ULo83Dv2ko/GnSNVVG6sALthmwE3NOPgvqP4RZIwBsHWjF9Z+yp46IkEWLJxBdIdI0xvuAPUKwBqXrlCBXa0uCSZn2SWvLMYRjhXW6OZVUUhl4jLDZlC/yCWwTLY8Ue4REye0jidPFB664MHzQX2+JnstteDbzRXd5P4z5NIikTvllUoc+g+u7ODtAuZhmkP3ndJdgKqwt8hvxbDnDArgGoBCJx7jxMJPpsH0G/McWW/AvO1/lI8kPyQOYh2X650JLUDlfjToFCmYkBrO99mo6U/7caPaCNY0xUm1t+Fu2cNS6FF1PxuYsVDpNNAOWqosMtL/Cp7YxJNt/tRFljeJ4bDRgby2XoDZSKasaZnARpk8GFUk/qt0ZYQqzZRaMuaVYpZ+KG1tW9a59U4iqP0uZoj5dijwHftDLQn9QlJ/pSjuAivALP6xjB9/yOovwVze0jauEjYcmICQVejdRwxLBnjmQ0Y2+GLKkfaTyTWK8Jny6I4ytK2efAV1VBovIv5l8q4WdO0WQb4z+CcelOxlfG3VAVOiQIpwUmzhort3hC3zrwcE7p9gaJFpaxVVtPfr0FINpk/xY7BWiHC4aENbNbBl84zb6nypCbHbI1f8EC1StlFG/VPVGIAI5+iDqHimRzNTZJpXD7XpGlZrBL2cqI2Vg4yLoYzf6AqF8KWpFGuKPz3qVWTNY/8bdDouQz5Wn3NeAMt4IGFBqQgeCrtSuoM3l3Bw+HpOate7AVa9U2FeOvgVisVfZKY/YP6cehtWAXKfFPzw0Nnzf9moto/RvqbJWBYQmXftW9itSTrLW8nfoRUGgSfqRfHDXAkmqfCP2iBxNMrC2ziEYOA8+WfCnTM562hrH8qAj4dPB2hNxWEgvcnJioyIYwPSJXjuRtOFT9CnaH5GCS8sjOwHU0+RmXP+cyqmI6f1Sj0yRwRUVfPcWUvAxs8xi76Xy+WkDVDumbZ8fNpDk8E00SycYGiXYMNIWS4rH6ld37oM9gMnEsDYXsIT4HY9SPw2c393T762nZ8UIGic49z7XdER16V4433Ipvbt/9a6nm3mUaf1MaE+PVNDT0i0w= 10 | identity.pub: AgCIbHB+TX0XNDMTHAnVLNFTxXb2pl8jGi0258p1F/2MidpQ61hnNR9Q9TW9yz4ZrTHLFOWDfp5qDto++CgXVZdkcoN5iNqCTngvhrsJi5GQ/3+afuQ1IgVoGfSGVDLTII9QFF1TD3aULZG7is3RgONJ965SrVZX9uI0pAzrEzxNyzgo1vytuxnVONBIsE0qUWqfF1m5XuUxq/eJPJTYE1kSnC0KHnOq79SVgPHKKlvQ1WMFwfEzBvjhr+VStURFcEnlhtZpd041PI0ujd4vrmO/yLGS5ObWL9HKWQc9xoHJdKhYfj66MJF7hpxsi6CCOJif0asFgpJzGkdqeUmwBeE0OK10GyumpPo0kPMt7L4O4IsYZkki3awBg4WqzjvT5aNJ6tO7IefrusERQPTVTuOzmQ9nNzXV2Ze4+P/fcPRsHyTUW+6AM5eqwQSGgsZOnxJbOkLuaFRrV9WGTNqyX7/3mZB8/f9onzwfJVSzZzx32K0hMzR40kbk8YhEVa0yvCAEj7vUIxcQsBQyRKMnlfD+XgX5Nq/4u4GySKv+0qw8o+HQyC3TLihJsvSgCSd5qTIVWiCkrOFXbMOzg4r2SYCxgdDHWTvKtxu9rUfhUCtIHmBku8t1zKc6zlt1CX0TIvTmcIrRk1YHK3Tg+NQoi5w7jPqw5g6Sxz3ns8xD+VbhBfmRYpd/oi4Z6NUSbrhuX9fewbxkrzN/S1Rhpw5ZnRBKPJrqrBsNFx0S605yexYY3QDmOAphM+A1gluMvIpMVV4YW2RgtSs+4lL2a87XcT68A2ItmuX0xr8TpQ61+ECFA9D/1I4b3zV/cZOr4xAe6xFeKYign6endDMJTgrDPLQkjdUoUaexspTDpuV38Uj+UGzxS/SCBNc/FI+8rAVF02bEEhjN7HlYf0ip8d3jqTyTRB7oVzXk91FbEF1ToWQbK+n9XeaN3vJUJFhOL8AqLOJV8l76f/+FhCU2VYHN 11 | known_hosts: AgCgWruc496gPUlAmYHVaddxVfWY4YsLXrwxnh6ZPX9uarfCuhWQ8sZmKbfH6nyPXy509m26mifLcvpmReJ88NfnvUSUqX1XIcJfMwYRueyBQ3EH9UAl3qJ+uRlKyx8nX3lJY/CLIK8Nai0WM1za3fIjzzN2qLoSC2uLqg1rfV9eLHy3Kr37jIGhDdX5g+TZKmlrs4i7eaaQlStbx60H56mt4m4BLkiC5rA9MOWC/aaeMNc4SF6OMX448PotdCQpdIoCti1G3Z4fkB0hxEi2Yyq6gGF+4rqoUY4hXdcmW9qOD5AbNN//WrSlUrJMCPyEwRWZKGLNfHMYJvW3vDwRx2irh391aK3NghNqhbFc72ZoNfqJ4dycHUfrsw9POxqD7UWgZNJHojO8LqMItgeJA1b7yzyH2H1kJzBuMwwTMga+RT2t3b0i1UgUwFd0YFEjEUEtgyUv81BPOTASi5ymdu5zX5G+fwxo4SF+ClsVdFY/u4SAdakC+srbHmeuEcAse8i+TnkC93hCYFx2R5wsYw0qY0OlWyrN+dmbzAkWXutifRnUREjTJ+/hzaEgbRlKxxnQfvaW62CLIWvnbEV/l1FtSyMnA2ZVYfhZ7vM/+R0Uugy6fhaYyzf72ATVQqBE0h66snRnH/TzQn3C7QU16bpmJ2m8H/ltylkwpfWMHzeUKDVcqguBnVduaoDEBYmUYD4pDEQEJ7FsYGLI5dd2aumF5QDRjmqgl8eRY3qfLqm5y0ea1mhddcKZIlGKbQ5GIAGHkkI2iUlJGKNIezmmoh0USuv5VbnP/vKUT/EtmC5/jm0DmS0tKF04RT9MwtbfCwqFwhTpmwqkmc/UWc82aqdb5nS+iuMvR8NL7xCHyyW/KgcJu8Z2wMosp0dr65KRAgBo8F7EH7RlaR3RYW1CCDA5bDU+lgFxrmrA8Sw= 12 | template: 13 | data: null 14 | metadata: 15 | creationTimestamp: null 16 | name: flux-system 17 | namespace: flux-system 18 | type: Opaque 19 | 20 | -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/template/secrets/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - namespace.yaml 6 | - git-secret.yaml -------------------------------------------------------------------------------- /repos/gitops-system/clusters-config/template/secrets/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | labels: 5 | app.kubernetes.io/instance: flux-system 6 | app.kubernetes.io/part-of: flux 7 | app.kubernetes.io/version: v0.26.3 8 | pod-security.kubernetes.io/warn: restricted 9 | pod-security.kubernetes.io/warn-version: latest 10 | name: flux-system 11 | -------------------------------------------------------------------------------- /repos/gitops-system/clusters/mgmt/clusters-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: clusters-config 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 2m0s 10 | path: ./clusters-config 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/mgmt/crossplane-eks-composition.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: crossplane-eks-composition 6 | namespace: flux-system 7 | spec: 8 | dependsOn: 9 | - name: crossplane-aws-provider-config 10 | - name: crossplane-k8s-provider-config 11 | interval: 3m0s 12 | path: ./tools-config/crossplane-eks-composition 13 | prune: true 14 | sourceRef: 15 | kind: GitRepository 16 | name: flux-system 17 | timeout: 2m 18 | 19 | -------------------------------------------------------------------------------- /repos/gitops-system/clusters/mgmt/crossplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: crossplane 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | force: true 10 | interval: 3m0s 11 | path: ./tools/crossplane 12 | sourceRef: 13 | kind: GitRepository 14 | name: flux-system 15 | healthChecks: 16 | - apiVersion: batch/v1 17 | kind: Job 18 | name: k8s-provider-config-job 19 | namespace: crossplane-system 20 | patches: 21 | - target: 22 | group: kustomize.toolkit.fluxcd.io 23 | kind: Kustomization 24 | version: v1beta2 25 | name: crossplane-aws-provider 26 | namespace: flux-system 27 | patch: |- 28 | - op: add 29 | path: /spec/postBuild 30 | value: 31 | substituteFrom: 32 | - kind: ConfigMap 33 | name: cluster-info 34 | optional: false 35 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/mgmt/flux-system/gotk-sync.yaml: -------------------------------------------------------------------------------- 1 | # This manifest was generated by flux. DO NOT EDIT. 2 | --- 3 | apiVersion: source.toolkit.fluxcd.io/v1beta2 4 | kind: GitRepository 5 | metadata: 6 | name: flux-system 7 | namespace: flux-system 8 | spec: 9 | interval: 1m0s 10 | ref: 11 | branch: main 12 | secretRef: 13 | name: flux-system 14 | url: REPO_PREFIX/gitops-system 15 | --- 16 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 17 | kind: Kustomization 18 | metadata: 19 | name: flux-system 20 | namespace: flux-system 21 | spec: 22 | interval: 3m0s 23 | path: ./clusters/mgmt 24 | prune: true 25 | sourceRef: 26 | kind: GitRepository 27 | name: flux-system 28 | -------------------------------------------------------------------------------- /repos/gitops-system/clusters/mgmt/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 | -------------------------------------------------------------------------------- /repos/gitops-system/clusters/mgmt/karpenter-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: karpenter-config 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 2m0s 10 | path: ./tools-config/karpenter-config 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | postBuild: 15 | substituteFrom: 16 | - kind: ConfigMap 17 | name: cluster-info 18 | optional: false 19 | dependsOn: 20 | - name: karpenter 21 | patches: 22 | - target: 23 | group: karpenter.k8s.aws 24 | kind: EC2NodeClass 25 | name: default 26 | patch: |- 27 | apiVersion: karpenter.k8s.aws/v1beta1 28 | kind: EC2NodeClass 29 | metadata: 30 | name: not-used 31 | spec: 32 | subnetSelectorTerms: 33 | - tags: 34 | Name: "mgmtPrivate*" 35 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/mgmt/karpenter-iam.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: karpenter-iam 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 2m0s 10 | path: ./tools-config/karpenter-iam 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | healthChecks: 15 | - kind: ServiceAccount 16 | apiVersion: v1 17 | name: karpenter-sa 18 | namespace: kube-system 19 | postBuild: 20 | substituteFrom: 21 | - kind: ConfigMap 22 | name: cluster-info 23 | optional: false 24 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/mgmt/karpenter.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: karpenter 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 10m0s 10 | path: ./tools/karpenter 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | healthChecks: 15 | - apiVersion: apps/v1 16 | kind: Deployment 17 | name: karpenter 18 | namespace: kube-system 19 | postBuild: 20 | substituteFrom: 21 | - kind: ConfigMap 22 | name: cluster-info 23 | optional: false 24 | dependsOn: 25 | - name: karpenter-iam 26 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/mgmt/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - ./flux-system 5 | - clusters-config.yaml 6 | - crossplane-eks-composition.yaml 7 | - crossplane.yaml 8 | - karpenter-config.yaml 9 | - karpenter-iam.yaml 10 | - karpenter.yaml 11 | 12 | -------------------------------------------------------------------------------- /repos/gitops-system/clusters/template/aws-auth.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: aws-auth 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 2m0s 10 | path: ./tools-config/aws-auth 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | postBuild: 15 | substituteFrom: 16 | - kind: ConfigMap 17 | name: cluster-info 18 | optional: false 19 | patches: 20 | - target: 21 | group: "" 22 | kind: ConfigMap 23 | name: aws-auth 24 | patch: |- 25 | apiVersion: v1 26 | kind: ConfigMap 27 | metadata: 28 | name: not-used 29 | data: 30 | mapRoles: | 31 | - groups: 32 | - system:bootstrappers 33 | - system:nodes 34 | rolearn: arn:aws:iam::${ACCOUNT_ID}:role/eks-nodegroup-role 35 | username: system:node:{{EC2PrivateDNSName}} 36 | - rolearn: EKS_CONSOLE_IAM_ENTITY_ARN 37 | username: EKS_CONSOLE_IAM_ENTITY_ARN 38 | - groups: 39 | - system:bootstrappers 40 | - system:nodes 41 | rolearn: arn:aws:iam::${ACCOUNT_ID}:role/karpenter-node-role-cluster-name 42 | username: system:node:{{EC2PrivateDNSName}} 43 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/template/aws-ebs-csi-iam.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: aws-ebs-csi-iam 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 2m0s 10 | path: ./tools-config/aws-ebs-csi-iam 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | healthChecks: 15 | - kind: ServiceAccount 16 | apiVersion: v1 17 | name: ebs-csi-controller-sa 18 | namespace: kube-system 19 | postBuild: 20 | substituteFrom: 21 | - kind: ConfigMap 22 | name: cluster-info 23 | optional: false 24 | patches: 25 | - target: 26 | group: iam.aws.crossplane.io 27 | kind: Role 28 | version: v1beta1 29 | name: ebs-csi-controller-role 30 | namespace: kube-system 31 | patch: |- 32 | - op: replace 33 | path: /metadata/name 34 | value: ebs-csi-controller-role-cluster-name 35 | - target: 36 | group: iam.aws.crossplane.io 37 | kind: RolePolicyAttachment 38 | version: v1beta1 39 | name: ebs-csi-controller-attachment 40 | namespace: kube-system 41 | patch: |- 42 | - op: replace 43 | path: /metadata/name 44 | value: ebs-csi-controller-attachment-cluster-name 45 | - op: replace 46 | path: /spec/forProvider/roleNameRef/name 47 | value: ebs-csi-controller-role-cluster-name 48 | - target: 49 | group: "" 50 | kind: ServiceAccount 51 | version: v1 52 | name: ebs-csi-controller-sa 53 | namespace: kube-system 54 | patch: |- 55 | - op: replace 56 | path: /metadata/annotations 57 | value: 58 | eks.amazonaws.com/role-arn: arn:aws:iam::${ACCOUNT_ID}:role/ebs-csi-controller-role-cluster-name 59 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/template/aws-ebs-csi.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: aws-ebs-csi 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 10m0s 10 | path: ./tools/aws-ebs-csi 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | dependsOn: 15 | - name: aws-ebs-csi-iam 16 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/template/aws-load-balancer-controller-iam.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: aws-load-balancer-controller-iam 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 2m0s 10 | path: ./tools-config/aws-load-balancer-controller-iam 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | healthChecks: 15 | - kind: ServiceAccount 16 | apiVersion: v1 17 | name: aws-load-balancer-controller 18 | namespace: kube-system 19 | postBuild: 20 | substituteFrom: 21 | - kind: ConfigMap 22 | name: cluster-info 23 | optional: false 24 | patches: 25 | - target: 26 | group: iam.aws.crossplane.io 27 | kind: Role 28 | version: v1beta1 29 | name: aws-load-balancer-controller-role 30 | namespace: kube-system 31 | patch: |- 32 | - op: replace 33 | path: /metadata/name 34 | value: aws-load-balancer-controller-role-cluster-name 35 | - target: 36 | group: iam.aws.crossplane.io 37 | kind: Policy 38 | version: v1beta1 39 | name: aws-load-balancer-controller-policy 40 | namespace: kube-system 41 | patch: |- 42 | - op: replace 43 | path: /metadata/name 44 | value: aws-load-balancer-controller-policy-cluster-name 45 | - op: replace 46 | path: /spec/forProvider/name 47 | value: aws-load-balancer-controller-policy-cluster-name 48 | - target: 49 | group: iam.aws.crossplane.io 50 | kind: RolePolicyAttachment 51 | version: v1beta1 52 | name: aws-load-balancer-controller-attachment 53 | namespace: kube-system 54 | patch: |- 55 | - op: replace 56 | path: /metadata/name 57 | value: aws-load-balancer-controller-attachment-cluster-name 58 | - op: replace 59 | path: /spec/forProvider/policyArnRef/name 60 | value: aws-load-balancer-controller-policy-cluster-name 61 | - op: replace 62 | path: /spec/forProvider/roleNameRef/name 63 | value: aws-load-balancer-controller-role-cluster-name 64 | - target: 65 | group: "" 66 | kind: ServiceAccount 67 | version: v1 68 | name: aws-load-balancer-controller 69 | namespace: kube-system 70 | patch: |- 71 | - op: replace 72 | path: /metadata/annotations 73 | value: 74 | eks.amazonaws.com/role-arn: arn:aws:iam::${ACCOUNT_ID}:role/aws-load-balancer-controller-role-cluster-name 75 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/template/aws-load-balancer-controller.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: aws-load-balancer-controller 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 10m0s 10 | path: ./tools/aws-load-balancer-controller 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | dependsOn: 15 | - name: aws-load-balancer-controller-iam 16 | patches: 17 | - target: 18 | group: helm.toolkit.fluxcd.io 19 | kind: HelmRelease 20 | name: aws-load-balancer-controller 21 | namespace: flux-system 22 | patch: |- 23 | - op: add 24 | path: /spec/values/clusterName 25 | value: cluster-name 26 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/template/crossplane.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: crossplane 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 3m0s 10 | path: ./tools/crossplane 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | patches: 15 | - target: 16 | group: kustomize.toolkit.fluxcd.io 17 | kind: Kustomization 18 | version: v1beta2 19 | name: crossplane-aws-provider 20 | namespace: flux-system 21 | patch: |- 22 | - op: add 23 | path: /spec/patches 24 | value: 25 | - target: 26 | group: pkg.crossplane.io 27 | kind: ControllerConfig 28 | version: v1alpha1 29 | name: aws-config 30 | patch: |- 31 | - op: replace 32 | path: /metadata/annotations 33 | value: 34 | eks.amazonaws.com/role-arn: arn:aws:iam::${ACCOUNT_ID}:role/crossplane-role-cluster-name 35 | - op: add 36 | path: /spec/postBuild 37 | value: 38 | substituteFrom: 39 | - kind: ConfigMap 40 | name: cluster-info 41 | optional: false 42 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/template/flux-system/gotk-sync.yaml: -------------------------------------------------------------------------------- 1 | # This manifest was generated by flux. DO NOT EDIT. 2 | --- 3 | apiVersion: source.toolkit.fluxcd.io/v1beta2 4 | kind: GitRepository 5 | metadata: 6 | name: flux-system 7 | namespace: flux-system 8 | spec: 9 | interval: 1m0s 10 | ref: 11 | branch: main 12 | secretRef: 13 | name: flux-system 14 | url: REPO_PREFIX/gitops-system 15 | --- 16 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 17 | kind: Kustomization 18 | metadata: 19 | name: flux-system 20 | namespace: flux-system 21 | spec: 22 | interval: 1m0s 23 | path: ./clusters/cluster-name 24 | prune: true 25 | sourceRef: 26 | kind: GitRepository 27 | name: flux-system 28 | -------------------------------------------------------------------------------- /repos/gitops-system/clusters/template/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 | -------------------------------------------------------------------------------- /repos/gitops-system/clusters/template/karpenter-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: karpenter-config 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 2m0s 10 | path: ./tools-config/karpenter-config 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | postBuild: 15 | substituteFrom: 16 | - kind: ConfigMap 17 | name: cluster-info 18 | optional: false 19 | dependsOn: 20 | - name: karpenter 21 | patches: 22 | - target: 23 | group: karpenter.k8s.aws 24 | kind: EC2NodeClass 25 | name: default 26 | patch: |- 27 | apiVersion: karpenter.k8s.aws/v1beta1 28 | kind: EC2NodeClass 29 | metadata: 30 | name: not-used 31 | spec: 32 | role: karpenter-node-role-cluster-name 33 | subnetSelectorTerms: 34 | - tags: 35 | Name: "cluster-name-eks-vpc-private*" 36 | - target: 37 | group: iam.aws.crossplane.io 38 | kind: Role 39 | version: v1beta1 40 | name: karpenter-node-role 41 | patch: |- 42 | - op: replace 43 | path: /metadata/name 44 | value: karpenter-node-role-cluster-name 45 | - target: 46 | group: iam.aws.crossplane.io 47 | kind: RolePolicyAttachment 48 | version: v1beta1 49 | name: karpenter-node-role-cni-attachment 50 | patch: |- 51 | - op: replace 52 | path: /metadata/name 53 | value: karpenter-node-role-cni-attachment-cluster-name 54 | - op: replace 55 | path: /spec/forProvider/roleNameRef/name 56 | value: karpenter-node-role-cluster-name 57 | - target: 58 | group: iam.aws.crossplane.io 59 | kind: RolePolicyAttachment 60 | version: v1beta1 61 | name: karpenter-node-role-wn-policy-attachment 62 | patch: |- 63 | - op: replace 64 | path: /metadata/name 65 | value: karpenter-node-role-wn-policy-attachment-cluster-name 66 | - op: replace 67 | path: /spec/forProvider/roleNameRef/name 68 | value: karpenter-node-role-cluster-name 69 | - target: 70 | group: iam.aws.crossplane.io 71 | kind: RolePolicyAttachment 72 | version: v1beta1 73 | name: karpenter-node-role-ecr-attachment 74 | patch: |- 75 | - op: replace 76 | path: /metadata/name 77 | value: karpenter-node-role-ecr-attachment-cluster-name 78 | - op: replace 79 | path: /spec/forProvider/roleNameRef/name 80 | value: karpenter-node-role-cluster-name 81 | - target: 82 | group: iam.aws.crossplane.io 83 | kind: RolePolicyAttachment 84 | version: v1beta1 85 | name: karpenter-node-role-ssm-attachment 86 | patch: |- 87 | - op: replace 88 | path: /metadata/name 89 | value: karpenter-node-role-ssm-attachment-cluster-name 90 | - op: replace 91 | path: /spec/forProvider/roleNameRef/name 92 | value: karpenter-node-role-cluster-name 93 | 94 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/template/karpenter-iam.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: karpenter-iam 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 2m0s 10 | path: ./tools-config/karpenter-iam 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | healthChecks: 15 | - kind: ServiceAccount 16 | apiVersion: v1 17 | name: karpenter-sa 18 | namespace: kube-system 19 | patches: 20 | - target: 21 | group: iam.aws.crossplane.io 22 | kind: Role 23 | version: v1beta1 24 | name: karpenter-role 25 | patch: |- 26 | - op: replace 27 | path: /metadata/name 28 | value: karpenter-role-cluster-name 29 | - target: 30 | group: iam.aws.crossplane.io 31 | kind: RolePolicyAttachment 32 | version: v1beta1 33 | name: karpenter-attachment 34 | patch: |- 35 | - op: replace 36 | path: /metadata/name 37 | value: karpenter-attachment-cluster-name 38 | - op: replace 39 | path: /spec/forProvider/policyArnRef/name 40 | value: karpenter-policy-cluster-name 41 | - op: replace 42 | path: /spec/forProvider/roleNameRef/name 43 | value: karpenter-role-cluster-name 44 | - target: 45 | group: iam.aws.crossplane.io 46 | kind: Policy 47 | version: v1beta1 48 | name: karpenter-policy 49 | patch: |- 50 | - op: replace 51 | path: /metadata/name 52 | value: karpenter-policy-cluster-name 53 | - op: replace 54 | path: /spec/forProvider/name 55 | value: karpenter-policy-cluster-name 56 | - target: 57 | group: "" 58 | kind: ServiceAccount 59 | version: v1 60 | name: karpenter-sa 61 | namespace: kube-system 62 | patch: |- 63 | - op: replace 64 | path: /metadata/annotations 65 | value: 66 | eks.amazonaws.com/role-arn: arn:aws:iam::${ACCOUNT_ID}:role/karpenter-role-cluster-name 67 | postBuild: 68 | substituteFrom: 69 | - kind: ConfigMap 70 | name: cluster-info 71 | optional: false 72 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/template/karpenter.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: karpenter 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 10m0s 10 | path: ./tools/karpenter 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | healthChecks: 15 | - apiVersion: apps/v1 16 | kind: Deployment 17 | name: karpenter 18 | namespace: kube-system 19 | postBuild: 20 | substituteFrom: 21 | - kind: ConfigMap 22 | name: cluster-info 23 | optional: false 24 | dependsOn: 25 | - name: karpenter-iam 26 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/template/kubecost.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: kubecost 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 10m0s 10 | path: ./tools/kubecost 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | --- -------------------------------------------------------------------------------- /repos/gitops-system/clusters/template/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - ./flux-system 5 | - aws-auth.yaml 6 | - crossplane.yaml 7 | - karpenter-iam.yaml 8 | - karpenter.yaml 9 | - karpenter-config.yaml 10 | - kubecost.yaml 11 | - aws-ebs-csi-iam.yaml 12 | - aws-ebs-csi.yaml 13 | - aws-load-balancer-controller-iam.yaml 14 | - aws-load-balancer-controller.yaml 15 | - workloads.yaml 16 | -------------------------------------------------------------------------------- /repos/gitops-system/clusters/template/workloads.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: workloads-initialization 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | dependsOn: 10 | - name: crossplane 11 | interval: 2m0s 12 | path: ./workloads/cluster-name 13 | sourceRef: 14 | kind: GitRepository 15 | name: flux-system 16 | postBuild: 17 | substituteFrom: 18 | - kind: ConfigMap 19 | name: cluster-info 20 | optional: false 21 | --- -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/aws-auth/aws-auth-cm.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: aws-auth 5 | namespace: kube-system 6 | data: 7 | mapRoles: | 8 | - groups: 9 | - system:bootstrappers 10 | - system:nodes 11 | rolearn: arn:aws:iam::${ACCOUNT_ID}:role/eks-nodegroup-role 12 | username: system:node:{{EC2PrivateDNSName}} 13 | - rolearn: EKS_CONSOLE_IAM_ENTITY_ARN 14 | username: EKS_CONSOLE_IAM_ENTITY_ARN 15 | mapUsers: | 16 | [] 17 | -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/aws-auth/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - aws-auth-cm.yaml 6 | - role.yaml 7 | - role-binding.yaml 8 | -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/aws-auth/role-binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: eks-console-dashboard-full-access-clusterrole-binding 5 | subjects: 6 | - kind: User 7 | name: EKS_CONSOLE_IAM_ENTITY_ARN 8 | apiGroup: rbac.authorization.k8s.io 9 | roleRef: 10 | kind: ClusterRole 11 | name: eks-console-dashboard-full-access-clusterrole 12 | apiGroup: rbac.authorization.k8s.io -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/aws-auth/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: eks-console-dashboard-full-access-clusterrole 5 | rules: 6 | - apiGroups: 7 | - "" 8 | resources: 9 | - nodes 10 | - namespaces 11 | - pods 12 | - configmaps 13 | - endpoints 14 | - events 15 | - limitranges 16 | - persistentvolumeclaims 17 | - podtemplates 18 | - replicationcontrollers 19 | - resourcequotas 20 | - secrets 21 | - serviceaccounts 22 | - services 23 | verbs: 24 | - get 25 | - list 26 | - apiGroups: 27 | - apps 28 | resources: 29 | - deployments 30 | - daemonsets 31 | - statefulsets 32 | - replicasets 33 | verbs: 34 | - get 35 | - list 36 | - apiGroups: 37 | - batch 38 | resources: 39 | - jobs 40 | - cronjobs 41 | verbs: 42 | - get 43 | - list 44 | - apiGroups: 45 | - coordination.k8s.io 46 | resources: 47 | - leases 48 | verbs: 49 | - get 50 | - list 51 | - apiGroups: 52 | - discovery.k8s.io 53 | resources: 54 | - endpointslices 55 | verbs: 56 | - get 57 | - list 58 | - apiGroups: 59 | - events.k8s.io 60 | resources: 61 | - events 62 | verbs: 63 | - get 64 | - list 65 | - apiGroups: 66 | - extensions 67 | resources: 68 | - daemonsets 69 | - deployments 70 | - ingresses 71 | - networkpolicies 72 | - replicasets 73 | verbs: 74 | - get 75 | - list 76 | - apiGroups: 77 | - networking.k8s.io 78 | resources: 79 | - ingresses 80 | - networkpolicies 81 | verbs: 82 | - get 83 | - list 84 | - apiGroups: 85 | - policy 86 | resources: 87 | - poddisruptionbudgets 88 | verbs: 89 | - get 90 | - list 91 | - apiGroups: 92 | - rbac.authorization.k8s.io 93 | resources: 94 | - rolebindings 95 | - roles 96 | verbs: 97 | - get 98 | - list 99 | - apiGroups: 100 | - storage.k8s.io 101 | resources: 102 | - csistoragecapacities 103 | verbs: 104 | - get 105 | - list -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/aws-ebs-csi-iam/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - role.yaml 6 | - sa.yaml -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/aws-ebs-csi-iam/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: iam.aws.crossplane.io/v1beta1 2 | kind: Role 3 | metadata: 4 | name: ebs-csi-controller-role 5 | namespace: kube-system 6 | spec: 7 | forProvider: 8 | assumeRolePolicyDocument: | 9 | { 10 | "Version": "2012-10-17", 11 | "Statement": [ 12 | { 13 | "Effect": "Allow", 14 | "Principal": { 15 | "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}" 16 | }, 17 | "Action": "sts:AssumeRoleWithWebIdentity", 18 | "Condition": { 19 | "StringEquals": { 20 | "${OIDC_PROVIDER}:aud": "sts.amazonaws.com", 21 | "${OIDC_PROVIDER}:sub": "system:serviceaccount:kube-system:ebs-csi-controller-sa" 22 | } 23 | } 24 | } 25 | ] 26 | } 27 | --- 28 | apiVersion: iam.aws.crossplane.io/v1beta1 29 | kind: RolePolicyAttachment 30 | metadata: 31 | name: ebs-csi-controller-attachment 32 | namespace: kube-system 33 | spec: 34 | forProvider: 35 | policyArn: "arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy" 36 | roleNameRef: 37 | name: ebs-csi-controller-role -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/aws-ebs-csi-iam/sa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: ebs-csi-controller-sa 5 | namespace: kube-system 6 | annotations: 7 | eks.amazonaws.com/role-arn: arn:aws:iam::${ACCOUNT_ID}:role/ebs-csi-controller-sa -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/aws-load-balancer-controller-iam/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - policy.yaml 6 | - role.yaml 7 | - sa.yaml -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/aws-load-balancer-controller-iam/policy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: iam.aws.crossplane.io/v1beta1 2 | kind: Policy 3 | metadata: 4 | name: aws-load-balancer-controller-policy 5 | namespace: kube-system 6 | spec: 7 | forProvider: 8 | name: AWSLoadBalancerControllerIAMPolicy 9 | document: | 10 | { 11 | "Version": "2012-10-17", 12 | "Statement": [ 13 | { 14 | "Effect": "Allow", 15 | "Action": [ 16 | "iam:CreateServiceLinkedRole" 17 | ], 18 | "Resource": "*", 19 | "Condition": { 20 | "StringEquals": { 21 | "iam:AWSServiceName": "elasticloadbalancing.amazonaws.com" 22 | } 23 | } 24 | }, 25 | { 26 | "Effect": "Allow", 27 | "Action": [ 28 | "ec2:DescribeAccountAttributes", 29 | "ec2:DescribeAddresses", 30 | "ec2:DescribeAvailabilityZones", 31 | "ec2:DescribeInternetGateways", 32 | "ec2:DescribeVpcs", 33 | "ec2:DescribeVpcPeeringConnections", 34 | "ec2:DescribeSubnets", 35 | "ec2:DescribeSecurityGroups", 36 | "ec2:DescribeInstances", 37 | "ec2:DescribeNetworkInterfaces", 38 | "ec2:DescribeTags", 39 | "ec2:GetCoipPoolUsage", 40 | "ec2:DescribeCoipPools", 41 | "elasticloadbalancing:DescribeLoadBalancers", 42 | "elasticloadbalancing:DescribeLoadBalancerAttributes", 43 | "elasticloadbalancing:DescribeListeners", 44 | "elasticloadbalancing:DescribeListenerCertificates", 45 | "elasticloadbalancing:DescribeSSLPolicies", 46 | "elasticloadbalancing:DescribeRules", 47 | "elasticloadbalancing:DescribeTargetGroups", 48 | "elasticloadbalancing:DescribeTargetGroupAttributes", 49 | "elasticloadbalancing:DescribeTargetHealth", 50 | "elasticloadbalancing:DescribeTags" 51 | ], 52 | "Resource": "*" 53 | }, 54 | { 55 | "Effect": "Allow", 56 | "Action": [ 57 | "cognito-idp:DescribeUserPoolClient", 58 | "acm:ListCertificates", 59 | "acm:DescribeCertificate", 60 | "iam:ListServerCertificates", 61 | "iam:GetServerCertificate", 62 | "waf-regional:GetWebACL", 63 | "waf-regional:GetWebACLForResource", 64 | "waf-regional:AssociateWebACL", 65 | "waf-regional:DisassociateWebACL", 66 | "wafv2:GetWebACL", 67 | "wafv2:GetWebACLForResource", 68 | "wafv2:AssociateWebACL", 69 | "wafv2:DisassociateWebACL", 70 | "shield:GetSubscriptionState", 71 | "shield:DescribeProtection", 72 | "shield:CreateProtection", 73 | "shield:DeleteProtection" 74 | ], 75 | "Resource": "*" 76 | }, 77 | { 78 | "Effect": "Allow", 79 | "Action": [ 80 | "ec2:AuthorizeSecurityGroupIngress", 81 | "ec2:RevokeSecurityGroupIngress" 82 | ], 83 | "Resource": "*" 84 | }, 85 | { 86 | "Effect": "Allow", 87 | "Action": [ 88 | "ec2:CreateSecurityGroup" 89 | ], 90 | "Resource": "*" 91 | }, 92 | { 93 | "Effect": "Allow", 94 | "Action": [ 95 | "ec2:CreateTags" 96 | ], 97 | "Resource": "arn:aws:ec2:*:*:security-group/*", 98 | "Condition": { 99 | "StringEquals": { 100 | "ec2:CreateAction": "CreateSecurityGroup" 101 | }, 102 | "Null": { 103 | "aws:RequestTag/elbv2.k8s.aws/cluster": "false" 104 | } 105 | } 106 | }, 107 | { 108 | "Effect": "Allow", 109 | "Action": [ 110 | "ec2:CreateTags", 111 | "ec2:DeleteTags" 112 | ], 113 | "Resource": "arn:aws:ec2:*:*:security-group/*", 114 | "Condition": { 115 | "Null": { 116 | "aws:RequestTag/elbv2.k8s.aws/cluster": "true", 117 | "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" 118 | } 119 | } 120 | }, 121 | { 122 | "Effect": "Allow", 123 | "Action": [ 124 | "ec2:AuthorizeSecurityGroupIngress", 125 | "ec2:RevokeSecurityGroupIngress", 126 | "ec2:DeleteSecurityGroup" 127 | ], 128 | "Resource": "*", 129 | "Condition": { 130 | "Null": { 131 | "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" 132 | } 133 | } 134 | }, 135 | { 136 | "Effect": "Allow", 137 | "Action": [ 138 | "elasticloadbalancing:CreateLoadBalancer", 139 | "elasticloadbalancing:CreateTargetGroup" 140 | ], 141 | "Resource": "*", 142 | "Condition": { 143 | "Null": { 144 | "aws:RequestTag/elbv2.k8s.aws/cluster": "false" 145 | } 146 | } 147 | }, 148 | { 149 | "Effect": "Allow", 150 | "Action": [ 151 | "elasticloadbalancing:CreateListener", 152 | "elasticloadbalancing:DeleteListener", 153 | "elasticloadbalancing:CreateRule", 154 | "elasticloadbalancing:DeleteRule" 155 | ], 156 | "Resource": "*" 157 | }, 158 | { 159 | "Effect": "Allow", 160 | "Action": [ 161 | "elasticloadbalancing:AddTags", 162 | "elasticloadbalancing:RemoveTags" 163 | ], 164 | "Resource": [ 165 | "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*", 166 | "arn:aws:elasticloadbalancing:*:*:loadbalancer/net/*/*", 167 | "arn:aws:elasticloadbalancing:*:*:loadbalancer/app/*/*" 168 | ], 169 | "Condition": { 170 | "Null": { 171 | "aws:RequestTag/elbv2.k8s.aws/cluster": "true", 172 | "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" 173 | } 174 | } 175 | }, 176 | { 177 | "Effect": "Allow", 178 | "Action": [ 179 | "elasticloadbalancing:AddTags", 180 | "elasticloadbalancing:RemoveTags" 181 | ], 182 | "Resource": [ 183 | "arn:aws:elasticloadbalancing:*:*:listener/net/*/*/*", 184 | "arn:aws:elasticloadbalancing:*:*:listener/app/*/*/*", 185 | "arn:aws:elasticloadbalancing:*:*:listener-rule/net/*/*/*", 186 | "arn:aws:elasticloadbalancing:*:*:listener-rule/app/*/*/*" 187 | ] 188 | }, 189 | { 190 | "Effect": "Allow", 191 | "Action": [ 192 | "elasticloadbalancing:ModifyLoadBalancerAttributes", 193 | "elasticloadbalancing:SetIpAddressType", 194 | "elasticloadbalancing:SetSecurityGroups", 195 | "elasticloadbalancing:SetSubnets", 196 | "elasticloadbalancing:DeleteLoadBalancer", 197 | "elasticloadbalancing:ModifyTargetGroup", 198 | "elasticloadbalancing:ModifyTargetGroupAttributes", 199 | "elasticloadbalancing:DeleteTargetGroup" 200 | ], 201 | "Resource": "*", 202 | "Condition": { 203 | "Null": { 204 | "aws:ResourceTag/elbv2.k8s.aws/cluster": "false" 205 | } 206 | } 207 | }, 208 | { 209 | "Effect": "Allow", 210 | "Action": [ 211 | "elasticloadbalancing:RegisterTargets", 212 | "elasticloadbalancing:DeregisterTargets" 213 | ], 214 | "Resource": "arn:aws:elasticloadbalancing:*:*:targetgroup/*/*" 215 | }, 216 | { 217 | "Effect": "Allow", 218 | "Action": [ 219 | "elasticloadbalancing:SetWebAcl", 220 | "elasticloadbalancing:ModifyListener", 221 | "elasticloadbalancing:AddListenerCertificates", 222 | "elasticloadbalancing:RemoveListenerCertificates", 223 | "elasticloadbalancing:ModifyRule" 224 | ], 225 | "Resource": "*" 226 | } 227 | ] 228 | } 229 | -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/aws-load-balancer-controller-iam/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: iam.aws.crossplane.io/v1beta1 2 | kind: Role 3 | metadata: 4 | name: aws-load-balancer-controller-role 5 | namespace: kube-system 6 | spec: 7 | forProvider: 8 | assumeRolePolicyDocument: | 9 | { 10 | "Version": "2012-10-17", 11 | "Statement": [ 12 | { 13 | "Effect": "Allow", 14 | "Principal": { 15 | "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}" 16 | }, 17 | "Action": "sts:AssumeRoleWithWebIdentity", 18 | "Condition": { 19 | "StringEquals": { 20 | "${OIDC_PROVIDER}:aud": "sts.amazonaws.com", 21 | "${OIDC_PROVIDER}:sub": "system:serviceaccount:kube-system:aws-load-balancer-controller" 22 | } 23 | } 24 | } 25 | ] 26 | } 27 | --- 28 | apiVersion: iam.aws.crossplane.io/v1beta1 29 | kind: RolePolicyAttachment 30 | metadata: 31 | name: aws-load-balancer-controller-attachment 32 | namespace: kube-system 33 | spec: 34 | forProvider: 35 | policyArnRef: 36 | name: aws-load-balancer-controller-policy 37 | roleNameRef: 38 | name: aws-load-balancer-controller -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/aws-load-balancer-controller-iam/sa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: aws-load-balancer-controller 5 | namespace: kube-system 6 | annotations: 7 | eks.amazonaws.com/role-arn: arn:aws:iam::${ACCOUNT_ID}:role/aws-load-balancer-controller -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/crossplane-eks-composition/compositeresourcedefinition.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apiextensions.crossplane.io/v1 3 | kind: CompositeResourceDefinition 4 | metadata: 5 | name: eksclusters.gitops.k8s.aws 6 | spec: 7 | group: gitops.k8s.aws 8 | names: 9 | kind: EKSCluster 10 | plural: eksclusters 11 | connectionSecretKeys: 12 | - cluster-ca 13 | - apiserver-endpoint 14 | - value 15 | versions: 16 | - name: v1beta1 17 | served: true 18 | referenceable: true 19 | schema: 20 | openAPIV3Schema: 21 | type: object 22 | properties: 23 | spec: 24 | type: object 25 | properties: 26 | parameters: 27 | type: object 28 | properties: 29 | region: 30 | description: Geographic location of this VPC 31 | type: string 32 | 33 | vpc-cidrBlock: 34 | description: CIDR block for VPC 35 | type: string 36 | vpc-name: 37 | description: Name for VPC 38 | type: string 39 | 40 | subnet1-public-name: 41 | description: Name for public subnet 1 42 | type: string 43 | subnet1-public-cidrBlock: 44 | description: CIDR block for public subnet 1 45 | type: string 46 | subnet1-public-availabilityZone: 47 | description: AZ for public subnet 1 48 | type: string 49 | 50 | subnet2-public-name: 51 | description: Name for public subnet 2 52 | type: string 53 | subnet2-public-cidrBlock: 54 | description: CIDR block for public subnet 2 55 | type: string 56 | subnet2-public-availabilityZone: 57 | description: AZ for public subnet 2 58 | type: string 59 | 60 | subnet1-private-name: 61 | description: Name for private subnet 1 62 | type: string 63 | subnet1-private-cidrBlock: 64 | description: CIDR block for private subnet 1 65 | type: string 66 | subnet1-private-availabilityZone: 67 | description: AZ for private subnet 1 68 | type: string 69 | 70 | subnet2-private-name: 71 | description: Name for private subnet 2 72 | type: string 73 | subnet2-private-cidrBlock: 74 | description: CIDR block for private subnet 2 75 | type: string 76 | subnet2-private-availabilityZone: 77 | description: AZ for private subnet 2 78 | type: string 79 | eks-k8s-version: 80 | description: Kubernetes version 81 | type: string 82 | mng-k8s-version: 83 | description: Kubernetes version 84 | type: string 85 | workers-size: 86 | description: Desired number of worker nodes in the cluster 87 | type: integer 88 | workload-type: 89 | description: Type of workloads to be run on this cluster (GPU or non-GPU)" 90 | type: string 91 | enum: ['gpu', 'non-gpu'] 92 | 93 | required: 94 | - region 95 | - vpc-name 96 | - vpc-cidrBlock 97 | - subnet1-public-name 98 | - subnet1-public-cidrBlock 99 | - subnet1-public-availabilityZone 100 | - subnet2-public-name 101 | - subnet2-public-cidrBlock 102 | - subnet2-public-availabilityZone 103 | - subnet1-private-name 104 | - subnet1-private-cidrBlock 105 | - subnet1-private-availabilityZone 106 | - subnet2-private-name 107 | - subnet2-private-cidrBlock 108 | - subnet2-private-availabilityZone 109 | - eks-k8s-version 110 | - mng-k8s-version 111 | - workers-size 112 | - workload-type 113 | required: 114 | - parameters 115 | status: 116 | description: A Status represents the observed state 117 | properties: 118 | account_id: 119 | description: Account ID 120 | type: string 121 | eks_cluster_arn: 122 | description: ARN of the EKS cluster 123 | type: string 124 | eks_cluster_name: 125 | description: EKS cluster name 126 | type: string 127 | eks_cluster_name_psuedo: 128 | description: EKS cluster name without the random suffix 129 | type: string 130 | eks_cluster_oidc_issuer_url: 131 | description: OIDC issuer url for the EKS cluster 132 | type: string 133 | eks_cluster_oidc_issuer: 134 | description: OIDC issuer for the EKS cluster 135 | type: string 136 | type: object 137 | -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/crossplane-eks-composition/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - compositeresourcedefinition.yaml 6 | - composition.yaml 7 | - roles.yaml 8 | -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/crossplane-eks-composition/roles.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: iam.aws.crossplane.io/v1beta1 3 | kind: Role 4 | metadata: 5 | name: eks-cluster-role 6 | labels: 7 | type: eks-cluster-role 8 | spec: 9 | forProvider: 10 | assumeRolePolicyDocument: | 11 | { 12 | "Version": "2012-10-17", 13 | "Statement": [ 14 | { 15 | "Effect": "Allow", 16 | "Principal": { 17 | "Service": "eks.amazonaws.com" 18 | }, 19 | "Action": "sts:AssumeRole" 20 | } 21 | ] 22 | } 23 | providerConfigRef: 24 | name: default 25 | --- 26 | apiVersion: iam.aws.crossplane.io/v1beta1 27 | kind: RolePolicyAttachment 28 | metadata: 29 | name: eks-cluster-role-amazoneksclusterpolicy 30 | spec: 31 | forProvider: 32 | policyArn: arn:aws:iam::aws:policy/AmazonEKSClusterPolicy 33 | roleNameRef: 34 | name: eks-cluster-role 35 | providerConfigRef: 36 | name: default 37 | --- 38 | apiVersion: iam.aws.crossplane.io/v1beta1 39 | kind: Role 40 | metadata: 41 | name: eks-nodegroup-role 42 | labels: 43 | type: eks-nodegroup-role 44 | spec: 45 | forProvider: 46 | assumeRolePolicyDocument: | 47 | { 48 | "Version": "2012-10-17", 49 | "Statement": [ 50 | { 51 | "Effect": "Allow", 52 | "Principal": { 53 | "Service": "ec2.amazonaws.com" 54 | }, 55 | "Action": "sts:AssumeRole" 56 | } 57 | ] 58 | } 59 | providerConfigRef: 60 | name: default 61 | --- 62 | apiVersion: iam.aws.crossplane.io/v1beta1 63 | kind: RolePolicyAttachment 64 | metadata: 65 | name: eks-nodegroup-role-amazoneksworkernodepolicy 66 | spec: 67 | forProvider: 68 | policyArn: arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy 69 | roleNameRef: 70 | name: eks-nodegroup-role 71 | providerConfigRef: 72 | name: default 73 | --- 74 | apiVersion: iam.aws.crossplane.io/v1beta1 75 | kind: RolePolicyAttachment 76 | metadata: 77 | name: eks-nodegroup-role-amazonec2containerregistryreadonly 78 | spec: 79 | forProvider: 80 | policyArn: arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly 81 | roleNameRef: 82 | name: eks-nodegroup-role 83 | providerConfigRef: 84 | name: default 85 | --- 86 | apiVersion: iam.aws.crossplane.io/v1beta1 87 | kind: RolePolicyAttachment 88 | metadata: 89 | name: eks-nodegroup-role-amazonssmmanagedinstancecore 90 | spec: 91 | forProvider: 92 | policyArn: arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore 93 | roleNameRef: 94 | name: eks-nodegroup-role 95 | providerConfigRef: 96 | name: default 97 | --- 98 | apiVersion: iam.aws.crossplane.io/v1beta1 99 | kind: RolePolicyAttachment 100 | metadata: 101 | name: eks-nodegroup-role-amazoneks-cni-policy 102 | spec: 103 | forProvider: 104 | policyArn: arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy 105 | roleNameRef: 106 | name: eks-nodegroup-role 107 | providerConfigRef: 108 | name: default 109 | --- -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/crossplane-iam/crossplane-iam.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: iam.aws.crossplane.io/v1beta1 3 | kind: Role 4 | metadata: 5 | name: crossplane-role 6 | spec: 7 | forProvider: 8 | assumeRolePolicyDocument: | 9 | { 10 | "Version": "2012-10-17", 11 | "Statement": [ 12 | { 13 | "Effect": "Allow", 14 | "Principal": { 15 | "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}" 16 | }, 17 | "Action": "sts:AssumeRoleWithWebIdentity", 18 | "Condition": { 19 | "StringEquals": { 20 | "${OIDC_PROVIDER}:aud": "sts.amazonaws.com" 21 | }, 22 | "StringLike": { 23 | "${OIDC_PROVIDER}:sub": "system:serviceaccount:crossplane-system:provider-aws-*" 24 | } 25 | } 26 | } 27 | ] 28 | } 29 | providerConfigRef: 30 | name: default 31 | --- 32 | apiVersion: iam.aws.crossplane.io/v1beta1 33 | kind: RolePolicyAttachment 34 | metadata: 35 | name: crossplane-rolepolicyattachment 36 | spec: 37 | forProvider: 38 | policyArnRef: 39 | name: crossplane-iam-policy 40 | roleNameRef: 41 | name: crossplane-role 42 | providerConfigRef: 43 | name: default 44 | --- 45 | apiVersion: iam.aws.crossplane.io/v1beta1 46 | kind: Policy 47 | metadata: 48 | name: crossplane-policy 49 | spec: 50 | forProvider: 51 | name: crossplane-policy 52 | document: | 53 | { 54 | "Version": "2012-10-17", 55 | "Statement": [ 56 | { 57 | "Sid": "Stmt1658116958078", 58 | "Action": [ 59 | "iam:AttachRolePolicy", 60 | "iam:CreatePolicy", 61 | "iam:CreatePolicyVersion", 62 | "iam:CreateRole", 63 | "iam:DeletePolicy", 64 | "iam:DeletePolicyVersion", 65 | "iam:DeleteRole", 66 | "iam:DeleteRolePermissionsBoundary", 67 | "iam:DeleteRolePolicy", 68 | "iam:DetachRolePolicy", 69 | "iam:GetPolicy", 70 | "iam:GetPolicyVersion", 71 | "iam:GetRole", 72 | "iam:GetRolePolicy", 73 | "iam:GetUserPolicy", 74 | "iam:ListAttachedRolePolicies", 75 | "iam:ListPolicies", 76 | "iam:ListPolicyTags", 77 | "iam:ListPolicyVersions", 78 | "iam:ListRolePolicies", 79 | "iam:ListRoleTags", 80 | "iam:PutRolePermissionsBoundary", 81 | "iam:PutRolePolicy", 82 | "iam:TagPolicy", 83 | "iam:TagRole", 84 | "iam:UntagPolicy", 85 | "iam:UntagRole", 86 | "iam:UpdateRole", 87 | "iam:UpdateRoleDescription" 88 | ], 89 | "Effect": "Allow", 90 | "Resource": "*" 91 | }, 92 | { 93 | "Sid": "Stmt1658117635374", 94 | "Action": [ 95 | "dynamodb:CreateTable", 96 | "dynamodb:DeleteTable", 97 | "dynamodb:DescribeTable", 98 | "dynamodb:TagResource", 99 | "dynamodb:UntagResource", 100 | "dynamodb:UpdateTable" 101 | ], 102 | "Effect": "Allow", 103 | "Resource": "*" 104 | } 105 | ] 106 | } 107 | providerConfigRef: 108 | name: default -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/external-secrets-iam/external-secrets-iam.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: iam.aws.crossplane.io/v1beta1 3 | kind: Role 4 | metadata: 5 | name: external-secrets-role 6 | labels: 7 | type: external-secrets-role 8 | spec: 9 | forProvider: 10 | assumeRolePolicyDocument: | 11 | { 12 | "Version": "2012-10-17", 13 | "Statement": [ 14 | { 15 | "Effect": "Allow", 16 | "Principal": { 17 | "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}" 18 | }, 19 | "Action": "sts:AssumeRoleWithWebIdentity", 20 | "Condition": { 21 | "StringEquals": { 22 | "${OIDC_PROVIDER}:aud": "sts.amazonaws.com", 23 | "${OIDC_PROVIDER}:sub": "system:serviceaccount:sealed-secrets:aws-secrets-manager" 24 | } 25 | } 26 | } 27 | ] 28 | } 29 | providerConfigRef: 30 | name: default 31 | --- 32 | apiVersion: iam.aws.crossplane.io/v1beta1 33 | kind: Policy 34 | metadata: 35 | name: external-secrets-policy 36 | spec: 37 | forProvider: 38 | name: external-secrets-policy 39 | document: | 40 | { 41 | "Version": "2012-10-17", 42 | "Statement": [ 43 | { 44 | "Effect": "Allow", 45 | "Action": [ 46 | "secretsmanager:GetResourcePolicy", 47 | "secretsmanager:GetSecretValue", 48 | "secretsmanager:DescribeSecret", 49 | "secretsmanager:ListSecretVersionIds" 50 | ], 51 | "Resource": [ 52 | "arn:aws:secretsmanager:${AWS_REGION}:${ACCOUNT_ID}:secret:sealed-secrets*" 53 | ] 54 | } 55 | ] 56 | } 57 | providerConfigRef: 58 | name: default 59 | --- 60 | apiVersion: iam.aws.crossplane.io/v1beta1 61 | kind: RolePolicyAttachment 62 | metadata: 63 | name: external-secrets-attachment 64 | spec: 65 | forProvider: 66 | policyArnRef: 67 | name: external-secrets-policy 68 | roleNameRef: 69 | name: external-secrets-role 70 | providerConfigRef: 71 | name: default -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/external-secrets/sealed-secrets-key.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: sealed-secrets 5 | --- 6 | apiVersion: v1 7 | kind: ServiceAccount 8 | metadata: 9 | name: aws-secrets-manager 10 | namespace: sealed-secrets 11 | annotations: 12 | eks.amazonaws.com/role-arn: arn:aws:iam::${ACCOUNT_ID}:role/external-secrets-role 13 | --- 14 | apiVersion: external-secrets.io/v1alpha1 15 | kind: SecretStore 16 | metadata: 17 | name: aws-secrets-manager 18 | namespace: sealed-secrets 19 | spec: 20 | provider: 21 | aws: 22 | service: SecretsManager 23 | region: AWS_REGION 24 | auth: 25 | jwt: 26 | serviceAccountRef: 27 | name: aws-secrets-manager 28 | --- 29 | apiVersion: external-secrets.io/v1alpha1 30 | kind: ExternalSecret 31 | metadata: 32 | name: sealed-secrets 33 | namespace: sealed-secrets 34 | spec: 35 | refreshInterval: 1h 36 | secretStoreRef: 37 | name: aws-secrets-manager 38 | kind: SecretStore 39 | target: 40 | name: sealed-secrets 41 | creationPolicy: Owner 42 | template: 43 | type: kubernetes.io/tls 44 | metadata: 45 | labels: 46 | sealedsecrets.bitnami.com/sealed-secrets-key: active 47 | data: 48 | - secretKey: tls.crt 49 | remoteRef: 50 | key: sealed-secrets 51 | property: crt 52 | - secretKey: tls.key 53 | remoteRef: 54 | key: sealed-secrets 55 | property: key -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/karpenter-config/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - node-pool.yaml 6 | - role.yaml 7 | -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/karpenter-config/node-pool.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: karpenter.sh/v1beta1 2 | kind: NodePool 3 | metadata: 4 | name: default 5 | spec: 6 | template: 7 | spec: 8 | requirements: 9 | - key: kubernetes.io/arch 10 | operator: In 11 | values: ["amd64"] 12 | - key: kubernetes.io/os 13 | operator: In 14 | values: ["linux"] 15 | - key: karpenter.sh/capacity-type 16 | operator: In 17 | values: ["on-demand"] 18 | - key: karpenter.k8s.aws/instance-category 19 | operator: In 20 | values: ["c", "m", "r"] 21 | - key: karpenter.k8s.aws/instance-generation 22 | operator: Gt 23 | values: ["2"] 24 | nodeClassRef: 25 | apiVersion: karpenter.k8s.aws/v1beta1 26 | kind: EC2NodeClass 27 | name: default 28 | limits: 29 | cpu: 1000 30 | disruption: 31 | consolidationPolicy: WhenUnderutilized 32 | expireAfter: 720h # 30 * 24h = 720h 33 | --- 34 | apiVersion: karpenter.k8s.aws/v1beta1 35 | kind: EC2NodeClass 36 | metadata: 37 | name: default 38 | spec: 39 | amiFamily: AL2 # Amazon Linux 2 40 | role: karpenter-node-role 41 | subnetSelectorTerms: 42 | - tags: 43 | Name: "eks-vpc-private*" 44 | securityGroupSelectorTerms: 45 | - tags: 46 | kubernetes.io/cluster/${CLUSTER_NAME}: owned 47 | 48 | -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/karpenter-config/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: iam.aws.crossplane.io/v1beta1 2 | kind: Role 3 | metadata: 4 | name: karpenter-node-role 5 | spec: 6 | forProvider: 7 | assumeRolePolicyDocument: | 8 | { 9 | "Version": "2012-10-17", 10 | "Statement": [ 11 | { 12 | "Effect": "Allow", 13 | "Action": [ 14 | "sts:AssumeRole" 15 | ], 16 | "Principal": { 17 | "Service": [ 18 | "ec2.amazonaws.com" 19 | ] 20 | } 21 | } 22 | ] 23 | } 24 | --- 25 | apiVersion: iam.aws.crossplane.io/v1beta1 26 | kind: RolePolicyAttachment 27 | metadata: 28 | name: karpenter-node-role-cni-attachment 29 | spec: 30 | forProvider: 31 | policyArn: "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" 32 | roleNameRef: 33 | name: karpenter-node-role 34 | --- 35 | apiVersion: iam.aws.crossplane.io/v1beta1 36 | kind: RolePolicyAttachment 37 | metadata: 38 | name: karpenter-node-role-wn-policy-attachment 39 | spec: 40 | forProvider: 41 | policyArn: "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy" 42 | roleNameRef: 43 | name: karpenter-node-role 44 | --- 45 | apiVersion: iam.aws.crossplane.io/v1beta1 46 | kind: RolePolicyAttachment 47 | metadata: 48 | name: karpenter-node-role-ecr-attachment 49 | spec: 50 | forProvider: 51 | policyArn: "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" 52 | roleNameRef: 53 | name: karpenter-node-role 54 | --- 55 | apiVersion: iam.aws.crossplane.io/v1beta1 56 | kind: RolePolicyAttachment 57 | metadata: 58 | name: karpenter-node-role-ssm-attachment 59 | spec: 60 | forProvider: 61 | policyArn: "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" 62 | roleNameRef: 63 | name: karpenter-node-role -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/karpenter-iam/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - role.yaml 6 | - sa.yaml 7 | - policy.yaml -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/karpenter-iam/policy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: iam.aws.crossplane.io/v1beta1 2 | kind: Policy 3 | metadata: 4 | name: karpenter-policy 5 | namespace: kube-system 6 | spec: 7 | forProvider: 8 | name: KarpenterIAMPolicy 9 | document: | 10 | { 11 | "Version": "2012-10-17", 12 | "Statement": [ 13 | { 14 | "Sid": "AllowScopedEC2InstanceAccessActions", 15 | "Effect": "Allow", 16 | "Resource": [ 17 | "arn:aws:ec2:${AWS_REGION}::image/*", 18 | "arn:aws:ec2:${AWS_REGION}::snapshot/*", 19 | "arn:aws:ec2:${AWS_REGION}:*:security-group/*", 20 | "arn:aws:ec2:${AWS_REGION}:*:subnet/*" 21 | ], 22 | "Action": [ 23 | "ec2:RunInstances", 24 | "ec2:CreateFleet" 25 | ] 26 | }, 27 | { 28 | "Sid": "AllowScopedEC2LaunchTemplateAccessActions", 29 | "Effect": "Allow", 30 | "Resource": "arn:aws:ec2:${AWS_REGION}:*:launch-template/*", 31 | "Action": [ 32 | "ec2:RunInstances", 33 | "ec2:CreateFleet" 34 | ], 35 | "Condition": { 36 | "StringEquals": { 37 | "aws:ResourceTag/kubernetes.io/cluster/${CLUSTER_NAME}": "owned" 38 | }, 39 | "StringLike": { 40 | "aws:ResourceTag/karpenter.sh/nodepool": "*" 41 | } 42 | } 43 | }, 44 | { 45 | "Sid": "AllowScopedEC2InstanceActionsWithTags", 46 | "Effect": "Allow", 47 | "Resource": [ 48 | "arn:aws:ec2:${AWS_REGION}:*:fleet/*", 49 | "arn:aws:ec2:${AWS_REGION}:*:instance/*", 50 | "arn:aws:ec2:${AWS_REGION}:*:volume/*", 51 | "arn:aws:ec2:${AWS_REGION}:*:network-interface/*", 52 | "arn:aws:ec2:${AWS_REGION}:*:launch-template/*", 53 | "arn:aws:ec2:${AWS_REGION}:*:spot-instances-request/*" 54 | ], 55 | "Action": [ 56 | "ec2:RunInstances", 57 | "ec2:CreateFleet", 58 | "ec2:CreateLaunchTemplate" 59 | ], 60 | "Condition": { 61 | "StringEquals": { 62 | "aws:RequestTag/kubernetes.io/cluster/${CLUSTER_NAME}": "owned" 63 | }, 64 | "StringLike": { 65 | "aws:RequestTag/karpenter.sh/nodepool": "*" 66 | } 67 | } 68 | }, 69 | { 70 | "Sid": "AllowScopedResourceCreationTagging", 71 | "Effect": "Allow", 72 | "Resource": [ 73 | "arn:aws:ec2:${AWS_REGION}:*:fleet/*", 74 | "arn:aws:ec2:${AWS_REGION}:*:instance/*", 75 | "arn:aws:ec2:${AWS_REGION}:*:volume/*", 76 | "arn:aws:ec2:${AWS_REGION}:*:network-interface/*", 77 | "arn:aws:ec2:${AWS_REGION}:*:launch-template/*", 78 | "arn:aws:ec2:${AWS_REGION}:*:spot-instances-request/*" 79 | ], 80 | "Action": "ec2:CreateTags", 81 | "Condition": { 82 | "StringEquals": { 83 | "aws:RequestTag/kubernetes.io/cluster/${CLUSTER_NAME}": "owned", 84 | "ec2:CreateAction": [ 85 | "RunInstances", 86 | "CreateFleet", 87 | "CreateLaunchTemplate" 88 | ] 89 | }, 90 | "StringLike": { 91 | "aws:RequestTag/karpenter.sh/nodepool": "*" 92 | } 93 | } 94 | }, 95 | { 96 | "Sid": "AllowScopedResourceTagging", 97 | "Effect": "Allow", 98 | "Resource": "arn:aws:ec2:${AWS_REGION}:*:instance/*", 99 | "Action": "ec2:CreateTags", 100 | "Condition": { 101 | "StringEquals": { 102 | "aws:ResourceTag/kubernetes.io/cluster/${CLUSTER_NAME}": "owned" 103 | }, 104 | "StringLike": { 105 | "aws:ResourceTag/karpenter.sh/nodepool": "*" 106 | }, 107 | "ForAllValues:StringEquals": { 108 | "aws:TagKeys": [ 109 | "karpenter.sh/nodeclaim", 110 | "Name" 111 | ] 112 | } 113 | } 114 | }, 115 | { 116 | "Sid": "AllowScopedDeletion", 117 | "Effect": "Allow", 118 | "Resource": [ 119 | "arn:aws:ec2:${AWS_REGION}:*:instance/*", 120 | "arn:aws:ec2:${AWS_REGION}:*:launch-template/*" 121 | ], 122 | "Action": [ 123 | "ec2:TerminateInstances", 124 | "ec2:DeleteLaunchTemplate" 125 | ], 126 | "Condition": { 127 | "StringEquals": { 128 | "aws:ResourceTag/kubernetes.io/cluster/${CLUSTER_NAME}": "owned" 129 | }, 130 | "StringLike": { 131 | "aws:ResourceTag/karpenter.sh/nodepool": "*" 132 | } 133 | } 134 | }, 135 | { 136 | "Sid": "AllowRegionalReadActions", 137 | "Effect": "Allow", 138 | "Resource": "*", 139 | "Action": [ 140 | "ec2:DescribeAvailabilityZones", 141 | "ec2:DescribeImages", 142 | "ec2:DescribeInstances", 143 | "ec2:DescribeInstanceTypeOfferings", 144 | "ec2:DescribeInstanceTypes", 145 | "ec2:DescribeLaunchTemplates", 146 | "ec2:DescribeSecurityGroups", 147 | "ec2:DescribeSpotPriceHistory", 148 | "ec2:DescribeSubnets" 149 | ], 150 | "Condition": { 151 | "StringEquals": { 152 | "aws:RequestedRegion": "${AWS_REGION}" 153 | } 154 | } 155 | }, 156 | { 157 | "Sid": "AllowSSMReadActions", 158 | "Effect": "Allow", 159 | "Resource": "arn:aws:ssm:${AWS_REGION}::parameter/aws/service/*", 160 | "Action": "ssm:GetParameter" 161 | }, 162 | { 163 | "Sid": "AllowPricingReadActions", 164 | "Effect": "Allow", 165 | "Resource": "*", 166 | "Action": "pricing:GetProducts" 167 | }, 168 | { 169 | "Sid": "AllowPassingInstanceRole", 170 | "Effect": "Allow", 171 | "Resource": "arn:aws:iam::${ACCOUNT_ID}:role/karpenter-node*", 172 | "Action": "iam:PassRole", 173 | "Condition": { 174 | "StringEquals": { 175 | "iam:PassedToService": "ec2.amazonaws.com" 176 | } 177 | } 178 | }, 179 | { 180 | "Sid": "AllowScopedInstanceProfileCreationActions", 181 | "Effect": "Allow", 182 | "Resource": "*", 183 | "Action": [ 184 | "iam:CreateInstanceProfile" 185 | ], 186 | "Condition": { 187 | "StringEquals": { 188 | "aws:RequestTag/kubernetes.io/cluster/${CLUSTER_NAME}": "owned", 189 | "aws:RequestTag/topology.kubernetes.io/region": "${AWS_REGION}" 190 | }, 191 | "StringLike": { 192 | "aws:RequestTag/karpenter.k8s.aws/ec2nodeclass": "*" 193 | } 194 | } 195 | }, 196 | { 197 | "Sid": "AllowScopedInstanceProfileTagActions", 198 | "Effect": "Allow", 199 | "Resource": "*", 200 | "Action": [ 201 | "iam:TagInstanceProfile" 202 | ], 203 | "Condition": { 204 | "StringEquals": { 205 | "aws:ResourceTag/kubernetes.io/cluster/${CLUSTER_NAME}": "owned", 206 | "aws:ResourceTag/topology.kubernetes.io/region": "${AWS_REGION}", 207 | "aws:RequestTag/kubernetes.io/cluster/${CLUSTER_NAME}": "owned", 208 | "aws:RequestTag/topology.kubernetes.io/region": "${AWS_REGION}" 209 | }, 210 | "StringLike": { 211 | "aws:ResourceTag/karpenter.k8s.aws/ec2nodeclass": "*", 212 | "aws:RequestTag/karpenter.k8s.aws/ec2nodeclass": "*" 213 | } 214 | } 215 | }, 216 | { 217 | "Sid": "AllowScopedInstanceProfileActions", 218 | "Effect": "Allow", 219 | "Resource": "*", 220 | "Action": [ 221 | "iam:AddRoleToInstanceProfile", 222 | "iam:RemoveRoleFromInstanceProfile", 223 | "iam:DeleteInstanceProfile" 224 | ], 225 | "Condition": { 226 | "StringEquals": { 227 | "aws:ResourceTag/kubernetes.io/cluster/${CLUSTER_NAME}": "owned", 228 | "aws:ResourceTag/topology.kubernetes.io/region": "${AWS_REGION}" 229 | }, 230 | "StringLike": { 231 | "aws:ResourceTag/karpenter.k8s.aws/ec2nodeclass": "*" 232 | } 233 | } 234 | }, 235 | { 236 | "Sid": "AllowInstanceProfileReadActions", 237 | "Effect": "Allow", 238 | "Resource": "*", 239 | "Action": "iam:GetInstanceProfile" 240 | }, 241 | { 242 | "Sid": "AllowAPIServerEndpointDiscovery", 243 | "Effect": "Allow", 244 | "Resource": "arn:aws:eks:${AWS_REGION}:${ACCOUNT_ID}:cluster/${CLUSTER_NAME}", 245 | "Action": "eks:DescribeCluster" 246 | } 247 | ] 248 | } 249 | 250 | -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/karpenter-iam/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: iam.aws.crossplane.io/v1beta1 2 | kind: Role 3 | metadata: 4 | name: karpenter-role 5 | namespace: kube-system 6 | spec: 7 | forProvider: 8 | assumeRolePolicyDocument: | 9 | { 10 | "Version": "2012-10-17", 11 | "Statement": [ 12 | { 13 | "Effect": "Allow", 14 | "Principal": { 15 | "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}" 16 | }, 17 | "Action": "sts:AssumeRoleWithWebIdentity", 18 | "Condition": { 19 | "StringEquals": { 20 | "${OIDC_PROVIDER}:aud": "sts.amazonaws.com", 21 | "${OIDC_PROVIDER}:sub": "system:serviceaccount:kube-system:karpenter-sa" 22 | } 23 | } 24 | } 25 | ] 26 | } 27 | --- 28 | apiVersion: iam.aws.crossplane.io/v1beta1 29 | kind: RolePolicyAttachment 30 | metadata: 31 | name: karpenter-attachment 32 | namespace: kube-system 33 | spec: 34 | forProvider: 35 | policyArnRef: 36 | name: karpenter-policy 37 | roleNameRef: 38 | name: karpenter-role -------------------------------------------------------------------------------- /repos/gitops-system/tools-config/karpenter-iam/sa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: karpenter-sa 5 | namespace: kube-system 6 | annotations: 7 | eks.amazonaws.com/role-arn: arn:aws:iam::${ACCOUNT_ID}:role/karpenter-role -------------------------------------------------------------------------------- /repos/gitops-system/tools/aws-ebs-csi/aws-ebs-csi-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: aws-ebs-csi 5 | namespace: flux-system 6 | spec: 7 | releaseName: aws-ebs-csi-driver 8 | targetNamespace: kube-system 9 | interval: 5m 10 | chart: 11 | spec: 12 | chart: aws-ebs-csi-driver 13 | version: '2.30.0' 14 | sourceRef: 15 | kind: HelmRepository 16 | name: aws-ebs-csi-repository 17 | namespace: flux-system 18 | interval: 1m 19 | values: 20 | controller: 21 | serviceAccount: 22 | create: false 23 | name: ebs-csi-controller-sa -------------------------------------------------------------------------------- /repos/gitops-system/tools/aws-ebs-csi/aws-ebs-csi-repo.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: source.toolkit.fluxcd.io/v1beta2 3 | kind: HelmRepository 4 | metadata: 5 | name: aws-ebs-csi-repository 6 | namespace: flux-system 7 | spec: 8 | interval: 5m 9 | url: https://kubernetes-sigs.github.io/aws-ebs-csi-driver -------------------------------------------------------------------------------- /repos/gitops-system/tools/aws-ebs-csi/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - aws-ebs-csi-repo.yaml 6 | - aws-ebs-csi-release.yaml -------------------------------------------------------------------------------- /repos/gitops-system/tools/aws-load-balancer-controller/aws-lb-controller-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: aws-load-balancer-controller 5 | namespace: flux-system 6 | spec: 7 | releaseName: aws-load-balancer-controller 8 | targetNamespace: kube-system 9 | interval: 5m 10 | chart: 11 | spec: 12 | chart: aws-load-balancer-controller 13 | version: '1.4.6' 14 | sourceRef: 15 | kind: HelmRepository 16 | name: aws-load-balancer-controller-repository 17 | namespace: flux-system 18 | interval: 1m 19 | values: 20 | serviceAccount: 21 | create: false 22 | name: aws-load-balancer-controller -------------------------------------------------------------------------------- /repos/gitops-system/tools/aws-load-balancer-controller/aws-lb-controller-repo.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: source.toolkit.fluxcd.io/v1beta2 3 | kind: HelmRepository 4 | metadata: 5 | name: aws-load-balancer-controller-repository 6 | namespace: flux-system 7 | spec: 8 | interval: 5m 9 | url: https://aws.github.io/eks-charts -------------------------------------------------------------------------------- /repos/gitops-system/tools/aws-load-balancer-controller/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - aws-lb-controller-repo.yaml 6 | - aws-lb-controller-release.yaml -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-aws-provider-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: crossplane-aws-provider-config 6 | namespace: flux-system 7 | spec: 8 | dependsOn: 9 | - name: crossplane-aws-provider 10 | interval: 3m0s 11 | path: ./tools/crossplane/crossplane-aws-provider-config 12 | prune: true 13 | sourceRef: 14 | kind: GitRepository 15 | name: flux-system 16 | healthChecks: 17 | - apiVersion: aws.crossplane.io/v1beta1 18 | kind: ProviderConfig 19 | name: default 20 | timeout: 2m 21 | 22 | -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-aws-provider-config/aws-providerconfig.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: aws.crossplane.io/v1beta1 3 | kind: ProviderConfig 4 | metadata: 5 | name: default 6 | spec: 7 | credentials: 8 | source: InjectedIdentity 9 | -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-aws-provider-config/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - aws-providerconfig.yaml 6 | 7 | 8 | -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-aws-provider.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: crossplane-aws-provider 6 | namespace: flux-system 7 | spec: 8 | dependsOn: 9 | - name: crossplane-core 10 | interval: 3m0s 11 | path: ./tools/crossplane/crossplane-aws-provider 12 | prune: true 13 | sourceRef: 14 | kind: GitRepository 15 | name: flux-system 16 | -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-aws-provider/aws-provider.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: pkg.crossplane.io/v1alpha1 3 | kind: ControllerConfig 4 | metadata: 5 | name: aws-config 6 | annotations: 7 | eks.amazonaws.com/role-arn: arn:aws:iam::${ACCOUNT_ID}:role/crossplane-role 8 | spec: 9 | podSecurityContext: 10 | fsGroup: 2000 11 | args: 12 | - '--debug' 13 | securityContext: 14 | runAsUser: 0 15 | --- 16 | apiVersion: pkg.crossplane.io/v1 17 | kind: Provider 18 | metadata: 19 | name: provider-aws 20 | spec: 21 | package: "xpkg.upbound.io/crossplane-contrib/provider-aws:v0.47.1" 22 | controllerConfigRef: 23 | name: aws-config -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-aws-provider/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - aws-provider.yaml 6 | -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-core.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: crossplane-core 6 | namespace: flux-system 7 | spec: 8 | interval: 3m0s 9 | path: ./tools/crossplane/crossplane-core 10 | prune: true 11 | sourceRef: 12 | kind: GitRepository 13 | name: flux-system 14 | # 15 | # A Kustomization can contain a series of health checks used to determine the rollout status of the deployed workloads and the ready status of custom resources. 16 | # A health check entry can reference either one of the Kubernetes builtin types or GitOps Toolkit types such as HelmRelease, HelmRepository, GitRepository, etc. 17 | # When a Kustomization contains HelmRelease objects, instead of checking the underling Deployments, you can define a health check that waits for the HelmReleases to be reconciled with 18 | # 19 | healthChecks: 20 | - apiVersion: helm.toolkit.fluxcd.io/v2beta1 21 | kind: HelmRelease 22 | name: crossplane-core 23 | namespace: crossplane-system 24 | - kind: Deployment 25 | name: crossplane 26 | namespace: crossplane-system 27 | - kind: Deployment 28 | name: crossplane-rbac-manager 29 | namespace: crossplane-system 30 | timeout: 2m 31 | 32 | -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-core/crossplane-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: crossplane-core 5 | namespace: flux-system 6 | spec: 7 | releaseName: crossplane-core 8 | interval: 5m 9 | chart: 10 | spec: 11 | chart: crossplane 12 | version: '1.15.0' 13 | sourceRef: 14 | kind: HelmRepository 15 | name: crossplane-repository 16 | namespace: crossplane-system 17 | interval: 1m 18 | 19 | 20 | -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-core/crossplane-repository.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: source.toolkit.fluxcd.io/v1beta2 3 | kind: HelmRepository 4 | metadata: 5 | name: crossplane-repository 6 | namespace: crossplane-system 7 | spec: 8 | interval: 5m 9 | url: https://charts.crossplane.io/stable -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-core/crossplane-system-namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: crossplane-system -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-core/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | namespace: crossplane-system 5 | resources: 6 | - crossplane-system-namespace.yaml 7 | - crossplane-repository.yaml 8 | - crossplane-release.yaml 9 | 10 | -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-k8s-provider-config.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: crossplane-k8s-provider-config 6 | namespace: flux-system 7 | spec: 8 | dependsOn: 9 | - name: crossplane-k8s-provider 10 | interval: 3m0s 11 | path: ./tools/crossplane/crossplane-k8s-provider-config 12 | prune: true 13 | sourceRef: 14 | kind: GitRepository 15 | name: flux-system 16 | healthChecks: 17 | - apiVersion: kubernetes.crossplane.io/v1alpha1 18 | kind: ProviderConfig 19 | name: k8s-providerconfig 20 | timeout: 2m 21 | 22 | -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-k8s-provider-config/k8s-providerconfig.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: k8s-provider-config-job-sa 6 | namespace: crossplane-system 7 | --- 8 | apiVersion: rbac.authorization.k8s.io/v1 9 | kind: ClusterRoleBinding 10 | metadata: 11 | name: k8s-provider-config-job-crb 12 | roleRef: 13 | apiGroup: rbac.authorization.k8s.io 14 | kind: ClusterRole 15 | name: cluster-admin 16 | subjects: 17 | - kind: ServiceAccount 18 | name: k8s-provider-config-job-sa 19 | namespace: crossplane-system 20 | --- 21 | apiVersion: batch/v1 22 | kind: Job 23 | metadata: 24 | name: k8s-provider-config-job 25 | namespace: crossplane-system 26 | spec: 27 | template: 28 | spec: 29 | serviceAccountName: k8s-provider-config-job-sa 30 | containers: 31 | - name: kubectl 32 | image: bitnami/kubectl:1.22.11 33 | command: 34 | - "/bin/bash" 35 | - "-c" 36 | - |+ 37 | SA="crossplane-system:"$(kubectl get provider.pkg.crossplane.io provider-kubernetes -o go-template --template='{{.status.currentRevision}}{{"\n"}}') 38 | status=$? 39 | if test $status -eq 1 40 | then 41 | echo "Provider not found. Deleting clusterrolebinding..." 42 | kubectl delete clusterrolebinding provider-kubernetes-admin-binding --ignore-not-found 43 | else 44 | kubectl get clusterrolebinding provider-kubernetes-admin-binding 45 | status=$? 46 | 47 | if test $status -eq 1 48 | then 49 | echo "Creating ClusterRoleBinding for serviceaccount [${SA}]" 50 | kubectl create clusterrolebinding provider-kubernetes-admin-binding --clusterrole cluster-admin --serviceaccount="${SA}" 51 | else 52 | echo "ClusterRoleBinding 'provider-kubernetes-admin-binding' exists." 53 | fi 54 | fi 55 | 56 | restartPolicy: Never 57 | backoffLimit: 4 58 | --- 59 | apiVersion: batch/v1 60 | kind: CronJob 61 | metadata: 62 | name: k8s-provider-config-cronjob 63 | namespace: crossplane-system 64 | spec: 65 | schedule: "*/3 * * * *" 66 | concurrencyPolicy: Forbid 67 | startingDeadlineSeconds: 100 68 | jobTemplate: 69 | spec: 70 | template: 71 | spec: 72 | serviceAccountName: k8s-provider-config-job-sa 73 | containers: 74 | - name: kubectl 75 | image: bitnami/kubectl:1.22.11 76 | command: 77 | - "/bin/bash" 78 | - "-c" 79 | - |+ 80 | SA="crossplane-system:"$(kubectl get provider.pkg.crossplane.io provider-kubernetes -o go-template --template='{{.status.currentRevision}}{{"\n"}}') 81 | status=$? 82 | if test $status -eq 1 83 | then 84 | echo "Provider not found. Deleting clusterrolebinding..." 85 | kubectl delete clusterrolebinding provider-kubernetes-admin-binding --ignore-not-found 86 | else 87 | kubectl get clusterrolebinding provider-kubernetes-admin-binding 88 | status=$? 89 | 90 | if test $status -eq 1 91 | then 92 | echo "Creating ClusterRoleBinding for serviceaccount [${SA}]" 93 | kubectl create clusterrolebinding provider-kubernetes-admin-binding --clusterrole cluster-admin --serviceaccount="${SA}" 94 | else 95 | echo "ClusterRoleBinding 'provider-kubernetes-admin-binding' exists." 96 | fi 97 | fi 98 | 99 | restartPolicy: Never 100 | backoffLimit: 4 101 | --- 102 | apiVersion: kubernetes.crossplane.io/v1alpha1 103 | kind: ProviderConfig 104 | metadata: 105 | name: k8s-providerconfig 106 | spec: 107 | credentials: 108 | source: InjectedIdentity -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-k8s-provider-config/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - k8s-providerconfig.yaml -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-k8s-provider.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: crossplane-k8s-provider 6 | namespace: flux-system 7 | spec: 8 | dependsOn: 9 | - name: crossplane-core 10 | interval: 3m0s 11 | path: ./tools/crossplane/crossplane-k8s-provider 12 | prune: true 13 | sourceRef: 14 | kind: GitRepository 15 | name: flux-system 16 | -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-k8s-provider/k8s-provider.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: pkg.crossplane.io/v1alpha1 3 | kind: ControllerConfig 4 | metadata: 5 | name: k8s-config 6 | spec: 7 | podSecurityContext: 8 | fsGroup: 2000 9 | args: 10 | - '--debug' 11 | --- 12 | apiVersion: pkg.crossplane.io/v1 13 | kind: Provider 14 | metadata: 15 | name: provider-kubernetes 16 | spec: 17 | package: "xpkg.upbound.io/crossplane-contrib/provider-kubernetes:v0.13.0" 18 | controllerConfigRef: 19 | name: k8s-config -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/crossplane-k8s-provider/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - k8s-provider.yaml -------------------------------------------------------------------------------- /repos/gitops-system/tools/crossplane/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - crossplane-core.yaml 6 | - crossplane-aws-provider.yaml 7 | - crossplane-aws-provider-config.yaml 8 | - crossplane-k8s-provider.yaml 9 | - crossplane-k8s-provider-config.yaml 10 | -------------------------------------------------------------------------------- /repos/gitops-system/tools/external-secrets/external-secrets-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: external-secrets 5 | namespace: flux-system 6 | spec: 7 | releaseName: external-secrets 8 | targetNamespace: external-secrets 9 | interval: 5m 10 | install: 11 | createNamespace: true 12 | chart: 13 | spec: 14 | chart: external-secrets 15 | version: '0.4.4' 16 | sourceRef: 17 | kind: HelmRepository 18 | name: external-secrets-repository 19 | namespace: flux-system 20 | interval: 1m -------------------------------------------------------------------------------- /repos/gitops-system/tools/external-secrets/external-secrets-repository.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: source.toolkit.fluxcd.io/v1beta2 3 | kind: HelmRepository 4 | metadata: 5 | name: external-secrets-repository 6 | namespace: flux-system 7 | spec: 8 | interval: 5m 9 | url: https://charts.external-secrets.io -------------------------------------------------------------------------------- /repos/gitops-system/tools/external-secrets/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - external-secrets-repository.yaml 6 | - external-secrets-release.yaml -------------------------------------------------------------------------------- /repos/gitops-system/tools/karpenter/karpenter-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: karpenter 5 | namespace: flux-system 6 | spec: 7 | releaseName: karpenter 8 | targetNamespace: kube-system 9 | interval: 5m 10 | chart: 11 | spec: 12 | chart: karpenter 13 | version: '0.36.1' 14 | sourceRef: 15 | kind: HelmRepository 16 | name: karpenter-repository 17 | namespace: flux-system 18 | interval: 1m 19 | values: 20 | logLevel: debug 21 | settings: 22 | clusterName: ${CLUSTER_NAME} 23 | controller: 24 | resources: 25 | requests: 26 | cpu: 1 27 | memory: 1Gi 28 | limits: 29 | cpu: 1 30 | memory: 1Gi 31 | serviceAccount: 32 | create: false 33 | name: karpenter-sa -------------------------------------------------------------------------------- /repos/gitops-system/tools/karpenter/karpenter-repo.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: source.toolkit.fluxcd.io/v1beta2 3 | kind: HelmRepository 4 | metadata: 5 | name: karpenter-repository 6 | namespace: flux-system 7 | spec: 8 | type: oci 9 | interval: 5m 10 | url: oci://public.ecr.aws/karpenter -------------------------------------------------------------------------------- /repos/gitops-system/tools/karpenter/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - karpenter-repo.yaml 6 | - karpenter-release.yaml -------------------------------------------------------------------------------- /repos/gitops-system/tools/kubecost/kubecost-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: kubecost 5 | namespace: flux-system 6 | spec: 7 | releaseName: kubecost 8 | targetNamespace: kubecost 9 | interval: 5m 10 | install: 11 | createNamespace: true 12 | chart: 13 | spec: 14 | chart: cost-analyzer 15 | version: '2.2.2' 16 | sourceRef: 17 | kind: HelmRepository 18 | name: kubecost-repository 19 | namespace: flux-system 20 | interval: 1m 21 | values: 22 | kubecostFrontend: 23 | image: public.ecr.aws/kubecost/frontend 24 | kubecostModel: 25 | image: public.ecr.aws/kubecost/cost-model 26 | forecasting: 27 | fullImageName: public.ecr.aws/kubecost/kubecost-modeling:v0.1.6 28 | networkCosts: 29 | image: 30 | repository: public.ecr.aws/kubecost/kubecost-network-costs 31 | clusterController: 32 | image: 33 | repository: public.ecr.aws/kubecost/cluster-controller 34 | prometheus: 35 | server: 36 | image: 37 | repository: public.ecr.aws/kubecost/prometheus 38 | configmapReload: 39 | prometheus: 40 | image: 41 | repository: public.ecr.aws/kubecost/prometheus-config-reloader 42 | reporting: 43 | productAnalytics: false 44 | -------------------------------------------------------------------------------- /repos/gitops-system/tools/kubecost/kubecost-repository.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: source.toolkit.fluxcd.io/v1beta2 3 | kind: HelmRepository 4 | metadata: 5 | name: kubecost-repository 6 | namespace: flux-system 7 | spec: 8 | type: oci 9 | interval: 5m 10 | url: oci://public.ecr.aws/kubecost -------------------------------------------------------------------------------- /repos/gitops-system/tools/kubecost/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - kubecost-repository.yaml 6 | - kubecost-release.yaml -------------------------------------------------------------------------------- /repos/gitops-system/tools/sealed-secrets/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - sealed-secrets-release.yaml 6 | - sealed-secrets-repository.yaml -------------------------------------------------------------------------------- /repos/gitops-system/tools/sealed-secrets/sealed-secrets-release.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.toolkit.fluxcd.io/v2beta1 2 | kind: HelmRelease 3 | metadata: 4 | name: sealed-secrets 5 | namespace: flux-system 6 | spec: 7 | releaseName: sealed-secrets 8 | targetNamespace: sealed-secrets 9 | interval: 5m 10 | install: 11 | createNamespace: true 12 | chart: 13 | spec: 14 | chart: sealed-secrets 15 | version: '2.7.1' 16 | sourceRef: 17 | kind: HelmRepository 18 | name: sealed-secrets-repository 19 | namespace: flux-system 20 | interval: 1m 21 | 22 | 23 | -------------------------------------------------------------------------------- /repos/gitops-system/tools/sealed-secrets/sealed-secrets-repository.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: source.toolkit.fluxcd.io/v1beta2 3 | kind: HelmRepository 4 | metadata: 5 | name: sealed-secrets-repository 6 | namespace: flux-system 7 | spec: 8 | interval: 5m 9 | url: https://bitnami-labs.github.io/sealed-secrets -------------------------------------------------------------------------------- /repos/gitops-system/workloads/template/flux-kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: workloads 6 | namespace: flux-system 7 | spec: 8 | prune: true 9 | interval: 2m0s 10 | path: ./cluster-name 11 | sourceRef: 12 | kind: GitRepository 13 | name: gitops-workloads 14 | postBuild: 15 | substituteFrom: 16 | - kind: ConfigMap 17 | name: cluster-info 18 | optional: false 19 | --- -------------------------------------------------------------------------------- /repos/gitops-system/workloads/template/git-repo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: GitRepository 3 | metadata: 4 | name: gitops-workloads 5 | namespace: flux-system 6 | spec: 7 | interval: 1m0s 8 | ref: 9 | branch: main 10 | secretRef: 11 | name: gitops-workloads 12 | timeout: 60s 13 | url: REPO_PREFIX/gitops-workloads 14 | 15 | -------------------------------------------------------------------------------- /repos/gitops-system/workloads/template/git-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: bitnami.com/v1alpha1 2 | kind: SealedSecret 3 | metadata: 4 | creationTimestamp: null 5 | name: gitops-workloads 6 | namespace: flux-system 7 | spec: 8 | encryptedData: 9 | identity: AgBtob6GFqkDVN9FbYI7qcYjINZwYBuh5EKcNuVn6lCrWKbsqQVY+S5cwTwky+CD66NE2U92U8sejV0X3H3wdKcSZ6UiJegEuD6C5c1b+WHlUcEt4YoQIMdcRBHdm1mO0R1B/3iQKRO52I2DmtLS75MRZF/lUZr1ZU25J0Ih6oRohVWdiryUHT+xThkzpEuU2ST/1a9ncBGFDul6QRDtLA0IlbSuhl6/VVviMpZbTsFvzQ4aM1LRcJ2wgNzW4fAIdQBbMhKCbufHEtJz34VuSb1YZqmBA1IcQDOh75MdZZNQ9hZ0KfABcwfiHuWPCVixW1fCNTjQQJclgb2U3CJptLMU1SeZWbxM40c0FezoeeNLnZSA2qvkrV36PW/n66XHNz0ECWXsOQ9Xp6CLMIv+ZFI1tup60DaeMM0vf2E4GQ44lMgUeLvw/b8CUYtFV8jACGBqYOACzUEkFBnar5LXGsRD/neAL2XElxvP8G+xNj7jptpoi5rD+pt0MnzQLrESLuaxam1H/tXezhlhf/FkzE9RvsfubJ6Yu7vHUJA0tU15H28CkYPtZmtsEDm9d6zISkBNMsMVH6dLc+b1G1QFggb5Lj8elQF6PbA+zoam6KAkC4Ff+MDKBKqd7S0ZuK71BxUDuceFomPN16vPSKixvR1PEIWIR3/EqsAJ3mnKIKAGuPSb7yNBL7j7h12NzptsmbHVW+TgVYHLhEGvUQ1cyv037L34/tHyubGix/Z4CJTDl5uRHytZaivZ1mpWOSsq69s1jyj6sIhYSvM5fwWr2sLXpjHaWo+bYvsyK/TYV+DoHKYN4pmWeMunDScM73h6fycNk3OlhIlCXBnmszLYlW14lixYPJXAd5sYOi7m7G53XqV1cjDLxPnMzNclh00UuKxo9di/hBQTBkIItrKcs0isYACbo4PO6teaxAEaxMraoTCWiZ2HSUJKcT/sR/bwDzEB8Gsi/x5yNO2lSm3od6O55oWd6/Z0d07KKsczF7pJ24wcXzW5Gc9AD2Q79mP1gOOE5vaeI373qPFyZrutWnRm239nabGF8n2jLe/iwxtedifiNJQRD5tnoUaojd/KsmH8kmdA/+8Y8TRt18Z3Nl9nuy2cA2OKxOp9bFr/Dxjgkc/RGduSJjwqOOsmY1JCFxb5fSH2+Oq8eWQzJ5UOh1AHMumxfmMw3K5G70suZXTqvEMg3d+HBYpEbbviwkZ/Bk8TI+C9qQMfA+9fYKsCjYigrgeIItsJldGkwFg= 10 | identity.pub: AgC6RiE5DwiixQzNJorTIslkqOGhY/HguUkQOfgEtyxAemm3i7lpWD1TQDT3z3x6CsYYTJDPH6wuHFp6WyRGU4ma4YiUKc76M+vfjx6kxUpqa93zxAbIoR+ddol8jG2hUzv864YBOEzUJJBgoDa7V6KkZ/rxABIQg1IYSlaNLbVuGTrjXmdLs6n+A/lPdcOsugXwaNic9EC9RVLi3d/N5OS7LCtz0AAiuIJsc8tae2PmuubQ9SEEUCg+hZOArCIECct1jGQ6ZC1YmV67DLOuoM7WnXbCZuOvV5wLyEoKmSz2+BUVX+aIARVXYMA3SgBXzx1dkKJnwpl9zERlgwIGTnl6qFxiI5dSHLw32N8cfUQv8CDO9QUIvt6Bn/9lps0/hn9MkQeoxbcJBrYHFOMPin/cwJS+SSf3zt2rp373zPz3+3tsU5AmabdlM5OIINf1srVrvULFlKIL3EvtpfDCRIVJVw7Pm6JNd/AbrATkRIscP/9K2T5v/LE3ILbLjxJsEvtCw+crHZNEbPzSCsq6wBCBou574WYaldEbIERBLSdWV43CWQEAikAZ4EJMofqC0Mg3HmWvzOcnNBKkGv8lLK925oIeYAoSW0F0TGd6WzviYo2UcAXtlv287xHguffhnIbOisIom3VCDeUMIx6xODnHnRZdFcbX23mdzakzuCiKtHzU2+cvSO2pWQZ6HttTuemrFmtkq1PO2vuo93eyxiSHPlRicsy7lVHT6P4OmmdnMsV2ggGc3oJvlZruxXZyPOjxFYraOBBZYWdLa8HdWda43/TmhO0Hlw6txvsmK97pI0I9OdrVpRgiwxAXM70FM2AfLQ== 11 | known_hosts: AgB3D1CjLsPRpjOsrCI9Uedr4SezCwlE5mJJHC2MTIUPSq/9Jhv9DEYv13O4vV7CgpJCeLC36ZTwRxntNL/RReY35GP3DJSex+VI/V8YN7ZEH9WjVdEfFdCXa/Vg6ToUzxEL2MySnQGFQAQ/QuhNpG2uLZ22KETe8RCGNvNeeZV/x4zHl43zoyXK7NoxtpsXGTNrpP5yo8Q7KbOEvm+ttzrZBVfYWr+PXM6bZihvBm8KeObGRaEeKqVaabyNjfNCHtJgb52l297hcibgeuh9FJAPmoxuzqCzIFpiseJ2dGdUCMjOPMmoQFqumX8G+xplfPWWyRPVsvKhlPrNJ5/yNk45/IDI5ob83puMiJBPSoNofvL3VbY6KBB1I5P9mWIk+mde5Yumk7yo0OebPfR3Eqgg18tvjqsf0xzay6Fk4pYE0mFqiKWKJAKgzZNN2hmmO2bX5TpjFy1qDMM8xDqYoSJqZstzRaqVBUbFGyHubSaN5ivBVUeBwXof6xhHEuWpjsLo++Ik0RpmRKJfOne3XrynVfXDRWCWutnNWJU6iAZf8LWm6UtaK1/8gQcimr/eiKywvi3vKWR4rTTtCH4qN9Hy8pNCb9BQ7+JDOCDshUQIsw4JWEGWz2GS0fhGFUJKBRFnqmlJAY9GaKxrLH0xlvcHbaq6iE0DjkbenAFJ5HZ6e41QrpmWywaYrWQifZitICPgy7IMr+Hg1vTAJbxY4zxJFbQ9APJz+VjoksnaiPdrS7XrLB3mrReGaXu4FGtHyxoXP2hA92LSd+KU0bu9lCHEr2wws2asXAdgaxZjEx0OJXLyKs4E4+sCjCgJhMN9YQrC96pBgPrO3rGphtY1yMdOfbMqoVG7gdmysaHmiHro3+kI+GkshVnx4gU10X0WaOqi7J+iEtoPEJW0mPuDikgZuzn3OaBrM14f1LB6 12 | template: 13 | data: null 14 | metadata: 15 | creationTimestamp: null 16 | name: gitops-workloads 17 | namespace: flux-system 18 | type: Opaque -------------------------------------------------------------------------------- /repos/gitops-system/workloads/template/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - git-repo.yaml 6 | - git-secret.yaml 7 | - flux-kustomization.yaml -------------------------------------------------------------------------------- /repos/gitops-workloads/template/app-template/app-iam.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: iam.aws.crossplane.io/v1beta1 3 | kind: Role 4 | metadata: 5 | name: app-name-cluster-name-role 6 | labels: 7 | type: app-name-cluster-name-role 8 | spec: 9 | forProvider: 10 | assumeRolePolicyDocument: | 11 | { 12 | "Version": "2012-10-17", 13 | "Statement": [ 14 | { 15 | "Effect": "Allow", 16 | "Principal": { 17 | "Federated": "arn:aws:iam::${ACCOUNT_ID}:oidc-provider/${OIDC_PROVIDER}" 18 | }, 19 | "Action": "sts:AssumeRoleWithWebIdentity", 20 | "Condition": { 21 | "StringEquals": { 22 | "${OIDC_PROVIDER}:aud": "sts.amazonaws.com", 23 | "${OIDC_PROVIDER}:sub": "system:serviceaccount:app-name:app-name-sa" 24 | } 25 | } 26 | } 27 | ] 28 | } 29 | providerConfigRef: 30 | name: default 31 | --- 32 | apiVersion: iam.aws.crossplane.io/v1beta1 33 | kind: Policy 34 | metadata: 35 | name: app-name-cluster-name-policy 36 | spec: 37 | forProvider: 38 | name: app-name-cluster-name-policy 39 | document: | 40 | { 41 | "Version": "2012-10-17", 42 | "Statement": [] 43 | } 44 | providerConfigRef: 45 | name: default 46 | --- 47 | apiVersion: iam.aws.crossplane.io/v1beta1 48 | kind: RolePolicyAttachment 49 | metadata: 50 | name: app-name-cluster-name-attachment 51 | spec: 52 | forProvider: 53 | policyArnRef: 54 | name: app-name-cluster-name-policy 55 | roleNameRef: 56 | name: app-name-cluster-name-role 57 | providerConfigRef: 58 | name: default -------------------------------------------------------------------------------- /repos/gitops-workloads/template/app-template/app-sa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | annotations: 5 | eks.amazonaws.com/role-arn: arn:aws:iam::${ACCOUNT_ID}:role/app-name-cluster-name-role 6 | name: app-name-sa 7 | namespace: app-name 8 | -------------------------------------------------------------------------------- /repos/gitops-workloads/template/app-template/flux-kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.toolkit.fluxcd.io/v1beta2 3 | kind: Kustomization 4 | metadata: 5 | name: app-name 6 | namespace: flux-system 7 | spec: 8 | serviceAccountName: app-name-team 9 | prune: true 10 | interval: 2m0s 11 | path: ./kubernetes/overlays/overlay-dir-name 12 | sourceRef: 13 | kind: GitRepository 14 | name: app-name 15 | postBuild: 16 | substituteFrom: 17 | - kind: ConfigMap 18 | name: cluster-info 19 | optional: false 20 | --- -------------------------------------------------------------------------------- /repos/gitops-workloads/template/app-template/git-repo.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: source.toolkit.fluxcd.io/v1beta2 2 | kind: GitRepository 3 | metadata: 4 | name: app-name 5 | namespace: flux-system 6 | spec: 7 | interval: 1m0s 8 | ref: 9 | branch: branch-name 10 | secretRef: 11 | name: app-name 12 | timeout: 60s 13 | url: REPO_PREFIX/app-name-manifests 14 | 15 | -------------------------------------------------------------------------------- /repos/gitops-workloads/template/app-template/git-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: bitnami.com/v1alpha1 2 | kind: SealedSecret 3 | metadata: 4 | creationTimestamp: null 5 | name: app-name 6 | namespace: flux-system 7 | spec: 8 | encryptedData: 9 | identity: AgDS032Vp8jvbk8zJvJBcVTJQ/00yV7Ygt16sGfPPZPtNBZs5BKo+5FpWoXjyj+3lOqFwZZ6HMxVzw99IoeHJSFlFyRUvdzmb72g0DD3UfpeAIA4VpWgRTnkaznKbllyHg6FuUrWhAQ86FJt1wpJtiLPmznsB1jQRdf92fYKRRFMLBRg7QeIIzbS8lR0iaDGDV3gi0/1cN6aCEFfzH5t481PVracNp7yJXj25puy3rA+eHsP8bqGxHZCIFZ+1xWDV6g7nLCc9MpCoU/WMyowAi3E+KCx5kvFicO8t0LkwaNWl84lgm0SXd1NvZ9GIqt/YQdmho1AlYt7Q2Dwchc2AprE1s+953ot3irykfar/Ql35VNQt+4V4BpO4mokyR6Zv7zTnaWGcQD75Hq6mcdtDfSjH5xuxO+QluF6uQXv3SOT8Sep2hN7ltv7rkKsShvdvafXKeCuK+xG7XBzgtYsMh5spvwD1CN7vLTJ7/cvWSF60G2u8BgrfG2zHZWN9kmbmQyjcIag0lbK1q/6SwUGYPwROssoo0f3yB760FCjvoC06Ag7kBVEH6Op1VUcX3GI3z/XL++QIuTuofLCugL3KhTzSkWq8M/eNtiKz9suxvXj8uBwJ3Pa9LJkdMr/6+82R4YTkT54P5n6DNPmL0RZbANynn99EOXXi9VWPNGYUsBS53oYHPJYqeIWVCnKpqc1Oe0sJy2m6giw0aw9d7W3ZUqzAXd6RH4PE3nEI9klzsetnAKPER2XVWowfXreFWkRsRAydfjTDkm6NyhbbtTS+z/FR3+mCbOVr8m2bwhMR/njZa95s0dkgA6ahpsM8iKxGUzJeZpm7qUTyNLRXTqCu/D67ZUAPs30KKBIpENAIlJksfCV2OnBEhtHkH6Xftsmc6lL93bAAoDdZOYfxwa+SrGcTQZU4wWhfio2J1HoD8IM+30x17VQ4XcIHLW3K3hlktParPx0p3t31WQ+5vUO1+xoTayyyibczWycx94p9l/ObgXkbb0V9iWODWaZR/tXI3j1NpqPHsPzKxJm54SVIfQmG44+qDLVQTp+Q7q47KGV3/i6jkfO6ATcfxwpUlEWiFkREVSDUPBTt5326lnr9SKnJMbcDVKy0Pra+sNyDeHg6JCD/FvvL+uwALDMQtX432eG8OCGSsffmnWowfroJolv9sJUzmq4j8S4MQXojl0ikuhfRlXfvhnn/Jh0BuclZxuDSQ22KgSxSfF/5MgO8UK6XbRsW+CHT3lM3Tk= 10 | identity.pub: AgBH83R2ziqvFI4MdVZ+wwkjkqGfWw2Gz8vwKsM7gJbUkNWrKb8JhUmT5ULuyw33rdZgUwdCZc9CXoKkWfohLrUDd5ReS6Ebs12z3bGUuvuXeTXTMpzdxiJDpR9BtJVL5T5zi/x99JLuULb1+zhIEG8mPRBOhqQJ68LNwsUWG/6/J6GaL0v54dEcQjPeLXs77SqF+Wpk3qtnvrIP8kX4t2LPrmOwAymzrSnPHsSb+mWFI9Al/7K+vVCCpBh6kVkHg4j9gW21d6yoVmrvpusSk3btMk579fOIDYoWHnTXEJ0MjnN91a1OpGDzE/JMPVTvrGwxv6dCkpzk11wcMX0oyD00pdQsJU+HFyhskTThiqz2fxgkJq/qHNJ86pKDasVfl2oE8ddB122A2PO8e3HF7ymTHxAn0BHGBb4xpfX7ekT/IVXl1UxrGdr0nyEnCgbG6nt1/lcaBvnGIk4U0dTGLndJAWwaYhXHwPNsmkKnvWiQLPCg4elnLOrJE1EGiLGblmv/ridpXLS7Kfdhc6WiFlbw6RTgBpc6cPBJfkFbrxQOsoJ+0grQSdh2OgqG43vo2gGeFPhHOugMASVjX/QPgh5zpmaEO6MDIfhyZRF074n633Izo14ntTEsQgv9aFTKyeu40xJNHXng9iwoeI0GXKgJrIfll8KLUJmgtI0xRSI4N9cNOmiVGSOMoxdhQifhYjALmozAXqgMmCVT7kWbyT4tRhWCWbLYneo5c2S9qcP/hOix3IU8aGsdrmxnW7FE/IB1FwehgXUyg+t/0+fvqcMG49ItUjflR0qisuh9kIQ0MX9B+bSAhMoUvzZnx+F9LeUuFQ== 11 | known_hosts: AgCcDk0zpUn2tlaSOxpSv8GF5oJ8YB5p+my855xlN7golrh6ej8IHzS8w5Ngn1KiY3v+MduHQuKi5aRCu26uIiY+mX7Kr0oAMTIcjiO9c3hHdFrBLWrGN13CGPNZz7dpIbzS33KN1zQamVZAJepjgQ11kAvll3j+UeHUi7UQm73ndG1ZCHYTHPZhytFEq8X4CU1QS/E2Hp4lkm6o3hWxwDrz8U9+oaSh5lBylODpb67NpMlgA0Xg9MsnKv9FZCf19Twb0+L27Z0Vndw9lZGv8+piljpYSUZgInq4JM9nEMd+Saa9QNvRtBtwxaEDiH0/62v2b/FKvXi5bVwxoGPYa2ApnbrfQskYxPrQNdqi4PfvS4MLEN969vF3k+Kj/rrwGgtCGnOLGZ9ZaiFLeDxmpsluBWbalYWReL0SFh0t2jHxdre47SP/xgjI6xl8YWOAjPGnVaVMK2G3sYea6zzbx/TTg9NDDSCeeGfPMPTzsB0mrrRWzR/DrlvGt4AwKPWfaM+C8b0BXWxjirkZIVuopLt2FIzSJV852xHLu68pK7qYSs72hBL3tMGIWY5LJG3H3nm89CG3Alp0yQjrVP5n9kIH9AxLUbu1zJpTpaqBNQn0cwJf4IBJNiiCmtIN2wJJ2peo6DejxAiqwFlscVoDieed42J7m0SKeCOco1P3XIoaM9RBsRXF5w6lnWkGpdNzcAIdL0La+3hq4ZbFPR93BtEDAp4gfurawyJoziP8pQaSN47V4JEIB1Tw4oY9zqSL/U/IoEPWNlsTyEUR+brRRUUSzXopAGCAataVKZwyZtXe71fQeHF2JzBtgyjhUiMZ08xv/FZVTNknC2sKZTkIwnLa5sCFC9WwLjYADODucDPoaBdcCz6JtLO0pjM0oCxxEm9XzFV/1VpiuF9nfoS6O9dFVIS2qlwxKw1J5Xna 12 | template: 13 | data: null 14 | metadata: 15 | creationTimestamp: null 16 | name: app-name 17 | namespace: flux-system 18 | type: Opaque -------------------------------------------------------------------------------- /repos/gitops-workloads/template/app-template/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | - git-repo.yaml 6 | - git-secret.yaml 7 | - flux-kustomization.yaml 8 | - ns.yaml 9 | - sa.yaml 10 | - role-binding.yaml 11 | - app-iam.yaml 12 | - app-sa.yaml -------------------------------------------------------------------------------- /repos/gitops-workloads/template/app-template/ns.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: app-name -------------------------------------------------------------------------------- /repos/gitops-workloads/template/app-template/role-binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: app-name-gotk-reconciler 5 | namespace: flux-system 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: cluster-admin 10 | subjects: 11 | - kind: User 12 | name: gotk:app-name:reconciler 13 | - kind: ServiceAccount 14 | name: app-name-team 15 | namespace: flux-system 16 | --- 17 | apiVersion: rbac.authorization.k8s.io/v1 18 | kind: RoleBinding 19 | metadata: 20 | name: app-name-infra-reconciler 21 | namespace: flux-system 22 | roleRef: 23 | apiGroup: rbac.authorization.k8s.io 24 | kind: Role 25 | name: app-name-team-infra-admin 26 | subjects: 27 | - kind: ServiceAccount 28 | name: app-name-team 29 | namespace: flux-system -------------------------------------------------------------------------------- /repos/gitops-workloads/template/app-template/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: app-name-team-infra-admin 5 | namespace: flux-system 6 | rules: 7 | - apiGroups: 8 | - aws.crossplane.io 9 | resources: 10 | - "*" 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - create 16 | - update 17 | - patch 18 | - delete 19 | - apiGroups: 20 | - "" 21 | resources: 22 | - configmaps 23 | - configmaps/status 24 | verbs: 25 | - get 26 | - list 27 | - watch 28 | - create 29 | - update 30 | - patch 31 | - delete -------------------------------------------------------------------------------- /repos/gitops-workloads/template/app-template/sa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: app-name-team 5 | namespace: flux-system -------------------------------------------------------------------------------- /repos/gitops-workloads/template/kustomization.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: kustomize.config.k8s.io/v1beta1 3 | kind: Kustomization 4 | resources: 5 | 6 | -------------------------------------------------------------------------------- /resources/reinvent-2022-slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/eks-multi-cluster-gitops/910fe7fd48015dfaf08b610f6acb3c2512d3b92c/resources/reinvent-2022-slides.pdf --------------------------------------------------------------------------------