Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ This repository contains comprehensive sample projects demonstrating how to deve
| [Function App and Storage](./samples/function-app-storage-http/dotnet/README.md) | Azure Functions App using Blob, Queue, and Table Storage |
| [Function App and Front Door](./samples/function-app-front-door/python/README.md) | Azure Functions App exposed via Front Door |
| [Function App and Managed Identities](./samples/function-app-managed-identity/python/README.md) | Azure Function App using Managed Identities |
| [Web App and CosmosDB for MongoDB API ](./samples/web-app-cosmosdb-mongodb-api/python/README.md) | Azure Web App using CosmosDB for MongoDB API |
| [Web App and PostgreSQL Database](./samples/web-app-postgresql-database/python/README.md) | Azure Web App using PostgreSQL Flexible Server |
| [Web App and CosmosDB for MongoDB API ](./samples/web-app-cosmosdb-mongodb-api/python/README.md) | Azure Web App using CosmosDB for MongoDB API |
| [Web App and CosmosDB for NoSQL API ](./samples/web-app-cosmosdb-nosql-api/python/README.md) | Azure Web App using CosmosDB for NoSQL API |
| [Web App and Managed Identities](./samples/web-app-managed-identity/python/README.md) | Azure Web App using Managed Identities |
| [Web App and SQL Database ](./samples/web-app-sql-database/python/README.md) | Azure Web App using SQL Database |
Expand Down
3 changes: 3 additions & 0 deletions run-samples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ SAMPLES=(
"samples/web-app-cosmosdb-mongodb-api/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh"
"samples/web-app-managed-identity/python|bash scripts/user-assigned.sh|bash scripts/validate.sh && bash scripts/call-web-app.sh"
"samples/web-app-sql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh && bash scripts/get-web-app-url.sh"
"samples/web-app-postgresql-database/python|bash scripts/deploy.sh|bash scripts/validate.sh"
)

# 3a. Define Terraform Samples
Expand All @@ -90,6 +91,7 @@ TERRAFORM_SAMPLES=(
"samples/web-app-cosmosdb-mongodb-api/python/terraform|bash deploy.sh"
"samples/web-app-managed-identity/python/terraform|bash deploy.sh"
"samples/web-app-sql-database/python/terraform|bash deploy.sh"
"samples/web-app-postgresql-database/python/terraform|bash deploy.sh"
)

# 3b. Define Bicep Samples
Expand All @@ -99,6 +101,7 @@ BICEP_SAMPLES=(
"samples/function-app-storage-http/dotnet/bicep|bash deploy.sh"
"samples/web-app-cosmosdb-mongodb-api/python/bicep|bash deploy.sh"
"samples/web-app-managed-identity/python/bicep|bash deploy.sh"
"samples/web-app-postgresql-database/python/bicep|bash deploy.sh"
)

# 4. Calculate Shard
Expand Down
10 changes: 8 additions & 2 deletions samples/function-app-storage-http/dotnet/scripts/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,14 @@ else
exit 1
fi

# Construct the storage connection string for LocalStack
STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=$STORAGE_ACCOUNT_NAME;AccountKey=$STORAGE_ACCOUNT_KEY;EndpointSuffix=core.windows.net"
# Retrieve the storage connection string from the CLI so it uses the correct
# endpoints for the current environment (LocalStack or Azure).
echo "Getting storage connection string for [$STORAGE_ACCOUNT_NAME]..."
STORAGE_CONNECTION_STRING=$($AZ storage account show-connection-string \
--name $STORAGE_ACCOUNT_NAME \
--resource-group $RESOURCE_GROUP_NAME \
--query connectionString \
--output tsv)

# Set function app settings
echo "Setting function app settings for [$FUNCTION_APP_NAME]..."
Expand Down
206 changes: 206 additions & 0 deletions samples/web-app-postgresql-database/python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
# Azure Database for PostgreSQL Flexible Server

This sample demonstrates a Notes web application with full-text search, powered by [Azure Database for PostgreSQL Flexible Server](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/overview). The app is a Python Flask single-page application that creates, searches, and deletes notes stored in the `notes` table within the `sampledb` database on a PostgreSQL Flexible Server instance. The sample also includes Python and C# Azure SDK management demos that exercise server, database, configuration, and firewall rule operations.

