Skip to content

Commit 78a2c9e

Browse files
committed
pulumi for gcp gke
1 parent 05b78f8 commit 78a2c9e

7 files changed

Lines changed: 604 additions & 20 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ node_modules
1313
# GENEREATE SDK CLIENT
1414
src
1515
openapi.json
16+
17+
# PULUMI
18+
*.pyc

Pulumi.dev.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
config:
2+
fastapi-rocket-boilerplate:nodesPerZone: "1"
3+
gcp:project: fastapi-rocket-boilerplate
4+
gcp:region: us-central1

Pulumi.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name: fastapi-rocket-boilerplate
2+
runtime:
3+
name: python
4+
options:
5+
virtualenv: venv
6+
description: A Python program to deploy a Kubernetes cluster on Google Cloud

README.md

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
<a href="https://www.docker.com/">
4444
<img src="https://img.shields.io/badge/docker-%230db7ed.svg?style=for-the-badge&logo=docker&logoColor=white" alt="Docker">
4545
</a>
46+
<a href="https://www.docker.com/">
47+
<img src="https://img.shields.io/badge/Pulumi-8A3391?style=for-the-badge&logo=pulumi&logoColor=white" alt="Pulumi">
48+
</a>
4649
</p>
4750

4851
<p align="center"> Also sqlmodel, pydantic, alembic, poetry, ...</p>
@@ -51,7 +54,8 @@
5154

5255
## 🧩 Features
5356

