Asp.net 用于通过AWS ECS在docker中多租户部署WebForms应用程序的Web.Config转换
环境Asp.net 用于通过AWS ECS在docker中多租户部署WebForms应用程序的Web.Config转换,asp.net,docker,jenkins,amazon-ecs,Asp.net,Docker,Jenkins,Amazon Ecs,环境 IIS上的ASP.NET WebForms应用程序 Docker容器主机 AWS云服务器托管平台 每个客户端托管自己的应用程序副本,并带有专用数据库连接字符串 背景 在非docker环境中,每个副本都是IIS下的一个虚拟目录,因此都有各自指向专用数据库的web.config。每个客户端的底层代码库都是相同的,不涉及特定于客户端的定制。路线在这里变为 在docker环境中(每个客户端一个容器),每个副本都作为一个中心根应用程序 Challange 由于根映像将是相同的,因此如何为每个客户
- IIS上的ASP.NET WebForms应用程序
- Docker容器主机
- AWS云服务器托管平台
- 每个客户端托管自己的应用程序副本,并带有专用数据库连接字符串
我们不应该创建多个映像(每个客户机一个),因为这将意味着有额外的部署作业,并失去集中化。理想情况下,连接字符串应存储在某种字典存储中,适用于ECS级别,可在加载相应容器时提供特定于客户端的值。介绍了我们用于解决此问题的方法。希望它能帮助其他类似案件的受害者 由于问题语句与拥有一个根映像和在运行时应用任何定制相关,我们知道在加载相应容器时需要对web.config进行转换 解决方案是使用一个PowerShell脚本,该脚本将读取web.config并获取替换键中嵌入自定义前缀的特定值。ECS中的自定义环境变量传递的值和web.config也得到更新,添加了前缀的密钥 现在,由于docker容器只能有一个入口点,因此创建了一个新的基本映像,该映像实例化了一个IIS服务器,并将PowerShell脚本称为启动。被调用的脚本调用此转换脚本,然后在w3cwp上设置ServiceMonitor
非常感谢这篇文章介绍了我们用于解决此问题的方法。希望它能帮助其他类似案件的受害者 由于问题语句与拥有一个根映像和在运行时应用任何定制相关,我们知道在加载相应容器时需要对web.config进行转换 解决方案是使用一个PowerShell脚本,该脚本将读取web.config并获取替换键中嵌入自定义前缀的特定值。ECS中的自定义环境变量传递的值和web.config也得到更新,添加了前缀的密钥 现在,由于docker容器只能有一个入口点,因此创建了一个新的基本映像,该映像实例化了一个IIS服务器,并将PowerShell脚本称为启动。被调用的脚本调用此转换脚本,然后在w3cwp上设置ServiceMonitor
非常感谢这篇文章我会按照OP的建议,在启动转换中使用环境变量,但是我想指出的是,您不希望在ECS任务定义中的环境变量(如DB密码)中包含敏感信息 对于受保护的信息,您应该使用ECS机密和Systems Manager中的参数存储。这些值可以加密存储在参数存储中(使用KMS密钥),ECS代理将在任务启动时“注入”它们作为环境变量 对我来说,为了简化事情,我只是在所有事情上使用秘密,尽管你可以选择只加密敏感信息,而不加密其他信息 我在部署时通过“名称空间”(参数存储支持的东西)查找给定应用程序的“机密”,动态地将给定应用程序的机密添加到任务定义中。然后,如果我需要添加一个新参数,我可以在给定的名称空间中向存储添加一个新的秘密,然后重新部署应用程序。它将自动获取并向任务定义中注入任何新定义的机密(或删除已失效的机密) 创建任务定义的示例ruby代码:
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
最后一个转换注入秘密,这样秘密“name”就是ENV变量名。。。结果是这样的:
"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"
}
您可以看到任务定义中现在没有值。当ECS启动您的任务时,将检索并注入它们
更多信息:
我会像OP建议的那样,在启动转换中使用环境变量,但是我想指出的是,您不希望在ECS任务定义中的环境变量(如DB密码)中包含敏感信息 对于受保护的信息,您应该使用ECS机密和Systems Manager中的参数存储。这些值可以加密存储在参数存储中(使用KMS密钥),ECS代理将在任务启动时“注入”它们作为环境变量 对我来说,为了简化事情,我只是在所有事情上使用秘密,尽管你可以选择只加密敏感信息,而不加密其他信息 我在部署时通过“名称空间”(参数存储支持的东西)查找给定应用程序的“机密”,动态地将给定应用程序的机密添加到任务定义中。然后,如果我需要添加一个新参数,我可以在给定的名称空间中向存储添加一个新的秘密,然后重新部署应用程序。它将自动获取并向任务定义中注入任何新定义的机密(或删除已失效的机密) 创建任务定义的示例ruby代码:
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
最后一个转换注入秘密,这样秘密“name”就是ENV变量名。。。最后是洛城