Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrated Build OVA pipeline from Jenkins to GHA Workflow #44

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions .github/workflows/ansible_playbooks/ova_generator.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
- hosts: all
become: true

tasks:
- name: Install git
yum:
name: git
state: present

- name: Make build directory
file:
path: "{{ ova_path }}"
state: directory

- name: Copy ova directory
copy:
src: "../../../ova"
dest: "{{ ova_path }}"

- name: Download the Wazuh installation assistant repository
git:
repo: "{{ wia_repository }}"
version: "{{ wia_branch }}"
dest: '/tmp/{{ wia_scripts }}'
depth: 1
register: clone_result
retries: 6
delay: 10
until: clone_result is success

- name: Set custom hostname
command: "hostnamectl set-hostname wazuh-server"

- name: Build Wazuh installation assistant script
command: "bash /tmp/{{ wia_scripts }}/builder.sh {{ builder_args }}"

- name: Copy Wazuh installation assistant script to tmp dir
command: "cp /tmp/{{ wia_scripts }}/wazuh-install.sh /tmp/wazuh-install.sh"

- name: Run provision script
command: "bash provision.sh {{ repository }} {{ debug }}"
args:
chdir: "{{ ova_path }}/ova"
async: 3600
poll: 10

- name: Clean provision files
file:
path: /var/provision/
state: absent

- name: Clean Wazuh installation assistant resources
file:
path: /tmp/{{ wia_scripts }}
state: absent

- name: Clean Wazuh installation assistant script
file:
path: /tmp/wazuh-install.sh
state: absent

- name: Clean Wazuh installation assistant files
file:
path: /tmp/wazuh-install-files.tar
state: absent

- name: Clean logs
shell: |
find /var/log/ -type f -exec bash -c 'cat /dev/null > {}' \;
find /var/ossec/logs -type f -execdir sh -c 'cat /dev/null > "$1"' _ {} \;
find /var/log/wazuh-indexer -type f -execdir sh -c 'cat /dev/null > "$1"' _ {} \;
find /var/log/filebeat -type f -execdir sh -c 'cat /dev/null > "$1"' _ {} \;
rm -rf /var/log/wazuh-install.log

- name: Clean history
shell: cat /dev/null > ~/.bash_history && history -c

