soleprint init commit

This commit is contained in:
buenosairesam
2025-12-24 05:38:37 -03:00
commit 329c401ff5
96 changed files with 11564 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
name: amar-gcp
runtime:
name: python
options:
virtualenv: venv
description: Amar Mascotas infrastructure on Google Cloud Platform

View File

@@ -0,0 +1,286 @@
"""
Google Cloud Platform Infrastructure for Amar Mascotas
Deploys:
- VPC with subnets
- Compute Engine instance for Django app + Celery
- Cloud SQL PostgreSQL (PostGIS via flags)
- Memorystore Redis
- Firewall rules
- (Optional) Cloud Load Balancer, Cloud DNS
Estimated cost: ~$93/month
NOTE: GCP has good free tier credits and competitive pricing.
PostGIS requires enabling the `cloudsql.enable_pgaudit` flag.
"""
import pulumi
import pulumi_gcp as gcp
import sys
sys.path.append("..")
from shared.config import get_config, APP_SERVER_INIT_SCRIPT
# Load configuration
cfg = get_config()
# Get project
project = gcp.organizations.get_project()
# =============================================================================
# NETWORKING - VPC
# =============================================================================
# VPC Network
vpc = gcp.compute.Network(
f"{cfg.resource_prefix}-vpc",
name=f"{cfg.resource_prefix}-vpc",
auto_create_subnetworks=False,
description="VPC for Amar Mascotas",
)
# Subnet for compute resources
subnet = gcp.compute.Subnetwork(
f"{cfg.resource_prefix}-subnet",
name=f"{cfg.resource_prefix}-subnet",
ip_cidr_range="10.0.1.0/24",
region="us-east1",
network=vpc.id,
private_ip_google_access=True, # Access Google APIs without public IP
)
# =============================================================================
# FIREWALL RULES
# =============================================================================
# Allow SSH
firewall_ssh = gcp.compute.Firewall(
f"{cfg.resource_prefix}-allow-ssh",
name=f"{cfg.resource_prefix}-allow-ssh",
network=vpc.name,
allows=[
gcp.compute.FirewallAllowArgs(
protocol="tcp",
ports=["22"],
),
],
source_ranges=cfg.allowed_ssh_ips or ["0.0.0.0/0"],
target_tags=["app-server"],
)
# Allow HTTP/HTTPS
firewall_http = gcp.compute.Firewall(
f"{cfg.resource_prefix}-allow-http",
name=f"{cfg.resource_prefix}-allow-http",
network=vpc.name,
allows=[
gcp.compute.FirewallAllowArgs(
protocol="tcp",
ports=["80", "443"],
),
],
source_ranges=["0.0.0.0/0"],
target_tags=["app-server"],
)
# Allow internal traffic (for DB/Redis access)
firewall_internal = gcp.compute.Firewall(
f"{cfg.resource_prefix}-allow-internal",
name=f"{cfg.resource_prefix}-allow-internal",
network=vpc.name,
allows=[
gcp.compute.FirewallAllowArgs(
protocol="tcp",
ports=["0-65535"],
),
gcp.compute.FirewallAllowArgs(
protocol="udp",
ports=["0-65535"],
),
gcp.compute.FirewallAllowArgs(
protocol="icmp",
),
],
source_ranges=["10.0.0.0/8"],
)
# =============================================================================
# DATABASE - Cloud SQL PostgreSQL
# =============================================================================
# Cloud SQL instance
# Note: PostGIS available via database flags
db_instance = gcp.sql.DatabaseInstance(
f"{cfg.resource_prefix}-db",
name=f"{cfg.resource_prefix}-db",
database_version="POSTGRES_15",
region="us-east1",
deletion_protection=False, # Set True for production!
settings=gcp.sql.DatabaseInstanceSettingsArgs(
tier="db-f1-micro", # $25/mo - smallest
disk_size=10,
disk_type="PD_SSD",
ip_configuration=gcp.sql.DatabaseInstanceSettingsIpConfigurationArgs(
ipv4_enabled=False,
private_network=vpc.id,
enable_private_path_for_google_cloud_services=True,
),
backup_configuration=gcp.sql.DatabaseInstanceSettingsBackupConfigurationArgs(
enabled=True,
start_time="03:00",
),
database_flags=[
# Enable PostGIS extensions
gcp.sql.DatabaseInstanceSettingsDatabaseFlagArgs(
name="cloudsql.enable_pg_cron",
value="on",
),
],
user_labels=cfg.tags,
),
opts=pulumi.ResourceOptions(depends_on=[vpc]),
)
# Database
db = gcp.sql.Database(
f"{cfg.resource_prefix}-database",
name=cfg.db_name,
instance=db_instance.name,
)
# Database user
db_user = gcp.sql.User(
f"{cfg.resource_prefix}-db-user",
name=cfg.db_user,
instance=db_instance.name,
password=pulumi.Config().require_secret("db_password"),
)
# Private IP for Cloud SQL
private_ip_address = gcp.compute.GlobalAddress(
f"{cfg.resource_prefix}-db-private-ip",
name=f"{cfg.resource_prefix}-db-private-ip",
purpose="VPC_PEERING",
address_type="INTERNAL",
prefix_length=16,
network=vpc.id,
)
# VPC peering for Cloud SQL
private_vpc_connection = gcp.servicenetworking.Connection(
f"{cfg.resource_prefix}-private-vpc-connection",
network=vpc.id,
service="servicenetworking.googleapis.com",
reserved_peering_ranges=[private_ip_address.name],
)
# =============================================================================
# CACHE - Memorystore Redis
# =============================================================================
redis_instance = gcp.redis.Instance(
f"{cfg.resource_prefix}-redis",
name=f"{cfg.resource_prefix}-redis",
tier="BASIC", # $20/mo - no HA
memory_size_gb=1,
region="us-east1",
redis_version="REDIS_7_0",
authorized_network=vpc.id,
connect_mode="PRIVATE_SERVICE_ACCESS",
labels=cfg.tags,
opts=pulumi.ResourceOptions(depends_on=[private_vpc_connection]),
)
# =============================================================================
# COMPUTE - Compute Engine Instance
# =============================================================================
# Service account for the instance
service_account = gcp.serviceaccount.Account(
f"{cfg.resource_prefix}-sa",
account_id=f"{cfg.resource_prefix}-app-sa",
display_name="Amar App Service Account",
)
# Compute instance
instance = gcp.compute.Instance(
f"{cfg.resource_prefix}-app",
name=f"{cfg.resource_prefix}-app",
machine_type="e2-medium", # $30/mo - 4GB RAM, 2 vCPU
zone="us-east1-b",
tags=["app-server"],
boot_disk=gcp.compute.InstanceBootDiskArgs(
initialize_params=gcp.compute.InstanceBootDiskInitializeParamsArgs(
image="ubuntu-os-cloud/ubuntu-2204-lts",
size=30,
type="pd-ssd",
),
),
network_interfaces=[
gcp.compute.InstanceNetworkInterfaceArgs(
network=vpc.id,
subnetwork=subnet.id,
access_configs=[
gcp.compute.InstanceNetworkInterfaceAccessConfigArgs(
# Ephemeral public IP
),
],
),
],
service_account=gcp.compute.InstanceServiceAccountArgs(
email=service_account.email,
scopes=["cloud-platform"],
),
metadata_startup_script=APP_SERVER_INIT_SCRIPT,
labels=cfg.tags,
)
# Static external IP (optional, costs extra)
static_ip = gcp.compute.Address(
f"{cfg.resource_prefix}-static-ip",
name=f"{cfg.resource_prefix}-static-ip",
region="us-east1",
)
# =============================================================================
# OPTIONAL: Cloud Load Balancer (uncomment if needed)
# =============================================================================
# health_check = gcp.compute.HealthCheck(
# f"{cfg.resource_prefix}-health-check",
# name=f"{cfg.resource_prefix}-health-check",
# http_health_check=gcp.compute.HealthCheckHttpHealthCheckArgs(
# port=80,
# request_path="/health/",
# ),
# )
# =============================================================================
# OUTPUTS
# =============================================================================
pulumi.export("instance_public_ip", instance.network_interfaces[0].access_configs[0].nat_ip)
pulumi.export("instance_private_ip", instance.network_interfaces[0].network_ip)
pulumi.export("static_ip", static_ip.address)
pulumi.export("db_private_ip", db_instance.private_ip_address)
pulumi.export("db_connection_name", db_instance.connection_name)
pulumi.export("db_name", cfg.db_name)
pulumi.export("db_user", cfg.db_user)
pulumi.export("redis_host", redis_instance.host)
pulumi.export("redis_port", redis_instance.port)
# Generate .env content
pulumi.export("env_file", pulumi.Output.all(
db_instance.private_ip_address,
redis_instance.host,
redis_instance.port,
).apply(lambda args: f"""
# Generated by Pulumi - GCP
DB_HOST={args[0]}
DB_PORT=5432
DB_NAME={cfg.db_name}
DB_USER={cfg.db_user}
DB_PASSWORD=<set via pulumi config>
CELERY_BROKER_URL=redis://{args[1]}:{args[2]}/0
CELERY_RESULT_BACKEND=redis://{args[1]}:{args[2]}/0
"""))

View File

@@ -0,0 +1,2 @@
pulumi>=3.0.0
pulumi-gcp>=7.0.0