Pamela Fox commited on
Commit
80db45a
·
1 Parent(s): 10521cb
.devcontainer/Dockerfile CHANGED
@@ -1,5 +1,8 @@
1
  # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.245.0/containers/python-3/.devcontainer/base.Dockerfile
2
 
3
  # [Choice] Python version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.10, 3.9, 3.8, 3.7, 3.6, 3-bullseye, 3.10-bullseye, 3.9-bullseye, 3.8-bullseye, 3.7-bullseye, 3.6-bullseye, 3-buster, 3.10-buster, 3.9-buster, 3.8-buster, 3.7-buster, 3.6-buster
4
- ARG VARIANT="3.10-bullseye"
5
- FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT}
 
 
 
 
1
  # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.245.0/containers/python-3/.devcontainer/base.Dockerfile
2
 
3
  # [Choice] Python version (use -bullseye variants on local arm64/Apple Silicon): 3, 3.10, 3.9, 3.8, 3.7, 3.6, 3-bullseye, 3.10-bullseye, 3.9-bullseye, 3.8-bullseye, 3.7-bullseye, 3.6-bullseye, 3-buster, 3.10-buster, 3.9-buster, 3.8-buster, 3.7-buster, 3.6-buster
4
+ ARG VARIANT=bullseye
5
+ FROM mcr.microsoft.com/vscode/devcontainers/base:0-${VARIANT}
6
+ RUN curl -fsSL https://aka.ms/install-azd.sh | bash
7
+ RUN apt update
8
+ RUN apt-get install --yes libpq-dev
.devcontainer/devcontainer.json CHANGED
@@ -6,11 +6,11 @@
6
  "build": {
7
  "dockerfile": "Dockerfile",
8
  "context": "..",
9
- "args": {
10
  // Update 'VARIANT' to pick a Python version: 3, 3.10, 3.9, 3.8, 3.7, 3.6
11
  // Append -bullseye or -buster to pin to an OS version.
12
  // Use -bullseye variants on local on arm64/Apple Silicon.
13
- "VARIANT": "3.10-bullseye"
14
  }
15
  },
16
 
@@ -19,7 +19,7 @@
19
  // Configure properties specific to VS Code.
20
  "vscode": {
21
  // Set *default* container specific settings.json values on container create.
22
- "settings": {
23
  "python.defaultInterpreterPath": "/usr/local/bin/python",
24
  "python.linting.enabled": true,
25
  "python.linting.pylintEnabled": true,
@@ -39,7 +39,7 @@
39
  "python.testing.pytestEnabled": true,
40
  "workbench.startupEditor": "newUntitledFile"
41
  },
42
-
43
  // Add the IDs of extensions you want installed when the container is created.
44
  "extensions": [
45
  "ms-python.python",
@@ -48,12 +48,18 @@
48
  }
49
  },
50
 
51
- // Use 'forwardPorts' to make a list of ports inside the container available locally.
52
- // "forwardPorts": [],
53
-
54
  // Use 'postCreateCommand' to run commands after the container is created.
55
- "postCreateCommand": "pip install -r requirements-dev.txt && pre-commit install",
56
 
57
  // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
58
- "remoteUser": "vscode"
59
- }
 
 
 
 
 
 
 
 
 
 
6
  "build": {
7
  "dockerfile": "Dockerfile",
8
  "context": "..",
9
+ "args": {
10
  // Update 'VARIANT' to pick a Python version: 3, 3.10, 3.9, 3.8, 3.7, 3.6
11
  // Append -bullseye or -buster to pin to an OS version.
12
  // Use -bullseye variants on local on arm64/Apple Silicon.
13
+ "VARIANT": "bullseye"
14
  }
15
  },
16
 
 
19
  // Configure properties specific to VS Code.
20
  "vscode": {
21
  // Set *default* container specific settings.json values on container create.
22
+ "settings": {
23
  "python.defaultInterpreterPath": "/usr/local/bin/python",
24
  "python.linting.enabled": true,
25
  "python.linting.pylintEnabled": true,
 
39
  "python.testing.pytestEnabled": true,
40
  "workbench.startupEditor": "newUntitledFile"
41
  },
42
+
43
  // Add the IDs of extensions you want installed when the container is created.
44
  "extensions": [
45
  "ms-python.python",
 
48
  }
49
  },
50
 
 
 
 
51
  // Use 'postCreateCommand' to run commands after the container is created.
52
+ "postCreateCommand": "pip install -r requirements.txt",
53
 
54
  // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