## Architecture

The following diagram illustrates the architecture of the solution:

```mermaid
graph TB
subgraph IaC["Infrastructure as Code"]
CLI["Azure CLI<br/>(azlocal)"]
Bicep["Bicep<br/>(main.bicep)"]
TF["Terraform<br/>(main.tf)"]
end

subgraph LS["LocalStack for Azure"]
MGMT["Management API<br/>(ARM / REST)"]
PG_SERVER["PostgreSQL Flexible Server"]
subgraph DBs["Databases"]
SAMPLEDB["sampledb"]
ANALYTICSDB["analyticsdb"]
end
FW["Firewall Rules<br/>allow-all · corporate · vpn"]
end

subgraph DC["Docker Compose Containers"]
NOTES["Notes App<br/>(Flask · port 5001)"]
SDK_PY["Python SDK Demo<br/>(azure-mgmt-postgresql)"]
SDK_CS["C# SDK Demo<br/>(Azure.ResourceManager)"]
end

USER((User<br/>Browser))

CLI -->|provision| MGMT
Bicep -->|provision| MGMT
TF -->|provision| MGMT
MGMT --> PG_SERVER
PG_SERVER --> DBs
PG_SERVER --> FW

USER -->|"http://localhost:5001"| NOTES
NOTES <-->|"psycopg2 · CRUD + full-text search"| SAMPLEDB

SDK_PY -->|"management plane<br/>list servers · configs · DBs · rules"| MGMT
SDK_PY -->|"psycopg2 · direct query"| SAMPLEDB
SDK_PY -->|"POST results to UI"| NOTES

SDK_CS -->|"management plane<br/>ArmClient · list · get"| MGMT
SDK_CS -->|"Npgsql · direct query"| SAMPLEDB
SDK_CS -->|"POST results to UI"| NOTES

USER -.->|"trigger SDK demo"| NOTES
NOTES -.->|"trigger signal"| SDK_PY
NOTES -.->|"trigger signal"| SDK_CS
```

- **Azure Database for PostgreSQL Flexible Server**: Managed PostgreSQL database server hosting the `sampledb` and `analyticsdb` databases
- **Notes App (Flask)**: Python Flask web application with full-text search using PostgreSQL `tsvector`
- **Python SDK Demo**: Demonstrates `azure-mgmt-postgresqlflexibleservers` management operations (list servers, get/update configurations, list databases, manage firewall rules, check name availability)
- **C# SDK Demo**: Demonstrates `Azure.ResourceManager.PostgreSql` management operations from .NET

## Prerequisites

