Medio ambiente

  • Aplicación ASP.NET WebForms sobre IIS
  • Docker contenedor host
  • Plataforma de alojamiento de AWS ECS
  • Cada cliente aloja su propia copia de la aplicación con una cadena de conexión de base de datos privada

Fondo

En el entorno no acoplable, cada copia es un directorio virtual bajo IIS y, por lo tanto, tiene su propio web.config individual que apunta a bases de datos dedicadas. La base de código subyacente es la misma para cada cliente, sin involucrar personalización específica del cliente. La ruta se convierte / aquí.

En el entorno de Docker (un contenedor por cliente), cada copia pasa como una aplicación raíz central.

Desafío

Dado que la imagen raíz será la misma, cómo anular web.config para cada implementación de cliente.

No deberíamos crear varias imágenes (una por cliente) ya que eso significaría tener trabajos de implementación adicionales y perder la centralización. Lo ideal es que las cadenas de conexión se almacenen en algún tipo de almacenamiento de diccionario aplicable a nivel ECS que pueda proporcionar valores específicos del cliente al cargar los contenedores correspondientes.

0
NitinSingh 6 dic. 2019 a las 13:10

2 respuestas

La mejor respuesta

Presentamos el enfoque que utilizamos para resolver este problema. Espero que pueda ayudar a otros afectados en casos similares.

Con la declaración del problema vinculada a tener una sola imagen raíz y aplicar cualquier personalización en tiempo de ejecución, sabíamos que debe haber una transformación de web.config en el momento de cargar los contenedores correspondientes.

La solución fue utilizar un script de PowerShell que leerá web.config y reemplazará los valores específicos que tenían un prefijo personalizado incrustado en la clave. Los valores se pasaron de variables de entorno personalizadas dentro de ECS y web.config también se actualizó para tener las claves con el prefijo agregado.

Ahora, dado que el contenedor docker solo puede tener un único punto de entrada, se creó una nueva imagen base que creó una instancia de un servidor IIS y llamó a un script de PowerShell como inicio. El script llamado llamó a este script de transformación y luego configuró el ServiceMonitor en el w3cwp.

Muchas gracias por este artículo https: / /anthonychu.ca/post/overriding-web-config-settings-environment-variables-containerized-aspnet-apps/

1
NitinSingh 6 dic. 2019 a las 10:10

Usaría variables de entorno como el OP sugiere para esto con una transformación de inicio, sin embargo, quiero señalar que no desea información confidencial en las variables ENV, como las contraseñas DB, en su tarea ECS definición.

Para esa información protegida, debe usar los secretos de ECS junto con el Almacén de parámetros en Systems Manager. Estos valores se pueden almacenar encriptados en el Almacén de parámetros (usando una clave KMS) y el Agente ECS los 'inyectará' como variables ENV en el inicio de la tarea.

Para mí, para simplificar las cosas, simplemente uso secretos para todo, aunque puede elegir cifrar solo la información confidencial y dejar claros los demás.

Agrego dinámicamente los secretos de la aplicación dada en las definiciones de mis tareas en el momento del despliegue buscando los 'secretos' de la aplicación dada por 'espacio de nombres' (algo que admite el Parameter Store). Luego, si necesito agregar un nuevo parámetro, simplemente puedo agregar un nuevo secreto a la tienda en el espacio de nombres dado y volver a implementar la aplicación. Recogerá e inyectará en la definición de tarea cualquier secreto recién definido automáticamente (o eliminará los que han sido retirados).

Ejemplo de código ruby para crear la definición de tarea:

params = ssm_client.get_parameters_by_path(path: '/production/my_app/').parameters
secrets = params.map{ |p| { name: p.name.split("/")[-1], value_from: p.arn } }
task_def.container_definitions[0].secrets = secrets

Esta última transformación inyecta los secretos de tal manera que el 'nombre' secreto es el nombre de la variable ENV ... que termina así:

      "secrets": [
    {
      "valueFrom": "arn:aws:ssm:us-east-1:578610029524:parameter/production/my_app/DB_HOSTNAME",
      "name": "DB_HOSTNAME"
    },
    {
      "valueFrom": "arn:aws:ssm:us-east-1:578610029524:parameter/production/my_app/DB_PASSWORD",
      "name": "DB_PASSWORD"
    }

Puede ver que no hay valores ahora en la definición de tarea. Se recuperan e inyectan cuando ECS inicia su tarea.

Más información: https://docs.aws.amazon.com/ AmazonECS / latest / developerguide / specifying-sensitive-data.html

1
Brett Green 6 dic. 2019 a las 13:19