Skip to content

Solution#34

Open
LitvinchukRoman wants to merge 2 commits into
mate-academy:mainfrom
LitvinchukRoman:main
Open

Solution#34
LitvinchukRoman wants to merge 2 commits into
mate-academy:mainfrom
LitvinchukRoman:main

Conversation

@LitvinchukRoman

Copy link
Copy Markdown

No description provided.

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

I’m requesting changes because there are critical blockers that will break artifact generation/validation and violate explicit requirements.

  • Artifacts container/name mismatch (blocker): artifacts.json points to task-artifacts, but task.ps1 creates task-atrifacts (typo). This prevents upload/download of exported-template.json. Fix the container name in task.ps1 (or update artifacts.json to the actual path) and ensure the SAS URL is valid and the file exists at artifacts.json.resourcesTemplate.
  • NSG naming requirement (blocker): The task requires each NSG name to exactly match its subnet name. In task.ps1, NSGs are created with a -nsg suffix; change to use webservers, management, database exactly (e.g., -Name $webSubnetName). Also ensure deployment parameters in result.json set those exact names.
  • Validation script inaccuracies (blocker for reliable grading): In scripts/validate-artifacts.ps1, success messages don’t match the checks (webservers expects 3 rules; management 2; database 1). Update messages to match counts, re-enable the webservers port checks (80/443 from Internet), and add sourceAddressPrefix -eq 'Internet' to the SSH rule check.

Minor/cleanup:

  • In result.json, remove the misspelled container resource task-atrifacts (lines 496–511) and keep only the correct task-artifacts (lines 479–494). Consider consolidating duplicate securityRules (inline vs child resources) to avoid confusion.

Once fixed, re-deploy to the required resource group, regenerate artifacts, and re-run validation. The rule logic itself looks solid—great work there. Keep going; you’re close!


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Important

Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.

Tip

If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.

Caution

Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.

Footnotes

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

