diff --git a/terraform/basic_gke/main.tf b/terraform/basic_gke/main.tf index 46b7963..77aee44 100644 --- a/terraform/basic_gke/main.tf +++ b/terraform/basic_gke/main.tf @@ -48,6 +48,7 @@ data "google_project" "project" { module "networking" { source = "../modules/networking" project = var.project + region = var.region } #################### Workload Identity #################### @@ -70,183 +71,24 @@ resource "google_project_service" "cloudkms" { disable_dependent_services = true } -resource "random_id" "gke_db" { - byte_length = 4 -} - -resource "google_kms_key_ring" "gke_db" { - project = var.project - name = "gke-db-${random_id.gke_db.hex}" - location = var.region - - lifecycle { - prevent_destroy = true - } - - depends_on = [ - google_project_service.cloudkms - ] -} - -resource "google_kms_key_ring_iam_policy" "gke_db" { - key_ring_id = google_kms_key_ring.gke_db.id - policy_data = data.google_iam_policy.gke_db.policy_data - - depends_on = [ - google_project_service.cloudkms - ] -} - -resource "google_kms_crypto_key" "gke_db" { - name = "gke-db-key" - key_ring = google_kms_key_ring.gke_db.id - - lifecycle { - prevent_destroy = true - } - - depends_on = [ - google_project_service.container - ] -} - -data "google_iam_policy" "gke_db" { - binding { - role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" - - members = [ - "serviceAccount:service-${data.google_project.project.number}@container-engine-robot.iam.gserviceaccount.com" - ] - } -} - #################### GKE ################################## -resource "google_project_service" "container" { - project = var.project - service = "container.googleapis.com" - disable_dependent_services = true -} - -resource "google_project_service" "containerregistry" { - project = var.project - service = "containerregistry.googleapis.com" - disable_dependent_services = true -} - -resource "google_service_account" "gke" { - project = var.project - account_id = "gke-service-account" - display_name = "GKE Service Account" -} - -# Allow GKE to access custom docker images in GCR -resource "google_storage_bucket_iam_member" "gke_gcr" { - bucket = "artifacts.${google_service_account.gke.project}.appspot.com" - role = "roles/storage.objectViewer" - member = "serviceAccount:${google_service_account.gke.email}" +module "gke" { + source = "../modules/gke" + project = var.project + region = var.region + private_network_id = module.networking.private_network_id + private_subnetwork_id = module.networking.private_subnetwork_id + service_cloudkms = google_project_service.cloudkms depends_on = [ - google_project_service.containerregistry - ] -} - -resource "google_container_cluster" "primary" { - project = var.project - name = "gke-cluster" - location = var.region - - remove_default_node_pool = true - initial_node_count = 1 - enable_shielded_nodes = true - min_master_version = "1.19.10-gke.1000" - - database_encryption { - state = "ENCRYPTED" - key_name = google_kms_crypto_key.gke_db.self_link - } - - maintenance_policy { - daily_maintenance_window { - start_time = "03:00" - } - } - - workload_identity_config { - identity_namespace = "${data.google_project.project.project_id}.svc.id.goog" - } - - release_channel { - channel = "STABLE" - } - - master_auth { - username = "" - password = "" - } - - ip_allocation_policy { - cluster_ipv4_cidr_block = "10.1.0.0/16" - services_ipv4_cidr_block = "10.2.0.0/20" - } - - lifecycle { - prevent_destroy = true - } - - depends_on = [ - google_project_service.container, - google_kms_key_ring_iam_policy.gke_db - ] -} - -resource "google_container_node_pool" "primary" { - project = google_container_cluster.primary.project - name_prefix = "node-pool" - location = var.region - cluster = google_container_cluster.primary.name - initial_node_count = 1 - - autoscaling { - min_node_count = 0 - max_node_count = 20 - } - - node_config { - preemptible = true - machine_type = "e2-medium" - - service_account = google_service_account.gke.email - oauth_scopes = [ - "https://www.googleapis.com/auth/cloud-platform" - ] - - metadata = { - disable-legacy-endpoints = "true" - } - - tags = [] - - shielded_instance_config { - enable_secure_boot = true - enable_integrity_monitoring = true - } - } - - lifecycle { - ignore_changes = [ - node_count - ] - } - - depends_on = [ - google_project_service.container + module.networking ] } output "gke_connect_command" { - description = "Command to run to connect to the kubernetes cluster." - value = "gcloud container clusters get-credentials ${google_container_cluster.primary.name} --region ${var.region} --project ${var.project}" + # description = "Command to run to connect to the kubernetes cluster." + value = module.gke.gke_connect_command } #################### SQL ################################## @@ -285,3 +127,8 @@ output "redis_port" { value = module.redis.redis_port } + + + + + diff --git a/terraform/modules/cloudsql/cloudsql.tf b/terraform/modules/cloudsql/cloudsql.tf index 44b1d3f..b9c9520 100644 --- a/terraform/modules/cloudsql/cloudsql.tf +++ b/terraform/modules/cloudsql/cloudsql.tf @@ -25,11 +25,14 @@ variable "private_network_id" { type = string } -resource "google_sql_database_instance" "instance" { - project = var.project - region = var.region - name = "my-database-instance" +resource "random_id" "cloudsql" { + byte_length = 4 +} +resource "google_sql_database_instance" "instance" { + project = var.project + region = var.region + name = "my-database-instance-${random_id.cloudsql.hex}" database_version = var.db_version settings { @@ -41,5 +44,6 @@ resource "google_sql_database_instance" "instance" { } } - deletion_protection = "true" + deletion_protection = "false" + # deletion_protection = "true" } diff --git a/terraform/modules/gke/gke.tf b/terraform/modules/gke/gke.tf new file mode 100644 index 0000000..7e5e9aa --- /dev/null +++ b/terraform/modules/gke/gke.tf @@ -0,0 +1,210 @@ +variable "project" { + description = "Project ID." + type = string +} + +variable "region" { + description = "Region." + type = string +} + +variable "service_cloudkms" { + description = "cloudkms service." +} + +variable "private_network_id" { + description = "Private network id." + type = string +} + +variable "private_subnetwork_id" { + description = "Private subnetwork id." + type = string +} + +output "gke_connect_command" { + description = "Command to run to connect to the kubernetes cluster." + value = "gcloud container clusters get-credentials ${google_container_cluster.primary.name} --region ${var.region} --project ${var.project}" +} + +data "google_project" "project" { + project_id = var.project +} + +#################### KMS ################################## + +resource "random_id" "gke_db" { + byte_length = 4 +} + +resource "google_kms_key_ring" "gke_db" { + project = var.project + name = "gke-db-${random_id.gke_db.hex}" + location = var.region + + lifecycle { + #prevent_destroy = true + } + + depends_on = [ + var.service_cloudkms + ] +} + +resource "google_kms_key_ring_iam_policy" "gke_db" { + key_ring_id = google_kms_key_ring.gke_db.id + policy_data = data.google_iam_policy.gke_db.policy_data + + depends_on = [ + var.service_cloudkms + ] +} + +resource "google_kms_crypto_key" "gke_db" { + name = "gke-db-key" + key_ring = google_kms_key_ring.gke_db.id + + lifecycle { + #prevent_destroy = true + } + + depends_on = [ + google_project_service.container + ] +} + +data "google_iam_policy" "gke_db" { + binding { + role = "roles/cloudkms.cryptoKeyEncrypterDecrypter" + + members = [ + "serviceAccount:service-${data.google_project.project.number}@container-engine-robot.iam.gserviceaccount.com" + ] + } +} + +#################### GKE ################################## + +resource "google_project_service" "container" { + project = var.project + service = "container.googleapis.com" + disable_dependent_services = true +} + +resource "google_project_service" "containerregistry" { + project = var.project + service = "containerregistry.googleapis.com" + disable_dependent_services = true +} + +resource "google_service_account" "gke" { + project = var.project + account_id = "gke-service-account" + display_name = "GKE Service Account" +} + +# Allow GKE to access custom docker images in GCR +resource "google_storage_bucket_iam_member" "gke_gcr" { + bucket = "artifacts.${google_service_account.gke.project}.appspot.com" + role = "roles/storage.objectViewer" + member = "serviceAccount:${google_service_account.gke.email}" + + depends_on = [ + google_project_service.containerregistry + ] +} + +resource "google_container_cluster" "primary" { + project = var.project + name = "gke-cluster" + location = var.region + network = var.private_network_id + subnetwork = var.private_subnetwork_id + + remove_default_node_pool = true + initial_node_count = 1 + enable_shielded_nodes = true + min_master_version = "1.19.10-gke.1000" + + database_encryption { + state = "ENCRYPTED" + key_name = google_kms_crypto_key.gke_db.self_link + } + + maintenance_policy { + daily_maintenance_window { + start_time = "03:00" + } + } + + workload_identity_config { + identity_namespace = "${data.google_project.project.project_id}.svc.id.goog" + } + + release_channel { + channel = "STABLE" + } + + master_auth { + username = "" + password = "" + } + + ip_allocation_policy { + cluster_ipv4_cidr_block = "/16" + services_ipv4_cidr_block = "/20" + } + + lifecycle { + #prevent_destroy = true + } + + depends_on = [ + google_project_service.container, + google_kms_key_ring_iam_policy.gke_db + ] +} + +resource "google_container_node_pool" "primary" { + project = google_container_cluster.primary.project + name_prefix = "node-pool" + location = var.region + cluster = google_container_cluster.primary.name + initial_node_count = 1 + + autoscaling { + min_node_count = 0 + max_node_count = 20 + } + + node_config { + preemptible = true + machine_type = "e2-medium" + + service_account = google_service_account.gke.email + oauth_scopes = [ + "https://www.googleapis.com/auth/cloud-platform" + ] + + metadata = { + disable-legacy-endpoints = "true" + } + + tags = [] + + shielded_instance_config { + enable_secure_boot = true + enable_integrity_monitoring = true + } + } + + lifecycle { + ignore_changes = [ + node_count + ] + } + + depends_on = [ + google_project_service.container + ] +} diff --git a/terraform/modules/networking/networking.tf b/terraform/modules/networking/networking.tf index 4a7b757..97aee17 100644 --- a/terraform/modules/networking/networking.tf +++ b/terraform/modules/networking/networking.tf @@ -3,11 +3,21 @@ variable "project" { type = string } +variable "region" { + description = "Region." + type = string +} + output "private_network_id" { description = "Private network id." value = google_compute_network.private_network.id } +output "private_subnetwork_id" { + description = "Private subnetwork id." + value = google_compute_subnetwork.subnet.id +} + resource "google_project_service" "servicenetworking" { project = var.project service = "servicenetworking.googleapis.com" @@ -23,6 +33,14 @@ resource "google_compute_network" "private_network" { ] } +resource "google_compute_subnetwork" "subnet" { + project = google_compute_network.private_network.project + name = "private-subnetwork" + ip_cidr_range = "10.100.0.0/16" + region = var.region + network = google_compute_network.private_network.id +} + resource "google_compute_global_address" "private_ip_address" { project = google_compute_network.private_network.project name = "private-ip-address"