- name: Clean YUM cache
shell: |
yum clean all
rm -rf /var/cache/yum/*

- name: Remove AuthorizedKeysCommand from sshd_config
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?AuthorizedKeysCommand.*'
state: absent

- name: Remove AuthorizedKeysCommandUser from sshd_config
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?AuthorizedKeysCommandUser.*'
state: absent

- name: Restart SSH service
service:
name: sshd
state: restarted
207 changes: 196 additions & 11 deletions .github/workflows/builder_OVA.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
run-name: Build OVA - Wazuh ${{ inputs.PACKAGE_VERSION }} Version - Launched by @${{ github.actor }}
run-name: Build OVA - Wazuh virtual machines branch ${{ inputs.WAZUH_VIRTUAL_MACHINES_REFERENCE }} - Launched by @${{ github.actor }}
name: Build OVA

on:
Expand All @@ -12,10 +12,6 @@ on:
description: 'Branch or tag of the wazuh-installation-assistant repository'
required: true
default: '4.10.0'
WAZUH_AUTOMATION_REFERENCE:
description: 'Branch or tag of the wazuh-automation repository'
required: true
default: '4.10.0'
WAZUH_PACKAGE_REPOSITORY:
type: choice
description: 'Wazuh package repository from which to download the packages'
Expand All @@ -31,14 +27,203 @@ on:
options:
- pre-release
- staging
DEBUG:
type: choice
description: 'Debug mode'
required: false
options:
- -v
- -vv
- -vvv

env:
LABEL: ubuntu-latest
OVA_AMI: "ami-0d4bd55523ee67aa4"
INSTANCE_TYPE: "t2.xlarge"
SECURITY_GROUP: "sg-005cff996b335d497"
SUBNET: "subnet-0b6aea31fb32cffad"
TEMPORAL_S3_BUCKET: "warehouse.wazuh.com"
S3_BUCKET: "packages-dev.wazuh.com"
OVA_ENVIRONMENT: "vmware"
CONTAINER_FORMAT: "ova"
TEMPORAL_S3_PATH: "trash/vm"
OVA_USER: "wazuh-user"
OVA_USER_PASSWORD: "wazuh"
INVENTORY_PATH: "/tmp/allocatorvm_ova"
AWS_REGION: "us-east-1"
OVA_PATH: "/var/provision/wazuh-virtual-machines"
WIA_DIR: "wazuh-installation-assistant"
WIA_REPOSITORY: "https://github.com/wazuh/wazuh-installation-assistant"

jobs:
initialize-environment:
runs-on: $LABEL
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout

jobs:
build_and_run:
runs-on: ubuntu-latest
steps:
- name: Set up Git
uses: actions/checkout@v3
- name: Install Ansible
run: sudo apt-get update && sudo apt install -y python3 jq sshpass && python3 -m pip install --user ansible-core==2.16

- name: Checkout code
uses: actions/checkout@v4

- name: Setting FILENAME var
run: |
WAZUH_VERSION=$(cat VERSION)
echo "WAZUH_VERSION=$WAZUH_VERSION" >> $GITHUB_ENV
FILENAME="wazuh-${WAZUH_VERSION}"
echo "FILENAME=$FILENAME" >> $GITHUB_ENV
FILENAME_OVA="${FILENAME}.ova"
echo "FILENAME_OVA=$FILENAME_OVA" >> $GITHUB_ENV
FILENAME_SHA="${FILENAME}.sha512"
echo "FILENAME_SHA=$FILENAME_SHA" >> $GITHUB_ENV

- name: View parameters
run: echo "${{ toJson(inputs) }}"

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_IAM_OVA_ROLE }}
role-session-name: "OVA-Builder"
aws-region: "${{ env.AWS_REGION }}"
role-duration-seconds: 10800 # Set the duration of the role session to 3 hours

- name: Install and config OpenVPN
run: |
sudo apt update
sudo apt install -y openvpn openvpn-systemd-resolved
echo "${{ secrets.CI_VPN_GITHUB }}" > vpn.ovpn
sudo openvpn --config "vpn.ovpn" --daemon

- name: Wait for a VPN connection
id: vpn_connected
timeout-minutes: 10
run: |
while ! ping -c2 10.10.0.252; do
sudo kill -9 `pidof openvpn`;
sudo openvpn --config "vpn.ovpn" --daemon;
sleep 30;
done

- name: Create OVA VM
id: alloc_vm_ova
run: |
instance=$(aws ec2 run-instances --image-id "${{ env.OVA_AMI }}" --count 1 --instance-type "${{ env.INSTANCE_TYPE }}" --key-name Ephemeral \
--security-group-ids "${{ env.SECURITY_GROUP }}" --subnet-id "${{ env.SUBNET }}" \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=gha_${{ github.run_id }}_ova_build},{Key=team,Value=devops}]')
INSTANCE_ID=$(echo $instance | jq -r '.Instances[0].InstanceId')
echo "INSTANCE_ID=${INSTANCE_ID}" >> $GITHUB_ENV

- name: Wait for instance to be running
run: |
MAX_RETRIES=40
NUM_RETRIES=0
while true; do
STATUS=$(aws ec2 describe-instances --instance-ids "${{ env.INSTANCE_ID }}" | jq -r '.Reservations[0].Instances[0].State.Name')
if [ "${STATUS}" == "running" ]; then
break
fi
sleep 30
NUM_RETRIES=$((NUM_RETRIES+1))
if [ ${NUM_RETRIES} -eq ${MAX_RETRIES} ]; then
echo "Error creating OVA VM"
aws ec2 terminate-instances --instance-ids "${{ env.INSTANCE_ID }}"
exit 1
fi
done
ansible_host=$(aws ec2 describe-instances --instance-ids "${{ env.INSTANCE_ID }}" | jq -r '.Reservations[0].Instances[0].PrivateIpAddress')
mkdir -p ${{ env.INVENTORY_PATH }}
echo "[gha_instance]" > ${{ env.INVENTORY_PATH }}/inventory
echo "$ansible_host ansible_user=${{ env.OVA_USER }} ansible_password=${{ env.OVA_USER_PASSWORD }} ansible_ssh_common_args='-o StrictHostKeyChecking=no'" >> ${{ env.INVENTORY_PATH }}/inventory
echo "ANSIBLE_HOST=$ansible_host" >> $GITHUB_ENV

- name: Wait for SSH to be available
run: |
ansible_host=${{ env.ANSIBLE_HOST }}
MAX_RETRIES=40
NUM_RETRIES=0
while true; do
if sshpass -p ${{ env.OVA_USER_PASSWORD }} ssh -o 'StrictHostKeyChecking no' -o 'ConnectTimeout=10' ${{ env.OVA_USER }}@$ansible_host "exit"; then
break
fi
sleep 30
NUM_RETRIES=$((NUM_RETRIES+1))
if [ ${NUM_RETRIES} -eq ${MAX_RETRIES} ]; then
echo "Error connecting to OVA VM"
aws ec2 terminate-instances --instance-ids "${{ env.INSTANCE_ID }}"
exit 1
fi
done

- name: Run Ansible playbook to generate the OVA
run: |
if [ "${{ inputs.WAZUH_PACKAGE_REPOSITORY }}" == "prod" ]; then
builder_args="-i"
elif [ "${{ inputs.WAZUH_PACKAGE_REPOSITORY }}" == "staging" ]; then
builder_args="-i -d staging"
elif [ "${{ inputs.WAZUH_PACKAGE_REPOSITORY }}" == "dev" ]; then
builder_args="-i -d"
fi
ansible-playbook -i ${{ env.INVENTORY_PATH }}/inventory .github/workflows/ansible_playbooks/ova_generator.yaml \
--extra-vars " \
wia_branch=${{ inputs.WAZUH_INSTALLATION_ASSISTANT_REFERENCE }} \
ova_branch=${{ inputs.WAZUH_VIRTUAL_MACHINES_REFERENCE }} \
repository=${{ inputs.WAZUH_PACKAGE_REPOSITORY }} \
ova_path=${{ env.OVA_PATH }} \
wia_scripts=${{ env.WIA_DIR }} \
wia_repository=${{ env.WIA_REPOSITORY }} \
builder_args='$builder_args' \
debug=yes" ${{ inputs.DEBUG }}

- name: Export Instance to create OVA
run: |
EXPORT=$(aws ec2 create-instance-export-task --instance-id "${{ env.INSTANCE_ID }}" --target-environment vmware \
--export-to-s3-task "ContainerFormat=${{ env.CONTAINER_FORMAT }},DiskImageFormat=VMDK,S3Bucket=${{ env.TEMPORAL_S3_BUCKET }},S3Prefix=${{ env.TEMPORAL_S3_PATH }}/${{ env.FILENAME }}")
EXPORT_ID=$(echo ${EXPORT} | jq -r '.ExportTask.ExportTaskId')
echo "EXPORT_ID=${EXPORT_ID}" >> $GITHUB_ENV

- name: Wait for export OVA
run: |
MAX_RETRIES=40
NUM_RETRIES=0
while true; do
STATUS=$(aws ec2 describe-export-tasks --export-task-ids "${{ env.EXPORT_ID }}" | jq -r '.ExportTasks[0].State')
if [ "${STATUS}" == "completed" ]; then
break
fi
sleep 270
NUM_RETRIES=$((NUM_RETRIES+1))
if [ ${NUM_RETRIES} -eq ${MAX_RETRIES} ]; then
echo "Error exporting OVA"
exit 1
fi
done

- name: Getting OVA from temporal bucket
run: |
aws s3 --quiet cp "s3://${{ env.TEMPORAL_S3_BUCKET }}/${{ env.TEMPORAL_S3_PATH }}/${{ env.FILENAME }}${{ env.EXPORT_ID }}.ova" /tmp/${{ env.FILENAME_OVA }}

- name: Standarizing OVA
run: |
sed -i "s|ovf:capacity=\"40\"|ovf:capacity=\"50\"|g" ova/wazuh_ovf_template
bash ova/setOVADefault.sh "ova/" "/tmp/${{ env.FILENAME_OVA }}" "/tmp/${{ env.FILENAME_OVA }}" "ova/wazuh_ovf_template" "${{ env.WAZUH_VERSION }}"

- name: Exporting OVA to final repository
run: |
aws s3 cp --quiet --acl public-read /tmp/${{ env.FILENAME_OVA }} s3://${{ env.S3_BUCKET }}/${{ inputs.S3_REPOSITORY }}/vm/${{ env.FILENAME_OVA }}

- name: Generating sha512 file
run: |
sha512sum /tmp/${{ env.FILENAME_OVA }} > /tmp/${{ env.FILENAME_SHA }}
aws s3 cp --quiet --acl public-read /tmp/${{ env.FILENAME_SHA }} s3://${{ env.S3_BUCKET }}/${{ inputs.S3_REPOSITORY }}/checksums/wazuh/${{ env.WAZUH_VERSION }}/${{ env.FILENAME_SHA }}

- name: Removing temporal files
run: |
aws s3 rm --quiet s3://${{ env.TEMPORAL_S3_BUCKET }}/${{ env.TEMPORAL_S3_PATH }}/${{ env.FILENAME }}${{ env.EXPORT_ID }}.ova

- name: Delete allocated VM
if: always() && steps.alloc_vm_ova.outcome == 'success'
run: |
aws ec2 terminate-instances --instance-ids "${{ env.INSTANCE_ID }}"
13 changes: 10 additions & 3 deletions ova/assets/custom/enable_fips.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
# Update the Operating System (OS) packages to ensure the OS is up to date
sudo yum update -y

# Install and enable the FIPS module
attempt=0
seconds=30
max_attempts=10
yum_lockfile="/var/run/yum.pid"
while [ -f "${yum_lockfile}" ] && [ "${attempt}" -lt "${max_attempts}" ]; do
echo "Waiting for other package managers to finish..."
sleep "${seconds}"
attempt=$((attempt+1))
done
sudo yum update -y
sudo yum install -y dracut-fips
sudo dracut -f

Expand Down
9 changes: 9 additions & 0 deletions ova/assets/steps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@
systemConfig() {

echo "Upgrading the system. This may take a while ..."
attempt=0
seconds=30
max_attempts=10
yum_lockfile="/var/run/yum.pid"
while [ -f "${yum_lockfile}" ] && [ "${attempt}" -lt "${max_attempts}" ]; do
echo "Waiting for other package managers to finish..."
sleep "${seconds}"
attempt=$((attempt+1))
done
yum upgrade -y > /dev/null 2>&1

# Disable kernel messages and edit background
Expand Down
9 changes: 8 additions & 1 deletion ova/provision.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,33 @@ echo "Using ${PACKAGES_REPOSITORY} packages"
WAZUH_VERSION=$(cat ${INSTALLER} | grep "wazuh_version=" | cut -d "\"" -f 2)

# System configuration
echo "Configuring system"
systemConfig

# Edit installation script
echo "Editing installation script"
preInstall

# Install
echo "Installing Wazuh central components"
bash ${INSTALLER} ${INSTALL_ARGS}

echo "Stopping Filebeat and Wazuh Manager"
systemctl stop filebeat wazuh-manager

# Delete indexes
echo "Deleting indexes"
for index in "${INDEXES[@]}"; do
curl -u admin:admin -XDELETE "https://127.0.0.1:9200/$index" -k
done

# Recreate empty indexes (wazuh-alerts and wazuh-archives)
echo "Recreating empty indexes"
bash /usr/share/wazuh-indexer/bin/indexer-security-init.sh -ho 127.0.0.1

echo "Stopping Wazuh indexer and Wazuh dashboard"
systemctl stop wazuh-indexer wazuh-dashboard
systemctl enable wazuh-manager


echo "Cleaning system"
clean
Loading