Skip to content

Commit 4fc590c

Browse files
committed
Updated pipeline to use service principal with federated credential to authenticate with Azure in order to deploy both the static web app and the azure functions
1 parent 988bebd commit 4fc590c

File tree

12 files changed

+149
-293
lines changed

12 files changed

+149
-293
lines changed

.github/workflows/deploy_to_azure.yml

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ on:
88

99
env:
1010
AZURE_FUNCTIONAPP_PACKAGE_PATH: '.'
11-
PYTHON_VERSION: '3.10'
11+
PYTHON_VERSION: '3.11'
1212
STORAGE_ACCOUNT_NAME: 'hvalfangststorageaccount'
13+
FUNCTION_APP_NAME: 'hvalfangstlinuxfunctionapp'
14+
RESOURCE_GROUP: 'hvalfangstresourcegroup'
1315

1416
jobs:
1517
build-function:
@@ -45,9 +47,9 @@ jobs:
4547
deploy-function:
4648
runs-on: ubuntu-latest
4749
needs: build-function
48-
environment:
49-
name: 'Production'
50-
url: ${{ steps.deploy-to-function.outputs.webapp-url }}
50+
permissions:
51+
id-token: write
52+
contents: read
5153
steps:
5254
- name: Download artifact from build job
5355
uses: actions/download-artifact@v4
@@ -57,20 +59,22 @@ jobs:
5759
- name: Unzip artifact for deployment
5860
run: unzip release.zip
5961

60-
- name: Login to Azure using Service Principal
61-
uses: azure/login@v1
62+
- name: Login to Azure with OIDC
63+
uses: azure/login@v2
6264
with:
63-
creds: ${{ secrets.AZURE_CREDENTIALS }}
65+
client-id: ${{ secrets.AZURE_CLIENT_ID }}
66+
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
67+
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
6468

65-
- name: Deploy to Azure Functions
66-
uses: Azure/functions-action@v1
67-
id: deploy-to-function
69+
- name: Deploy to Azure Functions using CLI
70+
uses: azure/CLI@v1
6871
with:
69-
app-name: 'hvalfangstlinuxfunctionapp'
70-
slot-name: 'Production'
71-
package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
72-
scm-do-build-during-deployment: true
73-
enable-oryx-build: true
72+
azcliversion: latest
73+
inlineScript: |
74+
az functionapp deployment source config-zip \
75+
--resource-group hvalfangstresourcegroup \
76+
--name hvalfangstlinuxfunctionapp \
77+
--src release.zip
7478
7579
build-react:
7680
runs-on: ubuntu-latest
@@ -103,6 +107,9 @@ jobs:
103107
deploy-react:
104108
runs-on: ubuntu-latest
105109
needs: build-react
110+
permissions:
111+
id-token: write
112+
contents: read
106113
steps:
107114
- name: Download React build artifact
108115
uses: actions/download-artifact@v4
@@ -112,10 +119,12 @@ jobs:
112119
- name: Unzip React build
113120
run: unzip build.zip
114121

115-
- name: Login to Azure using service principal
116-
uses: azure/login@v1
122+
- name: Login to Azure with OIDC
123+
uses: azure/login@v2
117124
with:
118-
creds: ${{ secrets.AZURE_CREDENTIALS }}
125+
client-id: ${{ secrets.AZURE_CLIENT_ID }}
126+
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
127+
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
119128

120129

121130
- name: Deploy React build to Azure Static Website

README.md

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
# Static web app invoking Azure functions
22

3-
Static web app built with the React framework. The [application](client/src/App.js) allows users to upload CSV files to a storage blob via an HTTP-triggered function.
4-
The uploaded files are then processed by a blob-triggered function, which stores the results in a separate container. Aforementioned functions
5-
are present in the [function_app.py](hvalfangst_function/function_app.py) python script - which is the main entrypoint of our Azure Function App instance.
3+
The aim of this repository is to demonstrate how to deploy a [static website](client/src/App.js) written in React to a [Storage Blob](https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website). The
4+
hosted SPA allows users to upload CSV files containing demographic and financial data about individuals. The files are uploaded to a storage blob by calling an HTTP-triggered Azure Function with the appropriate output bindings.
5+
Once the CSV has been uploaded to the storage blob, another, blob-triggered Azure Function calculates correlations between various variables, such as experience, state, gender, and income.
6+
The computed statistics are then stored in a new blob container, which is used to serve the results to the user.
7+
These two functions are defined in the python script [function_app.py](hvalfangst_function/function_app.py) - which is the main entrypoint of our Azure Function App instance.
68

7-
A pipeline has been set up to deploy the function app and the static web app to Azure using GitHub Actions. The pipeline is triggered by a push to the main branch or by manually running the workflow.
9+
The associated Azure infrastructure is deployed with a script (more on that below).
810

11+
A branch-triggered pipeline has been set up to deploy our code to the respective Azure resources using a GitHub Actions Workflows [script](.github/workflows/deploy_to_azure.yml).
12+
The two functions are deployed using the Function App's associated **publish profile**, whereas the static web app is deployed using a service principal configured with a federated credential.
13+
Note that the static web app is actually hosted directly on a storage blob, which is configured to serve static websites. Thus, deploying the web app is simply a matter of uploading the files to the designated blob container.
914

1015

1116
## Requirements
@@ -18,8 +23,8 @@ A pipeline has been set up to deploy the function app and the static web app to
1823

1924
## Allocate resources
2025

21-
The shell script [allocate_resources](infra/allocate_resources.sh) creates Azure resources specified in a
22-
[Bicep](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview?tabs=bicep) template [file](infra/main.bicep).
26+
The shell script [allocate_resources](infra/allocate_resources.sh) creates Azure resources using the Azure CLI and a
27+
[Bicep](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview?tabs=bicep) template [file](infra/main.bicep).
2328

2429
It will create the following hierarchy of resources:
2530

@@ -41,20 +46,13 @@ graph TD
4146
B -->|Contains| F
4247
```
4348

44-
## Deallocate resources
45-
46-
The shell script [deallocate_resources](infra/deallocate_resources.sh) deletes our Azure resources.
47-
48-
# CI/CD
49-
50-
A CI/CD pipeline for deploying our [Function App](hvalfangst_function/function_app.py) to Azure has been set up using a GitHub Actions workflows [script](.github/workflows/deploy_to_azure.yml). The pipeline is either triggered by a push to the main branch or by manually running the workflow.
51-
In order for the pipeline to work, the following secrets must be set in the repository settings:
52-
53-
![img.png](img.png)
54-
55-
The associated values of the aforementioned secret can be retrieved from the Azure portal, under our deployed Function App.
56-
Click on the **Get publish profile** button and copy/paste the file content into the secret value field.
57-
58-
![img_1.png](img_1.png)
49+
## GitHub secrets
50+
Four secrets are required in order for the GitHub Actions Workflow script to deploy the code to the Azure resources.
51+
As may be observed in the [script](.github/workflows/deploy_to_azure.yml), these are:
5952

53+
- **AZURE_CLIENT_ID**: Used to authenticate the service principal in order to deploy the static web app
54+
- **AZURE_SUBSCRIPTION_ID**: Used to authenticate the service principal in order to deploy the static web app
55+
- **AZURE_TENANT_ID**: Used to authenticate the service principal in order to deploy the static web app
56+
- **PUBLISH_PROFILE**: Used to deploy our two functions to the Azure Function App
6057

58+
![img_1.png](images/img_1.png)

0 commit comments

Comments
 (0)