#!/usr/bin/env bash # One-time bootstrap for a MuseHub EC2 instance. # # Installs AWS CLI v2 on the instance via SSM so that deploy.sh can # authenticate with ECR (aws ecr get-login-password). # # Run this once per instance — staging and prod each need it. # After this, all deploys go through deploy/push.sh. # # Usage: # bash deploy/bootstrap-instance.sh staging # bash deploy/bootstrap-instance.sh prod set -euo pipefail REGION="us-east-1" STAGING_INSTANCE="i-07547cd20bee2dea5" PROD_INSTANCE="i-0855d6efe7fa1a49d" case "${1:-}" in staging) INSTANCE_ID="$STAGING_INSTANCE"; ENV="staging" ;; prod) INSTANCE_ID="$PROD_INSTANCE"; ENV="prod" ;; *) echo "Usage: bash deploy/bootstrap-instance.sh [staging|prod]" exit 1 ;; esac log() { echo "[bootstrap] $*"; } die() { echo "[bootstrap] ERROR: $*" >&2; exit 1; } log "Bootstrapping $ENV ($INSTANCE_ID)..." CMD_ID=$(aws ssm send-command \ --region "$REGION" \ --instance-ids "$INSTANCE_ID" \ --document-name "AWS-RunShellScript" \ --parameters 'commands=[ "if command -v aws >/dev/null 2>&1; then echo \"[bootstrap] AWS CLI already installed: $(aws --version)\"; aws ecr get-login-password --region us-east-1 | sudo docker login --username AWS --password-stdin 992382692655.dkr.ecr.us-east-1.amazonaws.com && echo \"[bootstrap] ECR login OK.\"; exit 0; fi", "echo \"[bootstrap] Installing dependencies...\"", "sudo apt-get install -y unzip curl 2>&1 | tail -2", "echo \"[bootstrap] Installing AWS CLI v2...\"", "cd /tmp && curl -fsSL https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o awscliv2.zip && unzip -q awscliv2.zip && sudo ./aws/install && rm -rf awscliv2.zip aws/", "echo \"[bootstrap] Installed: $(aws --version)\"", "echo \"[bootstrap] Verifying ECR access...\"", "aws ecr get-login-password --region us-east-1 | sudo docker login --username AWS --password-stdin 992382692655.dkr.ecr.us-east-1.amazonaws.com && echo \"[bootstrap] ECR login OK.\"", "echo \"[bootstrap] Done.\"" ]' \ --comment "musehub bootstrap: install AWS CLI" \ --timeout-seconds 300 \ --query "Command.CommandId" \ --output text) log "SSM command ID: $CMD_ID" log "Waiting for bootstrap to complete..." for i in $(seq 1 60); do sleep 5 STATUS=$(aws ssm get-command-invocation \ --region "$REGION" \ --command-id "$CMD_ID" \ --instance-id "$INSTANCE_ID" \ --query "Status" \ --output text 2>/dev/null || echo "Pending") case "$STATUS" in Success) log "✅ Bootstrap complete." echo "" aws ssm get-command-invocation \ --region "$REGION" \ --command-id "$CMD_ID" \ --instance-id "$INSTANCE_ID" \ --query "StandardOutputContent" \ --output text 2>/dev/null || true exit 0 ;; Failed|Cancelled|TimedOut) log "❌ Bootstrap FAILED (status: $STATUS)" aws ssm get-command-invocation \ --region "$REGION" \ --command-id "$CMD_ID" \ --instance-id "$INSTANCE_ID" \ --query "[StandardOutputContent, StandardErrorContent]" \ --output text 2>/dev/null || true exit 1 ;; *) printf "." ;; esac done die "Bootstrap timed out. Check SSM command: $CMD_ID"