This template allows deploying a forgejo en either Scaleway or Hetzner (untested) without much knowledge about them. It DOES require knowledge about Terragrunt and ansible. A wizard of sorts is provided but it will not guarantee success without some knowledge about the underlying technology.
224 lines
5.4 KiB
HCL
224 lines
5.4 KiB
HCL
# Include root configuration
|
|
include "root" {
|
|
path = find_in_parent_folders("root.hcl")
|
|
}
|
|
|
|
# Terragrunt configuration
|
|
terraform {
|
|
source = "."
|
|
}
|
|
|
|
# Generate the main Terraform configuration
|
|
generate "main" {
|
|
path = "main.tf"
|
|
if_exists = "overwrite"
|
|
contents = <<EOF
|
|
# Scaleway Compute Instance for Forgejo
|
|
|
|
variable "project_name" {
|
|
description = "Project name"
|
|
type = string
|
|
}
|
|
|
|
variable "environment" {
|
|
description = "Environment name"
|
|
type = string
|
|
}
|
|
|
|
variable "region" {
|
|
description = "Scaleway region"
|
|
type = string
|
|
}
|
|
|
|
variable "zone" {
|
|
description = "Scaleway zone"
|
|
type = string
|
|
}
|
|
|
|
variable "common_tags" {
|
|
description = "Common tags for all resources"
|
|
type = map(string)
|
|
}
|
|
|
|
variable "instance_type" {
|
|
description = "Instance type for Forgejo server"
|
|
type = string
|
|
default = "DEV1-M" # 4GB RAM, 2 vCPUs, 40GB SSD
|
|
}
|
|
|
|
variable "ssh_public_key" {
|
|
description = "SSH public key for server access"
|
|
type = string
|
|
default = "" # Will use SSH agent keys if not provided
|
|
}
|
|
|
|
variable "domain_name" {
|
|
description = "Domain name for Forgejo (e.g., git.example.com)"
|
|
type = string
|
|
default = ""
|
|
}
|
|
|
|
# Data sources
|
|
data "scaleway_instance_image" "ubuntu" {
|
|
architecture = "x86_64"
|
|
name = "Ubuntu 24.04 Noble Numbat"
|
|
latest = true
|
|
}
|
|
|
|
# Security Group
|
|
resource "scaleway_instance_security_group" "forgejo" {
|
|
name = "$${var.project_name}-$${var.environment}-sg"
|
|
inbound_default_policy = "drop"
|
|
outbound_default_policy = "accept"
|
|
|
|
inbound_rule {
|
|
action = "accept"
|
|
port = "22"
|
|
protocol = "TCP"
|
|
ip_range = "0.0.0.0/0"
|
|
}
|
|
|
|
inbound_rule {
|
|
action = "accept"
|
|
port = "80"
|
|
protocol = "TCP"
|
|
ip_range = "0.0.0.0/0"
|
|
}
|
|
|
|
inbound_rule {
|
|
action = "accept"
|
|
port = "443"
|
|
protocol = "TCP"
|
|
ip_range = "0.0.0.0/0"
|
|
}
|
|
|
|
# SSH alternative port (optional, configured via Ansible)
|
|
inbound_rule {
|
|
action = "accept"
|
|
port = "2222"
|
|
protocol = "TCP"
|
|
ip_range = "0.0.0.0/0"
|
|
}
|
|
|
|
tags = [for k, v in var.common_tags : "$${k}:$${v}"]
|
|
}
|
|
|
|
# SSH Key (using IAM SSH key for Scaleway provider v2.x)
|
|
resource "scaleway_iam_ssh_key" "forgejo" {
|
|
count = var.ssh_public_key != "" ? 1 : 0
|
|
name = "$${var.project_name}-$${var.environment}-key"
|
|
public_key = var.ssh_public_key
|
|
}
|
|
|
|
# Block Volume for data persistence (create before instance)
|
|
resource "scaleway_block_volume" "forgejo_data" {
|
|
name = "$${var.project_name}-$${var.environment}-data"
|
|
size_in_gb = 50
|
|
iops = 5000
|
|
|
|
tags = [for k, v in var.common_tags : "$${k}:$${v}"]
|
|
}
|
|
|
|
# Reserved IP (create before instance for stability)
|
|
resource "scaleway_instance_ip" "forgejo" {}
|
|
|
|
# Compute Instance
|
|
resource "scaleway_instance_server" "forgejo" {
|
|
name = "$${var.project_name}-$${var.environment}"
|
|
type = var.instance_type
|
|
image = data.scaleway_instance_image.ubuntu.id
|
|
security_group_id = scaleway_instance_security_group.forgejo.id
|
|
ip_id = scaleway_instance_ip.forgejo.id
|
|
|
|
tags = [for k, v in var.common_tags : "$${k}:$${v}"]
|
|
|
|
# Ensure SSH key is registered before instance is created
|
|
depends_on = [scaleway_iam_ssh_key.forgejo]
|
|
|
|
# Cloud-init for initial setup (user_data is a map in v2.x)
|
|
user_data = {
|
|
cloud-init = <<-CLOUDINIT
|
|
#cloud-config
|
|
package_update: true
|
|
package_upgrade: true
|
|
packages:
|
|
- apt-transport-https
|
|
- ca-certificates
|
|
- curl
|
|
- gnupg
|
|
- lsb-release
|
|
- python3
|
|
- python3-pip
|
|
|
|
write_files:
|
|
- path: /etc/sysctl.d/99-forgejo.conf
|
|
content: |
|
|
# Forgejo optimizations
|
|
net.core.somaxconn = 1024
|
|
net.ipv4.tcp_max_syn_backlog = 2048
|
|
vm.swappiness = 10
|
|
|
|
runcmd:
|
|
- sysctl -p /etc/sysctl.d/99-forgejo.conf
|
|
- systemctl enable ssh
|
|
- ufw --force enable
|
|
- ufw allow 22/tcp
|
|
- ufw allow 80/tcp
|
|
- ufw allow 443/tcp
|
|
CLOUDINIT
|
|
}
|
|
}
|
|
|
|
# Attach block volume to instance
|
|
resource "scaleway_block_snapshot" "forgejo_data" {
|
|
count = 0 # Only create if you need snapshots
|
|
name = "$${var.project_name}-$${var.environment}-snapshot"
|
|
volume_id = scaleway_block_volume.forgejo_data.id
|
|
}
|
|
|
|
# Outputs
|
|
output "server_id" {
|
|
description = "Forgejo server ID"
|
|
value = scaleway_instance_server.forgejo.id
|
|
}
|
|
|
|
output "server_ip" {
|
|
description = "Forgejo server public IP"
|
|
value = scaleway_instance_ip.forgejo.address
|
|
}
|
|
|
|
output "server_private_ip" {
|
|
description = "Forgejo server private IP"
|
|
value = length(scaleway_instance_server.forgejo.private_ips) > 0 ? scaleway_instance_server.forgejo.private_ips[0].address : null
|
|
}
|
|
|
|
output "security_group_id" {
|
|
description = "Security group ID"
|
|
value = scaleway_instance_security_group.forgejo.id
|
|
}
|
|
|
|
output "volume_id" {
|
|
description = "Data volume ID"
|
|
value = scaleway_block_volume.forgejo_data.id
|
|
}
|
|
|
|
output "ssh_command" {
|
|
description = "SSH command to connect to server"
|
|
value = "ssh root@$${scaleway_instance_ip.forgejo.address}"
|
|
}
|
|
|
|
output "dns_record" {
|
|
description = "DNS A record to create"
|
|
value = var.domain_name != "" ? "$${var.domain_name} IN A $${scaleway_instance_ip.forgejo.address}" : "No domain configured"
|
|
}
|
|
EOF
|
|
}
|
|
|
|
# Dependencies
|
|
dependency "storage" {
|
|
config_path = "../storage"
|
|
skip_outputs = true
|
|
mock_outputs = {
|
|
bucket_name = "forgejo-storage"
|
|
}
|
|
}
|