650 lines
25 KiB
YAML
650 lines
25 KiB
YAML
---
|
|
# ============================================================================
|
|
# ENHANCED DOCKER DEPLOYMENT WITH AUTO-SCALING SUPPORT
|
|
# ============================================================================
|
|
|
|
# ============================================================================
|
|
# SYSTEM VALIDATION AND REQUIREMENTS CHECK
|
|
# ============================================================================
|
|
|
|
- name: Validate deployment environment
|
|
debug:
|
|
msg:
|
|
- "=== AUTO-SCALING DEPLOYMENT VALIDATION ==="
|
|
- "Target OS: {{ ansible_distribution }} {{ ansible_distribution_version }}"
|
|
- "Architecture: {{ ansible_architecture }}"
|
|
- "Available memory: {{ ansible_memtotal_mb }}MB"
|
|
- "Available disk: {{ ansible_mounts[0].size_available / 1024 / 1024 / 1024 | round(2) }}GB"
|
|
- "Target replicas: {{ docker_replicas | default(replicas | default(1)) }}"
|
|
- "Deployment strategy: {{ docker_deployment_strategy | default(deployment_strategy | default('rolling')) }}"
|
|
|
|
- name: Check minimum system requirements for auto-scaling
|
|
assert:
|
|
that:
|
|
- ansible_memtotal_mb >= (docker_replicas | default(1) | int * 512)
|
|
- (ansible_mounts[0].size_available / 1024 / 1024 / 1024) >= 5
|
|
- docker_replicas | default(1) | int <= docker_max_replicas | default(9) | int
|
|
fail_msg: |
|
|
Insufficient system resources for {{ docker_replicas | default(1) }} replicas.
|
|
Need at least {{ docker_replicas | default(1) | int * 512 }}MB RAM and 5GB disk space.
|
|
Replicas ({{ docker_replicas | default(1) }}) cannot exceed max_replicas ({{ docker_max_replicas | default(9) }}).
|
|
success_msg: "✅ System requirements met for auto-scaling deployment."
|
|
|
|
# ============================================================================
|
|
# PROJECT-SPECIFIC CONFIGURATION LOADING
|
|
# ============================================================================
|
|
- name: Load project-specific vars if exists
|
|
block:
|
|
- name: Check if project-specific variables file exists
|
|
stat:
|
|
path: "projects/{{ app_name }}/vars.yml"
|
|
register: project_vars_file
|
|
|
|
- name: Load project-specific variables
|
|
include_vars:
|
|
file: "projects/{{ app_name }}/vars.yml"
|
|
when: project_vars_file.stat.exists
|
|
|
|
- name: Check if project-specific variables by environment file exists
|
|
stat:
|
|
path: "projects/{{ app_name }}/group_vars/{{ deploy_env }}.yml"
|
|
register: project_vars_env_file
|
|
|
|
- name: Load project-specific variables by environment
|
|
include_vars:
|
|
file: "projects/{{ app_name }}/group_vars/{{ deploy_env }}.yml"
|
|
when: project_vars_env_file.stat.exists
|
|
delegate_to: localhost
|
|
run_once: true
|
|
|
|
- name: Load port registry
|
|
include_vars:
|
|
file: "{{ port_registry_file | default('group_vars/port_registry.yml') }}"
|
|
name: port_registry
|
|
delegate_to: localhost
|
|
run_once: true
|
|
when: port_registry_file is defined
|
|
|
|
# ============================================================================
|
|
# DEPLOYMENT CONFIGURATION SETUP
|
|
# ============================================================================
|
|
|
|
- name: Set deployment environment tag
|
|
set_fact:
|
|
deploy_env_tag: "{{ deploy_env }}{{ env_tag | default('') }}"
|
|
|
|
- name: Set auto-scaling configuration
|
|
set_fact:
|
|
# Auto-scaling parameters
|
|
final_replicas: "{{ docker_replicas | default(replicas | default(1)) }}"
|
|
final_max_replicas: "{{ docker_max_replicas | default(max_replicas | default(9)) }}"
|
|
final_deployment_strategy: "{{ docker_deployment_strategy | default(deployment_strategy | default('rolling')) }}"
|
|
final_health_check_timeout: "{{ docker_health_check_timeout | default(health_check_timeout | default(30)) }}"
|
|
final_deployment_timeout: "{{ docker_deployment_timeout | default(deployment_timeout | default(300)) }}"
|
|
|
|
# Port configuration
|
|
final_app_port: "{{ port_registry.projects[app_name][deploy_env_tag] | default(3000) }}"
|
|
final_container_port: "{{ container_port | default(3000) }}"
|
|
|
|
# Resource configuration
|
|
final_memory_limit: "{{ container_memory_limit | default(resource_limits[deploy_env].memory | default('1g')) }}"
|
|
final_cpu_limit: "{{ container_cpu_limit | default(resource_limits[deploy_env].cpu | default('1.0')) }}"
|
|
|
|
# Network configuration
|
|
final_docker_network: "{{ docker_network_name | default(app_name + '-' + deploy_env + '-network') }}"
|
|
final_restart_policy: "{{ container_restart_policy | default('unless-stopped') }}"
|
|
|
|
- name: Display auto-scaling deployment configuration
|
|
debug:
|
|
msg:
|
|
- "🚀 AUTO-SCALING DEPLOYMENT CONFIGURATION"
|
|
- "========================================"
|
|
- "Application: {{ app_name }}"
|
|
- "Environment: {{ deploy_env_tag }}"
|
|
- "Framework: {{ framework | default('unknown') }}"
|
|
- "Docker Image: {{ docker_image_name }}:{{ docker_image_tag }}"
|
|
- "Target Replicas: {{ final_replicas }}"
|
|
- "Max Replicas: {{ final_max_replicas }}"
|
|
- "Deployment Strategy: {{ final_deployment_strategy }}"
|
|
- "Base Port: {{ final_app_port }} (Pattern: {{ final_app_port }}{{ replica_number | default(1) }})"
|
|
- "Container Port: {{ final_container_port }}"
|
|
- "Memory Limit: {{ final_memory_limit }}"
|
|
- "CPU Limit: {{ final_cpu_limit }}"
|
|
- "Health Check Timeout: {{ final_health_check_timeout }}s"
|
|
- "Deployment Timeout: {{ final_deployment_timeout }}s"
|
|
|
|
# ============================================================================
|
|
# PRE-DEPLOYMENT VALIDATION
|
|
# ============================================================================
|
|
|
|
- name: Validate auto-scaling deployment parameters
|
|
assert:
|
|
that:
|
|
- app_name is defined and app_name != ""
|
|
- deploy_env in ['development', 'staging', 'production']
|
|
- docker_image_tag is defined and docker_image_tag != ""
|
|
- final_replicas | int >= 1
|
|
- final_replicas | int <= final_max_replicas | int
|
|
- final_deployment_strategy in ['rolling', 'blue-green', 'recreate']
|
|
- docker_registry is defined
|
|
fail_msg: "Missing or invalid auto-scaling deployment parameters"
|
|
success_msg: "✅ Auto-scaling deployment parameters validated"
|
|
tags: [validate]
|
|
|
|
# ============================================================================
|
|
# DIRECTORY AND ENVIRONMENT SETUP
|
|
# ============================================================================
|
|
|
|
- name: Create deployment directories
|
|
file:
|
|
path: "{{ item }}"
|
|
state: directory
|
|
owner: "{{ server_user }}"
|
|
group: "{{ server_user }}"
|
|
mode: '0755'
|
|
loop:
|
|
- "/home/{{ server_user }}/scripts"
|
|
- "/home/{{ server_user }}/ci"
|
|
- "/home/{{ server_user }}/ci/configs/{{ app_name }}/{{ deploy_env }}"
|
|
- "/home/{{ server_user }}/ci/data/{{ app_name }}/{{ deploy_env }}"
|
|
- "/home/{{ server_user }}/ci/logs/{{ app_name }}/{{ deploy_env }}"
|
|
- "/home/{{ server_user }}/ci/backups/{{ app_name }}/{{ deploy_env }}"
|
|
- "/home/{{ server_user }}/ci/deployments/{{ app_name }}/{{ deploy_env }}"
|
|
|
|
- name: Create environment file from vault if secrets_dict is defined
|
|
copy:
|
|
dest: "/home/{{ server_user }}/ci/configs/{{ app_name }}/{{ deploy_env }}/.env"
|
|
content: |
|
|
{% for key, value in secrets_dict.items() %}
|
|
{{ key }}={{ value }}
|
|
{% endfor %}
|
|
when: secrets_dict is defined
|
|
|
|
- name: Load project-specific env if exists
|
|
block:
|
|
- name: Check if project-specific .env template exists by environment
|
|
stat:
|
|
path: "projects/{{ app_name }}/templates/.env.{{ deploy_env }}.j2"
|
|
register: custom_env_template_by_env
|
|
delegate_to: localhost
|
|
run_once: true
|
|
|
|
- name: Create environment file from project template by environment
|
|
template:
|
|
src: "projects/{{ app_name }}/templates/.env.{{ deploy_env }}.j2"
|
|
dest: "/home/{{ server_user }}/ci/configs/{{ app_name }}/{{ deploy_env }}/.env"
|
|
owner: "{{ server_user }}"
|
|
group: "{{ server_user }}"
|
|
mode: '0600'
|
|
backup: yes
|
|
when: env_file_enabled | default(true) and custom_env_template_by_env.stat.exists
|
|
|
|
- name: Check if project-specific .env template exists
|
|
stat:
|
|
path: "projects/{{ app_name }}/templates/.env.j2"
|
|
register: custom_env_template
|
|
delegate_to: localhost
|
|
run_once: true
|
|
|
|
- name: Create environment file from project template
|
|
template:
|
|
src: "projects/{{ app_name }}/templates/.env.j2"
|
|
dest: "/home/{{ server_user }}/ci/configs/{{ app_name }}/{{ deploy_env }}/.env"
|
|
owner: "{{ server_user }}"
|
|
group: "{{ server_user }}"
|
|
mode: '0600'
|
|
backup: yes
|
|
when: env_file_enabled | default(true) and custom_env_template.stat.exists and not custom_env_template_by_env.stat.exists
|
|
|
|
- name: Create environment file with default template
|
|
template:
|
|
src: .env.j2
|
|
dest: "/home/{{ server_user }}/ci/configs/{{ app_name }}/{{ deploy_env }}/.env"
|
|
owner: "{{ server_user }}"
|
|
group: "{{ server_user }}"
|
|
mode: '0600'
|
|
backup: yes
|
|
when: not custom_env_template_by_env.stat.exists and not custom_env_template.stat.exists
|
|
vars:
|
|
# Pass auto-scaling configuration to template
|
|
auto_scaling_config:
|
|
replicas: "{{ final_replicas }}"
|
|
max_replicas: "{{ final_max_replicas }}"
|
|
deployment_strategy: "{{ final_deployment_strategy }}"
|
|
base_port: "{{ final_app_port }}"
|
|
container_port: "{{ final_container_port }}"
|
|
tags: [environment]
|
|
when: secrets_dict is not defined
|
|
|
|
# ============================================================================
|
|
# DOCKER ENVIRONMENT SETUP
|
|
# ============================================================================
|
|
|
|
- name: Setup Docker environment for auto-scaling
|
|
block:
|
|
- name: Check if Docker is installed
|
|
shell: |
|
|
command -v docker
|
|
register: docker_check
|
|
failed_when: false
|
|
changed_when: false
|
|
|
|
- name: Install Docker (Debian/Ubuntu)
|
|
apt:
|
|
name: docker.io
|
|
state: present
|
|
update_cache: yes
|
|
become: yes
|
|
when:
|
|
- docker_check.rc != 0
|
|
- ansible_os_family == "Debian"
|
|
|
|
- name: Install Docker (CentOS/RHEL)
|
|
yum:
|
|
name: docker
|
|
state: present
|
|
become: yes
|
|
when:
|
|
- docker_check.rc != 0
|
|
- ansible_os_family == "RedHat"
|
|
|
|
# Kiểm tra xem Python đã có Docker SDK chưa
|
|
- name: Check if Docker SDK for Python is installed
|
|
command: python3 -c "import docker"
|
|
register: docker_sdk_check
|
|
failed_when: false
|
|
changed_when: false
|
|
|
|
# Cài Docker SDK bằng pip nếu chưa có
|
|
- name: Install Docker SDK for Python via apt (nếu không muốn dùng pip)
|
|
apt:
|
|
name: python3-docker
|
|
state: present
|
|
become: yes
|
|
when:
|
|
- ansible_os_family == "Debian"
|
|
- docker_sdk_check.rc != 0
|
|
|
|
- name: Ensure Docker service is started and enabled
|
|
service:
|
|
name: docker
|
|
state: started
|
|
enabled: true
|
|
|
|
# - name: Create Docker network for auto-scaling deployment
|
|
# docker_network:
|
|
# name: "{{ final_docker_network }}"
|
|
# state: present
|
|
# driver: bridge
|
|
# ipam_config:
|
|
# - subnet: "172.{{ (final_app_port | string)[-2:] | int + 20 }}.0.0/16"
|
|
|
|
- name: Gather Docker networks on host
|
|
shell: docker network inspect $(docker network ls -q) 2>/dev/null || echo '[]'
|
|
register: docker_networks_raw
|
|
changed_when: false
|
|
failed_when: false
|
|
|
|
- name: Parse Docker networks JSON
|
|
set_fact:
|
|
docker_networks_info: "{{ docker_networks_raw.stdout | from_json }}"
|
|
|
|
- name: Extract existing subnets (as strings) from docker networks
|
|
set_fact:
|
|
existing_subnets: >-
|
|
{{
|
|
docker_networks_info | default([])
|
|
| selectattr('IPAM', 'defined')
|
|
| selectattr('IPAM.Config', 'defined')
|
|
| map(attribute='IPAM.Config')
|
|
| select
|
|
| map('first')
|
|
| selectattr('Subnet', 'defined')
|
|
| map(attribute='Subnet')
|
|
| list
|
|
}}
|
|
|
|
- name: Debug existing subnets
|
|
debug:
|
|
var: existing_subnets
|
|
|
|
- name: Get used second-octets from existing subnets (172.X.0.0/16 only)
|
|
set_fact:
|
|
used_seconds: >-
|
|
{%- set result = [] -%}
|
|
{%- for subnet in existing_subnets -%}
|
|
{%- if subnet.startswith('172.') -%}
|
|
{%- set parts = subnet.split('.') -%}
|
|
{%- if parts | length >= 2 -%}
|
|
{%- set _ = result.append(parts[1] | int) -%}
|
|
{%- endif -%}
|
|
{%- endif -%}
|
|
{%- endfor -%}
|
|
{{ result }}
|
|
|
|
- name: Debug used second octets
|
|
debug:
|
|
var: used_seconds
|
|
|
|
- name: Compute start octet from final_app_port (bounded 20..250)
|
|
set_fact:
|
|
start_octet: >-
|
|
{{
|
|
(((final_app_port | string)[-2:] | int) + 20)
|
|
if (((final_app_port | string)[-2:] | int) + 20) <= 250
|
|
else 250
|
|
}}
|
|
|
|
- name: Build candidate second-octet list (start -> 250 then 20 -> start-1)
|
|
set_fact:
|
|
candidate_list: >-
|
|
{{
|
|
(range(start_octet | int, 251) | list) + (range(20, start_octet | int) | list)
|
|
}}
|
|
|
|
- name: Debug candidate list
|
|
debug:
|
|
msg: "Candidates: {{ candidate_list }}, Used: {{ used_seconds }}"
|
|
|
|
- name: Select first unused second-octet
|
|
set_fact:
|
|
chosen_second: >-
|
|
{{
|
|
candidate_list
|
|
| map('int')
|
|
| reject('in', used_seconds)
|
|
| list
|
|
| first
|
|
}}
|
|
|
|
- name: Fail if couldn't find free subnet octet
|
|
fail:
|
|
msg: "No available 172.X.0.0/16 subnet found in candidate space (20..250). Existing used: {{ used_seconds }}"
|
|
when: chosen_second is not defined
|
|
|
|
- name: Build chosen subnet
|
|
set_fact:
|
|
chosen_subnet: "172.{{ chosen_second }}.0.0/16"
|
|
|
|
- name: Debug chosen subnet
|
|
debug:
|
|
msg: "Creating Docker network '{{ final_docker_network }}' with subnet {{ chosen_subnet }}"
|
|
|
|
- name: Create Docker network for auto-scaling deployment
|
|
community.docker.docker_network:
|
|
name: "{{ final_docker_network }}"
|
|
state: present
|
|
driver: bridge
|
|
ipam_config:
|
|
- subnet: "{{ chosen_subnet }}"
|
|
become: true
|
|
|
|
|
|
|
|
- name: Pull Docker image for auto-scaling deployment
|
|
docker_image:
|
|
name: "{{ docker_image_full | default(docker_image_name + ':' + docker_image_tag) }}"
|
|
source: pull
|
|
force_source: true
|
|
register: docker_pull_result
|
|
|
|
tags: [docker]
|
|
|
|
# ============================================================================
|
|
# ENHANCED DOCKER MANAGEMENT SCRIPT GENERATION
|
|
# ============================================================================
|
|
|
|
- name: Generate enhanced Docker management script with auto-scaling
|
|
template:
|
|
src: manage-docker.sh.j2
|
|
dest: "/home/{{ server_user }}/scripts/manage-{{ service_name }}.sh"
|
|
owner: "{{ server_user }}"
|
|
group: "{{ server_user }}"
|
|
mode: '0755'
|
|
backup: yes
|
|
vars:
|
|
# Container configuration
|
|
server_user: "{{ server_user }}"
|
|
container_name: "{{ service_name }}"
|
|
framework: "{{ framework }}"
|
|
|
|
# Auto-scaling configuration
|
|
default_replicas: "{{ final_replicas }}"
|
|
max_replicas: "{{ final_max_replicas }}"
|
|
health_check_timeout: "{{ final_health_check_timeout }}"
|
|
deployment_timeout: "{{ final_deployment_timeout }}"
|
|
|
|
# Port configuration
|
|
app_port: "{{ final_app_port }}"
|
|
container_port: "{{ final_container_port }}"
|
|
|
|
# Resource configuration
|
|
container_restart_policy: "{{ final_restart_policy }}"
|
|
container_memory_limit: "{{ final_memory_limit }}"
|
|
container_cpu_limit: "{{ final_cpu_limit }}"
|
|
|
|
# Network configuration
|
|
docker_network_name: "{{ final_docker_network }}"
|
|
|
|
# ============================================================================
|
|
# AUTO-SCALING DEPLOYMENT EXECUTION
|
|
# ============================================================================
|
|
|
|
- name: Check current deployment state
|
|
shell: |
|
|
if [ -f "/home/{{ server_user }}/scripts/manage-{{ app_name }}-{{ deploy_env }}{{ env_tag | default('') }}.sh" ]; then
|
|
sudo /home/{{ server_user }}/scripts/manage-{{ app_name }}-{{ deploy_env }}{{ env_tag | default('') }}.sh status 2>/dev/null || echo "no-containers"
|
|
else
|
|
echo "no-script"
|
|
fi
|
|
become_user: "{{ server_user }}"
|
|
register: current_deployment_state
|
|
changed_when: false
|
|
|
|
- name: Display current deployment state
|
|
debug:
|
|
msg: "{{ current_deployment_state.stdout_lines }}"
|
|
when: current_deployment_state.stdout_lines is defined
|
|
|
|
- name: Ensure Docker is installed and user has permissions
|
|
block:
|
|
- name: Add user to docker group
|
|
user:
|
|
name: "{{ server_user }}"
|
|
groups: docker
|
|
append: yes
|
|
become: yes
|
|
|
|
- name: Reset SSH connection for group changes
|
|
meta: reset_connection
|
|
|
|
- name: Test Docker access
|
|
command: docker version
|
|
register: docker_test
|
|
failed_when: docker_test.rc != 0
|
|
|
|
- name: Execute smart deployment with auto-scaling
|
|
shell: |
|
|
sudo /home/{{ server_user }}/scripts/manage-{{ app_name }}-{{ deploy_env }}{{ env_tag | default('') }}.sh deploy {{ replicas | default(1) }} {{ docker_image_tag }} rolling
|
|
async: 600
|
|
poll: 10 # Poll every 10 seconds instead of 0
|
|
register: deployment_result
|
|
become_user: "{{ server_user }}"
|
|
|
|
- name: Check deployment result
|
|
fail:
|
|
msg: "Deployment failed: {{ deployment_result.stderr | default('Unknown error') }}"
|
|
when:
|
|
- deployment_result.rc is defined
|
|
- deployment_result.rc != 0
|
|
|
|
# ============================================================================
|
|
# POST-DEPLOYMENT VERIFICATION
|
|
# ============================================================================
|
|
|
|
- name: Wait for auto-scaling deployment to settle
|
|
pause:
|
|
seconds: 5
|
|
tags: [health]
|
|
|
|
- name: Verify auto-scaling deployment completion
|
|
shell: |
|
|
sudo /home/{{ server_user }}/scripts/manage-{{ app_name }}-{{ deploy_env }}{{ env_tag | default('') }}.sh health
|
|
become_user: "{{ server_user }}"
|
|
register: auto_scaling_health_check
|
|
retries: 5
|
|
delay: 15
|
|
until: auto_scaling_health_check.rc == 0
|
|
tags: [health]
|
|
|
|
- name: Get final auto-scaling deployment status
|
|
shell: |
|
|
sudo /home/{{ server_user }}/scripts/manage-{{ app_name }}-{{ deploy_env }}{{ env_tag | default('') }}.sh status
|
|
become_user: "{{ server_user }}"
|
|
register: final_auto_scaling_status
|
|
changed_when: false
|
|
tags: [health]
|
|
|
|
- name: Extract auto-scaling deployment metrics
|
|
set_fact:
|
|
auto_scaling_metrics:
|
|
running_containers: "{{ final_auto_scaling_status.stdout | regex_search('Running Containers: (\\d+)', '\\1') | first | default('0') }}"
|
|
current_version: "{{ final_auto_scaling_status.stdout | regex_search('Current Version: ([^\\n]+)', '\\1') | first | default('unknown') }}"
|
|
base_port: "{{ final_auto_scaling_status.stdout | regex_search('Base Port: (\\d+)', '\\1') | first | default('0') }}"
|
|
|
|
# - name: Validate auto-scaling deployment metrics
|
|
# assert:
|
|
# that:
|
|
# - auto_scaling_metrics.running_containers | int == final_replicas | int
|
|
# - auto_scaling_metrics.current_version == docker_image_tag
|
|
# fail_msg: |
|
|
# Auto-scaling deployment validation failed:
|
|
# Expected: {{ final_replicas }} replicas with version {{ docker_image_tag }}
|
|
# Actual: {{ auto_scaling_metrics.running_containers }} replicas with version {{ auto_scaling_metrics.current_version }}
|
|
# success_msg: "✅ Auto-scaling deployment validation passed"
|
|
|
|
# ============================================================================
|
|
# LOAD BALANCER INTEGRATION
|
|
# ============================================================================
|
|
- name: Get active ports from script
|
|
shell: |
|
|
sudo /home/{{ server_user }}/scripts/manage-{{ app_name }}-{{ deploy_env }}{{ env_tag | default('') }}.sh deploy_active_ports
|
|
become_user: "{{ server_user }}"
|
|
register: active_ports_result
|
|
when: env_tag | default('') != '-worker'
|
|
|
|
- name: Convert ports to clean list
|
|
set_fact:
|
|
active_ports_list: "{{ active_ports_result.stdout.split() }}"
|
|
when: env_tag | default('') != '-worker' and active_ports_result.stdout | length > 0
|
|
|
|
- name: Generate nginx upstream configuration
|
|
template:
|
|
src: nginx-upstream.conf.j2
|
|
dest: "/etc/nginx/conf.d/{{ app_name }}-{{ deploy_env }}-upstream.conf"
|
|
backup: yes
|
|
vars:
|
|
upstream_name: "{{ app_name | regex_replace('[^A-Za-z0-9_]', '_') }}_{{ deploy_env }}_backend"
|
|
base_port: "{{ final_app_port }}"
|
|
replica_count: "{{ final_replicas }}"
|
|
load_balancing_method: "{{ nginx_config.load_balancing_method | default('least_conn') }}"
|
|
max_fails: "{{ nginx_config.max_fails | default(1) }}"
|
|
fail_timeout: "{{ nginx_config.fail_timeout | default(10) }}"
|
|
active_ports: "{{ active_ports_list }}"
|
|
when:
|
|
- update_load_balancer | default(true)
|
|
- env_tag | default('') != '-worker'
|
|
notify:
|
|
- test nginx configuration
|
|
- reload nginx
|
|
- webapplication purge cache
|
|
tags: [loadbalancer]
|
|
|
|
# ============================================================================
|
|
# DEPLOYMENT SUCCESS SUMMARY
|
|
# ============================================================================
|
|
|
|
- name: Display auto-scaling deployment success
|
|
debug:
|
|
msg:
|
|
- "🎉 AUTO-SCALING DEPLOYMENT SUCCESS"
|
|
- "=================================="
|
|
- "✅ Successfully deployed {{ app_name }} ({{ framework | default('unknown') }})"
|
|
- "🔢 Replicas: {{ auto_scaling_metrics.running_containers }}/{{ final_replicas }}"
|
|
- "🏷️ Version: {{ auto_scaling_metrics.current_version }}"
|
|
- "🚀 Strategy: {{ final_deployment_strategy }}"
|
|
- "🌐 Base Port: {{ auto_scaling_metrics.base_port }}"
|
|
- "🏥 Health Status: All containers healthy"
|
|
- "⚖️ Load Balancer: Updated with {{ final_replicas }} targets"
|
|
- ""
|
|
- "🔧 Management Commands:"
|
|
- " Status: ./scripts/manage-{{ app_name }}-{{ deploy_env }}{{ env_tag | default('') }}.sh status"
|
|
- " Scale: ./scripts/manage-{{ app_name }}-{{ deploy_env }}{{ env_tag | default('') }}.sh scale <replicas>"
|
|
- " Logs: ./scripts/manage-{{ app_name }}-{{ deploy_env }}{{ env_tag | default('') }}.sh logs"
|
|
- " Health: ./scripts/manage-{{ app_name }}-{{ deploy_env }}{{ env_tag | default('') }}.sh health"
|
|
tags: [info]
|
|
|
|
# ============================================================================
|
|
# CLEANUP AND MAINTENANCE
|
|
# ============================================================================
|
|
|
|
- name: Cleanup old Docker images (keep last 5 versions)
|
|
shell: |
|
|
# Enhanced cleanup for auto-scaling deployment
|
|
sudo /home/{{ server_user }}/scripts/manage-{{ app_name }}-{{ deploy_env }}{{ env_tag | default('') }}.sh clean
|
|
become_user: "{{ server_user }}"
|
|
ignore_errors: true
|
|
when: cleanup_old_images | default(true)
|
|
tags: [cleanup]
|
|
|
|
# ============================================================================
|
|
# DEPLOYMENT RECORD AND AUDIT TRAIL
|
|
# ============================================================================
|
|
|
|
- name: Create auto-scaling deployment record
|
|
copy:
|
|
content: |
|
|
# Auto-Scaling Deployment Record
|
|
timestamp: "{{ ansible_date_time.iso8601 }}"
|
|
application: "{{ app_name }}"
|
|
environment: "{{ deploy_env }}{{ env_tag | default('') }}"
|
|
version: "{{ docker_image_tag }}"
|
|
replicas: {{ final_replicas }}
|
|
max_replicas: {{ final_max_replicas }}
|
|
strategy: "{{ final_deployment_strategy }}"
|
|
base_port: "{{ final_app_port }}"
|
|
framework: "{{ framework | default('unknown') }}"
|
|
node_version: "{{ node_version | default('unknown') }}"
|
|
status: "success"
|
|
duration: "{{ auto_scaling_deployment_result.delta | default('unknown') }}"
|
|
operator: "{{ ansible_user_id }}"
|
|
git_commit: "{{ git_sha | default('unknown') }}"
|
|
git_tag: "{{ git_tag | default('unknown') }}"
|
|
memory_limit: "{{ final_memory_limit }}"
|
|
cpu_limit: "{{ final_cpu_limit }}"
|
|
docker_network: "{{ final_docker_network }}"
|
|
health_check_timeout: "{{ final_health_check_timeout }}"
|
|
deployment_timeout: "{{ final_deployment_timeout }}"
|
|
load_balancer_updated: {{ update_load_balancer | default(true) }}
|
|
management_script: "/home/{{ server_user }}/scripts/manage-{{ app_name }}-{{ deploy_env }}{{ env_tag | default('') }}.sh"
|
|
dest: "/home/{{ server_user }}/ci/logs/{{ app_name }}/{{ deploy_env }}/deployment-{{ ansible_date_time.epoch }}.yml"
|
|
owner: "{{ server_user }}"
|
|
group: "{{ server_user }}"
|
|
mode: '0644'
|
|
tags: [logging]
|
|
|
|
- name: Register auto-scaling deployment in system log
|
|
lineinfile:
|
|
path: "/var/log/microservices-deployments.log"
|
|
line: "{{ ansible_date_time.iso8601 }} | {{ app_name }} | {{ deploy_env }} | {{ docker_image_tag }} | {{ git_tag }} | AUTO-SCALE-SUCCESS | {{ final_replicas }}@{{ auto_scaling_metrics.base_port }} | {{ framework | default('unknown') }}"
|
|
create: true
|
|
mode: '0644'
|
|
tags: [logging]
|
|
|
|
- name: Cleanup old backups file
|
|
shell: |
|
|
ls -1t /home/{{ server_user }}/ci/configs/{{ app_name }}/{{ deploy_env }}/.env.*~ 2>/dev/null | tail -n +4 | xargs -r rm --
|
|
ls -1t /home/{{ server_user }}/scripts/manage-{{ service_name }}.sh.*~ 2>/dev/null | tail -n +4 | xargs -r rm --
|
|
ls -1t /etc/nginx/conf.d/{{ app_name }}-{{ deploy_env }}-upstream.conf.*~ 2>/dev/null | tail -n +4 | xargs -r rm --
|
|
args:
|
|
warn: false |