55
+ "remoteUser": "vscode",
56
+
57
+ "features": {
58
+ "ghcr.io/devcontainers/features/azure-cli:1": {
59
+ "version": "latest"
60
+ },
61
+ "ghcr.io/devcontainers/features/python:1": {
62
+ "version": "os-provided"
63
+ }
64
+ }
65
+ }
azure.yaml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json
2
+
3
+ name: flask-db-quiz-example
4
+
5
+ services:
6
+ web:
7
+ project: .
8
+ language: py
9
+ host: appservice
infra/main.bicep ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ targetScope = 'subscription'
2
+
3
+ @minLength(1)
4
+ @maxLength(64)
5
+ @description('Name which is used to generate a short unique hash for each resource')
6
+ param name string
7
+
8
+ @minLength(1)
9
+ @description('Primary location for all resources')
10
+ param location string
11
+
12
+ @secure()
13
+ @description('PostGreSQL Server administrator password')
14
+ param databasePassword string
15
+
16
+ var resourceToken = toLower(uniqueString(subscription().id, name, location))
17
+ var tags = { 'azd-env-name': name }
18
+
19
+ resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
20
+ name: '${name}-rg'
21
+ location: location
22
+ tags: tags
23
+ }
24
+
25
+ module resources 'resources.bicep' = {
26
+ name: 'resources'
27
+ scope: resourceGroup
28
+ params: {
29
+ name: name
30
+ location: location
31
+ resourceToken: resourceToken
32
+ tags: tags
33
+ databasePassword: databasePassword
34
+ }
35
+ }
36
+
37
+ output AZURE_LOCATION string = location
infra/main.parameters.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
3
+ "contentVersion": "1.0.0.0",
4
+ "parameters": {
5
+ "name": {
6
+ "value": "${AZURE_ENV_NAME}"
7
+ },
8
+ "location": {
9
+ "value": "${AZURE_LOCATION}"
10
+ },
11
+ "databasePassword": {
12
+ "value": "$(secretOrRandomPassword ${AZURE_KEY_VAULT_NAME} databasePassword)"
13
+ }
14
+ }
15
+ }
infra/resources.bicep ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ param name string
2
+ param location string
3
+ param resourceToken string
4
+ @secure()
5
+ param databasePassword string
6
+ param tags object
7
+
8
+ var prefix = '${name}-${resourceToken}'
9
+
10
+ var pgServerName = '${prefix}-postgres-server'
11
+ var databaseSubnetName = 'database-subnet'
12
+ var webappSubnetName = 'webapp-subnet'
13
+
14
+ resource virtualNetwork 'Microsoft.Network/virtualNetworks@2019-11-01' = {
15
+ name: '${prefix}-vnet'
16
+ location: location
17
+ tags: tags
18
+ properties: {
19
+ addressSpace: {
20
+ addressPrefixes: [
21
+ '10.0.0.0/16'
22
+ ]
23
+ }
24
+ subnets: [
25
+ {
26
+ name: databaseSubnetName
27
+ properties: {
28
+ addressPrefix: '10.0.0.0/24'
29
+ delegations: [
30
+ {
31
+ name: '${prefix}-subnet-delegation'
32
+ properties: {
33
+ serviceName: 'Microsoft.DBforPostgreSQL/flexibleServers'
34
+ }
35
+ }
36
+ ]
37
+ }
38
+ }
39
+ {
40
+ name: webappSubnetName
41
+ properties: {
42
+ addressPrefix: '10.0.1.0/24'
43
+ delegations: [
44
+ {
45
+ name: '${prefix}-subnet-delegation-web'
46
+ properties: {
47
+ serviceName: 'Microsoft.Web/serverFarms'
48
+ }
49
+ }
50
+ ]
51
+ }
52
+ }
53
+ ]
54
+ }
55
+ resource databaseSubnet 'subnets' existing = {
56
+ name: databaseSubnetName
57
+ }
58
+ resource webappSubnet 'subnets' existing = {
59
+ name: webappSubnetName
60
+ }
61
+ }
62
+
63
+ resource privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' = {
64
+ name: '${pgServerName}.private.postgres.database.azure.com'
65
+ location: 'global'
66
+ tags: tags
67
+ dependsOn: [
68
+ virtualNetwork
69
+ ]
70
+ }
71
+
72
+ resource privateDnsZoneLink 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-06-01' = {
73
+ parent: privateDnsZone
74
+ name: '${pgServerName}-link'
75
+ location: 'global'
76
+ properties: {
77
+ registrationEnabled: false
78
+ virtualNetwork: {
79
+ id: virtualNetwork.id
80
+ }
81
+ }
82
+ }
83
+
84
+ resource web 'Microsoft.Web/sites@2022-03-01' = {
85
+ name: '${prefix}-app-service'
86
+ location: location
87
+ tags: union(tags, { 'azd-service-name': 'web' })
88
+ kind: 'app,linux'
89
+ properties: {
90
+ serverFarmId: appServicePlan.id
91
+ siteConfig: {
92
+ alwaysOn: true
93
+ linuxFxVersion: 'PYTHON|3.10'
94
+ ftpsState: 'Disabled'
95
+ }
96
+ httpsOnly: true
97
+ }
98
+ identity: {
99
+ type: 'SystemAssigned'
100
+ }
101
+
102
+ resource appSettings 'config' = {
103
+ name: 'appsettings'
104
+ properties: {
105
+ DBHOST: postgresServer.name
106
+ DBNAME: djangoDatabase.name
107
+ DBUSER: postgresServer.properties.administratorLogin
108
+ DBPASS: databasePassword
109
+ SCM_DO_BUILD_DURING_DEPLOYMENT: 'true'
110
+ }
111
+ }
112
+
113
+ resource logs 'config' = {
114
+ name: 'logs'
115
+ properties: {
116
+ applicationLogs: {
117
+ fileSystem: {
118
+ level: 'Verbose'
119
+ }
120
+ }
121
+ detailedErrorMessages: {
122
+ enabled: true
123
+ }
124
+ failedRequestsTracing: {
125
+ enabled: true
126
+ }
127
+ httpLogs: {
128
+ fileSystem: {
129
+ enabled: true
130
+ retentionInDays: 1
131
+ retentionInMb: 35
132
+ }
133
+ }
134
+ }
135
+ }
136
+
137
+ resource webappVnetConfig 'networkConfig' = {
138
+ name: 'virtualNetwork'
139
+ properties: {
140
+ subnetResourceId: virtualNetwork::webappSubnet.id
141
+ }
142
+ }
143
+
144
+ dependsOn: [virtualNetwork]
145
+
146
+ }
147
+
148
+ resource appServicePlan 'Microsoft.Web/serverfarms@2021-03-01' = {
149
+ name: '${prefix}-service-plan'
150
+ location: location
151
+ tags: tags
152
+ sku: {
153
+ name: 'B1'
154
+ }
155
+ properties: {
156
+ reserved: true
157
+ }
158
+ }
159
+
160
+ resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2020-03-01-preview' = {
161
+ name: '${prefix}-workspace'
162
+ location: location
163
+ tags: tags
164
+ properties: any({
165
+ retentionInDays: 30
166
+ features: {
167
+ searchVersion: 1
168
+ }
169
+ sku: {
170
+ name: 'PerGB2018'
171
+ }
172
+ })
173
+ }
174
+
175
+ resource postgresServer 'Microsoft.DBforPostgreSQL/flexibleServers@2022-01-20-preview' = {
176
+ location: location
177
+ tags: tags
178
+ name: pgServerName
179
+ sku: {
180
+ name: 'Standard_D2ds_v4'
181
+ tier: 'GeneralPurpose'
182
+ }
183
+ properties: {
184
+ version: '13'
185
+ administratorLogin: 'django'
186
+ administratorLoginPassword: databasePassword
187
+ availabilityZone: '1'
188
+ storage: {
189
+ storageSizeGB: 128
190
+ }
191
+ backup: {
192
+ backupRetentionDays: 7
193
+ geoRedundantBackup: 'Disabled'
194
+ }
195
+ network: {
196
+ delegatedSubnetResourceId: virtualNetwork::databaseSubnet.id
197
+ privateDnsZoneArmResourceId: privateDnsZone.id
198
+ }
199
+ highAvailability: {
200
+ mode: 'Disabled'
201
+ }
202
+ maintenanceWindow: {
203
+ customWindow: 'Disabled'
204
+ dayOfWeek: 0
205
+ startHour: 0
206
+ startMinute: 0
207
+ }
208
+ }
209
+
210
+ dependsOn: [
211
+ privateDnsZoneLink
212
+ ]
213
+ }
214
+
215
+
216
+ resource djangoDatabase 'Microsoft.DBforPostgreSQL/flexibleServers/databases@2022-01-20-preview' = {
217
+ parent: postgresServer
218
+ name: 'django'
219
+ }
220
+
221
+ output WEB_URI string = 'https://${web.properties.defaultHostName}'