Azure Static Proxy Configuration

Configure Microsoft Azure services through static SSL proxy IPs for security compliance and IP whitelisting requirements

Azure Functions Azure Storage Azure SQL Network Security Groups

Overview

Microsoft Azure services often require static IP addresses for security compliance, IP whitelisting, and network security requirements. This guide demonstrates how to configure various Azure services to work through your OutboundGateway static SSL proxy IPs.

Key Benefits: Fixed IP addresses for compliance, simplified Network Security Group rules, enhanced security for outbound traffic, and better control over Azure service access.

Prerequisites

Required Accounts & Tools

  • Active OutboundGateway subscription with static IP credentials
  • Azure subscription with appropriate permissions
  • Azure CLI installed and configured
  • Python 3.8+ with Azure SDK for Python
  • Node.js 14+ with Azure SDK for JavaScript (optional)

Install Azure CLI

# Install Azure CLI
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

# Login to Azure
az login

# Set subscription
az account set --subscription "Your-Subscription-ID"

Azure Functions with Static Proxy

Python Azure Function Example

# __init__.py
import logging
import azure.functions as func
import requests
import os
import json

# Proxy configuration from application settings
PROXY_HOST = os.environ.get('PROXY_HOST', '192.168.1.100')
PROXY_PORT = os.environ.get('PROXY_PORT', '8080')
PROXY_USER = os.environ.get('PROXY_USER', 'your_proxy_username')
PROXY_PASS = os.environ.get('PROXY_PASS', 'your_proxy_password')

def create_proxy_session():
    """Create requests session with SSL proxy configuration"""
    session = requests.Session()
    proxy_url = f'https://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}'
    session.proxies = {
        'https': proxy_url
    }
    return session

app = func.FunctionApp()

@app.route(route="api-proxy", auth_level=func.AuthLevel.ANONYMOUS)
def api_proxy_handler(req: func.HttpRequest) -> func.HttpResponse:
    """HTTP trigger that makes API calls through static proxy"""

    logging.info('Python HTTP trigger function processed a request.')

    # Set CORS headers
    headers = {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type',
    }

    # Handle preflight requests
    if req.method == 'OPTIONS':
        return func.HttpResponse("", status_code=204, headers=headers)

    try:
        session = create_proxy_session()

        # Get request parameters
        api_url = req.params.get('url', 'https://api.example.com/data')
        method = req.method.upper()

        # Make API call through proxy
        if method == 'GET':
            response = session.get(api_url, timeout=30)
        elif method == 'POST':
            request_body = req.get_json()
            response = session.post(api_url, json=request_body, timeout=30)
        else:
            response = session.request(method, api_url, timeout=30)

        response_data = {
            'success': True,
            'api_url': api_url,
            'method': method,
            'status_code': response.status_code,
            'proxy_used': f'{PROXY_HOST}:{PROXY_PORT}',
            'data': response.json() if response.headers.get('content-type', '').startswith('application/json') else response.text
        }

        return func.HttpResponse(
            json.dumps(response_data),
            status_code=200,
            headers={**headers, 'Content-Type': 'application/json'}
        )

    except Exception as e:
        logging.error(f"Error processing request: {str(e)}")
        error_response = {
            'success': False,
            'error': str(e),
            'proxy_used': f'{PROXY_HOST}:{PROXY_PORT}'
        }

        return func.HttpResponse(
            json.dumps(error_response),
            status_code=500,
            headers={**headers, 'Content-Type': 'application/json'}
        )

@app.queue_trigger(arg_name="msg", queue_name="proxy-queue", connection="AzureWebJobsStorage")
def queue_trigger_handler(msg: func.Out[str]) -> None:
    """Queue trigger that processes messages through proxy"""

    try:
        session = create_proxy_session()

        # Process the queue message
        message_data = json.loads(msg.get_body())

        # Example: Make webhook call through proxy
        webhook_url = 'https://webhook.example.com/processing'
        response = session.post(
            webhook_url,
            json=message_data,
            headers={'Content-Type': 'application/json'},
            timeout=30
        )

        logging.info(f"Webhook sent successfully through proxy. Status: {response.status_code}")

        # Send response to output queue
        output_message = json.dumps({
            'status': 'success',
            'message': 'Processed successfully through proxy',
            'proxy_used': f'{PROXY_HOST}:{PROXY_PORT}',
            'original_message': message_data
        })
        msg.set(output_message)

    except Exception as e:
        logging.error(f"Error processing queue message: {str(e)}")
        error_message = json.dumps({
            'status': 'error',
            'error': str(e),
            'proxy_used': f'{PROXY_HOST}:{PROXY_PORT}'
        })
        msg.set(error_message)

requirements.txt

azure-functions
requests==2.31.0

host.json

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  },
  "functionTimeout": "00:05:00"
}

local.settings.json

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "PROXY_HOST": "192.168.1.100",
    "PROXY_PORT": "8080",
    "PROXY_USER": "your_proxy_username",
    "PROXY_PASS": "your_proxy_password"
  }
}

Deploy Azure Function

# Create resource group
az group create --name OutboundGatewayRG --location eastus

# Create storage account
az storage account create \
    --name proxyflowstorage \
    --location eastus \
    --resource-group OutboundGatewayRG \
    --sku Standard_LRS

# Create function app
az functionapp create \
    --resource-group OutboundGatewayRG \
    --consumption-plan-location eastus \
    --runtime python \
    --runtime-version 3.9 \
    --functions-version 4 \
    --name proxyflow-function-app \
    --storage-account proxyflowstorage

# Configure application settings
az functionapp config appsettings set \
    --name proxyflow-function-app \
    --resource-group OutboundGatewayRG \
    --settings PROXY_HOST=192.168.1.100 PROXY_PORT=8080 PROXY_USER=your_proxy_username PROXY_PASS=your_proxy_password

# Deploy function
func azure functionapp publish proxyflow-function-app

Azure Storage with Static Proxy

Python Example with Azure Storage SDK

from azure.storage.blob import BlobServiceClient
from azure.storage.queue import QueueServiceClient
from azure.identity import DefaultAzureCredential
import os

# Proxy configuration
PROXY_HOST = "192.168.1.100"  # Your static IP
PROXY_PORT = 8080
PROXY_USER = "your_proxy_username"
PROXY_PASS = "your_proxy_password"

class ProxyAzureStorageClient:
    def __init__(self, account_name, account_key=None, connection_string=None):
        """Initialize Azure Storage client with proxy configuration"""

        # Set SSL proxy environment variables
        os.environ['HTTPS_PROXY'] = f'https://{PROXY_USER}:{PROXY_PASS}@{PROXY_HOST}:{PROXY_PORT}'

        if connection_string:
            self.blob_client = BlobServiceClient.from_connection_string(connection_string)
            self.queue_client = QueueServiceClient.from_connection_string(connection_string)
        elif account_name and account_key:
            account_url = f"https://{account_name}.blob.core.windows.net"
            self.blob_client = BlobServiceClient(
                account_url=account_url,
                credential=account_key
            )

            queue_url = f"https://{account_name}.queue.core.windows.net"
            self.queue_client = QueueServiceClient(
                account_url=queue_url,
                credential=account_key
            )
        else:
            # Use DefaultAzureCredential (Managed Identity, Service Principal, etc.)
            account_url = f"https://{account_name}.blob.core.windows.net"
            self.blob_client = BlobServiceClient(
                account_url=account_url,
                credential=DefaultAzureCredential()
            )

            queue_url = f"https://{account_name}.queue.core.windows.net"
            self.queue_client = QueueServiceClient(
                account_url=queue_url,
                credential=DefaultAzureCredential()
            )

    def upload_blob(self, container_name, blob_name, file_path):
        """Upload blob to Azure Storage through proxy"""
        try:
            blob_client = self.blob_client.get_blob_client(container=container_name, blob=blob_name)

            with open(file_path, 'rb') as data:
                blob_client.upload_blob(data, overwrite=True)

            print(f"File {file_path} uploaded to {container_name}/{blob_name}")
            return True

        except Exception as e:
            print(f"Upload failed: {e}")
            return False

    def download_blob(self, container_name, blob_name, download_path):
        """Download blob from Azure Storage through proxy"""
        try:
            blob_client = self.blob_client.get_blob_client(container=container_name, blob=blob_name)

            with open(download_path, 'wb') as download_file:
                download_file.write(blob_client.download_blob().readall())

            print(f"Blob {container_name}/{blob_name} downloaded to {download_path}")
            return True

        except Exception as e:
            print(f"Download failed: {e}")
            return False

    def list_blobs(self, container_name):
        """List blobs in container through proxy"""
        try:
            container_client = self.blob_client.get_container_client(container=container_name)
            blob_list = []

            for blob in container_client.list_blobs():
                blob_list.append({
                    'name': blob.name,
                    'size': blob.size,
                    'last_modified': blob.last_modified,
                    'content_type': blob.content_settings.content_type if blob.content_settings else None
                })

            return blob_list

        except Exception as e:
            print(f"List blobs failed: {e}")
            return []

    def send_queue_message(self, queue_name, message):
        """Send message to Azure Queue through proxy"""
        try:
            queue_client = self.queue_client.get_queue_client(queue=queue_name)
            queue_client.send_message(message)
            print(f"Message sent to queue {queue_name}")
            return True

        except Exception as e:
            print(f"Send message failed: {e}")
            return False

    def receive_queue_messages(self, queue_name, num_messages=1):
        """Receive messages from Azure Queue through proxy"""
        try:
            queue_client = self.queue_client.get_queue_client(queue=queue_name)
            messages = queue_client.receive_messages(messages_per_page=num_messages)

            message_list = []
            for msg in messages:
                message_list.append({
                    'id': msg.id,
                    'content': msg.content,
                    'insertion_time': msg.insertion_time,
                    'expiration_time': msg.expiration_time
                })

            return message_list

        except Exception as e:
            print(f"Receive messages failed: {e}")
            return []

