> For the complete documentation index, see [llms.txt](https://docs.devolutions.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.devolutions.net/powershell-universal/es/config/hosting/azure.md).

# Azure

PowerShell Universal es una aplicación web de ASP.NET Core y puede alojarse en Windows Azure Web Apps.

## Aplicación web de contenedor

Las aplicaciones web de contenedor permiten utilizar imágenes de Docker como aplicaciones web en Azure. Desde el portal de Azure, puede crear una aplicación web de contenedor de Docker mediante el asistente App Services \ Create Web App.

Una vez que haya seleccionado un grupo de recursos, asignado un nombre y seleccionado un plan de cómputo, podrá crear la aplicación web.

![Aplicación web de contenedor](/files/y0QJML1do52Xu2INXHYP)

A continuación, deberá desplegar la imagen en su aplicación web. Para ello, seleccione el Deployment Center y configure la imagen que se debe extraer. Puede extraer una versión etiquetada estática (como 2.7.3) o extraer la última y su aplicación web se mantendrá automáticamente actualizada con las nuevas versiones de PowerShell Universal. Utilice la etiqueta con el sufijo `azure`. Está preconfigurada para ejecutarse en Azure.

{% hint style="info" %}
Para entornos de producción, sugerimos establecer una versión etiquetada para evitar actualizaciones involuntarias de su contenedor cuando se reinicie. De forma predeterminada, Azure actualizará automáticamente los contenedores cuando se actualice una etiqueta, como latest. Esto le permitirá controlar las actualizaciones de su versión de PowerShell Universal.
{% endhint %}

<figure><img src="/files/J3tTEdqC39gcQQpORcf6" alt=""><figcaption><p>Configuración de Docker</p></figcaption></figure>

### Persistencia local

De forma predeterminada, el contenedor escribirá en el directorio `/home`.

Deberá asegurarse de que la variable de entorno `WEBSITES_ENABLE_APP_SERVICE_STORAGE` esté establecida en true. Esto configura el contenedor para que la carpeta `/home` sea persistente y es allí donde se almacenan los datos de configuración de PowerShell Universal.

### Git y SQL

Si opta por utilizar la integración con git en PowerShell Universal, recomendamos configurar un servidor y una base de datos SQL para el almacenamiento. Git se utilizará para sincronizar los ficheros de configuración cuando se inicie el contenedor. SQL almacenará los ajustes de configuración de git junto con recursos como trabajos, tokens de aplicación e identidades.

Necesitará una base de datos de Azure SQL para empezar. Una vez que cree el recurso, deberá copiar la cadena de conexión de la base de datos para proporcionarla a PowerShell Universal.

<figure><img src="/files/0VRBCwthv6NH4MvFgyrt" alt=""><figcaption></figcaption></figure>

Asegúrese de haber permitido que los servicios de Azure accedan a la base de datos.

<figure><img src="/files/XRurDlU25F6Jzn72tsC7" alt=""><figcaption></figcaption></figure>

Para habilitar la compatibilidad con SQL, debe configurar los complementos de PowerShell Universal para que utilicen el complemento SQL en la Application Configuration de su aplicación web.

Cree un ajuste `Plugins__0` con el valor `SQL`. A continuación, establezca el valor `Data__ConnectionString` en la base de datos de su servidor SQL.

<figure><img src="/files/Wze8NLXhGLdOTcOOFbN9" alt=""><figcaption></figcaption></figure>

Una vez que tenga SQL configurado, puede iniciar su contenedor. El esquema de la base de datos se creará al iniciarse el contenedor. A continuación, deberá configurar git en PowerShell Universal haciendo clic en Settings \ Git. Introduzca su remoto, rama, nombre de usuario, contraseña o token de acceso personal, y el modo de sincronización. No se recomienda el modo push-only en esta configuración porque el estado del contenedor se pierde entre reinicios. Asegúrese de que el modo de inicialización esté establecido en Clone.

{% hint style="info" %}
Los ajustes de git se almacenan en su base de datos SQL y se recuperarán cada vez que se inicie el contenedor.
{% endhint %}

<figure><img src="/files/TVef0vgA2RKSVW0pDJY1" alt=""><figcaption></figcaption></figure>

### Cabeceras reenviadas

Los contenedores normalmente se alojan detrás de un proxy inverso y no conocerán la URL externa real sin configuración adicional. Para garantizar que los sistemas que requieren la URL externa, como OpenID Connect, reciban la información correcta, deberá establecer la variable de entorno `ASPNETCORE_FORWARDEDHEADERS_ENABLED` en `true`.

![](/files/9qnipxdZYudwzAvNeTWU)

Para más información, puede leer esta entrada de blog de [Microsoft](https://devblogs.microsoft.com/dotnet/forwarded-headers-middleware-updates-in-net-core-3-0-preview-6/).

### Bicep

Puede utilizar la siguiente plantilla de Bicep para desplegar una aplicación web de contenedor con almacenamiento persistente.

```bicep
@description('Name of Azure Web App')
param siteName string = 'psu-${uniqueString(resourceGroup().id)}'

@description('The version of PowerShell Universal')
param version string = '5.4.4'

@description('App Service Plan Pricing Tier')
@allowed([
  'B1'
  'B2'
  'B3'
  'S1'
  'S2'
  'S3'
  'P1V2'
  'P2V2'
  'P2V3'
])
param servicePlanPricingTier string = 'S2'
var servicePlanName = '${siteName}-asp'

@description('Location for all the resources.')
param location string = resourceGroup().location

var servicePlanPricingTiers = {
  F1: {
    tier: 'Free'
  }
  B1: {
    tier: 'Basic'
  }
  B2: {
    tier: 'Basic'
  }
  B3: {
    tier: 'Basic'
  }
  S1: {
    tier: 'Standard'
  }
  S2: {
    tier: 'Standard'
  }
  S3: {
    tier: 'Standard'
  }
  P1V2: {
    tier: 'Standard'
  }
  P2V2: {
    tier: 'Standard'
  }
  P2V3: {
    tier: 'Standard'
  }
}

resource planResource 'Microsoft.Web/serverfarms@2024-04-01' = {
  name: servicePlanName
  location: location
  sku: {
    name: servicePlanPricingTier
    tier: servicePlanPricingTiers[servicePlanPricingTier].tier
    capacity: 1
  }
  kind: 'linux'
  properties: {
    reserved: true
  }
}

resource siteResource 'Microsoft.Web/sites@2024-04-01' = {
  name: siteName
  location: location
  properties: {
    serverFarmId: planResource.id
    siteConfig: {
      linuxFxVersion: 'DOCKER|ironmansoftware/universal:${version}-azure'
    }
  }
}

resource siteWebAppsettingsResource 'Microsoft.Web/sites/config@2024-04-01' = {
  parent: siteResource
  name: 'appsettings'
  properties: {
    WEBSITES_ENABLE_APP_SERVICE_STORAGE: 'true'
  }
}

```

### Contenedores sidecar

Las aplicaciones web de contenedor también admiten [contenedores sidecar](https://learn.microsoft.com/en-us/azure/app-service/overview-sidecar), que le permiten ejecutar contenedores adicionales junto al contenedor de PowerShell Universal. Esto resulta útil para dar soporte a servicios como proxies, agentes, recopiladores u otros procesos complementarios. Al alojar PowerShell Universal en esta configuración, asegúrese de que el contenedor web exponga el puerto HTTP correcto. De forma predeterminada, PowerShell Universal escucha en el puerto `5000`.

## Aplicación web estándar

### Crear manualmente una aplicación web

Dentro del portal de Azure, deberá crear un nuevo recurso de aplicación web. Actualmente, PowerShell Universal requiere la pila de tiempo de ejecución .NET 10. Puede utilizar Linux o Windows.

{% hint style="info" %}
Si elige un plan de alojamiento de Windows en lugar de un plan de alojamiento de Linux en Azure al configurar su WebApp, deberá elegir un Basic Plan (B1) o superior para poder utilizar aplicaciones de 64 bits. También deberá ir a Settings > Configuration > General setting > Platform y seleccionar 64-bit antes de ejecutar el comando `Publish-AzWebApp`, o la instalación fallará.
{% endhint %}

<figure><img src="/files/zCvUzHvbeB1OhAukCZ9Q" alt=""><figcaption></figcaption></figure>

**Comando de inicio (solo Linux)**

Al alojar en un entorno Linux, deberá establecer el comando de inicio en Settings \ Configuration \ General Settings \ Startup Command con el siguiente valor.

```
dotnet Universal.Server.dll
```

En el ejemplo siguiente, utilizaremos el módulo Azure PowerShell para desplegar la aplicación web manualmente.

Primero deberá instalar Azure PowerShell.

```powershell
Install-Module Az
```

Una vez instalado, deberá conectarse a su suscripción.

```powershell
Connect-AzAccount
```

### Desplegar los ficheros de Windows

Si utiliza Windows, deberá descargar el fichero ZIP de Windows. Esto descargará la última versión de PowerShell Universal.

```powershell
$LatestVersion = Invoke-RestMethod https://imsreleases.blob.core.windows.net/universal/production/v5-version.txt
Invoke-WebRequest "https://imsreleases.blob.core.windows.net/universal/production/$LatestVersion/Universal.win7-x64.$LatestVersion.zip" -OutFile .\Universal.zip
```

### Desplegar los ficheros de Linux

Si utiliza Linux, deberá descargar el fichero ZIP de Linux. Esto descargará la última versión de PowerShell Universal.

```powershell
$LatestVersion = Invoke-RestMethod https://imsreleases.blob.core.windows.net/universal/production/v5-version.txt
Invoke-WebRequest "https://imsreleases.blob.core.windows.net/universal/production/$LatestVersion/Universal.linux-x64.$LatestVersion.zip" -OutFile .\Universal.zip
```

Ahora que tenemos el módulo Az configurado y el ZIP de Universal descargado, podemos desplegar la aplicación web.

```powershell
$Parameters = @{
    Force = $true
    ResourceGroupName = 'psudemo2_group'
    Name = 'psudemo2'
    ArchivePath = '.\Universal.zip'
}
Publish-AzWebApp @Parameters
```

{% hint style="info" %}
Puede comprobar en Azure, en Deployment Center > Logs, el estado Success (Active) para asegurarse de que los ficheros se desplegaron e instalaron correctamente.
{% endhint %}

### Ajustes necesarios

Estos ajustes pueden establecerse en la pestaña Configuration, dentro de Application settings.

<figure><img src="/files/lNtJyk3UPDFUSi4YWrrp" alt=""><figcaption></figcaption></figure>

#### Clave de firma JWT

La clave de firma JWT predeterminada no tiene la longitud suficiente y deberá actualizarse. Esto puede hacerse en `appsettings.json` o mediante variables de entorno.

#### appsettings.json

```
  "Jwt": {
    "SigningKey": "xXyt9UpJKB4Pb*4$hprd!JJoyOcK4ZOV**O7Hug9&@gYHc$",
    "Issuer": "IronmanSoftware",
    "Audience": "PowerShellUniversal"
  },
```

#### Variable de entorno

```
$Env:Jwt__SigningKey = 'xXyt9UpJKB4Pb*4$hprd!JJoyOcK4ZOV**O7Hug9&@gYHc$'
```

#### URL de la API

Las Azure Web Apps utilizan un proxy inverso y PowerShell Universal no detecta correctamente la URL externa. Al ejecutar trabajos, Universal utiliza la Management API para buscar automáticamente información de trabajos, scripts y programaciones. Esto significa que fallará si no puede dirigirse correctamente a la URL externa de la API.

La URL de la API debe ser la dirección HTTP externa de su aplicación web. Puede actualizarla en `appsettings.json` o mediante una variable de entorno.

#### appsettings.json

```
"Api": {
 "Url": "https://psudemo.azurewebsites.net"
 },
```

#### Variable de entorno

```
$Env:Api__Url = "https://psudemo.azurewebsites.net"
```

#### NodeName

Puede establecer el nombre de la instancia de PowerShell Universal especificando NodeName. Esto garantizará que los reinicios no afecten a la base de datos de PowerShell Universal. Esto no es necesario para las instalaciones con LiteDB.

```
$Env:NodeName = "psuazure"
```

#### PORT y WEBSITES\_PORT (solo Linux)

Para sobrescribir el puerto predeterminado en una aplicación web de Linux, debe establecer los ajustes PORT y WEBSITES\_PORT en 5000.

Después de publicar la aplicación web, visualice su instancia de PowerShell Universal navegando a la URL de la aplicación web.

#### Almacenamiento persistente

El fichero `appsettings.json` predeterminado almacenará la base de datos y los ficheros de configuración en una ubicación no persistente. Puede añadir variables de entorno para moverlos a un almacenamiento persistente dentro de su aplicación web.

**Data\_\_RepositoryPath**

La variable de entorno `Data__RepositoryPath` establece la ubicación de los ficheros de configuración de Universal. Establezca el valor siguiente.

```
D:\home\Data\PowerShellUniversal\Repository
```

### Actualizar su aplicación web

Cuando se publique una nueva versión de PowerShell Universal, deberá actualizar los ficheros de aplicación de su aplicación web. Recomendamos eliminar el directorio de la aplicación y volver a desplegar los ficheros. La base de datos y los ficheros de configuración no se almacenan en el directorio de la aplicación.

Puede eliminar los ficheros de su aplicación web utilizando la API de comandos de Kudu. Sus credenciales de Kudu utilizan autenticación básica y son las mismas que sus [credenciales de despliegue](https://github.com/projectkudu/kudu/wiki/Deployment-credentials).

Para eliminar todos los ficheros de su aplicación web, ejecute el siguiente comando.

```powershell
$Parameters = @{
   Uri = "https://psudemo2.scm.azurewebsites.net/api/command"
   Credential = (Get-Credential)
   Body = (@{
      command = "rd /s /q D:\home\site\wwwroot"
      dir = "D:\home\site\wwwroot"
   } | ConvertTo-Json)
}

Invoke-RestMethod @Parameters
```

Una vez que haya eliminado los ficheros de la aplicación, puede volver a desplegarlos ejecutando de nuevo los pasos de creación manual.

## Application Gateway

Puede configurar PowerShell Universal para que se ejecute detrás de un Application Gateway en Azure. Esto resulta útil para proporcionar equilibrio de carga y alta disponibilidad a varias instancias de PowerShell Universal.

En primer lugar, configure un grupo de backend que apunte a una o varias Azure Web Apps que ejecuten PowerShell Universal.

<figure><img src="/files/KS61XlkRqfU6kvnmyNhQ" alt=""><figcaption><p>Grupo de backend</p></figcaption></figure>

Para los ajustes de backend, deberá asegurarse de utilizar HTTPS con un certificado de una CA conocida. Se requiere la afinidad basada en cookies para garantizar que las sesiones se mantengan fijas a un nodo individual.

<figure><img src="/files/7zvSk3OLiqNH6uZ1zavc" alt=""><figcaption><p>Ajustes del grupo de backend</p></figcaption></figure>

Para permitir que Azure sirva la aplicación web correcta, deberá asegurarse de que esté configurado el ajuste Override with new host name. Utilice el nombre de host del destino de backend.

<figure><img src="/files/7P3cnn86v53ezCzcmkXB" alt=""><figcaption><p>Nombre de host de los ajustes de backend</p></figcaption></figure>

Asegúrese de que la regla del grupo de backend esté configurada como destino y no como redirección.

<figure><img src="/files/fZEdTkXFI1VrUMo3wyrz" alt=""><figcaption><p>Regla del Application Gateway</p></figcaption></figure>

Configure una regla de reescritura de cabeceras para transmitir el nombre de host público como la cabecera `X-Forwarded-Host`. PowerShell Universal la utilizará para construir las URL internamente.

<figure><img src="/files/TvIi9xFyUKisAfl8apEZ" alt=""><figcaption><p>Regla de reescritura</p></figcaption></figure>

La regla de reescritura anterior es un requisito de los métodos de autenticación OpenID Connect y SAML2.

Por último, puede configurar la IP pública de su Application Gateway utilizando un proveedor de DNS para un nombre de host personalizado. Cree un registro A en su gestión de DNS.

<figure><img src="/files/PVz8jTo2St1plGWcnwb6" alt=""><figcaption><p>Registro DNS</p></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.devolutions.net/powershell-universal/es/config/hosting/azure.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
