Skip to content

Commit

Permalink
Changed cosmosDb connection string
Browse files Browse the repository at this point in the history
added resource templates
  • Loading branch information
splotnikov-sketch committed Apr 5, 2021
1 parent d2a7afc commit 0150c3c
Show file tree
Hide file tree
Showing 13 changed files with 323 additions and 51 deletions.
91 changes: 91 additions & 0 deletions Infrastructure/az-resourse-management.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#az login

$resourceGroupName = "FuncsResourceGroup"
$location = "eastus"
$storageAccountName = "funcsstorageaccount"
$azureFunctionsPremiumPlanName = "FuncsPremiumPlan"
$appName = "SimpleFuncs"
#$appInsightsName = $appName + "Insight";

az group create `
-l $location `
-n $resourceGroupName

az storage account create `
-g $resourceGroupName `
-n $storageAccountName `
-l $location `
--sku Standard_LRS

az functionapp plan create `
--resource-group $resourceGroupName `
--name $azureFunctionsPremiumPlanName `
--location $location `
--number-of-workers 1 `
--sku EP1 `
--is-linux

az functionapp create --name $appName `
--storage-account $storageAccountName `
--resource-group $resourceGroupName `
--plan $azureFunctionsPremiumPlanName `
--runtime dotnet `
--functions-version 3

az functionapp deployment slot create `
--resource-group $resourceGroupName `
--name $appName `
-slot staging

az cosmosdb create `
--name $storageAccountName `
--resource $resourceGroupName `
--default-consistency-level Eventual `
--locations regionName=$location failoverPriority=0 isZoneRedundant=False


$appInsightsInstrumentationKey="$(az resource show -g $resourceGroupName -n $appName --resource-type 'Microsoft.Insights/components' --query properties.InstrumentationKey)"
# this instrumentation key comes with quotes, which we need to remove
$appInsightsInstrumentationKey = $appInsightsInstrumentationKey -replace '"', ""

#storage connection string
$storageConnectionString = "$(az storage account show-connection-string `
--resource-group $($resourceGroupName) `
--name $($storageAccountName) `
--query connectionString `
--output tsv)"

$cosmosConnectionString = "$(az cosmosdb keys list `
--type connection-strings `
--name $storageAccountName `
--resource-group $resourceGroupName `
--query connectionStrings[0].connectionString)"


$settings = @(
"APPINSIGHTS_INSTRUMENTATIONKEY=$appInsightsInstrumentationKey",
"AzureWebJobsStorage=$storageConnectionString",
"WEBSITE_RUN_FROM_PACKAGE=1",
"Cosmos:ConnectionString=$cosmosConnectionString",
"Cosmos:DatabaseId=FunctionsData",
"Cosmos:ContainerId=Primes"
)

az webapp config appsettings set `
--resource-group $resourceGroupName `
--name $appName `
--settings $settings `

//----------

// CI-CD

az functionapp deployment container config --enable-cd --query CI_CD_URL `
--output tsv `
--name $appName `
--resource-group $resourceGroupName

