Skip to content

Instantly share code, notes, and snippets.

@pcostesi
Created January 6, 2021 02:26
Show Gist options
  • Save pcostesi/b13a126997aabcde42d74af107a6a8ac to your computer and use it in GitHub Desktop.
Save pcostesi/b13a126997aabcde42d74af107a6a8ac to your computer and use it in GitHub Desktop.
Blog CI/CD Pipeline and Terraform files
resource "google_cloudbuild_trigger" "site_trigger" {
provider = google-beta
name = "${var.project}-trigger"
project = var.project
github {
push {
branch = "master"
}
owner = "pcostesi"
name = var.static_site
}
filename = "cloudbuild.yaml"
}
steps:
- name: node:current
entrypoint: npm
args: ["install"]
- name: node:current
entrypoint: npm
args: ["run", "build"]
- name: gcr.io/cloud-builders/gsutil
args: ["-m", "rsync", "-r", "-c", "-d", "./public", "gs://pcostesi.dev"]
# Global IP, needed for the load balancer (maybe this should go to `routing.tf`)
resource "google_compute_global_address" "static_sites" {
provider = google
name = "static-sites"
}
# Managed DNS zone
data "google_dns_managed_zone" "main_site" {
provider = google
name = var.project
}
# Bind IP to the DNS
resource "google_dns_record_set" "static_site" {
provider = google
name = "${var.static_site}."
type = "A"
ttl = 300
managed_zone = data.google_dns_managed_zone.main_site.name
rrdatas = [google_compute_global_address.static_sites.address]
}
# Site verification
resource "google_dns_record_set" "static_site_txt" {
provider = google
name = "${var.static_site}."
type = "TXT"
ttl = 300
managed_zone = data.google_dns_managed_zone.main_site.name
rrdatas = ["google-site-verification=${var.site_verification}"]
}
terraform {
required_providers {
google = {
source = "hashicorp/google"
}
google-beta = {
source = "hashicorp/google-beta"
}
}
backend "gcs"{
bucket = "a-bucket-for-storing-terraform-state"
prefix = "blog"
credentials = "/path/to/your/google/credentials.json"
}
}
provider "google" {
credentials = file(var.credentials)
project = var.project
region = var.region
zone = var.zone
}
provider "google-beta" {
credentials = file(var.credentials)
project = var.project
region = var.region
zone = var.zone
}
resource "google_monitoring_notification_channel" "basic" {
display_name = "Main Notification Channel"
type = "email"
project = var.project
provider = google-beta
labels = {
email_address = var.email_address
}
}
resource "google_monitoring_uptime_check_config" "static_site_https" {
provider = google-beta
display_name = "${var.project}-https-uptime-check"
timeout = "60s"
project = var.project
http_check {
path = "/"
port = "443"
use_ssl = true
validate_ssl = true
}
monitored_resource {
type = "uptime_url"
labels = {
project_id = var.project
host = var.static_site
}
}
}
resource "google_monitoring_alert_policy" "static_site_alert_policy" {
display_name = "Static Site Alert Policy"
combiner = "OR"
conditions {
display_name = "SSL certificate expiring soon"
condition_threshold {
filter = "metric.type=\"monitoring.googleapis.com/uptime_check/time_until_ssl_cert_expires\" AND resource.type=\"uptime_url\""
duration = "600s"
comparison = "COMPARISON_LT"
threshold_value = 15
trigger {
count = 1
}
aggregations {
alignment_period = "1200s"
per_series_aligner = "ALIGN_NEXT_OLDER"
cross_series_reducer = "REDUCE_MEAN"
group_by_fields = ["resource.label.*"]
}
}
}
user_labels = {
"uptime" = "ssl_cert_expiration"
"version" = "1"
}
notification_channels = [ google_monitoring_notification_channel.basic.name ]
}
# Add the bucket as a CDN backend
resource "google_compute_backend_bucket" "static_site" {
provider = google
name = "${var.project}-backend"
description = "Contains files needed by the website"
bucket_name = google_storage_bucket.static_site.name
enable_cdn = true
depends_on = [google_dns_record_set.static_site_txt]
}
# HTTPS certificate
resource "google_compute_managed_ssl_certificate" "static_site" {
provider = google-beta
name = "${var.project}-cert"
managed {
domains = [google_dns_record_set.static_site.name]
}
}
# GCP URL MAP (frontend config)
resource "google_compute_url_map" "static_site" {
provider = google
name = "${var.project}-url-map"
default_service = google_compute_backend_bucket.static_site.self_link
}
# GCP proxy (load balancer)
resource "google_compute_target_https_proxy" "static_site" {
provider = google
name = "${var.project}-target-proxy"
url_map = google_compute_url_map.static_site.self_link
ssl_certificates = [google_compute_managed_ssl_certificate.static_site.self_link]
}
# GCP forwarding rule (IP <-> Load Balancer mapping)
resource "google_compute_global_forwarding_rule" "default" {
provider = google
name = "${var.project}-forwarding-rule"
load_balancing_scheme = "EXTERNAL"
ip_address = google_compute_global_address.static_sites.address
ip_protocol = "TCP"
port_range = "443"
target = google_compute_target_https_proxy.static_site.self_link
}
resource "google_storage_bucket" "static_site" {
name = var.static_site
force_destroy = true
uniform_bucket_level_access = false
website {
main_page_suffix = "index.html"
not_found_page = "404.html"
}
cors {
origin = ["https://${var.static_site}"]
method = ["GET", "HEAD", "PUT", "POST", "DELETE"]
response_header = ["*"]
max_age_seconds = 3600
}
}
resource "google_storage_default_object_acl" "static_site_read" {
bucket = google_storage_bucket.static_site.name
role_entity = ["READER:allUsers"]
}
variable "project" {
default = "pcostesi-dev"
}
variable "credentials" {
default = "../credentials.json"
}
variable "region" {
default = "us-central1"
}
variable "zone" {
default = "us-central1-c"
}
variable "name" {
default = "main"
}
variable "static_site" {
default = "pcostesi.dev"
}
variable "email_address" {}
variable "site_verification" {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment