如果数据源没有找到任何结果,我如何继续Terraform的执行?

问题描述 投票:0回答:2

现在已经被困在这个问题上无数个小时了。

这个命令通过终端对我来说效果非常好:

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"
}
amazon-web-services terraform aws-cli
2个回答
2
投票

没有理由只是为了在 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
}

0
投票

正如马克在他的回答中解释的那样,您应该尽可能使用特定于资源的数据源。然而,如果资源不存在,数据源总是会出错。几年前曾提出“增强请求”,要求改变这种行为,但遭到拒绝。 因此,在这种情况下,外部

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 对象。

    

© www.soinside.com 2019 - 2024. All rights reserved.