现在已经被困在这个问题上无数个小时了。
这个命令通过终端对我来说效果非常好:
aws ssm get-parameter --name "/something/i/know/exists" --query "Parameter.Value" --output text
输出:
subnet-whatIwouldExpect
但是将其设置为 Terraform 内的变量则完全是另一回事。
(我一直很高兴使用 Terraform 计划/应用/销毁等)
data "external" "ssm_parameter_value" {
program = ["bash", "-c", <<-EOF
result=$(aws ssm get-parameter --name "/something/i/know/exists" --query "Parameter.Value" --output text)
echo "{\"result\": \"$result\"}"
EOF
]
}
output "ssm_parameter_result" {
value = data.external.ssm_parameter_value.result
}
当我尝试terraform刷新时,我得到:
ssm_parameter_result = tomap({
"result" = ""
})
这非常令人沮丧,我不知道我做错了什么。
这是我的整个文件:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.34.0"
}
}
required_version = ">= 0.14.9"
}
provider "aws" {
region = "eu-west-2"
default_tags {
tags = local.common_tags
}
}
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
# Execute AWS CLI command to get SSM parameter value
data "external" "ssm_parameter_value" {
program = ["bash", "-c", <<-EOF
result=$(aws ssm get-parameter --name "/something/i/know/exists" --query "Parameter.Value" --output text)
echo "{\"result\": \"$result\"}"
EOF
]
}
output "ssm_parameter_result" {
value = data.external.ssm_parameter_value.result
}
编辑:
我知道
data "aws_ssm_parameter" "example" { name = "/A/B/C" }
但是,如果 AWS 上不存在该参数,则会失败并显示 ParameterNotFound。
这似乎并不奇怪
我希望能够利用
的价值data.external.ssm_parameter_value.result
稍后驱动其他资源的创建/不创建:
例如
resource "aws_security_group_rule" "example" {
count = data.external.ssm_parameter_value.result != "" ? 1 : 0
type = "ingress"
from_port = 0
to_port = 0
protocol = "-1"
security_group_id = data.external.ssm_parameter_value.result["result"]
source_security_group_id = aws_security_group.another-sg.id
description = "All Traffic from Lambda"
}
没有理由只是为了在 Terraform 代码中查找 SSM 参数值而使用命令行并使用 AWS CLI 工具。这是一种非常复杂且容易出错的获取值的方法。
您已经在使用 AWS Terraform 提供程序,并且它已经连接到 AWS,那么为什么还要使用 AWS CLI 工具跳过额外的环节来从 AWS 读取值呢?
只需将您的
data "external" "ssm_parameter_value"
替换为以下内容:
data "aws_ssm_parameter" "my_parameter" {
name = "/something/i/know/exists"
}
然后用
aws_ssm_parameter.my_parameter.value
引用该值,例如:
output "ssm_parameter_result" {
value = aws_ssm_parameter.my_parameter.value
}
正如马克在他的回答中解释的那样,您应该尽可能使用特定于资源的数据源。然而,如果资源不存在,数据源总是会出错。几年前曾提出“增强请求”,要求改变这种行为,但遭到拒绝。 因此,在这种情况下,外部
data
源是一个有效的替代方案。
外部数据源要求程序输出必须是JSON对象。在此示例中,您可以执行以下操作:# Execute AWS CLI command to get SSM parameter value
data "external" "ssm_parameter_value" {
program = ["bash", "-c", <<-EOF
param=$(aws ssm get-parameter --name "/something/i/know/exists" --query "Parameter.Value" --output text 2>/dev/null);
if [ "$?" -eq 0 ]; then
jq -r -n --arg param "$param" '{"param":$param}'
else
jq -r -n '{"param":""}'
fi
EOF
]
}
output "ssm_parameter_result" {
value = data.external.ssm_parameter_value.result.param
}
如果秘密存在,输出将为:
$ terraform apply
...
ssm_parameter_result = "foo"
如果秘密不存在,输出将为:
$ terraform apply
...
ssm_parameter_result = ""
请注意,此方法需要
jq
来创建 JSON 对象。