Skip to content

Commit e03f007

Browse files
Integrate Azure Functions deployment
Signed-off-by: hancheng wang <wanghanchengchn@gmail.com> Integrate Azure Functions deployment Signed-off-by: hancheng wang <wanghanchengchn@gmail.com> Integrate Azure Functions deployment Signed-off-by: hancheng wang <wanghanchengchn@gmail.com> Integrate Azure Functions deployment Signed-off-by: hancheng wang <wanghanchengchn@gmail.com> Integrate Azure Functions deployment Signed-off-by: hancheng wang <wanghanchengchn@gmail.com>
1 parent 557e970 commit e03f007

File tree

8 files changed

+55
-64
lines changed

8 files changed

+55
-64
lines changed

.github/workflows/azure_integration_test.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
env:
2121
AZURE_APP_ID: ${{ secrets.AZURE_APP_ID }}
2222
AZURE_PASSWORD: ${{ secrets.AZURE_PASSWORD }}
23-
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
23+
AZURE_TENANT: ${{ secrets.AZURE_TENANT }}
2424

2525
steps:
2626
- name: Check if environment variables are set # Validate secrets are passed
@@ -33,8 +33,8 @@ jobs:
3333
echo "AZURE_PASSWORD is not set. Please check if secrets.AZURE_PASSWORD is in the repository."
3434
exit 1
3535
fi
36-
if [[ -z "$AZURE_TENANT_ID" ]]; then
37-
echo "AZURE_TENANT_ID is not set. Please check if secrets.AZURE_TENANT_ID is in the repository."
36+
if [[ -z "$AZURE_TENANT" ]]; then
37+
echo "AZURE_TENANT is not set. Please check if secrets.AZURE_TENANT is in the repository."
3838
exit 1
3939
fi
4040
@@ -59,7 +59,7 @@ jobs:
5959
python-version: '3.10'
6060

6161
- name: Azure CLI Login Using Service Principal
62-
run: az login --service-principal --username "$AZURE_APP_ID" --password "$AZURE_PASSWORD" --tenant "$AZURE_TENANT_ID"
62+
run: az login --service-principal --username "$AZURE_APP_ID" --password "$AZURE_PASSWORD" --tenant "$AZURE_TENANT"
6363

6464
- name: Run Azure-related integration test
6565
run: go test -v ./pkg/driver/deployment/azure_functions_test.go

.github/workflows/e2e_azure.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
env:
2121
AZURE_APP_ID: ${{ secrets.AZURE_APP_ID }}
2222
AZURE_PASSWORD: ${{ secrets.AZURE_PASSWORD }}
23-
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
23+
AZURE_TENANT: ${{ secrets.AZURE_TENANT }}
2424

2525
steps:
2626
- name: Check if environment variables are set # Validate secrets are passed
@@ -33,8 +33,8 @@ jobs:
3333
echo "AZURE_PASSWORD is not set. Please check if secrets.AZURE_PASSWORD is in the repository."
3434
exit 1
3535
fi
36-
if [[ -z "$AZURE_TENANT_ID" ]]; then
37-
echo "AZURE_TENANT_ID is not set. Please check if secrets.AZURE_TENANT_ID is in the repository."
36+
if [[ -z "$AZURE_TENANT" ]]; then
37+
echo "AZURE_TENANT is not set. Please check if secrets.AZURE_TENANT is in the repository."
3838
exit 1
3939
fi
4040
@@ -59,7 +59,7 @@ jobs:
5959
python-version: '3.10'
6060

6161
- name: Azure CLI Login Using Service Principal
62-
run: az login --service-principal --username "$AZURE_APP_ID" --password "$AZURE_PASSWORD" --tenant "$AZURE_TENANT_ID"
62+
run: az login --service-principal --username "$AZURE_APP_ID" --password "$AZURE_PASSWORD" --tenant "$AZURE_TENANT"
6363

