在ECS中与Tomcat服务共享一个秘密
AWS是相当不错的,有很多文档。然而,往往你需要在一堆没有错的文档中发现你所需要的细节,但并不完全能涵盖你的用例。
提供低层次的细节并不总是能提供足够的信息来组装一个完整的连贯的解决方案。
我最近在构建一些Cloudformation的部署。我们希望在ECS的fargate容器中运行的tomcat实例,能够用秘密证书指向部署环境的数据库。
这就给我们带来了一个痛苦的世界,那就是如何安全地从秘密管理器中的正确秘密中获取凭证,并将其输入到server.xml 中的配置中。
Tomcat如何读取环境变量
请记住,我的Tomcat运行在docker中......我可以把这个添加到Dockerfile 。
ENV JAVA_OPTS=-Dorg.apache.tomcat.util.digester.PROPERTY_SOURCE=org.apache.tomcat.util.digester.EnvironmentPropertySource
这样就可以在Tomcat配置的XML文件阅读中开启环境变量的插值。因此,如果我的server.xml ,做这样的事情。
<Resource name="jdbc/mydatabase" auth="Container" type="javax.sql.DataSource"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="com.mysql.cj.jdbc.Driver"
...
username="${MYSQL_USER}" password="${MYSQL_PASSWORD}"
url="jdbc:mysql://${MYSQL_HOST}/mydb?useSSL=false"
... />
这意味着,来自容器的MYSQL_ 环境变量被注入到JDBC设置中。
为了找到上述内容,我们进行了大量的搜索。
然后我们读取秘密
我所使用的秘密包含用户名、密码和主机。它是由Cloudformation自动制作的,并且有自己的旋转时间表。我所需要做的就是从中提取username,password 和host ,只要我知道要使用哪个秘密。
让我们在我们的Cloudformation中放入一个环境地图,其中包含秘密。
Mappings:
dev:
Database:
# the secret dictates usernames/passwords/endpoints
Secret: arn:aws:secretsmanager:eu-west-1:12345678:secret:database-secret-abRK8x
我们有一个StageName 变量,它决定了我们在哪个环境中。所以现在,在我们的fargate容器定义中,我们只需要把秘密中的值摘到环境变量中。
MyEcsTask:
Type: AWS::ECS::TaskDefinition
Properties:
RequiresCompatibilities:
- FARGATE
ContainerDefinitions:
- Name: !Sub ${AWS::StackName}-tomcat
Image: my-tomcat-container:latest
PortMappings:
- ContainerPort:8080
HostPort:8080
Secrets:
- Name: MYSQL_USER
ValueFrom: !Sub
-'${secret}:username::'
- secret: !FindInMap [!Ref StageName, Database, Secret]
- Name: MYSQL_PASSWORD
ValueFrom: !Sub
-'${secret}:password::'
- secret: !FindInMap [!Ref StageName, Database, Secret]
- Name: MYSQL_HOST
ValueFrom: !Sub
-'${secret}:host::'
- secret: !FindInMap [!Ref StageName, Database, Secret]
那里的Secrets 部分有很多事情要做。ValueFrom 正在使用一个!Sub 表达式来计算要使用的秘密,基于当前的StageName 使用环境图来寻找正确的秘密。
不过,正在发生的事情是,从秘密中的username 、password 和host 密钥正在被单独读取。这涉及到<secret-name>:<desired-json-key>:: 的语法--那些尾部的::s非常重要(否则就无法工作!)。
总结
如果你知道去哪里找的话,上述信息可以在文档中找到。
希望这个配方能对某些人有所帮助。