# Usage example
def main():
    # Initialize with connection string
    storage_client = ProxyAzureStorageClient(
        connection_string="DefaultEndpointsProtocol=https;AccountName=yourstorageaccount;AccountKey=youraccountkey;EndpointSuffix=core.windows.net"
    )

    # Upload a file
    success = storage_client.upload_blob(
        container_name="your-container",
        blob_name="test-file.txt",
        file_path="local-file.txt"
    )

    if success:
        # List blobs
        blobs = storage_client.list_blobs("your-container")
        print(f"Found {len(blobs)} blobs in container")
        for blob in blobs:
            print(f"  - {blob['name']} ({blob['size']} bytes)")

        # Send queue message
        storage_client.send_queue_message(
            queue_name="your-queue",
            message="Hello from Azure Storage through proxy!"
        )

if __name__ == '__main__':
    main()

Node.js Example with @azure/storage-blob

const { BlobServiceClient } = require('@azure/storage-blob');
const { QueueServiceClient } = require('@azure/storage-queue');
const { HttpsProxyAgent } = require('https-proxy-agent');

// SSL Proxy configuration
const proxyUrl = 'https://your_proxy_username:your_proxy_password@192.168.1.100:8080';
const proxyAgent = new HttpsProxyAgent(proxyUrl);

class ProxyAzureStorageClient {
    constructor(connectionString) {
        this.connectionString = connectionString;

        // Create service clients with proxy configuration
        this.blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
        this.queueServiceClient = QueueServiceClient.fromConnectionString(connectionString);

        // Configure proxy for all HTTP requests
        this.configureProxy();
    }

    configureProxy() {
        // Override the default HTTP agent to use proxy
        const originalRequest = this.blobServiceClient.pipeline.sendRequest;

        this.blobServiceClient.pipeline.sendRequest = async (request) => {
            request.agent = proxyAgent;
            return originalRequest.call(this.blobServiceClient.pipeline, request);
        };

        // Same for queue service
        const originalQueueRequest = this.queueServiceClient.pipeline.sendRequest;
        this.queueServiceClient.pipeline.sendRequest = async (request) => {
            request.agent = proxyAgent;
            return originalQueueRequest.call(this.queueServiceClient.pipeline, request);
        };
    }

    async uploadBlob(containerName, blobName, filePath) {
        try {
            const containerClient = this.blobServiceClient.getContainerClient(containerName);
            const blockBlobClient = containerClient.getBlockBlobClient(blobName);

            await blockBlobClient.uploadFile(filePath, {
                blobHTTPHeaders: { blobContentType: 'text/plain' }
            });

            console.log(`File ${filePath} uploaded to ${containerName}/${blobName}`);
            return true;
        } catch (error) {
            console.error('Upload failed:', error);
            return false;
        }
    }

    async downloadBlob(containerName, blobName, downloadPath) {
        try {
            const containerClient = this.blobServiceClient.getContainerClient(containerName);
            const blockBlobClient = containerClient.getBlockBlobClient(blobName);

            await blockBlobClient.downloadToFile(downloadPath);
            console.log(`Blob ${containerName}/${blobName} downloaded to ${downloadPath}`);
            return true;
        } catch (error) {
            console.error('Download failed:', error);
            return false;
        }
    }