6464
- name: Build and Run Loader
6565
run: go run cmd/loader.go --config cmd/config_azure_trace.json

.github/workflows/integration_tests.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ jobs:
3131
- uses: actions/setup-python@v5
3232
with:
3333
python-version: '3.9'
34-
35-
- name: Upgrade pip
36-
run: python3 -m pip install --upgrade pip
3734

3835
- uses: actions/cache@v4
3936
with:

.github/workflows/unit-tests.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ jobs:
4646
python-version: '3.9'
4747
env:
4848
PIP_TRUSTED_HOST: "pypi.python.org pypi.org files.pythonhosted.org"
49-
50-
- name: Upgrade pip
51-
run: python3 -m pip install --upgrade pip
5249

5350
- uses: actions/cache@v4
5451
with:
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# azurefunctionsconfig.yaml
22
azurefunctionsconfig:
3-
resource_group: ExperimentResourceGroup # Name of the resource group
4-
storage_account_name: testinvitrostorage # Name of the storage account
5-
function_app_name: testinvitrofunctionapp # Name of the function app
3+
resource_group: invitro-rg # Name of the resource group
4+
storage_account_name: invitrostorage # Name of the storage account
5+
function_app_name: invitro-functionapp # Name of the function app
66
location: EastUS # Region where resource created

