Files
smom-dbis-138/terraform/phases/phase2/phase2-main.tf
defiQUG 1fb7266469 Add Oracle Aggregator and CCIP Integration
- Introduced Aggregator.sol for Chainlink-compatible oracle functionality, including round-based updates and access control.
- Added OracleWithCCIP.sol to extend Aggregator with CCIP cross-chain messaging capabilities.
- Created .gitmodules to include OpenZeppelin contracts as a submodule.
- Developed a comprehensive deployment guide in NEXT_STEPS_COMPLETE_GUIDE.md for Phase 2 and smart contract deployment.
- Implemented Vite configuration for the orchestration portal, supporting both Vue and React frameworks.
- Added server-side logic for the Multi-Cloud Orchestration Portal, including API endpoints for environment management and monitoring.
- Created scripts for resource import and usage validation across non-US regions.
- Added tests for CCIP error handling and integration to ensure robust functionality.
- Included various new files and directories for the orchestration portal and deployment scripts.
2025-12-12 14:57:48 -08:00

182 lines
6.1 KiB
HCL

# Phase 2: Docker Compose Deployment - 5 US Commercial Azure Regions
# DeFi Oracle Meta Mainnet (ChainID 138)
#
# Architecture:
# - Deploys multi-service docker-compose stacks to Phase 1 VMs
# - Each region gets a region-specific docker-compose file
# - Services: Besu + FireFly + Cacti + Chainlink + Databases + Monitoring
#
# NOTE: Phase 1 must be deployed first. Phase 2 deploys docker-compose files to existing VMs.
terraform {
required_version = ">= 1.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
null = {
source = "hashicorp/null"
version = "~> 3.0"
}
local = {
source = "hashicorp/local"
version = "~> 2.0"
}
}
}
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = var.environment == "prod" ? true : false
}
}
}
# Local values for configuration
locals {
cloud_provider = "az"
env_codes = {
prod = "p"
dev = "d"
test = "t"
staging = "s"
}
env_code = local.env_codes[var.environment]
# Region to docker-compose file mapping
region_compose_map = {
centralus = "docker-compose.cus.yml"
eastus = "docker-compose.eus.yml"
eastus2 = "docker-compose.eus2.yml"
westus = "docker-compose.wus.yml"
westus2 = "docker-compose.wus2.yml"
}
# Extract region from phase1_vm_info keys
regions = keys(var.phase1_vm_info)
# Common tags
common_tags = merge(var.tags, {
Environment = var.environment
CostCenter = "Blockchain"
Owner = "DevOps Team"
NamingConvention = "az-env-region-resource-instance"
DeploymentPhase = "phase2"
Project = "DeFi Oracle Meta Mainnet"
ChainID = "138"
})
}
# Create deployment directory structure on VMs and copy docker-compose files
resource "null_resource" "deploy_docker_compose" {
for_each = var.phase1_vm_info
triggers = {
# Trigger when compose file changes or VM info changes
compose_file_hash = filemd5("${var.docker_compose_source_path}/${local.region_compose_map[each.value.region]}")
# Use VM name, resource group, and IPs to create unique trigger
vm_identifier = "${each.value.resource_group}/${each.value.vm_names[0]}/${join(",", each.value.private_ips)}/${join(",", each.value.public_ips)}"
}
# Determine connection IP (prefer private IP, fallback to public IP)
# NOTE: This Terraform should be run from the Nginx proxy host (20.160.58.99)
# where direct access to private IPs is available
connection {
type = "ssh"
user = var.vm_admin_username
private_key = file(var.ssh_private_key_path)
host = length(each.value.private_ips) > 0 ? each.value.private_ips[0] : (length(each.value.public_ips) > 0 ? each.value.public_ips[0] : null)
timeout = "5m"
}
# Step 1: Create directories for docker-compose and volume mounts
provisioner "remote-exec" {
inline = [
"sudo mkdir -p /opt/docker-compose",
"sudo mkdir -p /opt/besu/{data,config,keys,logs}",
"sudo mkdir -p /opt/firefly/{postgres,postgres-primary,postgres-replica}",
"sudo mkdir -p /opt/cacti/{postgres,postgres-primary}",
"sudo mkdir -p /opt/prometheus",
"sudo mkdir -p /opt/grafana",
"sudo mkdir -p /opt/grafana-logs",
"sudo mkdir -p /opt/alertmanager",
"sudo mkdir -p /opt/loki/{data,config}",
"sudo mkdir -p /opt/ipfs/data",
"sudo mkdir -p /opt/promtail",
"sudo chown -R ${var.vm_admin_username}:${var.vm_admin_username} /opt/docker-compose",
"sudo chown -R ${var.vm_admin_username}:${var.vm_admin_username} /opt/besu",
"sudo chown -R ${var.vm_admin_username}:${var.vm_admin_username} /opt/firefly",
"sudo chown -R ${var.vm_admin_username}:${var.vm_admin_username} /opt/cacti",
"sudo chown -R ${var.vm_admin_username}:${var.vm_admin_username} /opt/prometheus",
"sudo chown -R ${var.vm_admin_username}:${var.vm_admin_username} /opt/grafana",
"sudo chown -R ${var.vm_admin_username}:${var.vm_admin_username} /opt/grafana-logs",
"sudo chown -R ${var.vm_admin_username}:${var.vm_admin_username} /opt/alertmanager",
"sudo chown -R ${var.vm_admin_username}:${var.vm_admin_username} /opt/loki",
"sudo chown -R ${var.vm_admin_username}:${var.vm_admin_username} /opt/ipfs",
"sudo chown -R ${var.vm_admin_username}:${var.vm_admin_username} /opt/promtail",
]
}
# Step 2: Copy docker-compose file to VM
provisioner "file" {
source = "${var.docker_compose_source_path}/${local.region_compose_map[each.value.region]}"
destination = "/tmp/docker-compose.yml"
}
# Step 3: Move file to final location and set permissions
provisioner "remote-exec" {
inline = [
"mv /tmp/docker-compose.yml /opt/docker-compose/docker-compose.yml",
"chmod 644 /opt/docker-compose/docker-compose.yml",
"chown ${var.vm_admin_username}:${var.vm_admin_username} /opt/docker-compose/docker-compose.yml",
]
}
}
# Create systemd service file for docker-compose stack
resource "null_resource" "create_systemd_service" {
for_each = var.phase1_vm_info
triggers = {
compose_deployed = null_resource.deploy_docker_compose[each.key].id
}
connection {
type = "ssh"
user = var.vm_admin_username
private_key = file(var.ssh_private_key_path)
host = length(each.value.private_ips) > 0 ? each.value.private_ips[0] : (length(each.value.public_ips) > 0 ? each.value.public_ips[0] : null)
timeout = "5m"
}
# Create systemd service file
provisioner "file" {
content = templatefile("${path.module}/templates/phase2-stack.service.tpl", {
admin_username = var.vm_admin_username
})
destination = "/tmp/phase2-stack.service"
}
# Install systemd service
provisioner "remote-exec" {
inline = [
"sudo mv /tmp/phase2-stack.service /etc/systemd/system/phase2-stack.service",
"sudo chmod 644 /etc/systemd/system/phase2-stack.service",
"sudo systemctl daemon-reload",
"sudo systemctl enable phase2-stack.service",
"# Service will be started manually or via separate apply"
]
}
depends_on = [
null_resource.deploy_docker_compose
]
}