cp
This commit is contained in:
parent
ae219c8111
commit
f1c41a074d
4
.gitignore
vendored
4
.gitignore
vendored
@ -49,3 +49,7 @@ htmlcov/
|
||||
.coverage.*
|
||||
coverage.xml
|
||||
*.cover
|
||||
|
||||
# Terraform
|
||||
*.tfvars
|
||||
.terraform
|
||||
|
||||
64
deployment/README.md
Normal file
64
deployment/README.md
Normal file
@ -0,0 +1,64 @@
|
||||
# Deployment Options for Sereact
|
||||
|
||||
This directory contains multiple options for deploying the Sereact application:
|
||||
|
||||
## Terraform Infrastructure (`/terraform`)
|
||||
|
||||
The Terraform configuration automates the provisioning of all required Google Cloud resources:
|
||||
|
||||
- Google Cloud Run service
|
||||
- Google Container Registry (GCR)
|
||||
- Cloud Firestore
|
||||
- Cloud Storage buckets
|
||||
|
||||
See [terraform/README.md](terraform/README.md) for detailed instructions.
|
||||
|
||||
## Cloud Run Deployment (`/cloud-run`)
|
||||
|
||||
The `service.yaml` file defines the Cloud Run service configuration which can be deployed using:
|
||||
|
||||
```bash
|
||||
gcloud run services replace deployment/cloud-run/service.yaml --region=us-central1
|
||||
```
|
||||
|
||||
## Deployment Script (`deploy.sh`)
|
||||
|
||||
For convenience, a deployment script is provided to handle the entire deployment workflow:
|
||||
|
||||
```bash
|
||||
# Provision infrastructure with Terraform
|
||||
./deployment/deploy.sh --provision
|
||||
|
||||
# Build and push Docker image
|
||||
./deployment/deploy.sh --build
|
||||
|
||||
# Deploy to Cloud Run
|
||||
./deployment/deploy.sh --deploy
|
||||
|
||||
# Do everything (provision, build, deploy)
|
||||
./deployment/deploy.sh --all
|
||||
```
|
||||
|
||||
## CI/CD Pipelines
|
||||
|
||||
For CI/CD integration, consider using:
|
||||
|
||||
1. **GitHub Actions**: Sample workflow included in terraform/README.md
|
||||
2. **Cloud Build**: Configure a `cloudbuild.yaml` in your repository
|
||||
3. **Jenkins**: Use the `deploy.sh` script in your pipeline
|
||||
|
||||
## Managing Secrets
|
||||
|
||||
Sensitive data should be managed using Google Secret Manager:
|
||||
|
||||
```bash
|
||||
# Create a secret
|
||||
gcloud secrets create sereact-db-uri --replication-policy="automatic"
|
||||
|
||||
# Add a secret version
|
||||
echo -n "your-mongodb-uri" | gcloud secrets versions add sereact-db-uri --data-file=-
|
||||
|
||||
# Update Cloud Run service to use the secret
|
||||
gcloud run services update sereact \
|
||||
--update-secrets=DATABASE_URI=sereact-db-uri:latest
|
||||
```
|
||||
54
deployment/cloudbuild.yaml
Normal file
54
deployment/cloudbuild.yaml
Normal file
@ -0,0 +1,54 @@
|
||||
steps:
|
||||
# Build the container image
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: ['build', '-t', 'gcr.io/$PROJECT_ID/sereact:$COMMIT_SHA', '.']
|
||||
|
||||
# Push the container image to Container Registry
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: ['push', 'gcr.io/$PROJECT_ID/sereact:$COMMIT_SHA']
|
||||
|
||||
# Tag the image as latest
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: ['tag', 'gcr.io/$PROJECT_ID/sereact:$COMMIT_SHA', 'gcr.io/$PROJECT_ID/sereact:latest']
|
||||
|
||||
# Push the latest tag
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: ['push', 'gcr.io/$PROJECT_ID/sereact:latest']
|
||||
|
||||
# Deploy to Cloud Run
|
||||
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
|
||||
entrypoint: gcloud
|
||||
args:
|
||||
- 'run'
|
||||
- 'deploy'
|
||||
- 'sereact'
|
||||
- '--image=gcr.io/$PROJECT_ID/sereact:$COMMIT_SHA'
|
||||
- '--region=us-central1'
|
||||
- '--platform=managed'
|
||||
- '--allow-unauthenticated'
|
||||
- '--set-env-vars=GCS_BUCKET_NAME=${_GCS_BUCKET_NAME},DATABASE_NAME=${_DATABASE_NAME},VECTOR_DB_ENVIRONMENT=${_VECTOR_DB_ENVIRONMENT},VECTOR_DB_INDEX_NAME=${_VECTOR_DB_INDEX_NAME},LOG_LEVEL=INFO'
|
||||
- '--set-secrets=DATABASE_URI=sereact-db-uri:latest,API_KEY_SECRET=sereact-api-key-secret:latest,VECTOR_DB_API_KEY=sereact-vector-db-key:latest'
|
||||
|
||||
# Optional: Run tests after deployment
|
||||
# - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
|
||||
# entrypoint: /bin/bash
|
||||
# args:
|
||||
# - '-c'
|
||||
# - |
|
||||
# SERVICE_URL=$(gcloud run services describe sereact --region=us-central1 --format='value(status.url)')
|
||||
# curl -s -o /dev/null -w "%{http_code}" $${SERVICE_URL}/health | grep 200
|
||||
|
||||
# Store images in Container Registry
|
||||
images:
|
||||
- 'gcr.io/$PROJECT_ID/sereact:$COMMIT_SHA'
|
||||
- 'gcr.io/$PROJECT_ID/sereact:latest'
|
||||
|
||||
# Substitution variables to be set in the Cloud Build trigger
|
||||
substitutions:
|
||||
_GCS_BUCKET_NAME: 'your-app-storage-bucket'
|
||||
_DATABASE_NAME: 'imagedb'
|
||||
_VECTOR_DB_ENVIRONMENT: 'your-pinecone-env'
|
||||
_VECTOR_DB_INDEX_NAME: 'image-embeddings'
|
||||
|
||||
# Increase timeout to 30 minutes
|
||||
timeout: '1800s'
|
||||
142
deployment/deploy.sh
Normal file
142
deployment/deploy.sh
Normal file
@ -0,0 +1,142 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
PROJECT_ID=$(gcloud config get-value project)
|
||||
IMAGE_NAME="sereact"
|
||||
REGION="us-central1"
|
||||
SERVICE_NAME="sereact"
|
||||
|
||||
# Help function
|
||||
function show_help {
|
||||
echo "Usage: $0 [options]"
|
||||
echo "Options:"
|
||||
echo " --provision Run Terraform to provision cloud resources"
|
||||
echo " --build Build and push Docker image"
|
||||
echo " --deploy Deploy to Cloud Run"
|
||||
echo " --all Do all of the above"
|
||||
echo " --help Show this help message"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Check if any arguments were provided
|
||||
if [ $# -eq 0 ]; then
|
||||
show_help
|
||||
fi
|
||||
|
||||
# Process arguments
|
||||
PROVISION=false
|
||||
BUILD=false
|
||||
DEPLOY=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--provision)
|
||||
PROVISION=true
|
||||
shift
|
||||
;;
|
||||
--build)
|
||||
BUILD=true
|
||||
shift
|
||||
;;
|
||||
--deploy)
|
||||
DEPLOY=true
|
||||
shift
|
||||
;;
|
||||
--all)
|
||||
PROVISION=true
|
||||
BUILD=true
|
||||
DEPLOY=true
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
show_help
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
show_help
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Ensure gcloud is configured
|
||||
if [ -z "$PROJECT_ID" ]; then
|
||||
echo "ERROR: No Google Cloud project is set. Run 'gcloud config set project YOUR_PROJECT_ID'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Using Google Cloud project: $PROJECT_ID"
|
||||
echo "==================================="
|
||||
|
||||
# Provision resources with Terraform
|
||||
if [ "$PROVISION" = true ]; then
|
||||
echo "Provisioning cloud resources with Terraform..."
|
||||
cd "$(dirname "$0")/terraform"
|
||||
|
||||
# Check if terraform.tfvars exists, if not copy from example
|
||||
if [ ! -f terraform.tfvars ]; then
|
||||
echo "Creating terraform.tfvars from example..."
|
||||
cp terraform.tfvars.example terraform.tfvars
|
||||
# Replace project ID in tfvars file
|
||||
sed -i "s/your-gcp-project-id/$PROJECT_ID/g" terraform.tfvars
|
||||
echo "Please review and edit terraform.tfvars with your desired values"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
terraform init
|
||||
terraform apply
|
||||
|
||||
cd - > /dev/null
|
||||
echo "Provisioning completed."
|
||||
fi
|
||||
|
||||
# Build and push Docker image
|
||||
if [ "$BUILD" = true ]; then
|
||||
echo "Building and pushing Docker image..."
|
||||
|
||||
# Enable Docker to authenticate to GCR
|
||||
gcloud auth configure-docker gcr.io
|
||||
|
||||
# Build the image with timestamp tag
|
||||
TAG=$(date +%Y%m%d-%H%M%S)
|
||||
FULL_IMAGE_NAME="gcr.io/$PROJECT_ID/$IMAGE_NAME:$TAG"
|
||||
LATEST_IMAGE_NAME="gcr.io/$PROJECT_ID/$IMAGE_NAME:latest"
|
||||
|
||||
echo "Building image: $FULL_IMAGE_NAME"
|
||||
docker build -t "$FULL_IMAGE_NAME" -t "$LATEST_IMAGE_NAME" .
|
||||
|
||||
echo "Pushing images to Container Registry..."
|
||||
docker push "$FULL_IMAGE_NAME"
|
||||
docker push "$LATEST_IMAGE_NAME"
|
||||
|
||||
echo "Image built and pushed successfully."
|
||||
fi
|
||||
|
||||
# Deploy to Cloud Run
|
||||
if [ "$DEPLOY" = true ]; then
|
||||
echo "Deploying to Cloud Run..."
|
||||
|
||||
# Deploy using the latest image
|
||||
LATEST_IMAGE_NAME="gcr.io/$PROJECT_ID/$IMAGE_NAME:latest"
|
||||
|
||||
# Check if we have an existing service.yaml to use
|
||||
if [ -f "$(dirname "$0")/cloud-run/service.yaml" ]; then
|
||||
echo "Deploying using service.yaml configuration..."
|
||||
gcloud run services replace "$(dirname "$0")/cloud-run/service.yaml" --region="$REGION"
|
||||
else
|
||||
echo "Deploying directly..."
|
||||
gcloud run deploy "$SERVICE_NAME" \
|
||||
--image="$LATEST_IMAGE_NAME" \
|
||||
--platform="managed" \
|
||||
--region="$REGION" \
|
||||
--allow-unauthenticated
|
||||
fi
|
||||
|
||||
# Get service URL
|
||||
SERVICE_URL=$(gcloud run services describe "$SERVICE_NAME" --region="$REGION" --format='value(status.url)')
|
||||
|
||||
echo "Deployment completed successfully."
|
||||
echo "Service URL: $SERVICE_URL"
|
||||
fi
|
||||
|
||||
echo "All operations completed."
|
||||
21
deployment/terraform/.terraform.lock.hcl
generated
Normal file
21
deployment/terraform/.terraform.lock.hcl
generated
Normal file
@ -0,0 +1,21 @@
|
||||
# This file is maintained automatically by "terraform init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.terraform.io/hashicorp/google" {
|
||||
version = "6.36.1"
|
||||
hashes = [
|
||||
"h1:rj3g00i0dH4VxXYO5xXJg188i6OXWbFUT6WmLbO5orY=",
|
||||
"zh:161d054bda352a286a997f80f3d59366d072377abc6777bfe8abacc2e10ac2bf",
|
||||
"zh:314c38d8050036176031f691b533184c3578036085483fed877b3b139f887047",
|
||||
"zh:503c9807312feb9766f0da207d5ac149aa6f5a669144c60da38a33d072ebe2c2",
|
||||
"zh:897abe484c44c625b301e828a4967c9f781fbf33b5bb50afe226410ebbfd0137",
|
||||
"zh:97bcdc879b48f5f8bee98316234a1eed3c2e440e356631066d07b5d85ccfe288",
|
||||
"zh:b273e940da85c5d673cbb3cafe36fb70dd8536e2d8812e617191196c312dac3b",
|
||||
"zh:ba294699ca7082d394498ce62ecb55501c6a141fd1c43db00a6abdaebc92fa2e",
|
||||
"zh:c50be96b5c8df5124f18ccdef473eed0bc3a2452e674c19f58fbf7ee14195af4",
|
||||
"zh:d5a8fda3abda57d912be020e22bab3568facc729756e5339af9a3e56ca277cbc",
|
||||
"zh:dddbfed09dff01fe538830714a13e71d7581cf2ccfba15acc0a6bb7266147bed",
|
||||
"zh:e65e8c2e97d1e23c9380516b1d37e111cc700b538d8fca6b9e28ebb89e305ee0",
|
||||
"zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
|
||||
]
|
||||
}
|
||||
95
deployment/terraform/README.md
Normal file
95
deployment/terraform/README.md
Normal file
@ -0,0 +1,95 @@
|
||||
# Terraform Configuration for Sereact
|
||||
|
||||
This directory contains Terraform configurations to provision the required Google Cloud resources for Sereact:
|
||||
|
||||
- Google Cloud Run service
|
||||
- Google Container Registry (GCR)
|
||||
- Firestore database
|
||||
- Cloud Storage bucket
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Install [Terraform](https://www.terraform.io/downloads) (v1.0.0+)
|
||||
2. Install [Google Cloud SDK](https://cloud.google.com/sdk/docs/install)
|
||||
3. Authenticate with Google Cloud:
|
||||
```bash
|
||||
gcloud auth login
|
||||
gcloud auth application-default login
|
||||
```
|
||||
4. Create or select a Google Cloud project:
|
||||
```bash
|
||||
gcloud projects create PROJECT_ID --name="Sereact Project" # optional
|
||||
gcloud config set project PROJECT_ID
|
||||
```
|
||||
|
||||
## Setup and Usage
|
||||
|
||||
1. Copy the example variables file and edit it with your values:
|
||||
```bash
|
||||
cp terraform.tfvars.example terraform.tfvars
|
||||
# Edit terraform.tfvars with your project-specific values
|
||||
```
|
||||
|
||||
2. Initialize Terraform:
|
||||
```bash
|
||||
terraform init
|
||||
```
|
||||
|
||||
3. Preview the changes:
|
||||
```bash
|
||||
terraform plan
|
||||
```
|
||||
|
||||
4. Apply the configuration:
|
||||
```bash
|
||||
terraform apply
|
||||
```
|
||||
|
||||
5. After provisioning, you'll see outputs including:
|
||||
- Cloud Run service URL
|
||||
- Storage bucket name
|
||||
- Firestore database ID
|
||||
- Container Registry URL
|
||||
|
||||
## Managing Secrets
|
||||
|
||||
Secrets for environment variables (DATABASE_URI, API_KEY_SECRET, etc.) should be managed separately using Google Secret Manager:
|
||||
|
||||
```bash
|
||||
# Create secrets
|
||||
gcloud secrets create sereact-db-uri --replication-policy="automatic"
|
||||
gcloud secrets create sereact-api-key-secret --replication-policy="automatic"
|
||||
gcloud secrets create sereact-vector-db-key --replication-policy="automatic"
|
||||
|
||||
# Add secret versions
|
||||
echo -n "your-secret-value" | gcloud secrets versions add sereact-db-uri --data-file=-
|
||||
echo -n "your-secret-value" | gcloud secrets versions add sereact-api-key-secret --data-file=-
|
||||
echo -n "your-secret-value" | gcloud secrets versions add sereact-vector-db-key --data-file=-
|
||||
|
||||
# Update Cloud Run service to use secrets
|
||||
gcloud run services update sereact \
|
||||
--update-secrets=DATABASE_URI=sereact-db-uri:latest,API_KEY_SECRET=sereact-api-key-secret:latest,VECTOR_DB_API_KEY=sereact-vector-db-key:latest
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
To integrate this with CI/CD, store the `terraform.tfvars` securely in your CI/CD system and run Terraform as part of your deployment pipeline:
|
||||
|
||||
```yaml
|
||||
# Example GitHub Actions step
|
||||
- name: Terraform Apply
|
||||
run: |
|
||||
cd deployment/terraform
|
||||
terraform init
|
||||
terraform apply -auto-approve
|
||||
env:
|
||||
GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GCP_SA_KEY }}
|
||||
```
|
||||
|
||||
## Destroying Resources
|
||||
|
||||
To destroy all provisioned resources:
|
||||
|
||||
```bash
|
||||
terraform destroy
|
||||
```
|
||||
94
deployment/terraform/main.tf
Normal file
94
deployment/terraform/main.tf
Normal file
@ -0,0 +1,94 @@
|
||||
provider "google" {
|
||||
project = var.project_id
|
||||
region = var.region
|
||||
zone = var.zone
|
||||
}
|
||||
|
||||
# Enable required APIs
|
||||
resource "google_project_service" "services" {
|
||||
for_each = toset([
|
||||
"cloudresourcemanager.googleapis.com",
|
||||
"containerregistry.googleapis.com",
|
||||
"run.googleapis.com",
|
||||
"firestore.googleapis.com",
|
||||
"storage.googleapis.com"
|
||||
])
|
||||
|
||||
project = var.project_id
|
||||
service = each.key
|
||||
|
||||
disable_on_destroy = false
|
||||
}
|
||||
|
||||
# Cloud Storage bucket
|
||||
resource "google_storage_bucket" "app_bucket" {
|
||||
name = var.storage_bucket_name
|
||||
location = var.region
|
||||
uniform_bucket_level_access = true
|
||||
|
||||
depends_on = [google_project_service.services]
|
||||
}
|
||||
|
||||
# Firestore Database
|
||||
resource "google_firestore_database" "database" {
|
||||
name = var.firestore_db_name
|
||||
location_id = var.region
|
||||
type = "FIRESTORE_NATIVE"
|
||||
|
||||
depends_on = [google_project_service.services]
|
||||
}
|
||||
|
||||
# Container Registry - no explicit resource needed, just enable the API
|
||||
# You'll push images to gcr.io/${var.project_id}/sereact
|
||||
|
||||
# Cloud Run service
|
||||
resource "google_cloud_run_service" "sereact" {
|
||||
name = "sereact"
|
||||
location = var.region
|
||||
|
||||
template {
|
||||
spec {
|
||||
containers {
|
||||
# Using a public placeholder image that exists to avoid deployment failure
|
||||
# You'll need to update this later with your actual image
|
||||
image = "gcr.io/google-samples/hello-app:1.0"
|
||||
|
||||
ports {
|
||||
container_port = 8080
|
||||
}
|
||||
|
||||
resources {
|
||||
limits = {
|
||||
cpu = "1"
|
||||
memory = "512Mi"
|
||||
}
|
||||
}
|
||||
|
||||
env {
|
||||
name = "DATABASE_NAME"
|
||||
value = var.firestore_db_name
|
||||
}
|
||||
|
||||
env {
|
||||
name = "GCS_BUCKET_NAME"
|
||||
value = var.storage_bucket_name
|
||||
}
|
||||
|
||||
env {
|
||||
name = "LOG_LEVEL"
|
||||
value = "INFO"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [google_project_service.services]
|
||||
}
|
||||
|
||||
# Make the Cloud Run service publicly accessible
|
||||
resource "google_cloud_run_service_iam_member" "public_access" {
|
||||
service = google_cloud_run_service.sereact.name
|
||||
location = google_cloud_run_service.sereact.location
|
||||
role = "roles/run.invoker"
|
||||
member = "allUsers"
|
||||
}
|
||||
19
deployment/terraform/outputs.tf
Normal file
19
deployment/terraform/outputs.tf
Normal file
@ -0,0 +1,19 @@
|
||||
output "cloud_run_url" {
|
||||
value = google_cloud_run_service.sereact.status[0].url
|
||||
description = "The URL of the deployed Cloud Run service"
|
||||
}
|
||||
|
||||
output "storage_bucket_name" {
|
||||
value = google_storage_bucket.app_bucket.name
|
||||
description = "The name of the provisioned Cloud Storage bucket"
|
||||
}
|
||||
|
||||
output "firestore_database_id" {
|
||||
value = google_firestore_database.database.id
|
||||
description = "The ID of the provisioned Firestore database"
|
||||
}
|
||||
|
||||
output "container_registry_url" {
|
||||
value = "gcr.io/${var.project_id}/sereact"
|
||||
description = "The URL of the Container Registry repository"
|
||||
}
|
||||
9
deployment/terraform/terraform.tfstate
Normal file
9
deployment/terraform/terraform.tfstate
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"version": 4,
|
||||
"terraform_version": "1.10.1",
|
||||
"serial": 28,
|
||||
"lineage": "a183cd95-f987-8698-c6dd-84e933c394a5",
|
||||
"outputs": {},
|
||||
"resources": [],
|
||||
"check_results": null
|
||||
}
|
||||
416
deployment/terraform/terraform.tfstate.backup
Normal file
416
deployment/terraform/terraform.tfstate.backup
Normal file
@ -0,0 +1,416 @@
|
||||
{
|
||||
"version": 4,
|
||||
"terraform_version": "1.10.1",
|
||||
"serial": 18,
|
||||
"lineage": "a183cd95-f987-8698-c6dd-84e933c394a5",
|
||||
"outputs": {
|
||||
"cloud_run_url": {
|
||||
"value": "https://sereact-p64zpdtkta-uc.a.run.app",
|
||||
"type": "string"
|
||||
},
|
||||
"container_registry_url": {
|
||||
"value": "gcr.io/gen-lang-client-0424120530/sereact",
|
||||
"type": "string"
|
||||
},
|
||||
"firestore_database_id": {
|
||||
"value": "projects/gen-lang-client-0424120530/databases/imagedb",
|
||||
"type": "string"
|
||||
},
|
||||
"storage_bucket_name": {
|
||||
"value": "sereact-storage-bucket",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"mode": "managed",
|
||||
"type": "google_cloud_run_service",
|
||||
"name": "sereact",
|
||||
"provider": "provider[\"registry.terraform.io/hashicorp/google\"]",
|
||||
"instances": [
|
||||
{
|
||||
"schema_version": 2,
|
||||
"attributes": {
|
||||
"autogenerate_revision_name": false,
|
||||
"id": "locations/us-central1/namespaces/gen-lang-client-0424120530/services/sereact",
|
||||
"location": "us-central1",
|
||||
"metadata": [
|
||||
{
|
||||
"annotations": {},
|
||||
"effective_annotations": {
|
||||
"run.googleapis.com/ingress": "all",
|
||||
"run.googleapis.com/ingress-status": "all",
|
||||
"run.googleapis.com/operation-id": "0982194f-b3e8-45b8-a33f-7ed5fd529307",
|
||||
"run.googleapis.com/urls": "[\"https://sereact-761163285547.us-central1.run.app\",\"https://sereact-p64zpdtkta-uc.a.run.app\"]",
|
||||
"serving.knative.dev/creator": "johnpccd3@gmail.com",
|
||||
"serving.knative.dev/lastModifier": "johnpccd3@gmail.com"
|
||||
},
|
||||
"effective_labels": {
|
||||
"cloud.googleapis.com/location": "us-central1"
|
||||
},
|
||||
"generation": 1,
|
||||
"labels": {},
|
||||
"namespace": "gen-lang-client-0424120530",
|
||||
"resource_version": "AAY108GXDwM",
|
||||
"self_link": "/apis/serving.knative.dev/v1/namespaces/761163285547/services/sereact",
|
||||
"terraform_labels": {},
|
||||
"uid": "5b695749-5095-4fb5-86bd-4d86f77dc7da"
|
||||
}
|
||||
],
|
||||
"name": "sereact",
|
||||
"project": "gen-lang-client-0424120530",
|
||||
"status": [
|
||||
{
|
||||
"conditions": [
|
||||
{
|
||||
"message": "",
|
||||
"reason": "",
|
||||
"status": "True",
|
||||
"type": "Ready"
|
||||
},
|
||||
{
|
||||
"message": "",
|
||||
"reason": "",
|
||||
"status": "True",
|
||||
"type": "ConfigurationsReady"
|
||||
},
|
||||
{
|
||||
"message": "",
|
||||
"reason": "",
|
||||
"status": "True",
|
||||
"type": "RoutesReady"
|
||||
}
|
||||
],
|
||||
"latest_created_revision_name": "sereact-00001-bt2",
|
||||
"latest_ready_revision_name": "sereact-00001-bt2",
|
||||
"observed_generation": 1,
|
||||
"traffic": [
|
||||
{
|
||||
"latest_revision": true,
|
||||
"percent": 100,
|
||||
"revision_name": "sereact-00001-bt2",
|
||||
"tag": "",
|
||||
"url": ""
|
||||
}
|
||||
],
|
||||
"url": "https://sereact-p64zpdtkta-uc.a.run.app"
|
||||
}
|
||||
],
|
||||
"template": [
|
||||
{
|
||||
"metadata": [
|
||||
{
|
||||
"annotations": {
|
||||
"autoscaling.knative.dev/maxScale": "3"
|
||||
},
|
||||
"generation": 0,
|
||||
"labels": {
|
||||
"run.googleapis.com/startupProbeType": "Default"
|
||||
},
|
||||
"name": "",
|
||||
"namespace": "",
|
||||
"resource_version": "",
|
||||
"self_link": "",
|
||||
"uid": ""
|
||||
}
|
||||
],
|
||||
"spec": [
|
||||
{
|
||||
"container_concurrency": 80,
|
||||
"containers": [
|
||||
{
|
||||
"args": null,
|
||||
"command": null,
|
||||
"env": [
|
||||
{
|
||||
"name": "DATABASE_NAME",
|
||||
"value": "imagedb",
|
||||
"value_from": []
|
||||
},
|
||||
{
|
||||
"name": "GCS_BUCKET_NAME",
|
||||
"value": "sereact-storage-bucket",
|
||||
"value_from": []
|
||||
},
|
||||
{
|
||||
"name": "LOG_LEVEL",
|
||||
"value": "INFO",
|
||||
"value_from": []
|
||||
}
|
||||
],
|
||||
"env_from": [],
|
||||
"image": "gcr.io/google-samples/hello-app:1.0",
|
||||
"liveness_probe": [],
|
||||
"name": "",
|
||||
"ports": [
|
||||
{
|
||||
"container_port": 8080,
|
||||
"name": "http1",
|
||||
"protocol": ""
|
||||
}
|
||||
],
|
||||
"resources": [
|
||||
{
|
||||
"limits": {
|
||||
"cpu": "1",
|
||||
"memory": "512Mi"
|
||||
},
|
||||
"requests": null
|
||||
}
|
||||
],
|
||||
"startup_probe": [
|
||||
{
|
||||
"failure_threshold": 1,
|
||||
"grpc": [],
|
||||
"http_get": [],
|
||||
"initial_delay_seconds": 0,
|
||||
"period_seconds": 240,
|
||||
"tcp_socket": [
|
||||
{
|
||||
"port": 8080
|
||||
}
|
||||
],
|
||||
"timeout_seconds": 240
|
||||
}
|
||||
],
|
||||
"volume_mounts": [],
|
||||
"working_dir": ""
|
||||
}
|
||||
],
|
||||
"node_selector": null,
|
||||
"service_account_name": "761163285547-compute@developer.gserviceaccount.com",
|
||||
"serving_state": "",
|
||||
"timeout_seconds": 300,
|
||||
"volumes": []
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"timeouts": null,
|
||||
"traffic": [
|
||||
{
|
||||
"latest_revision": true,
|
||||
"percent": 100,
|
||||
"revision_name": "",
|
||||
"tag": "",
|
||||
"url": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH0sInNjaGVtYV92ZXJzaW9uIjoiMiJ9",
|
||||
"dependencies": [
|
||||
"google_project_service.services"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"mode": "managed",
|
||||
"type": "google_cloud_run_service_iam_member",
|
||||
"name": "public_access",
|
||||
"provider": "provider[\"registry.terraform.io/hashicorp/google\"]",
|
||||
"instances": [
|
||||
{
|
||||
"schema_version": 0,
|
||||
"attributes": {
|
||||
"condition": [],
|
||||
"etag": "BwY108GyUf0=",
|
||||
"id": "v1/projects/gen-lang-client-0424120530/locations/us-central1/services/sereact/roles/run.invoker/allUsers",
|
||||
"location": "us-central1",
|
||||
"member": "allUsers",
|
||||
"project": "gen-lang-client-0424120530",
|
||||
"role": "roles/run.invoker",
|
||||
"service": "v1/projects/gen-lang-client-0424120530/locations/us-central1/services/sereact"
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "bnVsbA==",
|
||||
"dependencies": [
|
||||
"google_cloud_run_service.sereact",
|
||||
"google_project_service.services"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"mode": "managed",
|
||||
"type": "google_firestore_database",
|
||||
"name": "database",
|
||||
"provider": "provider[\"registry.terraform.io/hashicorp/google\"]",
|
||||
"instances": [
|
||||
{
|
||||
"schema_version": 0,
|
||||
"attributes": {
|
||||
"app_engine_integration_mode": "DISABLED",
|
||||
"cmek_config": [],
|
||||
"concurrency_mode": "PESSIMISTIC",
|
||||
"create_time": "",
|
||||
"database_edition": "STANDARD",
|
||||
"delete_protection_state": "DELETE_PROTECTION_DISABLED",
|
||||
"deletion_policy": "ABANDON",
|
||||
"earliest_version_time": "2025-05-23T20:47:31.801717Z",
|
||||
"etag": "IIelp4e8uo0DMPX0nai7uo0D",
|
||||
"id": "projects/gen-lang-client-0424120530/databases/imagedb",
|
||||
"key_prefix": "",
|
||||
"location_id": "us-central1",
|
||||
"name": "imagedb",
|
||||
"point_in_time_recovery_enablement": "POINT_IN_TIME_RECOVERY_DISABLED",
|
||||
"project": "gen-lang-client-0424120530",
|
||||
"timeouts": null,
|
||||
"type": "FIRESTORE_NATIVE",
|
||||
"uid": "177e30f2-9b67-428c-9979-22e625b929c4",
|
||||
"update_time": "",
|
||||
"version_retention_period": "3600s"
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjEyMDAwMDAwMDAwMDAsInVwZGF0ZSI6MTIwMDAwMDAwMDAwMH19",
|
||||
"dependencies": [
|
||||
"google_project_service.services"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"mode": "managed",
|
||||
"type": "google_project_service",
|
||||
"name": "services",
|
||||
"provider": "provider[\"registry.terraform.io/hashicorp/google\"]",
|
||||
"instances": [
|
||||
{
|
||||
"index_key": "cloudresourcemanager.googleapis.com",
|
||||
"schema_version": 0,
|
||||
"attributes": {
|
||||
"disable_dependent_services": null,
|
||||
"disable_on_destroy": false,
|
||||
"id": "gen-lang-client-0424120530/cloudresourcemanager.googleapis.com",
|
||||
"project": "gen-lang-client-0424120530",
|
||||
"service": "cloudresourcemanager.googleapis.com",
|
||||
"timeouts": null
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjEyMDAwMDAwMDAwMDAsInJlYWQiOjYwMDAwMDAwMDAwMCwidXBkYXRlIjoxMjAwMDAwMDAwMDAwfX0="
|
||||
},
|
||||
{
|
||||
"index_key": "containerregistry.googleapis.com",
|
||||
"schema_version": 0,
|
||||
"attributes": {
|
||||
"disable_dependent_services": null,
|
||||
"disable_on_destroy": false,
|
||||
"id": "gen-lang-client-0424120530/containerregistry.googleapis.com",
|
||||
"project": "gen-lang-client-0424120530",
|
||||
"service": "containerregistry.googleapis.com",
|
||||
"timeouts": null
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjEyMDAwMDAwMDAwMDAsInJlYWQiOjYwMDAwMDAwMDAwMCwidXBkYXRlIjoxMjAwMDAwMDAwMDAwfX0="
|
||||
},
|
||||
{
|
||||
"index_key": "firestore.googleapis.com",
|
||||
"schema_version": 0,
|
||||
"attributes": {
|
||||
"disable_dependent_services": null,
|
||||
"disable_on_destroy": false,
|
||||
"id": "gen-lang-client-0424120530/firestore.googleapis.com",
|
||||
"project": "gen-lang-client-0424120530",
|
||||
"service": "firestore.googleapis.com",
|
||||
"timeouts": null
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjEyMDAwMDAwMDAwMDAsInJlYWQiOjYwMDAwMDAwMDAwMCwidXBkYXRlIjoxMjAwMDAwMDAwMDAwfX0="
|
||||
},
|
||||
{
|
||||
"index_key": "run.googleapis.com",
|
||||
"schema_version": 0,
|
||||
"attributes": {
|
||||
"disable_dependent_services": null,
|
||||
"disable_on_destroy": false,
|
||||
"id": "gen-lang-client-0424120530/run.googleapis.com",
|
||||
"project": "gen-lang-client-0424120530",
|
||||
"service": "run.googleapis.com",
|
||||
"timeouts": null
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjEyMDAwMDAwMDAwMDAsInJlYWQiOjYwMDAwMDAwMDAwMCwidXBkYXRlIjoxMjAwMDAwMDAwMDAwfX0="
|
||||
},
|
||||
{
|
||||
"index_key": "storage.googleapis.com",
|
||||
"schema_version": 0,
|
||||
"attributes": {
|
||||
"disable_dependent_services": null,
|
||||
"disable_on_destroy": false,
|
||||
"id": "gen-lang-client-0424120530/storage.googleapis.com",
|
||||
"project": "gen-lang-client-0424120530",
|
||||
"service": "storage.googleapis.com",
|
||||
"timeouts": null
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjoxMjAwMDAwMDAwMDAwLCJkZWxldGUiOjEyMDAwMDAwMDAwMDAsInJlYWQiOjYwMDAwMDAwMDAwMCwidXBkYXRlIjoxMjAwMDAwMDAwMDAwfX0="
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"mode": "managed",
|
||||
"type": "google_storage_bucket",
|
||||
"name": "app_bucket",
|
||||
"provider": "provider[\"registry.terraform.io/hashicorp/google\"]",
|
||||
"instances": [
|
||||
{
|
||||
"schema_version": 3,
|
||||
"attributes": {
|
||||
"autoclass": [],
|
||||
"cors": [],
|
||||
"custom_placement_config": [],
|
||||
"default_event_based_hold": false,
|
||||
"effective_labels": {
|
||||
"goog-terraform-provisioned": "true"
|
||||
},
|
||||
"enable_object_retention": false,
|
||||
"encryption": [],
|
||||
"force_destroy": false,
|
||||
"hierarchical_namespace": [
|
||||
{
|
||||
"enabled": false
|
||||
}
|
||||
],
|
||||
"id": "sereact-storage-bucket",
|
||||
"labels": {},
|
||||
"lifecycle_rule": [],
|
||||
"location": "US-CENTRAL1",
|
||||
"logging": [],
|
||||
"name": "sereact-storage-bucket",
|
||||
"project": "gen-lang-client-0424120530",
|
||||
"project_number": 761163285547,
|
||||
"public_access_prevention": "inherited",
|
||||
"requester_pays": false,
|
||||
"retention_policy": [],
|
||||
"rpo": null,
|
||||
"self_link": "https://www.googleapis.com/storage/v1/b/sereact-storage-bucket",
|
||||
"soft_delete_policy": [
|
||||
{
|
||||
"effective_time": "2025-05-23T20:47:26.788Z",
|
||||
"retention_duration_seconds": 604800
|
||||
}
|
||||
],
|
||||
"storage_class": "STANDARD",
|
||||
"terraform_labels": {
|
||||
"goog-terraform-provisioned": "true"
|
||||
},
|
||||
"time_created": "2025-05-23T20:47:26.788Z",
|
||||
"timeouts": null,
|
||||
"uniform_bucket_level_access": true,
|
||||
"updated": "2025-05-23T20:47:26.788Z",
|
||||
"url": "gs://sereact-storage-bucket",
|
||||
"versioning": [],
|
||||
"website": []
|
||||
},
|
||||
"sensitive_attributes": [],
|
||||
"private": "eyJlMmJmYjczMC1lY2FhLTExZTYtOGY4OC0zNDM2M2JjN2M0YzAiOnsiY3JlYXRlIjo2MDAwMDAwMDAwMDAsInJlYWQiOjI0MDAwMDAwMDAwMCwidXBkYXRlIjoyNDAwMDAwMDAwMDB9LCJzY2hlbWFfdmVyc2lvbiI6IjMifQ==",
|
||||
"dependencies": [
|
||||
"google_project_service.services"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"check_results": null
|
||||
}
|
||||
5
deployment/terraform/terraform.tfvars.example
Normal file
5
deployment/terraform/terraform.tfvars.example
Normal file
@ -0,0 +1,5 @@
|
||||
project_id = "your-gcp-project-id"
|
||||
region = "us-central1"
|
||||
zone = "us-central1-a"
|
||||
storage_bucket_name = "your-app-storage-bucket"
|
||||
firestore_db_name = "imagedb"
|
||||
27
deployment/terraform/variables.tf
Normal file
27
deployment/terraform/variables.tf
Normal file
@ -0,0 +1,27 @@
|
||||
variable "project_id" {
|
||||
description = "The Google Cloud project ID"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
description = "The Google Cloud region"
|
||||
type = string
|
||||
default = "us-central1"
|
||||
}
|
||||
|
||||
variable "zone" {
|
||||
description = "The Google Cloud zone"
|
||||
type = string
|
||||
default = "us-central1-a"
|
||||
}
|
||||
|
||||
variable "storage_bucket_name" {
|
||||
description = "The name of the Cloud Storage bucket"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "firestore_db_name" {
|
||||
description = "The name of the Firestore database"
|
||||
type = string
|
||||
default = "imagedb"
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user