Skip to content

Commit f754169

Browse files
author
Jean-Marc van Leerdam
committed
Implement commands to create resources and upload zip file
1 parent 8eee8f1 commit f754169

File tree

4 files changed

+157
-45
lines changed

4 files changed

+157
-45
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,16 @@ in your `build.sbt` provide values for the assembly and azure-functions plugins:
5050

5151
This will deploy the function to Azure, using the azure CLI, which is expected to be available on your path
5252
and logged in to the correct Azure Subscription.
53+
You will also have to install the app-insights extension to the CLI, by running `az extension add -n application-insights`
5354

54-
You can provide these settings to determine the destination:
55+
You can provide the following settings to determine the destination:
5556
* `azfunResourceGroup`
57+
* `azfunStorageAccount`
5658

5759

5860
## TODO:
5961
1. add task to upload to Azure
62+
1. add support for App Insights workspaces
6063
1. add tests against multiple Java versions (java 8 and Java 11)
6164

6265

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package nl.codestar.azurefunctions
2+
3+
import sbt.File
4+
import sbt.internal.util.ManagedLogger
5+
6+
class FunctionDeployFailedException(msg: String, cause: Throwable = None.orNull) extends sbt.FeedbackProvidedException
7+
8+
object DeployFunctionHelper {
9+
import scala.language.postfixOps
10+
import scala.sys.process._
11+
12+
def createResourceGroup(rgName: String, location: String, log: ManagedLogger): Unit = {
13+
log.info(s"Checking if group ${rgName} exists...")
14+
15+
val output = (s"az group exists -n ${rgName}" !!)
16+
val groupExists = output.startsWith("true")
17+
if (!groupExists) {
18+
log.info(s"Group ${rgName} does not yet exist, creating it")
19+
val result = (s"az group create -n ${rgName} -l ${location}" !)
20+
if (result != 0) {
21+
log.error("Failed to create resource group")
22+
throw new FunctionDeployFailedException("Failed to create resource group")
23+
} else {
24+
log.info("Resource group created")
25+
}
26+
} else {
27+
log.info(s"Group ${rgName} is present")
28+
}
29+
30+
}
31+
32+
def createStorageAccount(
33+
saName: String,
34+
rgName: String,
35+
location: String,
36+
skuValue: String,
37+
log: ManagedLogger
38+
): Unit = {
39+
log.info(s"Checking if storage account ${saName} exists...")
40+
41+
val output = (s"az storage account check-name -n ${saName} --query nameAvailable" !!)
42+
val saExists = output.startsWith("false")
43+
if (!saExists) {
44+
log.info(s"Storage Account ${saName} does not yet exist, creating it")
45+
46+
val result = (s"az storage account create -n ${saName} -l ${location} -g ${rgName} --sku ${skuValue}" !)
47+
if (result != 0) {
48+
log.error("Failed to create storage account")
49+
throw new FunctionDeployFailedException("Failed to create storage account")
50+
} else {
51+
log.info("Storage account created")
52+
}
53+
} else {
54+
log.info(s"Storage account ${saName} is present")
55+
}
56+
57+
}
58+
59+
def createAppInsightsInstance(
60+
aiName: String,
61+
rgName: String,
62+
location: String,
63+
workspace: Option[String],
64+
log: ManagedLogger
65+
): Unit = {
66+
log.info(s"Checking if app insights ${aiName} exists...")
67+
val output = (s"az monitor app-insights component show --app ${aiName} -g ${rgName}" !)
68+
if (output != 0) {
69+
log.info(s"App Insights ${aiName} does not yet exist, creating it")
70+
71+
val workspacePart = workspace match {
72+
case None => ""
73+
case Some(ws) => s"--workspace $ws"
74+
}
75+
val result = (s"""
76+
|az monitor app-insights component create
77+
| --app $aiName
78+
| --location $location
79+
| --resource-group $rgName
80+
| --application-type web
81+
| $workspacePart
82+
|""".stripMargin !)
83+
if (result != 0) {
84+
log.error("Failed to create App Insights")
85+
throw new FunctionDeployFailedException("Failed to create App Insights")
86+
} else {
87+
log.info("App Insights created")
88+
}
89+
} else {
90+
log.info(s"App Insights $aiName is present")
91+
}
92+
}
93+
94+
def createFunctionApp(
95+
appName: String,
96+
rgName: String,
97+
location: String,
98+
saName: String,
99+
aiName: String,
100+
log: ManagedLogger
101+
): Unit = {
102+
log.info(s"Checking if function app $appName exists...")
103+
val output = (s"az functionapp show -g $rgName --name $appName" !)
104+
if (output != 0) {
105+
log.info(s"Function App $appName does not yet exist, creating it")
106+
val result = (s"""
107+
|az functionapp create
108+
| --name $appName
109+
| --resource-group $rgName
110+
| --storage-account $saName
111+
| --consumption-plan-location $location
112+
| --app-insights $aiName
113+
| --runtime java
114+
|""".stripMargin !)
115+
if (result != 0) {
116+
log.error("Failed to create Function App")
117+
throw new FunctionDeployFailedException("Failed to create Function App")
118+
} else {
119+
log.info("Function App created")
120+
}
121+
} else {
122+
log.info(s"Function App $appName exists")
123+
}
124+
}
125+
126+
def deployZipFile(zipFile: File, appName: String, rgName: String, log: ManagedLogger): Unit = {
127+
val zipLocation = zipFile.getAbsolutePath
128+
log.info(s"Uploading $zipLocation into $appName")
129+
val result = (s"az functionapp deployment source config-zip -g $rgName -n $appName --src $zipLocation" !)
130+
if (result != 0) {
131+
log.error("Failed to upload zip file")
132+
throw new FunctionDeployFailedException("Failed to upload zip file")
133+
} else {
134+
log.info("Upload done")
135+
}
136+
}
137+
}
Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,35 @@
11
package sbtazurefunctions
22

3+
import nl.codestar.azurefunctions.DeployFunctionHelper
34
import sbt.Setting
4-
import sbtazurefunctions.AzureFunctionsKeys.{
5-
azfunCreateZipFile,
6-
azfunDeploy,
7-
azfunLocation,
8-
azfunResourceGroup,
9-
azfunSKU,
10-
azfunStorageAccount
11-
}
5+
import sbtazurefunctions.AzureFunctionsKeys._
126

137
object DeployTask {
148
def settings: Seq[Setting[_]] =
159
Seq(
1610
azfunDeploy := {
1711
// depend on having the zip available
18-
val _ = azfunCreateZipFile.value
19-
//val artefact = azfunCreateZipFile.value
12+
val artefact = azfunCreateZipFile.value
2013

2114
val log = sbt.Keys.streams.value.log
2215
log.info("Running azfunDeploy task")
2316

24-
import scala.language.postfixOps
25-
import scala.sys.process._
26-
2717
val resourceGroup = azfunResourceGroup.value
28-
log.info(s"Checking if group ${resourceGroup} exists...")
29-
val output = (s"az group exists -n ${resourceGroup}" !!)
30-
val groupExists = output.startsWith("true")
31-
if (!groupExists) {
32-
log.info(s"Group ${resourceGroup} does not yet exist, creating it")
33-
val result = (s"az group create -n ${resourceGroup} -l ${azfunLocation.value}" !)
34-
if (result != 0) {
35-
log.error("Failed to create resource group")
36-
} else {
37-
log.info("Resource group created")
38-
}
39-
} else {
40-
log.info(s"Group ${resourceGroup} is present")
41-
}
18+
val location = azfunLocation.value
19+
DeployFunctionHelper.createResourceGroup(resourceGroup, location, log)
4220

4321
val storageAccount = azfunStorageAccount.value
44-
log.info(s"Checking if storage account ${storageAccount} exists...")
45-
val output2 = (s"az storage account check-name -n ${storageAccount} --query nameAvailable" !!)
46-
val saExists = output2.startsWith("false")
47-
if (!saExists) {
48-
log.info(s"Storage Account ${storageAccount} does not yet exist, creating it")
49-
val result =
50-
s"az storage account create -n ${storageAccount} -l ${azfunLocation.value} -g ${resourceGroup} --sku ${azfunSKU.value}" !
51-
52-
if (result != 0) {
53-
log.error("Failed to create storage account")
54-
} else {
55-
log.info("Storage account created")
56-
}
57-
} else {
58-
log.info(s"Storage account ${storageAccount} is present")
59-
}
22+
val skuValue = azfunSKU.value
23+
DeployFunctionHelper.createStorageAccount(storageAccount, resourceGroup, location, skuValue, log)
24+
25+
val aiName = azfunAppInsightsName.value
26+
DeployFunctionHelper.createAppInsightsInstance(aiName, resourceGroup, location, None, log)
27+
28+
val appName = azfunFunctionAppName.value
29+
DeployFunctionHelper
30+
.createFunctionApp(appName, resourceGroup, location, storageAccount, aiName, log)
6031

32+
DeployFunctionHelper.deployZipFile(artefact, appName, resourceGroup, log)
6133
}
6234
)
6335
}

plugin/src/sbt-test/sbt-azure-functions/deploy/test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
> azfunDeploy
33

44
# Uncomment the next lines if you want to look at the results from the scripted test
5-
# $ pause
5+
$ pause

0 commit comments

Comments
 (0)