    async listBlobs(containerName) {
        try {
            const containerClient = this.blobServiceClient.getContainerClient(containerName);
            const blobList = [];

            for await (const blob of containerClient.listBlobsFlat()) {
                blobList.push({
                    name: blob.name,
                    size: blob.properties.contentLength,
                    lastModified: blob.properties.lastModified,
                    contentType: blob.properties.contentType
                });
            }

            return blobList;
        } catch (error) {
            console.error('List blobs failed:', error);
            return [];
        }
    }

    async sendMessage(queueName, message) {
        try {
            const queueClient = this.queueServiceClient.getQueueClient(queueName);
            await queueClient.sendMessage(message);
            console.log(`Message sent to queue ${queueName}`);
            return true;
        } catch (error) {
            console.error('Send message failed:', error);
            return false;
        }
    }

    async receiveMessages(queueName, numMessages = 1) {
        try {
            const queueClient = this.queueServiceClient.getQueueClient(queueName);
            const receivedMessages = await queueClient.receiveMessages({ numMessages });

            const messageList = receivedMessages.map(msg => ({
                id: msg.messageId,
                content: msg.messageText,
                insertionTime: msg.insertionTime,
                expirationTime: msg.expirationTime,
                popReceipt: msg.popReceipt
            }));

            return messageList;
        } catch (error) {
            console.error('Receive messages failed:', error);
            return [];
        }
    }
}

// Usage example
async function main() {
    const connectionString = "DefaultEndpointsProtocol=https;AccountName=yourstorageaccount;AccountKey=youraccountkey;EndpointSuffix=core.windows.net";
    const storageClient = new ProxyAzureStorageClient(connectionString);

    // Upload a file
    const uploadSuccess = await storageClient.uploadBlob(
        'your-container',
        'test-file.txt',
        'local-file.txt'
    );

    if (uploadSuccess) {
        // List blobs
        const blobs = await storageClient.listBlobs('your-container');
        console.log(`Found ${blobs.length} blobs in container`);
        blobs.forEach(blob => {
            console.log(`  - ${blob.name} (${blob.size} bytes)`);
        });

        // Send queue message
        await storageClient.sendMessage(
            'your-queue',
            'Hello from Azure Storage through proxy!'
        );
    }
}

main().catch(console.error);

Azure SQL Database with Static Proxy

Python Example with pyodbc

import pyodbc
import ssl

# Proxy and database configuration
PROXY_HOST = "192.168.1.100"  # Your static IP
PROXY_PORT = 8080
PROXY_USER = "your_proxy_username"
PROXY_PASS = "your_proxy_password"

# Azure SQL Database configuration
SQL_SERVER = "your-server.database.windows.net"
SQL_DATABASE = "your-database"
SQL_USER = "your-sql-user"
SQL_PASS = "your-sql-password"

class ProxyAzureSQLClient:
    def __init__(self):
        """Initialize Azure SQL client with proxy configuration"""
        self.connection_string = self._build_connection_string()

    def _build_connection_string(self):
        """Build connection string with proxy support"""
        return (
            f"DRIVER={ODBC Driver 18 for SQL Server};"
            f"SERVER={PROXY_HOST},{PROXY_PORT};"
            f"DATABASE={SQL_DATABASE};"
            f"UID={SQL_USER};"
            f"PWD={SQL_PASS};"
            f"Encrypt=yes;"
            f"TrustServerCertificate=no;"
            f"Connection Timeout=30;"
            f"Server={SQL_SERVER};"  # Add actual server as part of connection string
        )

    def test_connection(self):
        """Test database connection through proxy"""
        try:
            # Configure SSL context
            ssl_context = ssl.create_default_context()
            ssl_context.check_hostname = False
            ssl_context.verify_mode = ssl.CERT_NONE

            # Test connection
            connection = pyodbc.connect(
                self.connection_string,
                attrs_before={pyodbc.SQL_ATTR_SSL_CTX: ssl_context}
            )

            cursor = connection.cursor()
            cursor.execute("SELECT @@VERSION")
            version = cursor.fetchone()[0]

            cursor.close()
            connection.close()

            print(f"Successfully connected to Azure SQL through proxy!")
            print(f"SQL Server version: {version}")
            return True

        except Exception as e:
            print(f"Connection failed: {e}")
            return False

    def execute_query(self, query, params=None):
        """Execute SQL query through proxy"""
        try:
            ssl_context = ssl.create_default_context()
            ssl_context.check_hostname = False
            ssl_context.verify_mode = ssl.CERT_NONE

            connection = pyodbc.connect(
                self.connection_string,
                attrs_before={pyodbc.SQL_ATTR_SSL_CTX: ssl_context}
            )

            cursor = connection.cursor()

            if params:
                cursor.execute(query, params)
            else:
                cursor.execute(query)

            # Check if query returns results
            if cursor.description:
                # Get column names
                columns = [column[0] for column in cursor.description]
                results = []

                # Fetch all rows
                rows = cursor.fetchall()
                for row in rows:
                    results.append(dict(zip(columns, row)))

                cursor.close()
                connection.close()

                return results
            else:
                # For INSERT, UPDATE, DELETE queries
                rows_affected = cursor.rowcount
                connection.commit()

                cursor.close()
                connection.close()

                return {'rows_affected': rows_affected}

        except Exception as e:
            print(f"Query execution failed: {e}")
            return None

    def create_sample_table(self):
        """Create a sample table for testing"""
        create_table_query = """
        IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='proxy_test_table' AND xtype='U')
        CREATE TABLE proxy_test_table (
            id INT IDENTITY(1,1) PRIMARY KEY,
            message NVARCHAR(255),
            created_at DATETIME DEFAULT GETDATE(),
            proxy_used NVARCHAR(100)
        )
        """

        result = self.execute_query(create_table_query)
        if result:
            print("Sample table created successfully")
            return True
        return False

    def insert_test_data(self, message):
        """Insert test data through proxy"""
        insert_query = """
        INSERT INTO proxy_test_table (message, proxy_used)
        VALUES (?, ?)
        """

        params = (message, f"{PROXY_HOST}:{PROXY_PORT}")
        result = self.execute_query(insert_query, params)

        if result and result.get('rows_affected', 0) > 0:
            print(f"Test data inserted successfully")
            return True
        return False

    def select_test_data(self):
        """Select test data through proxy"""
        select_query = """
        SELECT id, message, created_at, proxy_used
        FROM proxy_test_table
        ORDER BY created_at DESC
        """

        results = self.execute_query(select_query)
        if results:
            print(f"Found {len(results)} records:")
            for record in results:
                print(f"  ID: {record['id']}, Message: {record['message']}, Proxy: {record['proxy_used']}")

        return results

# Usage example
def main():
    sql_client = ProxyAzureSQLClient()

    # Test connection
    if sql_client.test_connection():
        # Create sample table
        sql_client.create_sample_table()

        # Insert test data
        sql_client.insert_test_data("Hello from Azure SQL through static proxy!")

        # Select and display data
        sql_client.select_test_data()

if __name__ == '__main__':
    main()

Network Security Groups Configuration

Create NSG Rules for Static IPs

# Create Network Security Group
az network nsg create \
    --resource-group OutboundGatewayRG \
    --name proxyflow-nsg \
    --location eastus

# Create NSG rule to allow traffic from your static IP
az network nsg rule create \
    --resource-group OutboundGatewayRG \
    --nsg-name proxyflow-nsg \
    --name allow-proxyflow-static-ips \
    --protocol Tcp \
    --direction Inbound \
    --priority 1000 \
    --source-address-prefixes 192.168.1.100/32 192.168.1.101/32 \
    --source-port-ranges '*' \
    --destination-address-prefixes '*' \
    --destination-port-ranges 8080 443 80 \
    --access Allow \
    --description "Allow traffic from OutboundGateway static IPs"

# Create rule to allow all traffic from static IPs (less restrictive)
az network nsg rule create \
    --resource-group OutboundGatewayRG \
    --nsg-name proxyflow-nsg \
    --name allow-proxyflow-all \
    --protocol '*' \
    --direction Inbound \
    --priority 1001 \
    --source-address-prefixes 192.168.1.100/32 192.168.1.101/32 \
    --source-port-ranges '*' \
    --destination-address-prefixes '*' \
    --destination-port-ranges '*' \
    --access Allow \
    --description "Allow all traffic from OutboundGateway static IPs"

# List NSG rules
az network nsg rule list \
    --resource-group OutboundGatewayRG \
    --nsg-name proxyflow-nsg \
    --output table

