If you are looking for a simpler service than Kubernetes to deploy and manage containers on an environment (even in prod), Google Cloud offers a turnkey service that could be used, which is called Cloud Run.
The purpose of this article is to go a little further than the Quickstart, to show you how to deploy a simple python container, via Terraform.
Prerequisites for the demo
First, you will need this elements :
- Terraform: Install Terraform
- Google Cloud SDK: Install gcloud
- A Google Cloud Platform (GCP) Project: Create a GCP project
Then, create the Cloudbuild trigger in the GCP console :
- Go to the Cloud Build Triggers page.
- Click on Create Trigger.
- Set the following options:
-
Name:
your-github-trigger
-
Event:
Push to a branch
-
Source:
GitHub
- Repository: Select the repository you created for this project.
-
Branch:
main
-
Build Configuration:
Cloud Build configuration file (yaml or json)
-
Name:
- Click Create to finish setting up the trigger.
Note : create a service account with the name sa-cloudbuild
and assign it the Cloud Build Service Account
and Storage Admin
roles. This service account will be used by Cloud Build to deploy the application to Cloud Run.
Terraform resources
To create a repository in Artifact Registry :
resource "google_artifact_registry_repository" "repo" {
location = var.region
repository_id = "flask-repo"
description = "Repository for Flask app"
format = "DOCKER"
labels = {
managed_by = "terraform"
}
}
Create the simple app :
# main.py
import os
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
"""Example Hello World route."""
name = os.environ.get("NAME", "World")
return f"Hello {name}!"
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))
With this requirements :
# requirements.txt
Flask==3.0.3
gunicorn==23.0.0
Werkzeug==3.0.3
And this Dockerfile :
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt main.py ./
RUN pip install --no-cache-dir -r requirements.txt
EXPOSE 8080
ENV NAME=World
ENV PORT=8080
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "main:app"]
Here is the terraform code to build & push the container with Cloud Build :
resource "null_resource" "build_image" {
triggers = {
dockerfile_hash = filemd5("${path.root}/app/Dockerfile")
main_py_hash = filemd5("${path.root}/app/main.py")
requirements_hash = filemd5("${path.root}/app/requirements.txt")
}
provisioner "local-exec" {
command = <<-EOT
gcloud builds submit ${path.root}/app \
--tag ${var.region}-docker.pkg.dev/${var.project_id}/${google_artifact_registry_repository.repo.repository_id}/flask-app:latest \
--project ${var.project_id}
EOT
}
depends_on = [
google_artifact_registry_repository.repo
]
}
For our example, I choosed to launch it directly from Terraform, without the necessity to have Docker or Podman installed, just Gcloud Cli.
And finally the Terraform code to create the Cloud Run Service :
# Cloud Run Service
##
resource "google_cloud_run_v2_service" "flask_service" {
name = var.service_name
location = var.region
labels = {
managed_by = "terraform"
}
template {
labels = {
managed_by = "terraform"
}
containers {
image = "${var.region}-docker.pkg.dev/${var.project_id}/${google_artifact_registry_repository.repo.repository_id}/flask-app:latest"
ports {
container_port = 8080
}
env {
name = "NAME"
value = "Cloud Run"
}
resources {
limits = {
cpu = "1000m"
memory = "512Mi"
}
}
}
scaling {
min_instance_count = 0
max_instance_count = 3
}
}
depends_on = [
null_resource.build_image
]
}
# IAM policy to allow public access
##
resource "google_cloud_run_service_iam_member" "public_access" {
service = google_cloud_run_v2_service.flask_service.name
location = google_cloud_run_v2_service.flask_service.location
role = "roles/run.invoker"
member = "allUsers"
}
This outputs will give you the urls generated for your service, and the registry :
output "service_url" {
description = "URL of the Cloud Run service"
value = google_cloud_run_v2_service.flask_service.uri
}
output "artifact_registry_url" {
description = "Artifact Registry repository URL"
value = google_artifact_registry_repository.repo.name
}
Now you can launch a plan and apply your code, you have a container you can work on, handle a service managed by Google Cloud.
All the code is available in this github repository.
There is an “Awesome CloudRun” page where you will find a lot of interesting usages for Cloud Run.
Google also offers some Codelabs where you can get trained and explore advanced use cases with Cloud Run.
Now you can use and improve your configuration to work with your containers, have fun with it.
Top comments (0)