diff --git a/.gitignore b/.gitignore index f38ab5f..b228701 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,4 @@ registry*.json* terraform.tfstate** *history*.txt *.tfvars +gcloud/tf/.env diff --git a/gcloud/tf/main.tf b/gcloud/tf/main.tf index bd8f6e6..cb38fb6 100644 --- a/gcloud/tf/main.tf +++ b/gcloud/tf/main.tf @@ -81,6 +81,63 @@ resource "google_compute_disk" "app_data_disk" { } +// load balancer .... + + +# resource "google_compute_health_check" "http_health_check" { +# name = "http-health-check" +# check_interval_sec = 5 +# timeout_sec = 5 +# healthy_threshold = 2 +# unhealthy_threshold = 2 + +# http_health_check { +# port = 80 +# } +# } + +resource "google_compute_http_health_check" "http_health_check" { + name = "http-health-check" + request_path = "/" + port = 80 + check_interval_sec = 5 + timeout_sec = 5 + healthy_threshold = 2 + unhealthy_threshold = 2 +} + + +# resource "google_compute_target_pool" "k3s_pool" { +# name = "k3s-target-pool" +# instances = [google_compute_instance.k3s.self_link] +# health_checks = [google_compute_health_check.http_health_check.self_link] +# } + +resource "google_compute_target_pool" "k3s_pool" { + name = "k3s-target-pool" + instances = [google_compute_instance.k3s.self_link] + health_checks = [google_compute_http_health_check.http_health_check.self_link] +} + +resource "google_compute_forwarding_rule" "http_forwarding_rule" { + name = "http-forwarding-rule" + target = google_compute_target_pool.k3s_pool.self_link + port_range = "80" + ip_protocol = "TCP" + load_balancing_scheme = "EXTERNAL" +} + +resource "google_compute_forwarding_rule" "https_forwarding_rule" { + name = "https-forwarding-rule" + target = google_compute_target_pool.k3s_pool.self_link + port_range = "443" + ip_protocol = "TCP" + load_balancing_scheme = "EXTERNAL" +} + + + +// ---------------------------------- @@ -96,3 +153,8 @@ output "k3s_vm_public_ip" { value = google_compute_instance.k3s.network_interface[0].access_config[0].nat_ip description = "Ephemeral public IP of the k3s VM" } + +output "load_balancer_ip" { + value = google_compute_forwarding_rule.http_forwarding_rule.ip_address + description = "External IP address of the load balancer (HTTP)" +} diff --git a/gcloud/tf/scripts/build-gcloud-k3s-pipeline.json b/gcloud/tf/scripts/build-gcloud-k3s-pipeline.json new file mode 100644 index 0000000..14da3f1 --- /dev/null +++ b/gcloud/tf/scripts/build-gcloud-k3s-pipeline.json @@ -0,0 +1,29 @@ +[ + { + "name": "run pre-flight checks", + "function": "RunCommand", + "params": [ + "./scripts/pre-flight-checks.sh" + ], + "retryCount": 0, + "shouldAbort": true + }, + { + "name": "list gcloud infrastructure", + "function": "RunCommand", + "params": [ + "./scripts/list_gloud_infra.sh" + ], + "retryCount": 0, + "shouldAbort": true + }, + { + "name": "run tofu", + "function": "RunCommand", + "params": [ + "./scripts/run_tofu.sh" + ], + "retryCount": 0, + "shouldAbort": true + } +] \ No newline at end of file diff --git a/gcloud/tf/scripts/install_traefik.sh b/gcloud/tf/scripts/install_traefik.sh new file mode 100644 index 0000000..da3d96e --- /dev/null +++ b/gcloud/tf/scripts/install_traefik.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +# Exit immediately if a command exits with a non-zero status. +set -e + +TMPFILE=$(mktemp /tmp/traefik-values-XXXXXX.yaml) + + +cat > "$TMPFILE" < /dev/null; then + echo "Traefik is already installed in the 'traefik' namespace. Upgrading..." + helm upgrade traefik traefik/traefik --namespace traefik -f "$TMPFILE" +else + echo "Installing Traefik..." + helm repo add traefik https://traefik.github.io/charts + helm repo update + # Using --create-namespace is good practice, though traefik will always exist. + helm install traefik traefik/traefik --namespace traefik --create-namespace -f "$TMPFILE" +fi + + + +# echo +# echo "To access the dashboard:" +# echo "kubectl port-forward -n traefik \$(kubectl get pods -n traefik -l \"app.kubernetes.io/name=traefik\" -o name) 9000:9000" +# echo "Then visit http://localhost:9000/dashboard/ in your browser" + diff --git a/gcloud/tf/scripts/k3s-vm-startup.sh b/gcloud/tf/scripts/k3s-vm-startup.sh index 665aed3..e99697f 100644 --- a/gcloud/tf/scripts/k3s-vm-startup.sh +++ b/gcloud/tf/scripts/k3s-vm-startup.sh @@ -1,10 +1,15 @@ #!/bin/bash +INFCTL_GIT_REPO="https://codeberg.org/headshed/infctl-cli.git" +INFCTL_GIT_REPO_BRANCH="feature/gcloud-k3s" +INFCTL_INSTALL_DIR="/opt/infctl-cli" + # ensure only run once if [[ -f /etc/startup_was_launched ]]; then exit 0; fi touch /etc/startup_was_launched + # Format the k3s disk if not already formatted # This creates an ext4 filesystem on the specified @@ -42,7 +47,7 @@ fi # apt install apt update -apt install -y ncdu htop +apt install -y ncdu htop git curl # helm install curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 @@ -65,9 +70,7 @@ rc=/home/user/.bashrc } >> $rc -# Install k3s and configure it to use the persistent disk for data storage -# curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--data-dir /mnt/disks/k3s" sh - - +# Install k3s k3s_version="v1.32.8+k3s1" curl -sfL https://get.k3s.io \ | \ @@ -77,6 +80,7 @@ curl -sfL https://get.k3s.io \ --disable servicelb +# Set up kubeconfig for the 'user' user mkdir -p /home/user/.kube chown user:user /home/user/.kube chmod 700 /home/user/.kube @@ -84,3 +88,15 @@ chmod 700 /home/user/.kube # for easier access cp /etc/rancher/k3s/k3s.yaml /home/user/.kube/config chown user:user /home/user/.kube/config + +# install infctl +curl -L https://codeberg.org/headshed/infctl-cli/raw/branch/main/install.sh | bash + +# clone infctl repo if not already present +if [[ ! -d "$INFCTL_INSTALL_DIR" ]]; then + mkdir -p "$INFCTL_INSTALL_DIR" + cd ${INFCTL_INSTALL_DIR} || "echo 'Failed to change directory to $INFCTL_INSTALL_DIR' ; exit 1" + git clone --branch "$INFCTL_GIT_REPO_BRANCH" "$INFCTL_GIT_REPO" || "echo 'Failed to clone $INFCTL_GIT_REPO' ; exit 1" + chown -R user:user "$INFCTL_INSTALL_DIR" +fi + diff --git a/gcloud/tf/scripts/list_gloud_infra.sh b/gcloud/tf/scripts/list_gloud_infra.sh new file mode 100755 index 0000000..f7a4f39 --- /dev/null +++ b/gcloud/tf/scripts/list_gloud_infra.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +. .env + +if [ -z "$PROJECT_NAME" ]; then + echo "โŒ PROJECT_NAME is not set. Please add PROJECT_NAME= to your .env file before running this script." + exit 1 +fi + +gcloud compute instances list --project="$PROJECT_NAME" && gcloud compute disks list --project="$PROJECT_NAME" && gcloud compute firewall-rules list --project="$PROJECT_NAME" && gcloud storage buckets list --project="$PROJECT_NAME" + +if [ $? -ne 0 ]; then + echo "โŒ gcloud is not authenticated, please run 'gcloud auth login' first" + echo + exit 1 +fi \ No newline at end of file diff --git a/gcloud/tf/scripts/pre-flight-checks.sh b/gcloud/tf/scripts/pre-flight-checks.sh new file mode 100755 index 0000000..cbcba78 --- /dev/null +++ b/gcloud/tf/scripts/pre-flight-checks.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +echo "๐Ÿงช checking we have tofu insatalled..." +if ! command -v tofu &> /dev/null +then + echo "โŒ tofu could not be found, please install it first" + echo + echo "see https://opentofu.org/docs/intro/install/standalone/" + echo + echo "and https://opentofu.org/docs/intro/install/ for more details" + echo + exit 1 +fi + +echo "โœ… tofu is installed,..." +echo +tofu version +echo + +echo "๐Ÿงช checking we have gcloud insatalled..." +if ! command -v gcloud &> /dev/null +then + echo "โŒ gcloud could not be found, please install it first" + echo + echo "see https://cloud.google.com/sdk/docs/install" + echo + exit 1 +fi + +echo "โœ… gcloud is installed,..." +echo +gcloud version +echo + +echo "๐Ÿงช checking we have kubectl insatalled..." +if ! command -v kubectl &> /dev/null +then + echo "โŒ kubectl could not be found, please install it first" + echo + echo "see https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/" + echo + exit 1 +fi + +echo "โœ… kubectl is installed,..." +echo +kubectl version --client +echo + + diff --git a/gcloud/tf/scripts/run_tofu.sh b/gcloud/tf/scripts/run_tofu.sh new file mode 100755 index 0000000..f88453d --- /dev/null +++ b/gcloud/tf/scripts/run_tofu.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +if [[ -d ".terraform" && -f ".terraform.lock.hcl" ]]; then + echo "โœ… Terraform already initialized" + # tofu init +else + echo "โš ๏ธ Initializing Terraform..." + tofu init +fi + +if [[ $? -ne 0 ]]; then + echo "โŒ tofu init failed, please check the output above" + exit 1 +fi + +# tofu apply with auto-approve to make it non-interactive +tofu apply -auto-approve + +if [[ $? -ne 0 ]]; then + echo "โŒ tofu apply failed, please check the output above" + exit 1 +fi \ No newline at end of file