Skip to content

Commit 8f072ef

Browse files
committed
fixing deployment for premium sku
1 parent efe1b74 commit 8f072ef

5 files changed

Lines changed: 162 additions & 151 deletions

File tree

tests/integration/all-resource-types/Deploy-SourceApim.ps1

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,14 @@ if ($Destroy) {
8383
# Deploy path
8484
# ---------------------------------------------------------------------------
8585
$bicepFile = Join-Path $PSScriptRoot 'source-apim.bicep'
86+
$postActivationBicepFile = Join-Path $PSScriptRoot 'source-apim-post-activation.bicep'
8687

8788
if (-not (Test-Path $bicepFile)) {
8889
Write-Error "Bicep file not found at: $bicepFile"
8990
}
91+
if (-not (Test-Path $postActivationBicepFile)) {
92+
Write-Error "Bicep file not found at: $postActivationBicepFile"
93+
}
9094

9195
# Verify az CLI is authenticated
9296
Write-Host "🔐 Verifying Azure CLI authentication..."
@@ -190,29 +194,30 @@ $result = $raw | ConvertFrom-Json
190194
# Extract outputs
191195
$outputs = $result.properties.outputs
192196

193-
# policyRestriction is created here (not in Bicep) because scope validation needs the APIM data-plane to be active.
194-
$isClassicSku = $SkuName -in @('Developer', 'Premium')
195-
if ($isClassicSku) {
196-
$apimServiceName = $outputs.apimServiceName.value
197-
Wait-ApimActivation -ResourceGroupName $ResourceGroupName -ApimName $apimServiceName | Out-Null
198-
199-
$restrictionName = 'src-restriction-ip'
200-
$productId = 'src-product-starter'
201-
$restrictionUrl = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$ResourceGroupName/providers/Microsoft.ApiManagement/service/$apimServiceName/policyRestrictions/$restrictionName?api-version=2024-05-01"
202-
$restrictionBody = (@{ properties = @{ scope = "/products/$productId"; requireBase = 'true' } } | ConvertTo-Json -Compress)
203-
204-
Write-Host "Creating policyRestriction '$restrictionName' (scope /products/$productId)..." -ForegroundColor Cyan
205-
$putReplacements = $azReplacements.Clone()
206-
$putReplacements[$apimServiceName] = Protect-ApimName -Value $apimServiceName
207-
Invoke-MaskedProcess -FilePath 'az' -Replacements $putReplacements -Arguments @(
208-
'rest', '--method', 'put',
209-
'--url', $restrictionUrl,
210-
'--body', $restrictionBody
211-
)
212-
if ($LASTEXITCODE -ne 0) {
213-
throw "Failed to create policyRestriction '$restrictionName' on APIM '$(Protect-ApimName -Value $apimServiceName)'"
214-
}
215-
Write-Host " policyRestriction created" -ForegroundColor Green
197+
# Deploy activation-sensitive APIM children after activation.
198+
$apimServiceName = $outputs.apimServiceName.value
199+
Wait-ApimActivation -ResourceGroupName $ResourceGroupName -ApimName $apimServiceName | Out-Null
200+
201+
$postDeploymentName = "source-apim-post-activation-$(Get-Date -Format 'yyyyMMddHHmmss')"
202+
$postReplacements = $azReplacements.Clone()
203+
$postReplacements[$apimServiceName] = Protect-ApimName -Value $apimServiceName
204+
$postArgs = @(
205+
'deployment', 'group', 'create',
206+
'--resource-group', $ResourceGroupName,
207+
'--name', $postDeploymentName,
208+
'--template-file', $postActivationBicepFile,
209+
'--parameters', "apimName=$apimServiceName", "skuName=$SkuName",
210+
'--output', 'json'
211+
) + $azVerbosity
212+
213+
Write-Host "Applying post-activation APIM resources..." -ForegroundColor Cyan
214+
$postRaw = Invoke-MaskedAzCommand -Replacements $postReplacements -Arguments $postArgs
215+
if ($LASTEXITCODE -ne 0) {
216+
Write-DeploymentFailureDetails `
217+
-ResourceGroupName $ResourceGroupName `
218+
-DeploymentName $postDeploymentName `
219+
-Replacements $postReplacements
220+
throw "Source post-activation deployment failed (deployment '$postDeploymentName' in resource group '$(Protect-ResourceGroupName -Value $ResourceGroupName)'). See failed-operation details above."
216221
}
217222

218223
Write-Host ""

tests/integration/all-resource-types/expected-structure.json

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -299,23 +299,6 @@
299299
}
300300
]
301301
},
302-
"documentations": {
303-
"minCount": 1,
304-
"skuDependent": true,
305-
"skuFilter": ["Developer", "Premium"],
306-
"expected": [
307-
{
308-
"name": "src-doc-getting-started",
309-
"files": ["documentationInformation.json"],
310-
"spotChecks": {
311-
"documentationInformation.json": {
312-
"properties.title": "Getting Started",
313-
"properties.content": "exists"
314-
}
315-
}
316-
}
317-
]
318-
},
319302
"products": {
320303
"minCount": 2,
321304
"expected": [
@@ -344,7 +327,7 @@
344327
"note": "ProductTag is embedded in productInformation.json, not separate files"
345328
}
346329
},
347-
"notes": "Product wiki exists but is stored as wiki.md, not in wikis/ directory"
330+
"notes": "Wiki/documentation resources are disabled for cross-environment reliability"
348331
},
349332
{
350333
"name": "src-product-premium",

tests/integration/all-resource-types/run-roundtrip-test.ps1

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,27 @@ try {
451451
$apimName
452452
}
453453

454+
# Ensure post-activation deployment completed before extract/structure validation.
455+
if ($SkuName -in @('Developer', 'Premium')) {
456+
$postActivationState = az deployment group list `
457+
--resource-group $sourceRg `
458+
--query "sort_by([?starts_with(name, 'source-apim-post-activation-')], &properties.timestamp)[-1].properties.provisioningState" `
459+
-o tsv 2>$null
460+
if (-not $postActivationState) {
461+
Write-Host "❌ Could not find source-apim-post-activation deployment in $(Protect-ResourceGroupName -Value $sourceRg)"
462+
$exitCode = 2
463+
Invoke-Teardown
464+
exit $exitCode
465+
}
466+
if ($postActivationState -ne 'Succeeded') {
467+
Write-Host "❌ source-apim-post-activation deployment state is '$postActivationState' (expected 'Succeeded')"
468+
$exitCode = 2
469+
Invoke-Teardown
470+
exit $exitCode
471+
}
472+
Write-Host " ✅ source-apim-post-activation deployment confirmed"
473+
}
474+
454475
# -----------------------------------------------------------------------
455476
# Phase 2: Extract
456477
# -----------------------------------------------------------------------
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
@description('Existing APIM name to apply activation-sensitive child resources to.')
2+
param apimName string
3+
4+
@description('APIM SKU name. Classic SKUs support docs/wiki/policyRestriction.')
5+
@allowed(['Developer', 'Premium', 'StandardV2', 'PremiumV2'])
6+
param skuName string
7+
8+
var isClassicSku = skuName == 'Developer' || skuName == 'Premium'
9+
10+
var servicePolicyXml = '''
11+
<policies>
12+
<inbound>
13+
<cors allow-credentials="false">
14+
<allowed-origins>
15+
<origin>https://developer.contoso.com</origin>
16+
</allowed-origins>
17+
<allowed-methods><method>GET</method><method>POST</method></allowed-methods>
18+
<allowed-headers><header>Content-Type</header><header>Authorization</header></allowed-headers>
19+
</cors>
20+
</inbound>
21+
<backend />
22+
<outbound />
23+
<on-error />
24+
</policies>
25+
'''
26+
27+
var apiPolicyXml = '''
28+
<policies>
29+
<inbound>
30+
<base />
31+
<set-header name="X-all-resources" exists-action="override">
32+
<value>true</value>
33+
</set-header>
34+
</inbound>
35+
<backend><base /></backend>
36+
<outbound><base /></outbound>
37+
<on-error><base /></on-error>
38+
</policies>
39+
'''
40+
41+
var productPolicyXml = '''
42+
<policies>
43+
<inbound>
44+
<base />
45+
<rate-limit calls="1000" renewal-period="300" />
46+
</inbound>
47+
<backend><base /></backend>
48+
<outbound><base /></outbound>
49+
<on-error><base /></on-error>
50+
</policies>
51+
'''
52+
53+
resource apim 'Microsoft.ApiManagement/service@2025-09-01-preview' existing = {
54+
name: apimName
55+
}
56+
57+
resource productStarter 'Microsoft.ApiManagement/service/products@2025-09-01-preview' existing = {
58+
parent: apim
59+
name: 'src-product-starter'
60+
}
61+
62+
resource productPremium 'Microsoft.ApiManagement/service/products@2025-09-01-preview' existing = {
63+
parent: apim
64+
name: 'src-product-premium'
65+
}
66+
67+
resource apiRestOpenapi 'Microsoft.ApiManagement/service/apis@2025-09-01-preview' existing = {
68+
parent: apim
69+
name: 'src-rest-openapi'
70+
}
71+
72+
resource servicePolicy 'Microsoft.ApiManagement/service/policies@2025-09-01-preview' = {
73+
parent: apim
74+
name: 'policy'
75+
properties: {
76+
format: 'rawxml'
77+
value: servicePolicyXml
78+
}
79+
}
80+
81+
resource productPremiumPolicy 'Microsoft.ApiManagement/service/products/policies@2025-09-01-preview' = {
82+
parent: productPremium
83+
name: 'policy'
84+
properties: {
85+
format: 'rawxml'
86+
value: productPolicyXml
87+
}
88+
}
89+
90+
resource apiRestPolicy 'Microsoft.ApiManagement/service/apis/policies@2025-09-01-preview' = {
91+
parent: apiRestOpenapi
92+
name: 'policy'
93+
properties: {
94+
format: 'rawxml'
95+
value: apiPolicyXml
96+
}
97+
}
98+
99+
resource policyRestriction 'Microsoft.ApiManagement/service/policyRestrictions@2025-09-01-preview' = if (isClassicSku) {
100+
parent: apim
101+
name: 'src-restriction-ip'
102+
properties: {
103+
scope: '/products/src-product-starter'
104+
requireBase: 'true'
105+
}
106+
}

0 commit comments

Comments
 (0)