diff --git a/deployments/infra/ami-cdk.go b/deployments/infra/ami-cdk.go index cc8f5bf1d..7d5d69483 100644 --- a/deployments/infra/ami-cdk.go +++ b/deployments/infra/ami-cdk.go @@ -1,7 +1,9 @@ package main import ( + "fmt" "github.com/aws/aws-cdk-go/awscdk/v2" + "github.com/aws/jsii-runtime-go" "github.com/trufnetwork/node/infra/stacks" "go.uber.org/zap" ) @@ -20,8 +22,12 @@ func main() { Region: nil, // CDK will auto-detect from AWS CLI config } - // Use explicit stack name to match GitHub workflow expectations - stackName := "AMI-Pipeline-default-Stack" + // Use stage-specific stack name for proper environment isolation + stage := app.Node().TryGetContext(jsii.String("stage")) + if stage == nil { + stage = "default" + } + stackName := fmt.Sprintf("AMI-Pipeline-%s-Stack", stage) _, amiExports := stacks.AmiPipelineStack( app, stackName, diff --git a/deployments/infra/stacks/ami_pipeline_stack.go b/deployments/infra/stacks/ami_pipeline_stack.go index 0f6f105cf..ea1a21114 100644 --- a/deployments/infra/stacks/ami_pipeline_stack.go +++ b/deployments/infra/stacks/ami_pipeline_stack.go @@ -248,8 +248,6 @@ phases: # Default values PRIVATE_KEY="" ENABLE_MCP=false - MCP_TRANSPORT="sse" - MCP_ACCESS_MODE="restricted" # Parse command line arguments while [[ $# -gt 0 ]]; do @@ -262,14 +260,6 @@ phases: ENABLE_MCP=true shift ;; - --mcp-transport) - MCP_TRANSPORT="$2" - shift 2 - ;; - --mcp-access-mode) - MCP_ACCESS_MODE="$2" - shift 2 - ;; *) echo "Unknown option $1" exit 1 @@ -277,7 +267,15 @@ phases: esac done - echo "Configuring TRUF.NETWORK node..." + # Check if this is a reconfiguration + RECONFIGURE=false + if [ -f /opt/tn/.env ]; then + RECONFIGURE=true + echo "Existing configuration detected. Reconfiguring node..." + else + echo "Configuring TRUF.NETWORK node..." + fi + echo "Network: mainnet (tn-v2.1)" echo "MCP enabled: $ENABLE_MCP" @@ -285,29 +283,67 @@ phases: CHAIN_ID="tn-v2.1" cd /opt/tn - # Create .env file + # Handle configuration (new or reconfigure) + if [ "$RECONFIGURE" = true ]; then + # Block private key changes during reconfiguration + if [ -n "$PRIVATE_KEY" ]; then + echo "❌ Error: Cannot change private key on existing node!" + echo "Private key changes would alter node identity and cause network issues." + echo "To change private key, you must deploy a fresh instance." + echo "" + echo "You can only reconfigure MCP settings:" + echo " sudo tn-node-configure --enable-mcp" + echo " sudo tn-node-configure # (disable MCP)" + exit 1 + fi + + # Preserve existing private key + if grep -q "TN_PRIVATE_KEY=" .env; then + EXISTING_KEY=$(grep "TN_PRIVATE_KEY=" .env | cut -d'=' -f2) + echo "Preserving existing node identity" + fi + + # Stop service for reconfiguration + echo "Stopping existing services..." + sudo systemctl stop tn-node || true + sudo -u tn docker compose down || true + fi + + # Create/update .env file cat > .env << ENVEOF CHAIN_ID=$CHAIN_ID ENVEOF - # Only set COMPOSE_PROFILES when MCP is enabled + # Handle MCP configuration if [ "$ENABLE_MCP" = true ]; then echo "COMPOSE_PROFILES=mcp" >> .env fi - # Handle private key if provided - if [ -n "$PRIVATE_KEY" ]; then - echo "Converting private key to nodekey.json..." + # Handle private key (only for initial configuration) + if [ "$RECONFIGURE" = false ] && [ -n "$PRIVATE_KEY" ]; then + echo "Using provided private key..." echo "TN_PRIVATE_KEY=$PRIVATE_KEY" >> .env - echo "Private key will be converted on container startup" + elif [ "$RECONFIGURE" = true ] && [ -n "$EXISTING_KEY" ]; then + echo "Preserving existing private key..." + echo "TN_PRIVATE_KEY=$EXISTING_KEY" >> .env + elif [ "$RECONFIGURE" = false ]; then + echo "No private key provided - node will generate new identity" fi + # Set correct ownership + sudo chown tn:tn .env + sudo chmod 600 .env + sudo chmod 750 /opt/tn # Enable and start the service sudo systemctl daemon-reload sudo systemctl enable tn-node sudo systemctl start tn-node - echo "TRUF.NETWORK node configuration complete!" + if [ "$RECONFIGURE" = true ]; then + echo "TRUF.NETWORK node reconfiguration complete!" + else + echo "TRUF.NETWORK node configuration complete!" + fi echo "Service status: $(sudo systemctl is-active tn-node)" if [ "$ENABLE_MCP" = true ]; then @@ -322,7 +358,7 @@ phases: inputs: commands: - | - sudo tee /usr/local/bin/update-node > /dev/null << 'EOF' + sudo tee /usr/local/bin/tn-node-update > /dev/null << 'EOF' #!/bin/bash set -e @@ -330,22 +366,102 @@ phases: cd /opt/tn # Pull latest images - sudo -u tn docker-compose pull + echo "Pulling latest images..." + sudo -u tn docker compose pull - # Restart services with new images - sudo -u tn docker-compose up -d + # Stop and recreate containers with new images + echo "Recreating containers with latest images..." + sudo -u tn docker compose up -d --force-recreate echo "Node updated successfully!" echo "Service status: $(sudo systemctl is-active tn-node)" EOF - - sudo chmod +x /usr/local/bin/update-node + - sudo chmod +x /usr/local/bin/tn-node-update - - name: EnableServices + - name: PrepareServices action: ExecuteBash inputs: commands: - sudo systemctl daemon-reload - - sudo systemctl enable tn-node + # Note: We do not enable tn-node immediately - we let users configure first + + - name: CreateWelcomeMessage + action: ExecuteBash + inputs: + commands: + - | + sudo tee /etc/motd > /dev/null << 'EOF' + + 🚀 Welcome to your TRUF.NETWORK Node! + + Your node is ready for configuration. Please run ONE of the following commands: + + # Basic setup (auto-generated private key, no MCP) + sudo tn-node-configure + + # With your own private key + sudo tn-node-configure --private-key "your-64-character-hex-key" + + # With MCP enabled for AI integration + sudo tn-node-configure --enable-mcp + + # Full configuration example + sudo tn-node-configure \ + --private-key "your-key" \ + --enable-mcp + + After configuration, your node will start automatically and begin syncing! + + 🤖 MCP (AI Integration) Setup: + 1. Configure node with --enable-mcp flag + 2. Open port 8000 in your AWS Security Group: + EC2 Console → Instance → Security → Edit inbound rules + Add: Custom TCP, Port 8000, Source 0.0.0.0/0 + 3. Access via: http://YOUR-PUBLIC-IP:8000/sse + + For help: https://docs.truf.network + EOF + + - | + # Create a one-time welcome script that shows on first SSH login + sudo tee /etc/profile.d/tn-welcome.sh > /dev/null << 'EOF' + #!/bin/bash + + # Only show welcome message if node is not configured yet + if [ ! -f /opt/tn/.env ] && [ "$USER" = "ubuntu" ]; then + echo "" + echo "🚀 Welcome to your TRUF.NETWORK Node!" + echo "" + echo "Your node is ready for configuration. Please run ONE of the following commands:" + echo "" + echo "# Basic setup (auto-generated private key, no MCP)" + echo "sudo tn-node-configure" + echo "" + echo "# With your own private key" + echo "sudo tn-node-configure --private-key \"your-64-character-hex-key\"" + echo "" + echo "# With MCP enabled for AI integration" + echo "sudo tn-node-configure --enable-mcp" + echo "" + echo "# Full configuration example" + echo "sudo tn-node-configure \\" + echo " --private-key \"your-key\" \\" + echo " --enable-mcp" + echo "" + echo "After configuration, your node will start automatically and begin syncing!" + echo "" + echo "🤖 MCP (AI Integration) Setup:" + echo "1. Configure node with --enable-mcp flag" + echo "2. Open port 8000 in your AWS Security Group:" + echo " EC2 Console → Instance → Security → Edit inbound rules" + echo " Add: Custom TCP, Port 8000, Source 0.0.0.0/0" + echo "3. Access via: http://YOUR-PUBLIC-IP:8000/sse" + echo "" + echo "For help: https://docs.truf.network" + echo "" + fi + EOF + - sudo chmod +x /etc/profile.d/tn-welcome.sh `), }) diff --git a/deployments/infra/stacks/docker-compose.template.yml b/deployments/infra/stacks/docker-compose.template.yml index 1ee704e08..4837ba7ad 100644 --- a/deployments/infra/stacks/docker-compose.template.yml +++ b/deployments/infra/stacks/docker-compose.template.yml @@ -19,7 +19,7 @@ services: retries: 12 tn-node: - image: ghcr.io/trufnetwork/node:sha-eb8d9f0 + image: ghcr.io/trufnetwork/node:latest container_name: tn-node entrypoint: "" volumes: @@ -54,7 +54,7 @@ services: [ -n \"$$PUBLIC_IP\" ] && EXTERNAL_FLAG=\"--p2p.external-address $$PUBLIC_IP:26656\" || EXTERNAL_FLAG=\"\" echo \"Detected public IP: $$PUBLIC_IP\" - /app/kwild setup init --genesis /opt/tn/configs/network/v2/genesis.json --root /root/.kwild-new --p2p.bootnodes \"4e0b5c952be7f26698dc1898ff3696ac30e990f25891aeaf88b0285eab4663e1#ed25519@node-1.mainnet.truf.network:26656,0c830b69790eaa09315826403c2008edc65b5c7132be9d4b7b4da825c2a166ae#ed25519@node-2.mainnet.truf.network:26656\" --state-sync.enable --state-sync.trusted-providers \"0c830b69790eaa09315826403c2008edc65b5c7132be9d4b7b4da825c2a166ae#ed25519@node-2.mainnet.truf.network:26656\" --rpc.private --db.host tn-postgres $$EXTERNAL_FLAG + /app/kwild setup init --genesis /opt/tn/configs/network/v2/genesis.json --root /root/.kwild-new --p2p.bootnodes \"4e0b5c952be7f26698dc1898ff3696ac30e990f25891aeaf88b0285eab4663e1#ed25519@node-1.mainnet.truf.network:26656,0c830b69790eaa09315826403c2008edc65b5c7132be9d4b7b4da825c2a166ae#ed25519@node-2.mainnet.truf.network:26656\" --state-sync.enable --state-sync.trusted-providers \"4e0b5c952be7f26698dc1898ff3696ac30e990f25891aeaf88b0285eab4663e1#ed25519@node-1.mainnet.truf.network:26656\" --rpc.private --db.host tn-postgres $$EXTERNAL_FLAG mkdir -p /root/.kwild cp /root/.kwild-new/* /root/.kwild/ rm -rf /root/.kwild-new @@ -83,10 +83,9 @@ services: postgres-mcp: image: ghcr.io/trufnetwork/postgres-mcp:latest container_name: tn-mcp + command: ["--transport=sse", "--access-mode=restricted", "--sse-host=0.0.0.0"] environment: - DATABASE_URI=postgresql://postgres@tn-postgres:5432/kwild - - MCP_ACCESS_MODE=restricted - - MCP_TRANSPORT=sse ports: - "8000:8000" depends_on: @@ -102,4 +101,5 @@ services: networks: tn-network: + name: tn-network driver: bridge \ No newline at end of file