-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Ayrat Hudaygulov
committed
Dec 15, 2020
1 parent
1181a46
commit d0ee704
Showing
5 changed files
with
369 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
name: Deploy everything to Azure | ||
|
||
on: workflow_dispatch | ||
|
||
jobs: | ||
build: | ||
|
||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
|
||
- name: Deploy everything to Azure | ||
run: | | ||
cd src/Grinder.Farmer | ||
dotnet run --all |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
{ | ||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", | ||
"contentVersion": "1.0.0.0", | ||
"outputs": {}, | ||
"parameters": { | ||
"docker-password-for-vahterregistry": { | ||
"type": "securestring" | ||
} | ||
}, | ||
"resources": [ | ||
{ | ||
"apiVersion": "2020-03-01-preview", | ||
"location": "northeurope", | ||
"name": "vahter-log", | ||
"properties": { | ||
"publicNetworkAccessForIngestion": "Enabled", | ||
"publicNetworkAccessForQuery": "Enabled", | ||
"retentionInDays": 30, | ||
"sku": { | ||
"name": "PerGB2018" | ||
} | ||
}, | ||
"tags": {}, | ||
"type": "Microsoft.OperationalInsights/workspaces" | ||
}, | ||
{ | ||
"apiVersion": "2016-08-01", | ||
"dependsOn": [ | ||
"vahter-app-farm", | ||
"vahter-log" | ||
], | ||
"identity": { | ||
"type": "None" | ||
}, | ||
"kind": "app,linux,container", | ||
"location": "northeurope", | ||
"name": "vahter-app", | ||
"properties": { | ||
"httpsOnly": false, | ||
"serverFarmId": "vahter-app-farm", | ||
"siteConfig": { | ||
"alwaysOn": true, | ||
"appCommandLine": "", | ||
"appSettings": [ | ||
{ | ||
"name": "DOCKER_ENABLE_CI", | ||
"value": "true" | ||
}, | ||
{ | ||
"name": "DOCKER_REGISTRY_SERVER_PASSWORD", | ||
"value": "[parameters('docker-password-for-vahterregistry')]" | ||
}, | ||
{ | ||
"name": "DOCKER_REGISTRY_SERVER_URL", | ||
"value": "https://vahterregistry.azurecr.io" | ||
}, | ||
{ | ||
"name": "DOCKER_REGISTRY_SERVER_USERNAME", | ||
"value": "vahterregistry" | ||
}, | ||
{ | ||
"name": "VAHTER_CONFIG", | ||
"value": "{\r\n \"Bot\": {\r\n \"Token\": \"800514531:AAH12BMMpXJvuvtdj_6p4UHWszVs6101I5I\",\r\n \"ChannelId\": -1001492656505,\r\n \"AdminUserId\": 67509832,\r\n \"ChatsToMonitor\": [\r\n \"@fsharp_flood\",\r\n \"@dotnetby\",\r\n \"@cilchat\",\r\n \"@comput_math\",\r\n \"@higher_math\",\r\n \"@elasticsearch_ru\",\r\n \"@Avalonia\",\r\n \"@fsharp_jobs\",\r\n \"@pro_latex\",\r\n \"@fsharp_chat\",\r\n \"@pro_net\",\r\n \"@DotNetRuChat\",\r\n \"@dotnettalks\",\r\n \"@DotNetRuJobs\",\r\n \"@DotNetChat\",\r\n \"@powershell_pro\"\r\n ],\r\n \"AllowedUsers\": [\r\n \"Liminiens\",\r\n \"fvnever\",\r\n \"aensidhe\",\r\n \"etkee\",\r\n \"EgorBo\",\r\n \"neftedollar\",\r\n \"zawodskoj\",\r\n \"kekekeks\",\r\n \"ahydrax\",\r\n \"hacklex\",\r\n \"striped\",\r\n \"XaveScor\",\r\n \"omgszer\",\r\n \"grishace\",\r\n \"AnutaU\"\r\n ]\r\n }\r\n}" | ||
} | ||
], | ||
"connectionStrings": [], | ||
"linuxFxVersion": "DOCKER|vahterregistry.azurecr.io/vahter/grinder:latest", | ||
"metadata": [] | ||
} | ||
}, | ||
"tags": {}, | ||
"type": "Microsoft.Web/sites" | ||
}, | ||
{ | ||
"apiVersion": "2018-02-01", | ||
"kind": "linux", | ||
"location": "northeurope", | ||
"name": "vahter-app-farm", | ||
"properties": { | ||
"name": "vahter-app-farm", | ||
"perSiteScaling": false, | ||
"reserved": true | ||
}, | ||
"sku": { | ||
"capacity": 1, | ||
"name": "B1", | ||
"size": "0", | ||
"tier": "Basic" | ||
}, | ||
"tags": {}, | ||
"type": "Microsoft.Web/serverfarms" | ||
}, | ||
{ | ||
"type": "Microsoft.Web/sites/providers/diagnosticSettings", | ||
"apiVersion": "2017-05-01-preview", | ||
"name": "[concat('vahter-app', '/microsoft.insights/', 'vahter-log')]", | ||
"dependsOn": [], | ||
"properties": { | ||
"workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', 'vahter-log')]", | ||
"metrics": [], | ||
"logs": [ | ||
{ | ||
"category": "AppServiceConsoleLogs", | ||
"enabled": true | ||
}, | ||
{ | ||
"category": "AppServiceAppLogs", | ||
"enabled": true | ||
}, | ||
{ | ||
"category": "AppServiceHTTPLogs", | ||
"enabled": true | ||
} | ||
] | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net5.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<Compile Include="Program.fs" /> | ||
<Content Include="settings.json"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</Content> | ||
<Content Include="README.MD" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="FSharp.Core" Version="5.0.0" /> | ||
<PackageReference Include="Farmer" Version="1.2.0" /> | ||
<PackageReference Include="MedallionShell" Version="1.6.2" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
open System | ||
open System.IO | ||
open Farmer | ||
open Farmer.Builders | ||
open Medallion.Shell | ||
|
||
let resourceGroup = "vahter-rg" | ||
let acrName = "vahterregistry" | ||
let logName = "vahter-log" | ||
let appName = "vahter-app" | ||
|
||
let getEnv name = | ||
match Environment.GetEnvironmentVariable name with | ||
| null -> | ||
failwith $"Provide required ENV variable: {name}" | ||
// Console.WriteLine $"Please provide ENV variable: {name}" | ||
// Console.ReadLine() | ||
| value -> value | ||
|
||
let appId = getEnv "VAHTER_DEPLOY_APPID" | ||
let pwd = getEnv "VAHTER_DEPLOY_PWD" | ||
let tenant = getEnv "VAHTER_DEPLOY_TENANT" | ||
|
||
type Result.ResultBuilder with | ||
member _.Bind(cmd: Command, next: unit -> Result<'a, string>): Result<'a, string> = | ||
cmd.StandardOutput.PipeToAsync(Console.Out, true) |> ignore | ||
cmd.StandardError.PipeToAsync(Console.Error, true) |> ignore | ||
if cmd.Result.Success then | ||
next() | ||
else | ||
Error cmd.Result.StandardError | ||
|
||
let botSettings = | ||
let vahterConfig = Environment.GetEnvironmentVariable "VAHTER_CONFIG" | ||
if File.Exists "./settings.json" then | ||
File.ReadAllText "settings.json" | ||
else if vahterConfig <> null then | ||
vahterConfig | ||
else | ||
failwith "Please put bot settings either 1) in settings.json 2) or in env VAHTER_CONFIG" | ||
|
||
let logs = logAnalytics { | ||
name logName | ||
|
||
retention_period 30<Days> | ||
enable_query | ||
enable_ingestion | ||
} | ||
|
||
let registry = containerRegistry { | ||
name acrName | ||
|
||
sku ContainerRegistry.Basic | ||
enable_admin_user | ||
} | ||
|
||
let botApp = webApp { | ||
name appName | ||
|
||
app_insights_off | ||
always_on | ||
operating_system Linux | ||
sku WebApp.Sku.B1 | ||
|
||
setting "VAHTER_CONFIG" botSettings | ||
|
||
docker_ci | ||
docker_use_azure_registry acrName | ||
docker_image "vahter/grinder:latest" "" | ||
|
||
depends_on logs.Name | ||
} | ||
|
||
let registryDeployment = arm { | ||
location Location.NorthEurope | ||
add_resource registry | ||
output "host" registry.LoginServer | ||
output "pwd" $"[listCredentials(resourceId('Microsoft.ContainerRegistry/registries','{acrName}'),'2017-10-01').passwords[0].value]" | ||
output "login" $"['{acrName}']" | ||
} | ||
|
||
let appDeployment = arm { | ||
location Location.NorthEurope | ||
add_resources [ | ||
logs | ||
botApp | ||
] | ||
add_resource (Resource.ofJson $""" | ||
{{ | ||
"type": "Microsoft.Web/sites/providers/diagnosticSettings", | ||
"apiVersion": "2017-05-01-preview", | ||
"name": "[concat('{appName}', '/microsoft.insights/', '{logName}')]", | ||
"dependsOn": [], | ||
"properties": {{ | ||
"workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', '{logName}')]", | ||
"metrics": [], | ||
"logs": [ | ||
{{ | ||
"category": "AppServiceConsoleLogs", | ||
"enabled": true | ||
}}, | ||
{{ | ||
"category": "AppServiceAppLogs", | ||
"enabled": true | ||
}}, | ||
{{ | ||
"category": "AppServiceHTTPLogs", | ||
"enabled": true | ||
}} | ||
] | ||
}} | ||
}} | ||
""") | ||
} | ||
|
||
let getAcrCreds() = result { | ||
let azShell = Shell(fun opts -> | ||
opts.ThrowOnError(false) | ||
|> ignore | ||
) | ||
do! azShell.Run("az", "login", "--service-principal", "-u", appId, "-p", pwd, "--tenant", tenant) | ||
let pwd = azShell.Run("az", "acr", "credential", "show", "--name", acrName, "--query", "passwords[0].value") | ||
let pwdStringRaw = pwd.Result.StandardOutput | ||
let pwdString = pwdStringRaw.Substring(1, pwdStringRaw.Length - 3) // truncating first and last chars | ||
return $"{acrName}.azurecr.io", acrName, pwdString | ||
} | ||
|
||
let pushDockerImage (host, user, pwd) = result { | ||
let dockerShell = Shell(fun opts -> | ||
opts.ThrowOnError(false) | ||
.WorkingDirectory("../..") | ||
|> ignore | ||
) | ||
|
||
do! dockerShell.Run("docker", "login", "-u", user, "-p", pwd, host) | ||
do! dockerShell.Run("docker", "build", ".", "-t", "grinder") | ||
do! dockerShell.Run("docker", "tag", "grinder", $"{host}/vahter/grinder") | ||
do! dockerShell.Run("docker", "push", $"{host}/vahter/grinder") | ||
return () | ||
} | ||
|
||
let deployAll() = result { | ||
// authenticate into Azure | ||
let! authResult = Deploy.authenticate appId pwd tenant | ||
printfn "%A" authResult | ||
|
||
// deploying container registry | ||
let! registryDeploymentResult = | ||
Deploy.tryExecute | ||
resourceGroup | ||
Deploy.NoParameters | ||
registryDeployment | ||
|
||
let registryPwd = registryDeploymentResult.["pwd"] | ||
let registryLogin = registryDeploymentResult.["login"] | ||
let registryHost = registryDeploymentResult.["host"] | ||
|
||
// build&push image to registry | ||
do! pushDockerImage(registryHost, registryLogin, registryPwd) | ||
|
||
// deploy webapp with bot | ||
let! deploymentResult = | ||
Deploy.tryExecute | ||
resourceGroup | ||
[ botApp.DockerAcrCredentials.Value.Password.Value, registryPwd ] | ||
appDeployment | ||
return printfn "%A" deploymentResult | ||
} | ||
|
||
[<EntryPoint>] | ||
let main argv = | ||
match argv with | ||
| null | [||] -> | ||
// deploy only image | ||
result { | ||
let! host, usr, pwd = getAcrCreds() | ||
do! pushDockerImage(host, usr, pwd) | ||
} | ||
| x when Array.contains "--all" x -> | ||
// deploy everything = resources + image | ||
deployAll() | ||
| x -> | ||
failwithf "Unknown arguments %A" x | ||
|> Result.get | ||
0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#Description | ||
This project will deploy Grinder bot to Azure | ||
There are two scenarios | ||
- Deploy Azure resources together with docker image | ||
- Build and push docker image only into predeployed container registry | ||
|
||
To deploy everything pass `--all` argument | ||
|
||
To deploy just an image don't pass any argument | ||
|
||
#Prerequisites | ||
- AZ CLI | ||
- Docker | ||
- Net5 SDK | ||
|
||
- Azure credentials (put them in env variables) | ||
- `VAHTER_DEPLOY_APPID` | ||
- `VAHTER_DEPLOY_PWD` | ||
- `VAHTER_DEPLOY_TENANT` | ||
|
||
- Bot settings (pick one) | ||
- `settings.json` file | ||
- `VAHTER_CONFIG` variable | ||
|
||
#Run | ||
`dotnet run [args]` (from project folder) | ||
|
||
or just run from IDE |