54-
- **Infrastructure**: the common services that every backend needs, served by Docker Compose.
57+
- **Infrastructure**: the common services that every backend needs, served in local by Docker Compose
58+
and in Google Cloud by Pulumi.
5559
- **Easy**: all the commands ready by Makefile.
5660
- **Fast**: thanks to Fastapi and async programming.
5761
- **Async**: Celery using RabbitMQ as broker and Redis as backend.
@@ -65,8 +69,8 @@
6569
## ⚙️ Requirements
6670
- [Python 3.11](https://www.python.org/downloads/release/python-3114/)
6771
- [Docker](https://docs.docker.com/engine/install/)
68-
- [Node](https://nodejs.org/en) (only for SDK frontend generation)
69-
72+
- [Node](https://nodejs.org/en) only for SDK frontend generation
73+
- [Pulumi](https://www.pulumi.com/) only for deploying
7074

7175
## 🎛️ Use
7276
### 🔧 Installation
@@ -200,19 +204,61 @@ You should change the next env vars in `.env`:
200204

201205
Also, it is possible you want to modify the expiry time of access/refresh tokens.
202206

203-
## 🚀 Future features
204-
### Admin
205-
- Search events by model AND id
206-
- Fix popup for reverse_delete
207-
- Relationship of records into model details (performance)
207+
## 🚀 Deploy
208+
We use Pulumi for deploying.
209+
208210

209-
### Others
210-
- Deployment with Kubernetes in Google Cloud by Terraform
211-
- Add logging
211+
### Google Cloud
212+
The DB will be deployed in GCP SQL service.
212213

214+
The rest of the services will be deployed in GCP GKE.
213215

214-
- Integrity tests
215-
- Cover 100% with unit-testing
216-
- Add mypy and pylint to the Pre-commit
217-
- Use async/await for routes and database connections
218-
- Authentication client with Google
216+
1. Log in Google cloud
217+
```shell
218+
gcloud auth application-default login
219+
```
220+
2. Create a new project in Google console
221+
3. Set the project in gcloud
222+
```shell
223+
gcloud config set project <YOUR_GCP_PROJECT_ID>
224+
```
225+
To find it, you can run:
226+
```shell
227+
gcloud projects list
228+
```
229+
4. Modify `Pulumi-dev.yaml` with your GCP project and region.
230+
5. Modify the begging of `__main__.py` with your variables
231+
6. run:
232+
```
233+
pulumi up
234+
```
235+
236+
✅ It is done, your project is alive!
237+
238+
239+
## 🔮 Future features
240+
241+
### Deployment
242+
- [x] Deployment with Kubernetes in Google Cloud by Pulumi
243+
- [ ] Deployment with Kubernetes in AWS by Pulumi
244+
245+
### Monitoring
246+
- [ ] Add logging
247+
- [ ] Add Sentry
248+
- [ ] Add Flower
249+
250+
### Testing
251+
- [ ] Integrity tests
252+
- [ ] Cover 100% with unit-testing
253+
- [ ] Add mypy and pylint to the Pre-commit
254+
255+
### Async
256+
- [ ] Use 100% async/await for routes and database connections
257+
258+
### Auth
259+
- [ ] Authentication client with Google
260+
261+
### Admin
262+
- [ ] Search events by model AND id
263+
- [ ] Fix popup for reverse_delete
264+
- [ ] Relationship of records into model details (performance)

__main__.py

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
"""A Google Cloud Python Pulumi program"""
2+
3+
import pulumi
4+
import pulumi_gcp as gcp
5+
import pulumi_kubernetes as k8s
6+
from pulumi_gcp import storage
7+
8+
# SET YOUR VARIABLES
9+
db_instance_name = "instance"
10+
region = "us-central1"
11+
db_tier = "db-f1-micro"
12+
db_user = "myuser"
13+
db_password = "mypassword"
14+
15+
16+
# See versions at https://registry.terraform.io
17+
# /providers/hashicorp/google/latest/docs/resources
18+
# /sql_database_instance#database_version
19+
instance = gcp.sql.DatabaseInstance(
20+
db_instance_name,
21+
region=region,
22+
database_version="POSTGRES_15",
23+
settings=gcp.sql.DatabaseInstanceSettingsArgs(
24+
tier=db_tier,
25+
),
26+
deletion_protection=True,
27+
)
28+
29+
database_user = gcp.sql.User(
30+
db_user, instance=instance.name, password=db_password
31+
)
32+
33+
database = gcp.sql.Database("database", instance=instance.name)
34+
35+
# Create a GCP resource (Storage Bucket)
36+
bucket = storage.Bucket("my-bucket", location="US")
37+
38+
# Export the DNS name of the bucket
39+
pulumi.export("bucket_name", bucket.url)
40+
41+
42+
# Define your Google Cloud project
43+
project = "your-gcp-project"
44+
gcp_config = pulumi.Config("gcp")
45+
project = gcp_config.get("project") or project
46+
47+
# Configure the GKE cluster
48+
cluster_name = "my-gke-cluster"
49+
cluster = gcp.container.Cluster(
50+
cluster_name,
51+
initial_node_count=1,
52+
min_master_version="latest",
53+
node_version="latest",
54+
project=project,
55+
location="us-central1",
56+
)
57+
58+
# Use gcp.container.getClusterCredentials to get Kubernetes config
59+
kubeconfig = pulumi.Output.all(cluster.name, project).apply(
60+
lambda args: gcp.container.get_cluster_credentials(
61+
cluster_name=args[0], project=args[1]
62+
)
63+
)
64+
65+
# Define the configuration for your Kubernetes services
66+
67+
# App Deployment
68+
app_deployment = k8s.apps.v1.Deployment(
69+
"app-deployment",
70+
metadata={
71+
"name": "app-deployment",
72+
},
73+
spec={
74+
"replicas": 2,
75+
"selector": {
76+
"matchLabels": {"app": "app"},
77+
},
78+
"template": {
79+
"metadata": {"labels": {"app": "app"}},
80+
"spec": {
81+
"containers": [
82+
{
83+
"name": "app-container",
84+
"image": "your-app-image:latest",
85+
"ports": [{"containerPort": 8000}],
86+
# You can add additional
87+
# configurations and resources here
88+
}
89+
]
90+
},
91+
},
92+
},
93+
)
94+
95+
# Celery Deployment
96+
celery_deployment = k8s.apps.v1.Deployment(
97+
"celery-deployment",
98+
metadata={
99+
"name": "celery-deployment",
100+
},
101+
spec={
102+
"replicas": 2, # Adjust as needed
103+
"selector": {
104+
"matchLabels": {"app": "celery"},
105+
},
106+
"template": {
107+
"metadata": {"labels": {"app": "celery"}},
108+
"spec": {
109+
"containers": [
110+
{
111+
"name": "celery-container",
112+
"image": "your-celery-image:latest",
113+
# Add any necessary command and args here
114+
# You can add additional configurations
115+
# and resources here
116+
}
117+
]
118+
},
119+
},
120+
},
121+
)
122+
123+
# Redis Deployment
124+
redis_deployment = k8s.apps.v1.Deployment(
125+
"redis-deployment",
126+
metadata={
127+
"name": "redis-deployment",
128+
},
129+
spec={
130+
"replicas": 1, # Redis is typically deployed with a single node
131+
"selector": {
132+
"matchLabels": {"app": "redis"},
133+
},
134+
"template": {
135+
"metadata": {"labels": {"app": "redis"}},
136+
"spec": {
137+
"containers": [
138+
{
139+
"name": "redis-container",
140+
"image": "redis:latest",
141+
"ports": [{"containerPort": 6379}],
142+
# You can add additional configurations
143+
# and resources here
144+
}
145+
]
146+
},
147+
},
148+
},
149+
)
150+
151+
# RabbitMQ Deployment
152+
rabbitmq_deployment = k8s.apps.v1.Deployment(
153+
"rabbitmq-deployment",
154+
metadata={
155+
"name": "rabbitmq-deployment",
156+
},
157+
spec={
158+
"replicas": 1, # RabbitMQ is typically deployed with a single node
159+
"selector": {
160+
"matchLabels": {"app": "rabbitmq"},
161+
},
162+
"template": {
163+
"metadata": {"labels": {"app": "rabbitmq"}},
164+
"spec": {
165+
"containers": [
166+
{
167+
"name": "rabbitmq-container",
168+
"image": "rabbitmq:3.6-management",
169+
"ports": [
170+
{"containerPort": 5672},
171+
{"containerPort": 15672},
172+
], # RabbitMQ ports
173+
# You can add additional configurations
174+
# and resources here
175+
}
176+
]
177+
},
178+
},
179+
},
180+
)
181+
182+
# Export useful information
183+
pulumi.export("cluster_name", cluster.name)
184+
pulumi.export("kubeconfig", cluster.kube_config)
185+
186+
# Deploy the infrastructure
187+
pulumi.export("app_deployment", app_deployment.metadata)
188+
pulumi.export("celery_deployment", celery_deployment.metadata)
189+
pulumi.export("redis_deployment", redis_deployment.metadata)
190+
pulumi.export("rabbitmq_deployment", rabbitmq_deployment.metadata)

0 commit comments

Comments
 (0)