#cloud-config # Cloud-init configuration for Besu node setup # This script installs Docker, configures the node, and starts Besu package_update: true package_upgrade: true packages: - apt-transport-https - ca-certificates - curl - gnupg - lsb-release - jq - wget - unzip - azure-cli write_files: - path: /opt/besu/setup.sh content: | #!/bin/bash set -e NODE_TYPE="${node_type}" NODE_INDEX="${node_index}" CLUSTER_NAME="${cluster_name}" KEY_VAULT_ID="${key_vault_id}" GENESIS_FILE_PATH="${genesis_file_path}" ADMIN_USERNAME="${admin_username}" echo "Setting up Besu node: $NODE_TYPE-$NODE_INDEX" # Install Docker if ! command -v docker &> /dev/null; then echo "Installing Docker..." curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null apt-get update apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin systemctl enable docker systemctl start docker usermod -aG docker $ADMIN_USERNAME fi # Install Azure CLI (if not already installed) if ! command -v az &> /dev/null; then echo "Installing Azure CLI..." curl -sL https://aka.ms/InstallAzureCLIDeb | bash fi # Create directories mkdir -p /opt/besu/{data,config,keys,logs} chown -R $ADMIN_USERNAME:$ADMIN_USERNAME /opt/besu # Download genesis file from storage (if URL provided) if [ -n "$GENESIS_FILE_PATH" ] && [[ "$GENESIS_FILE_PATH" == http* ]]; then echo "Downloading genesis file from $GENESIS_FILE_PATH..." wget -q -O /opt/besu/config/genesis.json "$GENESIS_FILE_PATH" || echo "Failed to download genesis file" fi # Configure Azure CLI authentication (Managed Identity) if [ -n "$KEY_VAULT_ID" ]; then echo "Configuring Azure authentication for Key Vault access..." # VMs use Managed Identity for Key Vault access # Azure CLI will use Managed Identity automatically fi # Download validator keys from Key Vault (if validator) if [ "$NODE_TYPE" == "validator" ] && [ -n "$KEY_VAULT_ID" ]; then echo "Downloading validator keys from Key Vault..." # Extract key vault name from ID KEY_VAULT_NAME=$(echo "$KEY_VAULT_ID" | sed 's/.*\/\([^/]*\)$/\1/') # Download keys using Azure CLI with Managed Identity # az keyvault secret show --vault-name "$KEY_VAULT_NAME" --name "validator-key-$NODE_INDEX" --query value -o tsv > /opt/besu/keys/validator-key.txt || echo "Failed to download key" fi # Ensure directories have correct permissions chown -R $ADMIN_USERNAME:$ADMIN_USERNAME /opt/besu echo "Setup complete!" permissions: '0755' owner: root:root - path: /opt/besu/docker-compose.yml content: | version: '3.8' services: besu: image: hyperledger/besu:23.10.0 container_name: besu-${node_type}-${node_index} restart: unless-stopped user: "${admin_username}" volumes: - /opt/besu/data:/data - /opt/besu/config:/config - /opt/besu/keys:/keys:ro - /opt/besu/logs:/logs ports: - "9545:9545" # Metrics ${node_type == "validator" || node_type == "sentry" ? "- \"30303:30303\" # P2P TCP\n - \"30303:30303/udp\" # P2P UDP" : ""} ${node_type == "rpc" ? "- \"8545:8545\" # RPC HTTP\n - \"8546:8546\" # WebSocket" : ""} command: - /opt/besu/bin/besu - --config-file=/config/besu-config.toml environment: - BESU_OPTS=-Xmx4g -Xms4g networks: - besu-network logging: driver: "json-file" options: max-size: "10m" max-file: "3" healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9545/metrics"] interval: 30s timeout: 10s retries: 3 start_period: 120s networks: besu-network: driver: bridge permissions: '0644' owner: ${admin_username}:${admin_username} - path: /etc/systemd/system/besu.service content: | [Unit] Description=Besu Node Service After=docker.service Requires=docker.service [Service] Type=oneshot RemainAfterExit=yes WorkingDirectory=/opt/besu ExecStart=/usr/bin/docker compose up -d ExecStop=/usr/bin/docker compose down Restart=on-failure RestartSec=10 User=${admin_username} Group=${admin_username} [Install] WantedBy=multi-user.target permissions: '0644' owner: root:root runcmd: - /opt/besu/setup.sh - systemctl daemon-reload - systemctl enable besu.service - systemctl start besu.service final_message: "Besu node setup complete. Node type: ${node_type}, Index: ${node_index}"