Skip to content

Commit e3e1a35

Browse files
tyrosselmodridiTanguy Rossellentidas
authored
feat: add updated KinD example (#993)
* chore: update KinD example * feat: add Minio and Loki modules * feat(kind): update example deployment * feat(kind): add k8s metrics_server * docs: update KinD tutorial * docs: add symbolic link to deployment examples directory * docs: add symbolic link to github_workflows directory * chore: update KinD example to latest Kind module version * docs: update KinD tutorial * refactor: rename example folders * docs: add small corrections to the KinD tutorial * feat: add helloworld and reduce the code of kube-prometheus-stack * chore: add helm provider and reorder them by order of use in the code * fix(grafana): explicitly enable Grafana * docs: update Kind deployment - Added doc for pause and stop the cluster - Troubleshooting a error with loki-stack-promtail * fix(kind): use remote origin instead of local repository * docs: fix some capitalizations and rewording * feat: add latest updates * chore: update KinD example with latest module versions * chore: remove unused outputs --------- Co-authored-by: modridi <mohamed-amine.dridi@camptocamp.com> Co-authored-by: Tanguy Rossel <trossel@wrk149.wrk.lsn.camptocamp.com> Co-authored-by: GonΓ§alo Heleno <goncalo.heleno@camptocamp.com>
1 parent 3ce6f33 commit e3e1a35

32 files changed

Lines changed: 645 additions & 353 deletions

β€Ž.gitignoreβ€Ž

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,10 @@ tests/*/.terraform.lock.hcl
1414
tests/*/kubeconfig.yaml
1515
tests/*/terraform.tfstate
1616
tests/*/terraform.tfstate.backup
17+
examples/*/.terraform
18+
examples/*/terraform.tfstate
19+
examples/*/terraform.tfstate.*
20+
examples/*/.terraform.tfstate.lock.info
21+
examples/*/*-config
22+
examples/*/.terraform.lock.hcl
23+
docs_test
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../examples
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../../.github/workflows

β€Ždocs/modules/ROOT/pages/contributing/project_board.adocβ€Ž

Lines changed: 2 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ The app is called `DevOps Stack Project` and is available https://github.com/app
2525

2626
This app was created on our organization by an administrator and is configured with a limited scope of permissions: it can only access the projects of the organization where it is installed as well as the PRs and Issues of repositories on which it is installed (https://docs.github.com/en/apps/creating-github-apps/setting-up-a-github-app/creating-a-github-app[official documentation] on how to create a GitHub app).
2727

28-
After the app creation, an administrator was needed to install it on the organization and all the repositories of the DevOps Stack. This was done by going to the app page and clicking on the `Install` button then configuring the proper settings after installation (all this is done on the organization settings, check the https://docs.github.com/en/apps/maintaining-github-apps/installing-github-apps#installing-your-private-github-app-on-your-repository[official documentation]).
28+
After the app creation, an administrator was needed to install it on the organization and all the repositories of the DevOps Stack. This was done by going to the app page and clicking on the `Install` button then configuring the proper settings after installation (all this is done on the organization settings, check the https://docs.github.com/en/apps/maintaining-github-apps/installing-github-apps#installing-your-private-github-app-on-your-repository[official documentation]).
2929

3030
IMPORTANT: The reason to not install the app on all the repositories by default was to further limit the scope of the app, although *this adds the burden of installing it on each repository manually every time a new repository of the DevOps Stack is created*.
3131

@@ -35,48 +35,7 @@ The workflow definition is available in the {url-main-repo}/blob/main/.github/wo
3535

3636
[source,yaml]
3737
----
38-
---
39-
# GitHub Actions workflow to automatically push PRs and issues to the DevOps Stack project board.
40-
#
41-
# IMPORTANT: This workflow is called by other workflows in our DevOps Stack repositories and it is centralized here in
42-
# order to be easily maintained across modules. Because of this, please make sure you're not introducing any breaking
43-
# changes when modifying this workflow.
44-
45-
name: "pr-issues-project"
46-
47-
on:
48-
workflow_call:
49-
secrets:
50-
PROJECT_APP_PRIVATE_KEY:
51-
description: "GitHub App private key for the DevOps Stack Project app"
52-
required: true
53-
54-
issues:
55-
types:
56-
- opened
57-
- reopened
58-
59-
pull_request:
60-
types:
61-
- opened
62-
- reopened
63-
64-
jobs:
65-
add-to-project:
66-
runs-on: ubuntu-latest
67-
steps:
68-
- name: Generate authentication token from GitHub App
69-
id: generate_token
70-
uses: tibdex/github-app-token@v1
71-
with:
72-
app_id: 322306
73-
private_key: ${{ secrets.PROJECT_APP_PRIVATE_KEY }}
74-
75-
- name: Add PR or issue to DevOps Stack project board
76-
uses: actions/add-to-project@v0.5.0
77-
with:
78-
project-url: https://github.com/orgs/camptocamp/projects/3/
79-
github-token: ${{ steps.generate_token.outputs.token }}
38+
include::example$github_workflows/pr-issues-project.yaml[]
8039
----
8140

8241
NOTE: It is the step _Generate authentication token from GitHub App_ that uses the GitHub app created above in order to generate a token with the proper permissions that is then passed to the _Add PR or issue to DevOps Stack project board_ step.

β€Ždocs/modules/ROOT/pages/contributing/release.adocβ€Ž

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,7 @@ The workflow definition available in the {url-main-repo}/blob/main/.github/workf
2020

2121
[source,yaml]
2222
----
23-
---
24-
# GitHub Actions workflow to automatically create releases and changelogs in our DevOps Stack repositories.
25-
#
26-
# IMPORTANT: This workflow is called by other workflows in our DevOps Stack repositories and it is centralized here in
27-
# order to be easily maintained across modules. Because of this, please make sure you're not introducing any breaking
28-
# changes when modifying this workflow.
29-
30-
name: "modules-release-please"
31-
32-
on:
33-
workflow_call:
34-
35-
jobs:
36-
release-please:
37-
runs-on: ubuntu-latest
38-
steps:
39-
- uses: google-github-actions/release-please-action@v3
40-
with:
41-
release-type: simple
42-
pull-request-title-pattern: "chore: release ${version}"
43-
bump-minor-pre-major: true
44-
extra-files: |
45-
variables.tf
23+
include::example$github_workflows/modules-release-please.yaml[]
4624
----
4725

4826
Note following lines:
@@ -76,7 +54,7 @@ NOTE: Our {url-template-repo}/blob/main/.github/workflows/release-please.yaml[mo
7654

7755
== Automatic Versioning
7856

79-
The commit messages are used to determine the type of release that needs to be created.
57+
The commit messages are used to determine the type of release that needs to be created.
8058

8159
Only the `feat` and `fix` commit types will trigger the release CI. The `feat` commit type will trigger a minor version bump while the `fix` commit type will trigger a patch version bump. If you add a `!` after the commit type, the release will be a major version bump. For example, `feat!: this is a breaking change` will trigger a major version bump.
8260

Lines changed: 178 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,180 @@
11
= Deployment With KinD
22

3-
_Work In Progress_
3+
An example of a local deployment in KinD is provided https://github.com/camptocamp/devops-stack/tree/main/examples/kind[here]. Clone this repository and modify it at your convenance.
4+
In the folder, as in a standard https://developer.hashicorp.com/terraform/tutorials/modules/module#what-is-a-terraform-module[Terraform module], you will find the following files:
5+
6+
* `terraform.tf`: declaration of the Terraform providers used in this project.
7+
* `locals.tf`: local variables used in the DevOps Stacks.
8+
* `main.tf`: definition of all deployed modules.
9+
* `s3_bucket.tf`: configuration of the MinIO bucket, used as backend for Loki and Thanos.
10+
* `outputs.tf`: the output variables of the DevOps Stack, e.g. credentials and the `.kubeconfig` file to use with `kubectl`.
11+
12+
== Specificities of the KinD deployment
13+
14+
==== Local Load Balancer
15+
16+
https://metallb.universe.tf/[MetalLB] is used as a load balancer for the cluster. This allows us to have a multi-node KinD cluster without the need to use Traefik in a single replica with a NodePort configuration.
17+
18+
==== Self-signed SSL certificates
19+
20+
Since KinD is locally deployed, there is no easy way of creating valid SSL certificates for the ingresses using Let's Encrypt. As such, `cert-manager` is configured to use a self-signed Certificate Authority and the remaining modules are configured to ignore the SSL warnings/errors that are a consequence of that.
21+
22+
NOTE: When accessing the ingresses on your browser, you'll obviously see warnings saying that the certificate is not valid. You can safely ignore them.
23+
24+
== Requirements
25+
26+
For this setup, you will need to have installed on your machine:
27+
28+
* https://docs.docker.com/get-docker[Docker] to deploy the KinD containers
29+
* https://www.terraform.io/[Terraform] to provision the whole stack
30+
* https://kubernetes.io/docs/reference/kubectl/[`kubectl`] to interact with your cluster
31+
32+
== Deployment
33+
34+
1. From the source of the example deployment, initialize Terraform, which downloads all required providers and modules locally (they will be stored in the hidden folder `.terraform`).
35+
+
36+
[source,bash]
37+
----
38+
terraform init
39+
----
40+
41+
2. Check out the modules you want to deploy in the `main.tf` file, and comment out the others.
42+
+
43+
TIP: You can also add your owns Terraform modules in this file or any other file on the root folder. A good place to start to write your own module is to clone the https://github.com/camptocamp/devops-stack-helloworld[devops-stack-helloworld] repository and adapt it to your needs.
44+
45+
3. Configure the variables in `locals.tf` to your preference:
46+
+
47+
[source,hcl]
48+
----
49+
include::example$deploy_examples/kind/locals.tf[]
50+
----
51+
52+
4. Finally, run `terraform apply` and accept the proposed changes to create the Kubernetes nodes as Docker containers, and populate them with our services.
53+
+
54+
[source,bash]
55+
----
56+
terraform apply
57+
----
58+
59+
=== Troubleshooting
60+
61+
==== ArgoCD: connection refused
62+
63+
Because at the end of the deployment we use the Argo CD to deploy and manage itself, there could be an error like this one:
64+
65+
This error happens when ArgoCD bootstraps itself.
66+
[source,shell]
67+
----
68+
β•·
69+
β”‚ Error: Error while waiting for application argocd to be created
70+
β”‚
71+
β”‚ with module.argocd.argocd_application.this,
72+
β”‚ on .terraform/modules/argocd/main.tf line 55, in resource "argocd_application" "this":
73+
β”‚ 55: resource "argocd_application" "this" {
74+
β”‚
75+
β”‚ error while waiting for application argocd to be synced and healthy: rpc error: code = Unavailable desc = connection error: desc = "transport: error while dialing: dial tcp 127.0.0.1:45729: connect: connection refused"
76+
β•΅
77+
----
78+
79+
This happens because the Argo CD server pod is redeployed and the Argo CD Terraform provider loses connection. You can simply re-run the command `terraform apply` to finalize the bootstrap of the cluster.
80+
81+
==== `loki-stack-promtail` pods stuck with status `CrashLoopBackOff`
82+
83+
When the pods of `loki-stack-promtail` are stuck in a creation loop with the following logs:
84+
85+
[source]
86+
----
87+
level=error ts=2023-05-09T06:32:38.495673778Z caller=main.go:117 msg="error creating promtail" error="failed to make file target manager: too many open files"
88+
Stream closed EOF for loki-stack/loki-stack-promtail-bxcmw (promtail)
89+
----
90+
91+
You will have to increase the upper limit on the number of INotify instances that can be created per real user ID:
92+
93+
[source,bash]
94+
----
95+
# Increase the limit until next reboot:
96+
sudo sysctl fs.inotify.max_user_instances=512
97+
# Increase the limit permanently (run this command as root):
98+
echo 'fs.inotify.max_user_instances=512' >> /etc/sysctl.conf
99+
----
100+
101+
== Access the applications
102+
103+
The URLs of the applications are visible in the ingresses of the cluster. You can get them by running the following command:
104+
105+
[source,bash]
106+
----
107+
kubectl get ingress --all-namespaces
108+
----
109+
110+
For example, if the base domain name is `172-19-0-1.nip.io`, the applications are accessible at the following adresses:
111+
112+
----
113+
https://grafana.apps.172-19-0-1.nip.io
114+
https://alertmanager.apps.172-19-0-1.nip.io
115+
https://prometheus.apps.172-19-0-1.nip.io
116+
https://keycloak.apps.172-19-0-1.nip.io
117+
https://minio.apps.172-19-0-1.nip.io
118+
https://argocd.apps.172-19-0-1.nip.io
119+
https://thanos-bucketweb.apps.172-19-0-1.nip.io
120+
https://thanos-query.apps.172-19-0-1.nip.io
121+
----
122+
123+
You can access the applications using the credentials created by the Keycloak module. They are written to the Terraform output:
124+
125+
[source,bash]
126+
----
127+
# List all outputs:
128+
$ terraform output
129+
keycloak_admin_credentials = <sensitive>
130+
keycloak_users = <sensitive>
131+
kubernetes_kubeconfig = <sensitive>
132+
minio_root_user_credentials = <sensitive>
133+
134+
# To get the credentials for Grafana, Prometheus, etc.
135+
$ terraform output keycloak_users
136+
{
137+
"devopsadmin" = "aqhEbd3L0Msryjjp547ej7nyN6E2FllV"
138+
}
139+
----
140+
141+
== Pause the cluster
142+
143+
The `docker pause` command can be used to halt the cluster for a while in order to save energy (replace `kind-cluster` by the cluster name you defined in `locals.tf`):
144+
145+
[source,bash]
146+
----
147+
# Pause the cluster:
148+
docker pause kind-cluster-control-plane kind-cluster-worker{,2,3}
149+
150+
# Resume the cluster:
151+
docker unpause kind-cluster-control-plane kind-cluster-worker{,2,3}
152+
----
153+
154+
NOTE: When the host computer is restarted, the Docker container will start
155+
again, but the cluster will not resume correctly. It has to be destroyed and
156+
recreated.
157+
158+
== Stop the cluster
159+
160+
To definitively stop the cluster on a single command (that is the reason we delete some resources from the state file), we can use the following command:
161+
162+
[source,bash]
163+
----
164+
terraform state rm $(terraform state list | grep "argocd_application\|argocd_project\|kubernetes_\|helm_\|keycloak_") && terraform destroy
165+
----
166+
167+
A dirtier alternative is to directly destroy the Docker containers and volumes (replace `kind-cluster` by the cluster name you defined in `locals.tf`):
168+
169+
[source,bash]
170+
----
171+
# Stop and remove Docker containers:
172+
docker container stop kind-cluster-control-plane kind-cluster-worker{,2,3} && \
173+
docker container rm -v kind-cluster-control-plane kind-cluster-worker{,2,3}
174+
# Remove the Terraform state:
175+
rm terraform.state
176+
----
177+
178+
== Conclusion
179+
180+
That's it, you have deployed the DevOps Stack locally! For more informations, keep on reading the https://devops-stack.io/docs/latest/[documentation]. **You can explore the possibilities of each module and get the link to the source code on their respective documentation pages.**

0 commit comments

Comments
Β (0)