Skip to content
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
1 change: 1 addition & 0 deletions .github/workflows/agent-evaluation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ jobs:
agent-evaluation:
name: Agent Quality Evaluation
runs-on: ubuntu-latest
environment: ${{ inputs.environment || 'integration' }}
permissions:
contents: read
id-token: write # Needed for OIDC → DefaultAzureCredential
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/destroy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
terraform_destroy:
name: Terraform Destroy
runs-on: ubuntu-latest
# environment: ${{ inputs.environment || 'dev' }} # Commented out to use repo-level variables
environment: ${{ inputs.environment || 'integration' }}
permissions:
id-token: write
contents: read
Expand Down Expand Up @@ -66,13 +66,14 @@ jobs:
-var subscription_id=${{ vars.AZURE_SUBSCRIPTION_ID }} \
-var acr_name=${{ vars.ACR_NAME }} \
-var location=${{ vars.AZ_REGION }} \
-var environment=${{ inputs.environment || 'dev' }} \
-var environment=${{ inputs.environment || 'integration' }} \
-var docker_image_mcp=${{ vars.DOCKER_IMAGE_MCP }} \
-var docker_image_backend=${{ vars.DOCKER_IMAGE_BACKEND }} \
-var iteration=${{ inputs.environment || 'dev' }}
-var iteration=${{ vars.ITERATION }}
env:
TFSTATE_RG: ${{ vars.TFSTATE_RG }}
TFSTATE_ACCOUNT: ${{ vars.TFSTATE_ACCOUNT }}
TFSTATE_CONTAINER: ${{ vars.TFSTATE_CONTAINER }}
TFSTATE_KEY: "${{ github.event.repository.name }}-${{ github.ref_name }}.tfstate"
# Use environment name for state key — must match infrastructure.yml
TFSTATE_KEY: "${{ github.event.repository.name }}-${{ inputs.environment || 'integration' }}.tfstate"

5 changes: 3 additions & 2 deletions .github/workflows/docker-application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
build:
name: Build & Push Backend Image
runs-on: ubuntu-latest
# environment: ${{ inputs.environment || 'dev' }} # Commented out to use repo-level variables
environment: ${{ inputs.environment || 'integration' }}
permissions:
id-token: write
contents: read
Expand All @@ -46,10 +46,11 @@ jobs:
id: acr
run: |
# Construct ACR name matching Terraform pattern: {project}{env}acr{iteration}
# ACR names must be alphanumeric — strip hyphens to match Terraform's replace("-", "")
PROJECT="${{ vars.PROJECT_NAME || 'OpenAIWorkshop' }}"
ENV="${{ inputs.environment || 'dev' }}"
ITERATION="${{ vars.ITERATION || '002' }}"
ACR_NAME="${PROJECT}${ENV}acr${ITERATION}"
ACR_NAME=$(echo "${PROJECT}${ENV}acr${ITERATION}" | tr -d '-')
echo "name=${ACR_NAME}" >> $GITHUB_OUTPUT
echo "server=${ACR_NAME}.azurecr.io" >> $GITHUB_OUTPUT
echo "Using ACR: ${ACR_NAME}"
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/docker-mcp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
build:
name: Build & Push MCP Image
runs-on: ubuntu-latest
# environment: ${{ inputs.environment || 'dev' }} # Commented out to use repo-level variables
environment: ${{ inputs.environment || 'integration' }}
permissions:
id-token: write
contents: read
Expand All @@ -46,10 +46,11 @@ jobs:
id: acr
run: |
# Construct ACR name matching Terraform pattern: {project}{env}acr{iteration}
# ACR names must be alphanumeric — strip hyphens to match Terraform's replace("-", "")
PROJECT="${{ vars.PROJECT_NAME || 'OpenAIWorkshop' }}"
ENV="${{ inputs.environment || 'dev' }}"
ITERATION="${{ vars.ITERATION || '002' }}"
ACR_NAME="${PROJECT}${ENV}acr${ITERATION}"
ACR_NAME=$(echo "${PROJECT}${ENV}acr${ITERATION}" | tr -d '-')
echo "name=${ACR_NAME}" >> $GITHUB_OUTPUT
echo "server=${ACR_NAME}.azurecr.io" >> $GITHUB_OUTPUT
echo "Using ACR: ${ACR_NAME}"
Expand Down
92 changes: 72 additions & 20 deletions .github/workflows/infrastructure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
tf:
name: Terraform Deployment
runs-on: ubuntu-latest
# environment: removed to use repo-level variables
environment: ${{ inputs.environment }}
if: ${{ (github.event_name == 'workflow_dispatch' && github.event.inputs.iac-tool || 'tf') == 'tf' }}
permissions:
id-token: write
Expand All @@ -65,13 +65,13 @@ jobs:
- name: Terraform Setup
uses: hashicorp/setup-terraform@v3

- name: Sanitize branch name for state key
- name: Sanitize environment name for state key
id: sanitize
run: |
# Replace / and other invalid chars with - for valid Azure blob name
BRANCH="${{ github.head_ref || github.ref_name }}"
SAFE_BRANCH=$(echo "$BRANCH" | sed 's/[^a-zA-Z0-9._-]/-/g')
echo "branch=$SAFE_BRANCH" >> $GITHUB_OUTPUT
ENV="${{ inputs.environment }}"
SAFE_ENV=$(echo "$ENV" | sed 's/[^a-zA-Z0-9._-]/-/g')
echo "env=$SAFE_ENV" >> $GITHUB_OUTPUT

