Skip to content

Instantly share code, notes, and snippets.

@ninjarobot
Last active July 27, 2021 03:27
Show Gist options
  • Save ninjarobot/c904b3b626acb22b78c7042d103940e5 to your computer and use it in GitHub Desktop.
Save ninjarobot/c904b3b626acb22b78c7042d103940e5 to your computer and use it in GitHub Desktop.
Deploys an Azure Container Registry, builds Docker image, pushes it there, hosts in ACI
#r "nuget: Farmer"
#r "nuget: FSharp.Text.Docker"
open System
open Farmer
open Farmer.Builders
open FSharp.Text.Docker.Dockerfile
// Create Container Registry
let myAcr =
containerRegistry {
name "farmercontainers"
sku ContainerRegistry.Basic
enable_admin_user
}
// Some quick app we want to run. In the real world, you'll pull this source when building
// the image, but here we will just embed it.
let fsharpAppSource = """
#r "nuget: Suave, Version=2.6.0"
open Suave
let config = { defaultConfig with bindings = [ HttpBinding.createSimple HTTP "0.0.0.0" 8080 ] }
startWebServer config (Successful.OK "Hello Farmers!")
"""
let encodedSource = fsharpAppSource |> System.Text.Encoding.UTF8.GetBytes |> Convert.ToBase64String
// Define Docker image
let dockerfile =
[
From ("mcr.microsoft.com/dotnet/sdk", Some "5.0.301", None)
Expose [8080us]
Run (ShellCommand $"echo {encodedSource} | base64 -d > main.fsx")
Cmd (ShellCommand "dotnet fsi main.fsx")
] |> buildDockerfile
let encodedDockerfile = dockerfile |> System.Text.Encoding.UTF8.GetBytes |> Convert.ToBase64String
let scriptIdentity = createUserAssignedIdentity "deployment-identity"
// Build and push to that ACR from a deploymentScript
let buildImage =
deploymentScript {
name "build-image"
env_vars [ "ACR_NAME", "farmercontainers" ]
identity scriptIdentity
depends_on myAcr
script_content (
[
"set -eux"
$"echo {encodedDockerfile} | base64 -d > Dockerfile"
$"az acr build --registry $ACR_NAME --image fsharpwebapp:1.0.0 ."
] |> String.concat " ; "
)
}
/// Deploy a container group after the image is built. It will reference the container registry to get credentials.
let farmerContainerGroup =
containerGroup {
name "farmercontainers"
public_dns "farmercontainer" [TCP, 8080us]
add_instances [
containerInstance {
name "suave-script"
image "farmercontainers.azurecr.io/fsharpwebapp:1.0.0"
add_public_ports [ 8080us ]
}
]
reference_registry_credentials [
Arm.ContainerRegistry.registries.resourceId "farmercontainers"
]
depends_on buildImage
}
/// Deployment template to orchestrate all of these.
let template =
arm {
location Location.EastUS
add_resources [
scriptIdentity
myAcr
buildImage
farmerContainerGroup
]
}
template.Template |> Writer.toJson |> Console.WriteLine
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment