Skip to content

Commit

Permalink
Merge pull request #39 from Pwd9000-ML/v2.2.0-beta
Browse files Browse the repository at this point in the history
V2.2.0 beta
  • Loading branch information
Pwd9000-ML authored Jan 24, 2024
2 parents 3ba1cde + 0764026 commit 923fdc2
Show file tree
Hide file tree
Showing 14 changed files with 1,386 additions and 67 deletions.
1 change: 0 additions & 1 deletion 03_keyvault.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ resource "azurerm_key_vault" "az_openai_kv" {
depends_on = [azurerm_subnet.az_openai_subnet]
}


# Add "self" permission to key vault RBAC (to manange key vault secrets)
resource "azurerm_role_assignment" "kv_role_assigment" {
for_each = toset(["Key Vault Administrator"])
Expand Down
2 changes: 1 addition & 1 deletion 06_librechat_app.tf
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ resource "azurerm_app_service_custom_hostname_binding" "hostname_binding" {
app_service_name = var.libre_app_name
resource_group_name = azurerm_resource_group.az_openai_rg.name

depends_on = [azurerm_dns_cname_record.cname_record, azurerm_linux_web_app.librechat ]
depends_on = [azurerm_dns_cname_record.cname_record, azurerm_linux_web_app.librechat]
}

resource "azurerm_app_service_managed_certificate" "libre_app_cert" {
Expand Down
27 changes: 27 additions & 0 deletions 06_librechat_app_config.tf
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,33 @@ locals {
REFRESH_TOKEN_EXPIRY = (1000 * 60 * 60 * 24) * 5 #7 days
JWT_SECRET = var.libre_app_jwt_secret != null ? var.libre_app_jwt_secret : "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.libre_app_jwt_secret.id})"
JWT_REFRESH_SECRET = var.libre_app_jwt_refresh_secret != null ? var.libre_app_jwt_refresh_secret : "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.libre_app_jwt_refresh_secret.id})"

### User Violations ###
BAN_VIOLATIONS = var.libre_app_violations.enabled
BAN_DURATION = var.libre_app_violations.ban_duration
BAN_INTERVAL = var.libre_app_violations.ban_interval

LOGIN_VIOLATION_SCORE = var.libre_app_violations.login_violation_score
REGISTRATION_VIOLATION_SCORE = var.libre_app_violations.registration_violation_score
CONCURRENT_VIOLATION_SCORE = var.libre_app_violations.concurrent_violation_score
MESSAGE_VIOLATION_SCORE = var.libre_app_violations.message_violation_score
NON_BROWSER_VIOLATION_SCORE = var.libre_app_violations.non_browser_violation_score

LOGIN_MAX = var.libre_app_violations.login_max
LOGIN_WINDOW = var.libre_app_violations.login_window
REGISTER_MAX = var.libre_app_violations.register_max
REGISTER_WINDOW = var.libre_app_violations.register_window

LIMIT_CONCURRENT_MESSAGES = var.libre_app_violations.limit_concurrent_messages
CONCURRENT_MESSAGE_MAX = var.libre_app_violations.concurrent_message_max

LIMIT_MESSAGE_IP = var.libre_app_violations.limit_message_ip
MESSAGE_IP_MAX = var.libre_app_violations.message_ip_max
MESSAGE_IP_WINDOW = var.libre_app_violations.message_ip_window

LIMIT_MESSAGE_USER = var.libre_app_violations.limit_message_user
MESSAGE_USER_MAX = var.libre_app_violations.message_user_max
MESSAGE_USER_WINDOW = var.libre_app_violations.message_user_window
}
}

Expand Down
32 changes: 28 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,22 @@ New integrations and features have been added to the module to use the latest **

## Coming next - Feature development

- [x] Custom domain support with managed certificates (Released in v2.1.0)
### v2.3.x

- [ ] Privatise solution with Private endpoint support
- [ ] Front Door and WAF support for public entrypoint
- [ ] Azure AI Search/MeiliSearch Integration
- [ ] Add additional support for [Azure OpenAI DALL-E-3](https://docs.microsoft.com/en-us/azure/cognitive-services/openai-dall-e/overview)
- [ ] Updated documentation and examples

### v2.2.x

- [x] Added User Violations Support
- [x] Updated documentation and examples
- [x] Added module outputs

### v2.1.x

- [x] Custom domain support with managed certificates

## Legacy Version 1.x

Expand Down Expand Up @@ -51,9 +61,23 @@ coming soon...

## Examples

coming soon...
- [Public Deployment with Custom Domain and IP Whitelisting](https://github.com/Pwd9000-ML/terraform-azurerm-openai-private-chatgpt/tree/master/examples/public_deployment_with_custom_domain)

## Contributing

Contributions are welcome. Please submit a pull request if you have any improvements or fixes. Make sure to follow the existing code style and add comments to your code explaining what it does.

## License

This terraform module is licensed under the MIT License. See the LICENSE file for more details.

## Support

If you encounter any issues or have any questions about this terraform module, please open an issue on GitHub. We'll do our best to respond as quickly as possible.

## Acknowledgements

Enjoy!
This terraform module was developed by **Marcel Lupo** as part of a project to explore the capabilities of Azure OpenAI models. We'd like to thank the OpenAI and Microsoft team for their incredible work and ongoing support of the AI community.

<!-- BEGIN_TF_DOCS -->
## Requirements
Expand Down
File renamed without changes.
58 changes: 58 additions & 0 deletions examples/public_deployment_with_custom_domain/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Public Deployment with Custom Domain and IP Whitelisting

This example contains a Terraform script for provisioning a set of Azure resources for a chat application powered by Azure OpenAI models. The script is designed to be modular and configurable, allowing you to customise the resources and settings to fit your specific needs.

In this example the Chat App is deployed with a public endpoint, a custom domain name and managed certificate. The access to the app can be restricted to a set of whitelisted IP addresses or subnets using these variables:

```hcl
libre_app_virtual_network_subnet_id = null # Access is allowed on the built in subnet of this module. If networking is created as part of the module, this will be automatically populated if value is 'null' (priority 100)
libre_app_allowed_subnets = null # Add any other subnet ids to allow access to the app service (optional)
libre_app_allowed_ip_addresses = [
{
ip_address = "0.0.0.0/0" # (Change to your IP address or CIDR range)
priority = 200
name = "ip-access-rule1"
action = "Allow"
}
]
```

## Resources

The script provisions the following resources:

- **Random Integer**: This is used to generate unique names for the resources to avoid naming conflicts.
- **Resource Group**: This is the resource group that contains all the resources for the chat application.
- **Virtual Network**: This is the virtual network and subnet that contains the chat application and supporting resources.
- **Key Vault**: This is used to store secrets for the chat application, such as the OpenAI API key and other secrets used by the application.
- **OpenAI Service**: This is the core service that powers the chat application. It uses OpenAI's GPT-3 model to generate responses to user inputs.
- **CosmosDB Instance**: This is the database for the chat application. It stores user data and chat logs.
- **App Service**: This hosts the chat application. It's configured with various settings for networking, storage, and access control.

## Configuration

The script uses variables for configuration. These variables can be set in a `common.auto.tfvars` file or passed in via the command line when running `terraform apply`.

The variables include settings for the location, tags, resource group name, virtual network name, subnet configuration, key vault settings, OpenAI service settings, CosmosDB settings, and App Service settings.

## Usage

To use this script, you need to have Terraform installed. You can then clone this repository and run `terraform init` to initialize your Terraform workspace. Once the workspace is initialized, you can run `terraform apply` to create the resources.

Please note that you will need to provide values for all the required variables in the `common.auto.tfvars` file and defining the variables there, or by passing them in via the command line when running `terraform apply`.

## Contributing

Contributions are welcome. Please submit a pull request if you have any improvements or fixes. Make sure to follow the existing code style and add comments to your code explaining what it does.

## License

This script is licensed under the MIT License. See the LICENSE file for more details.

## Support

If you encounter any issues or have any questions about this script, please open an issue on GitHub. We'll do our best to respond as quickly as possible.

## Acknowledgements

This script was developed by **Marcel Lupo** as part of a project to explore the capabilities of Azure OpenAI models. We'd like to thank the OpenAI and Microsoft team for their incredible work and ongoing support of the AI community.
198 changes: 198 additions & 0 deletions examples/public_deployment_with_custom_domain/common.auto.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
### 01 Common Variables + RG ###
resource_group_name = "Private-ChatGPT-OpenAI-LibreChat-Example"
location = "SwedenCentral"
tags = {
Terraform = "True"
Description = "Private ChatGPT hosted on Azure OpenAI (Librechat)"
Author = "Marcel Lupo"
GitHub = "https://github.com/Pwd9000-ML/terraform-azurerm-openai-private-chatgpt"
}

### 02 networking ###
virtual_network_name = "demogptvnet"
vnet_address_space = ["10.3.0.0/24"]
subnet_config = {
subnet_name = "demogpt-sub"
subnet_address_space = ["10.3.0.0/24"]
service_endpoints = ["Microsoft.AzureCosmosDB", "Microsoft.Web", "Microsoft.KeyVault"]
private_endpoint_network_policies_enabled = false
private_link_service_network_policies_enabled = false
subnets_delegation_settings = {
app-service-plan = [
{
name = "Microsoft.Web/serverFarms"
actions = ["Microsoft.Network/virtualNetworks/subnets/action"]
}
]
}
}

### 03 KeyVault ###
kv_name = "demogptkv"
kv_sku = "standard"
kv_fw_default_action = "Deny"
kv_fw_bypass = "AzureServices"
kv_fw_allowed_ips = ["0.0.0.0/0"] # Allow all IPs (for demo purposes)
kv_fw_network_subnet_ids = null # leave null to allow access from default subnet of this module

### 04 Create OpenAI Service ###
oai_account_name = "demogptoai"
oai_sku_name = "S0"
oai_custom_subdomain_name = "demogptoai"
oai_dynamic_throttling_enabled = false
oai_fqdns = []
oai_local_auth_enabled = true
oai_outbound_network_access_restricted = false
oai_public_network_access_enabled = true
oai_customer_managed_key = null
oai_identity = {
type = "SystemAssigned"
}
oai_network_acls = null
oai_storage = null
oai_model_deployment = [
{
deployment_id = "gpt-35-turbo"
model_name = "gpt-35-turbo"
model_format = "OpenAI"
model_version = "1106"
scale_type = "Standard"
scale_capacity = 20 # 34K == Roughly 204 RPM (Requests per minute)
},
{
deployment_id = "gpt-4"
model_name = "gpt-4"
model_format = "OpenAI"
model_version = "1106-Preview"
scale_type = "Standard"
scale_capacity = 20
},
{
deployment_id = "gpt-4-vision-preview"
model_name = "gpt-4"
model_format = "OpenAI"
model_version = "vision-preview"
scale_type = "Standard"
scale_capacity = 5
},
{
deployment_id = "dall-e-3"
model_name = "dall-e-3"
model_format = "OpenAI"
model_version = "3.0"
scale_type = "Standard"
scale_capacity = 2
}
]

### 05 cosmosdb ###
cosmosdb_name = "demogptcosmosdb"
cosmosdb_offer_type = "Standard"
cosmosdb_kind = "MongoDB"
cosmosdb_automatic_failover = false
use_cosmosdb_free_tier = true
cosmosdb_consistency_level = "BoundedStaleness"
cosmosdb_max_interval_in_seconds = 10
cosmosdb_max_staleness_prefix = 200
cosmosdb_geo_locations = [
{
location = "SwedenCentral"
failover_priority = 0
}
]
cosmosdb_capabilities = ["EnableMongo", "MongoDBv3.4"]
cosmosdb_virtual_network_subnets = null # leave null to allow access from default subnet of this module
cosmosdb_is_virtual_network_filter_enabled = true
cosmosdb_public_network_access_enabled = true

### 06 app services (librechat app + meilisearch) ###
# App Service Plan
app_service_name = "demogptasp"
app_service_sku_name = "B1"

# LibreChat App Service
libre_app_name = "demogptchatapp"
libre_app_public_network_access_enabled = true
libre_app_virtual_network_subnet_id = null # Access is allowed on the built in subnet of this module. If networking is created as part of the module, this will be automatically populated if value is 'null' (priority 100)
libre_app_allowed_subnets = null # Add any other subnet ids to allow access to the app service (optional)
libre_app_allowed_ip_addresses = [
{
ip_address = "0.0.0.0/0" # Allow all IPs (for demo purposes)
priority = 200
name = "ip-access-rule1"
action = "Allow"
}
]

### LibreChat App Settings ###
# Server Config
libre_app_title = "PRIVATE DEMO CHATBOT"
libre_app_custom_footer = "Privately hosted GPT App powered by Azure OpenAI and LibreChat"
libre_app_host = "0.0.0.0"
libre_app_port = 80
libre_app_docker_image = "ghcr.io/danny-avila/librechat-dev-api:81ff598eba338e680c91e237cea3e3df870bce23" #v0.6.6 (Pre-release)
libre_app_mongo_uri = null # leave null to use the cosmosdb uri saved in keyvault created by this module
libre_app_domain_client = "http://localhost:80"
libre_app_domain_server = "http://localhost:80"

# debug logging
libre_app_debug_logging = true
libre_app_debug_console = false

# Endpoints
libre_app_endpoints = "azureOpenAI"

# Azure OpenAI
libre_app_az_oai_api_key = null # leave null to use the key saved in keyvault created by this module
libre_app_az_oai_models = "gpt-35-turbo,gpt-4,gpt-4-vision-preview"
libre_app_az_oai_use_model_as_deployment_name = true
libre_app_az_oai_instance_name = null # leave null to use the instance name created by this module
libre_app_az_oai_api_version = "2023-07-01-preview"
libre_app_az_oai_dall3_api_version = "2023-12-01-preview"
libre_app_az_oai_dall3_deployment_name = "dall-e-3"

# Plugins
libre_app_debug_plugins = true
libre_app_plugins_creds_key = null # leave null to use the key saved in keyvault created by this module
libre_app_plugins_creds_iv = null # leave null to use the iv saved in keyvault created by this module

# Search
libre_app_enable_meilisearch = false

# User Registration
libre_app_allow_email_login = true
libre_app_allow_registration = true
libre_app_allow_social_login = false
libre_app_allow_social_registration = false
libre_app_jwt_secret = null # leave null to use the secret saved in keyvault created by this module
libre_app_jwt_refresh_secret = null # leave null to use the refresh secret saved in keyvault created by this module

# violations
libre_app_violations = {
enabled = false
ban_duration = 1000 * 60 * 60 * 2
ban_interval = 20
login_violation_score = 1
registration_violation_score = 1
concurrent_violation_score = 1
message_violation_score = 1
non_browser_violation_score = 20
login_max = 7
login_window = 5
register_max = 5
register_window = 60
limit_concurrent_messages = false
concurrent_message_max = 2
limit_message_ip = false
message_ip_max = 40
message_ip_window = 1
limit_message_user = false
message_user_max = 40
message_user_window = 1
}

# Custom Domain and Managed Certificate (Optional)
libre_app_custom_domain_create = true
librechat_app_custom_domain_name = "privategptchatbot"
librechat_app_custom_dns_zone_name = "domain.com"
dns_resource_group_name = "DNS-Resource-Group-Name"
Loading

0 comments on commit 923fdc2

Please sign in to comment.