Skip to content
Draft
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
68 changes: 54 additions & 14 deletions .github/workflows/stack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,72 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Create stacks
id: create_stacks
run: |
set -euo pipefail
RELEASE=$(cat VERSION)

# oci-ods-aqua
STACKNAME=oci-ods-aqua
STACK_FILES="ai-quick-actions/policies/terraform/*"
RELEASE=$(cat VERSION)
ASSETS+="${STACKNAME}.zip"
echo "::group::Processing $STACKNAME"
zip -r ${STACKNAME}-stack.zip $STACK_FILES || { printf '\n⛔ Unable to create %s stack.\n'; exit 1; }
cp ${STACKNAME}-stack.zip ${STACKNAME}.zip || { printf '\n⛔ Unable to create %s stack.\n'; exit 1; }
zip -r ${STACKNAME}-stack.zip $STACK_FILES
cp ${STACKNAME}-stack.zip ${STACKNAME}.zip
echo "::endgroup::"

# ai-document-converter-app
DOC_CONVERTER_STACKNAME=ai-document-converter
DOC_CONVERTER_FILES="ai-hub/ai-document-converter/policies/terraform/*"
echo "::group::Packaging $DOC_CONVERTER_STACKNAME"
zip -r ${DOC_CONVERTER_STACKNAME}-stack.zip $DOC_CONVERTER_FILES
cp ${DOC_CONVERTER_STACKNAME}-stack.zip ${DOC_CONVERTER_STACKNAME}.zip
echo "::endgroup::"

# ai-translation-app
TRANSLATION_STACKNAME=ai-translation
TRANSLATION_FILES="ai-hub/ai-translation/policies/terraform/*"
echo "::group::Packaging $TRANSLATION_STACKNAME"
zip -r ${TRANSLATION_STACKNAME}-stack.zip $TRANSLATION_FILES
cp ${TRANSLATION_STACKNAME}-stack.zip ${TRANSLATION_STACKNAME}.zip
echo "::endgroup::"
echo "::set-output name=assets::$ASSETS"
echo "::set-output name=release::$RELEASE"
echo "::set-output name=prefix::$STACKNAME"

ASSETS="${STACKNAME}.zip ${DOC_CONVERTER_STACKNAME}.zip ${TRANSLATION_STACKNAME}.zip"

{
echo "assets=${ASSETS}"
echo "release=${RELEASE}"
echo "aqua=${STACKNAME}"
echo "ai_document_converter=${DOC_CONVERTER_STACKNAME}"
echo "ai_translation=${TRANSLATION_STACKNAME}"
} >> $GITHUB_OUTPUT

- name: Prepare Release Notes
shell: bash
run: |
#
printf '%s\n' '${{ steps.create_stacks.outputs.prefix }} Stack - v${{ steps.create_stacks.outputs.release }}' >release.md
printf '%s\n' '' '## [![Deploy to Oracle Cloud][magic_button]][magic_stack]' >>release.md
printf '%s\n' '' '' >>release.md
printf '%s\n' '' '[magic_button]: https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg' >>release.md
printf '%s\n' '' '[magic_stack]: https://cloud.oracle.com/resourcemanager/stacks/create?zipUrl=https://github.com/${{ github.repository }}/releases/download/${{ steps.create_stacks.outputs.release }}/${{ steps.create_stacks.outputs.prefix }}.zip' >>release.md
rel="${{ steps.create_stacks.outputs.release }}"
aqua="${{ steps.create_stacks.outputs.aqua }}"
ai_document_converter="${{ steps.create_stacks.outputs.ai_document_converter }}"
ai_translation="${{ steps.create_stacks.outputs.ai_translation }}"

{
printf '# Stacks - v%s\n\n' "$rel"
printf '### %s\n' "$aqua"
printf '## [![Deploy to Oracle Cloud][magic_button]][magic_stack_aqua]\n\n'

printf '### %s\n' "$ai_document_converter"
printf '## [![Deploy to Oracle Cloud][magic_button]][magic_stack_ai_document_converter]\n\n'

printf '### %s\n' "$ai_translation"
printf '## [![Deploy to Oracle Cloud][magic_button]][magic_stack_ai_translation]\n\n'

printf '[magic_button]: https://oci-resourcemanager-plugin.plugins.oci.oraclecloud.com/latest/deploy-to-oracle-cloud.svg\n'
printf '[magic_stack_aqua]: https://cloud.oracle.com/resourcemanager/stacks/create?zipUrl=https://github.com/${{ github.repository }}/releases/download/%s/%s.zip\n' "$rel" "$aqua"
printf '[magic_stack_ai_document_converter]: https://cloud.oracle.com/resourcemanager/stacks/create?zipUrl=https://github.com/${{ github.repository }}/releases/download/%s/%s.zip\n' "$rel" "$ai_document_converter"
printf '[magic_stack_ai_translation]: https://cloud.oracle.com/resourcemanager/stacks/create?zipUrl=https://github.com/${{ github.repository }}/releases/download/%s/%s.zip\n' "$rel" "$ai_translation"
} > release.md

