├── .dockerignore
├── .github
├── CODE_OF_CONDUCT.md
├── ISSUE_TEMPLATE.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ └── deploy.yml
├── .gitignore
├── Azure
├── app_config.bicep
├── container_app.bicep
├── environment.bicep
└── main.bicep
├── CHANGELOG.md
├── CONTRIBUTING.md
├── FeatureFlagsWithContainerApps.sln
├── FeatureFlagsWithContainerApps
├── Controllers
│ └── BetaController.cs
├── Dockerfile
├── FeatureFlagsWithContainerApps.csproj
├── Pages
│ ├── Error.cshtml
│ ├── Error.cshtml.cs
│ ├── Index.cshtml
│ ├── Index.cshtml.cs
│ ├── Privacy.cshtml
│ ├── Privacy.cshtml.cs
│ ├── Shared
│ │ ├── _Layout.cshtml
│ │ ├── _Layout.cshtml.css
│ │ └── _ValidationScriptsPartial.cshtml
│ ├── _ViewImports.cshtml
│ └── _ViewStart.cshtml
├── Program.cs
├── Properties
│ └── launchSettings.json
├── Views
│ └── Beta
│ │ └── Index.cshtml
├── appsettings.Development.json
├── appsettings.json
└── wwwroot
│ ├── css
│ └── site.css
│ ├── favicon.ico
│ ├── js
│ └── site.js
│ └── lib
│ ├── bootstrap
│ ├── LICENSE
│ └── dist
│ │ ├── css
│ │ ├── bootstrap-grid.css
│ │ ├── bootstrap-grid.css.map
│ │ ├── bootstrap-grid.min.css
│ │ ├── bootstrap-grid.min.css.map
│ │ ├── bootstrap-grid.rtl.css
│ │ ├── bootstrap-grid.rtl.css.map
│ │ ├── bootstrap-grid.rtl.min.css
│ │ ├── bootstrap-grid.rtl.min.css.map
│ │ ├── bootstrap-reboot.css
│ │ ├── bootstrap-reboot.css.map
│ │ ├── bootstrap-reboot.min.css
│ │ ├── bootstrap-reboot.min.css.map
│ │ ├── bootstrap-reboot.rtl.css
│ │ ├── bootstrap-reboot.rtl.css.map
│ │ ├── bootstrap-reboot.rtl.min.css
│ │ ├── bootstrap-reboot.rtl.min.css.map
│ │ ├── bootstrap-utilities.css
│ │ ├── bootstrap-utilities.css.map
│ │ ├── bootstrap-utilities.min.css
│ │ ├── bootstrap-utilities.min.css.map
│ │ ├── bootstrap-utilities.rtl.css
│ │ ├── bootstrap-utilities.rtl.css.map
│ │ ├── bootstrap-utilities.rtl.min.css
│ │ ├── bootstrap-utilities.rtl.min.css.map
│ │ ├── bootstrap.css
│ │ ├── bootstrap.css.map
│ │ ├── bootstrap.min.css
│ │ ├── bootstrap.min.css.map
│ │ ├── bootstrap.rtl.css
│ │ ├── bootstrap.rtl.css.map
│ │ ├── bootstrap.rtl.min.css
│ │ └── bootstrap.rtl.min.css.map
│ │ └── js
│ │ ├── bootstrap.bundle.js
│ │ ├── bootstrap.bundle.js.map
│ │ ├── bootstrap.bundle.min.js
│ │ ├── bootstrap.bundle.min.js.map
│ │ ├── bootstrap.esm.js
│ │ ├── bootstrap.esm.js.map
│ │ ├── bootstrap.esm.min.js
│ │ ├── bootstrap.esm.min.js.map
│ │ ├── bootstrap.js
│ │ ├── bootstrap.js.map
│ │ ├── bootstrap.min.js
│ │ └── bootstrap.min.js.map
│ ├── jquery-validation-unobtrusive
│ ├── LICENSE.txt
│ ├── jquery.validate.unobtrusive.js
│ └── jquery.validate.unobtrusive.min.js
│ ├── jquery-validation
│ ├── LICENSE.md
│ └── dist
│ │ ├── additional-methods.js
│ │ ├── additional-methods.min.js
│ │ ├── jquery.validate.js
│ │ └── jquery.validate.min.js
│ └── jquery
│ ├── LICENSE.txt
│ └── dist
│ ├── jquery.js
│ ├── jquery.min.js
│ └── jquery.min.map
├── LICENSE.md
├── Monitoring
├── ApplicationMapNodeNameInitializer.cs
└── Monitoring.csproj
├── README.md
└── docs
└── media
├── ab-test.png
├── all-green.png
├── app-config.png
├── build-running.png
├── build-started.png
├── create-revision.png
├── default-snapshot.png
├── edit-deploy.png
├── edited-file.png
├── feature-flags-logs.png
├── feature-flags-resources.png
├── new-revision.png
├── secrets.png
├── starting-revisions.png
└── topology.png
/.dockerignore:
--------------------------------------------------------------------------------
1 | **/.classpath
2 | **/.dockerignore
3 | **/.env
4 | **/.git
5 | **/.gitignore
6 | **/.project
7 | **/.settings
8 | **/.toolstarget
9 | **/.vs
10 | **/.vscode
11 | **/*.*proj.user
12 | **/*.dbmdl
13 | **/*.jfm
14 | **/azds.yaml
15 | **/bin
16 | **/charts
17 | **/docker-compose*
18 | **/Dockerfile*
19 | **/node_modules
20 | **/npm-debug.log
21 | **/obj
22 | **/secrets.dev.yaml
23 | **/values.dev.yaml
24 | LICENSE
25 | README.md
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Microsoft Open Source Code of Conduct
2 |
3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
4 |
5 | Resources:
6 |
7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
10 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
4 | > Please provide us with the following information:
5 | > ---------------------------------------------------------------
6 |
7 | ### This issue is for a: (mark with an `x`)
8 | ```
9 | - [ ] bug report -> please search issues before submitting
10 | - [ ] feature request
11 | - [ ] documentation issue or request
12 | - [ ] regression (a behavior that used to work and stopped in a new release)
13 | ```
14 |
15 | ### Minimal steps to reproduce
16 | >
17 |
18 | ### Any log messages given by the failure
19 | >
20 |
21 | ### Expected/desired behavior
22 | >
23 |
24 | ### OS and Version?
25 | > Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?)
26 |
27 | ### Versions
28 | >
29 |
30 | ### Mention any other details that might be useful
31 |
32 | > ---------------------------------------------------------------
33 | > Thanks! We'll be in touch soon.
34 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Purpose
2 |
3 | * ...
4 |
5 | ## Does this introduce a breaking change?
6 |
7 | ```
8 | [ ] Yes
9 | [ ] No
10 | ```
11 |
12 | ## Pull Request Type
13 | What kind of change does this Pull Request introduce?
14 |
15 |
16 | ```
17 | [ ] Bugfix
18 | [ ] Feature
19 | [ ] Code style update (formatting, local variables)
20 | [ ] Refactoring (no functional changes, no api changes)
21 | [ ] Documentation content changes
22 | [ ] Other... Please describe:
23 | ```
24 |
25 | ## How to Test
26 | * Get the code
27 |
28 | ```
29 | git clone [repo-address]
30 | cd [repo-name]
31 | git checkout [branch-name]
32 | npm install
33 | ```
34 |
35 | * Test the code
36 |
37 | ```
38 | ```
39 |
40 | ## What to Check
41 | Verify that the following are valid
42 | * ...
43 |
44 | ## Other Information
45 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Build and deploy .NET application to Container App silo
2 |
3 | on:
4 | push:
5 | branches:
6 | - deploy
7 |
8 | env:
9 |
10 | # alphanumeric string under 14 characters
11 | RESOURCE_GROUP_NAME: featureflagsaca
12 |
13 | # specify your preferred region
14 | REGION: eastus
15 |
16 | FRONTEND_DOCKER: FeatureFlagsWithContainerApps/Dockerfile
17 | FRONTEND_IMAGE: frontend
18 |
19 | jobs:
20 | provision:
21 | runs-on: ubuntu-latest
22 |
23 | steps:
24 |
25 | - name: Checkout to the branch
26 | uses: actions/checkout@v2
27 |
28 | - name: Azure Login
29 | uses: azure/login@v1
30 | with:
31 | creds: ${{ secrets.AzureSPN }}
32 |
33 | - name: Create resource group
34 | uses: azure/CLI@v1
35 | with:
36 | inlineScript: >
37 | echo "Creating resource group in Azure"
38 | echo "Executing 'az group create -l ${{ env.REGION }} -n ${{ env.RESOURCE_GROUP_NAME }}'"
39 |
40 | az group create -l ${{ env.REGION }} -n ${{ env.RESOURCE_GROUP_NAME }}
41 |
42 | - name: Creating resources
43 | uses: azure/CLI@v1
44 | with:
45 | inlineScript: >
46 | echo "Creating resources"
47 |
48 | az deployment group create --resource-group ${{ env.RESOURCE_GROUP_NAME }} --template-file '/github/workspace/Azure/main.bicep' --debug
49 |
50 | build:
51 | runs-on: ubuntu-latest
52 | needs: provision
53 |
54 | steps:
55 |
56 | - name: Checkout to the branch
57 | uses: actions/checkout@v2
58 |
59 | - name: Azure Login
60 | uses: azure/login@v1
61 | with:
62 | creds: ${{ secrets.AzureSPN }}
63 |
64 | - name: Set up Docker Buildx
65 | uses: docker/setup-buildx-action@v1
66 |
67 | - name: Login to ACR
68 | run: |
69 | set -euo pipefail
70 | access_token=$(az account get-access-token --query accessToken -o tsv)
71 | refresh_token=$(curl https://${{ env.RESOURCE_GROUP_NAME }}acr.azurecr.io/oauth2/exchange -v -d "grant_type=access_token&service=${{ env.RESOURCE_GROUP_NAME }}acr.azurecr.io&access_token=$access_token" | jq -r .refresh_token)
72 | docker login -u 00000000-0000-0000-0000-000000000000 --password-stdin ${{ env.RESOURCE_GROUP_NAME }}acr.azurecr.io <<< "$refresh_token"
73 |
74 | - name: Build the frontend image and push it to ACR
75 | uses: docker/build-push-action@v2
76 | with:
77 | push: true
78 | tags: ${{ env.RESOURCE_GROUP_NAME }}acr.azurecr.io/${{ env.FRONTEND_IMAGE }}:${{ github.sha }}
79 | file: ${{ env.FRONTEND_DOCKER }}
80 |
81 | deploy:
82 | runs-on: ubuntu-latest
83 | needs: build
84 |
85 | steps:
86 |
87 | - name: Checkout to the branch
88 | uses: actions/checkout@v2
89 |
90 | - name: Azure Login
91 | uses: azure/login@v1
92 | with:
93 | creds: ${{ secrets.AzureSPN }}
94 |
95 | - name: Installing Container Apps extension
96 | uses: azure/CLI@v1
97 | with:
98 | inlineScript: >
99 | az config set extension.use_dynamic_install=yes_without_prompt
100 |
101 | az extension add --name containerapp --yes
102 |
103 | - name: Login to ACR
104 | run: |
105 | set -euo pipefail
106 | access_token=$(az account get-access-token --query accessToken -o tsv)
107 | refresh_token=$(curl https://${{ env.RESOURCE_GROUP_NAME }}acr.azurecr.io/oauth2/exchange -v -d "grant_type=access_token&service=${{ env.RESOURCE_GROUP_NAME }}acr.azurecr.io&access_token=$access_token" | jq -r .refresh_token)
108 | docker login -u 00000000-0000-0000-0000-000000000000 --password-stdin ${{ env.RESOURCE_GROUP_NAME }}acr.azurecr.io <<< "$refresh_token"
109 |
110 | - name: Deploy Container Apps
111 | uses: azure/CLI@v1
112 | with:
113 | inlineScript: >
114 | az containerapp registry set -n frontend -g ${{ env.RESOURCE_GROUP_NAME }} --server ${{ env.RESOURCE_GROUP_NAME }}acr.azurecr.io
115 |
116 | az containerapp update -n frontend -g ${{ env.RESOURCE_GROUP_NAME }} -i ${{ env.RESOURCE_GROUP_NAME }}acr.azurecr.io/${{ env.FRONTEND_IMAGE }}:${{ github.sha }}
117 |
118 | - name: logout
119 | run: >
120 | az logout
121 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Aa][Rr][Mm]/
27 | [Aa][Rr][Mm]64/
28 | bld/
29 | [Bb]in/
30 | [Oo]bj/
31 | [Ll]og/
32 | [Ll]ogs/
33 |
34 | # Visual Studio 2015/2017 cache/options directory
35 | .vs/
36 | # Uncomment if you have tasks that create the project's static files in wwwroot
37 | #wwwroot/
38 |
39 | # Visual Studio 2017 auto generated files
40 | Generated\ Files/
41 |
42 | # MSTest test Results
43 | [Tt]est[Rr]esult*/
44 | [Bb]uild[Ll]og.*
45 |
46 | # NUnit
47 | *.VisualState.xml
48 | TestResult.xml
49 | nunit-*.xml
50 |
51 | # Build Results of an ATL Project
52 | [Dd]ebugPS/
53 | [Rr]eleasePS/
54 | dlldata.c
55 |
56 | # Benchmark Results
57 | BenchmarkDotNet.Artifacts/
58 |
59 | # .NET Core
60 | project.lock.json
61 | project.fragment.lock.json
62 | artifacts/
63 |
64 | # StyleCop
65 | StyleCopReport.xml
66 |
67 | # Files built by Visual Studio
68 | *_i.c
69 | *_p.c
70 | *_h.h
71 | *.ilk
72 | *.meta
73 | *.obj
74 | *.iobj
75 | *.pch
76 | *.pdb
77 | *.ipdb
78 | *.pgc
79 | *.pgd
80 | *.rsp
81 | *.sbr
82 | *.tlb
83 | *.tli
84 | *.tlh
85 | *.tmp
86 | *.tmp_proj
87 | *_wpftmp.csproj
88 | *.log
89 | *.vspscc
90 | *.vssscc
91 | .builds
92 | *.pidb
93 | *.svclog
94 | *.scc
95 |
96 | # Chutzpah Test files
97 | _Chutzpah*
98 |
99 | # Visual C++ cache files
100 | ipch/
101 | *.aps
102 | *.ncb
103 | *.opendb
104 | *.opensdf
105 | *.sdf
106 | *.cachefile
107 | *.VC.db
108 | *.VC.VC.opendb
109 |
110 | # Visual Studio profiler
111 | *.psess
112 | *.vsp
113 | *.vspx
114 | *.sap
115 |
116 | # Visual Studio Trace Files
117 | *.e2e
118 |
119 | # TFS 2012 Local Workspace
120 | $tf/
121 |
122 | # Guidance Automation Toolkit
123 | *.gpState
124 |
125 | # ReSharper is a .NET coding add-in
126 | _ReSharper*/
127 | *.[Rr]e[Ss]harper
128 | *.DotSettings.user
129 |
130 | # TeamCity is a build add-in
131 | _TeamCity*
132 |
133 | # DotCover is a Code Coverage Tool
134 | *.dotCover
135 |
136 | # AxoCover is a Code Coverage Tool
137 | .axoCover/*
138 | !.axoCover/settings.json
139 |
140 | # Visual Studio code coverage results
141 | *.coverage
142 | *.coveragexml
143 |
144 | # NCrunch
145 | _NCrunch_*
146 | .*crunch*.local.xml
147 | nCrunchTemp_*
148 |
149 | # MightyMoose
150 | *.mm.*
151 | AutoTest.Net/
152 |
153 | # Web workbench (sass)
154 | .sass-cache/
155 |
156 | # Installshield output folder
157 | [Ee]xpress/
158 |
159 | # DocProject is a documentation generator add-in
160 | DocProject/buildhelp/
161 | DocProject/Help/*.HxT
162 | DocProject/Help/*.HxC
163 | DocProject/Help/*.hhc
164 | DocProject/Help/*.hhk
165 | DocProject/Help/*.hhp
166 | DocProject/Help/Html2
167 | DocProject/Help/html
168 |
169 | # Click-Once directory
170 | publish/
171 |
172 | # Publish Web Output
173 | *.[Pp]ublish.xml
174 | *.azurePubxml
175 | # Note: Comment the next line if you want to checkin your web deploy settings,
176 | # but database connection strings (with potential passwords) will be unencrypted
177 | *.pubxml
178 | *.publishproj
179 |
180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
181 | # checkin your Azure Web App publish settings, but sensitive information contained
182 | # in these scripts will be unencrypted
183 | PublishScripts/
184 |
185 | # NuGet Packages
186 | *.nupkg
187 | # NuGet Symbol Packages
188 | *.snupkg
189 | # The packages folder can be ignored because of Package Restore
190 | **/[Pp]ackages/*
191 | # except build/, which is used as an MSBuild target.
192 | !**/[Pp]ackages/build/
193 | # Uncomment if necessary however generally it will be regenerated when needed
194 | #!**/[Pp]ackages/repositories.config
195 | # NuGet v3's project.json files produces more ignorable files
196 | *.nuget.props
197 | *.nuget.targets
198 |
199 | # Microsoft Azure Build Output
200 | csx/
201 | *.build.csdef
202 |
203 | # Microsoft Azure Emulator
204 | ecf/
205 | rcf/
206 |
207 | # Windows Store app package directories and files
208 | AppPackages/
209 | BundleArtifacts/
210 | Package.StoreAssociation.xml
211 | _pkginfo.txt
212 | *.appx
213 | *.appxbundle
214 | *.appxupload
215 |
216 | # Visual Studio cache files
217 | # files ending in .cache can be ignored
218 | *.[Cc]ache
219 | # but keep track of directories ending in .cache
220 | !?*.[Cc]ache/
221 |
222 | # Others
223 | ClientBin/
224 | ~$*
225 | *~
226 | *.dbmdl
227 | *.dbproj.schemaview
228 | *.jfm
229 | *.pfx
230 | *.publishsettings
231 | orleans.codegen.cs
232 |
233 | # Including strong name files can present a security risk
234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
235 | #*.snk
236 |
237 | # Since there are multiple workflows, uncomment next line to ignore bower_components
238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
239 | #bower_components/
240 |
241 | # RIA/Silverlight projects
242 | Generated_Code/
243 |
244 | # Backup & report files from converting an old project file
245 | # to a newer Visual Studio version. Backup files are not needed,
246 | # because we have git ;-)
247 | _UpgradeReport_Files/
248 | Backup*/
249 | UpgradeLog*.XML
250 | UpgradeLog*.htm
251 | ServiceFabricBackup/
252 | *.rptproj.bak
253 |
254 | # SQL Server files
255 | *.mdf
256 | *.ldf
257 | *.ndf
258 |
259 | # Business Intelligence projects
260 | *.rdl.data
261 | *.bim.layout
262 | *.bim_*.settings
263 | *.rptproj.rsuser
264 | *- [Bb]ackup.rdl
265 | *- [Bb]ackup ([0-9]).rdl
266 | *- [Bb]ackup ([0-9][0-9]).rdl
267 |
268 | # Microsoft Fakes
269 | FakesAssemblies/
270 |
271 | # GhostDoc plugin setting file
272 | *.GhostDoc.xml
273 |
274 | # Node.js Tools for Visual Studio
275 | .ntvs_analysis.dat
276 | node_modules/
277 |
278 | # Visual Studio 6 build log
279 | *.plg
280 |
281 | # Visual Studio 6 workspace options file
282 | *.opt
283 |
284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
285 | *.vbw
286 |
287 | # Visual Studio LightSwitch build output
288 | **/*.HTMLClient/GeneratedArtifacts
289 | **/*.DesktopClient/GeneratedArtifacts
290 | **/*.DesktopClient/ModelManifest.xml
291 | **/*.Server/GeneratedArtifacts
292 | **/*.Server/ModelManifest.xml
293 | _Pvt_Extensions
294 |
295 | # Paket dependency manager
296 | .paket/paket.exe
297 | paket-files/
298 |
299 | # FAKE - F# Make
300 | .fake/
301 |
302 | # CodeRush personal settings
303 | .cr/personal
304 |
305 | # Python Tools for Visual Studio (PTVS)
306 | __pycache__/
307 | *.pyc
308 |
309 | # Cake - Uncomment if you are using it
310 | # tools/**
311 | # !tools/packages.config
312 |
313 | # Tabs Studio
314 | *.tss
315 |
316 | # Telerik's JustMock configuration file
317 | *.jmconfig
318 |
319 | # BizTalk build output
320 | *.btp.cs
321 | *.btm.cs
322 | *.odx.cs
323 | *.xsd.cs
324 |
325 | # OpenCover UI analysis results
326 | OpenCover/
327 |
328 | # Azure Stream Analytics local run output
329 | ASALocalRun/
330 |
331 | # MSBuild Binary and Structured Log
332 | *.binlog
333 |
334 | # NVidia Nsight GPU debugger configuration file
335 | *.nvuser
336 |
337 | # MFractors (Xamarin productivity tool) working folder
338 | .mfractor/
339 |
340 | # Local History for Visual Studio
341 | .localhistory/
342 |
343 | # BeatPulse healthcheck temp database
344 | healthchecksdb
345 |
346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
347 | MigrationBackup/
348 |
349 | # Ionide (cross platform F# VS Code tools) working folder
350 | .ionide/
351 |
--------------------------------------------------------------------------------
/Azure/app_config.bicep:
--------------------------------------------------------------------------------
1 | @description('Specifies the name of the App Configuration store.')
2 | param configStoreName string = 'appconfig${uniqueString(resourceGroup().id)}'
3 |
4 | @description('Specifies the Azure location where the app configuration store should be created.')
5 | param location string = resourceGroup().location
6 |
7 | @description('Specifies the key of the feature flag.')
8 | param featureFlagKey string
9 |
10 | @description('Specifies the label of the feature flag. The label is optional and can be left as empty.')
11 | param featureFlagLabelEnabled string
12 |
13 | var featureFlagValue = {
14 | id: featureFlagKey
15 | description: 'Your description.'
16 | enabled: true
17 | }
18 |
19 | resource appConfig 'Microsoft.AppConfiguration/configurationStores@2021-10-01-preview' ={
20 | location: location
21 | name: configStoreName
22 | sku: {
23 | name: 'free'
24 | }
25 | }
26 |
27 | var appConfigConnectionString = appConfig.listKeys().value[0].connectionString
28 |
29 | resource beta 'Microsoft.AppConfiguration/configurationStores/keyValues@2021-10-01-preview' ={
30 | parent: appConfig
31 | name: '.appconfig.featureflag~2F${featureFlagKey}$${featureFlagLabelEnabled}'
32 | properties: {
33 | value: string(featureFlagValue)
34 | contentType: 'application/vnd.microsoft.appconfig.ff+json;charset=utf-8'
35 | }
36 | }
37 |
38 | output appConfigConnectionString string = appConfigConnectionString
39 |
--------------------------------------------------------------------------------
/Azure/container_app.bicep:
--------------------------------------------------------------------------------
1 | param name string
2 | param location string = resourceGroup().location
3 | param containerAppEnvironmentId string
4 | param repositoryImage string = 'mcr.microsoft.com/azuredocs/containerapps-helloworld:latest'
5 | param envVars array = []
6 | param registry string
7 | param minReplicas int = 1
8 | param maxReplicas int = 1
9 | param registryUsername string
10 | @secure()
11 | param registryPassword string
12 |
13 | resource containerApp 'Microsoft.App/containerApps@2022-01-01-preview' ={
14 | name: name
15 | location: location
16 | properties:{
17 | managedEnvironmentId: containerAppEnvironmentId
18 | configuration: {
19 | activeRevisionsMode: 'multiple'
20 | secrets: [
21 | {
22 | name: 'container-registry-password'
23 | value: registryPassword
24 | }
25 | ]
26 | registries: [
27 | {
28 | server: registry
29 | username: registryUsername
30 | passwordSecretRef: 'container-registry-password'
31 | }
32 | ]
33 | ingress: {
34 | external: true
35 | targetPort: 80
36 | transport: 'http'
37 | allowInsecure: true
38 | }
39 | }
40 | template: {
41 | containers: [
42 | {
43 | image: repositoryImage
44 | name: name
45 | env: envVars
46 | }
47 | ]
48 | scale: {
49 | minReplicas: minReplicas
50 | maxReplicas: maxReplicas
51 | }
52 | }
53 | }
54 | }
55 |
56 | output fqdn string = containerApp.properties.configuration.ingress.fqdn
57 |
--------------------------------------------------------------------------------
/Azure/environment.bicep:
--------------------------------------------------------------------------------
1 | param baseName string = resourceGroup().name
2 | param location string = resourceGroup().location
3 |
4 | resource logs 'Microsoft.OperationalInsights/workspaces@2021-06-01' = {
5 | name: '${baseName}logs'
6 | location: location
7 | properties: any({
8 | retentionInDays: 30
9 | features: {
10 | searchVersion: 1
11 | }
12 | sku: {
13 | name: 'PerGB2018'
14 | }
15 | })
16 | }
17 |
18 | resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
19 | name: '${baseName}ai'
20 | location: location
21 | kind: 'web'
22 | properties: {
23 | Application_Type: 'web'
24 | WorkspaceResourceId: logs.id
25 | }
26 | }
27 |
28 | resource env 'Microsoft.App/managedEnvironments@2022-01-01-preview' = {
29 | name: '${baseName}env'
30 | location: location
31 | properties: {
32 | appLogsConfiguration: {
33 | destination: 'log-analytics'
34 | logAnalyticsConfiguration: {
35 | customerId: logs.properties.customerId
36 | sharedKey: logs.listKeys().primarySharedKey
37 | }
38 | }
39 | }
40 | }
41 |
42 | output id string = env.id
43 | output appInsightsInstrumentationKey string = appInsights.properties.InstrumentationKey
44 | output appInsightsConnectionString string = appInsights.properties.ConnectionString
45 |
--------------------------------------------------------------------------------
/Azure/main.bicep:
--------------------------------------------------------------------------------
1 | param location string = resourceGroup().location
2 |
3 | // create the azure container registry
4 | resource acr 'Microsoft.ContainerRegistry/registries@2021-09-01' = {
5 | name: toLower('${resourceGroup().name}acr')
6 | location: location
7 | sku: {
8 | name: 'Basic'
9 | }
10 | properties: {
11 | adminUserEnabled: true
12 | }
13 | }
14 |
15 | // create the aca environment
16 | module env 'environment.bicep' = {
17 | name: 'containerAppEnvironment'
18 | params: {
19 | location: location
20 | }
21 | }
22 |
23 | // create the azure app configuration
24 | module appConfig 'app_config.bicep' ={
25 | name: 'appConfiguration'
26 | params: {
27 | location: location
28 | featureFlagKey: 'Beta'
29 | featureFlagLabelEnabled: 'BetaEnabled'
30 | }
31 | }
32 |
33 | // create the various config pairs
34 | var shared_config = [
35 | {
36 | name: 'ASPNETCORE_ENVIRONMENT'
37 | value: 'Development'
38 | }
39 | {
40 | name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
41 | value: env.outputs.appInsightsInstrumentationKey
42 | }
43 | {
44 | name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
45 | value: env.outputs.appInsightsConnectionString
46 | }
47 | {
48 | name: 'AzureAppConfig'
49 | value: appConfig.outputs.appConfigConnectionString
50 | }
51 | {
52 | name: 'RevisionLabel'
53 | value: 'BetaDisabled'
54 | }
55 | ]
56 |
57 | // create the service container app
58 | module frontend 'container_app.bicep' = {
59 | name: 'frontend'
60 | params: {
61 | name: 'frontend'
62 | location: location
63 | registryPassword: acr.listCredentials().passwords[0].value
64 | registryUsername: acr.listCredentials().username
65 | containerAppEnvironmentId: env.outputs.id
66 | registry: acr.name
67 | envVars: shared_config
68 | }
69 | }
70 |
71 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [project-title] Changelog
2 |
3 |
4 | # x.y.z (yyyy-mm-dd)
5 |
6 | *Features*
7 | * ...
8 |
9 | *Bug Fixes*
10 | * ...
11 |
12 | *Breaking Changes*
13 | * ...
14 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to [project-title]
2 |
3 | This project welcomes contributions and suggestions. Most contributions require you to agree to a
4 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
5 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
6 |
7 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide
8 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
9 | provided by the bot. You will only need to do this once across all repos using our CLA.
10 |
11 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
12 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
13 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
14 |
15 | - [Code of Conduct](#coc)
16 | - [Issues and Bugs](#issue)
17 | - [Feature Requests](#feature)
18 | - [Submission Guidelines](#submit)
19 |
20 | ## Code of Conduct
21 | Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
22 |
23 | ## Found an Issue?
24 | If you find a bug in the source code or a mistake in the documentation, you can help us by
25 | [submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can
26 | [submit a Pull Request](#submit-pr) with a fix.
27 |
28 | ## Want a Feature?
29 | You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub
30 | Repository. If you would like to *implement* a new feature, please submit an issue with
31 | a proposal for your work first, to be sure that we can use it.
32 |
33 | * **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
34 |
35 | ## Submission Guidelines
36 |
37 | ### Submitting an Issue
38 | Before you submit an issue, search the archive, maybe your question was already answered.
39 |
40 | If your issue appears to be a bug, and hasn't been reported, open a new issue.
41 | Help us to maximize the effort we can spend fixing issues and adding new
42 | features, by not reporting duplicate issues. Providing the following information will increase the
43 | chances of your issue being dealt with quickly:
44 |
45 | * **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
46 | * **Version** - what version is affected (e.g. 0.1.2)
47 | * **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you
48 | * **Browsers and Operating System** - is this a problem with all browsers?
49 | * **Reproduce the Error** - provide a live example or a unambiguous set of steps
50 | * **Related Issues** - has a similar issue been reported before?
51 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
52 | causing the problem (line of code or commit)
53 |
54 | You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/[organization-name]/[repository-name]/issues/new].
55 |
56 | ### Submitting a Pull Request (PR)
57 | Before you submit your Pull Request (PR) consider the following guidelines:
58 |
59 | * Search the repository (https://github.com/[organization-name]/[repository-name]/pulls) for an open or closed PR
60 | that relates to your submission. You don't want to duplicate effort.
61 |
62 | * Make your changes in a new git fork:
63 |
64 | * Commit your changes using a descriptive commit message
65 | * Push your fork to GitHub:
66 | * In GitHub, create a pull request
67 | * If we suggest changes then:
68 | * Make the required updates.
69 | * Rebase your fork and force push to your GitHub repository (this will update your Pull Request):
70 |
71 | ```shell
72 | git rebase master -i
73 | git push -f
74 | ```
75 |
76 | That's it! Thank you for your contribution!
77 |
--------------------------------------------------------------------------------
/FeatureFlagsWithContainerApps.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.2.32324.85
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FeatureFlagsWithContainerApps", "FeatureFlagsWithContainerApps\FeatureFlagsWithContainerApps.csproj", "{629E3242-5537-4728-9D63-BDCA7FC8B21C}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Monitoring", "Monitoring\Monitoring.csproj", "{681A8BE8-9351-47EA-9B14-53F7BDB4C444}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {629E3242-5537-4728-9D63-BDCA7FC8B21C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {629E3242-5537-4728-9D63-BDCA7FC8B21C}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {629E3242-5537-4728-9D63-BDCA7FC8B21C}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {629E3242-5537-4728-9D63-BDCA7FC8B21C}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {681A8BE8-9351-47EA-9B14-53F7BDB4C444}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {681A8BE8-9351-47EA-9B14-53F7BDB4C444}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {681A8BE8-9351-47EA-9B14-53F7BDB4C444}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {681A8BE8-9351-47EA-9B14-53F7BDB4C444}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(ExtensibilityGlobals) = postSolution
29 | SolutionGuid = {1A1162D8-963C-40EF-B6D4-DA48691874C4}
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/FeatureFlagsWithContainerApps/Controllers/BetaController.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.ApplicationInsights;
2 | using Microsoft.AspNetCore.Mvc;
3 | using Microsoft.FeatureManagement;
4 | using Microsoft.FeatureManagement.Mvc;
5 |
6 | namespace TestFeatureFlags.Controllers
7 | {
8 | public class BetaController : Controller
9 | {
10 | private readonly IFeatureManager _featureManager;
11 | private readonly TelemetryClient _telemetryClient;
12 |
13 | public BetaController(IFeatureManagerSnapshot featureManager, TelemetryClient telemetryClient)
14 | {
15 | _featureManager = featureManager;
16 | _telemetryClient = telemetryClient;
17 | }
18 |
19 | //[FeatureGate(MyFeatureFlags.Beta)]
20 | public IActionResult Index()
21 | {
22 | _telemetryClient.TrackEvent("Beta Page Loaded");
23 | return View();
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/FeatureFlagsWithContainerApps/Dockerfile:
--------------------------------------------------------------------------------
1 | #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
2 |
3 | FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
4 | WORKDIR /app
5 | EXPOSE 80
6 |
7 | FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
8 | WORKDIR /src
9 | COPY ["FeatureFlagsWithContainerApps/FeatureFlagsWithContainerApps.csproj", "FeatureFlagsWithContainerApps/"]
10 | RUN dotnet restore "FeatureFlagsWithContainerApps/FeatureFlagsWithContainerApps.csproj"
11 | COPY . .
12 | WORKDIR "/src/FeatureFlagsWithContainerApps"
13 | RUN dotnet build "FeatureFlagsWithContainerApps.csproj" -c Release -o /app/build
14 |
15 | FROM build AS publish
16 | RUN dotnet publish "FeatureFlagsWithContainerApps.csproj" -c Release -o /app/publish
17 |
18 | FROM base AS final
19 | WORKDIR /app
20 | COPY --from=publish /app/publish .
21 | ENTRYPOINT ["dotnet", "FeatureFlagsWithContainerApps.dll"]
--------------------------------------------------------------------------------
/FeatureFlagsWithContainerApps/FeatureFlagsWithContainerApps.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | enable
7 | Linux
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/FeatureFlagsWithContainerApps/Pages/Error.cshtml:
--------------------------------------------------------------------------------
1 | @page
2 | @model ErrorModel
3 | @{
4 | ViewData["Title"] = "Error";
5 | }
6 |
7 |
Error.
8 |
An error occurred while processing your request.
9 |
10 | @if (Model.ShowRequestId)
11 | {
12 |
13 | Request ID:@Model.RequestId
14 |
15 | }
16 |
17 |
Development Mode
18 |
19 | Swapping to the Development environment displays detailed information about the error that occurred.
20 |
21 |
22 | The Development environment shouldn't be enabled for deployed applications.
23 | It can result in displaying sensitive information from exceptions to end users.
24 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development
25 | and restarting the app.
26 |
` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n\n%heading {\n margin-top: 0; // 1\n margin-bottom: $headings-margin-bottom;\n font-family: $headings-font-family;\n font-style: $headings-font-style;\n font-weight: $headings-font-weight;\n line-height: $headings-line-height;\n color: $headings-color;\n}\n\nh1 {\n @extend %heading;\n @include font-size($h1-font-size);\n}\n\nh2 {\n @extend %heading;\n @include font-size($h2-font-size);\n}\n\nh3 {\n @extend %heading;\n @include font-size($h3-font-size);\n}\n\nh4 {\n @extend %heading;\n @include font-size($h4-font-size);\n}\n\nh5 {\n @extend %heading;\n @include font-size($h5-font-size);\n}\n\nh6 {\n @extend %heading;\n @include font-size($h6-font-size);\n}\n\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `
`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\n\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n\n// Abbreviations\n//\n// 1. Duplicate behavior to the data-bs-* attribute for our tooltip plugin\n// 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Prevent the text-decoration to be skipped.\n\nabbr[title],\nabbr[data-bs-original-title] { // 1\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n text-decoration-skip-ink: none; // 4\n}\n\n\n// Address\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\n\n// Lists\n\nol,\nul {\n padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\n// 1. Undo browser default\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // 1\n}\n\n\n// Blockquote\n\nblockquote {\n margin: 0 0 1rem;\n}\n\n\n// Strong\n//\n// Add the correct font weight in Chrome, Edge, and Safari\n\nb,\nstrong {\n font-weight: $font-weight-bolder;\n}\n\n\n// Small\n//\n// Add the correct font size in all browsers\n\nsmall {\n @include font-size($small-font-size);\n}\n\n\n// Mark\n\nmark {\n padding: $mark-padding;\n background-color: $mark-bg;\n}\n\n\n// Sub and Sup\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n\nsub,\nsup {\n position: relative;\n @include font-size($sub-sup-font-size);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n// Links\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n\n &:hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n &,\n &:hover {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n// Code\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-code;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n direction: ltr #{\"/* rtl:ignore */\"};\n unicode-bidi: bidi-override;\n}\n\n// 1. Remove browser default top margin\n// 2. Reset browser default of `1em` to use `rem`s\n// 3. Don't allow content to break outside\n\npre {\n display: block;\n margin-top: 0; // 1\n margin-bottom: 1rem; // 2\n overflow: auto; // 3\n @include font-size($code-font-size);\n color: $pre-color;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n @include font-size(inherit);\n color: inherit;\n word-break: normal;\n }\n}\n\ncode {\n @include font-size($code-font-size);\n color: $code-color;\n word-wrap: break-word;\n\n // Streamline the style when inside anchors to avoid broken underline and more\n a > & {\n color: inherit;\n }\n}\n\nkbd {\n padding: $kbd-padding-y $kbd-padding-x;\n @include font-size($kbd-font-size);\n color: $kbd-color;\n background-color: $kbd-bg;\n @include border-radius($border-radius-sm);\n\n kbd {\n padding: 0;\n @include font-size(1em);\n font-weight: $nested-kbd-font-weight;\n }\n}\n\n\n// Figures\n//\n// Apply a consistent margin strategy (matches our type styles).\n\nfigure {\n margin: 0 0 1rem;\n}\n\n\n// Images and content\n\nimg,\nsvg {\n vertical-align: middle;\n}\n\n\n// Tables\n//\n// Prevent double borders\n\ntable {\n caption-side: bottom;\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: $table-cell-padding-y;\n padding-bottom: $table-cell-padding-y;\n color: $table-caption-color;\n text-align: left;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `
` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n border-color: inherit;\n border-style: solid;\n border-width: 0;\n}\n\n\n// Forms\n//\n// 1. Allow labels to use `margin` for spacing.\n\nlabel {\n display: inline-block; // 1\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n// See https://github.com/twbs/bootstrap/issues/24093\n\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\n// 1. Remove the margin in Firefox and Safari\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // 1\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\n// Remove the inheritance of text transform in Firefox\nbutton,\nselect {\n text-transform: none;\n}\n// Set the cursor for non-`