Skip to content
Snippets Groups Projects
Commit 7d2daca8 authored by PERDEREAU Eloi's avatar PERDEREAU Eloi
Browse files

mv -r ../project-code/* .

parent 7f18dbba
Branches
No related tags found
No related merge requests found
Showing
with 878 additions and 59 deletions
# terraform-project
FILA3 Voting-App Terraform Project.
# Table of Content
* [Local Docker deployment](#docker-project)
* [Kubernetes on GCP](#kubernetes-project)
* [Offloading Redis from the Cluster](#terraform-project)
## Getting started
# Terraform project
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
## Objectives
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
The objective is to use Terraform to deploy the voting app.
## Add your files
The tutorial on Terraform did not give you _all_ elements for this project: it was on purpose.
The point is for you to learn how to seek information in providers and other documentations.
But most elements in the tutorials can be directly applied.
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
Different levels are possible, the more advancement you make the better. **Part 1 and Part 2 are mandatory.**
```
cd existing_repo
git remote add origin https://gitlab.imt-atlantique.fr/login-nuage/terraform-project.git
git branch -M main
git push -uf origin main
```
## Part 1 mandatory - Docker
## Integrate with your tools
In this first part, you must write code that deploys the application with the Terraform Docker provider.
The app will thus be deployed locally inside containers on your machine.
- [ ] [Set up project integrations](https://gitlab.imt-atlantique.fr/login-nuage/terraform-project/-/settings/integrations)
**TIP**: start from your previous `docker-compose.yml`.
## Collaborate with your team
## Part 2 mandatory - GKE and Kubernetes
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
In this second part, you must write code that deploys the application onto a Kubernetes cluster provisioned with Terraform on GKE.
Google and Kubernetes providers will be thus be used.
## Test and Deploy
**TIP**: you can start form the GKE tutorial and from your previous Kubernetes manifests.
Use the built-in continuous integration in GitLab.
**IMPORTANT**: Make sure to organize your Terraform code well. Attention will be given to your organization (modules, directories, files)
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
## Part 3 optional - GKE, Kubernetes and OpenStack
***
In this last part, you must deploy with Terraform the `Redis` database inside a VM on the school's OpenStack platform.
This database must then communicate with the other components of the application located on the GKE cluster.
# Editing this README
### Changes to make this work
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
By default, Redis is supposed to be used only locally and does not have a password.
You must thus modify the application code that uses Redis so that they connect with a password.
## Suggestions for a good README
#### Inside `vote/app.py`
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
On line 21, change
```
g.redis = Redis(host="redis", db=0, socket_timeout=5)
```
to
```
g.redis = Redis(host="redis", password="osef", db=0, socket_timeout=5)
```
## Name
Choose a self-explaining name for your project.
#### Inside `worker/Program.cs`
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
On line 116, change
```
return ConnectionMultiplexer.Connect(ipAddress);
```
to
```
return ConnectionMultiplexer.Connect("redis,password=osef");
```
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
#### cloud-init script to install Redis on a VM
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
Use this script as in cloud-init to install Redis.
```
#!/usr/bin/env bash
#
# Install and configure Redis
## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
DEBIAN_FRONTEND=noninteractive apt update -q
DEBIAN_FRONTEND=noninteractive apt install -q -y redis
## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
sed -e '/^bind/s/bind.*/bind 0.0.0.0/' -i /etc/redis/redis.conf
sed -e '/# requirepass/s/.*/requirepass osef/' -i /etc/redis/redis.conf
```
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
## Destroy everything
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
To keep some credits, make sure you execute `terraform destroy`.
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
There is a surprise here: GKE clusters cannot be destroyed by default, we need to modify the state by hand to tell terraform it is OK to delete it.
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
Open `terraform.tfstate`, look for the property `deletion_protection` and set its value to `false`.
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
Alternatively, use `sed`:
```
sed -e '/deletion_protection/s/true/false/' -i terraform.tfstate
```
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
### Améliorations
## License
For open source projects, say how it is licensed.
* Faire un du script d'install redis un template pour passer le mot de passe en paramètre. Adaptez le `.tf`.
* À partir du template `redis_endpointslice.yaml` qui configure une IP `endpoint_ip` de la BDD Redis externe. Adaptez le .tf
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.
# version is now using "compose spec"
# v2 and v3 are now combined!
# docker-compose v1.27+ required
services:
vote1:
# image: europe-west9-docker.pkg.dev/nuage-k8s/login-nuage-images/vote
# image: eloip13009/vote
build:
context: ./vote
dockerfile: Dockerfile
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000"]
interval: 15s
timeout: 5s
retries: 2
start_period: 5s
depends_on:
redis:
condition: service_healthy
networks:
- front-tier
- back-tier
vote2:
# image: europe-west9-docker.pkg.dev/nuage-k8s/login-nuage-images/vote
# image: eloip13009/vote
build:
context: ./vote
dockerfile: Dockerfile
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000"]
interval: 15s
timeout: 5s
retries: 2
start_period: 5s
depends_on:
redis:
condition: service_healthy
networks:
- front-tier
- back-tier
result:
# image: europe-west9-docker.pkg.dev/nuage-k8s/login-nuage-images/result
# image: eloip13009/result
build:
context: ./result
depends_on:
db:
condition: service_healthy
ports:
- "5050:80"
- "127.0.0.1:9229:9229"
networks:
- front-tier
- back-tier
worker:
# image: europe-west9-docker.pkg.dev/nuage-k8s/login-nuage-images/worker
# image: eloip13009/worker
build:
context: ./worker
environment:
PG_HOST: "db"
REDIS_HOST: "redis"
depends_on:
redis:
condition: service_healthy
db:
condition: service_healthy
networks:
- back-tier
redis:
image: redis:alpine # here is no dockerfile
# image: europe-west9-docker.pkg.dev/nuage-k8s/login-nuage-images/redis-hs
# image: eloip13009/redis-hc
# build:
# context: ./healthchecks
# dockerfile: Dockerfile-redis-hc
healthcheck:
test: /healthchecks/redis.sh
interval: "5s"
volumes:
- "./healthchecks:/healthchecks"
networks:
- back-tier
db:
image: postgres:15-alpine # here is no dockerfile
# image: europe-west9-docker.pkg.dev/nuage-k8s/login-nuage-images/postgres-hs
# image: eloip13009/postgres-hc
# build:
# context: ./healthchecks
# dockerfile: Dockerfile-postgres-hc
healthcheck:
test: /healthchecks/postgres.sh
interval: "5s"
environment:
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "postgres"
volumes:
- "db-data:/var/lib/postgresql/data"
- "./healthchecks:/healthchecks"
networks:
- back-tier
nginx:
build:
context: ./nginx
ports:
- "8000:8000"
depends_on:
vote1:
condition: service_healthy
vote2:
condition: service_healthy
networks:
- front-tier
seed:
# image: europe-west9-docker.pkg.dev/nuage-k8s/login-nuage-images/seed-data
# image: eloip13009/seed-data:vote5000
build:
context: ./seed-data
dockerfile: Dockerfile
environment:
SEED_HOST: "nginx"
SEED_PORT: 8000
depends_on:
- nginx
networks:
- front-tier
restart: "no"
volumes:
db-data:
networks:
front-tier:
back-tier:
<mxfile host="app.diagrams.net" modified="2024-03-05T16:30:44.885Z" agent="Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0" etag="rH7s3egcXEbWZkPB3phi" scale="1" border="0" version="24.0.1" type="device">
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">
<mxGraphModel dx="1270" dy="690" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="-aIuFbX0UB9FjIYz7hkI-54" value="" style="ellipse;shape=cloud;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;html=1;labelPosition=center;verticalLabelPosition=bottom;align=center;verticalAlign=top;spacing=0;spacingTop=-47;spacingBottom=10;spacingRight=4;spacingLeft=27;fillColor=#fff2cc;strokeColor=#d6b656;opacity=50;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="80" y="270" width="730" height="330" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-34" value="" style="group;fontSize=14;movable=1;resizable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1" connectable="0">
<mxGeometry x="217" y="130" width="593" height="395" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-52" value="" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;fillColor=#f5f5f5;fontColor=#333333;strokeColor=#666666;opacity=50;" parent="-aIuFbX0UB9FjIYz7hkI-34" vertex="1">
<mxGeometry x="-120" y="-60" width="678" height="365" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-60" value="front-tier" style="text;html=1;align=center;verticalAlign=middle;resizable=1;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=14;fontStyle=4;movable=1;rotatable=1;deletable=1;editable=1;locked=0;connectable=1;sketch=1;curveFitting=1;jiggle=2;fontFamily=Courier New;" parent="-aIuFbX0UB9FjIYz7hkI-34" vertex="1">
<mxGeometry x="393" y="50" width="110" height="30" as="geometry" />
</mxCell>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-3" value="seed" style="rounded=1;whiteSpace=wrap;html=1;glass=0;strokeWidth=1;shadow=0;comic=0;enumerate=0;treeMoving=1;treeFolding=0;cloneable=1;sketch=1;curveFitting=1;jiggle=2;arcSize=16;fontFamily=Architects Daughter;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DArchitects%2BDaughter;fontSize=15;" parent="-aIuFbX0UB9FjIYz7hkI-34" vertex="1">
<mxGeometry x="200" width="58" height="40" as="geometry" />
</mxCell>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-7" value="Nginx LB" style="rounded=1;whiteSpace=wrap;html=1;glass=0;strokeWidth=1;shadow=0;sketch=1;curveFitting=1;jiggle=2;fontSize=13;" parent="-aIuFbX0UB9FjIYz7hkI-34" vertex="1">
<mxGeometry x="125" y="110" width="100" height="50" as="geometry" />
</mxCell>
<mxCell id="KxudlqymiYV0jEx7q53w-0" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.388;exitY=0.958;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;exitPerimeter=0;" parent="-aIuFbX0UB9FjIYz7hkI-34" source="WIyWlLk6GJQsqaUBKTNV-3" target="WIyWlLk6GJQsqaUBKTNV-7" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="211.14" y="170" as="sourcePoint" />
<mxPoint x="261.14" y="120" as="targetPoint" />
<Array as="points">
<mxPoint x="221.14" y="50" />
<mxPoint x="173.14" y="50" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="KxudlqymiYV0jEx7q53w-2" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="-aIuFbX0UB9FjIYz7hkI-34" target="WIyWlLk6GJQsqaUBKTNV-7" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="241" y="40" as="sourcePoint" />
<mxPoint x="191.14" y="100" as="targetPoint" />
<Array as="points">
<mxPoint x="241.14" y="70" />
<mxPoint x="175" y="70" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-7" value="Redis" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;sketch=1;curveFitting=1;jiggle=2;fontSize=13;" parent="-aIuFbX0UB9FjIYz7hkI-34" vertex="1">
<mxGeometry y="315" width="60" height="80" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-9" value="&lt;div style=&quot;font-size: 15px;&quot;&gt;result&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;curveFitting=1;jiggle=2;fontFamily=Architects Daughter;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DArchitects%2BDaughter;fontSize=15;" parent="-aIuFbX0UB9FjIYz7hkI-34" vertex="1">
<mxGeometry x="313" y="220" width="80" height="30" as="geometry" />
</mxCell>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-11" value="Worker" style="rounded=1;whiteSpace=wrap;html=1;glass=0;strokeWidth=1;shadow=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Architects Daughter;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DArchitects%2BDaughter;fontSize=15;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="352" y="475" width="120" height="40" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-8" value="PostgreSQL" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;sketch=1;curveFitting=1;jiggle=2;fontSize=13;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="535" y="445" width="75" height="80" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-10" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.398;exitY=1.001;exitDx=0;exitDy=0;exitPerimeter=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="-aIuFbX0UB9FjIYz7hkI-5" target="-aIuFbX0UB9FjIYz7hkI-7" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="382" y="355" as="sourcePoint" />
<mxPoint x="312" y="455" as="targetPoint" />
<Array as="points">
<mxPoint x="406" y="410" />
<mxPoint x="247" y="410" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-14" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="-aIuFbX0UB9FjIYz7hkI-9" target="-aIuFbX0UB9FjIYz7hkI-8" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="292" y="355" as="sourcePoint" />
<mxPoint x="342" y="305" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-15" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=52.5;entryPerimeter=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="WIyWlLk6GJQsqaUBKTNV-11" target="-aIuFbX0UB9FjIYz7hkI-8" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="292" y="355" as="sourcePoint" />
<mxPoint x="342" y="305" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-19" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=1;exitY=0.3333333333333333;exitDx=0;exitDy=0;exitPerimeter=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="-aIuFbX0UB9FjIYz7hkI-16" target="-aIuFbX0UB9FjIYz7hkI-9" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="292" y="355" as="sourcePoint" />
<mxPoint x="342" y="305" as="targetPoint" />
<Array as="points">
<mxPoint x="570" y="60" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-20" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="WIyWlLk6GJQsqaUBKTNV-7" target="WIyWlLk6GJQsqaUBKTNV-12" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="292" y="355" as="sourcePoint" />
<mxPoint x="342" y="305" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-38" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0.1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="-aIuFbX0UB9FjIYz7hkI-33" target="WIyWlLk6GJQsqaUBKTNV-7" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="372" y="235" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-45" value="" style="endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.3333333333333333;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="-aIuFbX0UB9FjIYz7hkI-33" target="WIyWlLk6GJQsqaUBKTNV-7" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="292" y="355" as="sourcePoint" />
<mxPoint x="382" y="235" as="targetPoint" />
<Array as="points">
<mxPoint x="367" y="90" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-12" value="vote" style="rounded=1;whiteSpace=wrap;html=1;glass=0;strokeWidth=1;shadow=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="362" y="325" width="60" height="40" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-4" value="vote" style="rounded=1;whiteSpace=wrap;html=1;glass=0;strokeWidth=1;shadow=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="372" y="335" width="60" height="40" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-5" value="vote" style="rounded=1;whiteSpace=wrap;html=1;glass=0;strokeWidth=1;shadow=0;sketch=1;curveFitting=1;jiggle=2;fontFamily=Architects Daughter;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DArchitects%2BDaughter;fontSize=15;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="382" y="345" width="60" height="40" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-47" value="" style="endArrow=none;startArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0;exitDx=0;exitDy=52.5;exitPerimeter=0;startFill=1;sketch=1;curveFitting=1;jiggle=2;endFill=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="-aIuFbX0UB9FjIYz7hkI-7" target="WIyWlLk6GJQsqaUBKTNV-11" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="402" y="365" as="sourcePoint" />
<mxPoint x="452" y="315" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-16" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="630" y="40" width="30" height="60" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-58" value="" style="endArrow=none;html=1;rounded=0;exitX=1;exitY=0;exitDx=0;exitDy=52.5;exitPerimeter=0;sketch=1;curveFitting=1;jiggle=2;endFill=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="-aIuFbX0UB9FjIYz7hkI-8" target="-aIuFbX0UB9FjIYz7hkI-57" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="640" y="610" as="sourcePoint" />
<mxPoint x="510" y="380" as="targetPoint" />
<Array as="points">
<mxPoint x="696" y="498" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-59" value="&lt;pre style=&quot;font-size: 14px;&quot;&gt;back-tier&lt;/pre&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=14;fontStyle=4;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="630" y="430" width="100" height="60" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-57" value="&lt;div&gt;db-data&lt;/div&gt;" style="shape=cylinder3;boundedLbl=1;backgroundOutline=1;size=15;html=1;labelPosition=center;verticalLabelPosition=middle;align=center;verticalAlign=middle;fontFamily=Courier New;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="670" y="515" width="52" height="65" as="geometry" />
</mxCell>
<mxCell id="KxudlqymiYV0jEx7q53w-1" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" target="WIyWlLk6GJQsqaUBKTNV-7" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="450" y="170" as="sourcePoint" />
<mxPoint x="480" y="250" as="targetPoint" />
<Array as="points">
<mxPoint x="450" y="180" />
<mxPoint x="450" y="190" />
<mxPoint x="392" y="190" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-39" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0.1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="-aIuFbX0UB9FjIYz7hkI-32" target="WIyWlLk6GJQsqaUBKTNV-7" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="360.57428571428574" y="235" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-40" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0.1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="-aIuFbX0UB9FjIYz7hkI-31" target="WIyWlLk6GJQsqaUBKTNV-7" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="351.7171428571429" y="235" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-41" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0.1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="-aIuFbX0UB9FjIYz7hkI-30" target="WIyWlLk6GJQsqaUBKTNV-7" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="342.86" y="235" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-42" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0.1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="-aIuFbX0UB9FjIYz7hkI-29" target="WIyWlLk6GJQsqaUBKTNV-7" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="334.0028571428571" y="235" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-29" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;html=1;strokeColor=default;fillColor=default;textOpacity=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="200" y="30" width="26.57142857142857" height="60" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-30" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;html=1;strokeColor=default;fillColor=default;textOpacity=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="208.85714285714286" y="40" width="26.57142857142857" height="60" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-31" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;html=1;strokeColor=default;fillColor=default;textOpacity=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="217.71428571428572" y="50" width="26.57142857142857" height="60" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-32" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;html=1;strokeColor=default;fillColor=default;textOpacity=0;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="226.57142857142856" y="60" width="26.57142857142857" height="60" as="geometry" />
</mxCell>
<mxCell id="-aIuFbX0UB9FjIYz7hkI-33" value="&lt;div&gt;Actors&lt;/div&gt;" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;html=1;strokeColor=default;fillColor=default;sketch=1;curveFitting=1;jiggle=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="235.42857142857144" y="70" width="26.57142857142857" height="60" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
<mxfile host="app.diagrams.net" modified="2024-03-05T16:31:19.516Z" agent="Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0" etag="H_WbUNg_AQp871g6-zpg" version="24.0.1" type="device">
<diagram name="Page-1" id="LRgAmveIpWlrcjWVx1SN">
<mxGraphModel dx="1347" dy="1790" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="PWsmGeNbDvQFNoou8pB0-2" value="" style="rounded=0;whiteSpace=wrap;html=1;dashed=1;fillColor=#f5f5f5;fontColor=#333333;strokeColor=#666666;glass=0;shadow=0;textShadow=0;" parent="1" vertex="1">
<mxGeometry x="65" y="-940" width="720" height="270" as="geometry" />
</mxCell>
<mxCell id="PWsmGeNbDvQFNoou8pB0-3" value="&lt;font face=&quot;Courier New&quot;&gt;vote&lt;/font&gt; Pod 1" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;curveFitting=1;jiggle=2;" parent="1" vertex="1">
<mxGeometry x="165" y="-750" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="PWsmGeNbDvQFNoou8pB0-7" value="&lt;font face=&quot;Courier New&quot;&gt;vote&lt;/font&gt; Service" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;comic=0;fillStyle=auto;sketch=1;curveFitting=1;jiggle=2;rounded=1;fillColor=#d0cee2;strokeColor=#56517e;" parent="1" vertex="1">
<mxGeometry x="225" y="-930" width="160" height="90" as="geometry" />
</mxCell>
<mxCell id="PWsmGeNbDvQFNoou8pB0-15" value="" style="endArrow=classic;html=1;rounded=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="1" target="PWsmGeNbDvQFNoou8pB0-3" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="305" y="-850" as="sourcePoint" />
<mxPoint x="375" y="-750" as="targetPoint" />
<Array as="points">
<mxPoint x="303" y="-790" />
<mxPoint x="205" y="-790" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="PWsmGeNbDvQFNoou8pB0-17" value="" style="endArrow=classic;html=1;rounded=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="1" target="RoczK8zSZt4-ihxr8N2F-7" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="305" y="-850" as="sourcePoint" />
<mxPoint x="540" y="-750" as="targetPoint" />
<Array as="points">
<mxPoint x="305" y="-790" />
<mxPoint x="405" y="-790" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="PWsmGeNbDvQFNoou8pB0-18" value="" style="endArrow=classic;html=1;rounded=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;sketch=1;curveFitting=1;jiggle=2;" parent="1" target="RoczK8zSZt4-ihxr8N2F-6" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="305" y="-850" as="sourcePoint" />
<mxPoint x="372.99" y="-748" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="PWsmGeNbDvQFNoou8pB0-19" value="" style="rounded=0;whiteSpace=wrap;html=1;dashed=1;fillColor=#fff2cc;glass=0;shadow=0;textShadow=0;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="65" y="-670" width="720" height="270" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-89" style="edgeStyle=orthogonalEdgeStyle;rounded=0;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.499;exitY=0.956;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="1" source="PWsmGeNbDvQFNoou8pB0-23" target="RoczK8zSZt4-ihxr8N2F-3">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="PWsmGeNbDvQFNoou8pB0-23" value="&lt;font face=&quot;Courier New&quot;&gt;redis&lt;/font&gt; Service" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;comic=0;fillStyle=auto;sketch=1;curveFitting=1;jiggle=2;rounded=1;" parent="1" vertex="1">
<mxGeometry x="225" y="-640" width="160" height="90" as="geometry" />
</mxCell>
<mxCell id="PWsmGeNbDvQFNoou8pB0-30" value="Backend resources" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;fontFamily=Architects Daughter;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DArchitects%2BDaughter;sketch=1;curveFitting=1;jiggle=2;fontSize=15;" parent="1" vertex="1">
<mxGeometry x="65" y="-430" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-3" value="&lt;font face=&quot;Courier New&quot;&gt;redis&lt;/font&gt; Pod" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="270" y="-510" width="70" height="60" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-5" value="&lt;font face=&quot;Courier New&quot;&gt;worker&lt;/font&gt; Pod" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="425" y="-615" width="140" height="40" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-46" style="edgeStyle=orthogonalEdgeStyle;rounded=1;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;orthogonalLoop=1;jettySize=auto;html=1;curved=0;" edge="1" parent="1" source="RoczK8zSZt4-ihxr8N2F-6">
<mxGeometry relative="1" as="geometry">
<mxPoint x="305" y="-630" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-6" value="&lt;font face=&quot;Courier New&quot;&gt;vote&lt;/font&gt; Pod 2" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="265" y="-750" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-39" style="edgeStyle=orthogonalEdgeStyle;rounded=1;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;orthogonalLoop=1;jettySize=auto;html=1;curved=0;" edge="1" parent="1" source="RoczK8zSZt4-ihxr8N2F-7">
<mxGeometry relative="1" as="geometry">
<mxPoint x="305" y="-630" as="targetPoint" />
<Array as="points">
<mxPoint x="405" y="-650" />
<mxPoint x="305" y="-650" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-7" value="&lt;font face=&quot;Courier New&quot;&gt;vote&lt;/font&gt; Pod 3" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="365" y="-750" width="80" height="40" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-66" style="edgeStyle=orthogonalEdgeStyle;rounded=0;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" target="RoczK8zSZt4-ihxr8N2F-10">
<mxGeometry relative="1" as="geometry">
<mxPoint x="680" y="-840" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-8" value="&lt;font face=&quot;Courier New&quot;&gt;result&lt;/font&gt; Service" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;comic=0;fillStyle=auto;sketch=1;curveFitting=1;jiggle=2;rounded=1;shadow=0;textShadow=0;fillColor=#d0cee2;strokeColor=#56517e;" vertex="1" parent="1">
<mxGeometry x="600" y="-930" width="160" height="90" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-10" value="&lt;font face=&quot;Courier New&quot;&gt;result&lt;/font&gt; Pod" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="630" y="-750" width="100" height="40" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-67" style="edgeStyle=orthogonalEdgeStyle;rounded=1;hachureGap=4;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;strokeColor=default;curved=0;exitX=0.505;exitY=0.942;exitDx=0;exitDy=0;exitPerimeter=0;sketch=1;curveFitting=1;jiggle=2;" edge="1" parent="1" source="RoczK8zSZt4-ihxr8N2F-11" target="RoczK8zSZt4-ihxr8N2F-13">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-11" value="&lt;font face=&quot;Courier New&quot;&gt;db&lt;/font&gt; Service" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;comic=0;fillStyle=auto;sketch=1;curveFitting=1;jiggle=2;rounded=1;" vertex="1" parent="1">
<mxGeometry x="600" y="-640" width="160" height="90" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-14" value="GCE disk" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;sketch=1;curveFitting=1;jiggle=2;fillColor=#cdeb8b;strokeColor=#36393d;" vertex="1" parent="1">
<mxGeometry x="512.5" y="-380" width="60" height="70" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-37" style="edgeStyle=orthogonalEdgeStyle;rounded=1;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.498;entryY=0.115;entryDx=0;entryDy=0;entryPerimeter=0;curved=0;" edge="1" parent="1" source="PWsmGeNbDvQFNoou8pB0-3" target="PWsmGeNbDvQFNoou8pB0-23">
<mxGeometry relative="1" as="geometry">
<mxPoint x="304" y="-640" as="targetPoint" />
<Array as="points">
<mxPoint x="205" y="-650" />
<mxPoint x="305" y="-650" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-42" style="edgeStyle=orthogonalEdgeStyle;rounded=0;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.085;entryY=0.489;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="RoczK8zSZt4-ihxr8N2F-5" target="RoczK8zSZt4-ihxr8N2F-11">
<mxGeometry relative="1" as="geometry">
<mxPoint x="615" y="-596" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-43" style="edgeStyle=orthogonalEdgeStyle;rounded=0;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.875;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="RoczK8zSZt4-ihxr8N2F-5" target="PWsmGeNbDvQFNoou8pB0-23">
<mxGeometry relative="1" as="geometry">
<mxPoint x="375" y="-596" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-44" style="edgeStyle=orthogonalEdgeStyle;rounded=0;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0.1;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="RoczK8zSZt4-ihxr8N2F-10" target="RoczK8zSZt4-ihxr8N2F-11">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-48" value="&lt;font face=&quot;Courier New&quot;&gt;seed&lt;/font&gt; Job" style="shape=parallelogram;perimeter=parallelogramPerimeter;whiteSpace=wrap;html=1;fixedSize=1;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;" vertex="1" parent="1">
<mxGeometry x="85" y="-640" width="90" height="35" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-51" style="edgeStyle=orthogonalEdgeStyle;rounded=0;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.114;entryY=0.546;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" edge="1" parent="1" source="RoczK8zSZt4-ihxr8N2F-48" target="PWsmGeNbDvQFNoou8pB0-7">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="130" y="-881" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-58" value="" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;" vertex="1" parent="1">
<mxGeometry x="465" y="-1070" width="40" height="90" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-85" style="edgeStyle=orthogonalEdgeStyle;rounded=0;hachureGap=4;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;dashed=1;sketch=1;curveFitting=1;jiggle=2;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="RoczK8zSZt4-ihxr8N2F-65" target="RoczK8zSZt4-ihxr8N2F-84">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-65" value="&lt;font face=&quot;Courier New&quot;&gt;db-data&lt;/font&gt; PVC" style="rounded=0;whiteSpace=wrap;html=1;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;fillColor=#bac8d3;strokeColor=#23445d;" vertex="1" parent="1">
<mxGeometry x="505" y="-497.5" width="75" height="35" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-73" value="" style="swimlane;startSize=0;hachureGap=4;fillColor=#fad9d5;strokeColor=#ae4132;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="415" y="-630" width="160" height="70" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-74" value="" style="swimlane;startSize=0;hachureGap=4;fillColor=#fad9d5;strokeColor=#ae4132;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="155" y="-770" width="300" height="80" as="geometry">
<mxRectangle x="210" y="150" width="50" height="40" as="alternateBounds" />
</mxGeometry>
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-75" value="" style="swimlane;startSize=0;hachureGap=4;fillColor=#fad9d5;strokeColor=#ae4132;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="1">
<mxGeometry x="615" y="-760" width="130" height="60" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-81" style="edgeStyle=orthogonalEdgeStyle;rounded=0;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;dashed=1;" edge="1" parent="1" source="RoczK8zSZt4-ihxr8N2F-78" target="RoczK8zSZt4-ihxr8N2F-65">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-78" value="" style="swimlane;startSize=0;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;fillColor=#fad9d5;strokeColor=#ae4132;" vertex="1" parent="1">
<mxGeometry x="635" y="-510" width="90" height="60" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-13" value="&lt;font face=&quot;Courier New&quot;&gt;db&lt;/font&gt; Pod" style="rounded=1;whiteSpace=wrap;html=1;sketch=1;curveFitting=1;jiggle=2;" vertex="1" parent="RoczK8zSZt4-ihxr8N2F-78">
<mxGeometry x="10" y="10" width="70" height="40" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-93" style="edgeStyle=orthogonalEdgeStyle;rounded=0;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;dashed=1;" edge="1" parent="1" source="RoczK8zSZt4-ihxr8N2F-84" target="RoczK8zSZt4-ihxr8N2F-14">
<mxGeometry relative="1" as="geometry">
<mxPoint x="775" y="-340" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-84" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;hachureGap=4;" vertex="1" parent="1">
<mxGeometry x="537.5" y="-420" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-90" style="edgeStyle=orthogonalEdgeStyle;rounded=0;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.4;entryY=0.1;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="RoczK8zSZt4-ihxr8N2F-58" target="PWsmGeNbDvQFNoou8pB0-7">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-91" style="edgeStyle=orthogonalEdgeStyle;rounded=0;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.4;entryY=0.1;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="RoczK8zSZt4-ihxr8N2F-58" target="RoczK8zSZt4-ihxr8N2F-8">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-92" value="Frontend resources" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;fontFamily=Architects Daughter;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DArchitects%2BDaughter;sketch=1;curveFitting=1;jiggle=2;fontSize=15;" vertex="1" parent="1">
<mxGeometry x="65" y="-940" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-96" value="" style="swimlane;startSize=0;sketch=1;hachureGap=4;jiggle=2;curveFitting=1;fillColor=#fad9d5;strokeColor=#ae4132;" vertex="1" parent="1">
<mxGeometry x="255" y="-520" width="100" height="80" as="geometry" />
</mxCell>
<mxCell id="RoczK8zSZt4-ihxr8N2F-99" value="StorageClass + PV" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="547.5" y="-430" width="120" height="30" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>
FROM postgres:15-alpine
WORKDIR /healthchecks
COPY postgres.sh .
HEALTHCHECK --interval=5s \
CMD /healthchecks/postgres.sh
FROM redis:alpine
WORKDIR /healthchecks
COPY redis.sh .
HEALTHCHECK --interval=5s \
CMD /healthchecks/redis.sh
#!/bin/bash
set -eo pipefail
host="$(hostname -i || echo '127.0.0.1')"
user="${POSTGRES_USER:-postgres}"
db="${POSTGRES_DB:-$POSTGRES_USER}"
export PGPASSWORD="${POSTGRES_PASSWORD:-}"
args=(
# force postgres to not use the local unix socket (test "external" connectibility)
--host "$host"
--username "$user"
--dbname "$db"
--quiet --no-align --tuples-only
)
if select="$(echo 'SELECT 1' | psql "${args[@]}")" && [ "$select" = '1' ]; then
exit 0
fi
exit 1
#!/bin/sh
set -eo pipefail
host="$(hostname -i || echo '127.0.0.1')"
if ping="$(redis-cli -h "$host" ping)" && [ "$ping" = 'PONG' ]; then
exit 0
fi
exit 1
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: db-data-claim
spec:
storageClassName: standard-rwo # voir kubectl get storageclass
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
# apiVersion: networking.k8s.io/v1
# kind: IngressClass
# metadata:
# labels:
# app.kubernetes.io/component: admission-webhook
# app.kubernetes.io/instance: ingress-nginx
# app.kubernetes.io/name: ingress-nginx
# name: nginx
# spec:
# controller: k8s.io/ingress-nginx
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: pgsql
name: pgsql-deplt
spec:
replicas: 1
selector:
matchLabels:
app: pgsql
template:
metadata:
labels:
app: pgsql
spec:
volumes:
- name: db-data
# emptyDir: {}
persistentVolumeClaim:
claimName: db-data-claim
containers:
- image: postgres:15-alpine
# - image: eloip13009/postgres-hc
# - image: europe-west9-docker.pkg.dev/nuage-k8s/login-nuage-images/postgres-hs
name: postgres-container
env:
- name: POSTGRES_USER
value: postgres
- name: POSTGRES_PASSWORD
value: postgres
ports:
- containerPort: 5432
name: postgres-port
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: db-data
subPath: data
livenessProbe:
exec:
command:
- /healthchecks/postgres.sh
periodSeconds: 15
apiVersion: v1
kind: Service
metadata:
labels:
app: pgsql
name: db
spec:
type: ClusterIP
ports:
- name: pgsql-svc-port
port: 5432
targetPort: postgres-port
selector:
app: pgsql
# apiVersion: apps/v1
# kind: StatefulSet
# metadata:
# labels:
# app: pgsql
# name: pgsql-statefulset
# spec:
# serviceName: pgsql
# replicas: 1
# selector:
# matchLabels:
# app: pgsql
# template:
# metadata:
# labels:
# app: pgsql
# spec:
# volumes:
# - name: db-data
# # emptyDir: {}
# persistentVolumeClaim:
# claimName: db-data-claim
# containers:
# - image: postgres:15-alpine
# name: postgres-container
# env:
# - name: POSTGRES_USER
# value: postgres
# - name: POSTGRES_PASSWORD
# value: postgres
# ports:
# - containerPort: 5432
# name: postgres-port
# volumeMounts:
# - mountPath: /var/lib/postgresql/data
# name: db-data
# subPath: data
# apiVersion: apps/v1
# kind: Deployment
# metadata:
# labels:
# app: redis
# name: redis-deplt
# spec:
# replicas: 1
# selector:
# matchLabels:
# app: redis
# template:
# metadata:
# labels:
# app: redis
# spec:
# containers:
# - image: redis:alpine
# # - image: eloip13009/redis-hc
# # - image: europe-west9-docker.pkg.dev/nuage-k8s/login-nuage-images/redis-hs
# name: redis-container
# ports:
# - containerPort: 6379
# name: redis-port
# livenessProbe:
# exec:
# command:
# - /healthchecks/redis.sh
# periodSeconds: 15
apiVersion: v1
kind: Endpoints
metadata:
name: redis # Must be equal to Service name for automatic mapping
subsets:
- addresses:
- ip: "10.162.0.10" # OpenStack external floating IP
ports:
- port: 6379
# apiVersion: discovery.k8s.io/v1
# kind: EndpointSlice
# metadata:
# name: redis
# labels:
# kubernetes.io/service-name: redis
# addressType: IPv4
# ports:
# - port: 6379
# endpoints:
# - addresses:
# - ip: "10.162.0.6" # external VM IP
apiVersion: v1
kind: Service
metadata:
labels:
app: redis
name: redis
spec:
type: ClusterIP
ports:
- name: redis-svc-port
port: 6379
targetPort: 6379
protocol: TCP
# Do not select anything if Redis is on OpenStack, the 'redis' Endpoint will take over
# selector:
# app: redis
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: result
name: result-deplt
spec:
replicas: 1
selector:
matchLabels:
app: result
template:
metadata:
labels:
app: result
spec:
containers:
# - image: eloip13009/result
- image: europe-west9-docker.pkg.dev/tuto-terraform-406010/voting-app-repo/result
name: result-container
ports:
- containerPort: 80
name: result-port
livenessProbe:
httpGet:
path: /
port: result-port
periodSeconds: 15
timeoutSeconds: 5
failureThreshold: 2
initialDelaySeconds: 5
apiVersion: v1
kind: Service
metadata:
labels:
app: result
name: result
spec:
type: LoadBalancer
ports:
- name: result-svc-port
port: 5050
targetPort: result-port
selector:
app: result
apiVersion: batch/v1
kind: Job
metadata:
labels:
app: seed-job
name: seed-job
spec:
template:
spec:
containers:
- image: europe-west9-docker.pkg.dev/tuto-terraform-406010/voting-app-repo/seed-data
name: seed-job
env:
- name: SEED_HOST
value: "vote"
- name: SEED_PORT
value: "5000"
restartPolicy: Never
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment