Last active
November 24, 2020 16:35
-
-
Save mikesparr/42adb3b463d867f0dca4865362c213ac to your computer and use it in GitHub Desktop.
Example Terraform GCP org with Memcache in service project
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_providers { | |
google = { | |
source = "hashicorp/google" | |
version = ">= 3.37" | |
} | |
google-beta = { | |
source = "hashicorp/google-beta" | |
version = ">= 3.37" | |
} | |
} | |
} | |
provider "google" { | |
version = "3.37.0" | |
region = var.region | |
zone = var.zone | |
} | |
provider "google-beta" { | |
version = "3.37.0" | |
region = var.region | |
zone = var.zone | |
} | |
data "google_billing_account" "account" { | |
provider = google-beta | |
billing_account = var.billing_account_id | |
} | |
# folders | |
resource "google_folder" "demo_org" { | |
display_name = "demo-org" | |
parent = var.root_folder | |
} | |
resource "google_folder" "shared_services" { | |
display_name = "shared-services" | |
parent = google_folder.demo_org.name | |
} | |
resource "google_folder" "engineering" { | |
display_name = "engineering" | |
parent = google_folder.demo_org.name | |
} | |
resource "google_folder" "product_x" { | |
display_name = "product-x" | |
parent = google_folder.engineering.name | |
} | |
resource "google_folder" "non_production" { | |
display_name = "non-production" | |
parent = google_folder.product_x.name | |
} | |
resource "google_folder" "production" { | |
display_name = "production" | |
parent = google_folder.product_x.name | |
} | |
# audit config | |
resource "google_folder_iam_audit_config" "audit_root_folder" { | |
folder = google_folder.demo_org.folder_id | |
service = "allServices" | |
audit_log_config { | |
log_type = "ADMIN_READ" | |
} | |
audit_log_config { | |
log_type = "DATA_READ" | |
} | |
# audit_log_config { | |
# log_type = "DATA_WRITE" | |
# } | |
} | |
# policies | |
resource "google_folder_organization_policy" "default_network_policy" { | |
folder = google_folder.demo_org.id | |
constraint = "compute.skipDefaultNetworkCreation" | |
boolean_policy { | |
enforced = true | |
} | |
} | |
resource "google_folder_organization_policy" "service_acct_key_policy" { | |
folder = google_folder.demo_org.id | |
constraint = "iam.disableServiceAccountKeyCreation" | |
boolean_policy { | |
enforced = true | |
} | |
} | |
resource "google_folder_organization_policy" "shielded_vm_policy" { | |
folder = google_folder.demo_org.id | |
constraint = "compute.requireShieldedVm" | |
boolean_policy { | |
enforced = true | |
} | |
} | |
# finding GSuite ID: https://www.youtube.com/watch?v=AeadQfJT5kw | |
resource "google_folder_organization_policy" "allow_only_policy_member_domains" { | |
folder = google_folder.demo_org.id | |
constraint = "constraints/iam.allowedPolicyMemberDomains" | |
list_policy { | |
allow { | |
values = var.allowed_domain_ids | |
} | |
} | |
} | |
resource "google_folder_organization_policy" "restrict_vm_external_ip_policy" { | |
folder = google_folder.demo_org.id | |
constraint = "compute.vmExternalIpAccess" | |
list_policy { | |
deny { | |
all = true | |
} | |
} | |
} | |
resource "google_folder_organization_policy" "disable_appengine_code_download_policy" { | |
folder = google_folder.demo_org.id | |
constraint = "appengine.disableCodeDownload" | |
boolean_policy { | |
enforced = true | |
} | |
} | |
# shared projects | |
resource "random_id" "shared_random_id" { | |
byte_length = 4 | |
} | |
# security | |
resource "google_project" "shared_security" { | |
name = "security" | |
project_id = "security2-${random_id.shared_random_id.hex}" | |
folder_id = google_folder.shared_services.name | |
billing_account = var.billing_account_id | |
labels = { "dept" : "infosec" } | |
} | |
# bucket for audit-logs, with log sink and dynamic sa role | |
resource "google_storage_bucket" "bucket_audit_logs" { | |
name = var.audit_logs_bucket_name | |
location = "US" | |
project = google_project.shared_security.project_id | |
labels = { "dept": "infosec", "role": "storage" } | |
} | |
resource "google_logging_folder_sink" "log_sink_audit" { | |
name = "demo-org-audit-logs" | |
folder = google_folder.demo_org.name | |
include_children = true | |
destination = "storage.googleapis.com/${google_storage_bucket.bucket_audit_logs.name}" | |
filter = "protoPayload.@type:\"type.googleapis.com/google.cloud.audit.AuditLog\"" | |
} | |
resource "google_project_iam_binding" "audit_log_writer" { | |
project = google_project.shared_security.project_id | |
role = "roles/storage.objectCreator" | |
members = [ | |
google_logging_folder_sink.log_sink_audit.writer_identity, | |
] | |
} | |
# monitoring | |
resource "google_project" "shared_monitoring" { | |
name = "monitoring" | |
project_id = "monitoring2-${random_id.shared_random_id.hex}" | |
folder_id = google_folder.shared_services.name | |
billing_account = var.billing_account_id | |
labels = { "dept" : "engineering" } | |
} | |
resource "google_project_service" "bq_service_monitoring" { | |
project = google_project.shared_monitoring.project_id | |
service = "monitoring.googleapis.com" | |
} | |
resource "google_monitoring_notification_channel" "notification_channel_security" { | |
provider = google-beta | |
project = google_project.shared_monitoring.project_id # var.monitoring_project_id | |
display_name = "Security Notification Channel" | |
type = "email" | |
labels = { | |
email_address = var.group_security_admins | |
} | |
} | |
resource "google_monitoring_notification_channel" "notification_channel_devops" { | |
provider = google-beta | |
project = google_project.shared_monitoring.project_id # var.monitoring_project_id | |
display_name = "Devops Notification Channel" | |
type = "email" | |
labels = { | |
email_address = var.group_devops | |
} | |
} | |
resource "google_monitoring_notification_channel" "notification_channel_billing" { | |
provider = google-beta | |
project = google_project.shared_monitoring.project_id # var.monitoring_project_id | |
display_name = "Billing Notification Channel" | |
type = "email" | |
labels = { | |
email_address = var.group_billing_admins | |
} | |
} | |
resource "google_monitoring_notification_channel" "notification_channel_developers" { | |
provider = google-beta | |
project = google_project.shared_monitoring.project_id # var.monitoring_project_id | |
display_name = "Developers Notification Channel" | |
type = "email" | |
labels = { | |
email_address = var.group_developers | |
} | |
} | |
# TODO: workspace for monitoring (not avail in Terraform it seems so manual) | |
# billing | |
resource "google_project" "shared_billing" { | |
name = "billing" | |
project_id = "billing2-${random_id.shared_random_id.hex}" | |
folder_id = google_folder.shared_services.name | |
billing_account = var.billing_account_id | |
labels = { "dept" : "finance" } | |
} | |
# enable billingbudgets.googleapis.com | |
resource "google_project_service" "bq_service_billing_budgets" { | |
project = google_project.shared_billing.project_id | |
service = "billingbudgets.googleapis.com" | |
} | |
# BigQuery dataset for billing export | |
# NOTE: must enable 'Logs Configuration Writer' for tf-sa on billing acct | |
resource "google_project_service" "bq_service_billing" { | |
project = google_project.shared_billing.project_id | |
service = "bigquery.googleapis.com" | |
} | |
resource "google_project_service" "bq_data_transfer_service_billing" { | |
project = google_project.shared_billing.project_id | |
service = "bigquerydatatransfer.googleapis.com" | |
} | |
resource "google_bigquery_dataset" "billing_dataset" { | |
project = google_project.shared_billing.project_id | |
dataset_id = "billing_export_${random_id.shared_random_id.hex}" | |
friendly_name = "Billing Export" | |
description = "Exported billing data" | |
location = "US" | |
delete_contents_on_destroy = true # destroying resource will fail otherwise | |
labels = { "dept" = "finance", "role" = "analytics" } | |
} | |
resource "google_logging_billing_account_sink" "billing_bq_export" { | |
name = "billing-export" | |
billing_account = var.billing_account_id | |
destination = "bigquery.googleapis.com/projects/${google_project.shared_billing.project_id}/datasets/${google_bigquery_dataset.billing_dataset.dataset_id}" | |
} | |
resource "google_project_iam_binding" "billing_export_writer" { | |
project = google_project.shared_billing.project_id | |
role = "roles/bigquery.dataOwner" | |
members = [ | |
google_logging_billing_account_sink.billing_bq_export.writer_identity, | |
] | |
} | |
# host projects | |
# nonprod | |
resource "google_project" "shared_nw_nonprod" { | |
name = "shared-nw-nonprod" | |
project_id = "shared-nw-nonprod-${random_id.shared_random_id.hex}" | |
folder_id = google_folder.shared_services.name | |
billing_account = var.billing_account_id | |
labels = { "dept" : "network", "env" : "non-production" } | |
} | |
resource "google_project_service" "compute_shared_nw_nonprod" { | |
project = google_project.shared_nw_nonprod.project_id | |
service = "compute.googleapis.com" | |
} | |
resource "google_project_service" "container_shared_nw_nonprod" { | |
project = google_project.shared_nw_nonprod.project_id | |
service = "container.googleapis.com" | |
} | |
resource "google_project_service" "servicenetworking_shared_nw_nonprod" { | |
project = google_project.shared_nw_nonprod.project_id | |
service = "servicenetworking.googleapis.com" | |
} | |
resource "google_compute_shared_vpc_host_project" "host_nonprod" { | |
project = google_project.shared_nw_nonprod.project_id | |
depends_on = [google_project_service.compute_shared_nw_nonprod] | |
} | |
resource "google_compute_network" "vpc_devops" { | |
name = "devops-10-19-0-0" | |
routing_mode = "REGIONAL" | |
auto_create_subnetworks = false | |
project = google_project.shared_nw_nonprod.project_id | |
depends_on = [google_project_service.compute_shared_nw_nonprod] | |
} | |
resource "google_compute_subnetwork" "subnet_devops_k8s" { | |
name = "k8s-nodes-devops" | |
ip_cidr_range = "10.19.0.0/22" | |
region = var.region | |
private_ip_google_access = true | |
project = google_project.shared_nw_nonprod.project_id | |
network = google_compute_network.vpc_devops.id | |
secondary_ip_range { | |
range_name = "k8s-pods-devops" | |
ip_cidr_range = "10.89.0.0/18" | |
} | |
secondary_ip_range { | |
range_name = "k8s-svcs-devops" | |
ip_cidr_range = "10.89.64.0/22" | |
} | |
} | |
resource "google_compute_subnetwork" "subnet_devops_bastion" { | |
name = "bastion-devops" | |
ip_cidr_range = "10.19.64.0/29" | |
region = var.region | |
private_ip_google_access = true | |
project = google_project.shared_nw_nonprod.project_id | |
network = google_compute_network.vpc_devops.id | |
} | |
resource "google_compute_subnetwork" "subnet_devops_vms" { | |
name = "vms-devops" | |
ip_cidr_range = "10.19.65.0/24" | |
region = var.region | |
private_ip_google_access = true | |
project = google_project.shared_nw_nonprod.project_id | |
network = google_compute_network.vpc_devops.id | |
} | |
resource "google_compute_subnetwork" "subnet_devops_dbs" { | |
name = "databases-devops" | |
ip_cidr_range = "10.19.70.0/24" | |
region = var.region | |
private_ip_google_access = true | |
project = google_project.shared_nw_nonprod.project_id | |
network = google_compute_network.vpc_devops.id | |
} | |
# TODO: firewall rule port 22 for bastion | |
resource "google_compute_network" "vpc_development" { | |
name = "dev-10-12-0-0" | |
routing_mode = "REGIONAL" | |
auto_create_subnetworks = false | |
project = google_project.shared_nw_nonprod.project_id | |
depends_on = [google_project_service.compute_shared_nw_nonprod] | |
} | |
resource "google_compute_subnetwork" "subnet_dev_k8s" { | |
name = "k8s-nodes-dev" | |
ip_cidr_range = "10.12.0.0/22" | |
region = var.region | |
project = google_project.shared_nw_nonprod.project_id | |
private_ip_google_access = true | |
network = google_compute_network.vpc_development.id | |
secondary_ip_range { | |
range_name = "k8s-pods-dev" | |
ip_cidr_range = "10.82.0.0/18" | |
} | |
secondary_ip_range { | |
range_name = "k8s-svcs-dev" | |
ip_cidr_range = "10.82.64.0/22" | |
} | |
} | |
resource "google_compute_global_address" "service_range" { | |
provider = google-beta | |
name = "devrange-${random_id.shared_random_id.hex}" | |
project = google_project.shared_nw_nonprod.project_id | |
purpose = "VPC_PEERING" | |
address_type = "INTERNAL" | |
prefix_length = 16 | |
network = google_compute_network.vpc_development.id | |
} | |
resource "google_service_networking_connection" "private_service_connection" { | |
provider = google-beta | |
network = google_compute_network.vpc_development.id | |
service = "servicenetworking.googleapis.com" | |
reserved_peering_ranges = [google_compute_global_address.service_range.name] | |
} | |
resource "google_compute_subnetwork" "subnet_dev_bastion" { | |
name = "bastion-dev" | |
ip_cidr_range = "10.12.64.0/29" | |
region = var.region | |
private_ip_google_access = true | |
project = google_project.shared_nw_nonprod.project_id | |
network = google_compute_network.vpc_development.id | |
} | |
resource "google_compute_subnetwork" "subnet_dev_vms" { | |
name = "vms-dev" | |
ip_cidr_range = "10.12.65.0/24" | |
region = var.region | |
private_ip_google_access = true | |
project = google_project.shared_nw_nonprod.project_id | |
network = google_compute_network.vpc_development.id | |
} | |
resource "google_compute_subnetwork" "subnet_dev_dbs" { | |
name = "databases-dev" | |
ip_cidr_range = "10.12.70.0/24" | |
region = var.region | |
private_ip_google_access = true | |
project = google_project.shared_nw_nonprod.project_id | |
network = google_compute_network.vpc_development.id | |
} | |
# TODO: firewall rule port 22 for bastion | |
# prod | |
resource "google_project" "shared_nw_prod" { | |
name = "shared-nw-prod" | |
project_id = "shared-nw-prod-${random_id.shared_random_id.hex}" | |
folder_id = google_folder.shared_services.name | |
billing_account = var.billing_account_id | |
labels = { "dept" : "network", "env" : "production" } | |
} | |
resource "google_project_service" "compute_shared_nw_prod" { | |
project = google_project.shared_nw_prod.project_id | |
service = "compute.googleapis.com" | |
} | |
resource "google_project_service" "container_shared_nw_prod" { | |
project = google_project.shared_nw_prod.project_id | |
service = "container.googleapis.com" | |
} | |
resource "google_compute_shared_vpc_host_project" "host_prod" { | |
project = google_project.shared_nw_prod.project_id | |
depends_on = [google_project_service.compute_shared_nw_prod] | |
} | |
# network stage | |
resource "google_compute_network" "vpc_stage" { | |
name = "stage-10-11-0-0" | |
routing_mode = "REGIONAL" | |
auto_create_subnetworks = false | |
project = google_project.shared_nw_prod.project_id | |
depends_on = [google_project_service.compute_shared_nw_prod] | |
} | |
resource "google_compute_subnetwork" "subnet_stage_k8s" { | |
name = "k8s-nodes-stage" | |
ip_cidr_range = "10.11.0.0/22" | |
region = var.region | |
project = google_project.shared_nw_prod.project_id | |
private_ip_google_access = true | |
network = google_compute_network.vpc_stage.id | |
secondary_ip_range { | |
range_name = "k8s-pods-stage" | |
ip_cidr_range = "10.81.0.0/18" | |
} | |
secondary_ip_range { | |
range_name = "k8s-svcs-stage" | |
ip_cidr_range = "10.81.64.0/22" | |
} | |
} | |
resource "google_compute_subnetwork" "subnet_stage_bastion" { | |
name = "bastion-stage" | |
ip_cidr_range = "10.11.64.0/29" | |
region = var.region | |
private_ip_google_access = true | |
project = google_project.shared_nw_prod.project_id | |
network = google_compute_network.vpc_stage.id | |
} | |
resource "google_compute_subnetwork" "subnet_stage_vms" { | |
name = "vms-stage" | |
ip_cidr_range = "10.11.65.0/24" | |
region = var.region | |
private_ip_google_access = true | |
project = google_project.shared_nw_prod.project_id | |
network = google_compute_network.vpc_stage.id | |
} | |
resource "google_compute_subnetwork" "subnet_stage_dbs" { | |
name = "databases-stage" | |
ip_cidr_range = "10.11.70.0/24" | |
region = var.region | |
private_ip_google_access = true | |
project = google_project.shared_nw_prod.project_id | |
network = google_compute_network.vpc_stage.id | |
} | |
# network prod | |
resource "google_compute_network" "vpc_production" { | |
name = "production-10-10-0-0" | |
routing_mode = "REGIONAL" | |
auto_create_subnetworks = false | |
project = google_project.shared_nw_prod.project_id | |
depends_on = [google_project_service.compute_shared_nw_prod] | |
} | |
resource "google_compute_subnetwork" "subnet_prod_k8s" { | |
name = "k8s-nodes-prod" | |
ip_cidr_range = "10.10.0.0/22" | |
region = var.region | |
project = google_project.shared_nw_prod.project_id | |
private_ip_google_access = true | |
network = google_compute_network.vpc_production.id | |
secondary_ip_range { | |
range_name = "k8s-pods-prod" | |
ip_cidr_range = "10.80.0.0/18" | |
} | |
secondary_ip_range { | |
range_name = "k8s-svcs-prod" | |
ip_cidr_range = "10.80.64.0/22" | |
} | |
} | |
resource "google_compute_subnetwork" "subnet_prod_bastion" { | |
name = "bastion-prod" | |
ip_cidr_range = "10.12.64.0/29" | |
region = var.region | |
private_ip_google_access = true | |
project = google_project.shared_nw_prod.project_id | |
network = google_compute_network.vpc_production.id | |
} | |
resource "google_compute_subnetwork" "subnet_prod_vms" { | |
name = "vms-prod" | |
ip_cidr_range = "10.11.65.0/24" | |
region = var.region | |
private_ip_google_access = true | |
project = google_project.shared_nw_prod.project_id | |
network = google_compute_network.vpc_production.id | |
} | |
resource "google_compute_subnetwork" "subnet_prod_dbs" { | |
name = "databases-prod" | |
ip_cidr_range = "10.11.70.0/24" | |
region = var.region | |
private_ip_google_access = true | |
project = google_project.shared_nw_prod.project_id | |
network = google_compute_network.vpc_production.id | |
} | |
# service projects | |
# dev | |
resource "google_project" "development" { | |
name = "development" | |
project_id = "development-${random_id.shared_random_id.hex}" | |
folder_id = google_folder.non_production.name | |
billing_account = var.billing_account_id | |
labels = { "dept" : "engineering", "env" : "non-production", "product" : "x" } | |
} | |
resource "google_project_service" "compute_development" { | |
project = google_project.development.project_id | |
service = "compute.googleapis.com" | |
} | |
resource "google_project_service" "container_development" { | |
project = google_project.development.project_id | |
service = "container.googleapis.com" | |
} | |
resource "google_project_service" "servicenetworking_development" { | |
project = google_project.development.project_id | |
service = "servicenetworking.googleapis.com" | |
} | |
resource "google_project_service" "memcache_development" { | |
project = google_project.development.project_id | |
service = "memcache.googleapis.com" | |
} | |
resource "google_compute_shared_vpc_service_project" "service_dev" { | |
host_project = google_compute_shared_vpc_host_project.host_nonprod.project | |
service_project = google_project.development.project_id | |
} | |
# add IAM role to link project to shared subnet | |
data "google_project" "project_development" { | |
project_id = google_project.development.project_id | |
} | |
resource "google_compute_subnetwork_iam_member" "member_development" { | |
project = google_project.shared_nw_nonprod.project_id | |
region = google_compute_subnetwork.subnet_dev_k8s.region | |
subnetwork = google_compute_subnetwork.subnet_dev_k8s.name | |
role = "roles/compute.networkUser" | |
member = format("serviceAccount:service-%[email protected]", data.google_project.project_development.number) | |
} | |
# add memcache (Memorystore) example to development | |
resource "google_memcache_instance" "cache_dev" { | |
provider = google-beta | |
project = google_project.development.project_id | |
name = "cache-dev" | |
region = var.region | |
authorized_network = google_service_networking_connection.private_service_connection.network | |
node_config { | |
cpu_count = 1 | |
memory_size_mb = 1024 | |
} | |
node_count = 1 | |
memcache_version = "MEMCACHE_1_5" | |
depends_on = [ | |
google_service_networking_connection.private_service_connection, | |
google_project_service.memcache_development | |
] | |
} | |
# stage | |
resource "google_project" "stage" { | |
name = "stage" | |
project_id = "stage-${random_id.shared_random_id.hex}" | |
folder_id = google_folder.production.name | |
billing_account = var.billing_account_id | |
labels = { "dept" : "engineering", "env" : "non-production", "product" : "x" } | |
} | |
resource "google_project_service" "compute_stage" { | |
project = google_project.stage.project_id | |
service = "compute.googleapis.com" | |
} | |
resource "google_project_service" "container_stage" { | |
project = google_project.stage.project_id | |
service = "container.googleapis.com" | |
} | |
resource "google_compute_shared_vpc_service_project" "service_stage" { | |
host_project = google_compute_shared_vpc_host_project.host_prod.project | |
service_project = google_project.stage.project_id | |
} | |
# add IAM role to link project to shared subnet | |
data "google_project" "project_stage" { | |
project_id = google_project.stage.project_id | |
} | |
resource "google_compute_subnetwork_iam_member" "member_stage" { | |
project = google_project.shared_nw_prod.project_id | |
region = google_compute_subnetwork.subnet_stage_k8s.region | |
subnetwork = google_compute_subnetwork.subnet_stage_k8s.name | |
role = "roles/compute.networkUser" | |
member = format("serviceAccount:service-%[email protected]", data.google_project.project_stage.number) | |
} | |
# prod | |
resource "google_project" "production" { | |
name = "production" | |
project_id = "production-${random_id.shared_random_id.hex}" | |
folder_id = google_folder.production.name | |
billing_account = var.billing_account_id | |
labels = { "dept" : "engineering", "env" : "production", "product" : "x" } | |
} | |
resource "google_project_service" "compute_production" { | |
project = google_project.production.project_id | |
service = "compute.googleapis.com" | |
} | |
resource "google_project_service" "container_production" { | |
project = google_project.production.project_id | |
service = "container.googleapis.com" | |
} | |
resource "google_compute_shared_vpc_service_project" "service_prod" { | |
host_project = google_compute_shared_vpc_host_project.host_prod.project | |
service_project = google_project.production.project_id | |
} | |
# add IAM role to link project to shared subnet | |
data "google_project" "project_production" { | |
project_id = google_project.production.project_id | |
} | |
resource "google_compute_subnetwork_iam_member" "member_production" { | |
project = google_project.shared_nw_prod.project_id | |
region = google_compute_subnetwork.subnet_prod_k8s.region | |
subnetwork = google_compute_subnetwork.subnet_prod_k8s.name | |
role = "roles/compute.networkUser" | |
member = format("serviceAccount:service-%[email protected]", data.google_project.project_production.number) | |
} | |
# BUDGET | |
# budget notifications | |
resource "google_billing_budget" "budget_sandbox" { | |
provider = google-beta | |
billing_account = data.google_billing_account.account.id | |
display_name = "Sandbox Billing Budget" | |
budget_filter { | |
projects = [ | |
"projects/mike-stage" | |
] | |
} | |
amount { | |
specified_amount { | |
currency_code = "USD" | |
units = "100" | |
} | |
} | |
threshold_rules { | |
threshold_percent = 0.75 | |
} | |
all_updates_rule { | |
monitoring_notification_channels = [ | |
google_monitoring_notification_channel.notification_channel_billing.id, | |
] | |
} | |
} | |
# LOG MONITORING / ALERTS (production) | |
resource "google_logging_metric" "log_metric_route" { | |
project = google_project.production.project_id | |
name = "route_monitoring/metric" | |
filter = "resource.type=\"gce_route\" AND jsonPayload.event_subtype=\"compute.routes.delete\" OR jsonPayload.event_subtype=\"compute.routes.insert\"" | |
metric_descriptor { | |
metric_kind = "DELTA" | |
value_type = "INT64" | |
unit = "1" | |
display_name = "Route Monitoring" | |
} | |
} | |
resource "google_monitoring_alert_policy" "alert_policy_route" { | |
project = google_project.shared_monitoring.project_id | |
display_name = "Route Monitoring" | |
combiner = "OR" | |
notification_channels = [google_monitoring_notification_channel.notification_channel_security.name] | |
conditions { | |
display_name = "logging/user/ROUTE_MONITORING" | |
condition_threshold { | |
filter = "metric.type=\"logging.googleapis.com/user/route_monitoring/metric\" AND resource.type=\"global\"" | |
duration = "60s" | |
comparison = "COMPARISON_GT" | |
aggregations { | |
alignment_period = "60s" | |
per_series_aligner = "ALIGN_RATE" | |
cross_series_reducer = "REDUCE_COUNT" | |
} | |
trigger { | |
count = 1 | |
percent = 0 | |
} | |
} | |
} | |
} | |
resource "google_logging_metric" "log_metric_sql_instance" { | |
project = google_project.production.project_id | |
name = "sql_instance_monitoring/metric" | |
filter = "protoPayload.methodName=\"cloudsql.instances.update\"" | |
metric_descriptor { | |
metric_kind = "DELTA" | |
value_type = "INT64" | |
unit = "1" | |
display_name = "SQL Instance Monitoring" | |
} | |
} | |
resource "google_monitoring_alert_policy" "alert_policy_sql_instance" { | |
project = google_project.shared_monitoring.project_id | |
display_name = "SQL Instance Monitoring" | |
combiner = "OR" | |
notification_channels = [google_monitoring_notification_channel.notification_channel_security.name] | |
conditions { | |
display_name = "logging/user/SQL_INSTANCE_MONITORING" | |
condition_threshold { | |
filter = "metric.type=\"logging.googleapis.com/user/sql_instance_monitoring/metric\" AND resource.type=\"global\"" | |
duration = "60s" | |
comparison = "COMPARISON_GT" | |
aggregations { | |
alignment_period = "60s" | |
per_series_aligner = "ALIGN_RATE" | |
cross_series_reducer = "REDUCE_COUNT" | |
} | |
trigger { | |
count = 1 | |
percent = 0 | |
} | |
} | |
} | |
} | |
resource "google_logging_metric" "log_metric_network" { | |
project = google_project.shared_nw_prod.project_id | |
name = "network_monitoring/metric" | |
filter = "resource.type=gce_network AND jsonPayload.event_subtype=\"compute.networks.insert\" OR jsonPayload.event_subtype=\"compute.networks.patch\" OR jsonPayload.event_subtype=\"compute.networks.delete\" OR jsonPayload.event_subtype=\"compute.networks.removePeering\" OR jsonPayload.event_subtype=\"compute.networks.addPeering\"" | |
metric_descriptor { | |
metric_kind = "DELTA" | |
value_type = "INT64" | |
unit = "1" | |
display_name = "Network Monitoring" | |
} | |
} | |
resource "google_monitoring_alert_policy" "alert_policy_network" { | |
project = google_project.shared_monitoring.project_id | |
display_name = "Network Monitoring" | |
combiner = "OR" | |
notification_channels = [google_monitoring_notification_channel.notification_channel_security.name] | |
conditions { | |
display_name = "logging/user/NETWORK_MONITORING" | |
condition_threshold { | |
filter = "metric.type=\"logging.googleapis.com/user/network_monitoring/metric\" AND resource.type=\"global\"" | |
duration = "60s" | |
comparison = "COMPARISON_GT" | |
aggregations { | |
alignment_period = "60s" | |
per_series_aligner = "ALIGN_RATE" | |
cross_series_reducer = "REDUCE_COUNT" | |
} | |
trigger { | |
count = 1 | |
percent = 0 | |
} | |
} | |
} | |
} | |
resource "google_logging_metric" "log_metric_firewall" { | |
project = google_project.shared_nw_prod.project_id | |
name = "firewall_monitoring/metric" | |
filter = "resource.type=\"gce_firewall_rule\" AND jsonPayload.event_subtype=\"compute.firewalls.patch\" OR jsonPayload.event_subtype=\"compute.firewalls.insert\"" | |
metric_descriptor { | |
metric_kind = "DELTA" | |
value_type = "INT64" | |
unit = "1" | |
display_name = "Firewall Monitoring" | |
} | |
} | |
resource "google_monitoring_alert_policy" "alert_policy_firewall" { | |
project = google_project.shared_monitoring.project_id | |
display_name = "Firewall Monitoring" | |
combiner = "OR" | |
notification_channels = [google_monitoring_notification_channel.notification_channel_security.name] | |
conditions { | |
display_name = "logging/user/FIREWALL_MONITORING" | |
condition_threshold { | |
filter = "metric.type=\"logging.googleapis.com/user/firewall_monitoring/metric\" AND resource.type=\"global\"" | |
duration = "60s" | |
comparison = "COMPARISON_GT" | |
aggregations { | |
alignment_period = "60s" | |
per_series_aligner = "ALIGN_RATE" | |
cross_series_reducer = "REDUCE_COUNT" | |
} | |
trigger { | |
count = 1 | |
percent = 0 | |
} | |
} | |
} | |
} | |
resource "google_logging_metric" "log_metric_project_ownership" { | |
project = google_project.production.project_id | |
name = "project_ownership_monitoring/metric" | |
filter = "(protoPayload.serviceName=\"cloudresourcemanager.googleapis.com\") AND (ProjectOwnership OR projectOwnerInvitee) OR (protoPayload.serviceData.policyDelta.bindingDeltas.action=\"REMOVE\" AND protoPayload.serviceData.policyDelta.bindingDeltas.role=\"roles/owner\") OR (protoPayload.serviceData.policyDelta.bindingDeltas.action=\"ADD\" AND protoPayload.serviceData.policyDelta.bindingDeltas.role=\"roles/owner\")" | |
metric_descriptor { | |
metric_kind = "DELTA" | |
value_type = "INT64" | |
unit = "1" | |
display_name = "Project Ownership Monitoring" | |
} | |
} | |
resource "google_monitoring_alert_policy" "alert_policy_project_ownership" { | |
project = google_project.shared_monitoring.project_id | |
display_name = "Project Ownership Monitoring" | |
combiner = "OR" | |
notification_channels = [google_monitoring_notification_channel.notification_channel_security.name] | |
conditions { | |
display_name = "logging/user/PROJECT_OWNERSHIP_MONITORING" | |
condition_threshold { | |
filter = "metric.type=\"logging.googleapis.com/user/project_ownership_monitoring/metric\" AND resource.type=\"global\"" | |
duration = "60s" | |
comparison = "COMPARISON_GT" | |
aggregations { | |
alignment_period = "60s" | |
per_series_aligner = "ALIGN_RATE" | |
cross_series_reducer = "REDUCE_COUNT" | |
} | |
trigger { | |
count = 1 | |
percent = 0 | |
} | |
} | |
} | |
} | |
resource "google_logging_metric" "log_metric_bucket_iam" { | |
project = google_project.production.project_id | |
name = "bucket_iam_monitoring/metric" | |
filter = "resource.type=gcs_bucket AND protoPayload.methodName=\"storage.setIamPermissions\"" | |
metric_descriptor { | |
metric_kind = "DELTA" | |
value_type = "INT64" | |
unit = "1" | |
display_name = "Bucket IAM Monitoring" | |
} | |
} | |
resource "google_monitoring_alert_policy" "alert_policy_bucket_iam" { | |
project = google_project.shared_monitoring.project_id | |
display_name = "Bucket IAM Monitoring" | |
combiner = "OR" | |
notification_channels = [google_monitoring_notification_channel.notification_channel_security.name] | |
conditions { | |
display_name = "logging/user/BUCKET_IAM_MONITORING" | |
condition_threshold { | |
filter = "metric.type=\"logging.googleapis.com/user/bucket_iam_monitoring/metric\" AND resource.type=\"global\"" | |
duration = "60s" | |
comparison = "COMPARISON_GT" | |
aggregations { | |
alignment_period = "60s" | |
per_series_aligner = "ALIGN_RATE" | |
cross_series_reducer = "REDUCE_COUNT" | |
} | |
trigger { | |
count = 1 | |
percent = 0 | |
} | |
} | |
} | |
} | |
resource "google_logging_metric" "log_metric_audit_config" { | |
project = google_project.production.project_id | |
name = "audit_config_monitoring/metric" | |
filter = "protoPayload.methodName=\"SetIamPolicy\" AND protoPayload.serviceData.policyDelta.auditConfigDeltas:*" | |
metric_descriptor { | |
metric_kind = "DELTA" | |
value_type = "INT64" | |
unit = "1" | |
display_name = "Audit Config Monitoring" | |
} | |
} | |
resource "google_monitoring_alert_policy" "alert_policy_audit_config" { | |
project = google_project.shared_monitoring.project_id | |
display_name = "Audit Config Monitoring" | |
combiner = "OR" | |
notification_channels = [google_monitoring_notification_channel.notification_channel_security.name] | |
conditions { | |
display_name = "logging/user/AUDIT_CONFIG_MONITORING" | |
condition_threshold { | |
filter = "metric.type=\"logging.googleapis.com/user/audit_config_monitoring/metric\" AND resource.type=\"global\"" | |
duration = "60s" | |
comparison = "COMPARISON_GT" | |
aggregations { | |
alignment_period = "60s" | |
per_series_aligner = "ALIGN_RATE" | |
cross_series_reducer = "REDUCE_COUNT" | |
} | |
trigger { | |
count = 1 | |
percent = 0 | |
} | |
} | |
} | |
} | |
resource "google_logging_metric" "log_metric_custom_role" { | |
project = google_project.production.project_id | |
name = "custom_role_monitoring/metric" | |
filter = "resource.type=\"iam_role\" AND protoPayload.methodName=\"google.iam.admin.v1.CreateRole\" OR protoPayload.methodName=\"google.iam.admin.v1.DeleteRole\" OR protoPayload.methodName=\"google.iam.admin.v1.UpdateRole\"" | |
metric_descriptor { | |
metric_kind = "DELTA" | |
value_type = "INT64" | |
unit = "1" | |
display_name = "Custom Role Monitoring" | |
} | |
} | |
resource "google_monitoring_alert_policy" "alert_policy_custom_role" { | |
project = google_project.shared_monitoring.project_id | |
display_name = "Custom Role Monitoring" | |
combiner = "OR" | |
notification_channels = [google_monitoring_notification_channel.notification_channel_security.name] | |
conditions { | |
display_name = "logging/user/CUSTOM_ROLE_MONITORING" | |
condition_threshold { | |
filter = "metric.type=\"logging.googleapis.com/user/custom_role_monitoring/metric\" AND resource.type=\"global\"" | |
duration = "60s" | |
comparison = "COMPARISON_GT" | |
aggregations { | |
alignment_period = "60s" | |
per_series_aligner = "ALIGN_RATE" | |
cross_series_reducer = "REDUCE_COUNT" | |
} | |
trigger { | |
count = 1 | |
percent = 0 | |
} | |
} | |
} | |
} | |
# IAM roles | |
# org | |
# resource "google_organization_iam_binding" "org_iam_org_admin" { | |
# org = var.org_id | |
# role = "roles/iam.organizationAdmin" | |
# | |
# members = [ | |
# var.group_org_admins | |
# ] | |
# } | |
# | |
# resource "google_organization_iam_binding" "org_iam_billing_admin" { | |
# org = var.org_id | |
# role = "roles/billing.admin" | |
# | |
# members = [ | |
# var.group_billing_admins | |
# ] | |
# } | |
# | |
# Billing Account User (tf-sa: org) | |
# resource "google_organization_iam_binding" "org_iam_billing_user" { | |
# org = var.org_id | |
# role = "roles/billing.user" | |
# | |
# members = [ | |
# var.sa_terraform_admin | |
# ] | |
# } | |
# | |
# Organization Policy Admin (tf-sa: org) | |
# resource "google_organization_iam_binding" "org_iam_org_policy_admin" { | |
# org = var.org_id | |
# role = "roles/orgpolicy.policyAdmin" | |
# | |
# members = [ | |
# var.sa_terraform_admin | |
# ] | |
# } | |
# | |
# Cloud Security Scanner Editor (security: org) | |
# resource "google_organization_iam_binding" "org_iam_security_scanner_editor" { | |
# org = var.org_id | |
# role = "roles/cloudsecurityscanner.editor" | |
# | |
# members = [ | |
# var.group_security_admins | |
# ] | |
# } | |
# TODO: change (org) scoped bindings to google_organization_iam_binding (non-playground-org) | |
# Viewer (security, network, devops: org) | |
resource "google_folder_iam_binding" "folder_iam_viewer" { | |
folder = google_folder.demo_org.id | |
role = "roles/viewer" | |
members = [ | |
var.group_security_admins, | |
var.group_network_admins, | |
var.group_devops | |
] | |
} | |
# Security Admin (security: org) | |
resource "google_folder_iam_binding" "folder_iam_security_admin" { | |
folder = google_folder.demo_org.id | |
role = "roles/iam.securityAdmin" | |
members = [ | |
var.group_security_admins | |
] | |
} | |
# Compute Network Admin (network: org) roles/compute.networkAdmin | |
resource "google_folder_iam_binding" "folder_iam_compute_network_admin" { | |
folder = google_folder.demo_org.id | |
role = "roles/compute.networkAdmin" | |
members = [ | |
var.group_network_admins | |
] | |
} | |
# Service Networking Admin (network: org) roles/servicenetworking.networksAdmin | |
resource "google_folder_iam_binding" "folder_iam_service_networking_admin" { | |
folder = google_folder.demo_org.id | |
role = "roles/servicenetworking.networksAdmin" | |
members = [ | |
var.group_network_admins | |
] | |
} | |
# Compute Shared VPC Admin (network, tf-sa: org) | |
resource "google_folder_iam_binding" "folder_iam_xpn_admin" { | |
folder = google_folder.demo_org.id | |
role = "roles/compute.xpnAdmin" | |
members = [ | |
var.group_network_admins | |
] | |
} | |
# Logs Viewer (network: org) | |
resource "google_folder_iam_binding" "folder_iam_log_viewer" { | |
folder = google_folder.demo_org.id | |
role = "roles/compute.xpnAdmin" | |
members = [ | |
var.group_network_admins | |
] | |
} | |
# Private Logs Viewer (security: org) | |
resource "google_folder_iam_binding" "folder_iam_private_log_viewer" { | |
folder = google_folder.demo_org.id | |
role = "roles/logging.viewer" | |
members = [ | |
var.group_network_admins | |
] | |
} | |
# Compute Security Admin (security: org) | |
resource "google_folder_iam_binding" "folder_iam_compute_security_admin" { | |
folder = google_folder.demo_org.id | |
role = "roles/compute.securityAdmin" | |
members = [ | |
var.group_network_admins | |
] | |
} | |
# Compute Organization Security Policy Admin (security: org) | |
resource "google_folder_iam_binding" "folder_iam_compute_org_security_policy_admin" { | |
folder = google_folder.demo_org.id | |
role = "roles/compute.orgSecurityPolicyAdmin" | |
members = [ | |
var.group_network_admins | |
] | |
} | |
# Compute Instance Admin (tf-sa: org) | |
resource "google_folder_iam_binding" "folder_iam_compute_instance_admin" { | |
folder = google_folder.demo_org.id | |
role = "roles/compute.instanceAdmin" | |
members = [ | |
var.sa_terraform_admin | |
] | |
} | |
# Create Service Accounts (tf-sa: org) | |
resource "google_folder_iam_binding" "folder_iam_sa_creator" { | |
folder = google_folder.demo_org.id | |
role = "roles/iam.serviceAccountCreator" | |
members = [ | |
var.sa_terraform_admin | |
] | |
} | |
# Delete Service Accounts (tf-sa: org) | |
resource "google_folder_iam_binding" "folder_iam_sa_deleter" { | |
folder = google_folder.demo_org.id | |
role = "roles/iam.serviceAccountDeleter" | |
members = [ | |
var.sa_terraform_admin | |
] | |
} | |
# Service Account User (tf-sa: org) | |
resource "google_folder_iam_binding" "folder_iam_sa_user" { | |
folder = google_folder.demo_org.id | |
role = "roles/iam.serviceAccountUser" | |
members = [ | |
var.sa_terraform_admin | |
] | |
} | |
# Service Account Token Creator (tf-sa: org) | |
resource "google_folder_iam_binding" "folder_iam_sa_token_creator" { | |
folder = google_folder.demo_org.id | |
role = "roles/iam.serviceAccountTokenCreator" | |
members = [ | |
var.sa_terraform_admin | |
] | |
} | |
# Logs Configuration Writer (tf-sa: org) | |
resource "google_folder_iam_binding" "folder_iam_log_config_writer" { | |
folder = google_folder.demo_org.id | |
role = "roles/logging.configWriter" | |
members = [ | |
var.sa_terraform_admin | |
] | |
} | |
# Folder Creator (tf-sa: org) | |
resource "google_folder_iam_binding" "folder_iam_folder_creator" { | |
folder = google_folder.demo_org.id | |
role = "roles/resourcemanager.folderCreator" | |
members = [ | |
var.sa_terraform_admin | |
] | |
} | |
# Folder Editor (tf-sa: org) | |
resource "google_folder_iam_binding" "folder_iam_folder_editor" { | |
folder = google_folder.demo_org.id | |
role = "roles/resourcemanager.folderEditor" | |
members = [ | |
var.sa_terraform_admin | |
] | |
} | |
# projects | |
# Project Creator (tf-sa: org) | |
resource "google_folder_iam_binding" "folder_iam_project_creator" { | |
folder = google_folder.demo_org.id | |
role = "roles/resourcemanager.projectCreator" | |
members = [ | |
var.sa_terraform_admin | |
] | |
} | |
# Project Deleter (tf-sa: org) | |
resource "google_folder_iam_binding" "folder_iam_product_deleter" { | |
folder = google_folder.demo_org.id | |
role = "roles/resourcemanager.projectDeleter" | |
members = [ | |
var.sa_terraform_admin | |
] | |
} | |
# Access Context Manager Editor (tf-sa: org) | |
resource "google_folder_iam_binding" "folder_iam_access_context_editor" { | |
folder = google_folder.demo_org.id | |
role = "roles/accesscontextmanager.policyEditor" | |
members = [ | |
var.sa_terraform_admin | |
] | |
} | |
# BigQuery Data Viewer (billing: billing project) | |
resource "google_project_iam_binding" "project_iam_bq_data_viewer" { | |
project = google_project.shared_billing.project_id | |
role = "roles/bigquery.dataViewer" | |
members = [ | |
var.group_billing_admins | |
] | |
} | |
# Editor (security: security project) | |
resource "google_project_iam_binding" "project_iam_security_editor" { | |
project = google_project.shared_security.project_id | |
role = "roles/editor" | |
members = [ | |
var.group_security_admins | |
] | |
} | |
# Monitoring Admin (devops: monitoring project) | |
resource "google_project_iam_binding" "project_iam_monitoring_admin" { | |
project = google_project.shared_monitoring.project_id | |
role = "roles/monitoring.admin" | |
members = [ | |
var.group_devops | |
] | |
} | |
# Monitoring Viewer (dev: monitoring project) | |
resource "google_project_iam_binding" "project_iam_monitoring_viewer" { | |
project = google_project.shared_monitoring.project_id | |
role = "roles/monitoring.viewer" | |
members = [ | |
var.group_developers | |
] | |
} | |
# Kubernetes Engine Developer (dev: development project) | |
resource "google_project_iam_binding" "project_iam_container_developer" { | |
project = google_project.development.project_id | |
role = "roles/container.developer" | |
members = [ | |
var.group_developers | |
] | |
} |
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
variable "org_id" { | |
default = "YOUR_ORG_ID" | |
} | |
variable "billing_account_id" { | |
default = "CHANGEME" # DoiT Playground | |
} | |
# wherever you set up your workspace for monitoring | |
variable "monitoring_project_id" { | |
default = "mike-stage" | |
} | |
# finding GSuite ID: https://www.youtube.com/watch?v=AeadQfJT5kw | |
variable "allowed_domain_ids" { | |
default = ["CHANGEME"] | |
} | |
variable "region" { | |
default = "us-west4" | |
} | |
variable "zone" { | |
default = "us-west4-a" | |
} | |
variable "root_folder" { | |
default = "folders/CHANGEME" # CHANGE: folder in playground | |
} | |
variable "audit_logs_bucket_name" { | |
default = "demo-org-audit-logs" | |
} | |
# IAM groups (set up in Cloud Identity or GSuite) | |
# CHANGE: using personal domain for testing / demo | |
variable "group_org_admins" { | |
default = "group:[email protected]" | |
} | |
variable "group_billing_admins" { | |
default = "group:[email protected]" | |
} | |
variable "group_security_admins" { | |
default = "group:[email protected]" | |
} | |
variable "group_network_admins" { | |
default = "group:[email protected]" | |
} | |
variable "group_devops" { | |
default = "group:[email protected]" | |
} | |
variable "group_developers" { | |
default = "group:[email protected]" | |
} | |
variable "sa_terraform_admin" { | |
default = "serviceAccount:[email protected]" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment