-
Notifications
You must be signed in to change notification settings - Fork 884
Added azure native function app in python #1002
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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,2 @@ | ||
| *.pyc | ||
| venv/ |
This file contains hidden or 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,3 @@ | ||
| { | ||
| "python.pythonPath": "venv/bin/python" | ||
| } |
This file contains hidden or 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,6 @@ | ||
| name: azure-py-functions | ||
| runtime: | ||
| name: python | ||
| options: | ||
| virtualenv: venv | ||
| description: A minimal Azure Native Function in Python with Pulumi program |
This file contains hidden or 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,182 @@ | ||
| # Deploying Serverless Applications with Azure Functions | ||
|
|
||
| You will deploy a Azure Function Apps with HTTP-triggered serverless functions in python | ||
|
|
||
| ## Running the App | ||
|
|
||
| 1. Login to Azure CLI (you will be prompted to do this during deployment if you forget this step): | ||
|
|
||
| ``` | ||
| $ az login | ||
| ``` | ||
|
|
||
| 1. Create a new stack: | ||
|
|
||
| ``` | ||
| $ pulumi stack init dev | ||
| ``` | ||
|
|
||
|
|
||
| 1. Create a virtual environment and install python dependencies | ||
|
|
||
| ### Windows | ||
| Run the following command to create a virtual environment | ||
| ```bash | ||
| python -m venv venv | ||
| ``` | ||
|
|
||
| Activate the environment: | ||
| ```bash | ||
| venv\Scripts\activate | ||
| ``` | ||
|
|
||
| Install dependencies: | ||
| ```bash | ||
| pip3 install -r requirements.txt | ||
| ``` | ||
| ### Mac and Linux | ||
| Run the following command to create a virtual environment | ||
| ```bash | ||
| python3 -m venv venv | ||
| ``` | ||
|
|
||
| Activate the environment: | ||
| ```bash | ||
| source venv/bin/activate | ||
| ``` | ||
|
|
||
| Install dependencies: | ||
| ```bash | ||
| pip3 install -r requirements.txt | ||
| ``` | ||
|
|
||
| At this point, dependencies will be installed into your virtual environment. **If you close your terminal at any time**, you may need to re-activate the environment: | ||
| ```bash | ||
| source venv/bin/activate | ||
| ``` | ||
|
|
||
| 1. Configure the location to deploy the resources to. The Azure region to deploy to is pre-set to **WestUS** - but you can modify the region you would like to deploy to. | ||
|
|
||
| ```bash | ||
| pulumi config set azure-native:location eastus2 | ||
| ``` | ||
|
|
||
| [pulumi config set](https://www.pulumi.com/docs/reference/cli/pulumi_config_set/) allows us to pass in [configuration values](https://www.pulumi.com/docs/intro/concepts/config/#setting-and-getting-configuration-values) from the command line. | ||
| Feel free to choose any Azure region that supports the services used in these labs ([see this infographic](https://azure.microsoft.com/en-us/global-infrastructure/regions/) for current list of available regions). A list of some of the regions: | ||
|
|
||
| ``` | ||
| centralus,eastasia,southeastasia,eastus,eastus2,westus,westus2,northcentralus,southcentralus, | ||
| westcentralus,northeurope,westeurope,japaneast,japanwest,brazilsouth,australiasoutheast,australiaeast, | ||
| westindia,southindia,centralindia,canadacentral,canadaeast,uksouth,ukwest,koreacentral,koreasouth, | ||
| francecentral,southafricanorth,uaenorth,australiacentral,switzerlandnorth,germanywestcentral, | ||
| norwayeast,jioindiawest,australiacentral2 | ||
| ``` | ||
|
|
||
| The command updates and persists the value to the local `Pulumi.dev.yaml` file. You can view or edit this file at any time to effect the configuration of the current stack. | ||
|
|
||
| 1. Azure Python Function Zip file | ||
| The applications settings configure the app to run on Python3 deploy the specified zip file to the Function App. The app will download the specified file, extract the code from it, discover the functions, and run them. We’ve prepared this [zip](https://github.com/tusharshahrs/demo/blob/main/content/lab/pulumi/azure-native/python/app/HelloWithPython.zip) file for you to get started faster, you can find its code [here](https://github.com/tusharshahrs/demo/tree/main/content/lab/pulumi/azure-native/python/app). The code contains a single HTTP-triggered Azure Function. | ||
|
|
||
| 1. Run `pulumi up` to preview and select `yes` to deploy changes: | ||
|
|
||
| ``` | ||
| $ pulumi up | ||
| Previewing update (dev) | ||
|
|
||
| View Live: https://app.pulumi.com/myuser/azure-py-functions/dev/previews/f3ea-2esdff2-123d-e79d | ||
|
|
||
| Type Name Plan | ||
| + pulumi:pulumi:Stack azure-py-functions-dev create | ||
| + ├─ azure-native:resources:ResourceGroup resourcegroup_functions_py create | ||
| + ├─ azure-native:web:AppServicePlan consumption-plan create | ||
| + ├─ azure-native:storage:StorageAccount storageaccount create | ||
| + └─ azure-native:web:WebApp functionapp create | ||
|
|
||
| Resources: | ||
| + 5 to create | ||
|
|
||
| Do you want to perform this update? [Use arrows to move, enter to select, type to filter] | ||
| > yes | ||
| no | ||
| details | ||
|
|
||
| Updating (dev) | ||
|
|
||
| View Live: https://app.pulumi.com/myuser/azure-py-functions/dev/updates/1 | ||
|
|
||
| Type Name Status | ||
| + pulumi:pulumi:Stack azure-py-functions-dev created | ||
| + ├─ azure-native:resources:ResourceGroup resourcegroup_functions_py created | ||
| + ├─ azure-native:web:AppServicePlan consumption-plan created | ||
| + ├─ azure-native:storage:StorageAccount storageaccount created | ||
| + └─ azure-native:web:WebApp functionapp created | ||
|
|
||
| Outputs: | ||
| consumptionplan : "consumption-plan7b9df5ed" | ||
| endpoint : "https://functionappfe054af4.azurewebsites.net/api/HelloWithPython" | ||
| function_app : "functionappfe054af4" | ||
| primarystoragekey : "[secret]" | ||
| resourcegroup : "resourcegroup_functions_py4eba2bf2" | ||
| storageaccount : "storageaccounta6b2e431" | ||
| storageaccountkeys : "[secret]" | ||
| storageconnectionstring: "[secret]" | ||
|
|
||
| Resources: | ||
| + 5 created | ||
|
|
||
| Duration: 50s | ||
| ``` | ||
|
|
||
| 1. Check the deployed function endpoints via [pulumi stack output](https://www.pulumi.com/docs/reference/cli/pulumi_stack_output/) | ||
|
|
||
| ``` | ||
| $ pulumi stack output endpoint | ||
| https://functionappfe054af4.azurewebsites.net/api/HelloWithPython | ||
|
|
||
| 1. You can now open the resulting endpoint in the browser or curl it: | ||
| ``` | ||
| $ curl "$(pulumi stack output endpoint)" | ||
| Hello from Python in Pulumi! You have stood up a serverless function in Azure! | ||
| ``` | ||
|
|
||
| ## Cleanup and destroy everything | ||
|
|
||
| 1. Destroy the stack via: `pulumi destroy` .Select `yes` | ||
| ``` | ||
| Previewing destroy (dev) | ||
|
|
||
| Type Name Plan | ||
| - pulumi:pulumi:Stack azure-py-functions-dev delete | ||
| - ├─ azure-native:web:WebApp functionapp delete | ||
| .. | ||
| .. | ||
|
|
||
| Outputs: | ||
| - endpoint : "https://functionappfe054af4.azurewebsites.net/api/HelloWithPython" | ||
| .. | ||
| .. | ||
|
|
||
| Resources: | ||
| - 5 to delete | ||
|
|
||
| Do you want to perform this destroy? [Use arrows to move, enter to select, type to filter] | ||
| yes | ||
| > no | ||
| details | ||
| .. | ||
| .. | ||
| Resources: | ||
| - 5 deleted | ||
|
|
||
| Duration: 1m1s | ||
| ``` | ||
|
|
||
| 1. Remove the stack | ||
|
|
||
| ``` | ||
| pulumi stack rm | ||
| This will permanently remove the 'dev' stack! | ||
| Please confirm that this is what you'd like to do by typing ("dev"): | ||
| ``` | ||
|
|
||
| Type in the name of your stack: **dev** | ||
This file contains hidden or 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,90 @@ | ||
| import pulumi | ||
| from pulumi_azure_native import resources | ||
| from pulumi_azure_native import storage | ||
| from pulumi_azure_native import web | ||
| from pulumi import Output | ||
|
|
||
| # Create an Azure Resource Group | ||
| resource_group = resources.ResourceGroup('resourcegroup_functions_py') | ||
|
|
||
| # Create a Storage Account | ||
| account = storage.StorageAccount( | ||
| 'storageaccount', | ||
| resource_group_name=resource_group.name, | ||
| sku=storage.SkuArgs( | ||
| name=storage.SkuName.STANDARD_LRS, | ||
| ), | ||
| kind=storage.Kind.STORAGE_V2, | ||
| ) | ||
|
|
||
| # Create a consumption plan | ||
| # Consumption plan must be linux for python: https://docs.microsoft.com/en-us/azure/azure-functions/functions-scale#operating-systemruntime | ||
| plan = web.AppServicePlan( | ||
| "consumption-plan", | ||
| resource_group_name=resource_group.name, | ||
| location=resource_group.location, | ||
| kind="functionapp", | ||
| reserved=True, # This is an Azure Requirement for PYTHON. The function can only run on Linux. | ||
| sku=web.SkuDescriptionArgs(name="Y1", tier="Dynamic", size="Y1", family="Y", capacity=0), | ||
| ) | ||
|
|
||
| # Export the Azure Resource Group | ||
| pulumi.export('resourcegroup', resource_group.name) | ||
|
|
||
| # Export the Storage Account | ||
| pulumi.export('storageaccount', account.name) | ||
|
|
||
| # Export the Consumption Plan | ||
| pulumi.export('consumptionplan', plan.name) | ||
|
|
||
| # List of storage account keys | ||
| storageAccountKeys = pulumi.Output.all(resource_group.name, account.name).apply( | ||
| lambda args: storage.list_storage_account_keys( | ||
| resource_group_name=args[0], account_name=args[1] | ||
| ) | ||
| ) | ||
| # Primary storage account key | ||
| primaryStorageKey = storageAccountKeys.apply(lambda accountKeys: accountKeys.keys[0].value) | ||
| # Build a storage connection string out of it: | ||
| storageConnectionString = Output.concat( | ||
| "DefaultEndpointsProtocol=https;AccountName=", account.name, ";AccountKey=", primaryStorageKey | ||
| ) | ||
|
|
||
|
|
||
| # Export the storageacountkey as a secret | ||
| pulumi.export("storageaccountkeys", pulumi.Output.secret(storageAccountKeys)) | ||
| # Export the primarystoragekey as a secret | ||
| pulumi.export('primarystoragekey', pulumi.Output.secret(primaryStorageKey)) | ||
| # Export the storageconnectionstring as a secret | ||
| pulumi.export('storageconnectionstring', pulumi.Output.secret(storageConnectionString)) | ||
|
|
||
| # Create the functionapp | ||
| app = web.WebApp( | ||
| "functionapp", | ||
| resource_group_name=resource_group.name, | ||
| location=resource_group.location, | ||
| kind="functionapp", | ||
| reserved=True, | ||
| server_farm_id=plan.id, | ||
| site_config=web.SiteConfigArgs( | ||
| app_settings=[ | ||
| web.NameValuePairArgs(name="runtime", value="python"), | ||
| web.NameValuePairArgs(name="FUNCTIONS_WORKER_RUNTIME", value="python"), | ||
| web.NameValuePairArgs(name="FUNCTIONS_EXTENSION_VERSION", value="~3"), | ||
| web.NameValuePairArgs(name="AzureWebJobsStorage", value=storageConnectionString), | ||
| web.NameValuePairArgs( | ||
| name="WEBSITE_RUN_FROM_PACKAGE", | ||
| value="https://github.com/pulumi/examples/raw/master/azure-py-functions/app/HelloWithPython.zip", | ||
| ), | ||
| ], | ||
| ), | ||
| ) | ||
|
|
||
| # Export the function | ||
| pulumi.export('function_app', app.name) | ||
|
|
||
| # Full endpoint of your Function App | ||
| function_endpoint = app.default_host_name.apply( | ||
| lambda default_host_name: f"https://{default_host_name}/api/HelloWithPython" | ||
| ) | ||
| pulumi.export('endpoint', function_endpoint) |
Binary file not shown.
This file contains hidden or 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,10 @@ | ||
| import logging | ||
|
|
||
| import azure.functions as func | ||
|
|
||
|
|
||
| def main(req: func.HttpRequest) -> func.HttpResponse: | ||
| logging.info('Python HTTP trigger function processed a request.') | ||
| return func.HttpResponse( | ||
| f"Hello from Python in Pulumi! You have stood up a serverless function in Azure!" | ||
| ) |
This file contains hidden or 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,20 @@ | ||
| { | ||
| "scriptFile": "__init__.py", | ||
| "bindings": [ | ||
| { | ||
| "authLevel": "anonymous", | ||
| "type": "httpTrigger", | ||
| "direction": "in", | ||
| "name": "req", | ||
| "methods": [ | ||
| "get", | ||
| "post" | ||
| ] | ||
| }, | ||
| { | ||
| "type": "http", | ||
| "direction": "out", | ||
| "name": "$return" | ||
| } | ||
| ] | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this required now? I thought the CLI handled this for us?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We had this here due to a python workshop where the team was windows and ran into a lot of issues.