Skip to content

Commit 7e63f32

Browse files
fix: Correct deployment YAML file paths in Azure pipeline
- Updated the Azure pipeline configuration to ensure deployment YAML files are copied from the correct directory, aligning with recent structural changes in the project.
1 parent 9f540bf commit 7e63f32

21 files changed

+1460
-0
lines changed

deployments/bicep/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Compiled output from: az bicep build
2+
main.json

deployments/bicep/README.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# AKS Hub-Spoke Infrastructure (Bicep)
2+
3+
This folder contains Bicep templates to provision an AKS cluster in a Hub and Spoke network topology:
4+
- **Hub VNet**: Azure Firewall, Private DNS Zones for SQL and Blob
5+
- **Compute spoke**: AKS cluster (system + user node pools)
6+
- **Data spoke**: Azure SQL Database, Storage Account, each with Private Endpoints
7+
8+
## Prerequisites
9+
10+
- Azure CLI with Bicep (`az bicep version`)
11+
- Contributor (or higher) on target subscription/resource group
12+
- Sufficient quota for AKS, Firewall, SQL in the region
13+
14+
## Deployment
15+
16+
1. Create a resource group:
17+
```bash
18+
az group create --name rg-silkroad-hubspoke-dev --location eastus
19+
```
20+
21+
2. Deploy using the parameters file (provide `sqlAdministratorPassword` at deploy time):
22+
```bash
23+
az deployment group create \
24+
--resource-group rg-silkroad-hubspoke-dev \
25+
--template-file main.bicep \
26+
--parameters main.parameters.json \
27+
--parameters sqlAdministratorPassword='YourSecurePassword123!'
28+
```
29+
30+
Or deploy without a parameters file, passing all required params:
31+
```bash
32+
az deployment group create \
33+
--resource-group rg-silkroad-hubspoke-dev \
34+
--template-file main.bicep \
35+
--parameters sqlAdministratorLogin=sqladmin \
36+
--parameters sqlAdministratorPassword='YourSecurePassword123!'
37+
```
38+
39+
3. Get AKS credentials after deployment:
40+
```bash
41+
az aks get-credentials --resource-group rg-silkroad-hubspoke-dev --name silkroad-aks-dev
42+
```
43+
44+
## Parameters
45+
46+
| Parameter | Description | Default |
47+
|-----------|-------------|---------|
48+
| location | Azure region | resourceGroup().location |
49+
| environment | dev or prod | dev |
50+
| hubAddressPrefix | Hub VNet CIDR | 10.0.0.0/16 |
51+
| computeSpokeAddressPrefix | Compute spoke CIDR | 10.1.0.0/16 |
52+
| dataSpokeAddressPrefix | Data spoke CIDR | 10.2.0.0/16 |
53+
| aksNodeCount | User pool node count | 2 |
54+
| aksVmSize | Node VM size | Standard_D2s_v3 |
55+
| aksKubernetesVersion | Kubernetes version | 1.28 |
56+
| sqlAdministratorLogin | SQL admin login | (required) |
57+
| sqlAdministratorPassword | SQL admin password | (required, secure) |
58+
| enableAzureFirewall | Deploy Azure Firewall | true |
59+
| enablePrivateCluster | Private AKS API | false |
60+
| projectName | Resource naming prefix | silkroad |
61+
62+
## File Structure
63+
64+
```
65+
bicep/
66+
├── main.bicep # Entry point
67+
├── parameters.bicep # (Inlined in main.bicep)
68+
├── main.parameters.json # Default parameter values
69+
├── modules/
70+
│ ├── hub-network.bicep # Hub VNet, Firewall, Private DNS Zones
71+
│ ├── spoke-compute.bicep # Compute spoke VNet, AKS, DNS links
72+
│ ├── spoke-data.bicep # Data spoke VNet, SQL, Storage, PEs
73+
│ ├── peering.bicep # VNet peering (Hub ↔ Compute, Hub ↔ Data)
74+
│ └── aks-cluster.bicep # AKS cluster resource
75+
└── README.md
76+
```
77+
78+
## Outputs
79+
80+
- `hubVNetId`: Hub VNet resource ID
81+
- `aksClusterId`: AKS cluster resource ID
82+
- `aksClusterName`: AKS cluster name (for `az aks get-credentials`)
83+
- `aksClusterFqdn`: AKS API FQDN
84+
- `sqlServerFqdn`: SQL Server FQDN (for connection string)
85+
- `storageAccountName`: Storage account name

deployments/bicep/main.bicep

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
targetScope = 'resourceGroup'
2+
3+
@description('Azure region for all resources')
4+
param location string = resourceGroup().location
5+
6+
@description('Environment (dev | prod)')
7+
@allowed(['dev', 'prod'])
8+
param environment string = 'dev'
9+
10+
@description('Hub VNet address prefix')
11+
param hubAddressPrefix string = '10.0.0.0/16'
12+
13+
@description('Compute spoke VNet address prefix')
14+
param computeSpokeAddressPrefix string = '10.1.0.0/16'
15+
16+
@description('Data spoke VNet address prefix')
17+
param dataSpokeAddressPrefix string = '10.2.0.0/16'
18+
19+
@description('Number of AKS agent nodes in user pool')
20+
param aksNodeCount int = 2
21+
22+
@description('AKS agent node VM size')
23+
param aksVmSize string = 'Standard_D2s_v3'
24+
25+
@description('AKS Kubernetes version')
26+
param aksKubernetesVersion string = '1.28'
27+
28+
@description('SQL administrator login')
29+
param sqlAdministratorLogin string
30+
31+
@description('SQL administrator password')
32+
@secure()
33+
param sqlAdministratorPassword string
34+
35+
@description('Enable Azure Firewall in Hub')
36+
param enableAzureFirewall bool = true
37+
38+
@description('Enable private AKS cluster')
39+
param enablePrivateCluster bool = false
40+
41+
@description('Project/app name for resource naming')
42+
param projectName string = 'silkroad'
43+
44+
module hub 'modules/hub-network.bicep' = {
45+
name: 'hub-network-deployment'
46+
params: {
47+
location: location
48+
hubAddressPrefix: hubAddressPrefix
49+
enableAzureFirewall: enableAzureFirewall
50+
projectName: projectName
51+
environment: environment
52+
}
53+
}
54+
55+
module spokeData 'modules/spoke-data.bicep' = {
56+
name: 'spoke-data-deployment'
57+
params: {
58+
location: location
59+
dataSpokeAddressPrefix: dataSpokeAddressPrefix
60+
projectName: projectName
61+
environment: environment
62+
sqlAdministratorLogin: sqlAdministratorLogin
63+
sqlAdministratorPassword: sqlAdministratorPassword
64+
dnsZoneSqlId: hub.outputs.dnsZoneSqlId
65+
dnsZoneBlobId: hub.outputs.dnsZoneBlobId
66+
}
67+
}
68+
69+
module spokeCompute 'modules/spoke-compute.bicep' = {
70+
name: 'spoke-compute-deployment'
71+
dependsOn: [hub]
72+
params: {
73+
location: location
74+
computeSpokeAddressPrefix: computeSpokeAddressPrefix
75+
projectName: projectName
76+
environment: environment
77+
aksNodeCount: aksNodeCount
78+
aksVmSize: aksVmSize
79+
aksKubernetesVersion: aksKubernetesVersion
80+
enablePrivateCluster: enablePrivateCluster
81+
}
82+
}
83+
84+
module peering 'modules/peering.bicep' = {
85+
name: 'peering-deployment'
86+
params: {
87+
projectName: projectName
88+
environment: environment
89+
hubVNetId: hub.outputs.hubVNetId
90+
hubVNetName: hub.outputs.hubVNetName
91+
computeSpokeVNetId: spokeCompute.outputs.computeSpokeVNetId
92+
computeSpokeVNetName: spokeCompute.outputs.computeSpokeVNetName
93+
dataSpokeVNetId: spokeData.outputs.dataSpokeVNetId
94+
dataSpokeVNetName: spokeData.outputs.dataSpokeVNetName
95+
}
96+
}
97+
98+
output hubVNetId string = hub.outputs.hubVNetId
99+
output aksClusterId string = spokeCompute.outputs.aksClusterId
100+
output aksClusterName string = spokeCompute.outputs.aksClusterName
101+
output aksClusterFqdn string = spokeCompute.outputs.aksClusterFqdn
102+
output sqlServerFqdn string = spokeData.outputs.sqlServerFqdn
103+
output storageAccountName string = spokeData.outputs.storageAccountName
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
3+
"contentVersion": "1.0.0.0",
4+
"parameters": {
5+
"location": {
6+
"value": "eastus"
7+
},
8+
"environment": {
9+
"value": "dev"
10+
},
11+
"hubAddressPrefix": {
12+
"value": "10.0.0.0/16"
13+
},
14+
"computeSpokeAddressPrefix": {
15+
"value": "10.1.0.0/16"
16+
},
17+
"dataSpokeAddressPrefix": {
18+
"value": "10.2.0.0/16"
19+
},
20+
"aksNodeCount": {
21+
"value": 2
22+
},
23+
"aksVmSize": {
24+
"value": "Standard_D2s_v3"
25+
},
26+
"aksKubernetesVersion": {
27+
"value": "1.28"
28+
},
29+
"sqlAdministratorLogin": {
30+
"value": "sqladmin"
31+
},
32+
"sqlAdministratorPassword": {
33+
"value": "CHANGE_ME_AT_DEPLOY_TIME"
34+
},
35+
"enableAzureFirewall": {
36+
"value": true
37+
},
38+
"enablePrivateCluster": {
39+
"value": false
40+
},
41+
"projectName": {
42+
"value": "silkroad"
43+
}
44+
}
45+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
param location string = resourceGroup().location
2+
param projectName string = 'silkroad'
3+
param environment string = 'dev'
4+
param aksSubnetId string
5+
param aksNodeCount int = 2
6+
param aksVmSize string = 'Standard_D2s_v3'
7+
param aksKubernetesVersion string = '1.28'
8+
param enablePrivateCluster bool = false
9+
10+
var aksClusterName = '${projectName}-aks-${environment}'
11+
12+
resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-11-01' = {
13+
name: aksClusterName
14+
location: location
15+
identity: {
16+
type: 'SystemAssigned'
17+
}
18+
properties: {
19+
dnsPrefix: '${projectName}-${environment}'
20+
agentPoolProfiles: [
21+
{
22+
name: 'systempool'
23+
count: 2
24+
vmSize: aksVmSize
25+
osType: 'Linux'
26+
osDiskSizeGB: 30
27+
type: 'VirtualMachineScaleSets'
28+
mode: 'System'
29+
orchestratorVersion: aksKubernetesVersion
30+
enableNodePublicIP: false
31+
vnetSubnetID: aksSubnetId
32+
}
33+
{
34+
name: 'userpool'
35+
count: aksNodeCount
36+
vmSize: aksVmSize
37+
osType: 'Linux'
38+
osDiskSizeGB: 128
39+
type: 'VirtualMachineScaleSets'
40+
mode: 'User'
41+
orchestratorVersion: aksKubernetesVersion
42+
enableNodePublicIP: false
43+
vnetSubnetID: aksSubnetId
44+
enableAutoScaling: true
45+
minCount: 1
46+
maxCount: 5
47+
}
48+
]
49+
networkProfile: {
50+
networkPlugin: 'azure'
51+
networkPolicy: 'azure'
52+
loadBalancerSku: 'standard'
53+
serviceCidr: '10.10.0.0/16'
54+
dnsServiceIP: '10.10.0.10'
55+
}
56+
kubernetesVersion: aksKubernetesVersion
57+
enableRBAC: true
58+
apiServerAccessProfile: {
59+
enablePrivateCluster: enablePrivateCluster
60+
}
61+
}
62+
}
63+
64+
output aksClusterId string = aksCluster.id
65+
output aksClusterName string = aksCluster.name
66+
output aksClusterFqdn string = aksCluster.properties.fqdn
67+
output aksPrincipalId string = aksCluster.identity.principalId
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
param location string = resourceGroup().location
2+
param hubAddressPrefix string = '10.0.0.0/16'
3+
param enableAzureFirewall bool = true
4+
param projectName string = 'silkroad'
5+
param environment string = 'dev'
6+
7+
var hubVNetName = '${projectName}-hub-vnet-${environment}'
8+
var firewallSubnetName = 'AzureFirewallSubnet'
9+
var gatewaySubnetName = 'GatewaySubnet'
10+
var firewallSubnetPrefix = '10.0.0.0/26'
11+
var gatewaySubnetPrefix = '10.0.0.64/27'
12+
13+
resource hubVNet 'Microsoft.Network/virtualNetworks@2023-11-01' = {
14+
name: hubVNetName
15+
location: location
16+
properties: {
17+
addressSpace: {
18+
addressPrefixes: [hubAddressPrefix]
19+
}
20+
subnets: [
21+
{
22+
name: firewallSubnetName
23+
properties: {
24+
addressPrefix: firewallSubnetPrefix
25+
delegations: []
26+
privateEndpointNetworkPolicies: 'Enabled'
27+
privateLinkServiceNetworkPolicies: 'Enabled'
28+
}
29+
}
30+
{
31+
name: gatewaySubnetName
32+
properties: {
33+
addressPrefix: gatewaySubnetPrefix
34+
delegations: []
35+
privateEndpointNetworkPolicies: 'Enabled'
36+
privateLinkServiceNetworkPolicies: 'Enabled'
37+
}
38+
}
39+
]
40+
}
41+
}
42+
43+
resource azureFirewall 'Microsoft.Network/azureFirewalls@2023-11-01' = if (enableAzureFirewall) {
44+
name: '${projectName}-hub-fw-${environment}'
45+
location: location
46+
properties: {
47+
sku: {
48+
name: 'AZFW_Hub'
49+
tier: 'Standard'
50+
}
51+
threatIntelMode: 'Alert'
52+
ipConfigurations: [
53+
{
54+
name: 'configuration'
55+
properties: {
56+
subnet: {
57+
id: hubVNet.properties.subnets[0].id
58+
}
59+
}
60+
}
61+
]
62+
}
63+
}
64+
65+
resource dnsZoneSql 'Microsoft.Network/privateDnsZones@2023-11-01' = {
66+
name: 'privatelink.database.windows.net'
67+
location: 'global'
68+
properties: {}
69+
}
70+
71+
resource dnsZoneBlob 'Microsoft.Network/privateDnsZones@2023-11-01' = {
72+
name: 'privatelink.blob.core.windows.net'
73+
location: 'global'
74+
properties: {}
75+
}
76+
77+
output hubVNetId string = hubVNet.id
78+
output hubVNetName string = hubVNet.name
79+
output hubResourceGroup string = resourceGroup().name
80+
output firewallPrivateIp string = enableAzureFirewall ? azureFirewall.properties.ipConfigurations[0].properties.privateIPAddress : ''
81+
output dnsZoneSqlId string = dnsZoneSql.id
82+
output dnsZoneBlobId string = dnsZoneBlob.id

0 commit comments

Comments
 (0)