az functionapp deployment container show-cd-url --name $appName `
--resource-group $resourceGroupName

func azure functionapp fetch-app-settings $appName
16 changes: 11 additions & 5 deletions src/AzureFunctions/AzureFunctions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,22 @@
<UserSecretsId>248c2688-a5ac-4c7c-862a-1459e865012e</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<None Remove="appsettings.json" />
</ItemGroup>
<ItemGroup>
<Content Include="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.17.0" />
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.17.1" />
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.OpenApi" Version="0.5.1-preview" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="3.1.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.DurableTask" Version="2.4.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="3.1.13" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.11" />
</ItemGroup>
<ItemGroup>
<None Update="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
16 changes: 8 additions & 8 deletions src/AzureFunctions/Commands/Cosmos/BaseCosmosCommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

namespace AzureFunctions.Commands.Cosmos
{
public abstract class BaseCosmosCommandHandler<TCommand, TResult>: ICommandHandler<TCommand, TResult>
where TCommand: ICommand<TResult>
public abstract class BaseCosmosCommandHandler<TCommand, TResult> : ICommandHandler<TCommand, TResult>
where TCommand : ICommand<TResult>
{
public readonly CosmosOptions CosmosOptions;
public CosmosClient CosmosClient { private set; get; }
Expand All @@ -18,12 +18,12 @@ public abstract class BaseCosmosCommandHandler<TCommand, TResult>: ICommandHandl
protected BaseCosmosCommandHandler(IOptions<CosmosOptions> cosmosOptions)
{
CosmosOptions = cosmosOptions.Value;
CosmosClient =
new CosmosClient(CosmosOptions.EndpointUri, CosmosOptions.PrimaryKey,
new CosmosClientOptions
{
ApplicationName = Global.ApplicationName
});
CosmosClient = !string.IsNullOrWhiteSpace(CosmosOptions.ConnectionString)
? new CosmosClient(CosmosOptions.ConnectionString, new CosmosClientOptions
{
ApplicationName = Global.ApplicationName
})
: null;
}

public abstract Task<TResult> Execute(TCommand command);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ public override async Task<bool> Execute(InitCosmosCommand command)
{
try
{
if (CosmosClient == null)
{
return false;
}

Database database = await CosmosClient.CreateDatabaseIfNotExistsAsync(CosmosOptions.DatabaseId, 400);

Container container =
Expand Down
3 changes: 1 addition & 2 deletions src/AzureFunctions/Configuration/Options/CosmosOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
{
public class CosmosOptions
{
public string EndpointUri { get; set; }
public string PrimaryKey { get; set; }
public string ConnectionString { get; set; }
public string DatabaseId { get; set; }
public string ContainerId { get; set; }
}
Expand Down
8 changes: 0 additions & 8 deletions src/AzureFunctions/Functions/ActionFunctions.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
using System.IO;
using System.Net;
using System.Threading.Tasks;
using AzureFunctions.Commands.IsItPrime;
using AzureFunctions.Infrastructure.Commands;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;

namespace AzureFunctions.Functions
Expand All @@ -26,10 +22,6 @@ public ActionFunctions(ICommandHandler<IsItPrimeCommand, PrimeResult> isItPrime)


[FunctionName(nameof(IsItPrime))]
[OpenApiOperation(operationId: nameof(IsItPrime), tags: new[] { "math" })]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
[OpenApiParameter(name: "number", In = ParameterLocation.Query, Required = true, Type = typeof(long), Description = "The **Number** parameter")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(long), Description = "The OK response")]
public async Task<IActionResult> IsItPrime([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "math/prime")] HttpRequest req,
ILogger log)
{
Expand Down
36 changes: 22 additions & 14 deletions src/AzureFunctions/Functions/TestFunctions.cs
Original file line number Diff line number Diff line change
@@ -1,34 +1,30 @@
using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using AzureFunctions.Configuration.Options;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;

namespace AzureFunctions.Functions
{
public class TestFunctions
{
private readonly ConfigurationItems _configurationItems;
private readonly CosmosOptions _cosmos;

public TestFunctions(IOptions<ConfigurationItems> configurationItems)
public TestFunctions(IOptions<ConfigurationItems> configurationItems,
IOptions<CosmosOptions> cosmos)
{
_cosmos = cosmos.Value;
_configurationItems = configurationItems.Value;
}

[FunctionName(nameof(Configuration))]
[OpenApiOperation(operationId: nameof(Configuration), tags: new[] { "example" })]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "text/plain", bodyType: typeof(string), Description = "The OK response")]
public async Task<IActionResult> Configuration([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "example/config")] HttpRequest req,
ILogger log)
{
Expand All @@ -38,17 +34,29 @@ public async Task<IActionResult> Configuration([HttpTrigger(AuthorizationLevel.A
var commonValue = _configurationItems.CommonValue;
var secretValue = _configurationItems.SecretValue;

var result = new
{
ConfigurationItems = new
{
LocalSettingValue = localSettings,
CommonValue = commonValue,
SecretValue = secretValue
},

Cosmos = new
{
ConnectionString = _cosmos.ConnectionString,
DatabaseId = _cosmos.DatabaseId,
ContainerId = _cosmos.ContainerId
}
};

return
new OkObjectResult($"Local Value : '{localSettings}' | Global Value : '{commonValue}' | Secret Value : '{secretValue}'");
new OkObjectResult(result);
}


[FunctionName(nameof(SayHello))]
[OpenApiOperation(operationId: nameof(SayHello), tags: new[] { "example" })]
[OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
[OpenApiParameter(name: "name", In = ParameterLocation.Query, Required = true, Type = typeof(string), Description = "The **Name** parameter")]
[OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "text/plain", bodyType: typeof(string), Description = "The OK response")]

public async Task<IActionResult> SayHello([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "example/hello")] HttpRequest req,
ILogger log)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>ZipDeploy</WebPublishMethod>
<PublishProvider>AzureWebSite</PublishProvider>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish>http://simplefuncs.azurewebsites.net</SiteUrlToLaunchAfterPublish>
<LaunchSiteAfterPublish>False</LaunchSiteAfterPublish>
<ResourceId>/subscriptions/0edc09bb-e123-4bb8-8f5a-9b382654704a/resourceGroups/FuncsResourceGroup/providers/Microsoft.Web/sites/SimpleFuncs</ResourceId>
<UserName>$SimpleFuncs</UserName>
<_SavePWD>True</_SavePWD>
<PublishUrl>https://simplefuncs.scm.azurewebsites.net/</PublishUrl>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"resourceGroupName": {
"type": "string",
"defaultValue": "FuncsResourceGroup",
"metadata": {
"_parameterType": "resourceGroup",
"description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking."
}
},
"resourceGroupLocation": {
"type": "string",
"defaultValue": "eastus",
"metadata": {
"_parameterType": "location",
"description": "Location of the resource group. Resource groups could have different location than resources."
}
},
"resourceLocation": {
"type": "string",
"defaultValue": "[parameters('resourceGroupLocation')]",
"metadata": {
"_parameterType": "location",
"description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there."
}
}
},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"name": "[parameters('resourceGroupName')]",
"location": "[parameters('resourceGroupLocation')]",
"apiVersion": "2019-10-01"
},
{
"type": "Microsoft.Resources/deployments",
"name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat('SimpleFuncs', subscription().subscriptionId)))]",
"resourceGroup": "[parameters('resourceGroupName')]",
"apiVersion": "2019-10-01",
"dependsOn": [
"[parameters('resourceGroupName')]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"name": "SimpleFuncs",
"type": "microsoft.insights/components",
"location": "[parameters('resourceLocation')]",
"kind": "web",
"properties": {},
"apiVersion": "2015-05-01"
}
]
}
}
}
],
"metadata": {
"_dependencyType": "appInsights.azure"
}
}
Loading

0 comments on commit 0150c3c

Please sign in to comment.