Created
January 12, 2024 14:47
-
-
Save ayltai/895eb7b13a9df5beee36af254c05c0d9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
terraform { | |
required_version = ">= 1.6.5" | |
backend "gcs" { | |
bucket = "rockstar_project_terraform_states" | |
prefix = "terraform/state" | |
} | |
required_providers { | |
google = { | |
source = "hashicorp/google" | |
version = ">= 5.10" | |
} | |
tls = { | |
source = "hashicorp/tls" | |
version = ">= 4.0" | |
} | |
acme = { | |
source = "vancluever/acme" | |
version = ">= 2.19" | |
} | |
local = { | |
source = "hashicorp/local" | |
version = ">= 2.4" | |
} | |
} | |
} | |
provider "google" { | |
region = var.region | |
zone = var.zone | |
} | |
provider "acme" { | |
server_url = "https://acme-v02.api.letsencrypt.org/directory" | |
} | |
locals { | |
website_buckets = [ | |
for pair in setproduct(var.environments, var.static_website_bucket_names) : { | |
environment = pair[0] | |
name = "rockstar_project_${pair[0]}_${pair[1]}" | |
} | |
] | |
} | |
resource "google_storage_bucket" "rockstar_project_static_websites" { | |
for_each = { | |
for bucket in local.website_buckets : bucket.name => bucket | |
} | |
project = data.google_project.this.project_id | |
name = each.value.name | |
location = var.region_storage | |
uniform_bucket_level_access = false | |
force_destroy = true | |
# Set the default file to retrieve when none is specified, i.e. URLs ending with a slash | |
# Not-found page redirection is needed if this is a React SPA | |
website { | |
main_page_suffix = "index.html" | |
not_found_page = strcontains(each.value.name, "react") ? "index.html" : "404.html" | |
} | |
# Depends on your needs, setting CORS headers could make it easier for development | |
cors { | |
origin = [ | |
"*", | |
] | |
method = [ | |
"GET", | |
"HEAD", | |
"PUT", | |
"POST", | |
"DELETE", | |
"PATCH", | |
] | |
response_header = [ | |
"*", | |
] | |
max_age_seconds = 300 | |
} | |
} | |
# Make the files in the bucket publicly accessible | |
resource "google_storage_default_object_acl" "rockstart_project_static_websites" { | |
for_each = { | |
for bucket in local.website_buckets : bucket.name => bucket | |
} | |
bucket = each.value.name | |
role_entity = [ | |
"READER:allUsers", | |
] | |
} | |
# Define a backend for the load balancer in dev environment | |
resource "google_compute_backend_bucket" "rockstart_project_static_website_dev" { | |
name = "static_website_dev" | |
bucket_name = google_storage_bucket.rockstar_project_static_websites["rockstar_project_static_website_dev"].name | |
enable_cdn = true | |
cdn_policy { | |
default_ttl = 300 | |
client_ttl = 300 | |
max_ttl = 3600 | |
} | |
# This would make local development easier but not recommended in production | |
custom_response_headers = [ | |
"Access-Control-Allow-Origin: *", | |
] | |
} | |
# Define a backend for the load balancer in staging environment | |
resource "google_compute_backend_bucket" "rockstart_project_static_website_staging" { | |
name = "static_website_staging" | |
bucket_name = google_storage_bucket.rockstar_project_static_websites["rockstar_project_static_website_staging"].name | |
enable_cdn = true | |
cdn_policy { | |
default_ttl = 300 | |
client_ttl = 300 | |
max_ttl = 3600 | |
} | |
# This would make local development easier but not recommended in production | |
custom_response_headers = [ | |
"Access-Control-Allow-Origin: *", | |
] | |
} | |
# Get a public IP address for the load balancer | |
resource "google_compute_global_address" "loadbalancer" { | |
name = "loadbalancer" | |
} | |
# Tell the load balancer how you'd like the traffic to be redirected to different storage bucket backends | |
resource "google_compute_url_map" "websites" { | |
name = "websites" | |
default_service = google_compute_backend_bucket.rockstart_project_static_website_dev.self_link | |
host_rule { | |
hosts = [ | |
"dev.${var.domain}", | |
] | |
path_matcher = "rockstart-project-static-website-dev" | |
} | |
host_rule { | |
hosts = [ | |
"staging.${var.domain}", | |
] | |
path_matcher = "rockstart-project-static-website-staging" | |
} | |
path_matcher { | |
name = "rockstart-project-static-website-dev" | |
default_service = google_compute_backend_bucket.rockstart_project_static_website_dev.self_link | |
} | |
path_matcher { | |
name = "rockstart-project-static-website-staging" | |
default_service = google_compute_backend_bucket.rockstart_project_static_website_staging.self_link | |
} | |
} | |
# Generate a private key of a SSL certificate for signing your HTTPS domain name, not needed for HTTP-only websites | |
resource "tls_private_key" "website" { | |
algorithm = "RSA" | |
} | |
# Tell our ACME provider to use our private key for certificate generation | |
resource "acme_registration" "website" { | |
account_key_pem = tls_private_key.website.private_key_pem | |
email_address = var.acme_email | |
} | |
resource "google_compute_ssl_certificate" "rockstart_project_static_website_dev" { | |
name = "rockstart-project-static-website-dev" | |
private_key = acme_certificate.rockstart_project_static_website_dev.private_key_pem | |
certificate = acme_certificate.rockstart_project_static_website_dev.certificate_pem | |
} | |
resource "google_compute_ssl_certificate" "rockstart_project_static_website_staging" { | |
name = "rockstart-project-static-website-staging" | |
private_key = acme_certificate.rockstart_project_static_website_staging.private_key_pem | |
certificate = acme_certificate.rockstart_project_static_website_staging.certificate_pem | |
} | |
# Use Google CloudDNS to solve the DNS-01 challenge | |
resource "acme_certificate" "rockstart-project-static-website-dev" { | |
account_key_pem = acme_registration.website.account_key_pem | |
common_name = "dev.${var.domain}" | |
dns_challenge { | |
provider = "gcloud" | |
config = { | |
GCE_PROJECT = var.project_id | |
GCE_SERVICE_ACCOUNT_FILE = var.service_account_key_file | |
} | |
} | |
} | |
# Assign the certificates to the HTTPS proxy of the load balancer, not needed for HTTP-only proxy | |
resource "google_compute_target_https_proxy" "websites" { | |
name = "websites" | |
url_map = google_compute_url_map.websites.self_link | |
ssl_certificates = [ | |
google_compute_ssl_certificate.rockstart_project_static_website_dev.id, | |
google_compute_ssl_certificate.rockstart_project_static_website_staging.id, | |
] | |
} | |
# Map the incoming traffic of the load balancer to the HTTPS (or HTTP) proxy | |
resource "google_compute_global_forwarding_rule" "websites" { | |
name = "websites" | |
load_balancing_scheme = "EXTERNAL" | |
target = google_compute_target_https_proxy.websites.self_link | |
ip_address = google_compute_global_address.loadbalancer.address | |
port_range = "443" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment