Initial commit of Forgejo configuration

This commit is contained in:
Dada 2025-03-23 18:31:05 -04:00
commit ce9b28917b
16 changed files with 860 additions and 0 deletions

27
.gitignore vendored Normal file
View file

@ -0,0 +1,27 @@
# Terraform files
terraform/.terraform/
terraform/terraform.tfstate
terraform/terraform.tfstate.backup
terraform/.terraform.lock.hcl
terraform/crash.log
# Ansible files
ansible/*.retry
# SSH keys
*.pem
*.key
id_rsa*
# OS files
.DS_Store
Thumbs.db
# Editor files
.vscode/
.idea/
*.swp
*~
# Logs
*.log

147
DEPLOYMENT_GUIDE.md Normal file
View file

@ -0,0 +1,147 @@
# Forgejo Deployment Guide
This guide provides detailed step-by-step instructions for deploying the Forgejo git repository on a GCP VM with SSL.
## Prerequisites
1. Google Cloud Platform account with project ID: `homelab-454516`
2. Terraform installed locally
3. Ansible installed locally
4. SSH key pair at `~/.ssh/id_rsa` and `~/.ssh/id_rsa.pub`
5. DuckDNS account with subdomain: `bootknockery.duckdns.org`
## Deployment Steps
### 1. Infrastructure Provisioning with Terraform
```bash
# Navigate to the terraform directory
cd terraform
# Initialize Terraform
terraform init
# Apply the Terraform configuration
terraform apply
```
This will create a GCP VM in the `us-central1-a` zone with the following specifications:
- Machine type: e2-medium
- Disk size: 50GB
- Operating system: Debian
### 2. Update DuckDNS
Ensure your DuckDNS subdomain (`bootknockery.duckdns.org`) points to the VM's external IP address.
### 3. Deploy Forgejo with Ansible
```bash
# Navigate to the ansible directory
cd ../ansible
# Run the Ansible playbook
ansible-playbook -i inventory.yml forgejo.yml
```
This will:
- Install Docker and Docker Compose
- Deploy Forgejo in a Docker container
- Configure Nginx as a reverse proxy
- Set up SSL with Let's Encrypt
- Configure SQLite with WAL mode for better performance
### 4. Verify the Deployment
1. Access Forgejo via HTTPS:
```
https://bootknockery.duckdns.org
```
2. Check that SSL is properly configured:
```bash
ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo certbot certificates"
```
3. Verify that SQLite WAL mode is active:
```bash
ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo ls -la /opt/forgejo/data/gitea/gitea.db*"
```
You should see additional files like `gitea.db-wal` and `gitea.db-shm`.
## Post-Deployment Configuration
### Initial Forgejo Setup
When you first access Forgejo, you'll need to:
1. Set up the admin account
2. Configure the database settings (SQLite is already configured)
3. Set up repository settings
### SSH Access for Git Operations
To use Git over SSH:
```bash
# Add to ~/.ssh/config
Host bootknockery.duckdns.org
Port 222
User git
IdentityFile ~/.ssh/id_rsa
```
Then clone repositories using:
```bash
git clone git@bootknockery.duckdns.org:username/repository.git
```
## Maintenance Tasks
### SSL Certificate Renewal
SSL certificates are automatically renewed weekly. To manually renew:
```bash
ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo /etc/cron.weekly/certbot-renew"
```
### Database Backup
To back up the Forgejo database:
```bash
ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo cp /opt/forgejo/data/gitea/gitea.db ~/backup_gitea.db"
scp -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS:~/backup_gitea.db ./
```
### Updating Forgejo
To update Forgejo to a newer version:
1. Edit `ansible/templates/docker-compose.yml.j2` to update the image version
2. Run the Ansible playbook again:
```bash
cd ansible
ansible-playbook -i inventory.yml forgejo.yml
```
## Troubleshooting
### Common Issues
1. **Cannot access Forgejo via HTTPS**
- Check Nginx status: `ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo systemctl status nginx"`
- Verify SSL certificates: `ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo ls -la /etc/letsencrypt/live/bootknockery.duckdns.org/"`
2. **Forgejo container not running**
- Check Docker status: `ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo docker ps"`
- View Forgejo logs: `ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo docker logs forgejo"`
3. **SSL certificate issues**
- Check certificate logs: `ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo tail -f /var/log/letsencrypt/letsencrypt.log"`
- Force renewal: `ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo /etc/cron.weekly/certbot-renew"`
4. **Performance issues**
- Verify WAL mode: `ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo ls -la /opt/forgejo/data/gitea/gitea.db*"`
- Check system resources: `ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "top"`

142
README.md Normal file
View file

@ -0,0 +1,142 @@
# GCP Data Engineering VM with Forgejo
This project sets up a reusable Google Cloud Platform (GCP) virtual machine for data engineering and machine learning projects, with Forgejo as the first installed module.
## Technologies Used
- **Terraform**: For infrastructure provisioning and state management
- **Cloud-init**: For initial VM setup and configuration with Debian
- **Ansible**: For configuration management and application deployment
- **Docker & Docker Compose**: For containerized applications
- **Forgejo**: Open source git repository that can be accessed through a DuckDNS subdomain
## Project Structure
```
.
├── ansible/ # Ansible playbooks and configurations
│ ├── forgejo.yml # Forgejo installation playbook
│ ├── inventory.yml # Ansible inventory file
│ └── templates/ # Jinja2 templates for configurations
│ ├── app.ini.j2 # Forgejo app configuration
│ ├── docker-compose.yml.j2 # Docker Compose template
│ ├── nginx.conf.j2 # Nginx configuration with SSL support
│ └── certbot-renew.j2 # SSL certificate renewal script
├── cloud-init/ # Cloud-init scripts
│ └── cloud-init.sh # Initial VM setup script
├── terraform/ # Terraform configurations
│ ├── main.tf # Main Terraform configuration
│ ├── variables.tf # Variable definitions
│ └── terraform.tfvars.example # Example variable values
├── deploy.sh # Deployment automation script
└── README.md # This file
```
## Prerequisites
1. Google Cloud Platform account with a project
2. Terraform installed locally
3. Ansible installed locally
4. SSH key pair for VM access
5. DuckDNS subdomain for Forgejo access
## Setup Instructions
### 1. Configure Terraform Variables
Copy the example variables file and edit it with your GCP project details:
```bash
cp terraform/terraform.tfvars.example terraform/terraform.tfvars
```
Edit `terraform/terraform.tfvars` with your GCP project ID, preferred region/zone, and SSH key path.
### 2. Configure Ansible Inventory
Edit `ansible/inventory.yml` to set your DuckDNS subdomain and admin email for Let's Encrypt SSL certificates.
### 3. Run the Deployment Script
```bash
./deploy.sh
```
This script will:
- Initialize and apply Terraform configuration to create the VM
- Update the Ansible inventory with the VM's IP address
- Wait for the VM to be ready
- Run the Ansible playbook to install and configure Forgejo
## Accessing Forgejo
Once deployment is complete, Forgejo will be accessible at:
```
https://your-duckdns-subdomain.duckdns.org
```
The deployment automatically configures:
- HTTPS with Let's Encrypt SSL certificates
- Automatic HTTP to HTTPS redirection
- Weekly SSL certificate renewal
- SQLite with WAL mode for improved performance
SSH access to the Forgejo Git server will be available on port 222:
```bash
ssh -p 222 git@your-duckdns-subdomain.duckdns.org
```
## Performance Optimizations
### SQLite WAL Mode
The deployment configures SQLite to use Write-Ahead Logging (WAL) mode for better performance. This provides:
- Improved write performance with concurrent operations
- Better read concurrency (readers don't block writers)
- Reduced disk I/O
- Improved durability and crash recovery
To modify this setting, edit the `ansible/templates/app.ini.j2` file:
```ini
[database]
SQLITE_JOURNAL_MODE = WAL
```
## Customization
- **Machine Type**: Edit `terraform/terraform.tfvars` to change the VM size
- **Forgejo Configuration**: Modify `ansible/templates/app.ini.j2` to customize Forgejo settings
- **Additional Applications**: Add new Ansible playbooks in the `ansible` directory
## Maintenance
- **Terraform State**: The Terraform state is stored locally in `terraform/terraform.tfstate`
- **VM Updates**: SSH into the VM and run standard Debian update commands
- **Forgejo Updates**: Update the Docker image version in `ansible/templates/docker-compose.yml.j2`
- **SSL Certificate Renewal**: Certificates are automatically renewed weekly via a cron job
- **Database Backups**: To back up the Forgejo database, copy `/opt/forgejo/data/gitea/gitea.db*` from the VM
- **Monitoring**: Check the status of services with:
```bash
ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo systemctl status nginx"
ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo docker ps"
```
## Troubleshooting
- **SSH Access**: `ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS`
- **Logs**:
- Forgejo logs: `ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo docker logs forgejo"`
- Nginx logs: `ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo tail -f /var/log/nginx/error.log"`
- SSL certificate logs: `ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo tail -f /var/log/letsencrypt/letsencrypt.log"`
- **Connectivity**: Ensure GCP firewall rules allow traffic on ports 80, 443, 22, 3000, and 222
- **SSL Issues**:
- Check certificate status: `ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo certbot certificates"`
- Force certificate renewal: `ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo /etc/cron.weekly/certbot-renew"`
- **Database Performance**: If experiencing slowdowns, check SQLite WAL mode is working:
```bash
ssh -i ~/.ssh/id_rsa debian@VM_IP_ADDRESS "sudo ls -la /opt/forgejo/data/gitea/gitea.db*"
```
You should see additional files like `gitea.db-wal` and `gitea.db-shm` if WAL mode is active.

124
ansible/forgejo.yml Normal file
View file

@ -0,0 +1,124 @@
---
- name: Install and configure Forgejo
hosts: all
become: true
vars:
forgejo_domain: "{{ duckdns_subdomain }}.duckdns.org"
forgejo_data_dir: /opt/forgejo
forgejo_user_uid: 1000
forgejo_user_gid: 1000
forgejo_http_port: 3000
forgejo_ssh_port: 222
tasks:
- name: Ensure Forgejo directory exists
file:
path: "{{ forgejo_data_dir }}"
state: directory
owner: "{{ forgejo_user_uid }}"
group: "{{ forgejo_user_gid }}"
mode: '0755'
- name: Create Forgejo docker-compose.yml
template:
src: templates/docker-compose.yml.j2
dest: "{{ forgejo_data_dir }}/docker-compose.yml"
owner: "{{ forgejo_user_uid }}"
group: "{{ forgejo_user_gid }}"
mode: '0644'
- name: Create app.ini configuration file
template:
src: templates/app.ini.j2
dest: "{{ forgejo_data_dir }}/app.ini"
owner: "{{ forgejo_user_uid }}"
group: "{{ forgejo_user_gid }}"
mode: '0644'
- name: Start Forgejo with Docker Compose
community.docker.docker_compose_v2:
project_src: "{{ forgejo_data_dir }}"
state: present
become: true
become_user: debian
- name: Install Nginx
apt:
name: nginx
state: present
update_cache: yes
- name: Configure Nginx for Forgejo
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/sites-available/forgejo
owner: root
group: root
mode: '0644'
- name: Enable Nginx site
file:
src: /etc/nginx/sites-available/forgejo
dest: /etc/nginx/sites-enabled/forgejo
state: link
- name: Remove default Nginx site
file:
path: /etc/nginx/sites-enabled/default
state: absent
- name: Restart Nginx
service:
name: nginx
state: restarted
enabled: yes
- name: Pull Certbot Docker image
community.docker.docker_image:
name: certbot/certbot
source: pull
when: admin_email is defined
- name: Stop Nginx before obtaining SSL certificate
service:
name: nginx
state: stopped
when: admin_email is defined
- name: Obtain SSL certificate with Certbot Docker
block:
- name: Run Certbot Docker to obtain SSL certificate
command: >
docker run --rm -p 80:80 -p 443:443
-v /etc/letsencrypt:/etc/letsencrypt
-v /var/lib/letsencrypt:/var/lib/letsencrypt
certbot/certbot certonly --standalone
-d {{ forgejo_domain }} --non-interactive --agree-tos
-m {{ admin_email }}
args:
creates: /etc/letsencrypt/live/{{ forgejo_domain }}/fullchain.pem
register: certbot_output
failed_when: certbot_output.rc != 0 and certbot_output.stderr is not search("already exists")
- name: Handle certbot errors
debug:
msg: "Certbot error: {{ certbot_output.stderr }}"
when: certbot_output is failed
when: admin_email is defined
ignore_errors: yes
- name: Start Nginx after obtaining SSL certificate
service:
name: nginx
state: started
when: admin_email is defined
- name: Set up SSL certificate renewal
block:
- name: Create SSL certificate renewal script
template:
src: templates/certbot-renew.j2
dest: /etc/cron.weekly/certbot-renew
owner: root
group: root
mode: '0755'
when: admin_email is defined

8
ansible/inventory.yml Normal file
View file

@ -0,0 +1,8 @@
all:
hosts:
data_engineering_vm:
ansible_host: "34.67.170.119"
ansible_user: debian
ansible_ssh_private_key_file: "~/.ssh/id_rsa"
duckdns_subdomain: "bootknockery" # Replace with your actual DuckDNS subdomain
admin_email: "jaypeedaylee@gmail.com" # Replace with your email for Let's Encrypt

View file

@ -0,0 +1,77 @@
APP_NAME = Forgejo
RUN_USER = git
RUN_MODE = prod
[repository]
ROOT = /data/git/repositories
[repository.local]
LOCAL_COPY_PATH = /data/gitea/tmp/local-repo
[repository.upload]
TEMP_PATH = /data/gitea/uploads
[server]
APP_DATA_PATH = /data/gitea
DOMAIN = {{ forgejo_domain }}
SSH_DOMAIN = {{ forgejo_domain }}
HTTP_PORT = 3000
ROOT_URL = https://{{ forgejo_domain }}/
DISABLE_SSH = false
SSH_PORT = {{ forgejo_ssh_port }}
SSH_LISTEN_PORT = 22
LFS_START_SERVER = true
LFS_CONTENT_PATH = /data/git/lfs
LFS_JWT_SECRET =
OFFLINE_MODE = false
[database]
PATH = /data/gitea/gitea.db
DB_TYPE = sqlite3
SQLITE_JOURNAL_MODE = WAL
[indexer]
ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve
[session]
PROVIDER_CONFIG = /data/gitea/sessions
PROVIDER = file
[picture]
AVATAR_UPLOAD_PATH = /data/gitea/avatars
REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars
[attachment]
PATH = /data/gitea/attachments
[log]
MODE = console
LEVEL = info
ROOT_PATH = /data/gitea/log
[security]
INSTALL_LOCK = true
SECRET_KEY =
INTERNAL_TOKEN =
[service]
DISABLE_REGISTRATION = false
REQUIRE_SIGNIN_VIEW = false
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
ALLOW_ONLY_EXTERNAL_REGISTRATION = false
ENABLE_CAPTCHA = false
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
DEFAULT_ENABLE_TIMETRACKING = true
NO_REPLY_ADDRESS = noreply.example.org
[oauth2]
JWT_SECRET =
[mailer]
ENABLED = false
[openid]
ENABLE_OPENID_SIGNIN = true
ENABLE_OPENID_SIGNUP = true

View file

@ -0,0 +1,37 @@
#!/bin/bash
# Certbot renewal script for Forgejo SSL certificates
# Automatically created by Ansible
# Set up logging
LOG_FILE="/var/log/certbot-renewal.log"
echo "$(date): Starting certificate renewal" >> $LOG_FILE
# Stop Nginx to free up port 80
echo "$(date): Stopping Nginx" >> $LOG_FILE
systemctl stop nginx
if [ $? -ne 0 ]; then
echo "$(date): Failed to stop Nginx" >> $LOG_FILE
exit 1
fi
# Run Certbot renewal
echo "$(date): Running Certbot renewal" >> $LOG_FILE
docker run --rm -p 80:80 -p 443:443 \
-v /etc/letsencrypt:/etc/letsencrypt \
-v /var/lib/letsencrypt:/var/lib/letsencrypt \
certbot/certbot renew --standalone --non-interactive
if [ $? -ne 0 ]; then
echo "$(date): Certbot renewal failed" >> $LOG_FILE
# Even if renewal fails, we should restart Nginx
fi
# Start Nginx again
echo "$(date): Starting Nginx" >> $LOG_FILE
systemctl start nginx
if [ $? -ne 0 ]; then
echo "$(date): Failed to start Nginx" >> $LOG_FILE
exit 1
fi
echo "$(date): Certificate renewal completed successfully" >> $LOG_FILE

View file

@ -0,0 +1,21 @@
networks:
forgejo:
external: false
services:
server:
image: codeberg.org/forgejo/forgejo:10
container_name: forgejo
environment:
- USER_UID={{ forgejo_user_uid }}
- USER_GID={{ forgejo_user_gid }}
restart: always
networks:
- forgejo
volumes:
- {{ forgejo_data_dir }}/data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- '{{ forgejo_http_port }}:3000'
- '{{ forgejo_ssh_port }}:22'

View file

@ -0,0 +1,12 @@
server {
listen 80;
server_name {{ forgejo_domain }};
location / {
proxy_pass http://localhost:{{ forgejo_http_port }}/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

View file

@ -0,0 +1,32 @@
server {
listen 80;
server_name {{ forgejo_domain }};
# Redirect all HTTP requests to HTTPS
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name {{ forgejo_domain }};
ssl_certificate /etc/letsencrypt/live/{{ forgejo_domain }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ forgejo_domain }}/privkey.pem;
# SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location / {
proxy_pass http://localhost:{{ forgejo_http_port }}/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

44
cloud-init/cloud-init.sh Normal file
View file

@ -0,0 +1,44 @@
#!/bin/bash
set -e
# Update and install dependencies
apt-get update
apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release \
python3 \
python3-pip \
git \
unzip
# Install Docker
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io
# Install Docker Compose
curl -L "https://github.com/docker/compose/releases/download/v2.20.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# Add debian user to docker group
usermod -aG docker debian
# Install Ansible
pip3 install ansible
# Create directory for Ansible playbooks
mkdir -p /opt/ansible
chown -R debian:debian /opt/ansible
# Create directory for Forgejo
mkdir -p /opt/forgejo
chown -R debian:debian /opt/forgejo
# Signal cloud-init completion
touch /var/lib/cloud/instance/boot-finished

61
deploy.sh Executable file
View file

@ -0,0 +1,61 @@
#!/bin/bash
set -e
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
echo -e "${YELLOW}Starting deployment of GCP Data Engineering VM with Forgejo...${NC}"
# Check if terraform is installed
if ! command -v terraform &> /dev/null; then
echo -e "${RED}Terraform is not installed. Please install it first.${NC}"
exit 1
fi
# Check if ansible is installed
if ! command -v ansible &> /dev/null; then
echo -e "${RED}Ansible is not installed. Please install it first.${NC}"
exit 1
fi
# Check if terraform.tfvars exists
if [ ! -f terraform/terraform.tfvars ]; then
echo -e "${YELLOW}terraform.tfvars not found. Creating from example file...${NC}"
cp terraform/terraform.tfvars.example terraform/terraform.tfvars
echo -e "${RED}Please edit terraform/terraform.tfvars with your GCP project details before continuing.${NC}"
exit 1
fi
# Initialize Terraform
echo -e "${GREEN}Initializing Terraform...${NC}"
cd terraform
terraform init
# Apply Terraform configuration
echo -e "${GREEN}Applying Terraform configuration...${NC}"
terraform apply -auto-approve
# Get the VM IP address
VM_IP=$(terraform output -raw instance_ip)
echo -e "${GREEN}VM created with IP: ${VM_IP}${NC}"
cd ..
# Update Ansible inventory with VM IP
echo -e "${GREEN}Updating Ansible inventory with VM IP...${NC}"
sed -i "s/ansible_host: \"{{ vm_ip_address }}\"/ansible_host: \"${VM_IP}\"/g" ansible/inventory.yml
# Wait for VM to be ready
echo -e "${YELLOW}Waiting for VM to be ready (60 seconds)...${NC}"
sleep 60
# Run Ansible playbook
echo -e "${GREEN}Running Ansible playbook to configure Forgejo...${NC}"
cd ansible
ansible-playbook -i inventory.yml forgejo.yml
echo -e "${GREEN}Deployment completed successfully!${NC}"
echo -e "${YELLOW}Forgejo should be accessible at https://your-duckdns-subdomain.duckdns.org${NC}"
echo -e "${YELLOW}Please allow a few minutes for DNS propagation and SSL certificate setup.${NC}"

66
terraform/main.tf Normal file
View file

@ -0,0 +1,66 @@
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "~> 4.0"
}
}
backend "local" {
path = "terraform.tfstate"
}
}
provider "google" {
project = var.project_id
region = var.region
zone = var.zone
}
resource "google_compute_instance" "data_engineering_vm" {
name = var.instance_name
machine_type = var.machine_type
zone = var.zone
boot_disk {
initialize_params {
image = "debian-cloud/debian-11"
size = var.disk_size_gb
}
}
network_interface {
network = "default"
access_config {
// Ephemeral public IP
}
}
metadata = {
ssh-keys = "${var.ssh_username}:${file(var.ssh_pub_key_path)}"
}
metadata_startup_script = file("${path.module}/../cloud-init/cloud-init.sh")
tags = ["http-server", "https-server", "ssh"]
service_account {
scopes = ["cloud-platform"]
}
}
resource "google_compute_firewall" "forgejo" {
name = "allow-forgejo"
network = "default"
allow {
protocol = "tcp"
ports = ["22", "80", "443", "3000", "222"]
}
source_ranges = ["0.0.0.0/0"]
target_tags = ["http-server", "https-server", "ssh"]
}
output "instance_ip" {
value = google_compute_instance.data_engineering_vm.network_interface[0].access_config[0].nat_ip
}

View file

@ -0,0 +1,8 @@
project_id = "homelab-454516"
region = "us-central1"
zone = "us-central1-a"
instance_name = "data-engineering-vm"
machine_type = "e2-medium"
disk_size_gb = 50
ssh_username = "debian"
ssh_pub_key_path = "~/.ssh/id_rsa.pub"

View file

@ -0,0 +1,8 @@
project_id = "your-gcp-project-id"
region = "us-central1"
zone = "us-central1-a"
instance_name = "data-engineering-vm"
machine_type = "e2-medium"
disk_size_gb = 50
ssh_username = "debian"
ssh_pub_key_path = "~/.ssh/id_rsa.pub"

46
terraform/variables.tf Normal file
View file

@ -0,0 +1,46 @@
variable "project_id" {
description = "The GCP project ID"
type = string
}
variable "region" {
description = "The GCP region"
type = string
default = "us-central1"
}
variable "zone" {
description = "The GCP zone"
type = string
default = "us-central1-a"
}
variable "instance_name" {
description = "Name of the VM instance"
type = string
default = "data-engineering-vm"
}
variable "machine_type" {
description = "The machine type for the VM"
type = string
default = "e2-medium"
}
variable "disk_size_gb" {
description = "Boot disk size in GB"
type = number
default = 50
}
variable "ssh_username" {
description = "SSH username for the VM"
type = string
default = "debian"
}
variable "ssh_pub_key_path" {
description = "Path to the SSH public key file"
type = string
default = "~/.ssh/id_rsa.pub"
}