- name: Create Release
run: gh release create ${{ steps.create_stacks.outputs.release }} --generate-notes -F release.md ${{ steps.create_stacks.outputs.assets }}
Expand Down
128 changes: 128 additions & 0 deletions ai-hub/ai-document-converter/policies/terraform/api_gateway.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# API Gateway
resource "oci_apigateway_gateway" "ai_application_oci_apigateway_gateway" {
compartment_id = var.compartment_id
display_name = "ai_application_api_gw_${random_string.randomstring.result}"
endpoint_type = "PUBLIC"
response_cache_details {
type = "NONE"
}
subnet_id = local.api_gw_subnet_id
}

# API Gateway Deployments
resource "oci_apigateway_deployment" "ai_application_apigateway_deployment" {
compartment_id = var.compartment_id
display_name = "api-deployment${random_string.randomstring.result}"
gateway_id = oci_apigateway_gateway.ai_application_oci_apigateway_gateway.id
path_prefix = "/"
specification {
logging_policies {
execution_log {
log_level = "INFO"
}
}
request_policies {
authentication {
is_anonymous_access_allowed = "true"
token_auth_scheme = "Bearer"
token_header = "token"
type = "TOKEN_AUTHENTICATION"
validation_failure_policy {
client_details {
type = "VALIDATION_BLOCK"
}
logout_path = "/logout"
response_type = "CODE"
scopes = ["openid"]
source_uri_details {
type = "VALIDATION_BLOCK"
}
type = "OAUTH2"
use_cookies_for_intermediate_steps = "true"
use_cookies_for_session = "true"
}
validation_policy {
additional_validation_policy {
issuers = ["https://identity.oraclecloud.com/"]
}
client_details {
client_id = oci_identity_domains_app.ai_application_confidential_app.name
client_secret_id = oci_vault_secret.idcs_app_client_secret.id
client_secret_version_number = "1"
type = "CUSTOM"
}
max_cache_duration_in_hours = "1"
source_uri_details {
type = "DISCOVERY_URI"
uri = "${data.oci_identity_domain.application_identity_domain.url}/.well-known/openid-configuration"
}
type = "REMOTE_DISCOVERY"
}
}
mutual_tls {
is_verified_certificate_required = "false"
}
}
routes {
backend {
type = "OAUTH2_LOGOUT_BACKEND"
}
logging_policies {
}
methods = ["GET"]
path = "/logout"
}
routes {
backend {
status = "200"
type = "STOCK_RESPONSE_BACKEND"
}
logging_policies {
}
methods = ["ANY"]
path = "/token"
response_policies {
header_transformations {
set_headers {
items {
if_exists = "OVERWRITE"
name = "token"
values = ["$${request.auth[id_token]}"]
}
items {
if_exists = "OVERWRITE"
name = "x-csrf-token"
values = ["$${request.auth[apigw_csrf_token]}"]
}
}
}
}
}
routes {
backend {
connect_timeout_in_seconds = "60"
is_ssl_verify_disabled = "false"
read_timeout_in_seconds = "120"
send_timeout_in_seconds = "120"
type = "HTTP_BACKEND"
url = "http://${data.oci_core_vnic.ai_application_container_instance_vnic.private_ip_address}:8080/$${request.path[req]}"
}
logging_policies {
}
methods = ["ANY"]
path = "/{req*}"
response_policies {
header_transformations {
set_headers {
items {
name = "X-CSRF-TOKEN"
values = ["$${request.auth[apigw_csrf_token]}"]
if_exists = "OVERWRITE"
}
}
}
}
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
resource "oci_container_instances_container_instance" "ai_container_instance" {
#Required
availability_domain = var.availability_domain
compartment_id = var.compartment_id
containers {
#Required
image_url = local.image

#Optional
environment_variables = {
MULTIMODAL_LLM_PROVIDER = var.multimodal_llm_provider
MULTIMODAL_MODEL_NAME = var.multimodal_model_name
MULTIMODAL_MODEL_ENDPOINT = var.multimodal_model_endpoint
MAX_OUTPUT_TOKEN = var.multimodal_max_output_token
GENAI_COMPARTMENT_OCID = var.genai_compartment_ocid
PROMPT_VERSION = var.prompt_version
BACKEND_MD_URL = oci_datascience_model_deployment.ai_deployment.model_deployment_url
}
}
shape = var.container_shape
shape_config {
#Required
ocpus = var.ocpus

#Optional
memory_in_gbs = var.memory_in_gbs
}
vnics {
#Required
subnet_id = local.app_subnet_id
# private_ip = var.container_instance_private_ip
}

#Optional
display_name = var.container_display_name
}
25 changes: 25 additions & 0 deletions ai-hub/ai-document-converter/policies/terraform/datasources.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
data "oci_core_services" "all_oci_services" {
filter {
name = "name"
values = ["All .* Services In Oracle Services Network"]
regex = true
}
}

data "oci_identity_availability_domains" "get_availability_domains" {
compartment_id = var.compartment_ocid
}

data "oci_identity_domain" "application_identity_domain" {
domain_id = trimspace(var.identity_domain_id)
lifecycle {
precondition {
condition = var.identity_domain_id != null
error_message = "Existing domain id must be provided when using an existing domain."
}
}
}

data "oci_core_vnic" "ai_application_container_instance_vnic" {
vnic_id = oci_container_instances_container_instance.ai_container_instance.vnics[0].vnic_id
}
20 changes: 20 additions & 0 deletions ai-hub/ai-document-converter/policies/terraform/identity_app.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
resource "oci_identity_domains_app" "ai_application_confidential_app" {
based_on_template {
value = "CustomWebAppTemplateId"
well_known_id = "CustomWebAppTemplateId"
}
client_type = "confidential"
description = "Confidential Application for AI Translation Application"
display_name = "ai__translation_application_confidential_app_${random_string.randomstring.result}"
schemas = ["urn:ietf:params:scim:schemas:oracle:idcs:App"]
allowed_operations = ["introspect"]
idcs_endpoint = data.oci_identity_domain.application_identity_domain.url
active = true
is_oauth_client = true
bypass_consent = true
allowed_grants = ["authorization_code", "client_credentials", "urn:ietf:params:oauth:grant-type:jwt-bearer", "implicit"]
all_url_schemes_allowed = true
redirect_uris = ["https://${oci_apigateway_gateway.ai_application_oci_apigateway_gateway.hostname}/", "https://${oci_apigateway_gateway.ai_application_oci_apigateway_gateway.hostname}/ui/", "https://${oci_apigateway_gateway.ai_application_oci_apigateway_gateway.hostname}/html/convert", "https://${oci_apigateway_gateway.ai_application_oci_apigateway_gateway.hostname}/api/docs", "https://${oci_apigateway_gateway.ai_application_oci_apigateway_gateway.hostname}/callback"]
post_logout_redirect_uris = ["https://${oci_apigateway_gateway.ai_application_oci_apigateway_gateway.hostname}/"]
audience = oci_apigateway_gateway.ai_application_oci_apigateway_gateway.hostname
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Model deployment with custom network and scaling policy type = FIXED SIZE
resource "oci_datascience_model_deployment" "ai_deployment" {
# Required
display_name = var.deployment_display_name
description = local.md_desc
compartment_id = var.data_science_project_compartment_id
project_id = var.project_ocid

model_deployment_configuration_details {
deployment_type = var.deployment_type
model_configuration_details {
# Required
instance_configuration {
instance_shape_name = var.shape
model_deployment_instance_shape_config_details {
memory_in_gbs = var.memory_in_gbs
ocpus = var.ocpus
}
# Required for custom networking
# subnet_id = var.subnet_ocid
subnet_id = local.app_subnet_id
}
model_id = local.model_id
bandwidth_mbps = var.deployment_bandwidth_mbps
scaling_policy {
instance_count = var.deployment_instance_count
policy_type = "FIXED_SIZE"
}
}

environment_configuration_details {
image = local.image
image_digest = local.digest
environment_configuration_type = "OCIR_CONTAINER"
# Environment variables are customized based on the AI app.
environment_variables = {
# OCI GenAI Service
MULTIMODAL_LLM_PROVIDER = var.multimodal_llm_provider
MULTIMODAL_MODEL_NAME = var.multimodal_model_name
MULTIMODAL_MODEL_ENDPOINT = var.multimodal_model_endpoint
MAX_OUTPUT_TOKEN = var.multimodal_max_output_token
GENAI_COMPARTMENT_OCID = var.genai_compartment_ocid
PROMPT_VERSION = var.prompt_version,
MODEL_DEPLOY_CUSTOM_ENDPOINTS = "[{\"endpointURI\": \"/apis\", \"httpMethods\": [\"GET\"]}, {\"endpointURI\": \"/convert\", \"httpMethods\": [\"POST\"]}, {\"endpointURI\": \"/convert/file\", \"httpMethods\": [\"POST\"]}]"
}
}
}

# Logging, use the same log group and log ocid to reduce the variables.
category_log_details {
access {
log_group_id = var.log_group_ocid
log_id = var.log_ocid
}
predict {
log_group_id = var.log_group_ocid
log_id = var.log_ocid
}
}

}
Loading