Skip to content

Fix/terra alignment #112

Fix/terra alignment

Fix/terra alignment #112

Workflow file for this run

name: Deploy AI Gateway
on:
push:
branches:
- main
pull_request:
branches:
- dev
- main
workflow_dispatch:
permissions:
id-token: write
contents: read
env:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
TF_BACKEND_RG: ${{ secrets.TF_BACKEND_RG }}
TF_BACKEND_SA: ${{ secrets.TF_BACKEND_SA }}
TF_BACKEND_CONTAINER: ${{ secrets.TF_BACKEND_CONTAINER }}
TF_VAR_secrets_expiration_date: "2027-03-31T00:00:00Z"
# Dashboard: image and optional Grafana URL (set DASHBOARD_CONTAINER_IMAGE as a
# repository/environment variable to pin a specific digest; falls back to :latest)
TF_VAR_dashboard_container_image: ${{ vars.DASHBOARD_CONTAINER_IMAGE || 'ghcr.io/phoenixvc/ai-gateway-dashboard:latest' }}
TF_VAR_state_service_container_image: ${{ vars.STATE_SERVICE_CONTAINER_IMAGE || '' }}
TF_VAR_state_service_shared_token: ${{ secrets.STATE_SERVICE_SHARED_TOKEN || '' }}
TF_VAR_state_service_registry_username: ${{ vars.STATE_SERVICE_REGISTRY_USERNAME || github.repository_owner }}
TF_VAR_state_service_registry_password: ${{ secrets.STATE_SERVICE_REGISTRY_PASSWORD || '' }}
TF_VAR_grafana_url: ${{ secrets.GRAFANA_URL || '' }}
jobs:
plan:
# PR into dev → dev | PR into main + label 'run-staging' → staging | Push to main/workflow_dispatch → prod
# Skip plan for PRs from forks (no repo secrets; avoids AADSTS700213)
# Runtime staging toggle: add PR label 'run-staging' to enable staging on PRs into main.
if: |
(github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false) &&
(
(github.event_name == 'push' && github.ref == 'refs/heads/main') ||
(github.event_name == 'workflow_dispatch') ||
(github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'dev') ||
(github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main' && contains(join(github.event.pull_request.labels.*.name, ','), 'run-staging'))
)
name: Plan ${{ matrix.environment }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
environment: ${{ (github.event_name == 'workflow_dispatch' && fromJSON('["prod"]')) || (github.event_name == 'push' && github.ref == 'refs/heads/main' && fromJSON('["prod"]')) || (github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'dev' && fromJSON('["dev"]')) || (github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main' && contains(join(github.event.pull_request.labels.*.name, ','), 'run-staging') && fromJSON('["staging"]')) || fromJSON('["prod"]') }}
environment: ${{ matrix.environment }}
defaults:
run:
working-directory: infra/env/${{ matrix.environment }}
env:
# Terraform Variables (Environment Specific)
TF_VAR_env: "${{ matrix.environment }}"
TF_VAR_projname: "aigateway"
TF_VAR_location: "southafricanorth"
TF_VAR_location_short: "san"
# Terraform Variables (Secrets & Config) - sourced from per-environment GitHub secrets
TF_VAR_azure_openai_endpoint: ${{ secrets.AZURE_OPENAI_ENDPOINT }}
TF_VAR_azure_openai_api_key: ${{ secrets.AZURE_OPENAI_API_KEY }}
TF_VAR_azure_openai_embedding_endpoint: ${{ secrets.AZURE_OPENAI_EMBEDDING_ENDPOINT }}
TF_VAR_azure_openai_embedding_api_key: ${{ secrets.AZURE_OPENAI_EMBEDDING_API_KEY }}
TF_VAR_gateway_key: ${{ secrets.AIGATEWAY_KEY }}
# Model Configuration (environment-specific to match deploy jobs)
TF_VAR_codex_model: ${{ matrix.environment == 'prod' && 'gpt-4o' || 'gpt-5.3-codex' }}
TF_VAR_codex_api_version: ${{ matrix.environment == 'prod' && '2025-01-01-preview' || '2025-04-01-preview' }}
TF_VAR_embedding_deployment: "text-embedding-3-large"
TF_VAR_embeddings_api_version: "2024-02-01"
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Quickcheck required secrets and config
shell: bash
run: |
set -euo pipefail
missing=0
required=(
AZURE_CLIENT_ID
AZURE_TENANT_ID
AZURE_SUBSCRIPTION_ID
TF_BACKEND_RG
TF_BACKEND_SA
TF_BACKEND_CONTAINER
TF_VAR_azure_openai_endpoint
TF_VAR_azure_openai_api_key
TF_VAR_gateway_key
)
for v in "${required[@]}"; do
if [ -z "${!v:-}" ]; then
echo "::error::Missing required value: ${v}"
missing=1
else
echo "${v}=SET"
fi
done
echo "TF_VAR_env=${TF_VAR_env:-unset}"
echo "TF_VAR_embedding_deployment=${TF_VAR_embedding_deployment:-unset}"
echo "TF_VAR_codex_model=${TF_VAR_codex_model:-unset}"
if [ -n "${TF_VAR_azure_openai_endpoint:-}" ]; then
echo "Azure OpenAI endpoint=${TF_VAR_azure_openai_endpoint}"
endpoint_host=$(echo "${TF_VAR_azure_openai_endpoint}" | sed -E 's#^https?://([^/]+)/?.*$#\1#')
echo "Azure OpenAI endpoint host=${endpoint_host}"
fi
if [ "${missing}" -ne 0 ]; then
exit 1
fi
- name: Azure Login
uses: azure/login@v2
with:
client-id: ${{ env.AZURE_CLIENT_ID }}
tenant-id: ${{ env.AZURE_TENANT_ID }}
subscription-id: ${{ env.AZURE_SUBSCRIPTION_ID }}
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.14.6
- name: Terraform Init
run: |
terraform init \
-backend-config="resource_group_name=${TF_BACKEND_RG}" \
-backend-config="storage_account_name=${TF_BACKEND_SA}" \
-backend-config="container_name=${TF_BACKEND_CONTAINER}" \
-backend-config="key=${{ matrix.environment }}.terraform.tfstate"
- name: Terraform Plan
run: |
terraform plan -out=tfplan
- name: Upload Plan
uses: actions/upload-artifact@v4
with:
name: tfplan-${{ matrix.environment }}
path: infra/env/${{ matrix.environment }}/tfplan
retention-days: 1
deploy-dev:
name: Deploy dev
needs: plan
if: github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'dev'
uses: ./.github/workflows/deploy-environment.yaml
with:
env_name: dev
tf_state_key: dev.terraform.tfstate
codex_model: gpt-5.3-codex
codex_api_version: 2025-04-01-preview
terraform_working_directory: infra/env/dev
smoke_retry_sleep: "10"
smoke_models_wait_sleep: "15"

Check failure on line 161 in .github/workflows/deploy.yaml

View workflow run for this annotation

GitHub Actions / Deploy AI Gateway

Invalid workflow file

The workflow is not valid. .github/workflows/deploy.yaml (Line: 161, Col: 32): Invalid input, smoke_models_wait_sleep is not defined in the referenced workflow.
smoke_models_wait_attempts: "1"
include_aoai_host_check: false
environment: dev
secrets:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
TF_BACKEND_RG: ${{ secrets.TF_BACKEND_RG }}
TF_BACKEND_SA: ${{ secrets.TF_BACKEND_SA }}
TF_BACKEND_CONTAINER: ${{ secrets.TF_BACKEND_CONTAINER }}
EXPECTED_AOAI_ENDPOINT_HOST: ${{ secrets.EXPECTED_AOAI_ENDPOINT_HOST }}
AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }}
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
AZURE_OPENAI_EMBEDDING_ENDPOINT: ${{ secrets.AZURE_OPENAI_EMBEDDING_ENDPOINT }}
AZURE_OPENAI_EMBEDDING_API_KEY: ${{ secrets.AZURE_OPENAI_EMBEDDING_API_KEY }}
AIGATEWAY_KEY: ${{ secrets.AIGATEWAY_KEY }}
STATE_SERVICE_CONTAINER_IMAGE: ${{ vars.STATE_SERVICE_CONTAINER_IMAGE }}
STATE_SERVICE_SHARED_TOKEN: ${{ secrets.STATE_SERVICE_SHARED_TOKEN }}
STATE_SERVICE_REGISTRY_PASSWORD: ${{ secrets.STATE_SERVICE_REGISTRY_PASSWORD }}
DASHBOARD_CONTAINER_IMAGE: ${{ vars.DASHBOARD_CONTAINER_IMAGE }}
GRAFANA_URL: ${{ secrets.GRAFANA_URL }}
deploy-staging:
name: Deploy staging
needs: plan
if: github.event_name == 'pull_request' && github.event.pull_request.base.ref == 'main' && contains(join(github.event.pull_request.labels.*.name, ','), 'run-staging')
uses: ./.github/workflows/deploy-environment.yaml
with:
env_name: staging
tf_state_key: staging.terraform.tfstate
codex_model: gpt-5.3-codex
codex_api_version: 2025-04-01-preview
terraform_working_directory: infra/env/staging
smoke_retry_sleep: "10"
smoke_models_wait_sleep: "15"
smoke_models_wait_attempts: "1"
include_aoai_host_check: false
environment: staging
secrets:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
TF_BACKEND_RG: ${{ secrets.TF_BACKEND_RG }}
TF_BACKEND_SA: ${{ secrets.TF_BACKEND_SA }}
TF_BACKEND_CONTAINER: ${{ secrets.TF_BACKEND_CONTAINER }}
EXPECTED_AOAI_ENDPOINT_HOST: ${{ secrets.EXPECTED_AOAI_ENDPOINT_HOST }}
AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }}
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
AZURE_OPENAI_EMBEDDING_ENDPOINT: ${{ secrets.AZURE_OPENAI_EMBEDDING_ENDPOINT }}
AZURE_OPENAI_EMBEDDING_API_KEY: ${{ secrets.AZURE_OPENAI_EMBEDDING_API_KEY }}
AIGATEWAY_KEY: ${{ secrets.AIGATEWAY_KEY }}
STATE_SERVICE_CONTAINER_IMAGE: ${{ vars.STATE_SERVICE_CONTAINER_IMAGE }}
STATE_SERVICE_SHARED_TOKEN: ${{ secrets.STATE_SERVICE_SHARED_TOKEN }}
STATE_SERVICE_REGISTRY_PASSWORD: ${{ secrets.STATE_SERVICE_REGISTRY_PASSWORD }}
DASHBOARD_CONTAINER_IMAGE: ${{ vars.DASHBOARD_CONTAINER_IMAGE }}
GRAFANA_URL: ${{ secrets.GRAFANA_URL }}
deploy-prod:
name: Deploy prod
needs: plan
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/main')
uses: ./.github/workflows/deploy-environment.yaml
with:
env_name: prod
tf_state_key: prod.terraform.tfstate
codex_model: gpt-4o
codex_api_version: 2025-01-01-preview
terraform_working_directory: infra/env/prod
smoke_retry_sleep: "15"
smoke_models_wait_sleep: "30"
smoke_models_wait_attempts: "3"
include_aoai_host_check: true
environment: prod
secrets:
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
TF_BACKEND_RG: ${{ secrets.TF_BACKEND_RG }}
TF_BACKEND_SA: ${{ secrets.TF_BACKEND_SA }}
TF_BACKEND_CONTAINER: ${{ secrets.TF_BACKEND_CONTAINER }}
EXPECTED_AOAI_ENDPOINT_HOST: ${{ secrets.EXPECTED_AOAI_ENDPOINT_HOST }}
AZURE_OPENAI_ENDPOINT: ${{ secrets.AZURE_OPENAI_ENDPOINT }}
AZURE_OPENAI_API_KEY: ${{ secrets.AZURE_OPENAI_API_KEY }}
AZURE_OPENAI_EMBEDDING_ENDPOINT: ${{ secrets.AZURE_OPENAI_EMBEDDING_ENDPOINT }}
AZURE_OPENAI_EMBEDDING_API_KEY: ${{ secrets.AZURE_OPENAI_EMBEDDING_API_KEY }}
AIGATEWAY_KEY: ${{ secrets.AIGATEWAY_KEY }}
STATE_SERVICE_CONTAINER_IMAGE: ${{ vars.STATE_SERVICE_CONTAINER_IMAGE }}
STATE_SERVICE_SHARED_TOKEN: ${{ secrets.STATE_SERVICE_SHARED_TOKEN }}
STATE_SERVICE_REGISTRY_PASSWORD: ${{ secrets.STATE_SERVICE_REGISTRY_PASSWORD }}
DASHBOARD_CONTAINER_IMAGE: ${{ vars.DASHBOARD_CONTAINER_IMAGE }}
GRAFANA_URL: ${{ secrets.GRAFANA_URL }}
# Legacy inline deployments removed - see deploy-environment.yaml