From 35773c6efe87dba127f635a3e6bbe0954bbb7512 Mon Sep 17 00:00:00 2001 From: Javier Hinojosa <48923796+javierhinojosa@users.noreply.github.com> Date: Sun, 9 Nov 2025 11:17:13 -0500 Subject: [PATCH] added infra --- infra/gcp/.gitignore | 27 +++ infra/gcp/.terraform.lock.hcl | 22 ++ infra/gcp/CICD_PLAN.md | 127 +++++++++++ infra/gcp/README.md | 62 ++++++ infra/gcp/REVIEW.md | 385 ++++++++++++++++++++++++++++++++++ infra/gcp/backend.tf | 6 + infra/gcp/main.tf | 174 +++++++++++++++ infra/gcp/outputs.tf | 24 +++ infra/gcp/variables.tf | 28 +++ 9 files changed, 855 insertions(+) create mode 100644 infra/gcp/.gitignore create mode 100644 infra/gcp/.terraform.lock.hcl create mode 100644 infra/gcp/CICD_PLAN.md create mode 100644 infra/gcp/README.md create mode 100644 infra/gcp/REVIEW.md create mode 100644 infra/gcp/backend.tf create mode 100644 infra/gcp/main.tf create mode 100644 infra/gcp/outputs.tf create mode 100644 infra/gcp/variables.tf diff --git a/infra/gcp/.gitignore b/infra/gcp/.gitignore new file mode 100644 index 0000000..6ad49ee --- /dev/null +++ b/infra/gcp/.gitignore @@ -0,0 +1,27 @@ +# Local .terraform directories +.terraform/ + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# Ignore override files as they are usually used for local testing and overriding +# values locally +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include the .terraform.lock.hcl file to ensure that the same provider versions +# are used across all environments. +# .terraform.lock.hcl diff --git a/infra/gcp/.terraform.lock.hcl b/infra/gcp/.terraform.lock.hcl new file mode 100644 index 0000000..3acc57c --- /dev/null +++ b/infra/gcp/.terraform.lock.hcl @@ -0,0 +1,22 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/google" { + version = "5.45.2" + constraints = "~> 5.0" + hashes = [ + "h1:iy2Q9VcnMu4z/bH3v/NmI/nEpgYY7bXgJmT/hVTAUS4=", + "zh:0d09c8f20b556305192cdbe0efa6d333ceebba963a8ba91f9f1714b5a20c4b7a", + "zh:117143fc91be407874568df416b938a6896f94cb873f26bba279cedab646a804", + "zh:16ccf77d18dd2c5ef9c0625f9cf546ebdf3213c0a452f432204c69feed55081e", + "zh:3e555cf22a570a4bd247964671f421ed7517970cd9765ceb46f335edc2c6f392", + "zh:688bd5b05a75124da7ae6e885b2b92bd29f4261808b2b78bd5f51f525c1052ca", + "zh:6db3ef37a05010d82900bfffb3261c59a0c247e0692049cb3eb8c2ef16c9d7bf", + "zh:70316fde75f6a15d72749f66d994ccbdde5f5ed4311b6d06b99850f698c9bbf9", + "zh:84b8e583771a4f2bd514e519d98ed7fd28dce5efe0634e973170e1cfb5556fb4", + "zh:9d4b8ef0a9b6677935c604d94495042e68ff5489932cfd1ec41052e094a279d3", + "zh:a2089dd9bd825c107b148dd12d6b286f71aa37dfd4ca9c35157f2dcba7bc19d8", + "zh:f03d795c0fd9721e59839255ee7ba7414173017dc530b4ce566daf3802a0d6dd", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/infra/gcp/CICD_PLAN.md b/infra/gcp/CICD_PLAN.md new file mode 100644 index 0000000..8fdb256 --- /dev/null +++ b/infra/gcp/CICD_PLAN.md @@ -0,0 +1,127 @@ +# CI/CD Plan for GCP Terraform with Gitea + +This document outlines a CI/CD plan for the GCP Terraform infrastructure using Gitea Actions. + +## 1. Overview + +The goal is to automate the process of validating, planning, and applying Terraform changes. This will ensure that all infrastructure changes are peer-reviewed, tested, and applied in a consistent and predictable manner. + +We will use Gitea Actions, the built-in CI/CD solution in Gitea, to orchestrate the workflows. + +## 2. Branching Strategy + +We will use a simple GitFlow-like model: +- **`main` branch:** Represents the production infrastructure. Direct pushes will be disallowed. Changes are merged via pull requests. +- **Feature branches:** All changes are developed on feature branches (e.g., `feat/add-monitoring`, `fix/firewall-rules`). + +## 3. Secrets Management + +GCP credentials must be handled securely. We will use Gitea's encrypted secrets to store the GCP service account key. + +1. **Create a GCP Service Account:** Create a dedicated service account in GCP with the necessary permissions to manage the infrastructure. +2. **Generate a JSON Key:** Generate a JSON key for this service account. +3. **Store the Key in Gitea:** Store the contents of the JSON key file as a repository secret in Gitea with the name `GCP_SA_KEY`. + +## 4. Gitea Actions Workflow + +We will create a single workflow file at `.gitea/workflows/terraform.yml`. This workflow will have two main jobs, triggered by different events. + +### Workflow Triggers + +- **On `pull_request` to `main`:** The workflow will run `terraform init`, `terraform validate`, and `terraform plan`. The output of the plan will be added as a comment to the pull request for review. +- **On `push` to `main`:** After a pull request is merged, the workflow will run `terraform init` and `terraform apply` to deploy the changes to production. This step will require manual approval within Gitea Actions. + +### Workflow Definition (`.gitea/workflows/terraform.yml`) + +```yaml +name: Terraform CI/CD + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + terraform-plan: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v2 + with: + terraform_version: 1.8.0 + + - name: Authenticate to GCP + uses: google-github-actions/auth@v1 + with: + credentials_json: ${{ secrets.GCP_SA_KEY }} + + - name: Terraform Init + run: terraform init + + - name a: Terraform Validate + run: terraform validate + + - name: Terraform Plan + id: plan + run: terraform plan -no-color -out=tfplan + + - name: Add Plan to PR + uses: actions/github-script@v6 + with: + script: | + const output = `#### Terraform Plan 📖\n${{ steps.plan.outputs.stdout }}\n` + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: output + }) + + terraform-apply: + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + environment: production # This can be used to require manual approval + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup Terraform + uses: hashicorp/setup-terraform@v2 + with: + terraform_version: 1.8.0 + + - name: Authenticate to GCP + uses: google-github-actions/auth@v1 + with: + credentials_json: ${{ secrets.GCP_SA_KEY }} + + - name: Terraform Init + run: terraform init + + - name: Terraform Apply + run: terraform apply -auto-approve tfplan + +``` + +### 5. Manual Approval for Production + +To protect the production environment, the `terraform-apply` job will be configured to require manual approval. In Gitea, you can protect the `main` branch and require reviews before merging. For the deployment, Gitea Actions can be configured with an `environment` that requires a manual approval from a specific team or user before the job runs. + +## 6. Implementation Steps + +1. **Create the `.gitea/workflows` directory.** +2. **Create the `terraform.yml` file** with the content above. +3. **Create a dedicated GCP service account** with appropriate IAM roles. +4. **Generate a JSON key** for the service account. +5. **Add the JSON key as a secret** named `GCP_SA_KEY` in the Gitea repository settings. +6. **Protect the `main` branch** in Gitea to require pull requests and reviews. +7. **(Optional) Configure an environment** in Gitea that requires manual approval for deployments. + +This plan provides a solid foundation for automating the Terraform workflow in a safe and controlled manner. diff --git a/infra/gcp/README.md b/infra/gcp/README.md new file mode 100644 index 0000000..3ac61cb --- /dev/null +++ b/infra/gcp/README.md @@ -0,0 +1,62 @@ +# GCP Infrastructure for Sing For Hope + +This directory contains Terraform configurations for deploying and managing Gitea and n8n instances on Google Cloud Platform (GCP). + +## Services Deployed + +* **Gitea**: A self-hosted Git service, accessible at `https://git.singforhope.cloud`. +* **n8n**: A workflow automation tool, accessible at `https://n8n.singforhope.cloud`. + +Both services are deployed on separate `e2-small` virtual machines, configured with Nginx as a reverse proxy and SSL/TLS certificates from Let's Encrypt. + +## Prerequisites + +Before using these Terraform configurations, ensure you have the following: + +* **GCP Project**: A Google Cloud Platform project with billing enabled. +* **`gcloud` CLI**: The Google Cloud SDK installed and authenticated. +* **Terraform CLI**: Terraform installed on your local machine. +* **GCS Backend**: A Google Cloud Storage bucket named `tf-state-token-sfh` for Terraform state management. + +## Usage + +1. **Initialize Terraform**: + Navigate to this directory in your terminal and initialize Terraform: + ```bash + terraform init + ``` + +2. **Review the Plan**: + Review the execution plan to understand what changes Terraform will make. Replace `sing-for-hope` with your actual GCP project ID. + ```bash + terraform plan -var="project_id=sing-for-hope" + ``` + +3. **Apply the Configuration**: + Apply the Terraform configuration to create or update the resources. + ```bash + terraform apply -var="project_id=sing-for-hope" + ``` + You will be prompted to confirm the changes. Type `yes` to proceed. + +## Resources Managed + +The Terraform configuration in this directory manages the following GCP resources: + +* **`google_dns_managed_zone.singforhope_cloud`**: The DNS managed zone for `singforhope.cloud`. +* **`google_compute_instance.gitea_vm`**: The virtual machine instance for Gitea. +* **`google_compute_instance.n8n_vm`**: The virtual machine instance for n8n. +* **`google_dns_record_set.gitea`**: The A record for `git.singforhope.cloud`. +* **`google_dns_record_set.n8n`**: The A record for `n8n.singforhope.cloud`. +* **`google_compute_firewall.gitea_http`**: Firewall rule to allow traffic to Gitea on port 3000. +* **`google_compute_firewall.http_allow`**: Firewall rule to allow HTTP traffic (port 80) to Gitea. +* **`google_compute_firewall.https_allow`**: Firewall rule to allow HTTPS traffic (port 443) to Gitea. +* **`google_compute_firewall.n8n_app_allow`**: Firewall rule to allow traffic to n8n on port 5678. +* **`google_compute_firewall.n8n_http_allow`**: Firewall rule to allow HTTP traffic (port 80) to n8n. +* **`google_compute_firewall.n8n_https_allow`**: Firewall rule to allow HTTPS traffic (port 443) to n8n. + +## Important Notes + +* The initial setup of Gitea and n8n (Docker installation, Nginx configuration, and Certbot SSL) was performed manually via `gcloud` commands. This Terraform configuration now manages the underlying infrastructure (VMs, DNS, Firewall rules) but does not re-run the application-level setup scripts. +* The `metadata_startup_script` attribute for the VM instances is intentionally omitted from the Terraform configuration to prevent unintended re-provisioning of the VMs. +* The `dnssec_config` for the managed zone is included as it is a required parameter. diff --git a/infra/gcp/REVIEW.md b/infra/gcp/REVIEW.md new file mode 100644 index 0000000..f679db9 --- /dev/null +++ b/infra/gcp/REVIEW.md @@ -0,0 +1,385 @@ +# Infrastructure Review: GCP Terraform for Sing For Hope + +**Review Date:** November 9, 2025 +**Reviewer:** Claude Code +**Project:** GCP Infrastructure for Gitea and n8n + +--- + +## Executive Summary + +This Terraform project manages GCP infrastructure for hosting Gitea (self-hosted Git) and n8n (workflow automation) on separate VM instances. While the code is clean and functional, it has several critical issues that limit production-readiness, particularly around security, data persistence, and infrastructure-as-code completeness. + +**Overall Ratings:** +- Production-Readiness: **4/10** +- Code Quality: **6/10** +- Documentation: **7/10** +- Maintainability: **5/10** +- Security: **3/10** + +--- + +## Strengths + +### 1. Clean Project Structure +The project follows Terraform best practices with proper file organization: +- Separate files for variables, outputs, and backend configuration +- Clear naming conventions +- Logical resource grouping + +### 2. Good Documentation +The README.md provides: +- Clear service descriptions +- Prerequisite checklist +- Step-by-step usage instructions +- Honest acknowledgment of manual setup steps + +### 3. Remote State Management +- Uses GCS backend for state storage +- Prevents state conflicts in team environments +- Enables state locking + +### 4. DNS Security +- DNSSEC enabled with appropriate configuration +- Uses NSEC3 for non-existence proof +- Proper key specifications for signing and zone signing + +### 5. Sensible Defaults +- Variables have reasonable default values +- Machine type (e2-small) appropriate for small workloads +- Standard region/zone selection + +--- + +## Critical Issues + +### 1. Hardcoded Service Account Email +**Location:** `main.tf:53`, `main.tf:76` + +```terraform +service_account { + email = "456409048169-compute@developer.gserviceaccount.com" + scopes = [...] +} +``` + +**Impact:** +- Code is not portable across projects +- Violates infrastructure-as-code principles +- Will fail if used in different GCP projects + +**Fix:** +Use Terraform data sources to dynamically fetch the default compute service account: +```terraform +data "google_compute_default_service_account" "default" {} + +service_account { + email = data.google_compute_default_service_account.default.email + scopes = [...] +} +``` + +### 2. Infrastructure Drift (Manual Configuration) +**Location:** README.md notes manual setup of Docker, Nginx, Certbot + +**Impact:** +- Infrastructure cannot be reproduced from code alone +- Disaster recovery requires manual intervention and documentation +- Team members cannot spin up identical environments +- Configuration changes aren't tracked in version control + +**Fix:** +- Add startup scripts to `metadata_startup_script` in VM resources +- OR use Packer to create pre-configured VM images +- OR use configuration management tools (Ansible, Cloud Init) + +### 3. Security Vulnerabilities + +#### a. Overly Permissive Firewall Rules +**Location:** All firewall rules use `source_ranges = ["0.0.0.0/0"]` + +**Issues:** +- Gitea port 3000 exposed to the internet (`main.tf:82-93`) +- n8n port 5678 exposed to the internet (`main.tf:121-132`) +- These should only be accessible via reverse proxy (Nginx) + +#### b. Using Default VPC +**Location:** All resources use `network = "default"` + +**Issues:** +- Default network has permissive routing +- No network segmentation +- Shared with other project resources +- Difficult to implement security best practices + +#### c. No SSH Access Control +- No explicit SSH firewall rules defined +- Default GCP rules may be too permissive +- No bastion host or IAP tunneling + +### 4. No Data Persistence Strategy +**Locations:** `main.tf:40-44`, `main.tf:64-68` + +**Issues:** +- Boot disks use default sizing +- No separate data volumes for application data +- Gitea repositories and n8n workflows stored on ephemeral boot disk +- No backup configuration +- Risk of data loss if VMs are recreated + +**Impact:** +Critical user data (Git repositories, workflow configurations) could be lost during infrastructure updates. + +--- + +## Notable Gaps + +### 5. Missing Startup Automation +While intentionally omitted per README, this creates operational challenges: +- New team members can't provision working infrastructure +- Updates require manual SSH intervention +- No automated application updates or patching + +### 6. Outdated Operating System +**Location:** `main.tf:42`, `main.tf:66` + +Currently using `debian-cloud/debian-11` while Debian 12 is available and supported. + +### 7. No Monitoring or Alerting +Missing operational visibility: +- No Cloud Monitoring dashboards +- No alerting for VM health, disk usage, or service availability +- No log aggregation configuration +- No uptime checks for the applications + +### 8. No High Availability or Auto-Healing +Current setup has single points of failure: +- Single VM per service +- No managed instance groups +- No auto-restart on failure +- No health checks + +### 9. DNS Configuration Gaps +- Zone signing key uses 1024-bit RSA (should be 2048 bits) +- No apex domain record defined (only subdomains) +- TTL of 300 seconds is reasonable but not documented + +### 10. Missing Cost Optimization +- No committed use discounts +- Could use preemptible VMs for non-production +- No resource tagging for cost allocation +- No budgets or billing alerts + +--- + +## Detailed Recommendations + +### High Priority (Do First) + +1. **Fix Hardcoded Service Account** + - Use data sources or variables + - Ensures portability across projects + +2. **Implement Application Provisioning** + - Add startup scripts with idempotent configuration + - Or create golden images with Packer + - Document all manual steps taken + +3. **Secure Firewall Rules** + - Remove public access to ports 3000 and 5678 + - Restrict HTTP/HTTPS to CloudFlare IPs if using CDN + - Add explicit SSH rules with IP allowlisting + +4. **Create Custom VPC** + - Separate network for these resources + - Proper subnet configuration + - Network tags for better organization + +5. **Add Persistent Data Disks** + ```terraform + resource "google_compute_disk" "gitea_data" { + name = "gitea-data" + size = 50 + type = "pd-standard" + zone = var.zone + } + ``` + +6. **Implement Backup Strategy** + - Scheduled snapshots for data disks + - Retention policies + - Test restore procedures + +### Medium Priority (Important but Not Urgent) + +7. **Add Monitoring and Alerting** + - Cloud Monitoring dashboards for VM metrics + - Uptime checks for services + - Alert policies for disk usage, CPU, memory + - Email/Slack notifications + +8. **Upgrade Operating System** + - Change to `debian-cloud/debian-12` + - Test application compatibility first + +9. **Improve DNS Configuration** + - Increase zone signing key to 2048 bits + - Add apex domain record if needed + - Consider lower TTL during migrations + +10. **Add Lifecycle Management** + ```terraform + lifecycle { + prevent_destroy = true # For production + ignore_changes = [metadata_startup_script] + } + ``` + +11. **Implement Better Secrets Management** + - Use Secret Manager for application secrets + - Grant VMs access via service account + - Avoid hardcoding credentials + +12. **Add Resource Labels** + ```terraform + labels = { + environment = "production" + service = "gitea" + managed_by = "terraform" + cost_center = "engineering" + } + ``` + +### Low Priority (Nice to Have) + +13. **Modularize Terraform Code** + - Create reusable modules for VM + DNS pattern + - Separate module for firewall rules + - Easier to maintain and extend + +14. **Add terraform.tfvars.example** + - Document required variables + - Provide example values + - Help new team members get started + +15. **Consider Terragrunt** + - If planning multi-environment setup (dev/staging/prod) + - DRY configuration management + - Environment-specific overrides + +16. **Implement CI/CD for Terraform** + - Automated `terraform plan` on PRs + - Automated `terraform apply` after merge + - State locking verification + +17. **Add Pre-commit Hooks** + - Run `terraform fmt` automatically + - Run `terraform validate` + - Run security scanning (tfsec, checkov) + +18. **Consider Managed Services** + - Cloud Run for containerized apps (simpler than VMs) + - Cloud SQL if databases are needed + - Cloud Storage for artifacts/backups + +--- + +## Security Recommendations Summary + +### Immediate Actions Required: +1. Close ports 3000 and 5678 to public internet +2. Implement IP allowlisting for SSH access +3. Create custom VPC with proper firewall rules +4. Enable VPC Flow Logs for security monitoring +5. Implement Cloud Armor for DDoS protection + +### Additional Security Measures: +- Enable OS Login for SSH key management +- Use Identity-Aware Proxy (IAP) for VM access +- Implement least-privilege service account permissions +- Enable audit logging for all resources +- Regular security scanning with Cloud Security Scanner +- Implement Web Application Firewall (WAF) rules + +--- + +## Data Protection Recommendations + +### Backup Strategy: +```terraform +# Example snapshot schedule +resource "google_compute_resource_policy" "daily_backup" { + name = "daily-backup-policy" + region = var.region + + snapshot_schedule_policy { + schedule { + daily_schedule { + days_in_cycle = 1 + start_time = "04:00" + } + } + retention_policy { + max_retention_days = 14 + on_source_disk_delete = "KEEP_AUTO_SNAPSHOTS" + } + } +} +``` + +### Disaster Recovery Plan: +1. Document manual setup steps in code-readable format (cloud-init) +2. Test VM restoration from snapshots quarterly +3. Maintain off-site backups of critical data +4. Document RTO (Recovery Time Objective) and RPO (Recovery Point Objective) + +--- + +## Estimated Effort for Improvements + +| Priority | Task Category | Estimated Time | +|----------|---------------|----------------| +| High | Security fixes | 4-6 hours | +| High | Data persistence | 2-3 hours | +| High | Service account fix | 30 minutes | +| High | Startup scripts | 4-8 hours | +| Medium | Monitoring setup | 3-4 hours | +| Medium | OS upgrade | 1-2 hours | +| Low | Modularization | 6-8 hours | +| Low | CI/CD pipeline | 4-6 hours | + +**Total effort for high-priority items:** ~12-18 hours +**Total effort for all recommendations:** ~30-40 hours + +--- + +## Conclusion + +This infrastructure demonstrates a good starting point for managing cloud resources with Terraform. The code is readable, well-documented, and follows basic IaC principles. However, significant work is needed to make this production-ready. + +The most critical issue is the **hybrid approach** where infrastructure is managed by Terraform but application configuration is manual. This creates a maintenance burden and makes disaster recovery difficult. + +### Recommended Next Steps: +1. Start with security fixes (firewall rules, custom VPC) +2. Add persistent data disks and backups +3. Automate application provisioning +4. Implement monitoring and alerting +5. Create runbooks for common operations + +With these improvements, this infrastructure could achieve a production-readiness score of 8/10 and provide a solid foundation for the Sing For Hope organization's DevOps needs. + +--- + +## Questions for Further Discussion + +1. What is the expected traffic volume for these services? +2. What are the RTO/RPO requirements for disaster recovery? +3. Is high availability required, or is some downtime acceptable? +4. What is the budget for infrastructure costs? +5. Are there compliance requirements (HIPAA, SOC2, etc.)? +6. Who will be responsible for ongoing maintenance? +7. Are there plans to add more services to this infrastructure? + +--- + +**Note:** This review is based on the code as of November 9, 2025. As infrastructure evolves, periodic reviews should be conducted to ensure continued alignment with best practices and organizational needs. diff --git a/infra/gcp/backend.tf b/infra/gcp/backend.tf new file mode 100644 index 0000000..d680f97 --- /dev/null +++ b/infra/gcp/backend.tf @@ -0,0 +1,6 @@ +terraform { + backend "gcs" { + bucket = "tf-state-token-sfh" # Replace with your GCS bucket name + prefix = "gcp" + } +} diff --git a/infra/gcp/main.tf b/infra/gcp/main.tf new file mode 100644 index 0000000..5c78911 --- /dev/null +++ b/infra/gcp/main.tf @@ -0,0 +1,174 @@ +terraform { + required_providers { + google = { + source = "hashicorp/google" + version = "~> 5" + } + } +} + +provider "google" { + project = var.project_id +} + +resource "google_dns_managed_zone" "singforhope_cloud" { + name = "singforhope-cloud" + dns_name = "${var.domain_name}." + + dnssec_config { + state = "on" + non_existence = "nsec3" + default_key_specs { + algorithm = "rsasha256" + key_length = 2048 + key_type = "keySigning" + } + default_key_specs { + algorithm = "rsasha256" + key_length = 1024 + key_type = "zoneSigning" + } + } +} + +resource "google_compute_instance" "gitea_vm" { + name = "gitea-vm" + machine_type = var.machine_type + zone = var.zone + tags = ["gitea"] + + boot_disk { + initialize_params { + image = "debian-cloud/debian-11" + } + } + + network_interface { + network = "default" + access_config { + } + } + + service_account { + email = "456409048169-compute@developer.gserviceaccount.com" + scopes = ["https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/logging.write", "https://www.googleapis.com/auth/monitoring.write", "https://www.googleapis.com/auth/pubsub", "https://www.googleapis.com/auth/service.management.readonly", "https://www.googleapis.com/auth/servicecontrol", "https://www.googleapis.com/auth/trace.append"] + } +} + +resource "google_compute_instance" "n8n_vm" { + name = "n8n-vm" + machine_type = var.machine_type + zone = var.zone + tags = ["n8n"] + + boot_disk { + initialize_params { + image = "debian-cloud/debian-11" + } + } + + network_interface { + network = "default" + access_config { + } + } + + service_account { + email = "456409048169-compute@developer.gserviceaccount.com" + scopes = ["https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/logging.write", "https://www.googleapis.com/auth/monitoring.write", "https://www.googleapis.com/auth/pubsub", "https://www.googleapis.com/auth/service.management.readonly", "https://www.googleapis.com/auth/servicecontrol", "https://www.googleapis.com/auth/trace.append"] + } +} + +resource "google_compute_firewall" "gitea_http" { + name = "gitea-http" + network = "default" + + allow { + protocol = "tcp" + ports = ["3000"] + } + + source_ranges = ["0.0.0.0/0"] + target_tags = ["gitea"] +} + +resource "google_compute_firewall" "http_allow" { + name = "http-allow" + network = "default" + + allow { + protocol = "tcp" + ports = ["80"] + } + + source_ranges = ["0.0.0.0/0"] + target_tags = ["gitea"] +} + +resource "google_compute_firewall" "https_allow" { + name = "https-allow" + network = "default" + + allow { + protocol = "tcp" + ports = ["443"] + } + + source_ranges = ["0.0.0.0/0"] + target_tags = ["gitea"] +} + +resource "google_compute_firewall" "n8n_app_allow" { + name = "n8n-app-allow" + network = "default" + + allow { + protocol = "tcp" + ports = ["5678"] + } + + source_ranges = ["0.0.0.0/0"] + target_tags = ["n8n"] +} + +resource "google_compute_firewall" "n8n_http_allow" { + name = "n8n-http-allow" + network = "default" + + allow { + protocol = "tcp" + ports = ["80"] + } + + source_ranges = ["0.0.0.0/0"] + target_tags = ["n8n"] +} + +resource "google_compute_firewall" "n8n_https_allow" { + name = "n8n-https-allow" + network = "default" + + allow { + protocol = "tcp" + ports = ["443"] + } + + source_ranges = ["0.0.0.0/0"] + target_tags = ["n8n"] +} + +resource "google_dns_record_set" "gitea" { + name = "git.${var.domain_name}." + type = "A" + ttl = 300 + managed_zone = google_dns_managed_zone.singforhope_cloud.name + rrdatas = [google_compute_instance.gitea_vm.network_interface[0].access_config[0].nat_ip] +} + +resource "google_dns_record_set" "n8n" { + name = "n8n.${var.domain_name}." + type = "A" + ttl = 300 + managed_zone = google_dns_managed_zone.singforhope_cloud.name + rrdatas = [google_compute_instance.n8n_vm.network_interface[0].access_config[0].nat_ip] +} diff --git a/infra/gcp/outputs.tf b/infra/gcp/outputs.tf new file mode 100644 index 0000000..6aae051 --- /dev/null +++ b/infra/gcp/outputs.tf @@ -0,0 +1,24 @@ +output "gitea_vm_name" { + description = "The name of the Gitea VM." + value = google_compute_instance.gitea_vm.name +} + +output "gitea_vm_external_ip" { + description = "The external IP address of the Gitea VM." + value = google_compute_instance.gitea_vm.network_interface[0].access_config[0].nat_ip +} + +output "n8n_vm_name" { + description = "The name of the n8n VM." + value = google_compute_instance.n8n_vm.name +} + +output "n8n_vm_external_ip" { + description = "The external IP address of the n8n VM." + value = google_compute_instance.n8n_vm.network_interface[0].access_config[0].nat_ip +} + +output "dns_name_servers" { + description = "The name servers for the DNS zone." + value = google_dns_managed_zone.singforhope_cloud.name_servers +} \ No newline at end of file diff --git a/infra/gcp/variables.tf b/infra/gcp/variables.tf new file mode 100644 index 0000000..ddf0517 --- /dev/null +++ b/infra/gcp/variables.tf @@ -0,0 +1,28 @@ +variable "project_id" { + description = "The GCP project ID." + type = string +} + +variable "region" { + description = "The GCP region to deploy resources in." + type = string + default = "us-central1" +} + +variable "zone" { + description = "The GCP zone to deploy resources in." + type = string + default = "us-central1-a" +} + +variable "domain_name" { + description = "The domain name to configure DNS for." + type = string + default = "singforhope.cloud" +} + +variable "machine_type" { + description = "The machine type for the VM." + type = string + default = "e2-small" +}