feat(azure): add infra + build/deploy scripts for Azure Container Apps
Split Bicep into infra.bicep (one-time: ACR + Log Analytics + Env) and container-app.bicep (per-deploy: Container App with ACR auth). Add 1-infra.sh and 2-build-deploy.sh shell scripts with config.sh.example covering all .env variables. Gitignore azure/config.sh to prevent secret leakage. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b5c4d4a336
commit
ffe6c537d0
|
|
@ -60,3 +60,6 @@ backend/uploads/
|
|||
data/
|
||||
# Git worktrees
|
||||
.worktrees/
|
||||
|
||||
# Configuració Azure amb secrets (no comitejar mai)
|
||||
azure/config.sh
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
#!/usr/bin/env bash
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# 1-infra.sh — Crea la infraestructura base de MiroFish a Azure
|
||||
#
|
||||
# Executa UNA SOLA VEGADA (o si vols recrear la infraestructura).
|
||||
# Idempotent: pot executar-se múltiples vegades sense errors.
|
||||
#
|
||||
# Prerequisites:
|
||||
# - az login executat
|
||||
# - azure/config.sh existent (còpia de config.sh.example)
|
||||
#
|
||||
# Crea:
|
||||
# - Resource Group: rg_mirofish
|
||||
# - Azure Container Registry (ACR): ${PROJECT_NAME}acr
|
||||
# - Log Analytics Workspace: ${PROJECT_NAME}-logs
|
||||
# - Container Apps Environment: ${PROJECT_NAME}-env
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# ── Carregar configuració ─────────────────────────────────────────────────────
|
||||
CONFIG_FILE="${SCRIPT_DIR}/config.sh"
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
echo "ERROR: No s'ha trobat azure/config.sh"
|
||||
echo " Còpia l'exemple: cp azure/config.sh.example azure/config.sh"
|
||||
echo " Després omple els valors i torna a executar."
|
||||
exit 1
|
||||
fi
|
||||
# shellcheck source=config.sh.example
|
||||
source "$CONFIG_FILE"
|
||||
|
||||
# ── Validar variables obligatòries ───────────────────────────────────────────
|
||||
REQUIRED_VARS=(
|
||||
AZURE_SUBSCRIPTION_ID AZURE_LOCATION
|
||||
RESOURCE_GROUP PROJECT_NAME
|
||||
)
|
||||
for var in "${REQUIRED_VARS[@]}"; do
|
||||
if [[ -z "${!var:-}" ]]; then
|
||||
echo "ERROR: La variable $var no està configurada a config.sh"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
ACR_NAME="${PROJECT_NAME}acr"
|
||||
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
echo " MiroFish — Creació d'infraestructura Azure"
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
echo " Subscripció : $AZURE_SUBSCRIPTION_ID"
|
||||
echo " Localització: $AZURE_LOCATION"
|
||||
echo " Grup recurs : $RESOURCE_GROUP"
|
||||
echo " ACR : $ACR_NAME"
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
# ── Seleccionar subscripció ───────────────────────────────────────────────────
|
||||
echo "→ Seleccionant subscripció..."
|
||||
az account set --subscription "$AZURE_SUBSCRIPTION_ID"
|
||||
|
||||
# ── Registrar proveïdors necessaris ──────────────────────────────────────────
|
||||
echo "→ Registrant proveïdors Azure (pot trigar uns minuts la primera vegada)..."
|
||||
az provider register --namespace Microsoft.App --wait
|
||||
az provider register --namespace Microsoft.OperationalInsights --wait
|
||||
az provider register --namespace Microsoft.ContainerRegistry --wait
|
||||
|
||||
# ── Crear Resource Group ──────────────────────────────────────────────────────
|
||||
echo "→ Creant Resource Group '$RESOURCE_GROUP'..."
|
||||
az group create \
|
||||
--name "$RESOURCE_GROUP" \
|
||||
--location "$AZURE_LOCATION" \
|
||||
--output none
|
||||
echo " ✓ Resource Group llest"
|
||||
|
||||
# ── Desplegar infraestructura via Bicep ──────────────────────────────────────
|
||||
echo "→ Desplegant infraestructura (ACR + Log Analytics + Container Apps Env)..."
|
||||
INFRA_OUTPUT=$(az deployment group create \
|
||||
--resource-group "$RESOURCE_GROUP" \
|
||||
--template-file "${SCRIPT_DIR}/infra.bicep" \
|
||||
--parameters \
|
||||
projectName="$PROJECT_NAME" \
|
||||
location="$AZURE_LOCATION" \
|
||||
--output json)
|
||||
|
||||
# Extreure outputs del desplegament
|
||||
ACR_LOGIN_SERVER=$(echo "$INFRA_OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['properties']['outputs']['acrLoginServer']['value'])")
|
||||
ACR_NAME_OUT=$(echo "$INFRA_OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['properties']['outputs']['acrName']['value'])")
|
||||
ENV_ID=$(echo "$INFRA_OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['properties']['outputs']['containerAppsEnvId']['value'])")
|
||||
|
||||
echo ""
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
echo " Infraestructura creada correctament!"
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
echo " ACR Login Server : $ACR_LOGIN_SERVER"
|
||||
echo " Container Apps Env ID: $ENV_ID"
|
||||
echo ""
|
||||
echo " Proper pas: bash azure/2-build-deploy.sh"
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
#!/usr/bin/env bash
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# 2-build-deploy.sh — Build Docker + push a ACR + deploy Container App
|
||||
#
|
||||
# Executar a cada nova versió de l'aplicació.
|
||||
# Requereix que 1-infra.sh hagi estat executat prèviament.
|
||||
#
|
||||
# Prerequisites:
|
||||
# - az login executat
|
||||
# - azure/config.sh existent i configurat
|
||||
# - Docker instal·lat i en execució
|
||||
# - Infraestructura creada (azure/1-infra.sh)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
|
||||
# ── Carregar configuració ─────────────────────────────────────────────────────
|
||||
CONFIG_FILE="${SCRIPT_DIR}/config.sh"
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
echo "ERROR: No s'ha trobat azure/config.sh"
|
||||
echo " Còpia l'exemple: cp azure/config.sh.example azure/config.sh"
|
||||
exit 1
|
||||
fi
|
||||
# shellcheck source=config.sh.example
|
||||
source "$CONFIG_FILE"
|
||||
|
||||
# ── Validar variables obligatòries ───────────────────────────────────────────
|
||||
REQUIRED_VARS=(
|
||||
AZURE_SUBSCRIPTION_ID RESOURCE_GROUP PROJECT_NAME
|
||||
DEMO_PASSWORD SECRET_KEY LLM_API_KEY LLM_BASE_URL LLM_MODEL_NAME ZEP_API_KEY
|
||||
)
|
||||
for var in "${REQUIRED_VARS[@]}"; do
|
||||
if [[ -z "${!var:-}" ]]; then
|
||||
echo "ERROR: La variable $var no està configurada a config.sh"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
ACR_NAME="${PROJECT_NAME}acr"
|
||||
|
||||
# ── Seleccionar subscripció ───────────────────────────────────────────────────
|
||||
echo "→ Seleccionant subscripció..."
|
||||
az account set --subscription "$AZURE_SUBSCRIPTION_ID"
|
||||
|
||||
# ── Obtenir dades de la infraestructura existent ──────────────────────────────
|
||||
echo "→ Obtenint dades de la infraestructura..."
|
||||
|
||||
ACR_LOGIN_SERVER=$(az acr show \
|
||||
--name "$ACR_NAME" \
|
||||
--resource-group "$RESOURCE_GROUP" \
|
||||
--query loginServer --output tsv)
|
||||
|
||||
ENV_ID=$(az containerapp env show \
|
||||
--name "${PROJECT_NAME}-env" \
|
||||
--resource-group "$RESOURCE_GROUP" \
|
||||
--query id --output tsv)
|
||||
|
||||
if [[ -z "$ACR_LOGIN_SERVER" || -z "$ENV_ID" ]]; then
|
||||
echo "ERROR: No s'ha trobat la infraestructura. Executa primer: bash azure/1-infra.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Generar tag de versió ─────────────────────────────────────────────────────
|
||||
# Format: <git-sha-curt>-<timestamp> per a traçabilitat
|
||||
GIT_SHA=$(git -C "$REPO_ROOT" rev-parse --short HEAD 2>/dev/null || echo "nogit")
|
||||
TIMESTAMP=$(date +%Y%m%d%H%M)
|
||||
IMAGE_TAG="${GIT_SHA}-${TIMESTAMP}"
|
||||
FULL_IMAGE="${ACR_LOGIN_SERVER}/${PROJECT_NAME}:${IMAGE_TAG}"
|
||||
LATEST_IMAGE="${ACR_LOGIN_SERVER}/${PROJECT_NAME}:latest"
|
||||
|
||||
echo ""
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
echo " MiroFish — Build & Deploy"
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
echo " ACR : $ACR_LOGIN_SERVER"
|
||||
echo " Imatge : ${PROJECT_NAME}:${IMAGE_TAG}"
|
||||
echo " Container Env : ${PROJECT_NAME}-env"
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
# ── Login a l'ACR ─────────────────────────────────────────────────────────────
|
||||
echo "→ Login a l'ACR..."
|
||||
az acr login --name "$ACR_NAME"
|
||||
|
||||
# ── Build de la imatge Docker ─────────────────────────────────────────────────
|
||||
echo "→ Build de la imatge Docker..."
|
||||
docker build \
|
||||
--tag "$FULL_IMAGE" \
|
||||
--tag "$LATEST_IMAGE" \
|
||||
"$REPO_ROOT"
|
||||
echo " ✓ Build completat"
|
||||
|
||||
# ── Push de la imatge a l'ACR ─────────────────────────────────────────────────
|
||||
echo "→ Push a l'ACR ($FULL_IMAGE)..."
|
||||
docker push "$FULL_IMAGE"
|
||||
docker push "$LATEST_IMAGE"
|
||||
echo " ✓ Push completat"
|
||||
|
||||
# ── Obtenir credencials ACR per al Bicep ─────────────────────────────────────
|
||||
echo "→ Obtenint credencials ACR..."
|
||||
ACR_USERNAME=$(az acr credential show \
|
||||
--name "$ACR_NAME" \
|
||||
--resource-group "$RESOURCE_GROUP" \
|
||||
--query username --output tsv)
|
||||
ACR_PASSWORD=$(az acr credential show \
|
||||
--name "$ACR_NAME" \
|
||||
--resource-group "$RESOURCE_GROUP" \
|
||||
--query "passwords[0].value" --output tsv)
|
||||
|
||||
# ── Desplegar Container App via Bicep ─────────────────────────────────────────
|
||||
echo "→ Desplegant Container App..."
|
||||
DEPLOY_OUTPUT=$(az deployment group create \
|
||||
--resource-group "$RESOURCE_GROUP" \
|
||||
--template-file "${SCRIPT_DIR}/container-app.bicep" \
|
||||
--parameters \
|
||||
projectName="$PROJECT_NAME" \
|
||||
containerAppsEnvId="$ENV_ID" \
|
||||
containerImage="$FULL_IMAGE" \
|
||||
acrLoginServer="$ACR_LOGIN_SERVER" \
|
||||
acrUsername="$ACR_USERNAME" \
|
||||
acrPassword="$ACR_PASSWORD" \
|
||||
demoPassword="$DEMO_PASSWORD" \
|
||||
llmApiKey="$LLM_API_KEY" \
|
||||
llmBoostApiKey="${LLM_BOOST_API_KEY:-}" \
|
||||
zepApiKey="$ZEP_API_KEY" \
|
||||
secretKey="$SECRET_KEY" \
|
||||
llmBaseUrl="$LLM_BASE_URL" \
|
||||
llmModelName="$LLM_MODEL_NAME" \
|
||||
llmBoostBaseUrl="${LLM_BOOST_BASE_URL:-}" \
|
||||
llmBoostModelName="${LLM_BOOST_MODEL_NAME:-}" \
|
||||
oasisDefaultMaxRounds="${OASIS_DEFAULT_MAX_ROUNDS:-10}" \
|
||||
reportAgentMaxToolCalls="${REPORT_AGENT_MAX_TOOL_CALLS:-5}" \
|
||||
reportAgentMaxReflectionRounds="${REPORT_AGENT_MAX_REFLECTION_ROUNDS:-2}" \
|
||||
reportAgentTemperature="${REPORT_AGENT_TEMPERATURE:-0.5}" \
|
||||
--output json)
|
||||
|
||||
FQDN=$(echo "$DEPLOY_OUTPUT" | python3 -c "import sys,json; print(json.load(sys.stdin)['properties']['outputs']['containerAppFqdn']['value'])")
|
||||
|
||||
echo ""
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
echo " Deploy completat!"
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
echo " URL de l'aplicació: https://$FQDN"
|
||||
echo " Imatge desplegada : $FULL_IMAGE"
|
||||
echo "════════════════════════════════════════════════════════"
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env bash
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# Configuració de desplegament MiroFish a Azure
|
||||
#
|
||||
# INSTRUCCIONS:
|
||||
# 1. Còpia aquest fitxer a azure/config.sh (NO comitegis config.sh — té secrets)
|
||||
# cp azure/config.sh.example azure/config.sh
|
||||
# 2. Omple tots els valors marcats amb <...>
|
||||
# 3. Executa: az login
|
||||
# 4. Executa: bash azure/1-infra.sh (una sola vegada)
|
||||
# 5. Executa: bash azure/2-build-deploy.sh (a cada nova versió)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
# ── Subscripció i localització Azure ─────────────────────────────────────────
|
||||
AZURE_SUBSCRIPTION_ID="<la-teva-subscription-id>"
|
||||
AZURE_LOCATION="westeurope" # canvia si prefereixes altra regió
|
||||
|
||||
# ── Noms de recursos (pots deixar els valors per defecte) ─────────────────────
|
||||
RESOURCE_GROUP="rg_mirofish"
|
||||
PROJECT_NAME="mirofish" # prefix per a tots els recursos Azure
|
||||
# Nota: el nom de l'ACR serà "${PROJECT_NAME}acr" (sense guions, tot minúscula)
|
||||
|
||||
# ── Secrets de l'aplicació ────────────────────────────────────────────────────
|
||||
|
||||
# Contrasenya de l'usuari "demo" per fer login a l'app
|
||||
DEMO_PASSWORD="<contrasenya-segura>"
|
||||
|
||||
# Flask SECRET_KEY per signar tokens JWT
|
||||
# Genera-la amb: python -c "import secrets; print(secrets.token_hex(32))"
|
||||
SECRET_KEY="<flask-secret-key>"
|
||||
|
||||
# ── LLM principal (OpenAI-compatible) ─────────────────────────────────────────
|
||||
LLM_API_KEY="<la-teva-llm-api-key>"
|
||||
LLM_BASE_URL="https://dashscope.aliyuncs.com/compatible-mode/v1"
|
||||
LLM_MODEL_NAME="qwen-plus"
|
||||
|
||||
# ── LLM accelerador (opcional — deixar buit per desactivar) ───────────────────
|
||||
LLM_BOOST_API_KEY=""
|
||||
LLM_BOOST_BASE_URL=""
|
||||
LLM_BOOST_MODEL_NAME=""
|
||||
|
||||
# ── Zep Cloud (graf de memòria) ───────────────────────────────────────────────
|
||||
ZEP_API_KEY="<la-teva-zep-api-key>"
|
||||
|
||||
# ── Simulació OASIS (valors per defecte recomanats) ───────────────────────────
|
||||
OASIS_DEFAULT_MAX_ROUNDS="10"
|
||||
|
||||
# ── Report Agent (valors per defecte recomanats) ──────────────────────────────
|
||||
REPORT_AGENT_MAX_TOOL_CALLS="5"
|
||||
REPORT_AGENT_MAX_REFLECTION_ROUNDS="2"
|
||||
REPORT_AGENT_TEMPERATURE="0.5"
|
||||
|
|
@ -1,34 +1,42 @@
|
|||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// MiroFish — Azure Container App
|
||||
// Segueix les directrius CTTI per a desplegament d'aplicacions a Azure
|
||||
// (DA/TM: Azure Container Apps com a plataforma de desplegament de contenidors)
|
||||
// MiroFish — Container App (executar a cada deploy)
|
||||
//
|
||||
// Paràmetres que l'equip d'ops ha de proporcionar en desplegar:
|
||||
// Secrets (@secure): demoPassword, llmApiKey, llmBoostApiKey, zepApiKey, secretKey
|
||||
// Valors: containerImage, llmBaseUrl, llmModelName, llmBoostBaseUrl,
|
||||
// llmBoostModelName, oasisDefaultMaxRounds,
|
||||
// reportAgentMaxToolCalls, reportAgentMaxReflectionRounds,
|
||||
// reportAgentTemperature
|
||||
// Rep com a paràmetres els outputs d'infra.bicep (containerAppsEnvId,
|
||||
// acrLoginServer) i desplega/actualitza la Container App amb la nova imatge.
|
||||
//
|
||||
// Executar amb: azure/2-build-deploy.sh
|
||||
//
|
||||
// Extensions pendents per a l'equip d'operacions:
|
||||
// - DNS: afegir CNAME a *.intranet.gencat.cat (PRE) / *.gencat.cat (PRO)
|
||||
// - Xarxa: integrar en VNet Hub-Spoke + Private Link per a serveis interns
|
||||
// (descomentar el bloc vnetConfiguration a l'entorn)
|
||||
// - TLS: certificat gestionat via Container Apps o Azure Front Door
|
||||
// - ingress.external: canviar a false per a accés exclusiu per intranet
|
||||
// - TLS: certificat gestionat via Container Apps o Azure Front Door
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
@description('Nom base del projecte (es fa servir per als noms dels recursos)')
|
||||
@description('Nom base del projecte')
|
||||
param projectName string = 'mirofish'
|
||||
|
||||
@description('Localització Azure dels recursos')
|
||||
param location string = resourceGroup().location
|
||||
|
||||
@description('Imatge Docker completa (registry/imatge:tag)')
|
||||
@description('ID del Container Apps Environment (output d\'infra.bicep)')
|
||||
param containerAppsEnvId string
|
||||
|
||||
@description('Imatge Docker completa (acrLoginServer/nom:tag)')
|
||||
param containerImage string
|
||||
|
||||
@description('Login server de l\'ACR (ex: mirofsihacr.azurecr.io)')
|
||||
param acrLoginServer string
|
||||
|
||||
// ─── Paràmetres secrets (@secure — mai visibles als logs de desplegament) ────
|
||||
|
||||
@description('Nom d\'usuari de l\'ACR (az acr credential show --name <acr> --query username)')
|
||||
@secure()
|
||||
param acrUsername string
|
||||
|
||||
@description('Contrasenya de l\'ACR (az acr credential show --name <acr> --query passwords[0].value)')
|
||||
@secure()
|
||||
param acrPassword string
|
||||
|
||||
@description('Contrasenya de l\'usuari demo')
|
||||
@secure()
|
||||
param demoPassword string
|
||||
|
|
@ -45,7 +53,7 @@ param llmBoostApiKey string = ''
|
|||
@secure()
|
||||
param zepApiKey string
|
||||
|
||||
@description('SECRET_KEY de Flask per a JWT (generar amb: python -c "import secrets; print(secrets.token_hex(32))")')
|
||||
@description('SECRET_KEY de Flask per a JWT (python -c "import secrets; print(secrets.token_hex(32))")')
|
||||
@secure()
|
||||
param secretKey string
|
||||
|
||||
|
|
@ -81,54 +89,31 @@ param reportAgentMaxReflectionRounds string = '2'
|
|||
@description('Temperatura del model LLM per al Report Agent')
|
||||
param reportAgentTemperature string = '0.5'
|
||||
|
||||
// ─── Log Analytics Workspace ──────────────────────────────────────────────────
|
||||
// NOR0016-C: retenció mínima de logs de seguretat = 90 dies
|
||||
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
|
||||
name: '${projectName}-logs'
|
||||
location: location
|
||||
properties: {
|
||||
sku: {
|
||||
name: 'PerGB2018'
|
||||
}
|
||||
retentionInDays: 90
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Container Apps Environment ───────────────────────────────────────────────
|
||||
resource containerAppsEnv 'Microsoft.App/managedEnvironments@2023-05-01' = {
|
||||
name: '${projectName}-env'
|
||||
location: location
|
||||
properties: {
|
||||
appLogsConfiguration: {
|
||||
destination: 'log-analytics'
|
||||
logAnalyticsConfiguration: {
|
||||
customerId: logAnalytics.properties.customerId
|
||||
sharedKey: logAnalytics.listKeys().primarySharedKey
|
||||
}
|
||||
}
|
||||
// TODO (ops): descomentar per integrar en VNet Hub-Spoke CTTI
|
||||
// vnetConfiguration: {
|
||||
// infrastructureSubnetId: '/subscriptions/.../subnets/container-apps-subnet'
|
||||
// internal: true // true = accés únicament per intranet
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Container App ─────────────────────────────────────────────────────────────
|
||||
resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
|
||||
name: projectName
|
||||
location: location
|
||||
properties: {
|
||||
managedEnvironmentId: containerAppsEnv.id
|
||||
managedEnvironmentId: containerAppsEnvId
|
||||
|
||||
configuration: {
|
||||
// Secrets de Container Apps — mai en text pla a les variables d'entorn
|
||||
// Secrets: credencials ACR + variables sensibles de l'aplicació
|
||||
secrets: [
|
||||
{ name: 'demo-password', value: demoPassword }
|
||||
{ name: 'llm-api-key', value: llmApiKey }
|
||||
{ name: 'llm-boost-api-key', value: llmBoostApiKey }
|
||||
{ name: 'zep-api-key', value: zepApiKey }
|
||||
{ name: 'secret-key', value: secretKey }
|
||||
{ name: 'acr-password', value: acrPassword }
|
||||
{ name: 'demo-password', value: demoPassword }
|
||||
{ name: 'llm-api-key', value: llmApiKey }
|
||||
{ name: 'llm-boost-api-key', value: llmBoostApiKey }
|
||||
{ name: 'zep-api-key', value: zepApiKey }
|
||||
{ name: 'secret-key', value: secretKey }
|
||||
]
|
||||
|
||||
// Credencials del registre privat (ACR)
|
||||
registries: [
|
||||
{
|
||||
server: acrLoginServer
|
||||
username: acrUsername
|
||||
passwordSecretRef: 'acr-password'
|
||||
}
|
||||
]
|
||||
|
||||
// Ingrés: port únic 5001 (Flask serveix frontend + API)
|
||||
|
|
@ -138,11 +123,7 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
|
|||
transport: 'http'
|
||||
// TODO (ops): afegir domini corporatiu quan estigui assignat
|
||||
// customDomains: [
|
||||
// {
|
||||
// name: 'mirofish.intranet.gencat.cat' // PRE
|
||||
// certificateId: '<id-certificat-aca>'
|
||||
// bindingType: 'SniEnabled'
|
||||
// }
|
||||
// { name: 'mirofish.intranet.gencat.cat', certificateId: '...', bindingType: 'SniEnabled' }
|
||||
// ]
|
||||
}
|
||||
|
||||
|
|
@ -210,11 +191,8 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
|
|||
}
|
||||
|
||||
// ─── Outputs ──────────────────────────────────────────────────────────────────
|
||||
@description('FQDN de l\'aplicació desplegada')
|
||||
@description('FQDN públic de l\'aplicació')
|
||||
output containerAppFqdn string = containerApp.properties.configuration.ingress.fqdn
|
||||
|
||||
@description('Nom del recurs Container App')
|
||||
output containerAppName string = containerApp.name
|
||||
|
||||
@description('ID del workspace de Log Analytics')
|
||||
output logAnalyticsWorkspaceId string = logAnalytics.id
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// MiroFish — Infraestructura base (executar una sola vegada)
|
||||
//
|
||||
// Crea:
|
||||
// - Azure Container Registry (ACR) per emmagatzemar la imatge Docker
|
||||
// - Log Analytics Workspace (NOR0016-C: 90 dies retenció)
|
||||
// - Container Apps Environment (plataforma d'execució CTTI)
|
||||
//
|
||||
// Executar amb: azure/1-infra.sh
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
@description('Nom base del projecte')
|
||||
param projectName string = 'mirofish'
|
||||
|
||||
@description('Localització Azure dels recursos')
|
||||
param location string = resourceGroup().location
|
||||
|
||||
// ─── Azure Container Registry ─────────────────────────────────────────────────
|
||||
// SKU Basic: suficient per a imatges privades sense geo-replicació
|
||||
resource acr 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' = {
|
||||
name: '${projectName}acr' // ACR no admet guions, tot minúscula
|
||||
location: location
|
||||
sku: {
|
||||
name: 'Basic'
|
||||
}
|
||||
properties: {
|
||||
adminUserEnabled: true // necessari per a la autenticació des dels scripts
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Log Analytics Workspace ──────────────────────────────────────────────────
|
||||
// NOR0016-C: retenció mínima de logs de seguretat = 90 dies
|
||||
resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2022-10-01' = {
|
||||
name: '${projectName}-logs'
|
||||
location: location
|
||||
properties: {
|
||||
sku: {
|
||||
name: 'PerGB2018'
|
||||
}
|
||||
retentionInDays: 90
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Container Apps Environment ───────────────────────────────────────────────
|
||||
resource containerAppsEnv 'Microsoft.App/managedEnvironments@2023-05-01' = {
|
||||
name: '${projectName}-env'
|
||||
location: location
|
||||
properties: {
|
||||
appLogsConfiguration: {
|
||||
destination: 'log-analytics'
|
||||
logAnalyticsConfiguration: {
|
||||
customerId: logAnalytics.properties.customerId
|
||||
sharedKey: logAnalytics.listKeys().primarySharedKey
|
||||
}
|
||||
}
|
||||
// TODO (ops): descomentar per integrar en VNet Hub-Spoke CTTI
|
||||
// vnetConfiguration: {
|
||||
// infrastructureSubnetId: '/subscriptions/.../subnets/container-apps-subnet'
|
||||
// internal: true
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Outputs (usats pels scripts de deploy) ───────────────────────────────────
|
||||
@description('URL de login de l\'ACR (ex: mirofsihacr.azurecr.io)')
|
||||
output acrLoginServer string = acr.properties.loginServer
|
||||
|
||||
@description('Nom del recurs ACR (per a az acr build)')
|
||||
output acrName string = acr.name
|
||||
|
||||
@description('ID del Container Apps Environment')
|
||||
output containerAppsEnvId string = containerAppsEnv.id
|
||||
|
||||
@description('ID del Log Analytics Workspace')
|
||||
output logAnalyticsId string = logAnalytics.id
|
||||
Loading…
Reference in New Issue