provider "alicloud" { region = var.region } variable "region" { description = "The Alibaba Cloud region" type = string default = "cn-hongkong" } variable "instance_type" { description = "The ECS instance type" type = string default = "ecs.c9i.xlarge" validation { condition = can(regex("^ecs\\.", var.instance_type)) error_message = "The instance type must start with 'ecs.'" } } variable "system_disk_category" { description = "The system disk type" type = string default = "cloud_essd" validation { condition = contains(["cloud_efficiency", "cloud_ssd", "cloud_essd"], var.system_disk_category) error_message = "The system disk type must be one of cloud_efficiency, cloud_ssd, or cloud_essd." } } variable "system_disk_size" { description = "The system disk size in GB" type = number default = 40 validation { condition = var.system_disk_size >= 20 && var.system_disk_size <= 500 error_message = "The system disk size must be between 20 GB and 500 GB." } } variable "instance_password" { description = "The password for the ECS instance. It must be at least 8 characters long and contain an uppercase letter, a lowercase letter, and a number." 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 = "The password must be at least 8 characters long and contain an uppercase letter, a lowercase letter, and a number." } } variable "vpc_cidr" { description = "The CIDR block for the VPC" type = string default = "192.168.0.0/16" } variable "vswitch_cidr" { description = "The CIDR block for the vSwitch" type = string default = "192.168.1.0/24" } variable "project_name" { description = "The project name, used for naming resources" type = string default = "dify-deployment" } variable "internet_max_bandwidth_out" { description = "The maximum public bandwidth in Mbps" type = number default = 5 validation { condition = var.internet_max_bandwidth_out >= 1 && var.internet_max_bandwidth_out <= 200 error_message = "The public bandwidth must be between 1 Mbps and 200 Mbps." } } data "alicloud_zones" "default" { available_disk_category = var.system_disk_category available_resource_creation = "VSwitch" available_instance_type = var.instance_type } # Get the latest CentOS 7 image data "alicloud_images" "centos" { owners = "system" name_regex = "^centos_7" most_recent = true instance_type = var.instance_type } # Create a VPC resource "alicloud_vpc" "main" { vpc_name = "${var.project_name}-vpc" cidr_block = var.vpc_cidr } # Create a 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" } # Create a security group resource "alicloud_security_group" "main" { security_group_name = "${var.project_name}-sg" description = "Security group for Dify deployment" vpc_id = alicloud_vpc.main.id } # Security group rule - 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 = "Allow HTTP traffic" } # Security group rule - 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 = "Allow SSH traffic" } # Security group rule - 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 = "Allow HTTPS traffic" } # Create an ECS instance 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 { # Install and configure Dify deploy_dify = base64encode(<<-EOF #!/bin/bash # Dify auto-installation script set -e # Log function log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> /var/log/dify-install.log echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" } # Error handling error_exit() { log "ERROR: $1" exit 1 } log "Updating system packages..." yum update -y || error_exit "Failed to update system." yum install -y git log "Installing 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 "Starting Docker service..." systemctl start docker || error_exit "Failed to start Docker." systemctl enable docker || error_exit "Failed to enable Docker to start on boot." log "Creating application directory..." mkdir -p /opt/dify cd /opt/dify git clone https://github.com/langgenius/dify.git . || error_exit "Failed to clone dify." log "Copying environment configuration file..." cd docker cp .env.example .env || error_exit "Failed to copy environment configuration file." log "Starting Dify service..." docker compose up -d || error_exit "Failed to start Dify service." log "Dify installation complete!" log "Access URL: http://$(curl -s ipinfo.io/ip):80" log "The default administrator account must be created on the first visit." 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" } } # Get instance information data "alicloud_instances" "dify" { ids = [alicloud_instance.dify.id] depends_on = [alicloud_instance.dify] }