如何在Makefile同一Shell中正确传递AWS凭证?
解决Makefile中$(shell)命令无法继承目标环境变量的问题
你遇到的核心问题是Make的变量解析时机早于目标环境变量的设置:Make在解析整个Makefile的阶段就会执行$(shell)命令并完成SOME_KEY的赋值,此时get-some-key目标里的export语句还未生效,所以aws命令调用使用的是初始系统环境中的AWS凭证。
以下是几种可行的解决方案:
方案1:在目标的Shell命令中直接赋值使用
放弃在Make变量中提前用$(shell)赋值,转而在目标执行的Shell环境内完成密钥获取,此时目标的环境变量已经生效:
get-some-key: export AWS_ACCESS_KEY_ID=$(SOME_OTHER_AWS_ACCESS_KEY_ID) get-some-key: export AWS_SECRET_ACCESS_KEY=$(SOME_OTHER_AWS_SECRET_ACCESS_KEY) get-some-key: SOME_KEY=$$(aws secretsmanager get-value ...); echo $$SOME_KEY
这里用$$(...)是为了让Make把括号内的内容直接传递给Shell执行,而非提前解析。
方案2:通过eval延迟变量赋值
如果需要将结果存入Make变量,可以用$(eval)在目标执行阶段动态计算变量值,此时手动传递目标的环境变量给aws命令:
get-some-key: AWS_ACCESS_KEY_ID=$(SOME_OTHER_AWS_ACCESS_KEY_ID) get-some-key: AWS_SECRET_ACCESS_KEY=$(SOME_OTHER_AWS_SECRET_ACCESS_KEY) get-some-key: $(eval SOME_KEY := $(shell AWS_ACCESS_KEY_ID=$(AWS_ACCESS_KEY_ID) AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY) aws secretsmanager get-value ...)) echo $(SOME_KEY)
注意:这种方式会让SOME_KEY成为全局变量,若其他目标也使用该变量可能受到影响。
方案3:封装为独立Shell脚本
将密钥获取逻辑写入单独的Shell脚本,在Make目标中调用脚本,此时脚本会自动继承目标的环境变量:
- 创建
get-key.sh脚本:
#!/bin/bash # 给脚本添加执行权限:chmod +x get-key.sh SOME_KEY=$(aws secretsmanager get-value ...) echo "$SOME_KEY"
- 修改Makefile:
get-some-key: export AWS_ACCESS_KEY_ID=$(SOME_OTHER_AWS_ACCESS_KEY_ID) get-some-key: export AWS_SECRET_ACCESS_KEY=$(SOME_OTHER_AWS_SECRET_ACCESS_KEY) get-some-key: ./get-key.sh
这种方式逻辑清晰,适合复杂的命令逻辑场景。
内容的提问来源于stack exchange,提问作者Korepanov Aleksander
相关产品推荐
相关产品推荐

