Skip to content

Commit 7509d17

Browse files
fix: improve GCP user experience and documentation (#5)
1 parent 34ff55e commit 7509d17

File tree

15 files changed

+472
-27
lines changed

15 files changed

+472
-27
lines changed

cdn/README.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# GCP CDN Plugin
2+
3+
Creates a Google Cloud CDN distribution with load balancing, SSL certificates, and DNS configuration for global content delivery.
4+
5+
## Overview
6+
7+
This plugin provisions a complete CDN solution using Google Cloud CDN with:
8+
9+
- Global load balancing with Cloud Load Balancer
10+
- Automatic SSL certificate provisioning via Certificate Manager
11+
- DNS record management in Cloud DNS
12+
- Support for multiple origin types (Cloud Run, Cloud Storage, external)
13+
- Path-based routing capabilities
14+
15+
## Required Inputs
16+
17+
| Parameter | Type | Description |
18+
| --------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
19+
| `project_id` | string | Google Cloud Project ID (e.g. `my-project-123`) |
20+
| `region` | string | Google Cloud region (e.g. `us-central1`) |
21+
| `domain_name` | string | Domain name for the CDN (A records will be created) |
22+
| `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) |
23+
24+
## Optional Inputs
25+
26+
| Parameter | Type | Description | Default |
27+
| ------------ | ------ | -------------------------------- | ------- |
28+
| `domain_ttl` | number | TTL for DNS A records in seconds | `300` |
29+
30+
## Prerequisites
31+
32+
- Existing Cloud DNS zone in your project
33+
- Enabled APIs: Certificate Manager, DNS, Compute Engine
34+
35+
## Usage Example
36+
37+
**Note:** This example shows platform file syntax. You can configure this plugin directly in the Suga Platform Builder UI without writing YAML.
38+
39+
```yaml
40+
entrypoints:
41+
default:
42+
plugin: "gcp-cdn"
43+
properties:
44+
project_id: "my-project-123"
45+
region: "us-central1"
46+
domain_name: "cdn.example.com"
47+
dns_zone_name: "example-com-zone"
48+
domain_ttl: 300
49+
```
50+
51+
## Features
52+
53+
- **Global Distribution**: Leverages Google's global network for content delivery
54+
- **Automatic SSL**: Provisions and manages SSL certificates automatically
55+
- **Multi-Origin Support**: Routes traffic to Cloud Run services, Cloud Storage buckets, or external origins
56+
- **DNS Integration**: Automatically configures DNS records in your existing zone
57+
- **Load Balancing**: Built-in load balancing with health checking
58+
59+
## References
60+
61+
- [Cloud CDN Documentation](https://cloud.google.com/cdn/docs)
62+
- [Cloud Load Balancing Documentation](https://cloud.google.com/load-balancing/docs)
63+
- [Certificate Manager Documentation](https://cloud.google.com/certificate-manager/docs)
64+
- [Cloud DNS Documentation](https://cloud.google.com/dns/docs)

cdn/manifest.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,16 @@ inputs:
2020
type: object
2121
required: true
2222
description: 'CDN domain configuration (e.g. `{"name": "cdn.example.com", "ssl": true}`)'
23+
domain_name:
24+
type: string
25+
required: true
26+
description: "New A records will be created in the hosted zone to establish this domain name for the CDN"
27+
dns_zone_name:
28+
type: string
29+
required: true
30+
description: "The name of the existing Cloud DNS zone that you would like your domain to be configured in"
31+
domain_ttl:
32+
type: number
33+
description: "The time to live (TTL) for the A record created (in seconds). Defaults to 300 seconds"
2334

2435
outputs:

cdn/module/main.tf

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ locals {
6363
}
6464
}
6565

66-
6766
# Enable the required services
6867
resource "google_project_service" "required_services" {
6968
for_each = toset(local.required_services)
@@ -265,28 +264,28 @@ resource "google_compute_url_map" "https_url_map" {
265264

266265
# Lookup the Managed Zone for the CDN Domain
267266
data "google_dns_managed_zone" "cdn_zone" {
268-
name = var.cdn_domain.zone_name
267+
name = var.dns_zone_name
269268
project = var.project_id
270269

271270
depends_on = [google_project_service.required_services]
272271
}
273272

274273
# Create DNS Records for the CDN
275274
resource "google_dns_record_set" "cdn_dns_record" {
276-
name = endswith(var.cdn_domain.domain_name, ".") ? var.cdn_domain.domain_name : "${var.cdn_domain.domain_name}."
275+
name = endswith(var.domain_name, ".") ? var.domain_name : "${var.domain_name}."
277276
managed_zone = data.google_dns_managed_zone.cdn_zone.name
278277
type = "A"
279278
rrdatas = [google_compute_global_address.cdn_ip.address]
280-
ttl = var.cdn_domain.domain_ttl
279+
ttl = var.domain_ttl
281280
project = var.project_id
282281
}
283282

284283
resource "google_dns_record_set" "www_cdn_dns_record" {
285-
name = endswith(var.cdn_domain.domain_name, ".") ? "www.${var.cdn_domain.domain_name}" : "www.${var.cdn_domain.domain_name}."
284+
name = endswith(var.domain_name, ".") ? "www.${var.domain_name}" : "www.${var.domain_name}."
286285
managed_zone = data.google_dns_managed_zone.cdn_zone.name
287286
type = "A"
288287
rrdatas = [google_compute_global_address.cdn_ip.address]
289-
ttl = var.cdn_domain.domain_ttl
288+
ttl = var.domain_ttl
290289
project = var.project_id
291290
}
292291

@@ -297,7 +296,7 @@ resource "google_certificate_manager_certificate" "cdn_cert" {
297296
scope = "DEFAULT"
298297

299298
managed {
300-
domains = [var.cdn_domain.domain_name]
299+
domains = [var.domain_name]
301300
}
302301

303302
depends_on = [google_project_service.required_services]

cdn/module/providers.tf

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
11
terraform {
2+
required_version = ">= 1.0"
3+
24
required_providers {
5+
google = {
6+
source = "hashicorp/google"
7+
version = "7.4.0"
8+
}
9+
310
google-beta = {
411
source = "hashicorp/google-beta"
5-
version = "~> 6.17.0"
12+
version = "7.4.0"
13+
}
14+
15+
random = {
16+
source = "hashicorp/random"
17+
version = "~> 3.1"
618
}
719

820
corefunc = {
921
source = "northwood-labs/corefunc"
10-
version = "~> 1.4"
22+
version = "2.1.0"
1123
}
1224
}
1325
}

cdn/module/variables.tf

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,18 @@ variable "region" {
2525
type = string
2626
}
2727

28-
variable "cdn_domain" {
29-
description = "The CDN domain configuration."
30-
type = object({
31-
domain_name = string
32-
zone_name = string
33-
domain_ttl = optional(number, 300)
34-
})
28+
variable "domain_name" {
29+
type = string
30+
description = "New A records will be created in the hosted zone to establish this domain name for the CDN"
31+
}
32+
33+
variable "dns_zone_name" {
34+
type = string
35+
description = "The name of the existing Cloud DNS zone that you would like your domain to be configured in"
3536
}
37+
38+
variable "domain_ttl" {
39+
type = string
40+
description = "The time to live (TTL) for the A record created (in seconds). Defaults to 300 seconds"
41+
default = 300
42+
}

cloudrun/README.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# GCP Cloud Run Plugin
2+
3+
Deploys containerized applications to Google Cloud Run with automatic scaling, traffic management, and service account integration.
4+
5+
## Overview
6+
7+
This plugin provisions Cloud Run services with:
8+
9+
- Automatic scaling based on traffic
10+
- Configurable CPU, memory, and concurrency limits
11+
- Environment variable management
12+
- Service account integration for secure resource access
13+
- Flexible ingress controls
14+
- Request timeout configuration
15+
16+
## Required Inputs
17+
18+
| Parameter | Type | Description |
19+
| ------------ | ------ | --------------------------------------------------------------- |
20+
| `project_id` | string | Google Cloud Project ID (e.g. `my-project-123`) |
21+
| `region` | string | Google Cloud region for service deployment (e.g. `us-central1`) |
22+
23+
## Optional Inputs
24+
25+
| Parameter | Type | Description | Default |
26+
| ----------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
27+
| `environment` | map(string) | Environment variables (e.g. `{"NODE_ENV": "production", "API_KEY": "secret"}`) | `{}` |
28+
| `memory_mb` | number | Memory allocation in MB | `512` |
29+
| `cpus` | number | CPU allocation | `1` |
30+
| `gpus` | number | GPU allocation | `0` |
31+
| `min_instances` | number | Minimum instances to keep running | `0` |
32+
| `max_instances` | number | Maximum instances that can be created | `10` |
33+
| `container_concurrency` | number | Maximum concurrent requests per instance | `80` |
34+
| `timeout_seconds` | number | Maximum request timeout in seconds | `10` |
35+
| `container_port` | number | Container port number | `9001` |
36+
| `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` |
37+
38+
## Prerequisites
39+
40+
- Container image pushed to Google Container Registry or Artifact Registry
41+
- Service account with appropriate IAM permissions (managed by `gcp-service-account` plugin)
42+
43+
## Usage Example
44+
45+
**Note:** This example shows platform file syntax. You can configure this plugin directly in the Suga Platform Builder UI without writing YAML.
46+
47+
```yaml
48+
services:
49+
api:
50+
plugin: "gcp-cloudrun"
51+
identities:
52+
- plugin: "gcp-service-account"
53+
properties:
54+
project_id: "my-project-123"
55+
region: "us-central1"
56+
environment:
57+
NODE_ENV: "production"
58+
DATABASE_URL: "postgresql://..."
59+
memory_mb: 1024
60+
cpus: 2
61+
min_instances: 1
62+
max_instances: 100
63+
container_concurrency: 80
64+
timeout_seconds: 300
65+
container_port: 8080
66+
ingress: "INGRESS_TRAFFIC_ALL"
67+
```
68+
69+
## Features
70+
71+
- **Serverless**: Pay only for the resources you use
72+
- **Auto-scaling**: Automatically scales from zero to handle traffic spikes
73+
- **Security**: Integrated with GCP IAM and service accounts
74+
- **Flexibility**: Support for various runtime configurations and constraints
75+
- **Traffic Management**: Multiple ingress options for different security requirements
76+
77+
## References
78+
79+
- [Cloud Run Documentation](https://cloud.google.com/run/docs)
80+
- [Cloud Run Pricing](https://cloud.google.com/run/pricing)
81+
- [Cloud Run Quotas and Limits](https://cloud.google.com/run/quotas)
82+
- [Container Runtime Contract](https://cloud.google.com/run/docs/container-contract)

cloudrun/manifest.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ runtime:
1212
go_module: github.com/nitrictech/plugins/gcp/cloudrun
1313

1414
inputs:
15-
environment:
15+
environment_variables:
1616
type: map(string)
1717
description: 'Cloud Run service environment variables (e.g. `{"NODE_ENV": "production", "API_KEY": "secret"}`)'
1818
memory_mb:
@@ -47,5 +47,8 @@ inputs:
4747
container_port:
4848
type: number
4949
description: "Container port number (e.g. `9001`)"
50+
ingress:
51+
type: string
52+
description: "The ingress for this Service. Possible values are INGRESS_TRAFFIC_ALL, INGRESS_TRAFFIC_INTERNAL_ONLY, or INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"
5053

5154
outputs:

cloudrun/module/main.tf

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,13 @@ resource "google_cloud_run_v2_service" "service" {
8484
location = var.region
8585
project = var.project_id
8686
launch_stage = "GA"
87-
ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"
87+
ingress = var.ingress
8888

8989
deletion_protection = false
9090

9191
template {
92+
max_instance_request_concurrency = var.container_concurrency
93+
9294
scaling {
9395
min_instance_count = var.min_instances
9496
max_instance_count = var.max_instances
@@ -97,10 +99,13 @@ resource "google_cloud_run_v2_service" "service" {
9799
containers {
98100
image = "${local.service_image_url}@${docker_registry_image.push.sha256_digest}"
99101
resources {
100-
limits = {
101-
cpu = var.cpus
102-
memory = "${var.memory_mb}Mi"
103-
}
102+
limits = merge(
103+
{
104+
cpu = var.cpus
105+
memory = "${var.memory_mb}Mi"
106+
},
107+
var.gpus > 0 ? { "nvidia.com/gpu" = var.gpus } : {}
108+
)
104109
}
105110

106111
ports {
@@ -130,7 +135,7 @@ resource "google_cloud_run_v2_service" "service" {
130135
}
131136

132137
dynamic "env" {
133-
for_each = merge(var.environment, var.suga.env)
138+
for_each = merge(var.environment_variables, var.suga.env)
134139
content {
135140
name = env.key
136141
value = env.value

cloudrun/module/providers.tf

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11
terraform {
2+
required_version = ">= 1.0"
3+
24
required_providers {
5+
google = {
6+
source = "hashicorp/google"
7+
version = "7.4.0"
8+
}
9+
10+
random = {
11+
source = "hashicorp/random"
12+
version = "~> 3.1"
13+
}
14+
315
docker = {
416
source = "kreuzwerker/docker"
5-
version = "3.6.0"
17+
version = "3.6.2"
618
}
719
}
820
}

cloudrun/module/variables.tf

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ variable "suga" {
1010
})
1111
}
1212

13-
variable "environment" {
13+
variable "environment_variables" {
1414
type = map(string)
1515
description = "Environment variables to set on the lambda function"
1616
default = {}
@@ -72,4 +72,10 @@ variable "container_port" {
7272
description = "The port to expose the CloudRun service to"
7373
type = number
7474
default = 9001
75+
}
76+
77+
variable "ingress" {
78+
description = "The ingress for this Service. Possible values are INGRESS_TRAFFIC_ALL, INGRESS_TRAFFIC_INTERNAL_ONLY, or INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"
79+
type = string
80+
default = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"
7581
}

0 commit comments

Comments
 (0)