Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eks-prow-build-cluster: GitOps proposal #5336

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 55 additions & 7 deletions infra/aws/terraform/prow-build-cluster/Makefile
pkprzekwas marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -15,46 +15,94 @@
TF ?= terraform
TF_ARGS ?=

KUBECTL ?= kubectl

# TODO: figure out a workaround for: https://github.com/hashicorp/terraform-provider-kubernetes-alpha/issues/199#issuecomment-832614387
DEPLOY_K8S_RESOURCES ?= true

# Valid values are: canary, prod
PROW_ENV ?= canary

##@ Helpers:

.PHONY: help
help: ## Display this help.
@awk \
-v "col=${COLOR}" -v "nocol=${NOCOLOR}" \
' \
BEGIN { \
FS = ":.*##" ; \
printf "\nUsage:\n make %s<target>%s\n", col, nocol \
} \
/^[a-zA-Z_-]+:.*?##/ { \
printf " %s%-15s%s %s\n", col, $$1, nocol, $$2 \
} \
/^##@/ { \
printf "\n%s%s%s\n", col, substr($$0, 5), nocol \
} \
' $(MAKEFILE_LIST)

##@ Terraform:

.PHONY: init
init:
init: ## Initialize Terraform's state and download necessary providers.
$(TF) $@ \
-backend-config=./tfbackends/$(PROW_ENV).tfbackend

.PHONY: plan
plan:
plan: ## Present plan for creating/updating Terraform resources.
$(TF) $@ $(TF_ARGS) \
-var-file=./terraform.tfvars \
-var-file=./terraform.$(PROW_ENV).tfvars \
-var="deploy_kubernetes_resources=$(DEPLOY_K8S_RESOURCES)"

.PHONY: apply
apply:
apply: ## Create/Update Terraform resources.
$(TF) $@ $(TF_ARGS) \
-var-file=./terraform.tfvars \
-var-file=./terraform.$(PROW_ENV).tfvars \
-var="deploy_kubernetes_resources=$(DEPLOY_K8S_RESOURCES)"

.PHONY: destroy
destroy:
destroy: ## Delete Terraform resources.
$(TF) $@ $(TF_ARGS) \
-var-file=./terraform.tfvars \
-var-file=./terraform.$(PROW_ENV).tfvars \
-var="deploy_kubernetes_resources=$(DEPLOY_K8S_RESOURCES)"

.PHONY: fmt
fmt:
fmt: ## Format Terraform files.
$(TF) $@

.PHONY: output
output:
output: ## Print Terraform output.
$(TF) $@

.PHONY: clean
clean:
clean: ## Clean up Terraform cache and local state.
rm -rf ./.terraform

##@ FluxCD:

.PHONY: flux-install
flux-install: ## Install FluxCD components inside flux-system namespace.
${KUBECTL} apply --server-side -f ./resources/flux-system/gotk-components.yaml

.PHONY: flux-apply-sources
flux-apply-sources: ## Apply FluxCD Sources located inside "./resources/flux-system" folder.
find ./resources/flux-system -type f -name "flux-source-*" -exec ${KUBECTL} apply -f {} \;

.PHONY: flux-apply-kustomizations
flux-apply-kustomizations: ## Apply FluxCD Kustomizations located inside "./resources/flux-system" folder.
find ./resources/flux-system -type f -name "flux-ks-*" -exec ${KUBECTL} apply -f {} \;

.PHONY: flux-apply-helm-releases
flux-apply-helm-releases: ## Apply HelmReleases located inside "./resources" folder.
find ./resources -type f -name "flux-hr-*" -exec ${KUBECTL} apply -f {} \;

PHONY: flux-apply-all
flux-apply-all: flux-apply-sources flux-apply-kustomizations flux-apply-helm-releases ## Apply FluxCD Sources, Kustomizations and HelmReleases, all at once.

.PHONY: flux-update
flux-update: ## Update FluxCD manifests, generate Kustomizations and HelmReleases (requires flux cli).
./hack/flux-update.bash
50 changes: 50 additions & 0 deletions infra/aws/terraform/prow-build-cluster/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,53 @@ make destroy

