Skip to content

Commit 7b69740

Browse files
Merge pull request #37 from localstack-samples/updates
Remove large code blocks and add Key Vault to the Web App + SQL DB sample
2 parents f5eb9dd + dfdd989 commit 7b69740

19 files changed

Lines changed: 401 additions & 5979 deletions

File tree

samples/function-app-front-door/python/README.md

Lines changed: 229 additions & 154 deletions
Large diffs are not rendered by default.

samples/function-app-managed-identity/python/bicep/README.md

Lines changed: 15 additions & 498 deletions
Large diffs are not rendered by default.

samples/function-app-managed-identity/python/scripts/README.md

Lines changed: 8 additions & 431 deletions
Large diffs are not rendered by default.

samples/function-app-managed-identity/python/terraform/README.md

Lines changed: 12 additions & 271 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Before deploying this solution, ensure you have the following tools installed:
1717

1818
### Installing azlocal CLI
1919

20-
The deployment script uses the `azlocal` CLI instead of the standard Azure CLI to work with LocalStack. Install it using:
20+
The [deploy.sh](deploy.sh) Bash script uses the `azlocal` CLI instead of the standard Azure CLI to work with LocalStack. Install it using:
2121

2222
```bash
2323
pip install azlocal
@@ -27,7 +27,7 @@ For more information, see [Get started with the az tool on LocalStack](https://a
2727

2828
## Architecture Overview
2929

30-
The Terraform modules deploy the following Azure resources:
30+
The [main.tf](main.tf) Terraform module creates the following Azure resources:
3131

3232
1. [Azure Storage Account](https://learn.microsoft.com/en-us/azure/storage/common/storage-account-overview): Provides blob storage with `input` and `output` containers for storing text blobs processed by the function app.
3333
2. [Azure App Service Plan](https://learn.microsoft.com/en-us/azure/app-service/overview-hosting-plans): Defines the compute resources (CPU, memory, and scaling options) that host the Azure Functions app.
@@ -37,281 +37,22 @@ The Terraform modules deploy the following Azure resources:
3737

3838
For more information on the sample application, see [Azure Functions App with Managed Identity](../README.md).
3939

40-
## Terraform Modules
41-
42-
Below is a summary of the key Terraform modules included in this deployment:
43-
44-
- **`main.tf`**: Defines all Azure resources and their configuration.
45-
- **`variables.tf`**: Declares input variables and validation rules.
46-
- **`outputs.tf`**: Specifies output values after deployment.
47-
- **`providers.tf`**: Configures the Terraform provider for Azure.
48-
49-
Below you can read the declarative code in HashiCorp Configuration Language (HCL). The `main.tf` module uses conditional provisioning for the user-assigned managed identity and role assignments resources. In Terraform, you can use the `count` argument in a conditional expression to decide whether creating resources or not. For example, the `count = var.managed_identity_type == "UserAssigned" ? 1 : 0` expression instructs Terraform to create the user-assigned managed identity resource when the value of the variable named `managed_identity_type` is set to `UserAssigned`. Refer to ​​[Conditional Expressions](https://developer.hashicorp.com/terraform/language/expressions/conditionals) for more information.
50-
51-
```terraform
52-
# Local Variables
53-
locals {
54-
resource_group_name = "${var.prefix}-rg"
55-
storage_account_name = "${var.prefix}storage${var.suffix}"
56-
app_service_plan_name = "${var.prefix}-app-service-plan-${var.suffix}"
57-
function_app_name = "${var.prefix}-functionapp-${var.suffix}"
58-
managed_identity_name = "${var.prefix}-identity-${var.suffix}"
59-
}
60-
61-
# Create a resource group
62-
resource "azurerm_resource_group" "example" {
63-
location = var.location
64-
name = local.resource_group_name
65-
tags = var.tags
66-
}
67-
68-
# Create a storage account
69-
resource "azurerm_storage_account" "example" {
70-
name = local.storage_account_name
71-
resource_group_name = azurerm_resource_group.example.name
72-
location = azurerm_resource_group.example.location
73-
account_replication_type = var.account_replication_type
74-
account_kind = var.account_kind
75-
account_tier = var.account_tier
76-
tags = var.tags
77-
78-
identity {
79-
type = "SystemAssigned"
80-
}
81-
82-
lifecycle {
83-
ignore_changes = [
84-
tags
85-
]
86-
}
87-
}
88-
89-
# Create input storage container
90-
resource "azurerm_storage_container" "input" {
91-
name = var.input_container_name
92-
storage_account_id = azurerm_storage_account.example.id
93-
container_access_type = "private"
94-
}
95-
96-
# Create output storage container
97-
resource "azurerm_storage_container" "output" {
98-
name = var.output_container_name
99-
storage_account_id = azurerm_storage_account.example.id
100-
container_access_type = "private"
101-
}
102-
103-
# Conditionally create a user assigned identity for the function app
104-
resource "azurerm_user_assigned_identity" "identity" {
105-
count = var.managed_identity_type == "UserAssigned" ? 1 : 0
106-
107-
name = local.managed_identity_name
108-
resource_group_name = azurerm_resource_group.example.name
109-
location = azurerm_resource_group.example.location
110-
}
111-
112-
# Assign Storage Blob Data Contributor role to the function app identity
113-
resource "azurerm_role_assignment" "blob_contributor" {
114-
scope = azurerm_storage_account.example.id
115-
role_definition_name = "Storage Blob Data Contributor"
116-
principal_id = var.managed_identity_type == "UserAssigned" ? azurerm_user_assigned_identity.identity[0].principal_id : azurerm_linux_function_app.example.identity[0].principal_id
117-
}
118-
119-
# Assign Storage Queue Data Contributor role to the function app identity
120-
resource "azurerm_role_assignment" "queue_contributor" {
121-
scope = azurerm_storage_account.example.id
122-
role_definition_name = "Storage Queue Data Contributor"
123-
principal_id = var.managed_identity_type == "UserAssigned" ? azurerm_user_assigned_identity.identity[0].principal_id : azurerm_linux_function_app.example.identity[0].principal_id
124-
}
125-
126-
# Create a service plan
127-
resource "azurerm_service_plan" "example" {
128-
name = local.app_service_plan_name
129-
resource_group_name = azurerm_resource_group.example.name
130-
location = azurerm_resource_group.example.location
131-
sku_name = var.sku_name
132-
os_type = var.os_type
133-
zone_balancing_enabled = var.zone_balancing_enabled
134-
tags = var.tags
135-
136-
lifecycle {
137-
ignore_changes = [
138-
tags
139-
]
140-
}
141-
}
142-
143-
# Create a function app
144-
resource "azurerm_linux_function_app" "example" {
145-
name = local.function_app_name
146-
resource_group_name = azurerm_resource_group.example.name
147-
location = azurerm_resource_group.example.location
148-
service_plan_id = azurerm_service_plan.example.id
149-
storage_account_name = azurerm_storage_account.example.name
150-
storage_account_access_key = azurerm_storage_account.example.primary_access_key
151-
https_only = var.https_only
152-
public_network_access_enabled = var.public_network_access_enabled
153-
tags = var.tags
154-
functions_extension_version = "~4"
155-
156-
identity {
157-
type = var.managed_identity_type
158-
identity_ids = var.managed_identity_type == "UserAssigned" ? [
159-
azurerm_user_assigned_identity.identity[0].id
160-
] : []
161-
}
162-
163-
site_config {
164-
always_on = var.always_on
165-
minimum_tls_version = var.minimum_tls_version
166-
application_stack {
167-
python_version = var.python_version
168-
}
169-
}
170-
171-
app_settings = {
172-
SCM_DO_BUILD_DURING_DEPLOYMENT = "true"
173-
ENABLE_ORYX_BUILD = "true"
174-
AZURE_CLIENT_ID = var.managed_identity_type == "UserAssigned" ? azurerm_user_assigned_identity.identity[0].client_id : ""
175-
AzureWebJobsStorage = "DefaultEndpointsProtocol=https;AccountName=${azurerm_storage_account.example.name};AccountKey=${azurerm_storage_account.example.primary_access_key};EndpointSuffix=core.windows.net;"
176-
STORAGE_ACCOUNT_CONNECTION_STRING__blobServiceUri = azurerm_storage_account.example.primary_blob_endpoint
177-
STORAGE_ACCOUNT_CONNECTION_STRING__queueServiceUri = azurerm_storage_account.example.primary_queue_endpoint
178-
STORAGE_ACCOUNT_CONNECTION_STRING__tableServiceUri = azurerm_storage_account.example.primary_table_endpoint
179-
INPUT_STORAGE_CONTAINER_NAME = var.input_container_name
180-
OUTPUT_STORAGE_CONTAINER_NAME = var.output_container_name
181-
FUNCTIONS_WORKER_RUNTIME = var.runtime_name
182-
FUNCTIONS_EXTENSION_VERSION = "~4"
183-
}
184-
185-
lifecycle {
186-
ignore_changes = [
187-
tags
188-
]
189-
}
190-
}
191-
192-
# Create an app source control configuration
193-
resource "azurerm_app_service_source_control" "example" {
194-
count = var.repo_url == "" ? 0 : 1
195-
app_id = azurerm_linux_function_app.example.id
196-
repo_url = var.repo_url
197-
branch = "main"
198-
}
199-
```
200-
201-
## Deployment Script
202-
203-
You can use the `deploy.sh` script to automate the deployment of all Azure resources and the sample application in a single step, streamlining setup and reducing manual configuration. Before running the script, customize the variable values based on your needs. In particular, use the `MANAGED_IDENTITY_TYPE` variable to specify the type of managed identity to provision: `SystemAssigned` or `UserAssigned`.
204-
205-
```bash
206-
#!/bin/bash
207-
208-
# Variables
209-
PREFIX='local'
210-
SUFFIX='test'
211-
LOCATION='westeurope'
212-
MANAGED_IDENTITY_TYPE='UserAssigned' # SystemAssigned or UserAssigned
213-
CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
214-
ZIPFILE="function_app.zip"
215-
ENVIRONMENT=$(az account show --query environmentName --output tsv)
216-
217-
# Change the current directory to the script's directory
218-
cd "$CURRENT_DIR" || exit
219-
220-
# Run terraform init and apply
221-
if [[ $ENVIRONMENT == "LocalStack" ]]; then
222-
echo "Using tflocal and azlocal for LocalStack emulator environment and ."
223-
TERRAFORM="tflocal"
224-
AZ="azlocal"
225-
else
226-
echo "Using standard terraform and az for AzureCloud environment."
227-
TERRAFORM="terraform"
228-
AZ="az"
229-
fi
230-
231-
echo "Initializing Terraform..."
232-
$TERRAFORM init -upgrade
233-
234-
# Run terraform plan and check for errors
235-
echo "Planning Terraform deployment..."
236-
$TERRAFORM plan -out=tfplan \
237-
-var "prefix=$PREFIX" \
238-
-var "suffix=$SUFFIX" \
239-
-var "location=$LOCATION" \
240-
-var "managed_identity_type=$MANAGED_IDENTITY_TYPE"
40+
## Provisioning Scripts
24141

