Add support for feature flags (#2620)

* Foundation for feature flags

* Demo usage

* Use managed identity

* Add FFs using DI method

* missed a file

* Cleanup

* Forgot test context

* Default is off if the FF doesn't already exist

* Update src/ApiService/ApiService/Program.cs

Co-authored-by: George Pollard <porges@porg.es>

* force evaluate lock files

Co-authored-by: Teo Voinea <Teodor.Voinea@microsoft.com>
Co-authored-by: George Pollard <porges@porg.es>
This commit is contained in:
Teo Voinea
2022-12-05 09:07:00 -05:00
committed by GitHub
parent af806a3263
commit 59360103f1
15 changed files with 411 additions and 87 deletions

View File

@ -11,6 +11,9 @@
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.0.0-preview3" />
<PackageReference Include="Semver" Version="2.1.0" />
<PackageReference Include="Azure.Security.KeyVault.Secrets" Version="4.3.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.AzureAppConfiguration" Version="5.1.0" />
<PackageReference Include="Microsoft.FeatureManagement" Version="2.5.1" />
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Storage" Version="5.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.EventGrid" Version="2.1.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.13" />

View File

@ -0,0 +1,5 @@
namespace Microsoft.OneFuzz.Service;
public static class FeatureFlagConstants {
public const string EnableScribanOnly = "EnableScribanOnly";
}

View File

@ -8,6 +8,7 @@ public class AgentCanSchedule {
private readonly IEndpointAuthorization _auth;
private readonly IOnefuzzContext _context;
public AgentCanSchedule(ILogTracer log, IEndpointAuthorization auth, IOnefuzzContext context) {
_log = log;
_auth = auth;

View File

@ -13,8 +13,10 @@ using Azure.Identity;
using Microsoft.ApplicationInsights.DependencyCollector;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Middleware;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.FeatureManagement;
using Microsoft.Graph;
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;
@ -47,6 +49,13 @@ public class Program {
using var host =
new HostBuilder()
.ConfigureAppConfiguration(builder => {
var _ = builder.AddAzureAppConfiguration(options => {
var _ = options
.Connect(new Uri(configuration.AppConfigurationEndpoint!), new DefaultAzureCredential())
.UseFeatureFlags(ffOptions => ffOptions.CacheExpirationInterval = TimeSpan.FromMinutes(1));
});
})
.ConfigureFunctionsWorkerDefaults(builder => {
builder.UseMiddleware<LoggingMiddleware>();
builder.AddApplicationInsights(options => {
@ -54,6 +63,8 @@ public class Program {
});
})
.ConfigureServices((context, services) => {
services.AddAzureAppConfiguration();
_ = services.AddFeatureManagement();
services.Configure<JsonSerializerOptions>(options => {
options = EntityConverter.GetJsonSerializerOptions();
});

View File

@ -16,6 +16,7 @@ public interface IServiceConfig {
public string? ApplicationInsightsAppId { get; }
public string? ApplicationInsightsInstrumentationKey { get; }
public string? AppConfigurationEndpoint { get; }
public string? AzureSignalRConnectionString { get; }
public string? AzureSignalRServiceTransportType { get; }
@ -82,6 +83,8 @@ public class ServiceConfiguration : IServiceConfig {
public string? ApplicationInsightsAppId => GetEnv("APPINSIGHTS_APPID");
public string? ApplicationInsightsInstrumentationKey => GetEnv("APPINSIGHTS_INSTRUMENTATIONKEY");
public string? AppConfigurationEndpoint => GetEnv("APPCONFIGURATION_ENDPOINT");
public string? AzureSignalRConnectionString => GetEnv("AzureSignalRConnectionString");
public string? AzureSignalRServiceTransportType => GetEnv("AzureSignalRServiceTransportType");

View File

@ -1,8 +1,11 @@
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;
namespace Microsoft.OneFuzz.Service;
using Microsoft.Extensions.Configuration.AzureAppConfiguration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.FeatureManagement;
public interface IOnefuzzContext {
IAutoScaleOperations AutoScaleOperations { get; }
@ -46,6 +49,9 @@ public interface IOnefuzzContext {
ITeams Teams { get; }
IGithubIssues GithubIssues { get; }
IAdo Ado { get; }
IFeatureManagerSnapshot FeatureManagerSnapshot { get; }
IConfigurationRefresher ConfigurationRefresher { get; }
}
public class OnefuzzContext : IOnefuzzContext {
@ -95,4 +101,8 @@ public class OnefuzzContext : IOnefuzzContext {
public ITeams Teams => _serviceProvider.GetRequiredService<ITeams>();
public IGithubIssues GithubIssues => _serviceProvider.GetRequiredService<IGithubIssues>();
public IAdo Ado => _serviceProvider.GetRequiredService<IAdo>();
public IFeatureManagerSnapshot FeatureManagerSnapshot => _serviceProvider.GetRequiredService<IFeatureManagerSnapshot>();
public IConfigurationRefresher ConfigurationRefresher => _serviceProvider.GetRequiredService<IConfigurationRefresherProvider>().Refreshers.First();
}

View File

@ -34,6 +34,7 @@ public abstract class NotificationsBase {
private readonly Uri _targetUrl;
private readonly Uri _inputUrl;
private readonly Uri _reportUrl;
private readonly bool _scribanOnly;
public static async Async.Task<Renderer> ConstructRenderer(
IOnefuzzContext context,
@ -66,6 +67,9 @@ public abstract class NotificationsBase {
inputUrl = new Uri(context.Containers.AuthDownloadUrl(report.InputBlob.Container, report.InputBlob.Name));
}
await context.ConfigurationRefresher.TryRefreshAsync().IgnoreResult();
var scribanOnly = await context.FeatureManagerSnapshot.IsEnabledAsync(FeatureFlagConstants.EnableScribanOnly);
return new Renderer(
container,
filename,
@ -74,7 +78,8 @@ public abstract class NotificationsBase {
checkedJob,
targetUrl,
inputUrl!, // TODO: incorrect
reportUrl);
reportUrl,
scribanOnly);
}
public Renderer(
Container container,
@ -84,7 +89,8 @@ public abstract class NotificationsBase {
Job job,
Uri targetUrl,
Uri inputUrl,
Uri reportUrl) {
Uri reportUrl,
bool scribanOnly) {
_report = report;
_container = container;
_filename = filename;
@ -93,13 +99,17 @@ public abstract class NotificationsBase {
_reportUrl = reportUrl;
_targetUrl = targetUrl;
_inputUrl = inputUrl;
_scribanOnly = scribanOnly;
}
// TODO: This function is fallible but the python
// implementation doesn't have that so I'm trying to match it.
// We should probably propagate any errors up
public async Async.Task<string> Render(string templateString, Uri instanceUrl) {
templateString = JinjaTemplateAdapter.IsJinjaTemplate(templateString) ? JinjaTemplateAdapter.AdaptForScriban(templateString) : templateString;
if (!_scribanOnly && JinjaTemplateAdapter.IsJinjaTemplate(templateString)) {
templateString = JinjaTemplateAdapter.AdaptForScriban(templateString);
}
var template = Template.Parse(templateString);
if (template != null) {
return await template.RenderAsync(new {

View File

@ -157,6 +157,16 @@
"resolved": "0.12.2",
"contentHash": "JgMAGj8ekeAzKkagubXqf1UqgfHq89GyA1UQYWbkAe441uRr2Rh2rktkx5Z0LPwmD/aOqu9cxjekD2GZjP8rbw=="
},
"Microsoft.Azure.Functions.Extensions": {
"type": "Direct",
"requested": "[1.1.0, )",
"resolved": "1.1.0",
"contentHash": "zYKtQQoS1fdzufxFApuMFiFtoi9QAGH6McXxntpylwLKgKjmCMWdgUd1dcekzTKNR9DPSDPRLiulvukqXnpWrQ==",
"dependencies": {
"Microsoft.Azure.WebJobs": "3.0.18",
"Microsoft.Extensions.DependencyInjection": "2.1.0"
}
},
"Microsoft.Azure.Functions.Worker": {
"type": "Direct",
"requested": "[1.10.0, )",
@ -262,6 +272,31 @@
"System.Net.Http": "4.3.0"
}
},
"Microsoft.Extensions.Configuration.AzureAppConfiguration": {
"type": "Direct",
"requested": "[5.1.0, )",
"resolved": "5.1.0",
"contentHash": "FoAfgvT/rjL/+c7BP7q0LrJIdc4Hu6SH56BTIUbwCwVjHoUw4dpgGtLQULi5GmMjdbdAxyLQSnbwpOEWuBy+RA==",
"dependencies": {
"Azure.Data.AppConfiguration": "1.2.0",
"Azure.Messaging.EventGrid": "4.7.0",
"Azure.Security.KeyVault.Secrets": "4.0.1",
"Microsoft.Extensions.Configuration": "3.1.18",
"Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.18",
"Microsoft.Extensions.Logging": "3.1.18",
"System.Text.Json": "4.6.0"
}
},
"Microsoft.FeatureManagement": {
"type": "Direct",
"requested": "[2.5.1, )",
"resolved": "2.5.1",
"contentHash": "ERbRjk0etZs4d5Pv17unfogO4iBwV2c/HoBt4jqIJmfbKbmTLV+GbjBPYzidIg2RgYIFi8yA+EoEapSAIOp19g==",
"dependencies": {
"Microsoft.Extensions.Configuration.Binder": "2.1.10",
"Microsoft.Extensions.Logging": "2.1.1"
}
},
"Microsoft.Graph": {
"type": "Direct",
"requested": "[4.37.0, )",
@ -355,6 +390,16 @@
"resolved": "2.0.0",
"contentHash": "rXkSI9t4vP2EaPhuchsWiD3elcLNth3UOZAlGohGmuckpkiOr57oMHuzM5WDzz7MJd+ZewE27/WfrZhhhFDHzA=="
},
"Azure.Data.AppConfiguration": {
"type": "Transitive",
"resolved": "1.2.0",
"contentHash": "KA1dAM9TuDsq0CRFd+3cJTYUAzA2z9N8t9/xKdDbP9URuReq/NDFcKYr7GW2W9xzVGDtCHlD5j5am/+zLLBdSg==",
"dependencies": {
"Azure.Core": "1.20.0",
"Microsoft.Bcl.AsyncInterfaces": "1.0.0",
"System.Text.Json": "4.6.0"
}
},
"Azure.Storage.Common": {
"type": "Transitive",
"resolved": "12.12.0",
@ -567,6 +612,33 @@
"Microsoft.CodeAnalysis.CSharp": "3.11.0"
}
},
"Microsoft.Azure.WebJobs": {
"type": "Transitive",
"resolved": "3.0.18",
"contentHash": "aYJ76yjPkIpsafqFp1Xz1sA06RvhUwqJnk4AqX4I0teuRjPyig9Sv7LTzxUMAppKXc4JyR/Asos2At/LMiblqg==",
"dependencies": {
"Microsoft.Azure.WebJobs.Core": "3.0.18",
"Microsoft.Extensions.Configuration": "2.1.0",
"Microsoft.Extensions.Configuration.Abstractions": "2.1.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "2.1.0",
"Microsoft.Extensions.Configuration.Json": "2.1.0",
"Microsoft.Extensions.Hosting": "2.1.0",
"Microsoft.Extensions.Logging": "2.1.0",
"Microsoft.Extensions.Logging.Abstractions": "2.1.0",
"Microsoft.Extensions.Logging.Configuration": "2.1.0",
"Newtonsoft.Json": "11.0.2",
"System.Threading.Tasks.Dataflow": "4.8.0"
}
},
"Microsoft.Azure.WebJobs.Core": {
"type": "Transitive",
"resolved": "3.0.18",
"contentHash": "ajYI8pPzPn4qq7FL8C2tz9WmFEG5PorUlkw8W9CF5M+5egnFJaF7yH48WYC+zBoQIzv2vHmFq0zhQpnv+O8v5Q==",
"dependencies": {
"System.ComponentModel.Annotations": "4.4.0",
"System.Diagnostics.TraceSource": "4.3.0"
}
},
"Microsoft.Bcl.AsyncInterfaces": {
"type": "Transitive",
"resolved": "6.0.0",
@ -1381,6 +1453,22 @@
"System.Runtime": "4.3.0"
}
},
"System.Diagnostics.TraceSource": {
"type": "Transitive",
"resolved": "4.3.0",
"contentHash": "VnYp1NxGx8Ww731y2LJ1vpfb/DKVNKEZ8Jsh5SgQTZREL/YpWRArgh9pI8CDLmgHspZmLL697CaLvH85qQpRiw==",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0",
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Globalization": "4.3.0",
"System.Resources.ResourceManager": "4.3.0",
"System.Runtime": "4.3.0",
"System.Runtime.Extensions": "4.3.0",
"System.Threading": "4.3.0",
"runtime.native.System": "4.3.0"
}
},
"System.Diagnostics.Tracing": {
"type": "Transitive",
"resolved": "4.3.0",
@ -2077,6 +2165,11 @@
"System.Runtime": "4.3.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "Transitive",
"resolved": "4.8.0",
"contentHash": "PSIdcgbyNv7FZvZ1I9Mqy6XZOwstYYMdZiXuHvIyc0gDyPjEhrrP9OvTGDHp+LAHp1RNSLjPYssyqox9+Kt9Ug=="
},
"System.Threading.Tasks.Extensions": {
"type": "Transitive",
"resolved": "4.5.4",

View File

@ -1,7 +1,9 @@
using System;
using System.Linq;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration.AzureAppConfiguration;
using Microsoft.Extensions.Options;
using Microsoft.FeatureManagement;
using Microsoft.OneFuzz.Service;
using Microsoft.OneFuzz.Service.OneFuzzLib.Orm;
using Async = System.Threading.Tasks;
@ -120,6 +122,7 @@ public sealed class TestContext : IOnefuzzContext {
public ITeams Teams => throw new NotImplementedException();
public IGithubIssues GithubIssues => throw new NotImplementedException();
public IAdo Ado => throw new NotImplementedException();
public IFeatureManagerSnapshot FeatureManagerSnapshot => throw new NotImplementedException();
public IConfigurationRefresher ConfigurationRefresher => throw new NotImplementedException();
}

View File

@ -63,4 +63,5 @@ public sealed class TestServiceConfiguration : IServiceConfig {
public string? OneFuzzResourceGroup => throw new NotImplementedException();
public string? OneFuzzAllowOutdatedAgent => throw new NotImplementedException();
public string? AppConfigurationEndpoint => throw new NotImplementedException();
}

View File

@ -68,6 +68,16 @@
"System.Threading.Tasks.Extensions": "4.5.4"
}
},
"Azure.Data.AppConfiguration": {
"type": "Transitive",
"resolved": "1.2.0",
"contentHash": "KA1dAM9TuDsq0CRFd+3cJTYUAzA2z9N8t9/xKdDbP9URuReq/NDFcKYr7GW2W9xzVGDtCHlD5j5am/+zLLBdSg==",
"dependencies": {
"Azure.Core": "1.20.0",
"Microsoft.Bcl.AsyncInterfaces": "1.0.0",
"System.Text.Json": "4.6.0"
}
},
"Azure.Data.Tables": {
"type": "Transitive",
"resolved": "12.5.0",
@ -365,6 +375,15 @@
"resolved": "5.0.8",
"contentHash": "ZI9S2NGjuOKXN3PxJcF8EKVwd1cqpWyUSqiVoH8gqq5tlHaXULwPmoR0DBOFON4sEFETRWI69f5RQ3tJWw205A=="
},
"Microsoft.Azure.Functions.Extensions": {
"type": "Transitive",
"resolved": "1.1.0",
"contentHash": "zYKtQQoS1fdzufxFApuMFiFtoi9QAGH6McXxntpylwLKgKjmCMWdgUd1dcekzTKNR9DPSDPRLiulvukqXnpWrQ==",
"dependencies": {
"Microsoft.Azure.WebJobs": "3.0.18",
"Microsoft.Extensions.DependencyInjection": "2.1.0"
}
},
"Microsoft.Azure.Functions.Worker": {
"type": "Transitive",
"resolved": "1.10.0",
@ -519,6 +538,33 @@
"System.Net.Http": "4.3.0"
}
},
"Microsoft.Azure.WebJobs": {
"type": "Transitive",
"resolved": "3.0.18",
"contentHash": "aYJ76yjPkIpsafqFp1Xz1sA06RvhUwqJnk4AqX4I0teuRjPyig9Sv7LTzxUMAppKXc4JyR/Asos2At/LMiblqg==",
"dependencies": {
"Microsoft.Azure.WebJobs.Core": "3.0.18",
"Microsoft.Extensions.Configuration": "2.1.0",
"Microsoft.Extensions.Configuration.Abstractions": "2.1.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "2.1.0",
"Microsoft.Extensions.Configuration.Json": "2.1.0",
"Microsoft.Extensions.Hosting": "2.1.0",
"Microsoft.Extensions.Logging": "2.1.0",
"Microsoft.Extensions.Logging.Abstractions": "2.1.0",
"Microsoft.Extensions.Logging.Configuration": "2.1.0",
"Newtonsoft.Json": "11.0.2",
"System.Threading.Tasks.Dataflow": "4.8.0"
}
},
"Microsoft.Azure.WebJobs.Core": {
"type": "Transitive",
"resolved": "3.0.18",
"contentHash": "ajYI8pPzPn4qq7FL8C2tz9WmFEG5PorUlkw8W9CF5M+5egnFJaF7yH48WYC+zBoQIzv2vHmFq0zhQpnv+O8v5Q==",
"dependencies": {
"System.ComponentModel.Annotations": "4.4.0",
"System.Diagnostics.TraceSource": "4.3.0"
}
},
"Microsoft.Bcl.AsyncInterfaces": {
"type": "Transitive",
"resolved": "6.0.0",
@ -598,6 +644,20 @@
"Microsoft.Extensions.Primitives": "5.0.0"
}
},
"Microsoft.Extensions.Configuration.AzureAppConfiguration": {
"type": "Transitive",
"resolved": "5.1.0",
"contentHash": "FoAfgvT/rjL/+c7BP7q0LrJIdc4Hu6SH56BTIUbwCwVjHoUw4dpgGtLQULi5GmMjdbdAxyLQSnbwpOEWuBy+RA==",
"dependencies": {
"Azure.Data.AppConfiguration": "1.2.0",
"Azure.Messaging.EventGrid": "4.7.0",
"Azure.Security.KeyVault.Secrets": "4.0.1",
"Microsoft.Extensions.Configuration": "3.1.18",
"Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.18",
"Microsoft.Extensions.Logging": "3.1.18",
"System.Text.Json": "4.6.0"
}
},
"Microsoft.Extensions.Configuration.Binder": {
"type": "Transitive",
"resolved": "5.0.0",
@ -856,6 +916,15 @@
"resolved": "5.0.1",
"contentHash": "5WPSmL4YeP7eW+Vc8XZ4DwjYWBAiSwDV9Hm63JJWcz1Ie3Xjv4KuJXzgCstj48LkLfVCYa7mLcx7y+q6yqVvtw=="
},
"Microsoft.FeatureManagement": {
"type": "Transitive",
"resolved": "2.5.1",
"contentHash": "ERbRjk0etZs4d5Pv17unfogO4iBwV2c/HoBt4jqIJmfbKbmTLV+GbjBPYzidIg2RgYIFi8yA+EoEapSAIOp19g==",
"dependencies": {
"Microsoft.Extensions.Configuration.Binder": "2.1.10",
"Microsoft.Extensions.Logging": "2.1.1"
}
},
"Microsoft.Graph": {
"type": "Transitive",
"resolved": "4.37.0",
@ -2238,6 +2307,11 @@
"System.Runtime": "4.3.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "Transitive",
"resolved": "4.8.0",
"contentHash": "PSIdcgbyNv7FZvZ1I9Mqy6XZOwstYYMdZiXuHvIyc0gDyPjEhrrP9OvTGDHp+LAHp1RNSLjPYssyqox9+Kt9Ug=="
},
"System.Threading.Tasks.Extensions": {
"type": "Transitive",
"resolved": "4.5.4",
@ -2419,6 +2493,7 @@
"Azure.Storage.Blobs": "[12.13.0, )",
"Azure.Storage.Queues": "[12.11.0, )",
"Faithlife.Utility": "[0.12.2, )",
"Microsoft.Azure.Functions.Extensions": "[1.1.0, )",
"Microsoft.Azure.Functions.Worker": "[1.10.0, )",
"Microsoft.Azure.Functions.Worker.ApplicationInsights": "[1.0.0-preview3, )",
"Microsoft.Azure.Functions.Worker.Extensions.EventGrid": "[2.1.0, )",
@ -2429,6 +2504,8 @@
"Microsoft.Azure.Functions.Worker.Sdk": "[1.7.0, )",
"Microsoft.Azure.Management.Monitor": "[0.28.0-preview, )",
"Microsoft.Azure.Management.OperationalInsights": "[0.24.0-preview, )",
"Microsoft.Extensions.Configuration.AzureAppConfiguration": "[5.1.0, )",
"Microsoft.FeatureManagement": "[2.5.1, )",
"Microsoft.Graph": "[4.37.0, )",
"Microsoft.Identity.Client": "[4.46.2, )",
"Microsoft.Identity.Web.TokenCache": "[1.23.1, )",

View File

@ -87,6 +87,16 @@
"System.Threading.Tasks.Extensions": "4.5.4"
}
},
"Azure.Data.AppConfiguration": {
"type": "Transitive",
"resolved": "1.2.0",
"contentHash": "KA1dAM9TuDsq0CRFd+3cJTYUAzA2z9N8t9/xKdDbP9URuReq/NDFcKYr7GW2W9xzVGDtCHlD5j5am/+zLLBdSg==",
"dependencies": {
"Azure.Core": "1.20.0",
"Microsoft.Bcl.AsyncInterfaces": "1.0.0",
"System.Text.Json": "4.6.0"
}
},
"Azure.Data.Tables": {
"type": "Transitive",
"resolved": "12.5.0",
@ -414,6 +424,15 @@
"resolved": "5.0.8",
"contentHash": "ZI9S2NGjuOKXN3PxJcF8EKVwd1cqpWyUSqiVoH8gqq5tlHaXULwPmoR0DBOFON4sEFETRWI69f5RQ3tJWw205A=="
},
"Microsoft.Azure.Functions.Extensions": {
"type": "Transitive",
"resolved": "1.1.0",
"contentHash": "zYKtQQoS1fdzufxFApuMFiFtoi9QAGH6McXxntpylwLKgKjmCMWdgUd1dcekzTKNR9DPSDPRLiulvukqXnpWrQ==",
"dependencies": {
"Microsoft.Azure.WebJobs": "3.0.18",
"Microsoft.Extensions.DependencyInjection": "2.1.0"
}
},
"Microsoft.Azure.Functions.Worker": {
"type": "Transitive",
"resolved": "1.10.0",
@ -568,6 +587,33 @@
"System.Net.Http": "4.3.0"
}
},
"Microsoft.Azure.WebJobs": {
"type": "Transitive",
"resolved": "3.0.18",
"contentHash": "aYJ76yjPkIpsafqFp1Xz1sA06RvhUwqJnk4AqX4I0teuRjPyig9Sv7LTzxUMAppKXc4JyR/Asos2At/LMiblqg==",
"dependencies": {
"Microsoft.Azure.WebJobs.Core": "3.0.18",
"Microsoft.Extensions.Configuration": "2.1.0",
"Microsoft.Extensions.Configuration.Abstractions": "2.1.0",
"Microsoft.Extensions.Configuration.EnvironmentVariables": "2.1.0",
"Microsoft.Extensions.Configuration.Json": "2.1.0",
"Microsoft.Extensions.Hosting": "2.1.0",
"Microsoft.Extensions.Logging": "2.1.0",
"Microsoft.Extensions.Logging.Abstractions": "2.1.0",
"Microsoft.Extensions.Logging.Configuration": "2.1.0",
"Newtonsoft.Json": "11.0.2",
"System.Threading.Tasks.Dataflow": "4.8.0"
}
},
"Microsoft.Azure.WebJobs.Core": {
"type": "Transitive",
"resolved": "3.0.18",
"contentHash": "ajYI8pPzPn4qq7FL8C2tz9WmFEG5PorUlkw8W9CF5M+5egnFJaF7yH48WYC+zBoQIzv2vHmFq0zhQpnv+O8v5Q==",
"dependencies": {
"System.ComponentModel.Annotations": "4.4.0",
"System.Diagnostics.TraceSource": "4.3.0"
}
},
"Microsoft.Bcl.AsyncInterfaces": {
"type": "Transitive",
"resolved": "6.0.0",
@ -647,6 +693,20 @@
"Microsoft.Extensions.Primitives": "5.0.0"
}
},
"Microsoft.Extensions.Configuration.AzureAppConfiguration": {
"type": "Transitive",
"resolved": "5.1.0",
"contentHash": "FoAfgvT/rjL/+c7BP7q0LrJIdc4Hu6SH56BTIUbwCwVjHoUw4dpgGtLQULi5GmMjdbdAxyLQSnbwpOEWuBy+RA==",
"dependencies": {
"Azure.Data.AppConfiguration": "1.2.0",
"Azure.Messaging.EventGrid": "4.7.0",
"Azure.Security.KeyVault.Secrets": "4.0.1",
"Microsoft.Extensions.Configuration": "3.1.18",
"Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.18",
"Microsoft.Extensions.Logging": "3.1.18",
"System.Text.Json": "4.6.0"
}
},
"Microsoft.Extensions.Configuration.Binder": {
"type": "Transitive",
"resolved": "5.0.0",
@ -905,6 +965,15 @@
"resolved": "5.0.1",
"contentHash": "5WPSmL4YeP7eW+Vc8XZ4DwjYWBAiSwDV9Hm63JJWcz1Ie3Xjv4KuJXzgCstj48LkLfVCYa7mLcx7y+q6yqVvtw=="
},
"Microsoft.FeatureManagement": {
"type": "Transitive",
"resolved": "2.5.1",
"contentHash": "ERbRjk0etZs4d5Pv17unfogO4iBwV2c/HoBt4jqIJmfbKbmTLV+GbjBPYzidIg2RgYIFi8yA+EoEapSAIOp19g==",
"dependencies": {
"Microsoft.Extensions.Configuration.Binder": "2.1.10",
"Microsoft.Extensions.Logging": "2.1.1"
}
},
"Microsoft.Graph": {
"type": "Transitive",
"resolved": "4.37.0",
@ -2333,6 +2402,11 @@
"System.Runtime": "4.3.0"
}
},
"System.Threading.Tasks.Dataflow": {
"type": "Transitive",
"resolved": "4.8.0",
"contentHash": "PSIdcgbyNv7FZvZ1I9Mqy6XZOwstYYMdZiXuHvIyc0gDyPjEhrrP9OvTGDHp+LAHp1RNSLjPYssyqox9+Kt9Ug=="
},
"System.Threading.Tasks.Extensions": {
"type": "Transitive",
"resolved": "4.5.4",
@ -2546,6 +2620,7 @@
"Azure.Storage.Blobs": "[12.13.0, )",
"Azure.Storage.Queues": "[12.11.0, )",
"Faithlife.Utility": "[0.12.2, )",
"Microsoft.Azure.Functions.Extensions": "[1.1.0, )",
"Microsoft.Azure.Functions.Worker": "[1.10.0, )",
"Microsoft.Azure.Functions.Worker.ApplicationInsights": "[1.0.0-preview3, )",
"Microsoft.Azure.Functions.Worker.Extensions.EventGrid": "[2.1.0, )",
@ -2556,6 +2631,8 @@
"Microsoft.Azure.Functions.Worker.Sdk": "[1.7.0, )",
"Microsoft.Azure.Management.Monitor": "[0.28.0-preview, )",
"Microsoft.Azure.Management.OperationalInsights": "[0.24.0-preview, )",
"Microsoft.Extensions.Configuration.AzureAppConfiguration": "[5.1.0, )",
"Microsoft.FeatureManagement": "[2.5.1, )",
"Microsoft.Graph": "[4.37.0, )",
"Microsoft.Identity.Client": "[4.46.2, )",
"Microsoft.Identity.Web.TokenCache": "[1.23.1, )",

View File

@ -40,23 +40,27 @@ var roleAssignmentsParams = [
}
{
suffix: '-storage'
role:'17d1049b-9a84-46fb-8f53-869881c3d3ab' //StorageAccountContributor
role: '17d1049b-9a84-46fb-8f53-869881c3d3ab' //StorageAccountContributor
}
{
suffix: '-network'
role: '4d97b98b-1d4f-4787-a291-c67834d212e7'//NetworkContributor
role: '4d97b98b-1d4f-4787-a291-c67834d212e7' //NetworkContributor
}
{
suffix: '-logs'
role: '92aaf0da-9dab-42b6-94a3-d43ce8d16293'//LogAnalyticsContributor
role: '92aaf0da-9dab-42b6-94a3-d43ce8d16293' //LogAnalyticsContributor
}
{
suffix: '-user_managed_identity'
role: 'f1a07417-d97a-45cb-824c-7a7467783830'//ManagedIdentityOperator
role: 'f1a07417-d97a-45cb-824c-7a7467783830' //ManagedIdentityOperator
}
{
suffix: '-contributor'
role: 'b24988ac-6180-42a0-ab88-20f7382dd24c'//Contributor
role: 'b24988ac-6180-42a0-ab88-20f7382dd24c' //Contributor
}
{
suffix: '-app_config_reader'
role: '516239f1-63e1-4d78-a4de-a74fb236a071' //App Configuration Data Reader
}
]
resource scalesetIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = {
@ -162,7 +166,7 @@ module autoscaleSettings 'bicep-templates/autoscale-settings.bicep' = {
module eventGrid 'bicep-templates/event-grid.bicep' = {
name: 'event-grid'
params:{
params: {
location: location
storageFuzzId: storage.outputs.FuzzId
storageFuncId: storage.outputs.FuncId
@ -184,6 +188,7 @@ resource roleAssignments 'Microsoft.Authorization/roleAssignments@2020-10-01-pre
eventGrid
keyVault
serverFarm
featureFlags
]
}]
@ -198,10 +203,10 @@ resource roleAssignmentsNet 'Microsoft.Authorization/roleAssignments@2020-10-01-
eventGrid
keyVault
serverFarm
featureFlags
]
}]
// try to make role assignments to deploy as late as possible in order to have principalId ready
resource readBlobUserAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = {
name: guid('${resourceGroup().id}-user_managed_idenity_read_blob')
@ -213,9 +218,16 @@ resource readBlobUserAssignment 'Microsoft.Authorization/roleAssignments@2020-10
eventGrid
keyVault
serverFarm
]
featureFlags
]
}
module featureFlags 'bicep-templates/feature-flags.bicep' = {
name: 'featureFlags'
params: {
location: location
}
}
module function 'bicep-templates/function.bicep' = {
name: 'function'
@ -278,45 +290,46 @@ module functionSettings 'bicep-templates/function-settings.bicep' = {
monitor_account_name: operationalInsights.outputs.monitorAccountName
multi_tenant_domain: multi_tenant_domain
enable_profiler: enable_profiler
app_config_endpoint: featureFlags.outputs.AppConfigEndpoint
functions_disabled: '0'
agent_function_names: [
'AgentCanSchedule' //0
'AgentCommands' //1
'AgentEvents' //2
'AgentRegistration' //3
'Containers' //4
'Download' //5
'Info' //6
'InstanceConfig' //7
'Jobs' //8
'JobTemplates' //9
'JobTemplatesManage' //10
'Negotiate' //11
'Node' //12
'NodeAddSshKey' //13
'Notifications' //14
'Pool' //15
'Proxy' //16
'QueueFileChanges' //17
'QueueNodeHeartbeat' //18
'QueueProxyUpdate' //19
'QueueSignalrEvents' //20
'QueueTaskHeartbeat' //21
'QueueUpdates' //22
'QueueWebhooks' //23
'ReproVms' //24
'Scaleset' //25
'Tasks' //26
'TimerDaily' //27
'TimerProxy' //28
'TimerRepro' //29
'TimerRetention' //30
'TimerTasks' //31
'TimerWorkers' //32
'Tools' //33
'Webhooks' //34
'WebhooksLogs' //35
'WebhooksPing' //36
'AgentCanSchedule' //0
'AgentCommands' //1
'AgentEvents' //2
'AgentRegistration' //3
'Containers' //4
'Download' //5
'Info' //6
'InstanceConfig' //7
'Jobs' //8
'JobTemplates' //9
'JobTemplatesManage' //10
'Negotiate' //11
'Node' //12
'NodeAddSshKey' //13
'Notifications' //14
'Pool' //15
'Proxy' //16
'QueueFileChanges' //17
'QueueNodeHeartbeat' //18
'QueueProxyUpdate' //19
'QueueSignalrEvents' //20
'QueueTaskHeartbeat' //21
'QueueUpdates' //22
'QueueWebhooks' //23
'ReproVms' //24
'Scaleset' //25
'Tasks' //26
'TimerDaily' //27
'TimerProxy' //28
'TimerRepro' //29
'TimerRetention' //30
'TimerTasks' //31
'TimerWorkers' //32
'Tools' //33
'Webhooks' //34
'WebhooksLogs' //35
'WebhooksPing' //36
]
}
dependsOn: [
@ -324,7 +337,6 @@ module functionSettings 'bicep-templates/function-settings.bicep' = {
]
}
module netFunctionSettings 'bicep-templates/function-settings.bicep' = {
name: 'netFunctionSettings'
params: {
@ -344,45 +356,46 @@ module netFunctionSettings 'bicep-templates/function-settings.bicep' = {
monitor_account_name: operationalInsights.outputs.monitorAccountName
multi_tenant_domain: multi_tenant_domain
enable_profiler: enable_profiler
app_config_endpoint: featureFlags.outputs.AppConfigEndpoint
functions_disabled: '1'
agent_function_names: [
'AgentCanSchedule' //0
'AgentCommands' //1
'AgentEvents' //2
'AgentRegistration' //3
'Containers' //4
'Download' //5
'Info' //6
'InstanceConfig' //7
'Jobs' //8
'JobTemplates' //9
'JobTemplatesManage' //10
'Negotiate' //11
'Node' //12
'NodeAddSshKey' //13
'Notifications' //14
'Pool' //15
'Proxy' //16
'QueueFileChanges' //17
'QueueNodeHeartbeat' //18
'QueueProxyUpdate' //19
'QueueSignalrEvents' //20
'QueueTaskHeartbeat' //21
'QueueUpdates' //22
'QueueWebhooks' //23
'ReproVms' //24
'Scaleset' //25
'Tasks' //26
'TimerDaily' //27
'TimerProxy' //28
'TimerRepro' //29
'TimerRetention' //30
'TimerTasks' //31
'TimerWorkers' //32
'Tools' //33
'Webhooks' //34
'WebhookLogs' //35
'WebhookPing' //36
'AgentCanSchedule' //0
'AgentCommands' //1
'AgentEvents' //2
'AgentRegistration' //3
'Containers' //4
'Download' //5
'Info' //6
'InstanceConfig' //7
'Jobs' //8
'JobTemplates' //9
'JobTemplatesManage' //10
'Negotiate' //11
'Node' //12
'NodeAddSshKey' //13
'Notifications' //14
'Pool' //15
'Proxy' //16
'QueueFileChanges' //17
'QueueNodeHeartbeat' //18
'QueueProxyUpdate' //19
'QueueSignalrEvents' //20
'QueueTaskHeartbeat' //21
'QueueUpdates' //22
'QueueWebhooks' //23
'ReproVms' //24
'Scaleset' //25
'Tasks' //26
'TimerDaily' //27
'TimerProxy' //28
'TimerRepro' //29
'TimerRetention' //30
'TimerTasks' //31
'TimerWorkers' //32
'Tools' //33
'Webhooks' //34
'WebhookLogs' //35
'WebhookPing' //36
]
}
dependsOn: [

View File

@ -0,0 +1,14 @@
param location string
var suffix = uniqueString(resourceGroup().id)
var appConfigName = 'app-config-${suffix}'
resource featureFlags 'Microsoft.AppConfiguration/configurationStores@2022-05-01' = {
name: appConfigName
location: location
sku:{
name: 'standard'
}
}
output AppConfigEndpoint string = 'https://${appConfigName}.azconfig.io'

View File

@ -13,6 +13,8 @@ param multi_tenant_domain string
@secure()
param signal_r_connection_string string
param app_config_endpoint string
param func_storage_resource_id string
param fuzz_storage_resource_id string
@ -67,6 +69,7 @@ resource functionSettings 'Microsoft.Web/sites/config@2021-03-01' = {
AzureWebJobsDisableHomepage: 'true'
AzureSignalRConnectionString: signal_r_connection_string
AzureSignalRServiceTransportType: 'Transient'
APPCONFIGURATION_ENDPOINT: app_config_endpoint
ONEFUZZ_INSTANCE_NAME: instance_name
ONEFUZZ_INSTANCE: 'https://${instance_name}.azurewebsites.net'
ONEFUZZ_RESOURCE_GROUP: resourceGroup().id