provider "alicloud" {
region = var.region
}
variable "region" {
description = "Wilayah Alibaba Cloud"
type = string
default = "cn-hongkong"
}
variable "instance_type" {
description = "Tipe instans ECS"
type = string
default = "ecs.c9i.xlarge"
validation {
condition = can(regex("^ecs\\.", var.instance_type))
error_message = "Tipe instans harus diawali dengan 'ecs.'"
}
}
variable "system_disk_category" {
description = "Jenis disk sistem"
type = string
default = "cloud_essd"
validation {
condition = contains(["cloud_efficiency", "cloud_ssd", "cloud_essd"], var.system_disk_category)
error_message = "Jenis disk sistem harus salah satu dari cloud_efficiency, cloud_ssd, atau cloud_essd."
}
}
variable "system_disk_size" {
description = "Ukuran disk sistem dalam GB"
type = number
default = 40
validation {
condition = var.system_disk_size >= 20 && var.system_disk_size <= 500
error_message = "Ukuran disk sistem harus antara 20 GB dan 500 GB."
}
}
variable "instance_password" {
description = "Kata sandi untuk instance ECS. Harus terdiri dari minimal 8 karakter dan mengandung huruf kapital, huruf kecil, serta angka."
type = string
sensitive = true
validation {
condition = (
length(var.instance_password) >= 8 &&
length(var.instance_password) <= 30 &&
can(regex("[a-z]", var.instance_password)) &&
can(regex("[A-Z]", var.instance_password)) &&
can(regex("[0-9]", var.instance_password))
)
error_message = "Kata sandi harus terdiri dari minimal 8 karakter dan mengandung huruf kapital, huruf kecil, serta angka."
}
}
variable "vpc_cidr" {
description = "Blok CIDR untuk VPC"
type = string
default = "192.168.0.0/16"
}
variable "vswitch_cidr" {
description = "Blok CIDR untuk vSwitch"
type = string
default = "192.168.1.0/24"
}
variable "project_name" {
description = "Nama proyek, digunakan untuk penamaan sumber daya"
type = string
default = "dify-deployment"
}
variable "internet_max_bandwidth_out" {
description = "Bandwidth publik maksimum dalam Mbps"
type = number
default = 5
validation {
condition = var.internet_max_bandwidth_out >= 1 && var.internet_max_bandwidth_out <= 200
error_message = "Bandwidth publik harus antara 1 Mbps dan 200 Mbps."
}
}
data "alicloud_zones" "default" {
available_disk_category = var.system_disk_category
available_resource_creation = "VSwitch"
available_instance_type = var.instance_type
}
# Mendapatkan citra CentOS 7 terbaru
data "alicloud_images" "centos" {
owners = "system"
name_regex = "^centos_7"
most_recent = true
instance_type = var.instance_type
}
# Membuat VPC
resource "alicloud_vpc" "main" {
vpc_name = "${var.project_name}-vpc"
cidr_block = var.vpc_cidr
}
# Membuat vSwitch
resource "alicloud_vswitch" "main" {
vpc_id = alicloud_vpc.main.id
cidr_block = var.vswitch_cidr
zone_id = data.alicloud_zones.default.zones.0.id
vswitch_name = "${var.project_name}-vswitch"
}
# Membuat grup keamanan
resource "alicloud_security_group" "main" {
security_group_name = "${var.project_name}-sg"
description = "Grup keamanan untuk penerapan Dify"
vpc_id = alicloud_vpc.main.id
}
# Aturan grup keamanan - HTTP
resource "alicloud_security_group_rule" "http" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = "80/80"
priority = 1
security_group_id = alicloud_security_group.main.id
cidr_ip = "0.0.0.0/0"
description = "Mengizinkan lalu lintas HTTP"
}
# Aturan grup keamanan - SSH
resource "alicloud_security_group_rule" "ssh" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = "22/22"
priority = 1
security_group_id = alicloud_security_group.main.id
cidr_ip = "0.0.0.0/0"
description = "Mengizinkan lalu lintas SSH"
}
# Aturan grup keamanan - HTTPS
resource "alicloud_security_group_rule" "https" {
type = "ingress"
ip_protocol = "tcp"
nic_type = "intranet"
policy = "accept"
port_range = "443/443"
priority = 1
security_group_id = alicloud_security_group.main.id
cidr_ip = "0.0.0.0/0"
description = "Mengizinkan lalu lintas HTTPS"
}
# Membuat instance ECS
resource "alicloud_instance" "dify" {
instance_name = "${var.project_name}-instance"
image_id = data.alicloud_images.centos.images[0].id
instance_type = var.instance_type
system_disk_category = var.system_disk_category
system_disk_size = var.system_disk_size
password = var.instance_password
vswitch_id = alicloud_vswitch.main.id
security_groups = [alicloud_security_group.main.id]
internet_max_bandwidth_out = var.internet_max_bandwidth_out
}
locals {
# Menginstal dan mengonfigurasi Dify
deploy_dify = base64encode(<<-EOF
#!/bin/bash
# Skrip instalasi otomatis Dify
set -e
# Fungsi log
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> /var/log/dify-install.log
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# Penanganan kesalahan
error_exit() {
log "ERROR: $1"
exit 1
}
log "Memperbarui paket sistem..."
yum update -y || error_exit "Gagal memperbarui sistem."
yum install -y git
log "Menginstal Docker..."
sudo wget -O /etc/yum.repos.d/docker-ce.repo http://mirrors.cloud.aliyuncs.com/docker-ce/linux/centos/docker-ce.repo
sudo sed -i 's|https://mirrors.aliyun.com|http://mirrors.cloud.aliyuncs.com|g' /etc/yum.repos.d/docker-ce.repo
sudo yum -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
log "Menjalankan layanan Docker..."
systemctl start docker || error_exit "Gagal menjalankan Docker."
systemctl enable docker || error_exit "Gagal mengaktifkan Docker agar berjalan saat boot."
log "Membuat direktori aplikasi..."
mkdir -p /opt/dify
cd /opt/dify
git clone https://github.com/langgenius/dify.git . || error_exit "Gagal mengkloning dify."
log "Menyalin file konfigurasi lingkungan..."
cd docker
cp .env.example .env || error_exit "Gagal menyalin file konfigurasi lingkungan."
log "Menjalankan layanan Dify..."
docker compose up -d || error_exit "Gagal menjalankan layanan Dify."
log "Instalasi Dify selesai!"
log "URL akses: http://$(curl -s ipinfo.io/ip):80"
log "Akun administrator default harus dibuat saat kunjungan pertama."
EOF
)
}
resource "alicloud_ecs_command" "deploy_dify" {
name = "deploy_dify"
type = "RunShellScript"
command_content = local.deploy_dify
timeout = 600
working_dir = "/root"
}
resource "alicloud_ecs_invocation" "invocation" {
instance_id = [alicloud_instance.dify.id]
command_id = alicloud_ecs_command.deploy_dify.id
timeouts {
create = "10m"
}
}
# Mendapatkan informasi instance
data "alicloud_instances" "dify" {
ids = [alicloud_instance.dify.id]
depends_on = [alicloud_instance.dify]
}