Comment thread artifacts.json
@@ -1,3 +1,3 @@
{
"resourcesTemplate": ""
"resourcesTemplate": "https://storageac88.blob.core.windows.net/task-artifacts/task16/exported-template.json?sv=2025-05-05&se=2025-10-31T00%3A21%3A42Z&sr=b&sp=r&sig=PWWf7gJLK%2BJzmSlo1%2Bh8WjCp%2B09mDWxfdwEgkLpyE9A%3D"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The URL on this line points at the container task-artifacts and the exported template location. Confirm that this exact path exists and that the SAS URL remains valid. The validation script downloads the template from artifacts.json.resourcesTemplate, so if the file is not present at this location the validation will fail (scripts/validate-artifacts.ps1 reads this value and invokes Invoke-WebRequest) . If you intend to keep the current URL, ensure your deployment creates the container and uploads exported-template.json to this path.

Comment thread result.json
Comment on lines +496 to +511
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2025-01-01",
"name": "[concat(parameters('storageAccounts_storageac88_name'), '/default/task-atrifacts')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', parameters('storageAccounts_storageac88_name'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_storageac88_name'))]"
],
"properties": {
"immutableStorageWithVersioning": {
"enabled": false
},
"defaultEncryptionScope": "$account-encryption-key",
"denyEncryptionScopeOverride": false,
"publicAccess": "None"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a misspelled storage container resource named task-atrifacts. The artifacts generation expects task-artifacts — the typo will prevent artifact upload and later validation. Remove the incorrect container resource or rename it to task-artifacts so only the correct container exists. See the correct container resource at lines 479-494 and the typo at lines 496-511 in this file.

Comment thread result.json
Comment on lines +11 to +18
"networkSecurityGroups_database_nsg_name": {
"type": "String"
},
"networkSecurityGroups_management_nsg_name": {
"type": "String"
},
"networkSecurityGroups_webservers_nsg_name": {
"type": "String"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The template defines parameters for NSG names (e.g. networkSecurityGroups_webservers_nsg_name) but does not enforce concrete values here. The task requirement states each NSG must have the same name as its corresponding subnet (webservers, database, management). When you deploy/generate artifacts ensure the parameter values are set to those exact subnet names (no extra suffixes such as -nsg). If the parameters are populated incorrectly at deployment time, validation may fail. Relevant parameter block is shown here.

Comment thread result.json
Comment on lines +112 to +174
"securityRules": [
{
"name": "Allow-VNet",
"id": "[resourceId('Microsoft.Network/networkSecurityGroups/securityRules', parameters('networkSecurityGroups_webservers_nsg_name'), 'Allow-VNet')]",
"type": "Microsoft.Network/networkSecurityGroups/securityRules",
"properties": {
"description": "Allow all VNet traffic",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "*",
"sourceAddressPrefix": "VirtualNetwork",
"destinationAddressPrefix": "VirtualNetwork",
"access": "Allow",
"priority": 100,
"direction": "Inbound",
"sourcePortRanges": [],
"destinationPortRanges": [],
"sourceAddressPrefixes": [],
"destinationAddressPrefixes": []
}
},
{
"name": "Allow-HTTP",
"id": "[resourceId('Microsoft.Network/networkSecurityGroups/securityRules', parameters('networkSecurityGroups_webservers_nsg_name'), 'Allow-HTTP')]",
"type": "Microsoft.Network/networkSecurityGroups/securityRules",
"properties": {
"description": "Allow HTTP",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "80",
"sourceAddressPrefix": "Internet",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 200,
"direction": "Inbound",
"sourcePortRanges": [],
"destinationPortRanges": [],
"sourceAddressPrefixes": [],
"destinationAddressPrefixes": []
}
},
{
"name": "Allow-HTTPS",
"id": "[resourceId('Microsoft.Network/networkSecurityGroups/securityRules', parameters('networkSecurityGroups_webservers_nsg_name'), 'Allow-HTTPS')]",
"type": "Microsoft.Network/networkSecurityGroups/securityRules",
"properties": {
"description": "Allow HTTPS",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "443",
"sourceAddressPrefix": "Internet",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 210,
"direction": "Inbound",
"sourcePortRanges": [],
"destinationPortRanges": [],
"sourceAddressPrefixes": [],
"destinationAddressPrefixes": []
}
}
]
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The NSG rules for each NSG look correct and comply with requirements: Allow-VNet priority 100 (intra-VNet allow), webservers NSG includes inbound TCP 80 and 443 from Internet (priorities 200 and 210), management NSG includes inbound TCP 22 from Internet (priority 200), and database NSG only has the Allow-VNet rule. These are the expected rule semantics (source prefixes, directions and priorities). See webservers rules and management rules in the template.

Comment thread result.json
Comment on lines +213 to +280
{
"type": "Microsoft.Network/networkSecurityGroups/securityRules",
"apiVersion": "2024-07-01",
"name": "[concat(parameters('networkSecurityGroups_webservers_nsg_name'), '/Allow-HTTP')]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroups_webservers_nsg_name'))]"
],
"properties": {
"description": "Allow HTTP",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "80",
"sourceAddressPrefix": "Internet",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 200,
"direction": "Inbound",
"sourcePortRanges": [],
"destinationPortRanges": [],
"sourceAddressPrefixes": [],
"destinationAddressPrefixes": []
}
},
{
"type": "Microsoft.Network/networkSecurityGroups/securityRules",
"apiVersion": "2024-07-01",
"name": "[concat(parameters('networkSecurityGroups_webservers_nsg_name'), '/Allow-HTTPS')]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroups_webservers_nsg_name'))]"
],
"properties": {
"description": "Allow HTTPS",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "443",
"sourceAddressPrefix": "Internet",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 210,
"direction": "Inbound",
"sourcePortRanges": [],
"destinationPortRanges": [],
"sourceAddressPrefixes": [],
"destinationAddressPrefixes": []
}
},
{
"type": "Microsoft.Network/networkSecurityGroups/securityRules",
"apiVersion": "2024-07-01",
"name": "[concat(parameters('networkSecurityGroups_management_nsg_name'), '/Allow-SSH')]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroups_management_nsg_name'))]"
],
"properties": {
"description": "Allow SSH",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "22",
"sourceAddressPrefix": "Internet",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 200,
"direction": "Inbound",
"sourcePortRanges": [],
"destinationPortRanges": [],
"sourceAddressPrefixes": [],
"destinationAddressPrefixes": []
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are duplicated securityRules entries: security rules exist inline within NSG resources and also as separate Microsoft.Network/networkSecurityGroups/securityRules resources (for example the separate Allow-HTTP/Allow-HTTPS/Allow-SSH resources starting around line 213). While ARM exports sometimes produce both forms, having both can be confusing and could lead to management complexity. Consider consolidating (either inline or separate child resources) so the template is clearer. If you keep both, ensure they remain consistent.


$databaseNSG = ( $TemplateObject.resources | Where-Object -Property type -EQ "Microsoft.Network/networkSecurityGroups" | Where-Object {$_.name.Contains("database")})
if ($databaseNSG.properties.securityRules.Count -eq 0) {
if ($databaseNSG.properties.securityRules.Count -eq 1) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The database NSG check asserts Count -eq 1 (which corresponds to the Allow-VNet rule), but the success message says "Checked if database NSG has no rules - OK." This is contradictory. Update the message to reflect the actual expectation (1 rule: Allow-VNet) or change the test if the intended expectation differs. The current mismatch is confusing and may hide failures.

Comment thread task.ps1
-SourceAddressPrefix Internet -SourcePortRange * `
-DestinationAddressPrefix * -DestinationPortRange 443

$webnsg = New-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Location $location -Name "$webSubnetName-nsg" -SecurityRules $allowVnet,$allowHttp,$allowHttps

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NSG name uses a -nsg suffix. The task requires each NSG to have the same name as its corresponding subnet (i.e. webservers, database, management). Change the -Name parameter to use the subnet name variable directly, e.g. -Name $webSubnetName instead of -Name "$webSubnetName-nsg". Also ensure the resource group used is the required one (see other comment). This impacts validation which expects NSG names to match subnets. Requirement reference: each NSG must have the same name as its corresponding subnet.

Comment thread task.ps1
-SourceAddressPrefix Internet -SourcePortRange * `
-DestinationAddressPrefix * -DestinationPortRange 22

$mngnsg = New-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Location $location -Name "$mngSubnetName-nsg" -SecurityRules $allowVnet,$allowSsh

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue here for the management NSG. Use -Name $mngSubnetName (i.e. management) rather than -Name "$mngSubnetName-nsg". Also confirm the resource group variable is set to the required mate-resources before deployment so artifacts/validation target the correct RG.

Comment thread task.ps1
-SourceAddressPrefix VirtualNetwork -SourcePortRange * `
-DestinationAddressPrefix VirtualNetwork -DestinationPortRange *

$dbnsg = New-AzNetworkSecurityGroup -ResourceGroupName $resourceGroupName -Location $location -Name "$dbSubnetName-nsg" -SecurityRules $allowVnet

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue for the database NSG. Use -Name $dbSubnetName (i.e. database) instead of -Name "$dbSubnetName-nsg". The validate script expects NSGs attached and named after subnets. After renaming, re-deploy and re-run artifact generation/validation.

Comment thread task.ps1 Outdated

$storageKey = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroupName -Name $storageName)[0].Value
$ctx = New-AzStorageContext -StorageAccountName $storageName -StorageAccountKey $storageKey
New-AzStorageContainer -Name "task-atrifacts" -Context $ctx -Permission Off No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Storage container name is misspelled: you create task-atrifacts (missing a second 'c'). The artifacts generation/validation pipeline expects the container task-artifacts. Rename this to task-artifacts so scripts/generate-artifacts.ps1 can upload artifacts and scripts/validate-artifacts.ps1 can retrieve them. This typo will break the verification workflow.

@mateacademy-ai-mentor mateacademy-ai-mentor left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Decision: REQUEST_CHANGES — there are critical blockers that will break validation and task completion.

  • Critical blockers to fix:

    1. In result.json, remove the duplicate/misspelled storage container resource task-atrifacts (lines noted in comments). Keep only the correct task-artifacts resource to prevent artifact upload/download failures.
    2. In task.ps1, NSG names must exactly match subnet names (no “-nsg” suffix). Update New-AzNetworkSecurityGroup -Name to use webservers, management, and database exactly. This is required by the checklist and the validator depends on exact names.
    3. In scripts/validate-artifacts.ps1, re-enable the HTTP/HTTPS checks for webservers and ensure the SSH check verifies sourceAddressPrefix -eq 'Internet'. Also fix the error messages to match the expected rule counts (webservers=3, management=2, database=1) to avoid confusing failures.
  • Additional guidance:

    • In result.json, remove duplicated child securityRules resources or keep only inline rules to avoid ambiguity.
    • Ensure artifacts.json SAS URL is valid and that exported-template.json is uploaded to task-artifacts after running scripts/generate-artifacts.ps1.

You’ve correctly implemented the NSG rule logic and subnet associations—great work. Address the naming, container, and validator issues above, regenerate artifacts, and the solution should pass validation.


✨ Please rate this review in the Platform's notification center1. I will be grateful for your feedback! ✨

Important

Fix the issues, commit the changes, and then re-request my review using the Re-request review button2 in the Reviewers tab.

Tip

If you have any comments about this review, please leave a message in the Add a comment section below and mention me with the @mateacademy-ai-mentor tag3.
I will read your message during my next review of your pull request. Please do not reply directly to my comments, as that feature is not supported yet.

Caution

Do not close the pull request until the review is complete. Closing it early can lead to unexpected behavior and disrupt the review process.

Footnotes

  1. Rate AI review example

  2. Re-request AI review example

  3. Add AI review comments example

Comment thread artifacts.json
@@ -1,3 +1,3 @@
{
"resourcesTemplate": ""
"resourcesTemplate": "https://storageac88.blob.core.windows.net/task-artifacts/task16/exported-template.json?sv=2025-05-05&se=2025-10-31T00%3A21%3A42Z&sr=b&sp=r&sig=PWWf7gJLK%2BJzmSlo1%2Bh8WjCp%2B09mDWxfdwEgkLpyE9A%3D"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The resourcesTemplate URL uses the task-artifacts container — this is correct and matches the expected artifacts container. Before submitting, verify: 1) the SAS URL is valid and not expired; 2) the file exported-template.json exists at this exact path after you run scripts/generate-artifacts.ps1; 3) there are no typos in other files (e.g., task-atrifacts) that would cause uploads/downloads to go to a different container. If any typos exist elsewhere, fix them so all references use task-artifacts.

Comment thread result.json
Comment on lines +496 to +511
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2025-01-01",
"name": "[concat(parameters('storageAccounts_storageac88_name'), '/default/task-atrifacts')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', parameters('storageAccounts_storageac88_name'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_storageac88_name'))]"
],
"properties": {
"immutableStorageWithVersioning": {
"enabled": false
},
"defaultEncryptionScope": "$account-encryption-key",
"denyEncryptionScopeOverride": false,
"publicAccess": "None"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical: The template contains a duplicate and misspelled storage container resource named "task-atrifacts". This will conflict with the artifacts workflow (artifacts.json expects task-artifacts) and break upload/download of exported-template.json. Remove this resource (the entire object at these lines) so only the correct "task-artifacts" container remains.

Comment thread result.json
Comment on lines +479 to +494
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2025-01-01",
"name": "[concat(parameters('storageAccounts_storageac88_name'), '/default/task-artifacts')]",
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts/blobServices', parameters('storageAccounts_storageac88_name'), 'default')]",
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccounts_storageac88_name'))]"
],
"properties": {
"immutableStorageWithVersioning": {
"enabled": false
},
"defaultEncryptionScope": "$account-encryption-key",
"denyEncryptionScopeOverride": false,
"publicAccess": "None"
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The correct storage container resource appears earlier at lines 479–494 as "task-artifacts" — keep that one and delete the misspelled duplicate. Ensure the SAS URL in artifacts.json points to this container and is valid after you regenerate artifacts.

Comment thread result.json
Comment on lines +11 to +18
"networkSecurityGroups_database_nsg_name": {
"type": "String"
},
"networkSecurityGroups_management_nsg_name": {
"type": "String"
},
"networkSecurityGroups_webservers_nsg_name": {
"type": "String"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The template defines parameters for NSG names (networkSecurityGroups_webservers_nsg_name, networkSecurityGroups_management_nsg_name, networkSecurityGroups_database_nsg_name) but does not set explicit values here. The validator and task requirements expect NSG names to exactly match subnet names (webservers, management, database). Make sure the exported template (or the parameters passed during deployment/artifacts generation) populates these parameters with exactly those names (no '-nsg' suffix). You can provide defaultValue fields here or ensure task.ps1 creates NSGs with these exact names so the exported template contains them.

Comment thread result.json
Comment on lines +213 to +349
{
"type": "Microsoft.Network/networkSecurityGroups/securityRules",
"apiVersion": "2024-07-01",
"name": "[concat(parameters('networkSecurityGroups_webservers_nsg_name'), '/Allow-HTTP')]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroups_webservers_nsg_name'))]"
],
"properties": {
"description": "Allow HTTP",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "80",
"sourceAddressPrefix": "Internet",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 200,
"direction": "Inbound",
"sourcePortRanges": [],
"destinationPortRanges": [],
"sourceAddressPrefixes": [],
"destinationAddressPrefixes": []
}
},
{
"type": "Microsoft.Network/networkSecurityGroups/securityRules",
"apiVersion": "2024-07-01",
"name": "[concat(parameters('networkSecurityGroups_webservers_nsg_name'), '/Allow-HTTPS')]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroups_webservers_nsg_name'))]"
],
"properties": {
"description": "Allow HTTPS",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "443",
"sourceAddressPrefix": "Internet",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 210,
"direction": "Inbound",
"sourcePortRanges": [],
"destinationPortRanges": [],
"sourceAddressPrefixes": [],
"destinationAddressPrefixes": []
}
},
{
"type": "Microsoft.Network/networkSecurityGroups/securityRules",
"apiVersion": "2024-07-01",
"name": "[concat(parameters('networkSecurityGroups_management_nsg_name'), '/Allow-SSH')]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroups_management_nsg_name'))]"
],
"properties": {
"description": "Allow SSH",
"protocol": "Tcp",
"sourcePortRange": "*",
"destinationPortRange": "22",
"sourceAddressPrefix": "Internet",
"destinationAddressPrefix": "*",
"access": "Allow",
"priority": 200,
"direction": "Inbound",
"sourcePortRanges": [],
"destinationPortRanges": [],
"sourceAddressPrefixes": [],
"destinationAddressPrefixes": []
}
},
{
"type": "Microsoft.Network/networkSecurityGroups/securityRules",
"apiVersion": "2024-07-01",
"name": "[concat(parameters('networkSecurityGroups_database_nsg_name'), '/Allow-VNet')]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroups_database_nsg_name'))]"
],
"properties": {
"description": "Allow all VNet traffic",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "*",
"sourceAddressPrefix": "VirtualNetwork",
"destinationAddressPrefix": "VirtualNetwork",
"access": "Allow",
"priority": 100,
"direction": "Inbound",
"sourcePortRanges": [],
"destinationPortRanges": [],
"sourceAddressPrefixes": [],
"destinationAddressPrefixes": []
}
},
{
"type": "Microsoft.Network/networkSecurityGroups/securityRules",
"apiVersion": "2024-07-01",
"name": "[concat(parameters('networkSecurityGroups_management_nsg_name'), '/Allow-VNet')]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroups_management_nsg_name'))]"
],
"properties": {
"description": "Allow all VNet traffic",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "*",
"sourceAddressPrefix": "VirtualNetwork",
"destinationAddressPrefix": "VirtualNetwork",
"access": "Allow",
"priority": 100,
"direction": "Inbound",
"sourcePortRanges": [],
"destinationPortRanges": [],
"sourceAddressPrefixes": [],
"destinationAddressPrefixes": []
}
},
{
"type": "Microsoft.Network/networkSecurityGroups/securityRules",
"apiVersion": "2024-07-01",
"name": "[concat(parameters('networkSecurityGroups_webservers_nsg_name'), '/Allow-VNet')]",
"dependsOn": [
"[resourceId('Microsoft.Network/networkSecurityGroups', parameters('networkSecurityGroups_webservers_nsg_name'))]"
],
"properties": {
"description": "Allow all VNet traffic",
"protocol": "*",
"sourcePortRange": "*",
"destinationPortRange": "*",
"sourceAddressPrefix": "VirtualNetwork",
"destinationAddressPrefix": "VirtualNetwork",
"access": "Allow",
"priority": 100,
"direction": "Inbound",
"sourcePortRanges": [],
"destinationPortRanges": [],
"sourceAddressPrefixes": [],
"destinationAddressPrefixes": []
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are duplicated security rule entries: the NSG resources include inline securityRules (e.g., webservers NSG at lines 112–173 includes Allow-HTTP and Allow-HTTPS), and later the template also contains separate Microsoft.Network/networkSecurityGroups/securityRules child resources (starting at line 213 and onward). This duplication is confusing and may lead to unexpected template behavior. Consider keeping rules inline in the NSG resource OR as child resources — not both — to avoid ambiguity and simplify validation.

Comment thread task.ps1
-DestinationAddressPrefix VirtualNetwork -DestinationPortRange *

# Allow HTTP from Internet
$allowHttp = New-AzNetworkSecurityRuleConfig -Name "Allow-HTTP" -Description "Allow HTTP" `

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Positive: HTTP allow rule is defined for webservers with SourceAddressPrefix Internet and DestinationPortRange 80 — this satisfies the requirement to allow HTTP from the Internet. Ensure the exported template includes this as a separate security rule so the validator can find it.

Comment thread task.ps1
-DestinationAddressPrefix * -DestinationPortRange 80

# Allow HTTPS from Internet
$allowHttps = New-AzNetworkSecurityRuleConfig -Name "Allow-HTTPS" -Description "Allow HTTPS" `

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Positive: HTTPS allow rule is defined for webservers with SourceAddressPrefix Internet and DestinationPortRange 443 — this satisfies the requirement to allow HTTPS from the Internet. Together with the Allow-VNet rule, webservers NSG should have three inbound rules.

Comment thread task.ps1
-DestinationAddressPrefix VirtualNetwork -DestinationPortRange *

# Allow SSH from Internet
$allowSsh = New-AzNetworkSecurityRuleConfig -Name "Allow-SSH" -Description "Allow SSH" `

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Positive: SSH allow rule is defined for management with SourceAddressPrefix Internet and DestinationPortRange 22. This meets the requirement that management accepts SSH from the Internet. Ensure the validation script checks the sourceAddressPrefix equals 'Internet' (validator in repo needs that check enabled).

Comment thread task.ps1
Comment on lines +78 to +80
$webSubnet = New-AzVirtualNetworkSubnetConfig -Name $webSubnetName -AddressPrefix $webSubnetIpRange -NetworkSecurityGroup $webnsg
$dbSubnet = New-AzVirtualNetworkSubnetConfig -Name $dbSubnetName -AddressPrefix $dbSubnetIpRange -NetworkSecurityGroup $dbnsg
$mngSubnet = New-AzVirtualNetworkSubnetConfig -Name $mngSubnetName -AddressPrefix $mngSubnetIpRange -NetworkSecurityGroup $mngnsg

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Subnet association: NSG objects are attached to the subnet configs via the -NetworkSecurityGroup parameter when creating the subnets ($webSubnet, $dbSubnet, $mngSubnet) and then New-AzVirtualNetwork is called with those subnets. This correctly associates NSGs with subnets. After fixing NSG names above, this association should remain valid.

Comment thread task.ps1

$storageKey = (Get-AzStorageAccountKey -ResourceGroupName $resourceGroupName -Name $storageName)[0].Value
$ctx = New-AzStorageContext -StorageAccountName $storageName -StorageAccountKey $storageKey
New-AzStorageContainer -Name "task-artifacts" -Context $ctx -Permission Off No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Artifacts container: the script creates the storage container task-artifacts (New-AzStorageContainer -Name "task-artifacts"). This matches the expected container name in artifacts.json — ensure the SAS URL in artifacts.json references the same container and is valid. If other files/templates include a misspelled container (task-atrifacts), remove that misspelling so artifact generation/validation works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants