Skip to content

Commit f9219c5

Browse files
committed
feat: Add README and Bicep files for sample web application blueprint
1 parent 68bc1a9 commit f9219c5

2 files changed

Lines changed: 221 additions & 0 deletions

File tree

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Sample Web Application Blueprint
2+
3+
## Overview
4+
5+
A three-tier web application architecture on Azure with App Service, SQL Database, and Key Vault for secure configuration management.
6+
7+
## Architecture Components
8+
9+
| Component | Azure Service | Purpose |
10+
| --- | --- | --- |
11+
| Web Frontend | App Service | Hosts the web application |
12+
| Database | Azure SQL Database | Persistent data storage |
13+
| Secrets Management | Key Vault | Stores connection strings and API keys |
14+
| Monitoring | Application Insights | Telemetry and diagnostics |
15+
| Identity | Managed Identity | Service-to-service authentication |
16+
17+
## Data Flows
18+
19+
1. Users access the web application via HTTPS
20+
2. App Service retrieves secrets from Key Vault using managed identity
21+
3. Application queries SQL Database using connection string from Key Vault
22+
4. Telemetry flows to Application Insights
23+
24+
## Security Considerations
25+
26+
- All traffic encrypted in transit (TLS 1.2+)
27+
- Managed identity eliminates credential storage in code
28+
- Key Vault access controlled via RBAC
29+
- SQL Database firewall restricts network access
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
@description('The Azure region for resource deployment.')
2+
param location string = resourceGroup().location
3+
4+
@description('Environment name used for resource naming.')
5+
@allowed(['dev', 'staging', 'prod'])
6+
param environmentName string = 'dev'
7+
8+
@description('Base name for all resources.')
9+
param baseName string = 'samplewebapp'
10+
11+
/* ========================================================================== */
12+
/* Variables */
13+
/* ========================================================================== */
14+
15+
var resourceSuffix = '${baseName}-${environmentName}'
16+
var keyVaultName = 'kv-${resourceSuffix}'
17+
var appServicePlanName = 'asp-${resourceSuffix}'
18+
var appServiceName = 'app-${resourceSuffix}'
19+
var sqlServerName = 'sql-${resourceSuffix}'
20+
var sqlDatabaseName = 'sqldb-${resourceSuffix}'
21+
var appInsightsName = 'ai-${resourceSuffix}'
22+
var logAnalyticsName = 'log-${resourceSuffix}'
23+
24+
/* ========================================================================== */
25+
/* Log Analytics Workspace */
26+
/* ========================================================================== */
27+
28+
@description('Log Analytics workspace for monitoring.')
29+
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2023-09-01' = {
30+
name: logAnalyticsName
31+
location: location
32+
properties: {
33+
sku: {
34+
name: 'PerGB2018'
35+
}
36+
retentionInDays: 30
37+
}
38+
}
39+
40+
/* ========================================================================== */
41+
/* Application Insights */
42+
/* ========================================================================== */
43+
44+
@description('Application Insights for telemetry.')
45+
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
46+
name: appInsightsName
47+
location: location
48+
kind: 'web'
49+
properties: {
50+
Application_Type: 'web'
51+
WorkspaceResourceId: logAnalytics.id
52+
}
53+
}
54+
55+
/* ========================================================================== */
56+
/* Key Vault */
57+
/* ========================================================================== */
58+
59+
@description('Key Vault for secrets management.')
60+
resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
61+
name: keyVaultName
62+
location: location
63+
properties: {
64+
sku: {
65+
family: 'A'
66+
name: 'standard'
67+
}
68+
tenantId: subscription().tenantId
69+
enableRbacAuthorization: true
70+
enableSoftDelete: true
71+
softDeleteRetentionInDays: 90
72+
enablePurgeProtection: true
73+
networkAcls: {
74+
defaultAction: 'Deny'
75+
bypass: 'AzureServices'
76+
}
77+
}
78+
}
79+
80+
/* ========================================================================== */
81+
/* App Service Plan */
82+
/* ========================================================================== */
83+
84+
@description('App Service Plan for hosting.')
85+
resource appServicePlan 'Microsoft.Web/serverfarms@2023-12-01' = {
86+
name: appServicePlanName
87+
location: location
88+
sku: {
89+
name: 'P1v3'
90+
tier: 'PremiumV3'
91+
}
92+
properties: {
93+
reserved: false
94+
}
95+
}
96+
97+
/* ========================================================================== */
98+
/* App Service */
99+
/* ========================================================================== */
100+
101+
@description('App Service for web application.')
102+
resource appService 'Microsoft.Web/sites@2023-12-01' = {
103+
name: appServiceName
104+
location: location
105+
identity: {
106+
type: 'SystemAssigned'
107+
}
108+
properties: {
109+
serverFarmId: appServicePlan.id
110+
httpsOnly: true
111+
siteConfig: {
112+
minTlsVersion: '1.2'
113+
ftpsState: 'Disabled'
114+
alwaysOn: true
115+
appSettings: [
116+
{
117+
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
118+
value: appInsights.properties.InstrumentationKey
119+
}
120+
{
121+
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
122+
value: appInsights.properties.ConnectionString
123+
}
124+
{
125+
name: 'KeyVaultUri'
126+
value: keyVault.properties.vaultUri
127+
}
128+
]
129+
}
130+
}
131+
}
132+
133+
/* ========================================================================== */
134+
/* SQL Server */
135+
/* ========================================================================== */
136+
137+
@description('SQL Server for database hosting.')
138+
resource sqlServer 'Microsoft.Sql/servers@2023-08-01-preview' = {
139+
name: sqlServerName
140+
location: location
141+
properties: {
142+
administratorLogin: 'sqladmin'
143+
minimalTlsVersion: '1.2'
144+
publicNetworkAccess: 'Disabled'
145+
}
146+
}
147+
148+
/* ========================================================================== */
149+
/* SQL Database */
150+
/* ========================================================================== */
151+
152+
@description('SQL Database for application data.')
153+
resource sqlDatabase 'Microsoft.Sql/servers/databases@2023-08-01-preview' = {
154+
parent: sqlServer
155+
name: sqlDatabaseName
156+
location: location
157+
sku: {
158+
name: 'S1'
159+
tier: 'Standard'
160+
}
161+
properties: {
162+
collation: 'SQL_Latin1_General_CP1_CI_AS'
163+
}
164+
}
165+
166+
/* ========================================================================== */
167+
/* Key Vault Access for App Service */
168+
/* ========================================================================== */
169+
170+
@description('Key Vault Secrets User role assignment for App Service.')
171+
resource keyVaultRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
172+
name: guid(keyVault.id, appService.id, '4633458b-17de-408a-b874-0445c86b69e6')
173+
scope: keyVault
174+
properties: {
175+
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4633458b-17de-408a-b874-0445c86b69e6')
176+
principalId: appService.identity.principalId
177+
principalType: 'ServicePrincipal'
178+
}
179+
}
180+
181+
/* ========================================================================== */
182+
/* Outputs */
183+
/* ========================================================================== */
184+
185+
@description('The App Service default hostname.')
186+
output appServiceHostname string = appService.properties.defaultHostName
187+
188+
@description('The Key Vault URI.')
189+
output keyVaultUri string = keyVault.properties.vaultUri
190+
191+
@description('The SQL Server FQDN.')
192+
output sqlServerFqdn string = sqlServer.properties.fullyQualifiedDomainName

0 commit comments

Comments
 (0)