如何通过Quarkus扩展从AWS SecretsManager获取密钥作为环境变量
1. 添加依赖
首先在项目中引入Quarkus Amazon SecretsManager扩展:
Maven
在pom.xml中添加依赖:
<dependency> <groupId>io.quarkiverse.amazonservices</groupId> <artifactId>quarkus-amazon-secretsmanager</artifactId> </dependency>
Gradle
在build.gradle中添加依赖:
implementation 'io.quarkiverse.amazonservices:quarkus-amazon-secretsmanager'
2. 配置AWS SecretsManager
在application.properties中配置AWS区域,认证会自动使用AWS默认凭证链(本地~/.aws/credentials文件、EC2/EKS实例角色、环境变量AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY等均可):
quarkus.amazon-secretsmanager.region=us-east-1
如果需要显式指定凭证(不推荐,优先用默认链),可以添加:
quarkus.amazon-secretsmanager.credentials.access-key=你的AWS访问密钥 quarkus.amazon-secretsmanager.credentials.secret-key=你的AWS秘密密钥
3. 将SecretsManager密钥映射为可用配置属性(模拟环境变量)
Quarkus支持直接在配置文件中引用SecretsManager的密钥,格式为${sm://<密钥名称>};如果密钥是JSON结构,还可以用${sm://<密钥名称>/<字段名>}提取具体值。这种方式下,你可以像使用环境变量或普通配置项一样注入这些值。
示例1:引用纯文本密钥
假设SecretsManager中有一个名为db-password的纯文本密钥,值为mySecurePass123,在application.properties中配置:
database.password=${sm://db-password}
然后在代码中通过@ConfigProperty注入使用:
import jakarta.inject.Inject; import org.eclipse.microprofile.config.inject.ConfigProperty; public class DatabaseConnector { @Inject @ConfigProperty(name = "database.password") String dbPassword; // 使用dbPassword初始化数据库连接 }
示例2:引用JSON格式密钥的字段
如果密钥是JSON结构,比如名为db-credentials的密钥值为{"username":"admin","password":"secretPass"},可以提取指定字段:
database.username=${sm://db-credentials/username} database.password=${sm://db-credentials/password}
同样通过@ConfigProperty注入即可,和使用普通环境变量完全一致。
示例3:编程式获取并设置为系统属性
如果需要主动控制密钥加载逻辑(不推荐,优先用配置映射),可以注入SecretsManagerClient手动获取密钥,再设置为系统属性(可通过System.getProperty()获取,效果类似环境变量):
import jakarta.enterprise.context.ApplicationScoped; import jakarta.annotation.PostConstruct; import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient; import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest; @ApplicationScoped public class SecretInitializer { @Inject SecretsManagerClient secretsManagerClient; @PostConstruct public void loadSecret() { var request = GetSecretValueRequest.builder() .secretId("db-password") .build(); var response = secretsManagerClient.getSecretValue(request); String secretValue = response.secretString(); // 设置为系统属性,后续可通过System.getProperty("DB_PASSWORD")获取 System.setProperty("DB_PASSWORD", secretValue); } }
注意:JVM运行时修改环境变量(System.getenv()对应的)有一定限制,部分操作系统不支持动态修改,因此优先用系统属性或配置映射方式。
关键注意事项
- 确保运行应用的实体(EC2实例、ECS任务、本地用户等)拥有
secretsmanager:GetSecretValue的IAM权限,否则会报错权限不足。 - 配置映射方式(
${sm://...})是Quarkus官方推荐的做法,更简洁且能自动处理密钥刷新(如果配置了刷新机制)。 - 若密钥是二进制格式,需使用
response.secretBinary()获取并处理成对应格式。
内容的提问来源于stack exchange,提问作者Mohamed r

