feat: CI/CD pipeline setup complete - Ansible playbooks updated, secrets configured, workflow ready
This commit is contained in:
284
deployment/scripts/deploy.sh
Executable file
284
deployment/scripts/deploy.sh
Executable file
@@ -0,0 +1,284 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Deploy Application to Production
|
||||
# This script deploys application updates using Ansible
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
DEPLOYMENT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
ANSIBLE_DIR="$DEPLOYMENT_DIR/ansible"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to print colored messages
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}ℹ️ $1${NC}"
|
||||
}
|
||||
|
||||
# Show usage
|
||||
usage() {
|
||||
echo "Usage: $0 <image-tag> [options]"
|
||||
echo ""
|
||||
echo "Arguments:"
|
||||
echo " image-tag Docker image tag to deploy (e.g., sha-abc123, v1.2.3, latest)"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --registry-user USER Docker registry username (default: from vault)"
|
||||
echo " --registry-pass PASS Docker registry password (default: from vault)"
|
||||
echo " --commit SHA Git commit SHA (default: auto-detect)"
|
||||
echo " --dry-run Run in check mode without making changes"
|
||||
echo " --help Show this help message"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 sha-abc123"
|
||||
echo " $0 v1.2.3 --commit abc123def"
|
||||
echo " $0 latest --dry-run"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
IMAGE_TAG=""
|
||||
REGISTRY_USER=""
|
||||
REGISTRY_PASS=""
|
||||
GIT_COMMIT=""
|
||||
DRY_RUN=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--registry-user)
|
||||
REGISTRY_USER="$2"
|
||||
shift 2
|
||||
;;
|
||||
--registry-pass)
|
||||
REGISTRY_PASS="$2"
|
||||
shift 2
|
||||
;;
|
||||
--commit)
|
||||
GIT_COMMIT="$2"
|
||||
shift 2
|
||||
;;
|
||||
--dry-run)
|
||||
DRY_RUN="--check"
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
if [ -z "$IMAGE_TAG" ]; then
|
||||
IMAGE_TAG="$1"
|
||||
shift
|
||||
else
|
||||
print_error "Unknown argument: $1"
|
||||
usage
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Validate image tag
|
||||
if [ -z "$IMAGE_TAG" ]; then
|
||||
print_error "Image tag is required"
|
||||
usage
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🚀 Deploy Application to Production"
|
||||
echo "===================================="
|
||||
echo ""
|
||||
|
||||
# Check if running from correct directory
|
||||
if [ ! -f "$ANSIBLE_DIR/ansible.cfg" ]; then
|
||||
print_error "Error: Must run from deployment/scripts directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$ANSIBLE_DIR"
|
||||
|
||||
# Auto-detect git commit if not provided
|
||||
if [ -z "$GIT_COMMIT" ]; then
|
||||
if command -v git &> /dev/null && [ -d "$(git rev-parse --git-dir 2>/dev/null)" ]; then
|
||||
GIT_COMMIT=$(git rev-parse --short HEAD)
|
||||
print_info "Auto-detected git commit: $GIT_COMMIT"
|
||||
else
|
||||
GIT_COMMIT="unknown"
|
||||
print_warning "Could not auto-detect git commit"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Generate deployment timestamp
|
||||
DEPLOYMENT_TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
|
||||
# Check Prerequisites
|
||||
echo "Checking Prerequisites..."
|
||||
echo "------------------------"
|
||||
|
||||
# Check Ansible
|
||||
if ! command -v ansible &> /dev/null; then
|
||||
print_error "Ansible is not installed"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Ansible installed"
|
||||
|
||||
# Check vault password
|
||||
if [ ! -f "$ANSIBLE_DIR/secrets/.vault_pass" ]; then
|
||||
print_error "Vault password file not found"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Vault password file found"
|
||||
|
||||
# Check playbook
|
||||
if [ ! -f "$ANSIBLE_DIR/playbooks/deploy-update.yml" ]; then
|
||||
print_error "Deploy playbook not found"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Deploy playbook found"
|
||||
|
||||
# Test connection
|
||||
print_info "Testing connection to production..."
|
||||
if ansible production -m ping > /dev/null 2>&1; then
|
||||
print_success "Connection successful"
|
||||
else
|
||||
print_error "Connection to production failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Deployment Summary
|
||||
echo "Deployment Summary"
|
||||
echo "-----------------"
|
||||
echo " Image Tag: $IMAGE_TAG"
|
||||
echo " Git Commit: $GIT_COMMIT"
|
||||
echo " Timestamp: $DEPLOYMENT_TIMESTAMP"
|
||||
echo " Registry: git.michaelschiemer.de:5000"
|
||||
if [ -n "$DRY_RUN" ]; then
|
||||
echo " Mode: DRY RUN (no changes will be made)"
|
||||
else
|
||||
echo " Mode: PRODUCTION DEPLOYMENT"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Confirmation
|
||||
if [ -z "$DRY_RUN" ]; then
|
||||
read -p "Proceed with deployment? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
print_warning "Deployment cancelled"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Build ansible-playbook command
|
||||
ANSIBLE_CMD="ansible-playbook $ANSIBLE_DIR/playbooks/deploy-update.yml"
|
||||
ANSIBLE_CMD="$ANSIBLE_CMD --vault-password-file $ANSIBLE_DIR/secrets/.vault_pass"
|
||||
ANSIBLE_CMD="$ANSIBLE_CMD -e image_tag=$IMAGE_TAG"
|
||||
ANSIBLE_CMD="$ANSIBLE_CMD -e git_commit_sha=$GIT_COMMIT"
|
||||
ANSIBLE_CMD="$ANSIBLE_CMD -e deployment_timestamp=$DEPLOYMENT_TIMESTAMP"
|
||||
|
||||
# Add registry credentials if provided
|
||||
if [ -n "$REGISTRY_USER" ]; then
|
||||
ANSIBLE_CMD="$ANSIBLE_CMD -e docker_registry_username=$REGISTRY_USER"
|
||||
fi
|
||||
if [ -n "$REGISTRY_PASS" ]; then
|
||||
ANSIBLE_CMD="$ANSIBLE_CMD -e docker_registry_password=$REGISTRY_PASS"
|
||||
fi
|
||||
|
||||
# Add dry-run flag if set
|
||||
if [ -n "$DRY_RUN" ]; then
|
||||
ANSIBLE_CMD="$ANSIBLE_CMD $DRY_RUN"
|
||||
fi
|
||||
|
||||
# Execute deployment
|
||||
print_info "Starting deployment..."
|
||||
echo ""
|
||||
|
||||
if eval "$ANSIBLE_CMD"; then
|
||||
echo ""
|
||||
if [ -z "$DRY_RUN" ]; then
|
||||
print_success "Deployment completed successfully!"
|
||||
else
|
||||
print_success "Dry run completed successfully!"
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
print_error "Deployment failed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Post-deployment checks
|
||||
if [ -z "$DRY_RUN" ]; then
|
||||
echo "Post-Deployment Checks"
|
||||
echo "---------------------"
|
||||
|
||||
SSH_KEY="$HOME/.ssh/production"
|
||||
|
||||
# Check service status
|
||||
print_info "Checking service status..."
|
||||
ssh -i "$SSH_KEY" deploy@94.16.110.151 "docker service ls --filter name=app_" || true
|
||||
echo ""
|
||||
|
||||
# Show recent logs
|
||||
print_info "Recent application logs:"
|
||||
ssh -i "$SSH_KEY" deploy@94.16.110.151 "docker service logs --tail 20 app_app" || true
|
||||
echo ""
|
||||
|
||||
# Health check URL
|
||||
HEALTH_URL="https://michaelschiemer.de/health"
|
||||
print_info "Health check URL: $HEALTH_URL"
|
||||
echo ""
|
||||
|
||||
# Summary
|
||||
echo "✅ Deployment Complete!"
|
||||
echo "======================"
|
||||
echo ""
|
||||
echo "Deployed:"
|
||||
echo " Image: git.michaelschiemer.de:5000/framework:$IMAGE_TAG"
|
||||
echo " Commit: $GIT_COMMIT"
|
||||
echo " Timestamp: $DEPLOYMENT_TIMESTAMP"
|
||||
echo ""
|
||||
echo "Next Steps:"
|
||||
echo ""
|
||||
echo "1. Monitor application:"
|
||||
echo " ssh -i $SSH_KEY deploy@94.16.110.151 'docker service logs -f app_app'"
|
||||
echo ""
|
||||
echo "2. Check service status:"
|
||||
echo " ssh -i $SSH_KEY deploy@94.16.110.151 'docker service ps app_app'"
|
||||
echo ""
|
||||
echo "3. Test application:"
|
||||
echo " curl $HEALTH_URL"
|
||||
echo ""
|
||||
echo "4. Rollback if needed:"
|
||||
echo " $SCRIPT_DIR/rollback.sh"
|
||||
echo ""
|
||||
else
|
||||
echo "Dry Run Summary"
|
||||
echo "==============="
|
||||
echo ""
|
||||
echo "This was a dry run. No changes were made to production."
|
||||
echo ""
|
||||
echo "To deploy for real, run:"
|
||||
echo " $0 $IMAGE_TAG"
|
||||
echo ""
|
||||
fi
|
||||
330
deployment/scripts/rollback.sh
Executable file
330
deployment/scripts/rollback.sh
Executable file
@@ -0,0 +1,330 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Rollback Application Deployment
|
||||
# This script rolls back to a previous deployment using Ansible
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
DEPLOYMENT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
ANSIBLE_DIR="$DEPLOYMENT_DIR/ansible"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Function to print colored messages
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}ℹ️ $1${NC}"
|
||||
}
|
||||
|
||||
# Show usage
|
||||
usage() {
|
||||
echo "Usage: $0 [version] [options]"
|
||||
echo ""
|
||||
echo "Arguments:"
|
||||
echo " version Backup version to rollback to (e.g., 2025-01-28T15-30-00)"
|
||||
echo " If not provided, will rollback to previous version"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --list List available backup versions"
|
||||
echo " --dry-run Run in check mode without making changes"
|
||||
echo " --help Show this help message"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 # Rollback to previous version"
|
||||
echo " $0 2025-01-28T15-30-00 # Rollback to specific version"
|
||||
echo " $0 --list # List available backups"
|
||||
echo " $0 2025-01-28T15-30-00 --dry-run # Test rollback"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
ROLLBACK_VERSION=""
|
||||
LIST_BACKUPS=false
|
||||
DRY_RUN=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--list)
|
||||
LIST_BACKUPS=true
|
||||
shift
|
||||
;;
|
||||
--dry-run)
|
||||
DRY_RUN="--check"
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
usage
|
||||
;;
|
||||
*)
|
||||
if [ -z "$ROLLBACK_VERSION" ]; then
|
||||
ROLLBACK_VERSION="$1"
|
||||
shift
|
||||
else
|
||||
print_error "Unknown argument: $1"
|
||||
usage
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "🔄 Rollback Application Deployment"
|
||||
echo "==================================="
|
||||
echo ""
|
||||
|
||||
# Check if running from correct directory
|
||||
if [ ! -f "$ANSIBLE_DIR/ansible.cfg" ]; then
|
||||
print_error "Error: Must run from deployment/scripts directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$ANSIBLE_DIR"
|
||||
|
||||
SSH_KEY="$HOME/.ssh/production"
|
||||
DEPLOY_USER="deploy"
|
||||
DEPLOY_HOST="94.16.110.151"
|
||||
|
||||
# List available backups
|
||||
list_backups() {
|
||||
print_info "Fetching available backups from production server..."
|
||||
echo ""
|
||||
|
||||
if ! ssh -i "$SSH_KEY" "$DEPLOY_USER@$DEPLOY_HOST" \
|
||||
"ls -lt /home/deploy/backups/ 2>/dev/null" | tail -n +2; then
|
||||
print_error "Failed to list backups"
|
||||
print_info "Make sure backups exist on production server: /home/deploy/backups/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
print_info "To rollback to a specific version, run:"
|
||||
echo " $0 <version>"
|
||||
echo ""
|
||||
print_info "To rollback to previous version, run:"
|
||||
echo " $0"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Check Prerequisites
|
||||
check_prerequisites() {
|
||||
echo "Checking Prerequisites..."
|
||||
echo "------------------------"
|
||||
|
||||
# Check Ansible
|
||||
if ! command -v ansible &> /dev/null; then
|
||||
print_error "Ansible is not installed"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Ansible installed"
|
||||
|
||||
# Check vault password
|
||||
if [ ! -f "$ANSIBLE_DIR/secrets/.vault_pass" ]; then
|
||||
print_error "Vault password file not found"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Vault password file found"
|
||||
|
||||
# Check playbook
|
||||
if [ ! -f "$ANSIBLE_DIR/playbooks/rollback.yml" ]; then
|
||||
print_error "Rollback playbook not found"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Rollback playbook found"
|
||||
|
||||
# Test connection
|
||||
print_info "Testing connection to production..."
|
||||
if ansible production -m ping > /dev/null 2>&1; then
|
||||
print_success "Connection successful"
|
||||
else
|
||||
print_error "Connection to production failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Get current deployment info
|
||||
get_current_deployment() {
|
||||
print_info "Fetching current deployment information..."
|
||||
|
||||
CURRENT_IMAGE=$(ssh -i "$SSH_KEY" "$DEPLOY_USER@$DEPLOY_HOST" \
|
||||
"docker service inspect app_app --format '{{.Spec.TaskTemplate.ContainerSpec.Image}}' 2>/dev/null" || echo "unknown")
|
||||
|
||||
if [ "$CURRENT_IMAGE" != "unknown" ]; then
|
||||
print_info "Current deployment: $CURRENT_IMAGE"
|
||||
else
|
||||
print_warning "Could not determine current deployment"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Main logic
|
||||
if [ "$LIST_BACKUPS" = true ]; then
|
||||
list_backups
|
||||
fi
|
||||
|
||||
check_prerequisites
|
||||
get_current_deployment
|
||||
|
||||
# Show available backups
|
||||
echo "Available Backups"
|
||||
echo "----------------"
|
||||
ssh -i "$SSH_KEY" "$DEPLOY_USER@$DEPLOY_HOST" \
|
||||
"ls -lt /home/deploy/backups/ 2>/dev/null | tail -n +2 | head -10" || {
|
||||
print_warning "No backups found on production server"
|
||||
echo ""
|
||||
print_info "Backups are created automatically during deployments"
|
||||
print_info "You need at least one previous deployment to rollback"
|
||||
exit 1
|
||||
}
|
||||
echo ""
|
||||
|
||||
# Rollback Summary
|
||||
echo "Rollback Summary"
|
||||
echo "---------------"
|
||||
if [ -n "$ROLLBACK_VERSION" ]; then
|
||||
echo " Target Version: $ROLLBACK_VERSION"
|
||||
echo " Current Image: $CURRENT_IMAGE"
|
||||
else
|
||||
echo " Target Version: Previous deployment (most recent backup)"
|
||||
echo " Current Image: $CURRENT_IMAGE"
|
||||
fi
|
||||
if [ -n "$DRY_RUN" ]; then
|
||||
echo " Mode: DRY RUN (no changes will be made)"
|
||||
else
|
||||
echo " Mode: PRODUCTION ROLLBACK"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Confirmation
|
||||
if [ -z "$DRY_RUN" ]; then
|
||||
print_warning "⚠️ WARNING: This will rollback your production deployment!"
|
||||
echo ""
|
||||
read -p "Are you sure you want to proceed with rollback? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
print_warning "Rollback cancelled"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Build ansible-playbook command
|
||||
ANSIBLE_CMD="ansible-playbook $ANSIBLE_DIR/playbooks/rollback.yml"
|
||||
ANSIBLE_CMD="$ANSIBLE_CMD --vault-password-file $ANSIBLE_DIR/secrets/.vault_pass"
|
||||
|
||||
# Add version if specified
|
||||
if [ -n "$ROLLBACK_VERSION" ]; then
|
||||
ANSIBLE_CMD="$ANSIBLE_CMD -e rollback_to_version=$ROLLBACK_VERSION"
|
||||
fi
|
||||
|
||||
# Add dry-run flag if set
|
||||
if [ -n "$DRY_RUN" ]; then
|
||||
ANSIBLE_CMD="$ANSIBLE_CMD $DRY_RUN"
|
||||
fi
|
||||
|
||||
# Execute rollback
|
||||
print_info "Starting rollback..."
|
||||
echo ""
|
||||
|
||||
if eval "$ANSIBLE_CMD"; then
|
||||
echo ""
|
||||
if [ -z "$DRY_RUN" ]; then
|
||||
print_success "Rollback completed successfully!"
|
||||
else
|
||||
print_success "Dry run completed successfully!"
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
print_error "Rollback failed!"
|
||||
echo ""
|
||||
print_info "Check the Ansible output above for error details"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Post-rollback checks
|
||||
if [ -z "$DRY_RUN" ]; then
|
||||
echo "Post-Rollback Checks"
|
||||
echo "-------------------"
|
||||
|
||||
# Check service status
|
||||
print_info "Checking service status..."
|
||||
ssh -i "$SSH_KEY" "$DEPLOY_USER@$DEPLOY_HOST" "docker service ls --filter name=app_" || true
|
||||
echo ""
|
||||
|
||||
# Get new image
|
||||
NEW_IMAGE=$(ssh -i "$SSH_KEY" "$DEPLOY_USER@$DEPLOY_HOST" \
|
||||
"docker service inspect app_app --format '{{.Spec.TaskTemplate.ContainerSpec.Image}}' 2>/dev/null" || echo "unknown")
|
||||
|
||||
if [ "$NEW_IMAGE" != "unknown" ]; then
|
||||
print_info "Rolled back to: $NEW_IMAGE"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Show recent logs
|
||||
print_info "Recent application logs:"
|
||||
ssh -i "$SSH_KEY" "$DEPLOY_USER@$DEPLOY_HOST" "docker service logs --tail 20 app_app" || true
|
||||
echo ""
|
||||
|
||||
# Summary
|
||||
echo "✅ Rollback Complete!"
|
||||
echo "===================="
|
||||
echo ""
|
||||
echo "Rollback Details:"
|
||||
echo " From: $CURRENT_IMAGE"
|
||||
echo " To: $NEW_IMAGE"
|
||||
if [ -n "$ROLLBACK_VERSION" ]; then
|
||||
echo " Version: $ROLLBACK_VERSION"
|
||||
else
|
||||
echo " Version: Previous deployment"
|
||||
fi
|
||||
echo ""
|
||||
echo "Next Steps:"
|
||||
echo ""
|
||||
echo "1. Monitor application:"
|
||||
echo " ssh -i $SSH_KEY $DEPLOY_USER@$DEPLOY_HOST 'docker service logs -f app_app'"
|
||||
echo ""
|
||||
echo "2. Check service status:"
|
||||
echo " ssh -i $SSH_KEY $DEPLOY_USER@$DEPLOY_HOST 'docker service ps app_app'"
|
||||
echo ""
|
||||
echo "3. Test application:"
|
||||
echo " curl https://michaelschiemer.de/health"
|
||||
echo ""
|
||||
echo "4. If rollback didn't fix the issue, check available backups:"
|
||||
echo " $0 --list"
|
||||
echo ""
|
||||
else
|
||||
echo "Dry Run Summary"
|
||||
echo "==============="
|
||||
echo ""
|
||||
echo "This was a dry run. No changes were made to production."
|
||||
echo ""
|
||||
if [ -n "$ROLLBACK_VERSION" ]; then
|
||||
echo "To rollback for real, run:"
|
||||
echo " $0 $ROLLBACK_VERSION"
|
||||
else
|
||||
echo "To rollback for real, run:"
|
||||
echo " $0"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
211
deployment/scripts/setup-production.sh
Executable file
211
deployment/scripts/setup-production.sh
Executable file
@@ -0,0 +1,211 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Setup Production Server
|
||||
# This script performs initial production server setup with Ansible
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
DEPLOYMENT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
ANSIBLE_DIR="$DEPLOYMENT_DIR/ansible"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo ""
|
||||
echo "🚀 Production Server Setup"
|
||||
echo "=========================="
|
||||
echo ""
|
||||
|
||||
# Function to print colored messages
|
||||
print_success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
print_error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
print_warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
print_info() {
|
||||
echo -e "${BLUE}ℹ️ $1${NC}"
|
||||
}
|
||||
|
||||
# Check if running from correct directory
|
||||
if [ ! -f "$ANSIBLE_DIR/ansible.cfg" ]; then
|
||||
print_error "Error: Must run from deployment/scripts directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$ANSIBLE_DIR"
|
||||
|
||||
# Step 1: Check Prerequisites
|
||||
echo "Step 1: Checking Prerequisites"
|
||||
echo "------------------------------"
|
||||
|
||||
# Check Ansible installed
|
||||
if ! command -v ansible &> /dev/null; then
|
||||
print_error "Ansible is not installed"
|
||||
echo ""
|
||||
echo "Install Ansible:"
|
||||
echo " pip install ansible"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Ansible is installed: $(ansible --version | head -n1)"
|
||||
|
||||
# Check Ansible playbooks exist
|
||||
if [ ! -f "$ANSIBLE_DIR/playbooks/setup-production-secrets.yml" ]; then
|
||||
print_error "Ansible playbooks not found"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Ansible playbooks found"
|
||||
|
||||
# Check SSH key
|
||||
SSH_KEY="$HOME/.ssh/production"
|
||||
if [ ! -f "$SSH_KEY" ]; then
|
||||
print_warning "SSH key not found: $SSH_KEY"
|
||||
echo ""
|
||||
read -p "Do you want to create SSH key now? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
ssh-keygen -t ed25519 -f "$SSH_KEY" -C "ansible-deploy"
|
||||
chmod 600 "$SSH_KEY"
|
||||
chmod 644 "$SSH_KEY.pub"
|
||||
print_success "SSH key created"
|
||||
echo ""
|
||||
echo "📋 Public key:"
|
||||
cat "$SSH_KEY.pub"
|
||||
echo ""
|
||||
print_warning "You must add this public key to the production server:"
|
||||
echo " ssh-copy-id -i $SSH_KEY.pub deploy@94.16.110.151"
|
||||
echo ""
|
||||
read -p "Press ENTER after adding SSH key to server..."
|
||||
else
|
||||
print_error "SSH key is required for Ansible"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_success "SSH key found: $SSH_KEY"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 2: Setup Ansible Secrets
|
||||
echo "Step 2: Setup Ansible Secrets"
|
||||
echo "-----------------------------"
|
||||
|
||||
# Check if vault file exists
|
||||
if [ ! -f "$ANSIBLE_DIR/secrets/production.vault.yml" ]; then
|
||||
print_warning "Vault file not found"
|
||||
echo ""
|
||||
read -p "Do you want to run init-secrets.sh now? (Y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
|
||||
"$ANSIBLE_DIR/scripts/init-secrets.sh"
|
||||
else
|
||||
print_error "Vault file is required"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_success "Vault file exists"
|
||||
fi
|
||||
|
||||
# Check vault password file
|
||||
if [ ! -f "$ANSIBLE_DIR/secrets/.vault_pass" ]; then
|
||||
print_error "Vault password file not found: secrets/.vault_pass"
|
||||
echo ""
|
||||
echo "Run init-secrets.sh to create vault password file:"
|
||||
echo " $ANSIBLE_DIR/scripts/init-secrets.sh"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Vault password file found"
|
||||
|
||||
# Verify vault can be decrypted
|
||||
if ! ansible-vault view "$ANSIBLE_DIR/secrets/production.vault.yml" \
|
||||
--vault-password-file "$ANSIBLE_DIR/secrets/.vault_pass" > /dev/null 2>&1; then
|
||||
print_error "Failed to decrypt vault file"
|
||||
echo "Check your vault password in: secrets/.vault_pass"
|
||||
exit 1
|
||||
fi
|
||||
print_success "Vault file can be decrypted"
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 3: Test Connection
|
||||
echo "Step 3: Test Connection to Production"
|
||||
echo "-------------------------------------"
|
||||
|
||||
if ansible production -m ping 2>&1 | grep -q "SUCCESS"; then
|
||||
print_success "Connection to production server successful"
|
||||
else
|
||||
print_error "Connection to production server failed"
|
||||
echo ""
|
||||
echo "Troubleshooting steps:"
|
||||
echo "1. Test SSH manually: ssh -i $SSH_KEY deploy@94.16.110.151"
|
||||
echo "2. Verify SSH key is added: ssh-copy-id -i $SSH_KEY.pub deploy@94.16.110.151"
|
||||
echo "3. Check inventory file: cat $ANSIBLE_DIR/inventory/production.yml"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 4: Deploy Secrets to Production
|
||||
echo "Step 4: Deploy Secrets to Production"
|
||||
echo "------------------------------------"
|
||||
|
||||
read -p "Deploy secrets to production server? (Y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Nn]$ ]]; then
|
||||
print_info "Deploying secrets to production..."
|
||||
echo ""
|
||||
|
||||
if ansible-playbook "$ANSIBLE_DIR/playbooks/setup-production-secrets.yml" \
|
||||
--vault-password-file "$ANSIBLE_DIR/secrets/.vault_pass"; then
|
||||
print_success "Secrets deployed successfully"
|
||||
else
|
||||
print_error "Failed to deploy secrets"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_warning "Skipped secrets deployment"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Step 5: Verify Docker Services
|
||||
echo "Step 5: Verify Docker Services"
|
||||
echo "------------------------------"
|
||||
|
||||
print_info "Checking Docker services on production..."
|
||||
echo ""
|
||||
|
||||
ssh -i "$SSH_KEY" deploy@94.16.110.151 "docker node ls" || true
|
||||
echo ""
|
||||
ssh -i "$SSH_KEY" deploy@94.16.110.151 "docker service ls" || true
|
||||
|
||||
echo ""
|
||||
|
||||
# Summary
|
||||
echo ""
|
||||
echo "✅ Production Server Setup Complete!"
|
||||
echo "===================================="
|
||||
echo ""
|
||||
echo "Next Steps:"
|
||||
echo ""
|
||||
echo "1. Verify secrets are deployed:"
|
||||
echo " ssh -i $SSH_KEY deploy@94.16.110.151 'cat /home/deploy/secrets/.env'"
|
||||
echo ""
|
||||
echo "2. Deploy your application:"
|
||||
echo " $SCRIPT_DIR/deploy.sh <image-tag>"
|
||||
echo ""
|
||||
echo "3. Monitor deployment:"
|
||||
echo " ssh -i $SSH_KEY deploy@94.16.110.151 'docker service logs -f app_app'"
|
||||
echo ""
|
||||
echo "📖 For more information, see: $ANSIBLE_DIR/README.md"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user