init
This commit is contained in:
commit
f0d13cd510
29 files changed
+6868
No files matched your search
@@ -0,0 +1,650 @@
|
||||
---
|
||||
# ============================================================================
|
||||
# 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
|
||||
Reference in new issue
Block a user