- name: Terraform Init/Plan/Apply
id: terraform
Expand All @@ -82,21 +82,73 @@ jobs:
export ARM_TENANT_ID="${{ vars.AZURE_TENANT_ID }}"
export ARM_SUBSCRIPTION_ID="${{ vars.AZURE_SUBSCRIPTION_ID }}"

# Common -var flags used by plan and import
TF_VARS=(
-var project_name=${{ github.event.repository.name }}
-var environment=${{ inputs.environment }}
-var tenant_id=${{ vars.AZURE_TENANT_ID }}
-var subscription_id=${{ vars.AZURE_SUBSCRIPTION_ID }}
-var acr_name=${{ vars.ACR_NAME }}
-var location=${{ vars.AZ_REGION }}
-var docker_image_mcp=${{ vars.DOCKER_IMAGE_MCP }}
-var docker_image_backend=${{ vars.DOCKER_IMAGE_BACKEND }}
-var iteration=${{ vars.ITERATION }}
)

terraform init -backend-config="resource_group_name=${TFSTATE_RG}" \
-backend-config="key=${TFSTATE_KEY}" -backend-config="storage_account_name=${TFSTATE_ACCOUNT}" \
-backend-config="container_name=${TFSTATE_CONTAINER}" -backend-config="use_oidc=true" -backend-config="use_azuread_auth=true"
terraform plan -out tfplan \
-var project_name=${{ github.event.repository.name }} \
-var environment=${{ github.event_name == 'workflow_dispatch' && github.event.inputs.environment || (github.base_ref == 'main' && 'prod') || (github.base_ref == 'int-agentic' && 'integration') || 'dev' }} \
-var tenant_id=${{ vars.AZURE_TENANT_ID }} \
-var subscription_id=${{ vars.AZURE_SUBSCRIPTION_ID }} \
-var acr_name=${{ vars.ACR_NAME }} \
-var location=${{ vars.AZ_REGION }} \
-var docker_image_mcp=${{ vars.DOCKER_IMAGE_MCP }} \
-var docker_image_backend=${{ vars.DOCKER_IMAGE_BACKEND }} \
-var iteration=${{ (github.event_name != 'workflow_dispatch' && github.base_ref != 'main' && github.base_ref != 'int-agentic') && '${GITHUB_SHA:0:7}' || vars.ITERATION }}

terraform apply -auto-approve tfplan

# ── Apply with auto-import on "already exists" errors ──
# If a prior run partially created resources but crashed before recording
# them in state, Terraform will fail with "already exists". This loop
# detects those errors, auto-imports the orphaned resources, and retries.
MAX_ATTEMPTS=3
for attempt in $(seq 1 $MAX_ATTEMPTS); do
echo "🔄 Terraform apply attempt $attempt/$MAX_ATTEMPTS"

terraform plan -out tfplan "${TF_VARS[@]}"

if terraform apply -auto-approve tfplan 2>&1 | tee /tmp/tf_apply.log; then
echo "✅ Terraform apply succeeded"
break
fi

# Check if the failure is due to "already exists" errors
if ! grep -q "already exists" /tmp/tf_apply.log; then
echo "❌ Terraform failed with a non-import error"
cat /tmp/tf_apply.log
exit 1
fi

if [ "$attempt" -eq "$MAX_ATTEMPTS" ]; then
echo "❌ Terraform failed after $MAX_ATTEMPTS attempts"
cat /tmp/tf_apply.log
exit 1
fi

echo "⚠️ Detected 'already exists' errors — auto-importing orphaned resources..."

# Parse error output: extract terraform address and Azure resource ID pairs
# Error format: with azurerm_container_app.mcp,
# followed by: a resource with the ID "/.../containerApps/ca-mcp-002" already exists
while IFS= read -r line; do
# Extract the TF resource address (e.g. azurerm_container_app.mcp)
tf_addr=$(echo "$line" | grep -oP 'with \K[a-zA-Z0-9_.]+(?=,)')
# Extract the Azure resource ID
azure_id=$(echo "$line" | grep -oP 'the ID "\K[^"]+')

if [ -n "$tf_addr" ] && [ -n "$azure_id" ]; then
echo " 📥 Importing $tf_addr → $azure_id"
terraform import "${TF_VARS[@]}" "$tf_addr" "$azure_id" || true
fi
done < <(
# Combine consecutive lines so address + ID are on the same logical line
cat /tmp/tf_apply.log | tr '\n' '§' | sed 's/§│/│/g' | tr '§' '\n' | grep "already exists"
)

echo "🔁 Retrying terraform apply..."
done

output=$(terraform output -raw openai_endpoint 2>/dev/null || true)
echo "MODEL_ENDPOINT=$output" >> $GITHUB_OUTPUT
Expand All @@ -109,12 +161,12 @@ jobs:
TFSTATE_RG: ${{ vars.TFSTATE_RG }}
TFSTATE_ACCOUNT: ${{ vars.TFSTATE_ACCOUNT }}
TFSTATE_CONTAINER: ${{ vars.TFSTATE_CONTAINER }}
# Use sanitized branch name for valid Azure blob name
TFSTATE_KEY: "${{ github.event.repository.name }}-${{ steps.sanitize.outputs.branch }}.tfstate"
# Use environment name for state key — each env gets its own TF state
TFSTATE_KEY: "${{ github.event.repository.name }}-${{ steps.sanitize.outputs.env }}.tfstate"

bicep:
runs-on: ubuntu-latest
# environment: removed to use repo-level variables
environment: ${{ inputs.environment }}
if: ${{ (github.event_name == 'workflow_dispatch' && github.event.inputs.iac-tool || 'tf') == 'bicep' }}
permissions:
id-token: write
Expand Down
Loading
Loading