Skip to content

Commit 9a46db0

Browse files
Merge pull request #757 from microsoft/psl-30705
fix: Map inputs to environment variables and Add input validation for workflow parameters
2 parents 89b8eed + 621ea95 commit 9a46db0

File tree

5 files changed

+571
-75
lines changed

5 files changed

+571
-75
lines changed

.github/workflows/job-deploy-linux.yml

Lines changed: 183 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,145 @@ jobs:
5454
- name: Checkout Code
5555
uses: actions/checkout@v4
5656

57+
- name: Validate Workflow Input Parameters
58+
shell: bash
59+
env:
60+
INPUT_ENV_NAME: ${{ inputs.ENV_NAME }}
61+
INPUT_AZURE_ENV_OPENAI_LOCATION: ${{ inputs.AZURE_ENV_OPENAI_LOCATION }}
62+
INPUT_AZURE_LOCATION: ${{ inputs.AZURE_LOCATION }}
63+
INPUT_RESOURCE_GROUP_NAME: ${{ inputs.RESOURCE_GROUP_NAME }}
64+
INPUT_IMAGE_TAG: ${{ inputs.IMAGE_TAG }}
65+
INPUT_BUILD_DOCKER_IMAGE: ${{ inputs.BUILD_DOCKER_IMAGE }}
66+
INPUT_EXP: ${{ inputs.EXP }}
67+
INPUT_WAF_ENABLED: ${{ inputs.WAF_ENABLED }}
68+
INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: ${{ inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }}
69+
INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: ${{ inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID }}
70+
run: |
71+
echo "🔍 Validating workflow input parameters..."
72+
VALIDATION_FAILED=false
73+
74+
# Validate ENV_NAME (required, alphanumeric and hyphens)
75+
if [[ -z "$INPUT_ENV_NAME" ]]; then
76+
echo "❌ ERROR: ENV_NAME is required but not provided"
77+
VALIDATION_FAILED=true
78+
elif [[ ! "$INPUT_ENV_NAME" =~ ^[a-zA-Z0-9-]+$ ]]; then
79+
echo "❌ ERROR: ENV_NAME '$INPUT_ENV_NAME' is invalid. Must contain only alphanumerics and hyphens"
80+
VALIDATION_FAILED=true
81+
else
82+
echo "✅ ENV_NAME: '$INPUT_ENV_NAME' is valid"
83+
fi
84+
85+
# Validate AZURE_ENV_OPENAI_LOCATION (required, Azure region format)
86+
if [[ -z "$INPUT_AZURE_ENV_OPENAI_LOCATION" ]]; then
87+
echo "❌ ERROR: AZURE_ENV_OPENAI_LOCATION is required but not provided"
88+
VALIDATION_FAILED=true
89+
elif [[ ! "$INPUT_AZURE_ENV_OPENAI_LOCATION" =~ ^[a-z0-9]+$ ]]; then
90+
echo "❌ ERROR: AZURE_ENV_OPENAI_LOCATION '$INPUT_AZURE_ENV_OPENAI_LOCATION' is invalid. Must contain only lowercase letters and numbers"
91+
VALIDATION_FAILED=true
92+
else
93+
echo "✅ AZURE_ENV_OPENAI_LOCATION: '$INPUT_AZURE_ENV_OPENAI_LOCATION' is valid"
94+
fi
95+
96+
# Validate AZURE_LOCATION (required, Azure region format)
97+
if [[ -z "$INPUT_AZURE_LOCATION" ]]; then
98+
echo "❌ ERROR: AZURE_LOCATION is required but not provided"
99+
VALIDATION_FAILED=true
100+
elif [[ ! "$INPUT_AZURE_LOCATION" =~ ^[a-z0-9]+$ ]]; then
101+
echo "❌ ERROR: AZURE_LOCATION '$INPUT_AZURE_LOCATION' is invalid. Must contain only lowercase letters and numbers"
102+
VALIDATION_FAILED=true
103+
else
104+
echo "✅ AZURE_LOCATION: '$INPUT_AZURE_LOCATION' is valid"
105+
fi
106+
107+
# Validate RESOURCE_GROUP_NAME (required, Azure naming convention)
108+
if [[ -z "$INPUT_RESOURCE_GROUP_NAME" ]]; then
109+
echo "❌ ERROR: RESOURCE_GROUP_NAME is required but not provided"
110+
VALIDATION_FAILED=true
111+
elif [[ ! "$INPUT_RESOURCE_GROUP_NAME" =~ ^[a-zA-Z0-9._\(\)-]+$ ]] || [[ "$INPUT_RESOURCE_GROUP_NAME" =~ \.$ ]]; then
112+
echo "❌ ERROR: RESOURCE_GROUP_NAME '$INPUT_RESOURCE_GROUP_NAME' is invalid. Must contain only alphanumerics, periods, underscores, hyphens, and parentheses. Cannot end with period."
113+
VALIDATION_FAILED=true
114+
elif [[ ${#INPUT_RESOURCE_GROUP_NAME} -gt 90 ]]; then
115+
echo "❌ ERROR: RESOURCE_GROUP_NAME '$INPUT_RESOURCE_GROUP_NAME' exceeds 90 characters"
116+
VALIDATION_FAILED=true
117+
else
118+
echo "✅ RESOURCE_GROUP_NAME: '$INPUT_RESOURCE_GROUP_NAME' is valid"
119+
fi
120+
121+
# Validate IMAGE_TAG (required, Docker tag pattern)
122+
if [[ -z "$INPUT_IMAGE_TAG" ]]; then
123+
echo "❌ ERROR: IMAGE_TAG is required but not provided"
124+
VALIDATION_FAILED=true
125+
elif [[ ! "$INPUT_IMAGE_TAG" =~ ^[a-zA-Z0-9_][a-zA-Z0-9._-]{0,127}$ ]]; then
126+
echo "❌ ERROR: IMAGE_TAG '$INPUT_IMAGE_TAG' is invalid. Must start with alphanumeric or underscore, max 128 characters"
127+
VALIDATION_FAILED=true
128+
else
129+
echo "✅ IMAGE_TAG: '$INPUT_IMAGE_TAG' is valid"
130+
fi
131+
132+
# Validate BUILD_DOCKER_IMAGE (required, must be 'true' or 'false')
133+
if [[ "$INPUT_BUILD_DOCKER_IMAGE" != "true" && "$INPUT_BUILD_DOCKER_IMAGE" != "false" ]]; then
134+
echo "❌ ERROR: BUILD_DOCKER_IMAGE must be 'true' or 'false', got: '$INPUT_BUILD_DOCKER_IMAGE'"
135+
VALIDATION_FAILED=true
136+
else
137+
echo "✅ BUILD_DOCKER_IMAGE: '$INPUT_BUILD_DOCKER_IMAGE' is valid"
138+
fi
139+
140+
# Validate EXP (required, must be 'true' or 'false')
141+
if [[ "$INPUT_EXP" != "true" && "$INPUT_EXP" != "false" ]]; then
142+
echo "❌ ERROR: EXP must be 'true' or 'false', got: '$INPUT_EXP'"
143+
VALIDATION_FAILED=true
144+
else
145+
echo "✅ EXP: '$INPUT_EXP' is valid"
146+
fi
147+
148+
# Validate WAF_ENABLED (must be 'true' or 'false')
149+
if [[ "$INPUT_WAF_ENABLED" != "true" && "$INPUT_WAF_ENABLED" != "false" ]]; then
150+
echo "❌ ERROR: WAF_ENABLED must be 'true' or 'false', got: '$INPUT_WAF_ENABLED'"
151+
VALIDATION_FAILED=true
152+
else
153+
echo "✅ WAF_ENABLED: '$INPUT_WAF_ENABLED' is valid"
154+
fi
155+
156+
# Validate AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID (optional, if provided must be valid Resource ID)
157+
if [[ -n "$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID" ]]; then
158+
if [[ ! "$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID" =~ ^/subscriptions/[a-fA-F0-9-]+/resourceGroups/[^/]+/providers/microsoft\.operationalinsights/workspaces/[^/]+$ ]]; then
159+
echo "❌ ERROR: AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID is invalid. Must be a valid Azure Resource ID format:"
160+
echo " /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.OperationalInsights/workspaces/{workspaceName}"
161+
echo " Got: '$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID'"
162+
VALIDATION_FAILED=true
163+
else
164+
echo "✅ AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: Valid Resource ID format"
165+
fi
166+
fi
167+
168+
# Validate AZURE_EXISTING_AI_PROJECT_RESOURCE_ID (optional, if provided must be valid Resource ID)
169+
if [[ -n "$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID" ]]; then
170+
if [[ ! "$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID" =~ ^/subscriptions/[a-fA-F0-9-]+/resourceGroups/[^/]+/providers/(Microsoft\.MachineLearningServices/(workspaces|projects)/[^/]+|Microsoft\.CognitiveServices/accounts/[^/]+/projects/[^/]+)$ ]]; then
171+
echo "❌ ERROR: AZURE_EXISTING_AI_PROJECT_RESOURCE_ID is invalid. Must be a valid Azure Resource ID format:"
172+
echo " /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CognitiveServices/accounts/{accountName}/projects/{projectName}"
173+
echo " Got: '$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID'"
174+
VALIDATION_FAILED=true
175+
else
176+
echo "✅ AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: Valid Resource ID format"
177+
fi
178+
fi
179+
180+
# Fail workflow if any validation failed
181+
if [[ "$VALIDATION_FAILED" == "true" ]]; then
182+
echo ""
183+
echo "❌ Parameter validation failed. Please correct the errors above and try again."
184+
exit 1
185+
fi
186+
187+
echo ""
188+
echo "✅ All input parameters validated successfully!"
189+
57190
- name: Configure Parameters Based on WAF Setting
58191
shell: bash
192+
env:
193+
INPUT_WAF_ENABLED: ${{ inputs.WAF_ENABLED }}
59194
run: |
60-
if [[ "${{ inputs.WAF_ENABLED }}" == "true" ]]; then
195+
if [[ "$INPUT_WAF_ENABLED" == "true" ]]; then
61196
cp infra/main.waf.parameters.json infra/main.parameters.json
62197
echo "✅ Successfully copied WAF parameters to main parameters file"
63198
else
@@ -87,44 +222,54 @@ jobs:
87222
- name: Deploy using azd up and extract values (Linux)
88223
id: get_output_linux
89224
shell: bash
225+
env:
226+
INPUT_ENV_NAME: ${{ inputs.ENV_NAME }}
227+
INPUT_AZURE_ENV_OPENAI_LOCATION: ${{ inputs.AZURE_ENV_OPENAI_LOCATION }}
228+
INPUT_AZURE_LOCATION: ${{ inputs.AZURE_LOCATION }}
229+
INPUT_RESOURCE_GROUP_NAME: ${{ inputs.RESOURCE_GROUP_NAME }}
230+
INPUT_IMAGE_TAG: ${{ inputs.IMAGE_TAG }}
231+
INPUT_BUILD_DOCKER_IMAGE: ${{ inputs.BUILD_DOCKER_IMAGE }}
232+
INPUT_EXP: ${{ inputs.EXP }}
233+
INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID: ${{ inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }}
234+
INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID: ${{ inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID }}
90235
run: |
91236
set -e
92237
# Install azd (Azure Developer CLI)
93238
curl -fsSL https://aka.ms/install-azd.sh | bash
94239
95240
echo "Creating environment..."
96-
azd env new ${{ inputs.ENV_NAME }} --no-prompt
97-
echo "Environment created: ${{ inputs.ENV_NAME }}"
241+
azd env new $INPUT_ENV_NAME --no-prompt
242+
echo "Environment created: $INPUT_ENV_NAME"
98243
99244
echo "Setting default subscription..."
100245
azd config set defaults.subscription ${{ secrets.AZURE_SUBSCRIPTION_ID }}
101246
102247
# Set additional parameters
103248
azd env set AZURE_SUBSCRIPTION_ID="${{ secrets.AZURE_SUBSCRIPTION_ID }}"
104-
azd env set AZURE_ENV_OPENAI_LOCATION="${{ inputs.AZURE_ENV_OPENAI_LOCATION }}"
105-
azd env set AZURE_LOCATION="${{ inputs.AZURE_LOCATION }}"
106-
azd env set AZURE_RESOURCE_GROUP="${{ inputs.RESOURCE_GROUP_NAME }}"
107-
azd env set AZURE_ENV_IMAGE_TAG="${{ inputs.IMAGE_TAG }}"
249+
azd env set AZURE_ENV_OPENAI_LOCATION="$INPUT_AZURE_ENV_OPENAI_LOCATION"
250+
azd env set AZURE_LOCATION="$INPUT_AZURE_LOCATION"
251+
azd env set AZURE_RESOURCE_GROUP="$INPUT_RESOURCE_GROUP_NAME"
252+
azd env set AZURE_ENV_IMAGE_TAG="$INPUT_IMAGE_TAG"
108253
109-
if [[ "${{ inputs.BUILD_DOCKER_IMAGE }}" == "true" ]]; then
254+
if [[ "$INPUT_BUILD_DOCKER_IMAGE" == "true" ]]; then
110255
ACR_NAME=$(echo "${{ secrets.ACR_TEST_LOGIN_SERVER }}")
111256
azd env set AZURE_ENV_CONTAINER_REGISTRY_ENDPOINT="$ACR_NAME"
112257
echo "Set ACR name to: $ACR_NAME"
113258
else
114259
echo "Skipping ACR name configuration (using existing image)"
115260
fi
116261
117-
if [[ "${{ inputs.EXP }}" == "true" ]]; then
262+
if [[ "$INPUT_EXP" == "true" ]]; then
118263
echo "✅ EXP ENABLED - Setting EXP parameters..."
119264
120-
if [[ -n "${{ inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }}" ]]; then
121-
EXP_LOG_ANALYTICS_ID="${{ inputs.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }}"
265+
if [[ -n "$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID" ]]; then
266+
EXP_LOG_ANALYTICS_ID="$INPUT_AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID"
122267
else
123268
EXP_LOG_ANALYTICS_ID="${{ secrets.AZURE_ENV_LOG_ANALYTICS_WORKSPACE_ID }}"
124269
fi
125270
126-
if [[ -n "${{ inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID }}" ]]; then
127-
EXP_AI_PROJECT_ID="${{ inputs.AZURE_EXISTING_AI_PROJECT_RESOURCE_ID }}"
271+
if [[ -n "$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID" ]]; then
272+
EXP_AI_PROJECT_ID="$INPUT_AZURE_EXISTING_AI_PROJECT_RESOURCE_ID"
128273
else
129274
EXP_AI_PROJECT_ID="${{ secrets.AZURE_ENV_FOUNDRY_PROJECT_ID }}"
130275
fi
@@ -169,13 +314,15 @@ jobs:
169314
echo "WEBAPP_URL=$WEBAPP_URL" >> $GITHUB_OUTPUT
170315
171316
- name: Run Post deployment scripts
317+
env:
318+
INPUT_RESOURCE_GROUP_NAME: ${{ inputs.RESOURCE_GROUP_NAME }}
172319
run: |
173320
set -e
174321
az account set --subscription "${{ secrets.AZURE_SUBSCRIPTION_ID }}"
175322
176323
# Set environment variables for selecting_team_config_and_data.sh
177324
export AZURE_SUBSCRIPTION_ID="${{ secrets.AZURE_SUBSCRIPTION_ID }}"
178-
export AZURE_RESOURCE_GROUP="${{ inputs.RESOURCE_GROUP_NAME }}"
325+
export AZURE_RESOURCE_GROUP="$INPUT_RESOURCE_GROUP_NAME"
179326
export BACKEND_URL="${{ steps.get_output_linux.outputs.BACKEND_URL }}"
180327
export AZURE_STORAGE_ACCOUNT_NAME="${{ steps.get_output_linux.outputs.AZURE_STORAGE_ACCOUNT_NAME }}"
181328
export AZURE_STORAGE_CONTAINER_NAME="sample-dataset"
@@ -190,17 +337,34 @@ jobs:
190337
- name: Generate Deployment Summary
191338
if: always()
192339
shell: bash
340+
env:
341+
INPUT_RESOURCE_GROUP_NAME: ${{ inputs.RESOURCE_GROUP_NAME }}
342+
INPUT_WAF_ENABLED: ${{ inputs.WAF_ENABLED }}
343+
INPUT_EXP: ${{ inputs.EXP }}
344+
INPUT_AZURE_LOCATION: ${{ inputs.AZURE_LOCATION }}
345+
INPUT_AZURE_ENV_OPENAI_LOCATION: ${{ inputs.AZURE_ENV_OPENAI_LOCATION }}
346+
INPUT_IMAGE_TAG: ${{ inputs.IMAGE_TAG }}
193347
run: |
194348
echo "## 🚀 Deploy Job Summary (Linux)" >> $GITHUB_STEP_SUMMARY
195349
echo "" >> $GITHUB_STEP_SUMMARY
196350
echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
197351
echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY
198352
echo "| **Job Status** | ${{ job.status == 'success' && '✅ Success' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY
199-
echo "| **Resource Group** | \`${{ inputs.RESOURCE_GROUP_NAME }}\` |" >> $GITHUB_STEP_SUMMARY
200-
echo "| **Configuration Type** | \`${{ inputs.WAF_ENABLED == 'true' && inputs.EXP == 'true' && 'WAF + EXP' || inputs.WAF_ENABLED == 'true' && inputs.EXP != 'true' && 'WAF + Non-EXP' || inputs.WAF_ENABLED != 'true' && inputs.EXP == 'true' && 'Non-WAF + EXP' || 'Non-WAF + Non-EXP' }}\` |" >> $GITHUB_STEP_SUMMARY
201-
echo "| **Azure Region (Infrastructure)** | \`${{ inputs.AZURE_LOCATION }}\` |" >> $GITHUB_STEP_SUMMARY
202-
echo "| **Azure OpenAI Region** | \`${{ inputs.AZURE_ENV_OPENAI_LOCATION }}\` |" >> $GITHUB_STEP_SUMMARY
203-
echo "| **Docker Image Tag** | \`${{ inputs.IMAGE_TAG }}\` |" >> $GITHUB_STEP_SUMMARY
353+
echo "| **Resource Group** | \`$INPUT_RESOURCE_GROUP_NAME\` |" >> $GITHUB_STEP_SUMMARY
354+
CONFIG_TYPE=""
355+
if [[ "$INPUT_WAF_ENABLED" == "true" && "$INPUT_EXP" == "true" ]]; then
356+
CONFIG_TYPE="WAF + EXP"
357+
elif [[ "$INPUT_WAF_ENABLED" == "true" && "$INPUT_EXP" != "true" ]]; then
358+
CONFIG_TYPE="WAF + Non-EXP"
359+
elif [[ "$INPUT_WAF_ENABLED" != "true" && "$INPUT_EXP" == "true" ]]; then
360+
CONFIG_TYPE="Non-WAF + EXP"
361+
else
362+
CONFIG_TYPE="Non-WAF + Non-EXP"
363+
fi
364+
echo "| **Configuration Type** | \`$CONFIG_TYPE\` |" >> $GITHUB_STEP_SUMMARY
365+
echo "| **Azure Region (Infrastructure)** | \`$INPUT_AZURE_LOCATION\` |" >> $GITHUB_STEP_SUMMARY
366+
echo "| **Azure OpenAI Region** | \`$INPUT_AZURE_ENV_OPENAI_LOCATION\` |" >> $GITHUB_STEP_SUMMARY
367+
echo "| **Docker Image Tag** | \`$INPUT_IMAGE_TAG\` |" >> $GITHUB_STEP_SUMMARY
204368
echo "" >> $GITHUB_STEP_SUMMARY
205369
if [[ "${{ job.status }}" == "success" ]]; then
206370
echo "### ✅ Deployment Details" >> $GITHUB_STEP_SUMMARY

0 commit comments

Comments
 (0)