feat(azure): update deployment files for Phase 3 auth variables
Replace DEMO_PASSWORD/SECRET_KEY with JWT_SECRET_KEY, ADMIN_EMAIL, ADMIN_PASSWORD, and optional ACS (Azure Communication Services) vars across config.sh.example, container-app.bicep, and 2-build-deploy.sh. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2e0896e34d
commit
0d04dee670
|
|
@ -29,7 +29,8 @@ source "$CONFIG_FILE"
|
||||||
# ── Validar variables obligatòries ───────────────────────────────────────────
|
# ── Validar variables obligatòries ───────────────────────────────────────────
|
||||||
REQUIRED_VARS=(
|
REQUIRED_VARS=(
|
||||||
AZURE_SUBSCRIPTION_ID RESOURCE_GROUP PROJECT_NAME
|
AZURE_SUBSCRIPTION_ID RESOURCE_GROUP PROJECT_NAME
|
||||||
DEMO_PASSWORD SECRET_KEY LLM_API_KEY LLM_BASE_URL LLM_MODEL_NAME
|
JWT_SECRET_KEY ADMIN_EMAIL ADMIN_PASSWORD
|
||||||
|
LLM_API_KEY LLM_BASE_URL LLM_MODEL_NAME
|
||||||
DATABASE_URL STORAGE_CONNECTION_STRING
|
DATABASE_URL STORAGE_CONNECTION_STRING
|
||||||
)
|
)
|
||||||
# Validate graph backend config
|
# Validate graph backend config
|
||||||
|
|
@ -42,6 +43,9 @@ if [[ "$GRAPH_BACKEND" == "graphiti" && -z "${NEO4J_PASSWORD:-}" ]]; then
|
||||||
echo "ERROR: NEO4J_PASSWORD is required when GRAPH_BACKEND=graphiti"
|
echo "ERROR: NEO4J_PASSWORD is required when GRAPH_BACKEND=graphiti"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
if [[ -z "${ACS_CONNECTION_STRING:-}" ]]; then
|
||||||
|
echo "AVÍS: ACS_CONNECTION_STRING no configurat — emails d'invitació es mostraran als logs"
|
||||||
|
fi
|
||||||
for var in "${REQUIRED_VARS[@]}"; do
|
for var in "${REQUIRED_VARS[@]}"; do
|
||||||
if [[ -z "${!var:-}" ]]; then
|
if [[ -z "${!var:-}" ]]; then
|
||||||
echo "ERROR: La variable $var no està configurada a config.sh"
|
echo "ERROR: La variable $var no està configurada a config.sh"
|
||||||
|
|
@ -133,7 +137,15 @@ DEPLOY_OUTPUT=$(az deployment group create \
|
||||||
acrLoginServer="$ACR_LOGIN_SERVER" \
|
acrLoginServer="$ACR_LOGIN_SERVER" \
|
||||||
acrUsername="$ACR_USERNAME" \
|
acrUsername="$ACR_USERNAME" \
|
||||||
acrPassword="$ACR_PASSWORD" \
|
acrPassword="$ACR_PASSWORD" \
|
||||||
demoPassword="$DEMO_PASSWORD" \
|
jwtSecretKey="$JWT_SECRET_KEY" \
|
||||||
|
adminEmail="$ADMIN_EMAIL" \
|
||||||
|
adminPassword="$ADMIN_PASSWORD" \
|
||||||
|
acsConnectionString="${ACS_CONNECTION_STRING:-}" \
|
||||||
|
acsSenderAddress="${ACS_SENDER_ADDRESS:-}" \
|
||||||
|
acsInvitationTtlHours="${ACS_INVITATION_TTL_HOURS:-48}" \
|
||||||
|
acsResetPasswordTtlHours="${ACS_RESET_PASSWORD_TTL_HOURS:-1}" \
|
||||||
|
jwtAccessTokenExpires="${JWT_ACCESS_TOKEN_EXPIRES:-28800}" \
|
||||||
|
jwtRefreshTokenExpires="${JWT_REFRESH_TOKEN_EXPIRES:-604800}" \
|
||||||
llmApiKey="$LLM_API_KEY" \
|
llmApiKey="$LLM_API_KEY" \
|
||||||
llmBoostApiKey="${LLM_BOOST_API_KEY:-}" \
|
llmBoostApiKey="${LLM_BOOST_API_KEY:-}" \
|
||||||
llmProvider="${LLM_PROVIDER:-}" \
|
llmProvider="${LLM_PROVIDER:-}" \
|
||||||
|
|
@ -143,7 +155,6 @@ DEPLOY_OUTPUT=$(az deployment group create \
|
||||||
neo4jUser="${NEO4J_USER:-neo4j}" \
|
neo4jUser="${NEO4J_USER:-neo4j}" \
|
||||||
neo4jDatabase="${NEO4J_DATABASE:-neo4j}" \
|
neo4jDatabase="${NEO4J_DATABASE:-neo4j}" \
|
||||||
graphBackend="${GRAPH_BACKEND:-zep}" \
|
graphBackend="${GRAPH_BACKEND:-zep}" \
|
||||||
secretKey="$SECRET_KEY" \
|
|
||||||
llmBaseUrl="$LLM_BASE_URL" \
|
llmBaseUrl="$LLM_BASE_URL" \
|
||||||
llmModelName="$LLM_MODEL_NAME" \
|
llmModelName="$LLM_MODEL_NAME" \
|
||||||
llmBoostBaseUrl="${LLM_BOOST_BASE_URL:-}" \
|
llmBoostBaseUrl="${LLM_BOOST_BASE_URL:-}" \
|
||||||
|
|
|
||||||
|
|
@ -22,12 +22,22 @@ PROJECT_NAME="mirofish" # prefix per a tots els recursos Azure
|
||||||
|
|
||||||
# ── Secrets de l'aplicació ────────────────────────────────────────────────────
|
# ── Secrets de l'aplicació ────────────────────────────────────────────────────
|
||||||
|
|
||||||
# Contrasenya de l'usuari "demo" per fer login a l'app
|
# ── Auth JWT ──────────────────────────────────────────────────────────────────
|
||||||
DEMO_PASSWORD="<contrasenya-segura>"
|
# Genera JWT_SECRET_KEY amb: python -c "import secrets; print(secrets.token_hex(32))"
|
||||||
|
JWT_SECRET_KEY="<clau-secreta-jwt>"
|
||||||
|
JWT_ACCESS_TOKEN_EXPIRES=28800 # 8h en segons
|
||||||
|
JWT_REFRESH_TOKEN_EXPIRES=604800 # 7d en segons
|
||||||
|
|
||||||
# Flask SECRET_KEY per signar tokens JWT
|
# ── Admin inicial (per flask init-system) ─────────────────────────────────────
|
||||||
# Genera-la amb: python -c "import secrets; print(secrets.token_hex(32))"
|
ADMIN_EMAIL="admin@example.com"
|
||||||
SECRET_KEY="<flask-secret-key>"
|
ADMIN_PASSWORD="<contrasenya-segura>"
|
||||||
|
|
||||||
|
# ── Azure Communication Services (emails d'invitació i reset) ────────────────
|
||||||
|
# ACS és opcional en dev: els links apareixeran als logs si ACS_CONNECTION_STRING és buit
|
||||||
|
ACS_CONNECTION_STRING=""
|
||||||
|
ACS_SENDER_ADDRESS="donotreply@example.com"
|
||||||
|
ACS_INVITATION_TTL_HOURS=48
|
||||||
|
ACS_RESET_PASSWORD_TTL_HOURS=1
|
||||||
|
|
||||||
# ── LLM principal (OpenAI-compatible) ─────────────────────────────────────────
|
# ── LLM principal (OpenAI-compatible) ─────────────────────────────────────────
|
||||||
LLM_API_KEY="<la-teva-llm-api-key>"
|
LLM_API_KEY="<la-teva-llm-api-key>"
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,6 @@ param acrUsername string
|
||||||
@secure()
|
@secure()
|
||||||
param acrPassword string
|
param acrPassword string
|
||||||
|
|
||||||
@description('Contrasenya de l\'usuari demo')
|
|
||||||
@secure()
|
|
||||||
param demoPassword string
|
|
||||||
|
|
||||||
@description('Clau de l\'API LLM principal (OpenAI-compatible)')
|
@description('Clau de l\'API LLM principal (OpenAI-compatible)')
|
||||||
@secure()
|
@secure()
|
||||||
param llmApiKey string
|
param llmApiKey string
|
||||||
|
|
@ -57,9 +53,17 @@ param zepApiKey string = ''
|
||||||
@secure()
|
@secure()
|
||||||
param neo4jPassword string = ''
|
param neo4jPassword string = ''
|
||||||
|
|
||||||
@description('SECRET_KEY de Flask per a JWT (python -c "import secrets; print(secrets.token_hex(32))")')
|
@description('JWT Secret Key per a flask-jwt-extended')
|
||||||
@secure()
|
@secure()
|
||||||
param secretKey string
|
param jwtSecretKey string
|
||||||
|
|
||||||
|
@description('Contrasenya de l\'admin inicial (per flask init-system)')
|
||||||
|
@secure()
|
||||||
|
param adminPassword string
|
||||||
|
|
||||||
|
@description('Connection string Azure Communication Services (opcional)')
|
||||||
|
@secure()
|
||||||
|
param acsConnectionString string = ''
|
||||||
|
|
||||||
@description('Connection string del Storage Account per a Azure Files (output d\'infra.bicep)')
|
@description('Connection string del Storage Account per a Azure Files (output d\'infra.bicep)')
|
||||||
@secure()
|
@secure()
|
||||||
|
|
@ -72,6 +76,24 @@ param databaseUrl string = ''
|
||||||
@description('Nom del Storage Account (output d\'infra.bicep)')
|
@description('Nom del Storage Account (output d\'infra.bicep)')
|
||||||
param storageAccountName string = ''
|
param storageAccountName string = ''
|
||||||
|
|
||||||
|
@description('Email de l\'admin inicial')
|
||||||
|
param adminEmail string = ''
|
||||||
|
|
||||||
|
@description('Adreça remitent ACS')
|
||||||
|
param acsSenderAddress string = ''
|
||||||
|
|
||||||
|
@description('TTL invitació en hores')
|
||||||
|
param acsInvitationTtlHours string = '48'
|
||||||
|
|
||||||
|
@description('TTL reset password en hores')
|
||||||
|
param acsResetPasswordTtlHours string = '1'
|
||||||
|
|
||||||
|
@description('Expiració access token JWT en segons')
|
||||||
|
param jwtAccessTokenExpires string = '28800'
|
||||||
|
|
||||||
|
@description('Expiració refresh token JWT en segons')
|
||||||
|
param jwtRefreshTokenExpires string = '604800'
|
||||||
|
|
||||||
// ─── Paràmetres LLM principal ─────────────────────────────────────────────────
|
// ─── Paràmetres LLM principal ─────────────────────────────────────────────────
|
||||||
|
|
||||||
@description('URL base de l\'API LLM principal')
|
@description('URL base de l\'API LLM principal')
|
||||||
|
|
@ -149,10 +171,10 @@ param reportAgentTemperature string = '0.5'
|
||||||
|
|
||||||
// ─── Secrets i env vars condicionals (Azure rebutja secrets amb valor buit) ───
|
// ─── Secrets i env vars condicionals (Azure rebutja secrets amb valor buit) ───
|
||||||
var mandatorySecrets = [
|
var mandatorySecrets = [
|
||||||
{ name: 'acr-password', value: acrPassword }
|
{ name: 'acr-password', value: acrPassword }
|
||||||
{ name: 'demo-password', value: demoPassword }
|
{ name: 'jwt-secret-key', value: jwtSecretKey }
|
||||||
{ name: 'llm-api-key', value: llmApiKey }
|
{ name: 'admin-password', value: adminPassword }
|
||||||
{ name: 'secret-key', value: secretKey }
|
{ name: 'llm-api-key', value: llmApiKey }
|
||||||
]
|
]
|
||||||
var optionalSecrets = concat(
|
var optionalSecrets = concat(
|
||||||
empty(llmBoostApiKey) ? [] : [{ name: 'llm-boost-api-key', value: llmBoostApiKey }],
|
empty(llmBoostApiKey) ? [] : [{ name: 'llm-boost-api-key', value: llmBoostApiKey }],
|
||||||
|
|
@ -161,14 +183,21 @@ var optionalSecrets = concat(
|
||||||
empty(zepApiKey) ? [] : [{ name: 'zep-api-key', value: zepApiKey }],
|
empty(zepApiKey) ? [] : [{ name: 'zep-api-key', value: zepApiKey }],
|
||||||
empty(neo4jPassword) ? [] : [{ name: 'neo4j-password', value: neo4jPassword }],
|
empty(neo4jPassword) ? [] : [{ name: 'neo4j-password', value: neo4jPassword }],
|
||||||
empty(storageConnectionString) ? [] : [{ name: 'storage-connection-string', value: storageConnectionString }],
|
empty(storageConnectionString) ? [] : [{ name: 'storage-connection-string', value: storageConnectionString }],
|
||||||
empty(databaseUrl) ? [] : [{ name: 'database-url', value: databaseUrl }]
|
empty(databaseUrl) ? [] : [{ name: 'database-url', value: databaseUrl }],
|
||||||
|
empty(acsConnectionString) ? [] : [{ name: 'acs-connection-string', value: acsConnectionString }]
|
||||||
)
|
)
|
||||||
var allSecrets = concat(mandatorySecrets, optionalSecrets)
|
var allSecrets = concat(mandatorySecrets, optionalSecrets)
|
||||||
|
|
||||||
var mandatoryEnv = [
|
var mandatoryEnv = [
|
||||||
{ name: 'DEMO_PASSWORD', secretRef: 'demo-password' }
|
{ name: 'JWT_SECRET_KEY', secretRef: 'jwt-secret-key' }
|
||||||
|
{ name: 'ADMIN_EMAIL', value: adminEmail }
|
||||||
|
{ name: 'ADMIN_PASSWORD', secretRef: 'admin-password' }
|
||||||
|
{ name: 'JWT_ACCESS_TOKEN_EXPIRES', value: jwtAccessTokenExpires }
|
||||||
|
{ name: 'JWT_REFRESH_TOKEN_EXPIRES', value: jwtRefreshTokenExpires }
|
||||||
|
{ name: 'ACS_SENDER_ADDRESS', value: acsSenderAddress }
|
||||||
|
{ name: 'ACS_INVITATION_TTL_HOURS', value: acsInvitationTtlHours }
|
||||||
|
{ name: 'ACS_RESET_PASSWORD_TTL_HOURS', value: acsResetPasswordTtlHours }
|
||||||
{ name: 'LLM_API_KEY', secretRef: 'llm-api-key' }
|
{ name: 'LLM_API_KEY', secretRef: 'llm-api-key' }
|
||||||
{ name: 'SECRET_KEY', secretRef: 'secret-key' }
|
|
||||||
{ name: 'LLM_BASE_URL', value: llmBaseUrl }
|
{ name: 'LLM_BASE_URL', value: llmBaseUrl }
|
||||||
{ name: 'LLM_MODEL_NAME', value: llmModelName }
|
{ name: 'LLM_MODEL_NAME', value: llmModelName }
|
||||||
{ name: 'LLM_PROVIDER', value: llmProvider }
|
{ name: 'LLM_PROVIDER', value: llmProvider }
|
||||||
|
|
@ -199,7 +228,8 @@ var optionalEnv = concat(
|
||||||
empty(zepApiKey) ? [] : [{ name: 'ZEP_API_KEY', secretRef: 'zep-api-key' }],
|
empty(zepApiKey) ? [] : [{ name: 'ZEP_API_KEY', secretRef: 'zep-api-key' }],
|
||||||
empty(neo4jPassword) ? [] : [{ name: 'NEO4J_PASSWORD', secretRef: 'neo4j-password' }],
|
empty(neo4jPassword) ? [] : [{ name: 'NEO4J_PASSWORD', secretRef: 'neo4j-password' }],
|
||||||
empty(storageConnectionString) ? [] : [{ name: 'AZURE_STORAGE_CONNECTION_STRING', secretRef: 'storage-connection-string' }],
|
empty(storageConnectionString) ? [] : [{ name: 'AZURE_STORAGE_CONNECTION_STRING', secretRef: 'storage-connection-string' }],
|
||||||
empty(databaseUrl) ? [] : [{ name: 'DATABASE_URL', secretRef: 'database-url' }]
|
empty(databaseUrl) ? [] : [{ name: 'DATABASE_URL', secretRef: 'database-url' }],
|
||||||
|
empty(acsConnectionString) ? [] : [{ name: 'ACS_CONNECTION_STRING', secretRef: 'acs-connection-string' }]
|
||||||
)
|
)
|
||||||
var allEnv = concat(mandatoryEnv, optionalEnv)
|
var allEnv = concat(mandatoryEnv, optionalEnv)
|
||||||
|
|
||||||
|
|
@ -266,7 +296,7 @@ resource containerApp 'Microsoft.App/containerApps@2023-05-01' = {
|
||||||
name: 'uploads'
|
name: 'uploads'
|
||||||
storageType: 'AzureFile'
|
storageType: 'AzureFile'
|
||||||
storageName: 'uploads'
|
storageName: 'uploads'
|
||||||
mountOptions: 'nobrl,cache=strict,nosharesock,actimeo=30'
|
mountOptions: 'nobrl,cache=strict,nosharesock'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue