Complete restructure

This commit is contained in:
gregory hendrickson
2023-03-15 13:17:41 -07:00
parent 2081f04c24
commit cf7e3c2271
22 changed files with 369 additions and 521 deletions

57
main.tf
View File

@@ -1,46 +1,37 @@
# Module Configuration
module "backend" {
source = "./modules/backend"
instance_name = var.backend_instance_name
machine_type = var.backend_machine_type
zone = var.zone
network_name = module.network.network_name
subnet_name = module.network.backend_subnet_name
tags = ["backend"]
image_family = "debian-11"
image_project = "debian-cloud"
module "instances" {
source = "./modules/instances"
}
module "frontend" {
source = "./modules/frontend"
instance_name = var.frontend_instance_name
machine_type = var.frontend_machine_type
zone = var.zone
network_name = module.network.network_name
subnet_name = module.network.frontend_subnet_name
tags = ["frontend"]
module "instance-group" {
source = "./modules/instance-group"
}
module "network" {
source = "./modules/network"
project_id = var.project_id
region = var.region
network_name = var.network_name
subnet_cidrs = var.subnet_cidrs
nat_gateway_count = var.nat_gateway_count
firewall_name = var.firewall_name
}
module "storage" {
source = "./modules/storage"
}
module "autoscale" {
source = "./modules/autoscale"
}
module "firewall" {
source = "./modules/firewall"
project_id = var.project_id
network_name = module.network.network_name
firewall_name = var.firewall_name
allowed_ports = var.allowed_ports
target_tags = ["backend"]
source = "./modules/network/firewall"
}
module "healthchecks" {
source = "./modules/network/healthchecks"
}
module "loadbalancer" {
source = "./modules/network/loadbalancer"
}

15
modules/autoscale/main.tf Normal file
View File

@@ -0,0 +1,15 @@
resource "google_compute_region_autoscaler" "fancy_fe_autoscaler" {
name = "fancy-fe-autoscaler"
target = google_compute_instance_group_manager.fancy_fe_mig.self_link
cooldown_period_sec = 60
load_balancing_utilization_target = 0.6
max_replicas = 2
}
resource "google_compute_region_autoscaler" "fancy_be_autoscaler" {
name = "fancy-be-autoscaler"
target = google_compute_instance_group_manager.fancy_be_mig.self_link
cooldown_period_sec = 60
load_balancing_utilization_target = 0.6
max_replicas = 2
}

View File

@@ -1,30 +0,0 @@
provider "google" {
project = var.project_id
region = var.region
}
data "google_compute_image" "debian" {
family = "debian-10"
project = "debian-cloud"
}
resource "google_compute_instance" "backend" {
name = "backend"
machine_type = "e2-small"
zone = var.region
boot_disk {
initialize_params {
image = data.google_compute_image.debian.self_link
}
}
network_interface {
subnetwork = module.network.subnet_name
access_config {
// Include this section to give the VM an external ip address
}
}
metadata_startup_script = module.network.startup_script
}

View File

@@ -1,19 +0,0 @@
variable "project_id" {
type = string
description = "The ID of the Google Cloud project to use for resources."
}
variable "region" {
type = string
description = "The region to create resources in."
}
variable "sa_email" {
type = string
description = "The email address of the service account to associate with the instance."
}
variable "image_name" {
type = string
description = "The name of the image to use for the instance boot disk."
}

View File

@@ -1,11 +0,0 @@
resource "google_compute_firewall" "default" {
name = var.firewall_name
network = var.network_name
allow {
protocol = "tcp"
ports = var.allowed_ports
}
source_ranges = var.source_ranges
}

View File

@@ -1,21 +0,0 @@
variable "firewall_name" {
description = "The name of the firewall"
type = string
}
variable "network_name" {
description = "The name of the network to apply the firewall rule to"
type = string
}
variable "allowed_ports" {
description = "The list of ports that are allowed by the firewall"
type = list(number)
default = [80, 443]
}
variable "source_ranges" {
description = "The list of source IP ranges that are allowed by the firewall"
type = list(string)
default = ["0.0.0.0/0"]
}

View File

@@ -1,31 +0,0 @@
provider "google" {
project = var.project_id
region = var.region
}
resource "google_compute_instance" "frontend" {
name = "frontend"
machine_type = "e2-micro"
zone = var.zone
boot_disk {
initialize_params {
image = "ubuntu-os-cloud/ubuntu-2004-lts"
}
}
network_interface {
network = var.network_name
access_config {
// Allocate a one-to-one NAT IP to the instance
}
}
metadata_startup_script = file(var.startup_script_path)
tags = ["http-server"]
}
output "frontend_ip" {
value = google_compute_instance.frontend.network_interface.0.access_config.0.nat_ip
}

View File

@@ -1,33 +0,0 @@
variable "project_id" {
description = "The ID of the Google Cloud project where resources will be created"
}
variable "region" {
description = "The region in which to create the resources"
}
variable "zone" {
description = "The zone in which to create the resources"
}
variable "instance_name" {
description = "The name to assign to the Compute Engine instance"
}
variable "machine_type" {
description = "The machine type of the Compute Engine instance"
default = "f1-micro"
}
variable "image_name" {
description = "The name of the image to use for the Compute Engine instance boot disk"
default = "ubuntu-os-cloud/ubuntu-2004-lts"
}
variable "network_name" {
description = "The name of the network to which the Compute Engine instance will be attached"
}
variable "startup_script_path" {
description = "The local path to the startup script to be run on the Compute Engine instance"
}

View File

@@ -0,0 +1,61 @@
resource "google_compute_instance_group_manager" "fancy_fe_mig" {
name = "fancy-fe-mig"
base_instance_name = "fancy-fe"
instance_template = google_compute_instance_template.fancy_fe_template.self_link
target_size = 2
target_pools = [
google_compute_target_pool.fancy_target_pool.self_link
]
zone = "us-central1-a"
update_policy {
type = "PROACTIVE"
min_instance_restart_time_sec = 300
}
named_port {
name = "frontend"
port = "8080"
}
depends_on = [
google_compute_http_health_check.fancy_fe_hc,
google_compute_backend_service.fancy_frontend_service
]
}
resource "google_compute_instance_group_manager" "fancy_be_mig" {
name = "fancy-be-mig"
base_instance_name = "fancy-be"
instance_template = google_compute_instance_template.fancy_be_template.self_link
target_size = 2
target_pools = [
google_compute_target_pool.fancy_target_pool.self_link
]
zone = "us-central1-a"
update_policy {
type = "PROACTIVE"
min_instance_restart_time_sec = 300
}
named_port {
name = "orders"
port = "8081"
}
named_port {
name = "products"
port = "8082"
}
depends_on = [
google_compute_http_health_check.fancy_be_hc,
google_compute_backend_service.fancy_backend_service
]
}

42
modules/instances/main.tf Normal file
View File

@@ -0,0 +1,42 @@
#BE Instance
resource "google_compute_instance" "backend" {
name = "backend"
machine_type = "n1-standard-1"
tags = ["backend"]
metadata = {
startup-script-url = "gs://${google_storage_bucket.fancy_store.name}/startup-script.sh"
}
boot_disk {
initialize_params {
image = "debian-cloud/debian-10"
}
}
network_interface {
network = "default"
}
}
#FE Instance
resource "google_compute_instance" "frontend" {
name = "frontend"
machine_type = "n1-standard-1"
tags = ["frontend"]
metadata = {
startup-script-url = "gs://${google_storage_bucket.fancy_store.name}/startup-script.sh"
}
boot_disk {
initialize_params {
image = "debian-cloud/debian-10"
}
}
network_interface {
network = "default"
}
}

View File

@@ -0,0 +1,21 @@
## Firewall Rules to allow Front-End and Back-End
resource "google_compute_firewall" "fw_fe" {
name = "fw-fe"
network = "default"
allow {
protocol = "tcp"
ports = ["8080"]
}
target_tags = ["frontend"]
}
resource "google_compute_firewall" "fw_be" {
name = "fw-be"
network = "default"
allow {
protocol = "tcp"
ports = ["8081-8082"]
}
target_tags = ["backend"]
}

View File

@@ -0,0 +1,40 @@
#Create HealthChecks
resource "google_compute_http_health_check" "fancy_fe_hc" {
name = "fancy-fe-hc"
port = "8080"
request_path = "/"
check_interval_sec = 30
timeout_sec = 10
healthy_threshold = 1
unhealthy_threshold = 3
}
resource "google_compute_http_health_check" "fancy_be_hc" {
name = "fancy-be-hc"
port = "8081"
request_path = "/api/orders"
check_interval_sec = 30
timeout_sec = 10
healthy_threshold = 1
unhealthy_threshold = 3
}
resource "google_compute_http_health_check" "fancy_fe_frontend_hc" {
name = "fancy-fe-frontend-hc"
request_path = "/"
port = 8080
}
resource "google_compute_http_health_check" "fancy_be_orders_hc" {
name = "fancy-be-orders-hc"
request_path = "/api/orders"
port = 8081
}
resource "google_compute_http_health_check" "fancy_be_products_hc" {
name = "fancy-be-products-hc"
request_path = "/api/products"
port = 8082
}

View File

@@ -0,0 +1,98 @@
resource "google_compute_backend_service" "fancy_fe_frontend" {
name = "fancy-fe-frontend"
port_name = "frontend"
protocol = "HTTP"
load_balancing_scheme = "INTERNAL_SELF_MANAGED"
backend {
group = google_compute_instance_group_manager.fancy_fe_mig.self_link
}
health_checks = [
google_compute_http_health_check.fancy_fe_frontend_hc.self_link
]
}
resource "google_compute_backend_service" "fancy_be_orders" {
name = "fancy-be-orders"
port_name = "orders"
protocol = "HTTP"
load_balancing_scheme = "INTERNAL_SELF_MANAGED"
backend {
group = google_compute_instance_group_manager.fancy_be_mig.self_link
}
health_checks = [
google_compute_http_health_check.fancy_be_orders_hc.self_link
]
}
resource "google_compute_backend_service" "fancy_be_products" {
name = "fancy-be-products"
port_name = "products"
protocol = "HTTP"
load_balancing_scheme = "INTERNAL_SELF_MANAGED"
backend {
group = google_compute_instance_group_manager.fancy_be_mig.self_link
}
health_checks = [
google_compute_http_health_check.fancy_be_products_hc.self_link
]
}
resource "google_compute_url_map" "fancy_map" {
name = "fancy-map"
default_service = google_compute_backend_service.fancy_fe_frontend.self_link
}
resource "google_compute_path_matcher" "fancy_path_matcher" {
name = "orders"
default_service = google_compute_backend_service.fancy_fe_frontend.self_link
path_rule {
paths = ["/api/orders"]
service = google_compute_backend_service.fancy_be_orders.self_link
}
path_rule {
paths = ["/api/products"]
service = google_compute_backend_service.fancy_be_products.self_link
}
url_map = google_compute_url_map.fancy_map.self_link
}
resource "google_compute_target_http_proxy" "fancy_proxy" {
name = "fancy-proxy"
url_map = google_compute_url_map.fancy_map.self_link
}
resource "google_compute_global_forwarding_rule" "fancy_http_rule" {
name = "fancy-http-rule"
target = google_compute_target_http_proxy.fancy_proxy.self_link
port_range = "80"
}
# ENABLE CDN
resource "google_compute_backend_service" "fancy_fe_frontend" {
name = "fancy-fe-frontend"
port_name = "frontend"
protocol = "HTTP"
load_balancing_scheme = "INTERNAL_SELF_MANAGED"
backend {
group = google_compute_instance_group_manager.fancy_fe_mig.self_link
}
health_checks = [
google_compute_http_health_check.fancy_fe_frontend_hc.self_link
]
enable_cdn = true
}

View File

@@ -1,41 +1,59 @@
# Define VPC
resource "google_compute_network" "vpc_network" {
name = var.vpc_name
project = var.project_id
auto_create_subnetworks = false
resource "google_compute_backend_service" "fancy_backend_service" {
name = "fancy-backend-service"
protocol = "HTTP"
backend {
group = google_compute_instance_group_manager.fancy_be_mig.self_link
}
health_checks = [
google_compute_http_health_check.fancy_be_hc.self_link
]
port_name = "orders"
named_port {
name = "orders"
port = "8081"
}
named_port {
name = "products"
port = "8082"
}
}
# Define subnetwork
resource "google_compute_subnetwork" "vpc_subnet" {
name = var.subnet_name
ip_cidr_range = var.subnet_cidr_range
region = var.region
network = google_compute_network.vpc_network.self_link
resource "google_compute_backend_service" "fancy_frontend_service" {
name = "fancy-frontend-service"
protocol = "HTTP"
backend {
group = google_compute_instance_group_manager.fancy_fe_mig.self_link
}
health_checks = [
google_compute_http_health_check.fancy_fe_hc.self_link
]
port_name = "frontend"
named_port {
name = "frontend"
port = "8080"
}
}
# Define firewall rule for frontend instances
resource "google_compute_firewall" "frontend_firewall" {
name = "allow-frontend"
network = google_compute_network.vpc_network.self_link
resource "google_compute_firewall" "allow_health_check" {
name = "allow-health-check"
network = "default"
allow {
protocol = "tcp"
ports = ["8080"]
ports = ["8080-8081"]
}
target_tags = ["frontend"]
}
# Define firewall rule for backend instances
resource "google_compute_firewall" "backend_firewall" {
name = "allow-backend"
network = google_compute_network.vpc_network.self_link
allow {
protocol = "tcp"
ports = ["8081-8082"]
}
target_tags = ["backend"]
}
source_ranges = [
"130.211.0.0/22",
"35.191.0.0/16"
]
}

View File

@@ -1,71 +0,0 @@
provider "google" {
project = var.project_id
region = var.region
}
resource "google_compute_network" "vpc_network" {
name = var.vpc_name
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "subnet" {
name = var.subnet_name
network = google_compute_network.vpc_network.self_link
ip_cidr_range = var.subnet_cidr_range
}
resource "google_compute_router" "router" {
name = var.router_name
region = var.region
network = google_compute_network.vpc_network.self_link
bgp {
asn = 64514
}
dynamic "interface" {
for_each = var.router_interfaces
content {
name = interface.value.name
ip_address = interface.value.ip_address
management = interface.value.management
management_config = interface.value.management_config
}
}
}
resource "google_compute_address" "nat_ip" {
name = var.nat_ip_name
region = var.region
address_type = "EXTERNAL"
}
resource "google_compute_instance" "nat_instance" {
name = var.nat_instance_name
machine_type = var.machine_type
zone = var.zone
tags = ["nat"]
boot_disk {
initialize_params {
image = var.image_name
}
}
network_interface {
network = google_compute_network.vpc_network.self_link
access_config {
nat_ip = google_compute_address.nat_ip.address
}
}
}
resource "google_compute_route" "nat_route" {
name = var.nat_route_name
destination_range = var.destination_range
next_hop_instance = google_compute_instance.nat_instance.self_link
next_hop_instance_zone = var.zone
tags = ["nat"]
}
output "nat_ip_address" {
value = google_compute_address.nat_ip.address
}

View File

@@ -1,96 +0,0 @@
# Variables for network module
variable "region" {
description = "The region where the network will be created"
type = string
}
variable "project_id" {
description = "The project id where the network will be created"
type = string
}
variable "network_name" {
description = "The name of the VPC network"
type = string
}
variable "subnet_name" {
description = "The name of the subnet within the VPC network"
type = string
}
variable "subnet_ip_cidr_range" {
description = "The IP CIDR range of the subnet within the VPC network"
type = string
}
# Variables for backend module
variable "bucket_name" {
description = "The name of the GCS bucket"
type = string
}
# Variables for frontend module
variable "instance_name" {
description = "The name of the instance"
type = string
}
variable "instance_zone" {
description = "The zone where the instance will be created"
type = string
}
variable "machine_type" {
description = "The machine type of the instance"
type = string
}
variable "instance_startup_script" {
description = "The startup script for the instance"
type = string
}
variable "firewall_allow_80" {
description = "Whether or not to allow incoming traffic on port 80"
type = bool
}
# Variables for nat_gateway module
variable "nat_gateway_name" {
description = "The name of the NAT gateway instance"
type = string
}
variable "nat_gateway_zone" {
description = "The zone where the NAT gateway instance will be created"
type = string
}
variable "nat_gateway_machine_type" {
description = "The machine type of the NAT gateway instance"
type = string
}
variable "nat_gateway_startup_script" {
description = "The startup script for the NAT gateway instance"
type = string
}
variable "nat_subnet_name" {
description = "The name of the subnet in which to deploy the NAT gateway"
type = string
}
# Variables for firewall module
variable "allowed_ingress_ports" {
description = "The list of ingress ports allowed to access the instance"
type = list(number)
default = [22, 80]
}
variable "allowed_egress_ports" {
description = "The list of egress ports allowed to leave the instance"
type = list(number)
default = []
}

View File

@@ -1,19 +0,0 @@
output "vpc_network_name" {
value = google_compute_network.vpc_network.name
}
output "subnet_name" {
value = google_compute_subnetwork.vpc_subnet.name
}
output "subnet_cidr_range" {
value = google_compute_subnetwork.vpc_subnet.ip_cidr_range
}
output "frontend_firewall_name" {
value = google_compute_firewall.frontend_firewall.name
}
output "backend_firewall_name" {
value = google_compute_firewall.backend_firewall.name
}

View File

@@ -1,23 +0,0 @@
variable "project_id" {
description = "The ID of the Google Cloud project to deploy resources to."
}
variable "region" {
description = "The region where the resources will be created."
default = "us-central1"
}
variable "vpc_name" {
description = "The name of the VPC network to be created."
default = "fancy-store-vpc"
}
variable "subnet_name" {
description = "The name of the subnet to be created."
default = "fancy-store-subnet"
}
variable "subnet_cidr_range" {
description = "The CIDR range of the subnet to be created."
default = "10.0.0.0/24"
}

12
modules/storage/main.tf Normal file
View File

@@ -0,0 +1,12 @@
resource "google_storage_bucket" "fancy_store" {
name = "fancy-store-${var.project_id}"
location = "US"
force_destroy = true
}
resource "google_storage_bucket_object" "startup_script" {
name = "startup-script.sh"
bucket = google_storage_bucket.fancy_store.name
source = "${path.module}/startup-script.sh"
content_type = "text/plain"
}

View File

@@ -1,46 +1,29 @@
#!/bin/bash
# Install logging monitor. The monitor will automatically pick up logs sent to
# syslog.
curl -s "https://storage.googleapis.com/signals-agents/logging/google-fluentd-install.sh" | bash
service google-fluentd restart &
# Install dependencies from apt
apt-get update
apt-get install -yq ca-certificates git build-essential supervisor psmisc
# Install nodejs
mkdir /opt/nodejs
curl https://nodejs.org/dist/v16.14.0/node-v16.14.0-linux-x64.tar.gz | tar xvzf - -C /opt/nodejs --strip-components=1
ln -s /opt/nodejs/bin/node /usr/bin/node
ln -s /opt/nodejs/bin/npm /usr/bin/npm
# Get the application source code from the Google Cloud Storage bucket.
mkdir /fancy-store
gsutil -m cp -r gs://fancy-store-${var.project_id}/monolith-to-microservices/microservices/* /fancy-store/
# Install app dependencies.
cd /fancy-store/
npm install
# Create a nodeapp user. The application will run as this user.
useradd -m -d /home/nodeapp nodeapp
chown -R nodeapp:nodeapp /fancy-store
chown -R nodeapp:nodeapp /opt/app
# Configure supervisor to run the node app.
cat >/etc/supervisor/conf.d/node-app.conf << EOF
[program:orders]
directory=/fancy-store/orders
command=npm start
autostart=true
autorestart=true
user=nodeapp
environment=HOME="/home/nodeapp",USER="nodeapp",NODE_ENV="production"
stdout_logfile=syslog
stderr_logfile=syslog
[program:products]
directory=/fancy-store/products
[program:nodeapp]
directory=/fancy-store
command=npm start
autostart=true
autorestart=true
@@ -49,6 +32,5 @@ environment=HOME="/home/nodeapp",USER="nodeapp",NODE_ENV="production"
stdout_logfile=syslog
stderr_logfile=syslog
EOF
supervisorctl reread
supervisorctl update

View File

@@ -1,69 +0,0 @@
resource "google_compute_instance" "backend" {
name = "backend"
machine_type = "n1-standard-1"
zone = var.zone
boot_disk {
initialize_params {
image = var.image
}
}
network_interface {
network = module.network.network_name
access_config {
// Ephemeral IP
}
}
metadata_startup_script = var.startup_script
tags = ["backend"]
}
resource "google_compute_instance" "frontend" {
name = "frontend"
machine_type = "n1-standard-1"
zone = var.zone
boot_disk {
initialize_params {
image = var.image
}
}
network_interface {
network = module.network.network_name
access_config {
// Ephemeral IP
}
}
metadata_startup_script = var.startup_script
tags = ["frontend"]
}
resource "google_compute_firewall" "fw_fe" {
name = "fw-fe"
network = module.network.network_name
allow {
protocol = "tcp"
ports = ["8080"]
}
source_tags = ["frontend"]
}
resource "google_compute_firewall" "fw_be" {
name = "fw-be"
network = module.network.network_name
allow {
protocol = "tcp"
ports = ["8081-8082"]
}
source_tags = ["backend"]
}

View File

@@ -8,16 +8,7 @@ variable "region" {
description = "The region to deploy resources into"
}
variable "network_cidr" {
variable "zone" {
type = string
description = "The CIDR block for the VPC network"
}
variable "network_name" {}
variable "subnet_name" {}
variable "firewall_name" {}
description = "The zone in which resource to be deployed"
}