- [Azure Subscription](https://azure.microsoft.com/free/)
- [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli)
- [Python 3.12+](https://www.python.org/downloads/)
- [Docker](https://docs.docker.com/get-docker/)
- [Bicep extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-bicep), if you plan to install the sample via Bicep.
- [Terraform](https://developer.hashicorp.com/terraform/downloads), if you plan to install the sample via Terraform.

## Deployment

Set up the Azure emulator using the LocalStack for Azure Docker image. Before starting, ensure you have a valid `LOCALSTACK_AUTH_TOKEN` to access the Azure emulator. Refer to the [Auth Token guide](https://docs.localstack.cloud/getting-started/auth-token/) to obtain your Auth Token and set it in the `LOCALSTACK_AUTH_TOKEN` environment variable. The Azure Docker image is available on the [LocalStack Docker Hub](https://hub.docker.com/r/localstack/localstack-azure-alpha). To pull the image, execute:

```bash
docker pull localstack/localstack-azure-alpha
```

Start the LocalStack Azure emulator by running:

```bash
export LOCALSTACK_AUTH_TOKEN=<your_auth_token>
IMAGE_NAME=localstack/localstack-azure-alpha localstack start
```

Deploy the application to LocalStack for Azure using one of these methods:

- [Azure CLI Deployment](./scripts/README.md)
- [Bicep Deployment](./bicep/README.md)
- [Terraform Deployment](./terraform/README.md)

All deployment methods have been fully tested against Azure and the LocalStack for Azure local emulator.

> **Note**
> When you deploy the application to LocalStack for Azure for the first time, the initialization process involves downloading and building Docker images. This is a one-time operation—subsequent deployments will be significantly faster. Depending on your internet connection and system resources, this initial setup may take several minutes.

## Test

After provisioning the PostgreSQL Flexible Server infrastructure using any of the deployment methods above, launch the application containers using Docker Compose:

```bash
cd samples/postgresql-flexible-server/python

# Set environment variables (adjust values based on your deployment outputs)
export RESOURCE_GROUP="rg-pgflex"
export SERVER_NAME="pgflex-sample"
export PG_HOST="host.docker.internal"
export PG_PORT="5432"
export PG_USER="pgadmin"
export PG_PASSWORD="P@ssw0rd12345!"
export PG_DATABASE="sampledb"
export FLASK_PORT="5001"

docker compose up --build
```

Open a web browser and navigate to `http://localhost:5001`. If the deployment was successful, you will see the Notes application with full-text search and Azure SDK demo panels.

You can use the `validate.sh` Bash script below to verify that all Azure resources were created and configured correctly:

```bash
#!/bin/bash

# Variables
RESOURCE_GROUP='rg-pgflex'
SERVER_NAME='pgflex-sample'
PRIMARY_DB='sampledb'
SECONDARY_DB='analyticsdb'
ENVIRONMENT=$(az account show --query environmentName --output tsv)

# Choose the appropriate CLI based on the environment
if [[ $ENVIRONMENT == "LocalStack" ]]; then
echo "Using azlocal for LocalStack emulator environment."
AZ="azlocal"
else
echo "Using standard az for AzureCloud environment."
AZ="az"
fi

# Check resource group
echo "=== Resource Group ==="
$AZ group show \
--name "$RESOURCE_GROUP" \
--output table

# List resources in the resource group
echo ""
echo "=== Resources ==="
$AZ resource list \
--resource-group "$RESOURCE_GROUP" \
--output table

# Check PostgreSQL Flexible Server
echo ""
echo "=== PostgreSQL Flexible Server ==="
$AZ postgres flexible-server show \
--name "$SERVER_NAME" \
--resource-group "$RESOURCE_GROUP" \
--output table

# List databases
echo ""
echo "=== Databases ==="
$AZ postgres flexible-server db list \
--server-name "$SERVER_NAME" \
--resource-group "$RESOURCE_GROUP" \
--output table

# List firewall rules
echo ""
echo "=== Firewall Rules ==="
$AZ postgres flexible-server firewall-rule list \
--server-name "$SERVER_NAME" \
--resource-group "$RESOURCE_GROUP" \
--output table
```

## PostgreSQL Tooling

You can use [pgAdmin](https://www.pgadmin.org/) to explore and manage your PostgreSQL databases. When connecting, specify `localhost` as the host and use the port published by the PostgreSQL container on the host, mapped to the internal PostgreSQL port `5432`.

Alternatively, you can use the [psql](https://www.postgresql.org/docs/current/app-psql.html) command-line tool to interact with and administer your PostgreSQL instance, as shown below:

```bash
~$ psql -h localhost -p 49114 -U pgadmin -d sampledb
Password for user pgadmin:
psql (16.0)
Type "help" for help.

sampledb=# SELECT id, title, SUBSTRING(content, 1, 30) FROM notes;
id | title | substring
----+----------------+--------------------------------
1 | Meeting Notes | Discussed Q4 planning and bud
2 | Shopping List | Eggs, milk, bread, butter, ch
3 | Project Ideas | Build a notes app with full-te
(3 rows)
```

## References

- [Azure Database for PostgreSQL Flexible Server](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/overview)
- [Azure CLI — PostgreSQL Flexible Server](https://learn.microsoft.com/en-us/cli/azure/postgres/flexible-server)
- [Terraform — azurerm_postgresql_flexible_server](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/postgresql_flexible_server)
- [Azure Identity Client Library for Python](https://learn.microsoft.com/en-us/python/api/overview/azure/identity-readme?view=azure-python)
- [LocalStack for Azure](https://azure.localstack.cloud/)
124 changes: 124 additions & 0 deletions samples/web-app-postgresql-database/python/bicep/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# Bicep Deployment

This directory contains the Bicep template and a deployment script for provisioning Azure Database for PostgreSQL Flexible Server resources in LocalStack for Azure. Refer to the [Azure Database for PostgreSQL Flexible Server](../README.md) guide for details about the sample application.

## Prerequisites

Before deploying this solution, ensure you have the following tools installed:

- [LocalStack for Azure](https://azure.localstack.cloud/): Local Azure cloud emulator for development and testing
- [Visual Studio Code](https://code.visualstudio.com/): Code editor installed on one of the [supported platforms](https://code.visualstudio.com/docs/supporting/requirements#_platforms)
- [Bicep extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-bicep): VS Code extension for Bicep language support and IntelliSense
- [Docker](https://docs.docker.com/get-docker/): Container runtime required for LocalStack
- [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli): Azure command-line interface
- [azlocal CLI](https://azure.localstack.cloud/user-guides/sdks/az/): LocalStack Azure CLI wrapper
- [Python](https://www.python.org/downloads/): Python runtime (version 3.12 or above)
- [jq](https://jqlang.org/): JSON processor for scripting and parsing command outputs

### Installing azlocal CLI

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

```bash
pip install azlocal
```

For more information, see [Get started with the az tool on LocalStack](https://azure.localstack.cloud/user-guides/sdks/az/).

## Architecture Overview

The [deploy.sh](deploy.sh) script creates the [Azure Resource Group](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/manage-resource-groups-cli) for all the Azure resources, while the [main.bicep](main.bicep) Bicep module creates the following Azure resources:

1. [Azure Database for PostgreSQL Flexible Server](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/overview): Managed PostgreSQL database server with version 16.
2. [PostgreSQL Database](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/concepts-servers): The `sampledb` database for the Notes application.
3. [Firewall Rule](https://learn.microsoft.com/en-us/azure/postgresql/flexible-server/concepts-firewall-rules): Allows access from all IP addresses for development.

For more information, see [Azure Database for PostgreSQL Flexible Server](../README.md).

## Deployment

You can set up the Azure emulator by utilizing LocalStack for Azure Docker image. Before starting, ensure you have a valid `LOCALSTACK_AUTH_TOKEN` to access the Azure emulator. Refer to the [Auth Token guide](https://docs.localstack.cloud/getting-started/auth-token/) to obtain your Auth Token and specify it in the `LOCALSTACK_AUTH_TOKEN` environment variable. The Azure Docker image is available on the [LocalStack Docker Hub](https://hub.docker.com/r/localstack/localstack-azure-alpha). To pull the Azure Docker image, execute the following command:

```bash
docker pull localstack/localstack-azure-alpha
```

Start the LocalStack Azure emulator using the localstack CLI, execute the following command:

```bash
export LOCALSTACK_AUTH_TOKEN=<your_auth_token>
IMAGE_NAME=localstack/localstack-azure-alpha localstack start
```

Navigate to the `bicep` folder:

```bash
cd samples/postgresql-flexible-server/python/bicep
```

Make the script executable:

```bash
chmod +x deploy.sh
```

Run the deployment script:

```bash
./deploy.sh
```

## Validation

After deployment, you can use the `validate.sh` script to verify that all resources were created and configured correctly:

```bash
#!/bin/bash

# Variables
ENVIRONMENT=$(az account show --query environmentName --output tsv)

# Choose the appropriate CLI based on the environment
if [[ $ENVIRONMENT == "LocalStack" ]]; then
echo "Using azlocal for LocalStack emulator environment."
AZ="azlocal"
else
echo "Using standard az for AzureCloud environment."
AZ="az"
fi

# Check resource group
$AZ group show \
--name rg-pgflex-bicep \
--output table

# List resources
$AZ resource list \
--resource-group rg-pgflex-bicep \
--output table

# Check PostgreSQL Flexible Server
$AZ postgres flexible-server list \
--resource-group rg-pgflex-bicep \
--output table
```

## Cleanup

To destroy all created resources:

```bash
# Delete resource group and all contained resources
azlocal group delete --name rg-pgflex-bicep --yes --no-wait

# Verify deletion
azlocal group list --output table
```

This will remove all Azure resources created by the Bicep deployment script.

## Related Documentation

- [Azure Bicep Documentation](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/)
- [Bicep Language Reference](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-functions)
- [LocalStack for Azure Documentation](https://azure.localstack.cloud/)
Loading