242-
if [[ $? != 0 ]]; then
243-
echo "Terraform plan failed. Exiting."
244-
exit 1
245-
fi
246-
247-
# Apply the Terraform configuration
248-
echo "Applying Terraform configuration..."
249-
$TERRAFORM apply -auto-approve tfplan
250-
251-
if [[ $? != 0 ]]; then
252-
echo "Terraform apply failed. Exiting."
253-
exit 1
254-
fi
255-
256-
# Get the output values
257-
RESOURCE_GROUP_NAME=$(terraform output -raw resource_group_name)
258-
FUNCTION_APP_NAME=$(terraform output -raw function_app_name)
259-
260-
if [[ -z "$RESOURCE_GROUP_NAME" || -z "$FUNCTION_APP_NAME" ]]; then
261-
echo "Resource Group Name or Function App Name is empty. Exiting."
262-
exit 1
263-
fi
264-
265-
# Print the variables
266-
echo "Resource Group: $RESOURCE_GROUP_NAME"
267-
echo "Function App: $FUNCTION_APP_NAME"
268-
269-
# CD into the function app directory
270-
cd ../src || exit
271-
272-
# Remove any existing zip package of the function app
273-
if [ -f "$ZIPFILE" ]; then
274-
rm "$ZIPFILE"
275-
fi
276-
277-
# Create the zip package of the function app
278-
echo "Creating zip package of the function app..."
279-
zip -r "$ZIPFILE" function_app.py host.json requirements.txt
280-
281-
# Deploy the function app
282-
echo "Deploying function app [$FUNCTION_APP_NAME] with zip file [$ZIPFILE]..."
283-
$AZ functionapp deploy \
284-
--resource-group "$RESOURCE_GROUP_NAME" \
285-
--name "$FUNCTION_APP_NAME" \
286-
--src-path "$ZIPFILE" \
287-
--type zip \
288-
--async true 1>/dev/null
289-
290-
if [ $? -eq 0 ]; then
291-
echo "Function app [$FUNCTION_APP_NAME] deployed successfully."
292-
else
293-
echo "Failed to deploy function app [$FUNCTION_APP_NAME]."
294-
exit 1
295-
fi
296-
297-
# Remove the zip package of the function app
298-
if [ -f "$ZIPFILE" ]; then
299-
rm "$ZIPFILE"
300-
fi
301-
```
42+
The [deploy.sh](deploy.sh) script automates the deployment of all Azure resources and the sample application in a single step. Before running the script, customize the variable values based on your needs. In particular, use the `MANAGED_IDENTITY_TYPE` variable to specify the type of managed identity to provision: `SystemAssigned` or `UserAssigned`.
30243

30344
> **Note**
30445
> You can use the `azlocal` CLI as a drop-in replacement for the `az` CLI to direct all commands to the LocalStack for Azure emulator. Alternatively, run `azlocal start_interception` to automatically intercept and redirect all `az` commands to LocalStack. Likewise, the `tflocal` is a local replacement for the standard `terraform` CLI, allowing you to run Terraform commands against LocalStack's Azure emulation environment. For more information, see [Get started with the az tool on LocalStack](https://azure.localstack.cloud/user-guides/sdks/az/).
30546
306-
The `deploy.sh` script executes the following steps:
47+
The [deploy.sh](deploy.sh) script executes the following steps:
30748

308-
- Cleans up any previous Terraform state and plan files to ensure a fresh deployment.
309-
- Initializes the Terraform working directory and downloads required plugins.
310-
- Creates and validates a Terraform execution plan for the Azure infrastructure.
311-
- Applies the Terraform plan to provision all necessary Azure resources.
312-
- Extracts resource names and outputs from the Terraform deployment.
313-
- Packages the code of the serverless application into a zip file for deployment.
314-
- Deploys the zip package to the Azure Functions App using the LocalStack Azure CLI.
49+
- Cleans up any previous Terraform state and plan files to ensure a fresh deployment
50+
- Initializes the Terraform working directory and downloads required plugins
51+
- Creates and validates a Terraform execution plan for the Azure infrastructure
52+
- Applies the Terraform plan to provision all necessary Azure resources
53+
- Extracts resource names and outputs from the Terraform deployment
54+
- Packages the code of the serverless application into a zip file for deployment
55+
- Deploys the zip package to the Azure Functions App using the LocalStack Azure CLI
31556

31657
## Configuration
31758

0 commit comments

Comments
 (0)