diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 89c881d9f5888fe4d61cdea9292b4681cfab1e4f..a49162e14041df988b0b99cd69c3b72bb3102323 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,16 +1,16 @@ image: busybox:latest variables: - TF_ROOT: ${CI_PROJECT_DIR}/manifests/elastic - TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/manifests-elastic + TF_ROOT_ELASTIC: ${CI_PROJECT_DIR}/manifests/elastic + TF_ROOT_MAGENTO: ${CI_PROJECT_DIR}/manifests/magento cache: key: manifests-elastic paths: - - ${TF_ROOT}/.terraform + - ${TF_ROOT_ELASTIC}/.terraform # docs: https://docs.gitlab.com/ee/user/infrastructure/iac/terraform_state.html#get-started-using-gitlab-ci -elastic: +terraform-elastic: stage: deploy tags: - docker @@ -18,9 +18,10 @@ elastic: name: registry.gitlab.com/gitlab-org/terraform-images/stable:latest entrypoint: [""] variables: + TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/elastic TF_VAR_ec_apikey: $EC_API_KEY script: |- - cd $TF_ROOT + cd $TF_ROOT_ELASTIC gitlab-terraform init gitlab-terraform validate gitlab-terraform fmt -check @@ -28,30 +29,45 @@ elastic: # gitlab-terraform apply -auto-approve # gitlab-terraform destroy -auto-approve -gcloud: +terraform-magento: stage: deploy tags: - docker image: - name: google/cloud-sdk:slim + name: registry.gitlab.com/gitlab-org/terraform-images/stable:latest entrypoint: [""] variables: - GCP_PROJECT_ID: $GCP_PROJECT_ID + TF_ADDRESS: ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/terraform/state/magento + TF_VAR_ec_apikey: $EC_API_KEY + TF_VAR_project_id: $GCP_PROJECT_ID GCP_SA_GITLAB: $GCP_SA_GITLAB script: |- + cd $TF_ROOT_MAGENTO echo $GCP_SA_GITLAB > gcp-sa.json - gcloud auth activate-service-account --key-file gcp-sa.json - echo "Activate Service Account: OK" - gcloud config set project $GCP_PROJECT_ID - echo "Set Project: OK" - gcloud projects list + gitlab-terraform init + gitlab-terraform validate + gitlab-terraform fmt -check + gitlab-terraform plan +# gitlab-terraform apply -auto-approve +# gitlab-terraform destroy -auto-approve -link: +gcloud-psc: stage: deploy needs: - - elastic - - gcloud + - terraform-elastic + - terraform-magento tags: - docker + image: + name: google/cloud-sdk:slim + entrypoint: [""] + variables: + GCP_PROJECT_ID: $GCP_PROJECT_ID + GCP_SA_GITLAB: $GCP_SA_GITLAB script: |- - echo "Link" \ No newline at end of file + echo $GCP_SA_GITLAB > gcp-sa.json + gcloud auth activate-service-account --key-file gcp-sa.json + echo "Activate Service Account: OK" + gcloud config set project $GCP_PROJECT_ID + echo "Set Project: OK" + gcloud projects list \ No newline at end of file diff --git a/manifests/magento/main.tf b/manifests/magento/main.tf new file mode 100644 index 0000000000000000000000000000000000000000..38b5264a4257092c21c8c5ec8f66c1eff86c3e38 --- /dev/null +++ b/manifests/magento/main.tf @@ -0,0 +1,262 @@ +terraform { + backend "http" { + } + + required_providers { + google = { + source = "hashicorp/google" + version = "4.3.0" + } + } +} + +provider "google" { + credentials = file(gcp-sa.json) + project = var.project_id + region = var.region +} + +### Reserve Static IP +resource "google_compute_global_address" "static_ip" { + provider = google + project = var.project_id + name = "magento-frontend" +} + +### Create Network +resource "google_compute_network" "vpc_network" { + provider = google + project = var.project_id + name = var.vpc_network_name + auto_create_subnetworks = false + mtu = 1460 + routing_mode = "GLOBAL" +} + +### Create Subnetwork +resource "google_compute_subnetwork" "vpc_subnetwork" { + provider = google + project = var.project_id + name = var.vpc_subnetwork_name + ip_cidr_range = "192.168.100.0/24" + region = var.region + network = google_compute_network.vpc_network.id + secondary_ip_range { + range_name = "pods" + ip_cidr_range = "10.0.0.0/14" + } + secondary_ip_range { + range_name = "services" + ip_cidr_range = "10.4.0.0/19" + } + private_ip_google_access = true + + depends_on = [ + google_compute_network.vpc_network + ] +} + +### Create VPC network peering +resource "google_compute_global_address" "vpc_private_ip_address" { + provider = google + project = var.project_id + name = var.vpc_private_ip_address_name + purpose = "VPC_PEERING" + address_type = "INTERNAL" + prefix_length = 16 + network = google_compute_network.vpc_network.id +} + +resource "google_service_networking_connection" "vpc_private_vpc_connection" { + provider = google + network = google_compute_network.vpc_network.id + service = "servicenetworking.googleapis.com" + reserved_peering_ranges = [ + google_compute_global_address.vpc_private_ip_address.name + ] +} + +### Create firewall rules +resource "google_compute_firewall" "fw_http" { + provider = google + project = var.project_id + name = var.fw_http_name + network = google_compute_network.vpc_network.name + allow { + protocol = "tcp" + ports = ["80"] + } + target_tags = ["http-server"] + source_ranges = ["0.0.0.0/0"] + disabled = false +} + +resource "google_compute_firewall" "fw_https" { + provider = google + project = var.project_id + name = var.fw_https_name + network = google_compute_network.vpc_network.name + allow { + protocol = "tcp" + ports = ["443"] + } + target_tags = ["https-server"] + source_ranges = ["0.0.0.0/0"] + disabled = false +} + +resource "google_compute_firewall" "allow_from_iap_to_instances" { + provider = google + project = var.project_id + name = var.fw_ssh_name + network = google_compute_network.vpc_network.name + allow { + protocol = "tcp" + ports = ["22"] + } + source_ranges = ["35.235.240.0/20"] +} + +### Create Cloud NAT +resource "google_compute_router" "router" { + provider = google + project = var.project_id + name = var.router_name + region = var.region + network = google_compute_network.vpc_network.id + bgp { + asn = 64514 + } +} + +resource "google_compute_router_nat" "cloud_nat" { + provider = google + project = var.project_id + name = var.cloud_nat_name + region = var.region + router = google_compute_router.router.name + nat_ip_allocate_option = "AUTO_ONLY" + source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES" + + log_config { + enable = false + filter = "ERRORS_ONLY" + } + + min_ports_per_vm = 64 +} + +### Create Kubernetes Cluster +resource "google_container_cluster" "cluster" { + provider = google + project = var.project_id + name = var.cluster_name + location = var.region + remove_default_node_pool = true + initial_node_count = 1 + logging_service = "logging.googleapis.com/kubernetes" + default_max_pods_per_node = 20 + networking_mode = "VPC_NATIVE" + network = google_compute_network.vpc_network.id + subnetwork = google_compute_subnetwork.vpc_subnetwork.id + enable_shielded_nodes = true + + private_cluster_config { + enable_private_endpoint = false + enable_private_nodes = true + master_ipv4_cidr_block = "172.16.0.0/28" + } + + default_snat_status { + disabled = false + } + + ip_allocation_policy { + cluster_secondary_range_name = "pods" + services_secondary_range_name = "services" + } + + workload_identity_config { + identity_namespace = "${data.google_project.project.project_id}.svc.id.goog" + } + + depends_on = [ + google_compute_network.vpc_network, + google_compute_subnetwork.vpc_subnetwork_1 + ] +} + +### Create Kubernetes Node Pool +resource "google_container_node_pool" "node_pool" { + provider = google + project = var.project_id + name = var.node_pool_name + location = var.region + cluster = google_container_cluster.cluster.name + node_count = 1 + + node_config { + preemptible = true + machine_type = "e2-standard-4" + disk_size_gb = "100" + disk_type = "pd-ssd" + image_type = "cos" + + oauth_scopes = [ + "https://www.googleapis.com/auth/cloud-platform" + ] + + labels = { + disktype = "ssd" + cputype = "e2" + preemptible = "true" + } + } +} + +### Create Cloud SQL +resource "google_sql_database_instance" "cloud_sql" { + provider = google + project = var.project_id + name = var.cloud_sql_name + region = var.region + database_version = "MYSQL_8_0" + deletion_protection = true + + settings { + tier = "db-custom-2-3840" # 2vCPU - 3.75 Go + availability_type = "REGIONAL" + + backup_configuration { + enabled = true + binary_log_enabled = true + location = "eu" + } + + ip_configuration { + ipv4_enabled = false + private_network = google_compute_network.vpc_network.id + } + + location_preference { + zone = "europe-west1-b" + } + + maintenance_window { + day = 1 + hour = 0 + } + } +} + +### Create Redis +resource "google_redis_instance" "memory_store" { + provider = google + project = var.project_id + name = var.memory_store_name + region = var.region + memory_size_gb = 1 + authorized_network = google_compute_network.vpc_network.id + connect_mode = "PRIVATE_SERVICE_ACCESS" + redis_version = "REDIS_6_X" +} diff --git a/manifests/magento/outputs.tf b/manifests/magento/outputs.tf new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/manifests/magento/variables.tf b/manifests/magento/variables.tf new file mode 100644 index 0000000000000000000000000000000000000000..de77fc7609fd328b31b37ee2b4d5b9d09e63ffb5 --- /dev/null +++ b/manifests/magento/variables.tf @@ -0,0 +1,68 @@ +variable "project_id" { + type = string +} + +variable "region" { + type = string + default = "europe-west1" +} + +### Network & Subnetwork +variable "vpc_network_name" { + type = string + default = "vpc-magento" +} +variable "vpc_subnetwork_name" { + type = string + default = "vpc-sb-magento" +} +variable "vpc_private_ip_address_name" { + type = string + default = "vpc-private-ip-magento" +} + +### Firewall +variable "fw_http_name" { + type = string + default = "fw-vpc-allow-http" +} +variable "fw_https_name" { + type = string + default = "fw-vpc-allow-https" +} +variable "fw_ssh_name" { + type = string + default = "fw-vpc-allow-ssh-from-iap" +} + +### Router & Cloud NAT +variable "router_name" { + type = string + default = "router-vpc-name" +} +variable "cloud_nat_name" { + type = string + default = "cloud-nat-vpc-name" +} + +### Kubernetes Cluster & Node Pool +variable "cluster_name" { + type = string + default = "gke-magento" +} +variable "node_pool_name" { + type = string + default = "gke-preemptible-nodes-magento" +} + +### Cloud SQL +variable "cloud_sql_name" { + type = string + default = "cloudsql-magento" +} + +### Memory Store +variable "memory_store_name" { + type = string + default = "cloudsql-magento" +} \ No newline at end of file