Fix/terra alignment #112
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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
|
||
| 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 | ||