# Associate NSG with a subnet
az network vnet subnet update \
    --resource-group OutboundGatewayRG \
    --vnet-name your-vnet \
    --name your-subnet \
    --network-security-group proxyflow-nsg

Configure Virtual Network and Subnets

# Create Virtual Network
az network vnet create \
    --resource-group OutboundGatewayRG \
    --name proxyflow-vnet \
    --address-prefix 10.0.0.0/16 \
    --subnet-name default \
    --subnet-prefix 10.0.0.0/24 \
    --location eastus

# Create additional subnet for Azure Functions
az network vnet subnet create \
    --resource-group OutboundGatewayRG \
    --vnet-name proxyflow-vnet \
    --name functions-subnet \
    --address-prefix 10.0.1.0/24 \
    --delegations Microsoft.Web/serverfarms

# Associate NSG with subnets
az network vnet subnet update \
    --resource-group OutboundGatewayRG \
    --vnet-name proxyflow-vnet \
    --name default \
    --network-security-group proxyflow-nsg

az network vnet subnet update \
    --resource-group OutboundGatewayRG \
    --vnet-name proxyflow-vnet \
    --name functions-subnet \
    --network-security-group proxyflow-nsg

# List VNET and subnet details
az network vnet show \
    --resource-group OutboundGatewayRG \
    --name proxyflow-vnet \
    --output table

Managed Identity Configuration

Create and Configure Managed Identity

# Create User-Assigned Managed Identity
az identity create \
    --resource-group OutboundGatewayRG \
    --name proxyflow-identity

# Get identity details
IDENTITY_ID=$(az identity show \
    --resource-group OutboundGatewayRG \
    --name proxyflow-identity \
    --query id -o tsv)

IDENTITY_CLIENT_ID=$(az identity show \
    --resource-group OutboundGatewayRG \
    --name proxyflow-identity \
    --query clientId -o tsv)

echo "Identity ID: $IDENTITY_ID"
echo "Identity Client ID: $IDENTITY_CLIENT_ID"

# Assign Storage Blob Data Contributor role to identity
az role assignment create \
    --assignee $IDENTITY_ID \
    --role "Storage Blob Data Contributor" \
    --scope /subscriptions/your-subscription-id/resourceGroups/OutboundGatewayRG

# Assign Storage Queue Data Contributor role to identity
az role assignment create \
    --assignee $IDENTITY_ID \
    --role "Storage Queue Data Contributor" \
    --scope /subscriptions/your-subscription-id/resourceGroups/OutboundGatewayRG

# Assign SQL DB Contributor role to identity
az role assignment create \
    --assignee $IDENTITY_ID \
    --role "SQL DB Contributor" \
    --scope /subscriptions/your-subscription-id/resourceGroups/OutboundGatewayRG/providers/Microsoft.Sql/servers/your-server/databases/your-database

# Configure Azure Function with managed identity
az functionapp identity assign \
    --resource-group OutboundGatewayRG \
    --name proxyflow-function-app \
    --identities $IDENTITY_ID

# Configure application settings for managed identity
az functionapp config appsettings set \
    --resource-group OutboundGatewayRG \
    --name proxyflow-function-app \
    --settings AZURE_CLIENT_ID=$IDENTITY_CLIENT_ID

Troubleshooting

Proxy Connection Issues

If you experience proxy connection problems:

  • Verify static IP addresses are correctly configured in NSG rules
  • Check proxy credentials are active and properly formatted
  • Ensure proxy server is accessible from Azure resources
  • Test connectivity using Azure Function logs

Authentication and Authorization

For authentication issues:

  • Verify Azure AD permissions and role assignments
  • Check managed identity configuration and client ID
  • Ensure service principal has correct API permissions
  • Validate connection strings and credential storage

Network Configuration

For network-related issues:

  • Check VNET integration settings for Azure Functions
  • Verify NSG rule priorities and configurations
  • Ensure proper DNS resolution for proxy endpoints
  • Monitor Azure service health and availability

Performance Optimization

To improve performance:

  • Use connection pooling for database operations
  • Implement retry logic with exponential backoff
  • Monitor proxy bandwidth usage and latency
  • Consider Azure Front Door for global distribution

Ready to Configure Azure with Static IPs?

Get your static SSL proxy IPs today and ensure your Microsoft Azure services maintain consistent IP addresses for compliance and security requirements.

Get Started with OutboundGateway