If you want to remove roles used for EKS creation go to `../iam/<aws_account_name>` and run `terraform destroy` command there.


## GitOps
pkprzekwas marked this conversation as resolved.
Show resolved Hide resolved

To synchronize the state from this Git repository into the EKS cluster, we utilize [FluxCD](https://fluxcd.io/).

FluxCD provides a dedicated [CLI tool](https://fluxcd.io/flux/installation/#install-the-flux-cli). We leverage this tool in scripts to generate and monitor syncs.

The FluxCD resources are stored inside the `./resources` directory and are generated using the `./hack/flux-update.bash` script. This script prepares manifests for the [GitOps Tool Kit](https://fluxcd.io/flux/components/), generating [Sources](https://fluxcd.io/flux/components/source/), [Kustomizations](https://fluxcd.io/flux/components/kustomize/kustomization/) and [Helm Releases](https://fluxcd.io/flux/components/helm/helmreleases/). **It's important to note that the terms "Kustomization" and "Helm Release" used in this section refer specifically to FluxCD concepts.** The FluxCD Kustomization CRD serves as the counterpart to Kustomize's kustomization.yaml config file, and the Helm Release is a FluxCD CRD that defines a resource for automated controller-driven Helm releases.

The `flux-system` namespace contains all GitOps Tool Kit components, Flux Sources, and Kustomizations. Helm Releases should be deployed in the same namespace as the manifests they create. As a convention, Flux Helm Releases should be prefixed with `flux-hr-`, Kustomizations with `flux-ks-`, and sources with `flux-source-`. These naming conventions are used in our automation's discovery process.

- To install Flux GitOps Tool Kit components, run the following command:
```bash
make flux-install
```

- To deploy Kustomizations, use the command:
```bash
make flux-apply-kustomizations
```

### Accessing Flux

To access FluxCD, you need a kubeconfig file with broad cluster permissions and the Flux CLI installed locally. That option is reserved for cluster administrators. You can contanct them via #sig-k8s-infra Slack channel. (__TODO__: mention monitoring dashboards when ready)

### Adding New Kustomization
pkprzekwas marked this conversation as resolved.
Show resolved Hide resolved

1. Navigate to the `./resources` directory and create a new folder to contain your manifests.
2. Open `./hack/flux-update.bash` in your editor of choice.
3. Locate the `kustomizations` variable, which contains a list of kustomizations to generate. Each element in the list corresonds to a directory inside the `./resources` folder.
4. Extend the kustomization list by adding the name of the folder you created in the first step.
5. Regenerate the kustomizations by running: `make flux-update`
6. Commit your changes and wait for your resources to appear in the cluster. If you have access to the cluster, you can use `flux get ks <kustomization-name>` to monitor the state.

### Adding New Helm Release

1. Open `./hack/flux-update.bash` in your preferred editor.
2. Create a new Helm source. If you already have a Helm source, you can skip this step.
1. Locate the section of the script responsible for creating the `eks-charts` Helm release.
2. Use the same pattern to create a new Helm source.
3. Create a new Helm release.
1. Locate the section of the script responsible for creating the Helm release for `node-termination-handler`.
2. Based on the `node-termination-handler` example, extend the script with your Helm release.
4. Regenerate the Helm releases by running: `make flux-update`
5. To deploy your Helm Release, you need to add it to an exiting Kustomization or create a new one.
6. If you have access to the cluster, you can check the status by executing: `flux get hr -n <namespace> <helm_release_name>` or `flux get hr -A` to list all Helm releases inside the cluster. (__TODO__: replace this section with grafana dashboard when ready)

### Monitoring Flux

__TODO__
96 changes: 96 additions & 0 deletions infra/aws/terraform/prow-build-cluster/hack/flux-update.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Copyright 2023 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

#!/usr/bin/env bash
set -xeuo pipefail

# TODO(pkprzekwas): point at k8s.io main
github_org=pkprzekwas
pkprzekwas marked this conversation as resolved.
Show resolved Hide resolved
github_repo=k8s.io
github_branch=eks-prow-build-cluster-gitops

if ! command -v flux &> /dev/null
then
echo "flux could not be found"
exit 2
fi

script_root=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)

function boilerplate() {
cat ${script_root}/../../../../../hack/boilerplate/boilerplate.sh.txt | sed -e "s/\<YEAR\>/$(date +'%Y')/"
echo "# Code generated by make flux-update. DO NOT EDIT."
}

resources_dir=${script_root}/../resources

# Generate all FluxCD resources.
# gotk stands for GitOpsToolKit (https://fluxcd.io/flux/components/)
boilerplate > ${resources_dir}/flux-system/gotk-components.yaml
flux install --export >> ${resources_dir}/flux-system/gotk-components.yaml

# sync_interval determines Flux Source Controller sync interval.
# (https://github.com/fluxcd/source-controller)
sync_interval=5m

boilerplate > ${resources_dir}/flux-system/flux-source-git-k8s.io.yaml
flux create source git k8s-io \
--url=https://github.com/${github_org}/k8s.io \
--branch=${github_branch} \
--interval=${sync_interval} \
--export >> ${resources_dir}/flux-system/flux-source-git-k8s.io.yaml

boilerplate > ${resources_dir}/flux-system/flux-source-helm-eks-charts.yaml
flux create source helm eks-charts \
--url=https://aws.github.io/eks-charts \
--interval=${sync_interval} \
--export >> ${resources_dir}/flux-system/flux-source-helm-eks-charts.yaml

boilerplate > ${resources_dir}/kube-system/flux-hr-node-termination-handler.yaml
flux create hr node-termination-handler \
--source=HelmRepository/eks-charts.flux-system \
--namespace=kube-system \
--chart=aws-node-termination-handler \
--chart-version=0.21.0 \
--interval=${sync_interval} \
--export >> ${resources_dir}/kube-system/flux-hr-node-termination-handler.yaml

# This list contains names of folders inside ./resources directory
# that are used for generating FluxCD kustomizations.
kustomizations=(
boskos
flux-system
kube-system
monitoring
node-problem-detector
rbac
test-pods
external-secrets
)

# Code below is used to figure out a relative path of
# resources dir in relation to the root dir of git repo.
pushd ${resources_dir} > /dev/null
resources_git_repo_path=$(git rev-parse --show-prefix)
popd > /dev/null

for k in "${kustomizations[@]}"; do
boilerplate > ${resources_dir}/flux-system/flux-ks-${k}.yaml
flux create kustomization ${k} \
--source=GitRepository/k8s-io.flux-system \
--path=${resources_git_repo_path}/${k} \
--interval=5m \
--prune \
--export >> ${resources_dir}/flux-system/flux-ks-${k}.yaml
done
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2023 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: Namespace
metadata:
name: external-secrets
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2023 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Code generated by make flux-update. DO NOT EDIT.
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: boskos
namespace: flux-system
spec:
interval: 5m0s
path: ./infra/aws/terraform/prow-build-cluster/resources/boskos
prune: true
sourceRef:
kind: GitRepository
name: k8s-io
namespace: flux-system
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2023 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Code generated by make flux-update. DO NOT EDIT.
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: external-secrets
namespace: flux-system
spec:
interval: 5m0s
path: ./infra/aws/terraform/prow-build-cluster/resources/external-secrets
prune: true
sourceRef:
kind: GitRepository
name: k8s-io
namespace: flux-system
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2023 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Code generated by make flux-update. DO NOT EDIT.
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: flux-system
namespace: flux-system
spec:
interval: 5m0s
path: ./infra/aws/terraform/prow-build-cluster/resources/flux-system
prune: true
sourceRef:
kind: GitRepository
name: k8s-io
namespace: flux-system
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright 2023 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Code generated by make flux-update. DO NOT EDIT.
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: kube-system
namespace: flux-system
spec:
interval: 5m0s
path: ./infra/aws/terraform/prow-build-cluster/resources/kube-system
prune: true
sourceRef:
kind: GitRepository
name: k8s-io
namespace: flux-system
Loading