Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions cdn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# GCP CDN Plugin

Creates a Google Cloud CDN distribution with load balancing, SSL certificates, and DNS configuration for global content delivery.

## Overview

This plugin provisions a complete CDN solution using Google Cloud CDN with:

- Global load balancing with Cloud Load Balancer
- Automatic SSL certificate provisioning via Certificate Manager
- DNS record management in Cloud DNS
- Support for multiple origin types (Cloud Run, Cloud Storage, external)
- Path-based routing capabilities

## Required Inputs

| Parameter | Type | Description |
| --------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `project_id` | string | Google Cloud Project ID (e.g. `my-project-123`) |
| `region` | string | Google Cloud region (e.g. `us-central1`) |
| `domain_name` | string | Domain name for the CDN (A records will be created) |
| `dns_zone_name` | string | Name of the existing [Cloud DNS](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/dns_managed_zone#dns_name-2) |

## Optional Inputs

| Parameter | Type | Description | Default |
| ------------ | ------ | -------------------------------- | ------- |
| `domain_ttl` | number | TTL for DNS A records in seconds | `300` |

## Prerequisites

- Existing Cloud DNS zone in your project
- Enabled APIs: Certificate Manager, DNS, Compute Engine

## Usage Example

**Note:** This example shows platform file syntax. You can configure this plugin directly in the Suga Platform Builder UI without writing YAML.

```yaml
entrypoints:
default:
plugin: "gcp-cdn"
properties:
project_id: "my-project-123"
region: "us-central1"
domain_name: "cdn.example.com"
dns_zone_name: "example-com-zone"
domain_ttl: 300
```

## Features

- **Global Distribution**: Leverages Google's global network for content delivery
- **Automatic SSL**: Provisions and manages SSL certificates automatically
- **Multi-Origin Support**: Routes traffic to Cloud Run services, Cloud Storage buckets, or external origins
- **DNS Integration**: Automatically configures DNS records in your existing zone
- **Load Balancing**: Built-in load balancing with health checking

## References

- [Cloud CDN Documentation](https://cloud.google.com/cdn/docs)
- [Cloud Load Balancing Documentation](https://cloud.google.com/load-balancing/docs)
- [Certificate Manager Documentation](https://cloud.google.com/certificate-manager/docs)
- [Cloud DNS Documentation](https://cloud.google.com/dns/docs)
11 changes: 11 additions & 0 deletions cdn/manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,16 @@ inputs:
type: object
required: true
description: 'CDN domain configuration (e.g. `{"name": "cdn.example.com", "ssl": true}`)'
domain_name:
type: string
required: true
description: "New A records will be created in the hosted zone to establish this domain name for the CDN"
dns_zone_name:
type: string
required: true
description: "The name of the existing Cloud DNS zone that you would like your domain to be configured in"
domain_ttl:
type: number
description: "The time to live (TTL) for the A record created (in seconds). Defaults to 300 seconds"

outputs:
13 changes: 6 additions & 7 deletions cdn/module/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ locals {
}
}


# Enable the required services
resource "google_project_service" "required_services" {
for_each = toset(local.required_services)
Expand Down Expand Up @@ -233,28 +232,28 @@ resource "google_compute_url_map" "https_url_map" {

# Lookup the Managed Zone for the CDN Domain
data "google_dns_managed_zone" "cdn_zone" {
name = var.cdn_domain.zone_name
name = var.dns_zone_name
project = var.project_id

depends_on = [google_project_service.required_services]
}

# Create DNS Records for the CDN
resource "google_dns_record_set" "cdn_dns_record" {
name = endswith(var.cdn_domain.domain_name, ".") ? var.cdn_domain.domain_name : "${var.cdn_domain.domain_name}."
name = endswith(var.domain_name, ".") ? var.domain_name : "${var.domain_name}."
managed_zone = data.google_dns_managed_zone.cdn_zone.name
type = "A"
rrdatas = [google_compute_global_address.cdn_ip.address]
ttl = var.cdn_domain.domain_ttl
ttl = var.domain_ttl
project = var.project_id
}

resource "google_dns_record_set" "www_cdn_dns_record" {
name = endswith(var.cdn_domain.domain_name, ".") ? "www.${var.cdn_domain.domain_name}" : "www.${var.cdn_domain.domain_name}."
name = endswith(var.domain_name, ".") ? "www.${var.domain_name}" : "www.${var.domain_name}."
managed_zone = data.google_dns_managed_zone.cdn_zone.name
type = "A"
rrdatas = [google_compute_global_address.cdn_ip.address]
ttl = var.cdn_domain.domain_ttl
ttl = var.domain_ttl
project = var.project_id
}

Expand All @@ -265,7 +264,7 @@ resource "google_certificate_manager_certificate" "cdn_cert" {
scope = "DEFAULT"

managed {
domains = [var.cdn_domain.domain_name]
domains = [var.domain_name]
}

depends_on = [google_project_service.required_services]
Expand Down
16 changes: 14 additions & 2 deletions cdn/module/providers.tf
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
terraform {
required_version = ">= 1.0"

required_providers {
google = {
source = "hashicorp/google"
version = "7.4.0"
}

google-beta = {
source = "hashicorp/google-beta"
version = "~> 6.17.0"
version = "7.4.0"
}

random = {
source = "hashicorp/random"
version = "~> 3.1"
}

corefunc = {
source = "northwood-labs/corefunc"
version = "~> 1.4"
version = "2.1.0"
}
}
}
Expand Down
21 changes: 14 additions & 7 deletions cdn/module/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,18 @@ variable "region" {
type = string
}

variable "cdn_domain" {
description = "The CDN domain configuration."
type = object({
domain_name = string
zone_name = string
domain_ttl = optional(number, 300)
})
variable "domain_name" {
type = string
description = "New A records will be created in the hosted zone to establish this domain name for the CDN"
}

variable "dns_zone_name" {
type = string
description = "The name of the existing Cloud DNS zone that you would like your domain to be configured in"
}

variable "domain_ttl" {
type = string
description = "The time to live (TTL) for the A record created (in seconds). Defaults to 300 seconds"
default = 300
}
82 changes: 82 additions & 0 deletions cloudrun/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# GCP Cloud Run Plugin

Deploys containerized applications to Google Cloud Run with automatic scaling, traffic management, and service account integration.

## Overview

This plugin provisions Cloud Run services with:

- Automatic scaling based on traffic
- Configurable CPU, memory, and concurrency limits
- Environment variable management
- Service account integration for secure resource access
- Flexible ingress controls
- Request timeout configuration

## Required Inputs

| Parameter | Type | Description |
| ------------ | ------ | --------------------------------------------------------------- |
| `project_id` | string | Google Cloud Project ID (e.g. `my-project-123`) |
| `region` | string | Google Cloud region for service deployment (e.g. `us-central1`) |

## Optional Inputs

| Parameter | Type | Description | Default |
| ----------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
| `environment` | map(string) | Environment variables (e.g. `{"NODE_ENV": "production", "API_KEY": "secret"}`) | `{}` |
| `memory_mb` | number | Memory allocation in MB | `512` |
| `cpus` | number | CPU allocation | `1` |
| `gpus` | number | GPU allocation | `0` |
| `min_instances` | number | Minimum instances to keep running | `0` |
| `max_instances` | number | Maximum instances that can be created | `10` |
| `container_concurrency` | number | Maximum concurrent requests per instance | `80` |
| `timeout_seconds` | number | Maximum request timeout in seconds | `10` |
| `container_port` | number | Container port number | `9001` |
| `ingress` | string | Traffic ingress setting. Must be one of `INGRESS_TRAFFIC_ALL`, `INGRESS_TRAFFIC_INTERNAL_ONLY`, or `INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER` | `INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER` |

## Prerequisites

- Container image pushed to Google Container Registry or Artifact Registry
- Service account with appropriate IAM permissions (managed by `gcp-service-account` plugin)

## Usage Example

**Note:** This example shows platform file syntax. You can configure this plugin directly in the Suga Platform Builder UI without writing YAML.

```yaml
services:
api:
plugin: "gcp-cloudrun"
identities:
- plugin: "gcp-service-account"
properties:
project_id: "my-project-123"
region: "us-central1"
environment:
NODE_ENV: "production"
DATABASE_URL: "postgresql://..."
memory_mb: 1024
cpus: 2
min_instances: 1
max_instances: 100
container_concurrency: 80
timeout_seconds: 300
container_port: 8080
ingress: "INGRESS_TRAFFIC_ALL"
```

## Features

- **Serverless**: Pay only for the resources you use
- **Auto-scaling**: Automatically scales from zero to handle traffic spikes
- **Security**: Integrated with GCP IAM and service accounts
- **Flexibility**: Support for various runtime configurations and constraints
- **Traffic Management**: Multiple ingress options for different security requirements

## References

- [Cloud Run Documentation](https://cloud.google.com/run/docs)
- [Cloud Run Pricing](https://cloud.google.com/run/pricing)
- [Cloud Run Quotas and Limits](https://cloud.google.com/run/quotas)
- [Container Runtime Contract](https://cloud.google.com/run/docs/container-contract)
5 changes: 4 additions & 1 deletion cloudrun/manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ runtime:
go_module: github.com/nitrictech/plugins/gcp/cloudrun

inputs:
environment:
environment_variables:
type: map(string)
description: 'Cloud Run service environment variables (e.g. `{"NODE_ENV": "production", "API_KEY": "secret"}`)'
memory_mb:
Expand Down Expand Up @@ -47,5 +47,8 @@ inputs:
container_port:
type: number
description: "Container port number (e.g. `9001`)"
ingress:
type: string
description: "The ingress for this Service. Possible values are INGRESS_TRAFFIC_ALL, INGRESS_TRAFFIC_INTERNAL_ONLY, or INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"

outputs:
17 changes: 11 additions & 6 deletions cloudrun/module/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,13 @@ resource "google_cloud_run_v2_service" "service" {
location = var.region
project = var.project_id
launch_stage = "GA"
ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"
ingress = var.ingress

deletion_protection = false

template {
max_instance_request_concurrency = var.container_concurrency

scaling {
min_instance_count = var.min_instances
max_instance_count = var.max_instances
Expand All @@ -97,10 +99,13 @@ resource "google_cloud_run_v2_service" "service" {
containers {
image = "${local.service_image_url}@${docker_registry_image.push.sha256_digest}"
resources {
limits = {
cpu = var.cpus
memory = "${var.memory_mb}Mi"
}
limits = merge(
{
cpu = var.cpus
memory = "${var.memory_mb}Mi"
},
var.gpus > 0 ? { "nvidia.com/gpu" = var.gpus } : {}
)
}

ports {
Expand Down Expand Up @@ -130,7 +135,7 @@ resource "google_cloud_run_v2_service" "service" {
}

dynamic "env" {
for_each = merge(var.environment, var.suga.env)
for_each = merge(var.environment_variables, var.suga.env)
content {
name = env.key
value = env.value
Expand Down
14 changes: 13 additions & 1 deletion cloudrun/module/providers.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
terraform {
required_version = ">= 1.0"

required_providers {
google = {
source = "hashicorp/google"
version = "7.4.0"
}

random = {
source = "hashicorp/random"
version = "~> 3.1"
}

docker = {
source = "kreuzwerker/docker"
version = "3.6.0"
version = "3.6.2"
}
}
}
8 changes: 7 additions & 1 deletion cloudrun/module/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ variable "suga" {
})
}

variable "environment" {
variable "environment_variables" {
type = map(string)
description = "Environment variables to set on the lambda function"
default = {}
Expand Down Expand Up @@ -72,4 +72,10 @@ variable "container_port" {
description = "The port to expose the CloudRun service to"
type = number
default = 9001
}

variable "ingress" {
description = "The ingress for this Service. Possible values are INGRESS_TRAFFIC_ALL, INGRESS_TRAFFIC_INTERNAL_ONLY, or INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"
type = string
default = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"
}
Loading