diff --git a/awx/awx-instance.yaml b/awx/awx-instance.yaml new file mode 100644 index 0000000..a9d452b --- /dev/null +++ b/awx/awx-instance.yaml @@ -0,0 +1,48 @@ +--- +# AWX namespace +apiVersion: v1 +kind: Namespace +metadata: + name: awx +--- +# Admin password secret — the password is 'REDACTED_PASSWORD' (fleet standard) +apiVersion: v1 +kind: Secret +metadata: + name: awx-admin-password + namespace: awx +type: Opaque +stringData: + password: REDACTED_PASSWORD +--- +# AWX Custom Resource — single instance, LoadBalancer service +apiVersion: awx.ansible.com/v1beta1 +kind: AWX +metadata: + name: tsys-awx + namespace: awx +spec: + service_type: LoadBalancer + ingress_type: none + + admin_user: admin + admin_password_secret: awx-admin-password + + # PostgreSQL — bundled, stored on local disk via PVC (k3s local-path) + postgres_storage_class: local-path + postgres_data_volume_size: 8Gi + postgres_resource_requirements: + requests: + memory: 1Gi + + # Resource limits — fit within 12 GB host RAM + web_resource_requirements: + requests: + memory: 1Gi + task_resource_requirements: + requests: + memory: 1Gi + + # Annotations for LoadBalancer (k3s ServiceLB) + service_annotations: + metallb.io/address-pool: "" diff --git a/awx/deploy-awx.sh b/awx/deploy-awx.sh new file mode 100644 index 0000000..34c01ea --- /dev/null +++ b/awx/deploy-awx.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +############################################################################### +# deploy-awx.sh — Deploy AWX Operator + instance on k3s. +# +# Prerequisites: k3s must be installed and running (install-k3s.sh). +# Intended to run ON the target VM (tsys-awx.knel.net) as root or via sudo. +# +# Usage: sudo bash deploy-awx.sh +############################################################################### +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +export KUBECONFIG="${KUBECONFIG:-/etc/rancher/k3s/k3s.yaml}" + +OPERATOR_VERSION="${OPERATOR_VERSION:-2.19.1}" + +echo "==========================================================" +echo " AWX Operator deployment — version ${OPERATOR_VERSION}" +echo "==========================================================" + +# --------------------------------------------------------------------------- +# Step 1: Create namespace +# --------------------------------------------------------------------------- +echo "" +echo "=== Step 1: Create namespace ===" +kubectl apply -f "${SCRIPT_DIR}/namespace.yaml" + +# --------------------------------------------------------------------------- +# Step 2: Deploy AWX Operator +# --------------------------------------------------------------------------- +echo "" +echo "=== Step 2: Deploy AWX Operator ${OPERATOR_VERSION} ===" + +# Clone the operator to get kustomize manifests +OPERATOR_DIR="/tmp/awx-operator-${OPERATOR_VERSION}" +rm -rf "${OPERATOR_DIR}" +git clone --branch "${OPERATOR_VERSION}" --depth 1 \ + "https://github.com/ansible/awx-operator.git" "${OPERATOR_DIR}" 2>&1 | tail -3 + +# The operator's default namespace is 'awx' — matches our setup +# Apply the operator via kustomize +kubectl apply -k "${OPERATOR_DIR}" 2>&1 || { + echo "kustomize apply failed, trying raw manifests..." + kubectl apply -f "https://raw.githubusercontent.com/ansible/awx-operator/${OPERATOR_VERSION}/deploy/awx-operator.yaml" +} + +echo "" +echo "Waiting for AWX Operator deployment to be ready..." +kubectl -n awx wait --for=condition=Available deployment/awx-operator-controller-manager \ + --timeout=300s 2>&1 || { + echo "Operator not ready yet — checking status..." + kubectl -n awx get pods +} + +# --------------------------------------------------------------------------- +# Step 3: Deploy AWX instance +# --------------------------------------------------------------------------- +echo "" +echo "=== Step 3: Deploy AWX instance ===" +kubectl apply -f "${SCRIPT_DIR}/awx-instance.yaml" + +echo "" +echo "AWX instance created. Operator will now reconcile." +echo "This typically takes 5-10 minutes for the first deployment." +echo "" +echo "Monitor progress with:" +echo " kubectl -n awx get awx tsys-awx -o jsonpath='{.status.conditions}' | jq ." +echo " kubectl -n awx get pods -w" +echo " kubectl -n awx logs deployment/awx-operator-controller-manager -f" diff --git a/awx/install-k3s.sh b/awx/install-k3s.sh new file mode 100644 index 0000000..9f98423 --- /dev/null +++ b/awx/install-k3s.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +############################################################################### +# install-k3s.sh — Install k3s single-node on the tsys-awx VM. +# +# Intended to run ON the target VM (tsys-awx.knel.net) as root or via sudo. +# Installs k3s without Traefik (we use NodePort/LoadBalancer directly). +# +# Usage: sudo bash install-k3s.sh +############################################################################### +set -euo pipefail + +NODE_NAME="${NODE_NAME:-tsys-awx}" + +echo "==========================================================" +echo " k3s single-node install — ${NODE_NAME}" +echo "==========================================================" + +if command -v k3s >/dev/null 2>&1 && k3s kubectl get nodes >/dev/null 2>&1; then + echo "k3s already installed and running. Skipping." + k3s kubectl get nodes + exit 0 +fi + +echo "" +echo "=== Installing k3s (this takes 1-2 minutes) ===" +curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable=traefik --write-kubeconfig-mode=644" sh - + +echo "" +echo "=== Waiting for k3s node to be Ready ===" +export KUBECONFIG=/etc/rancher/k3s/k3s.yaml +for i in $(seq 1 30); do + if k3s kubectl get nodes 2>/dev/null | grep -q ' Ready'; then + echo "Node is Ready!" + k3s kubectl get nodes + break + fi + echo " waiting... (${i}/30)" + sleep 5 +done + +echo "" +echo "=== k3s install complete ===" +echo "kubeconfig: /etc/rancher/k3s/k3s.yaml" +echo "kubectl: k3s kubectl (or set KUBECONFIG=/etc/rancher/k3s/k3s.yaml)" diff --git a/awx/namespace.yaml b/awx/namespace.yaml new file mode 100644 index 0000000..b9fd05b --- /dev/null +++ b/awx/namespace.yaml @@ -0,0 +1,6 @@ +--- +# AWX Operator namespace +apiVersion: v1 +kind: Namespace +metadata: + name: awx