- 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.
186 lines
7.6 KiB
HCL
186 lines
7.6 KiB
HCL
# Networking Module for VM Deployment (Phase 1)
|
|
# Creates VNet, subnets, NSGs for VM-based deployment
|
|
|
|
# Virtual Network
|
|
resource "azurerm_virtual_network" "main" {
|
|
name = "${var.cluster_name}-vnet"
|
|
address_space = [var.vnet_address_space]
|
|
location = var.location
|
|
resource_group_name = var.resource_group_name
|
|
|
|
tags = merge(var.tags, {
|
|
Purpose = "Networking"
|
|
})
|
|
}
|
|
|
|
# Subnet for VMs
|
|
resource "azurerm_subnet" "vm" {
|
|
name = "${var.cluster_name}-vm-subnet"
|
|
resource_group_name = var.resource_group_name
|
|
virtual_network_name = azurerm_virtual_network.main.name
|
|
address_prefixes = [var.subnet_address_prefix]
|
|
|
|
service_endpoints = ["Microsoft.Storage", "Microsoft.KeyVault"]
|
|
}
|
|
|
|
# Network Security Group for VMs
|
|
resource "azurerm_network_security_group" "vm" {
|
|
name = "${var.cluster_name}-vm-nsg"
|
|
location = var.location
|
|
resource_group_name = var.resource_group_name
|
|
|
|
# Allow SSH (restrict to specific IPs in production)
|
|
security_rule {
|
|
name = "AllowSSH"
|
|
priority = 1000
|
|
direction = "Inbound"
|
|
access = "Allow"
|
|
protocol = "Tcp"
|
|
source_port_range = "*"
|
|
destination_port_range = "22"
|
|
source_address_prefix = length(var.allowed_ssh_ips) > 0 ? null : "*"
|
|
source_address_prefixes = length(var.allowed_ssh_ips) > 0 ? var.allowed_ssh_ips : null
|
|
destination_address_prefix = "*"
|
|
description = length(var.allowed_ssh_ips) > 0 ? "Allow SSH access from specified IPs" : "Allow SSH access from anywhere (WARNING: Not secure for production)"
|
|
}
|
|
|
|
# Allow P2P (Besu) - TCP (only for Besu nodes, not Nginx proxy)
|
|
dynamic "security_rule" {
|
|
for_each = var.enable_besu_rules ? [1] : []
|
|
content {
|
|
name = "AllowP2PTCP"
|
|
priority = 1001
|
|
direction = "Inbound"
|
|
access = "Allow"
|
|
protocol = "Tcp"
|
|
source_port_range = "*"
|
|
destination_port_range = "30303"
|
|
source_address_prefix = length(var.allowed_p2p_ips) > 0 ? null : "*"
|
|
source_address_prefixes = length(var.allowed_p2p_ips) > 0 ? var.allowed_p2p_ips : null
|
|
destination_address_prefix = "*"
|
|
description = length(var.allowed_p2p_ips) > 0 ? "Allow Besu P2P TCP from specified IPs" : "Allow Besu P2P TCP from anywhere (WARNING: Not secure for production)"
|
|
}
|
|
}
|
|
|
|
# Allow P2P (Besu) - UDP (only for Besu nodes, not Nginx proxy)
|
|
dynamic "security_rule" {
|
|
for_each = var.enable_besu_rules ? [1] : []
|
|
content {
|
|
name = "AllowP2PUDP"
|
|
priority = 1002
|
|
direction = "Inbound"
|
|
access = "Allow"
|
|
protocol = "Udp"
|
|
source_port_range = "*"
|
|
destination_port_range = "30303"
|
|
source_address_prefix = length(var.allowed_p2p_ips) > 0 ? null : "*"
|
|
source_address_prefixes = length(var.allowed_p2p_ips) > 0 ? var.allowed_p2p_ips : null
|
|
destination_address_prefix = "*"
|
|
description = length(var.allowed_p2p_ips) > 0 ? "Allow Besu P2P UDP from specified IPs" : "Allow Besu P2P UDP from anywhere (WARNING: Not secure for production)"
|
|
}
|
|
}
|
|
|
|
# Allow RPC HTTP (from Nginx proxy via VPN/ExpressRoute)
|
|
# NOTE: Backend VMs use private IPs only. Nginx proxy connects via VPN/ExpressRoute.
|
|
# Restrict to Nginx proxy private IP subnet once VPN is deployed.
|
|
# Only for Besu nodes, not Nginx proxy
|
|
dynamic "security_rule" {
|
|
for_each = var.enable_besu_rules ? [1] : []
|
|
content {
|
|
name = "AllowRPCHTTP"
|
|
priority = 1003
|
|
direction = "Inbound"
|
|
access = "Allow"
|
|
protocol = "Tcp"
|
|
source_port_range = "*"
|
|
destination_port_range = "8545"
|
|
source_address_prefix = length(var.allowed_rpc_ips) > 0 ? null : "*"
|
|
source_address_prefixes = length(var.allowed_rpc_ips) > 0 ? var.allowed_rpc_ips : null
|
|
destination_address_prefix = "*"
|
|
description = length(var.allowed_rpc_ips) > 0 ? "Allow RPC HTTP from specified IPs (Nginx proxy subnet or Cloudflare Tunnel IPs)" : "Allow RPC HTTP from anywhere (WARNING: Not secure for production)"
|
|
}
|
|
}
|
|
|
|
# Allow RPC WebSocket (from Nginx proxy via VPN/ExpressRoute)
|
|
# NOTE: Backend VMs use private IPs only. Nginx proxy connects via VPN/ExpressRoute.
|
|
# Restrict to Nginx proxy private IP subnet once VPN is deployed.
|
|
# Only for Besu nodes, not Nginx proxy
|
|
dynamic "security_rule" {
|
|
for_each = var.enable_besu_rules ? [1] : []
|
|
content {
|
|
name = "AllowRPCWS"
|
|
priority = 1004
|
|
direction = "Inbound"
|
|
access = "Allow"
|
|
protocol = "Tcp"
|
|
source_port_range = "*"
|
|
destination_port_range = "8546"
|
|
source_address_prefix = length(var.allowed_rpc_ips) > 0 ? null : "*"
|
|
source_address_prefixes = length(var.allowed_rpc_ips) > 0 ? var.allowed_rpc_ips : null
|
|
destination_address_prefix = "*"
|
|
description = length(var.allowed_rpc_ips) > 0 ? "Allow RPC WebSocket from specified IPs (Nginx proxy subnet or Cloudflare Tunnel IPs)" : "Allow RPC WebSocket from anywhere (WARNING: Not secure for production)"
|
|
}
|
|
}
|
|
|
|
# Allow Metrics (only for Besu nodes, not Nginx proxy)
|
|
dynamic "security_rule" {
|
|
for_each = var.enable_besu_rules ? [1] : []
|
|
content {
|
|
name = "AllowMetrics"
|
|
priority = 1005
|
|
direction = "Inbound"
|
|
access = "Allow"
|
|
protocol = "Tcp"
|
|
source_port_range = "*"
|
|
destination_port_range = "9545"
|
|
source_address_prefix = length(var.allowed_metrics_ips) > 0 ? null : "*"
|
|
source_address_prefixes = length(var.allowed_metrics_ips) > 0 ? var.allowed_metrics_ips : null
|
|
destination_address_prefix = "*"
|
|
description = length(var.allowed_metrics_ips) > 0 ? "Allow Prometheus metrics from specified IPs" : "Allow Prometheus metrics from anywhere (WARNING: Not secure for production)"
|
|
}
|
|
}
|
|
|
|
# Allow outbound internet access
|
|
security_rule {
|
|
name = "AllowOutboundInternet"
|
|
priority = 2000
|
|
direction = "Outbound"
|
|
access = "Allow"
|
|
protocol = "*"
|
|
source_port_range = "*"
|
|
destination_port_range = "*"
|
|
source_address_prefix = "*"
|
|
destination_address_prefix = "*"
|
|
description = "Allow outbound internet access"
|
|
}
|
|
|
|
tags = merge(var.tags, {
|
|
Purpose = "Network-Security"
|
|
})
|
|
}
|
|
|
|
# Associate NSG with VM subnet (only if subnet_nsg_enabled is true)
|
|
# For Nginx proxy subnet, we don't need subnet-level NSG (NIC-level NSG is sufficient)
|
|
resource "azurerm_subnet_network_security_group_association" "vm" {
|
|
count = var.subnet_nsg_enabled ? 1 : 0
|
|
subnet_id = azurerm_subnet.vm.id
|
|
network_security_group_id = azurerm_network_security_group.vm.id
|
|
}
|
|
|
|
# Outputs
|
|
output "vm_subnet_id" {
|
|
value = azurerm_subnet.vm.id
|
|
description = "Subnet ID for VMs"
|
|
}
|
|
|
|
output "vm_nsg_id" {
|
|
value = azurerm_network_security_group.vm.id
|
|
description = "Network Security Group ID for VMs"
|
|
}
|
|
|
|
output "vnet_id" {
|
|
value = azurerm_virtual_network.main.id
|
|
description = "Virtual Network ID"
|
|
}
|
|
|