docs/loader.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ Note:
302302
```
303303
2. Use existing Service Principal credentials in order login to Azure.
304304
```bash
305-
az login --service-principal --username $AZURE_APP_ID --password $AZURE_PASSWORD --tenant $AZURE_TENANT_ID
305+
az login --service-principal --username $AZURE_APP_ID --password $AZURE_PASSWORD --tenant $AZURE_TENANT
306306
```
307307
> Refer to Note section for generation of Service Principal credentials
308308
3. Start the Azure Functions deployment experiment:
@@ -321,7 +321,7 @@ Notes:
321321
- Click **Register**
322322
3. Once registered, note down the following:
323323
- **Application (client) ID** → This is your `AZURE_APP_ID`
324-
- **Directory (tenant) ID** → This is your `AZURE_TENANT_ID`
324+
- **Directory (tenant) ID** → This is your `AZURE_TENANT`
325325
4. Click **Add a certificate or secret**
326326
- Click **+ New client secret**
327327
- Add a description and choose an expiry (e.g., 6 months)
@@ -338,7 +338,7 @@ Notes:
338338
```bash
339339
export AZURE_APP_ID=<appId>
340340
export AZURE_PASSWORD=<password>
341-
export AZURE_TENANT_ID=<tenant>
341+
export AZURE_TENANT=<tenant>
342342
```
343343
- Current deployment is via ZIP
344-
- Python is used for deployment workload as Go is not supported in Consumption Plan
344+
- Python is used for deployment workload as Go is not supported in Consumption Plan

pkg/driver/deployment/azure_functions.go

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"os"
66
"os/exec"
7+
"time"
78

89
"path/filepath"
910

@@ -25,6 +26,7 @@ type Config struct {
2526

2627
type azureFunctionsDeployer struct {
2728
functions []*common.Function
29+
config *Config
2830
}
2931

3032
func newAzureFunctionsDeployer() *azureFunctionsDeployer {
@@ -33,14 +35,14 @@ func newAzureFunctionsDeployer() *azureFunctionsDeployer {
3335

3436
func (afd *azureFunctionsDeployer) Deploy(cfg *config.Configuration) {
3537
afd.functions = cfg.Functions
36-
DeployAzureFunctions(afd.functions)
38+
afd.config = DeployAzureFunctions(afd.functions)
3739
}
3840

3941
func (afd *azureFunctionsDeployer) Clean() {
40-
CleanAzureFunctions(afd.functions)
42+
CleanAzureFunctions(afd.config, afd.functions)
4143
}
4244

43-
func DeployAzureFunctions(functions []*common.Function) {
45+
func DeployAzureFunctions(functions []*common.Function) *Config {
4446
// 1. Copy exec_func.py to azurefunctions_setup
4547
// 2. Initialize resources required for Azure Functions deployment
4648
// 3. Create function folders
@@ -53,6 +55,12 @@ func DeployAzureFunctions(functions []*common.Function) {
5355
log.Fatalf("Error loading azure functions config yaml: %s", err)
5456
}
5557

58+
// Set unique names for Azure Resources
59+
timestamp := time.Now().Format("150405") // HHMMSS format
60+
config.AzureConfig.ResourceGroup = fmt.Sprintf("%s-%s", config.AzureConfig.ResourceGroup, timestamp) // invitro-rg-XXXXXX
61+
config.AzureConfig.StorageAccountName = fmt.Sprintf("%s%s", config.AzureConfig.StorageAccountName, timestamp) // invitrostorageXXXXXX
62+
config.AzureConfig.FunctionAppName = fmt.Sprintf("%s-%s", config.AzureConfig.FunctionAppName, timestamp) // invitro-functionapp-XXXXXX
63+
5664
// Define the base directory containing functions to be zipped individually
5765
baseDir := "azure_functions_for_zip"
5866
sharedWorkloadDir := filepath.Join("azurefunctions_setup", "shared_azure_workload")
@@ -80,15 +88,11 @@ func DeployAzureFunctions(functions []*common.Function) {
8088
if err := DeployFunctions(config, zipBaseDir, functions); err != nil {
8189
log.Fatalf("Error deploying function: %s", err)
8290
}
83-
}
8491

85-
func CleanAzureFunctions(functions []*common.Function) {
86-
// Load azurefunctionsconfig yaml file
87-
config, err := LoadConfig("azurefunctions_setup/azurefunctionsconfig.yaml")
88-
if err != nil {
89-
log.Fatalf("Error loading azure functions config yaml: %s", err)
90-
}
92+
return config
93+
}
9194

95+
func CleanAzureFunctions(config *Config, functions []*common.Function) {
9296
log.Infof("Performing cleanup of experiment...")
9397

9498
baseDir := "azure_functions_for_zip"
@@ -132,6 +136,12 @@ func InitAzureFunctions(config *Config, functions []*common.Function) {
132136

133137
// 2. Create Storage Account
134138
if err := CreateStorageAccount(config); err != nil {
139+
140+
cleanupErr := DeleteResourceGroup(config)
141+
if cleanupErr != nil {
142+
log.Errorf("Failed to delete resource group during cleanup: %v", cleanupErr)
143+
}
144+
135145
log.Fatalf("Error during Storage Account creation: %s", err)
136146
}
137147

@@ -140,16 +150,34 @@ func InitAzureFunctions(config *Config, functions []*common.Function) {
140150
functionAppName := fmt.Sprintf("%s-%d", config.AzureConfig.FunctionAppName, i)
141151

142152
if err := CreateFunctionApp(config, functionAppName); err != nil {
153+
154+
cleanupErr := DeleteResourceGroup(config)
155+
if cleanupErr != nil {
156+
log.Errorf("Failed to delete resource group during cleanup: %v", cleanupErr)
157+
}
158+
143159
log.Fatalf("Error during Function App creation: %s", err)
144160
}
145161

146162
// Set SCM_DO_BUILD_DURING_DEPLOYMENT
147163
if err := SetSCMSettings(config, functionAppName); err != nil {
164+
165+
cleanupErr := DeleteResourceGroup(config)
166+
if cleanupErr != nil {
167+
log.Errorf("Failed to delete resource group during cleanup: %v", cleanupErr)
168+
}
169+
148170
log.Fatalf("failed to set SCM settings: %s", err)
149171
}
150172

151173
// Set ENABLE_ORYX_BUILD
152174
if err := SetORYXSettings(config, functionAppName); err != nil {
175+
176+
cleanupErr := DeleteResourceGroup(config)
177+
if cleanupErr != nil {
178+
log.Errorf("Failed to delete resource group during cleanup: %v", cleanupErr)
179+
}
180+
153181
log.Fatalf("failed to set Oryx settings: %s", err)
154182
}
155183
}
@@ -250,31 +278,6 @@ func SetORYXSettings(config *Config, functionAppName string) error {
250278

251279
/* Function to create folders and copy files to the folders */
252280

253-
// func CreateFunctionFolders(baseDir string, functions []*common.Function) error {
254-
// for i := 0; i < len(functions); i++ {
255-
// folderName := fmt.Sprintf("function%d", i)
256-
// folderPath := filepath.Join(baseDir, folderName)
257-
258-
// // Create the function folder
259-
// if err := os.MkdirAll(folderPath, os.ModePerm); err != nil {
260-
// return fmt.Errorf("failed to create folder %s: %w", folderPath, err)
261-
// }
262-
263-
// // Copy azurefunctionsworkload.py, exec_func.py and function.json into each function folder
264-
// if err := common.CopyFile("azurefunctions_setup/shared_azure_workload/azurefunctionsworkload.py", filepath.Join(folderPath, "azurefunctionsworkload.py")); err != nil {
265-
// return fmt.Errorf("failed to copy azurefunctionsworkload.py to %s: %w", folderPath, err)
266-
// }
267-
// if err := common.CopyFile("azurefunctions_setup/shared_azure_workload/exec_func.py", filepath.Join(folderPath, "exec_func.py")); err != nil {
268-
// return fmt.Errorf("failed to copy exec_func.py to %s: %w", folderPath, err)
269-
// }
270-
// if err := common.CopyFile("azurefunctions_setup/shared_azure_workload/function.json", filepath.Join(folderPath, "function.json")); err != nil {
271-
// return fmt.Errorf("failed to copy function.json to %s: %w", folderPath, err)
272-
// }
273-
// }
274-
// log.Debugf("Created %d function folders with copies of azurefunctionsworkload.py, exec_func.py and function.json under %s folder.\n", len(functions), baseDir)
275-
// return nil
276-
// }
277-
278281
func CreateFunctionFolders(baseDir, sharedWorkloadDir string, functions []*common.Function) error {
279282
for i := 0; i < len(functions); i++ {
280283
folderName := fmt.Sprintf("function%d", i)
@@ -345,13 +348,7 @@ func DeployFunctions(config *Config, baseDir string, functions []*common.Functio
345348
"--src", zipFilePath,
346349
"--build-remote", "true")
347350

348-
//var stdout, stderr bytes.Buffer // debugging output
349-
//cmd.Stdout = &stdout // debugging output
350-
//cmd.Stderr = &stderr // debugging output
351-
352351
if err := cmd.Run(); err != nil {
353-
//log.Errorf("Deployment stdout:\n%s", stdout.String()) // debugging output
354-
//log.Errorf("Deployment stderr:\n%s", stderr.String()) // debugging output
355352
return fmt.Errorf("failed to deploy %s to function app %s: %w", zipFilePath, functionAppName, err)
356353
}
357354

pkg/driver/deployment/azure_functions_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,11 +245,11 @@ func setupAzureLogin(t *testing.T) {
245245

246246
appID := os.Getenv("AZURE_APP_ID")
247247
password := os.Getenv("AZURE_PASSWORD")
248-
tenantID := os.Getenv("AZURE_TENANT_ID")
248+
tenantID := os.Getenv("AZURE_TENANT")
249249

250250
require.NotEmpty(t, appID, "AZURE_APP_ID must be set")
251251
require.NotEmpty(t, password, "AZURE_PASSWORD must be set")
252-
require.NotEmpty(t, tenantID, "AZURE_TENANT_ID must be set")
252+
require.NotEmpty(t, tenantID, "AZURE_TENANT must be set")
253253

254254
cmd := exec.Command("az", "login",
255255
"--service-principal",

0 commit comments

Comments
 (0)