gighiveThis document outlines the detailed implementation plan for replacing GigHive’s bash script entry points with Ansible-first bootstrap playbooks. This approach preserves the existing sophisticated infrastructure while eliminating brittleness through proper Ansible orchestration.
The Ansible-first approach creates a unified entry point that orchestrates the existing sophisticated infrastructure through proper Ansible playbooks instead of brittle bash scripts.
ansible/playbooks/
├── bootstrap.yml # Main entry point (replaces all 3 bash scripts)
├── prerequisites.yml # Replaces 1prereqsInstall.sh
├── infrastructure.yml # Replaces 2bootstrap.sh
├── teardown.yml # Replaces 3deleteAll.sh
└── site.yml # Existing application deployment (unchanged)
1prereqsInstall.sh)Create ansible/roles/prerequisites/ with these capabilities:
ansible/roles/prerequisites/tasks/main.yml---
- name: Detect Linux distribution
setup:
gather_subset:
- "!all"
- "!min"
- "distribution"
- name: Fail if unsupported distribution
fail:
msg: "Unsupported distribution: "
when: not (ansible_distribution == "Ubuntu" and ansible_distribution_version is version('20.04', '>='))
- name: Install base packages
apt:
name: ""
state: present
update_cache: yes
become: yes
- name: Add Docker repository
block:
- name: Add Docker GPG key
apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
keyring: /etc/apt/keyrings/docker.gpg
state: present
- name: Add Docker repository
apt_repository:
repo: "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu stable"
state: present
filename: docker
- name: Install Docker packages
apt:
name: ""
state: present
update_cache: yes
become: yes
- name: Install Python packages in virtual environment
pip:
name: ""
virtualenv: ""
virtualenv_python: python3
when: create_python_venv | default(true)
- name: Install Terraform
include_tasks: terraform.yml
when: install_terraform | default(true)
- name: Verify installations
include_tasks: verify.yml
ansible/roles/prerequisites/vars/main.yml---
prerequisite_packages:
- python3
- python3-pip
- python3-venv
- curl
- gnupg
- software-properties-common
- lsb-release
- ca-certificates
- apt-transport-https
- genisoimage
- cloud-image-utils
docker_packages:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose-plugin
python_packages:
- ansible
- azure-cli
- azure-mgmt-resource
- azure-storage-blob
- docker-compose
ansible_venv_path: "/.ansible-azure"
ansible/roles/prerequisites/tasks/terraform.yml---
- name: Add HashiCorp GPG key
apt_key:
url: https://apt.releases.hashicorp.com/gpg
keyring: /usr/share/keyrings/hashicorp-archive-keyring.gpg
state: present
become: yes
- name: Add HashiCorp repository
apt_repository:
repo: "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com main"
state: present
filename: hashicorp
become: yes
- name: Install Terraform
apt:
name: terraform
state: present
update_cache: yes
become: yes
ansible/roles/prerequisites/tasks/verify.yml---
- name: Verify Docker installation
command: docker --version
register: docker_version
changed_when: false
- name: Verify Docker Compose installation
command: docker compose version
register: compose_version
changed_when: false
- name: Verify Terraform installation
command: terraform version
register: terraform_version
changed_when: false
when: install_terraform | default(true)
- name: Verify Azure CLI installation
command: "/bin/az version"
register: az_version
changed_when: false
when: create_python_venv | default(true)
- name: Display installation verification
debug:
msg:
- "Docker: "
- "Docker Compose: "
- "Terraform: "
- "Azure CLI: Installed"
2bootstrap.sh)Create ansible/roles/infrastructure/ for cloud resource management:
ansible/roles/infrastructure/tasks/main.yml---
- name: Validate Azure credentials
azure.azcollection.azure_rm_resourcegroup_info:
name: ""
register: rg_check
failed_when: false
when: deployment_target == "azure"
- name: Authenticate to Azure if needed
block:
- name: Check existing Azure session
command: az account show
register: az_account
failed_when: false
changed_when: false
- name: Login to Azure
command: az login --use-device-code
when: az_account.rc != 0
when: deployment_target == "azure"
- name: Create Terraform backend resources
include_tasks: terraform_backend.yml
when: deployment_target == "azure"
- name: Initialize Terraform
terraform:
project_path: ""
state: present
backend_config: ""
variables: ""
plan_file: "/tfplan"
register: terraform_plan
- name: Show Terraform plan
debug:
var: terraform_plan.stdout_lines
- name: Apply Terraform plan
terraform:
project_path: ""
state: present
plan_file: "/tfplan"
when:
- terraform_plan.changed
- auto_apply_terraform | default(false) or (ansible_interactive | default(true) and (user_confirm_apply | default('') | lower in ['y', 'yes']))
- name: Extract infrastructure outputs
terraform:
project_path: ""
state: present
register: terraform_outputs
- name: Update Ansible inventory with new IP
include_tasks: update_inventory.yml
when: terraform_outputs.outputs.vm_public_ip is defined
ansible/roles/infrastructure/tasks/terraform_backend.yml---
- name: Set subscription
command: az account set --subscription ""
when: azure_subscription_id is defined
- name: Create backend resource group
azure.azcollection.azure_rm_resourcegroup:
name: ""
location: ""
state: present
- name: Create backend storage account
azure.azcollection.azure_rm_storageaccount:
resource_group: ""
name: ""
location: ""
account_type: Standard_LRS
kind: StorageV2
state: present
- name: Create backend storage container
azure.azcollection.azure_rm_storageblob:
resource_group: ""
storage_account_name: ""
container: ""
state: present
ansible/roles/infrastructure/tasks/update_inventory.yml---
- name: Generate inventory from template
template:
src: inventory_azure.yml.j2
dest: "/ansible/inventories/inventory_azure.yml"
backup: yes
vars:
vm_public_ip: ""
- name: Display updated inventory
debug:
msg: "Updated inventory with VM IP: "
ansible/playbooks/bootstrap.yml---
- name: GigHive Bootstrap - Prerequisites
hosts: localhost
connection: local
gather_facts: yes
vars:
deployment_target: ""
roles:
- role: prerequisites
tags: [prereqs]
tags: [bootstrap, prereqs]
- name: GigHive Bootstrap - Infrastructure
hosts: localhost
connection: local
vars:
deployment_target: ""
roles:
- role: infrastructure
tags: [infra]
when: deployment_target in ['azure', 'virtualbox']
tags: [bootstrap, infra]
- name: GigHive Bootstrap - Application Deployment
import_playbook: site.yml
vars:
deployment_target: ""
tags: [bootstrap, deploy]
ansible/playbooks/teardown.yml (Replaces 3deleteAll.sh)---
- name: GigHive Infrastructure Teardown
hosts: localhost
connection: local
gather_facts: no
vars:
deployment_target: ""
tasks:
- name: Confirm teardown
pause:
prompt: "Are you sure you want to destroy ALL resources in ? (yes/no)"
register: confirm_teardown
when: not force_teardown | default(false)
- name: Fail if not confirmed
fail:
msg: "Teardown cancelled by user"
when:
- not force_teardown | default(false)
- confirm_teardown.user_input | lower != 'yes'
- name: Destroy Terraform infrastructure
terraform:
project_path: ""
state: absent
force_init: true
when: deployment_target == "azure"
- name: Monitor teardown progress
include_tasks: monitor_teardown.yml
when: deployment_target == "azure"
# VirtualBox deployment
ansible-playbook ansible/playbooks/bootstrap.yml -e target=virtualbox
# Azure deployment
ansible-playbook ansible/playbooks/bootstrap.yml -e target=azure -e auto_apply_terraform=true
# Bare metal deployment
ansible-playbook ansible/playbooks/bootstrap.yml -e target=baremetal -i ansible/inventories/inventory_baremetal.yml
# Only install prerequisites
ansible-playbook ansible/playbooks/bootstrap.yml --tags prereqs
# Only infrastructure provisioning
ansible-playbook ansible/playbooks/bootstrap.yml --tags infra -e target=azure
# Skip prerequisites (already installed)
ansible-playbook ansible/playbooks/bootstrap.yml --skip-tags prereqs
# Development environment
ansible-playbook ansible/playbooks/bootstrap.yml -e target=virtualbox -e database_full=false
# Production environment
ansible-playbook ansible/playbooks/bootstrap.yml -e target=azure -e database_full=true -e app_flavor=gighive
# Interactive teardown with confirmation
ansible-playbook ansible/playbooks/teardown.yml -e target=azure
# Force teardown without confirmation
ansible-playbook ansible/playbooks/teardown.yml -e target=azure -e force_teardown=true
Replace environment variable dependencies with Ansible variable precedence:
ansible/inventories/group_vars/all.yml---
# Global defaults
gighive_home: "/scripts/gighive"
terraform_dir: "/terraform"
ansible_venv_path: "/.ansible-azure"
# Azure configuration (can be overridden via -e or vault)
azure_subscription_id: ""
azure_tenant_id: ""
# Terraform backend configuration
terraform_backend_rg: "gighive-terraform-backend"
terraform_backend_storage_account: "gighiveterraformstate"
terraform_backend_container: "tfstate"
terraform_backend_key: "gighive.tfstate"
# Deployment behavior
auto_apply_terraform: false
create_python_venv: true
install_terraform: true
# Create encrypted credentials file
ansible-vault create ansible/inventories/group_vars/vault.yml
# Content of vault.yml:
azure_subscription_id: "your-subscription-id"
azure_tenant_id: "your-tenant-id"
gighive_admin_password: "secure-password"
gighive_viewer_password: "secure-password"
gighive_uploader_password: "secure-password"
# Deploy with vault
ansible-playbook ansible/playbooks/bootstrap.yml --ask-vault-pass -e target=azure
# Or with vault password file
ansible-playbook ansible/playbooks/bootstrap.yml --vault-password-file ~/.vault_pass -e target=azure
- name: Validate prerequisites
block:
- name: Check GIGHIVE_HOME is accessible
stat:
path: ""
register: gighive_home_stat
failed_when: not gighive_home_stat.stat.exists
- name: Verify SSH keys exist
stat:
path: "/ssh/"
register: ssh_key_check
failed_when: not ssh_key_check.stat.exists
loop:
- id_rsa.pub
- id_ed25519.pub
ignore_errors: yes
- name: Fail if no SSH keys found
fail:
msg: "No SSH public keys found in /ssh/"
when: ssh_key_check.results | selectattr('stat.exists') | list | length == 0
- name: Validate Azure credentials
command: az account show
register: az_account_check
failed_when: false
changed_when: false
when: deployment_target == "azure"
- name: Warn about Azure authentication
debug:
msg: "Azure CLI not authenticated. Will prompt for device code login."
when:
- deployment_target == "azure"
- az_account_check.rc != 0
- name: Infrastructure rollback
block:
- name: Destroy Terraform resources
terraform:
project_path: ""
state: absent
force_init: true
when: rollback_infrastructure | default(false)
- name: Clean up local state
file:
path: ""
state: absent
loop:
- "/.terraform"
- "/tfplan"
when: clean_local_state | default(false)
- name: Remove generated inventory
file:
path: "/ansible/inventories/inventory_azure.yml"
state: absent
when: cleanup_inventory | default(false)
rescue:
- name: Log rollback failure
debug:
msg: "Rollback failed, manual cleanup may be required"
- name: Display manual cleanup instructions
debug:
msg:
- "Manual cleanup may be required:"
- "1. Check Azure portal for remaining resources"
- "2. Remove /.terraform directory"
- "3. Remove /tfplan file"
- name: Validate deployment
block:
- name: Wait for VM to be accessible
wait_for:
host: ""
port: 22
timeout: 300
when: deployment_target == "azure"
- name: Test SSH connectivity
command: ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no @ echo "SSH OK"
register: ssh_test
when: deployment_target == "azure"
- name: Validate application deployment
uri:
url: "https://"
validate_certs: no
status_code: [200, 401] # 401 is expected due to basic auth
register: app_test
when: deployment_target in ["azure", "virtualbox"]
- name: Display deployment summary
debug:
msg:
- "Deployment completed successfully!"
- "Target: "
- "VM IP: "
- "Application URL: https://"
- "SSH Access: ssh @"
The Ansible-first approach enhances rather than replaces existing sophisticated infrastructure:
# Traditional approach still works
ansible-playbook -i ansible/inventories/inventory_azure.yml ansible/playbooks/site.yml
# New unified approach
ansible-playbook ansible/playbooks/bootstrap.yml -e target=azure
ansible/roles/infrastructure/templates/inventory_azure.yml.j2all:
hosts:
localhost:
ansible_connection: local
ansible_python_interpreter: /bin/python
azure_vm:
ansible_host:
ansible_user: azureuser
ansible_python_interpreter: /usr/bin/python3
ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
ansible_become: yes
children:
gighive:
hosts:
azure_vm:
target_vms:
children:
gighive:
ansible/roles/prerequisites/ alongside existing bash scripts1prereqsInstall.sh functionalityansible/roles/infrastructure/ for Terraform orchestration2bootstrap.sh functionalityansible/playbooks/bootstrap.yml main entry pointansible/playbooks/teardown.yml3deleteAll.sh functionality# Test individual roles
ansible-playbook ansible/playbooks/bootstrap.yml --tags prereqs --check
ansible-playbook ansible/playbooks/bootstrap.yml --tags infra --check
# Test complete workflow in check mode
ansible-playbook ansible/playbooks/bootstrap.yml -e target=azure --check
# Test with minimal deployment
ansible-playbook ansible/playbooks/bootstrap.yml -e target=virtualbox -e database_full=false
# Test teardown and rebuild
ansible-playbook ansible/playbooks/teardown.yml -e target=azure -e force_teardown=true
ansible-playbook ansible/playbooks/bootstrap.yml -e target=azure
This comprehensive migration plan preserves your sophisticated architecture while eliminating the brittleness of bash script entry points through proper Ansible orchestration, providing a robust, maintainable, and scalable deployment solution.